rpc 调试

This commit is contained in:
COOL 2025-01-17 18:00:58 +08:00
parent 4b3bcd7ea5
commit 56476d19a9
30 changed files with 721 additions and 22 deletions

28
.vscode/config.code-snippets vendored Normal file
View File

@ -0,0 +1,28 @@
{
"config": {
"prefix": "config",
"body": [
"import { ModuleConfig } from '@cool-midway/core';",
"",
"/**",
" * 模块配置",
" */",
"export default () => {",
" return {",
" // 模块名称",
" name: 'xxx',",
" // 模块描述",
" description: 'xxx',",
" // 中间件,只对本模块有效",
" middlewares: [],",
" // 中间件,全局有效",
" globalMiddlewares: [],",
" // 模块加载顺序默认为0值越大越优先加载",
" order: 0,",
" } as ModuleConfig;",
"};",
""
],
"description": "cool-admin config代码片段"
}
}

19
.vscode/controller.code-snippets vendored Normal file
View File

@ -0,0 +1,19 @@
{
"controller": {
"prefix": "controller",
"body": [
"import { CoolController, BaseController } from '@cool-midway/core';",
"",
"/**",
" * 描述",
" */",
"@CoolController({",
" api: ['add', 'delete', 'update', 'info', 'list', 'page'],",
" entity: 实体,",
"})",
"export class XxxController extends BaseController {}",
""
],
"description": "cool-admin controller代码片段"
}
}

20
.vscode/entity.code-snippets vendored Normal file
View File

@ -0,0 +1,20 @@
{
"entity": {
"prefix": "entity",
"body": [
"import { BaseEntity } from '../../base/entity/base';",
"import { Column, Entity } from 'typeorm';",
"",
"/**",
" * 描述",
" */",
"@Entity('xxx_xxx_xxx')",
"export class XxxEntity extends BaseEntity {",
" @Column({ comment: '描述' })",
" xxx: string;",
"}",
""
],
"description": "cool-admin entity代码片段"
}
}

21
.vscode/event.code-snippets vendored Normal file
View File

@ -0,0 +1,21 @@
{
"event": {
"prefix": "event",
"body": [
"import { CoolEvent, Event } from '@cool-midway/core';",
"",
"/**",
" * 接收事件",
" */",
"@CoolEvent()",
"export class xxxEvent {",
" @Event('updateUser')",
" async updateUser(msg, a) {",
" console.log('ImEvent', 'updateUser', msg, a);",
" }",
"}",
""
],
"description": "cool-admin event代码片段"
}
}

29
.vscode/middleware.code-snippets vendored Normal file
View File

@ -0,0 +1,29 @@
{
"middleware": {
"prefix": "middleware",
"body": [
"import { Middleware } from '@midwayjs/decorator';",
"import { NextFunction, Context } from '@midwayjs/koa';",
"import { IMiddleware } from '@midwayjs/core';",
"",
"/**",
" * 描述",
" */",
"@Middleware()",
"export class XxxMiddleware implements IMiddleware<Context, NextFunction> {",
" resolve() {",
" return async (ctx: Context, next: NextFunction) => {",
" // 控制器前执行的逻辑",
" const startTime = Date.now();",
" // 执行下一个 Web 中间件,最后执行到控制器",
" await next();",
" // 控制器之后执行的逻辑",
" console.log(Date.now() - startTime);",
" };",
" }",
"}",
""
],
"description": "cool-admin middleware代码片段"
}
}

21
.vscode/queue.code-snippets vendored Normal file
View File

@ -0,0 +1,21 @@
{
"queue": {
"prefix": "queue",
"body": [
"import { BaseCoolQueue, CoolQueue } from '@cool-midway/task';",
"",
"/**",
" * 队列",
" */",
"@CoolQueue()",
"export abstract class xxxQueue extends BaseCoolQueue {",
" async data(job: any, done: any) {",
" console.log('收到的数据', job.data);",
" done();",
" }",
"}",
""
],
"description": "cool-admin service代码片段"
}
}

32
.vscode/service.code-snippets vendored Normal file
View File

@ -0,0 +1,32 @@
{
"service": {
"prefix": "service",
"body": [
"import { BaseService, Init, Provide } from '@cool-midway/core';",
"import { InjectEntityModel } from '@midwayjs/typeorm';",
"import { Repository } from 'typeorm';",
"",
"/**",
" * 描述",
" */",
"@Provide()",
"export class XxxService extends BaseService {",
" @InjectEntityModel(实体)",
" xxxEntity: Repository<实体>;",
""
" @Init()"
" async init() {",
" await super.init();",
" this.setEntity(this.xxxEntity);",
" }",
"",
" /**",
" * 描述",
" */",
" async xxx() {}",
"}",
""
],
"description": "cool-admin service代码片段"
}
}

View File

@ -61,6 +61,9 @@ export default {
cool: { cool: {
// 已经插件化,本地文件上传查看 plugin/config.ts其他云存储查看对应插件的使用 // 已经插件化,本地文件上传查看 plugin/config.ts其他云存储查看对应插件的使用
file: {}, file: {},
rpc: {
name: 'main',
},
// redis配置 // redis配置
redis: { redis: {
port: 6379, port: 6379,

View File

@ -23,7 +23,7 @@ export default {
}, },
cool: { cool: {
// 实体与路径跟生成代码、前端请求、swagger文档相关 注意:线上不建议开启,以免暴露敏感信息 // 实体与路径跟生成代码、前端请求、swagger文档相关 注意:线上不建议开启,以免暴露敏感信息
eps: false, eps: true,
// 是否自动导入模块数据库 // 是否自动导入模块数据库
initDB: true, initDB: true,
// 判断是否初始化的方式 // 判断是否初始化的方式

View File

@ -19,7 +19,7 @@ import * as ProdConfig from './config/config.prod';
import * as cool from '@cool-midway/core'; import * as cool from '@cool-midway/core';
import * as upload from '@midwayjs/upload'; import * as upload from '@midwayjs/upload';
import * as task from '@cool-midway/task'; import * as task from '@cool-midway/task';
// import * as rpc from '@cool-midway/rpc'; import * as rpc from '@cool-midway/rpc';
@Configuration({ @Configuration({
imports: [ imports: [
@ -40,7 +40,7 @@ import * as task from '@cool-midway/task';
// cool-admin 官方组件 https://cool-js.com // cool-admin 官方组件 https://cool-js.com
cool, cool,
// rpc 微服务 远程调用 // rpc 微服务 远程调用
// rpc, rpc,
// 任务与队列 // 任务与队列
task, task,
{ {

View File

@ -10,17 +10,18 @@ import * as entity7 from './modules/recycle/entity/data';
import * as entity8 from './modules/plugin/entity/info'; import * as entity8 from './modules/plugin/entity/info';
import * as entity9 from './modules/dict/entity/type'; import * as entity9 from './modules/dict/entity/type';
import * as entity10 from './modules/dict/entity/info'; import * as entity10 from './modules/dict/entity/info';
import * as entity11 from './modules/base/entity/base'; import * as entity11 from './modules/demo/entity/goods';
import * as entity12 from './modules/base/entity/sys/user_role'; import * as entity12 from './modules/base/entity/base';
import * as entity13 from './modules/base/entity/sys/user'; import * as entity13 from './modules/base/entity/sys/user_role';
import * as entity14 from './modules/base/entity/sys/role_menu'; import * as entity14 from './modules/base/entity/sys/user';
import * as entity15 from './modules/base/entity/sys/role_department'; import * as entity15 from './modules/base/entity/sys/role_menu';
import * as entity16 from './modules/base/entity/sys/role'; import * as entity16 from './modules/base/entity/sys/role_department';
import * as entity17 from './modules/base/entity/sys/param'; import * as entity17 from './modules/base/entity/sys/role';
import * as entity18 from './modules/base/entity/sys/menu'; import * as entity18 from './modules/base/entity/sys/param';
import * as entity19 from './modules/base/entity/sys/log'; import * as entity19 from './modules/base/entity/sys/menu';
import * as entity20 from './modules/base/entity/sys/department'; import * as entity20 from './modules/base/entity/sys/log';
import * as entity21 from './modules/base/entity/sys/conf'; import * as entity21 from './modules/base/entity/sys/department';
import * as entity22 from './modules/base/entity/sys/conf';
export const entities = [ export const entities = [
...Object.values(entity0), ...Object.values(entity0),
...Object.values(entity1), ...Object.values(entity1),
@ -44,4 +45,5 @@ export const entities = [
...Object.values(entity19), ...Object.values(entity19),
...Object.values(entity20), ...Object.values(entity20),
...Object.values(entity21), ...Object.values(entity21),
...Object.values(entity22),
]; ];

View File

@ -0,0 +1,11 @@
import { CoolController, BaseController } from '@cool-midway/core';
import { DemoGoodsEntity } from '../../entity/goods';
/**
* -
*/
@CoolController({
api: ['add', 'delete', 'update', 'info', 'list', 'page'],
entity: DemoGoodsEntity,
})
export class AdminDemoGoodsController extends BaseController {}

View File

@ -0,0 +1,37 @@
import { DemoCacheService } from '../../service/cache';
import { Inject, Post, Provide, Get, InjectClient } from '@midwayjs/core';
import { CoolController, BaseController } from '@cool-midway/core';
import { CachingFactory, MidwayCache } from '@midwayjs/cache-manager';
/**
*
*/
@CoolController()
export class OpenDemoCacheController extends BaseController {
@InjectClient(CachingFactory, 'default')
midwayCache: MidwayCache;
@Inject()
demoCacheService: DemoCacheService;
/**
*
* @returns
*/
@Post('/set', { summary: '设置缓存' })
async set() {
await this.midwayCache.set('a', 1);
// 缓存10秒
await this.midwayCache.set('a', 1, 10 * 1000);
return this.ok(await this.midwayCache.get('a'));
}
/**
*
* @returns
*/
@Get('/get', { summary: '获得缓存' })
async get() {
return this.ok(await this.demoCacheService.get());
}
}

View File

@ -0,0 +1,27 @@
import { Inject, Post } from '@midwayjs/core';
import {
CoolController,
BaseController,
CoolEventManager,
} from '@cool-midway/core';
/**
*
*/
@CoolController()
export class OpenDemoEventController extends BaseController {
@Inject()
coolEventManager: CoolEventManager;
@Post('/comm', { summary: '普通事件,本进程生效' })
async comm() {
await this.coolEventManager.emit('demo', { a: 2 }, 1);
return this.ok();
}
@Post('/global', { summary: '全局事件,多进程都有效' })
async global() {
await this.coolEventManager.globalEmit('demo', false, { a: 2 }, 1);
return this.ok();
}
}

View File

@ -0,0 +1,32 @@
import { DemoGoodsService } from '../../service/goods';
import { DemoGoodsEntity } from '../../entity/goods';
import { Body, Config, Inject, Post, Provide } from '@midwayjs/core';
import { CoolController, BaseController } from '@cool-midway/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';
/**
*
*/
@CoolController({
api: ['add', 'delete', 'update', 'info', 'list', 'page'],
entity: DemoGoodsEntity,
service: DemoGoodsService,
})
export class OpenDemoGoodsController extends BaseController {
@InjectEntityModel(DemoGoodsEntity)
demoGoodsEntity: Repository<DemoGoodsEntity>;
@Inject()
demoGoodsService: DemoGoodsService;
@Post('/sqlPage', { summary: 'sql分页查询' })
async sqlPage(@Body() query) {
return this.ok(await this.demoGoodsService.sqlPage(query));
}
@Post('/entityPage', { summary: 'entity分页查询' })
async entityPage(@Body() query) {
return this.ok(await this.demoGoodsService.entityPage(query));
}
}

View File

@ -13,13 +13,17 @@ export class OpenDemoPluginController extends BaseController {
@Get('/invoke', { summary: '调用插件' }) @Get('/invoke', { summary: '调用插件' })
async invoke() { async invoke() {
// 获取插件实例 // 获取插件实例
const instance = await this.pluginService.getInstance('feishu'); const instance: any = await this.pluginService.getInstance('ollama');
instance.sendByHook({ // 调用chat
msg_type: 'text', const messages = [
content: { { role: 'system', content: '你叫小酷,是一个智能助理' },
text: '测试', { role: 'user', content: '写一个1000字的关于春天的文章' },
}, ];
}); for (let i = 0; i < 3; i++) {
instance.chat(messages, { stream: true }, res => {
console.log(i, res.content);
});
}
return this.ok(); return this.ok();
} }
} }

View File

@ -0,0 +1,49 @@
import { Get, Inject, Post, Provide } from '@midwayjs/core';
import { CoolController, BaseController } from '@cool-midway/core';
import { DemoCommQueue } from '../../queue/comm';
import { DemoGetterQueue } from '../../queue/getter';
/**
*
*/
@CoolController()
export class OpenDemoQueueController extends BaseController {
// 普通队列
@Inject()
demoCommQueue: DemoCommQueue;
// 主动消费队列
@Inject()
demoGetterQueue: DemoGetterQueue;
/**
*
*/
@Post('/add', { summary: '发送队列数据' })
async queue() {
this.demoCommQueue.add({ a: 2 });
return this.ok();
}
@Post('/addGetter')
async addGetter() {
await this.demoGetterQueue.add({ a: new Date() });
return this.ok();
}
/**
* getter时有效
*/
@Get('/getter')
async getter() {
const job = await this.demoGetterQueue.getters.getJobs(
['wait'],
0,
0,
true
);
// 获得完将数据从队列移除
await job[0]?.remove();
return this.ok(job[0]?.data);
}
}

View File

@ -0,0 +1,29 @@
import { Inject, Provide, Get } from '@midwayjs/core';
import { CoolController, BaseController } from '@cool-midway/core';
import { DemoRpcService } from '../../service/rpc';
/**
* RPC调用
*/
@CoolController()
export class OpenDemoRpcController extends BaseController {
@Inject()
demoRpcService: DemoRpcService;
@Get('/call', { summary: '远程调用' })
async call() {
return this.ok(await this.demoRpcService.call());
}
@Get('/event', { summary: '集群事件' })
async event() {
await this.demoRpcService.event();
return this.ok();
}
@Get('/transaction', { summary: '分布式事务' })
async transaction() {
await this.demoRpcService.transaction({ a: 1 });
return this.ok();
}
}

View File

@ -0,0 +1,49 @@
import { CoolController, BaseController } from '@cool-midway/core';
import { Get, Inject } from '@midwayjs/core';
import { PluginService } from '../../../plugin/service/info';
import { PassThrough } from 'stream';
import { IMidwayKoaContext } from '@midwayjs/koa';
/**
*
*/
@CoolController()
export class OpenDemoSSEController extends BaseController {
@Inject()
ctx: IMidwayKoaContext;
@Inject()
pluginService: PluginService;
@Get('/call', { summary: '事件流 服务端主动推送' })
async call() {
// 设置响应头
this.ctx.set('Content-Type', 'text/event-stream');
this.ctx.set('Cache-Control', 'no-cache');
this.ctx.set('Connection', 'keep-alive');
const stream = new PassThrough();
// 发送数据
const send = (data: any) => {
stream.write(`data: ${JSON.stringify(data)}\n\n`);
};
// 获取插件实例
const instance: any = await this.pluginService.getInstance('ollama');
// 调用chat
const messages = [
{ role: 'system', content: '你叫小酷,是个编程助手' },
{ role: 'user', content: '用js写个Hello World' },
];
instance.chat(messages, { stream: true }, res => {
send(res);
if (res.isEnd) {
this.ctx.res.end();
}
});
this.ctx.status = 200;
this.ctx.body = stream;
}
}

View File

@ -0,0 +1,14 @@
import { DemoGoodsEntity } from '../../entity/goods';
import { Provide } from '@midwayjs/core';
import { CoolController, BaseController } from '@cool-midway/core';
import { DemoTransactionService } from '../../service/transaction';
/**
*
*/
@CoolController({
api: ['add', 'delete', 'update', 'info', 'list', 'page'],
entity: DemoGoodsEntity,
service: DemoTransactionService,
})
export class OpenDemoTransactionController extends BaseController {}

View File

@ -0,0 +1,32 @@
import { BaseEntity } from '../../base/entity/base';
import { Column, Entity, Index } from 'typeorm';
/**
* -
*/
@Entity('demo_goods')
export class DemoGoodsEntity extends BaseEntity {
@Index()
@Column({ comment: '标题', length: 50 })
title: string;
@Column({
comment: '价格',
type: 'decimal',
precision: 5,
scale: 2,
})
price: number;
@Column({ comment: '描述', nullable: true })
description: string;
@Column({ comment: '主图', nullable: true })
mainImage: string;
@Column({ comment: '示例图', nullable: true, type: 'json' })
exampleImages: string[];
@Column({ comment: '库存', default: 0 })
stock: number;
}

View File

@ -0,0 +1,27 @@
import { CoolEvent, Event } from '@cool-midway/core';
import { EVENT_PLUGIN_READY } from '../../plugin/service/center';
/**
*
*/
@CoolEvent()
export class DemoCommEvent {
/**
*
* @param msg
* @param a
*/
@Event('demo')
async demo(msg, a) {
console.log(`comm当前进程的ID是: ${process.pid}`);
console.log('comm收到消息', msg, a);
}
/**
*
*/
@Event(EVENT_PLUGIN_READY)
async pluginReady() {
// TODO 插件已就绪
}
}

View File

@ -0,0 +1,20 @@
import { BaseCoolQueue, CoolQueue } from '@cool-midway/task';
import { IMidwayApplication } from '@midwayjs/core';
import { App } from '@midwayjs/core';
/**
*
*/
@CoolQueue()
export class DemoCommQueue extends BaseCoolQueue {
@App()
app: IMidwayApplication;
async data(job: any, done: any): Promise<void> {
// 这边可以执行定时任务具体的业务或队列的业务
console.log('数据', job.data);
// 抛出错误 可以让队列重试默认重试5次
//throw new Error('错误');
done();
}
}

View File

@ -0,0 +1,7 @@
import { BaseCoolQueue, CoolQueue } from '@cool-midway/task';
/**
*
*/
@CoolQueue({ type: 'getter' })
export class DemoGetterQueue extends BaseCoolQueue {}

View File

@ -0,0 +1,20 @@
import { BaseCoolQueue, CoolQueue } from '@cool-midway/task';
import { IMidwayApplication } from '@midwayjs/core';
import { App } from '@midwayjs/core';
/**
* cluster
*/
@CoolQueue({ type: 'single' })
export class DemoSingleQueue extends BaseCoolQueue {
@App()
app: IMidwayApplication;
async data(job: any, done: any): Promise<void> {
// 这边可以执行定时任务具体的业务或队列的业务
console.log('数据', job.data);
// 抛出错误 可以让队列重试默认重试5次
//throw new Error('错误');
done();
}
}

View File

@ -0,0 +1,18 @@
import { Provide } from '@midwayjs/core';
import { CoolCache } from '@cool-midway/core';
/**
*
*/
@Provide()
export class DemoCacheService {
// 数据缓存5秒
@CoolCache(5)
async get() {
console.log('执行方法');
return {
a: 1,
b: 2,
};
}
}

View File

@ -0,0 +1,40 @@
import { DemoGoodsEntity } from './../entity/goods';
import { Provide } from '@midwayjs/core';
import { BaseService } from '@cool-midway/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';
/**
*
*/
@Provide()
export class DemoGoodsService extends BaseService {
@InjectEntityModel(DemoGoodsEntity)
demoGoodsEntity: Repository<DemoGoodsEntity>;
/**
* sql分页
*/
async sqlPage(query) {
await this.demoGoodsEntity.save({
id: 1,
title: '标题',
price: 99.0,
description: '商品描述',
mainImage: 'https://cool-js.com/logo.png',
});
return this.sqlRenderPage(
'select * from demo_goods ORDER BY id ASC',
query,
false
);
}
/**
* entity分页
*/
async entityPage(query) {
const find = this.demoGoodsEntity.createQueryBuilder();
return this.entityRenderPage(find, query);
}
}

View File

@ -0,0 +1,70 @@
import { App, Provide } from '@midwayjs/core';
import { DemoGoodsEntity } from '../entity/goods';
import { IMidwayApplication, Inject } from '@midwayjs/core';
import {
BaseRpcService,
CoolRpc,
CoolRpcService,
CoolRpcTransaction,
} from '@cool-midway/rpc';
import { QueryRunner } from 'typeorm';
@Provide()
@CoolRpcService({
entity: DemoGoodsEntity,
method: ['info', 'add', 'page'],
})
export class DemoRpcService extends BaseRpcService {
@App()
app: IMidwayApplication;
@Inject()
rpc: CoolRpc;
/**
*
* @returns
*/
async call() {
return await this.rpc.call('goods', 'demoGoodsService', 'test', {
a: 1,
});
}
/**
*
*/
async event() {
this.rpc.event('test', { a: 1 });
}
async info(params) {
return params;
}
async getUser() {
return {
uid: '123',
username: 'mockedName',
phone: '12345678901',
email: 'xxx.xxx@xxx.com',
};
}
@CoolRpcTransaction()
async transaction(params, rpcTransactionId?, queryRunner?: QueryRunner) {
console.log('获得的参数', params);
const data = {
title: '商品标题',
pic: 'https://xxx',
price: 99.0,
type: 1,
};
await queryRunner.manager.save(DemoGoodsEntity, data);
// 将事务id传给调用的远程服务方法
await this.rpc.call('goods', 'demoGoodsService', 'transaction', {
rpcTransactionId,
...params,
});
}
}

View File

@ -0,0 +1,23 @@
import { DemoGoodsEntity } from './../entity/goods';
import { Provide } from '@midwayjs/core';
import { BaseService, CoolTransaction } from '@cool-midway/core';
import { QueryRunner } from 'typeorm';
/**
*
*/
@Provide()
export class DemoTransactionService extends BaseService {
/**
*
*/
@CoolTransaction({
connectionName: 'default',
})
async add(param, queryRunner?: QueryRunner) {
await queryRunner.manager.insert<DemoGoodsEntity>(DemoGoodsEntity, param);
return {
id: param.id,
};
}
}

View File

@ -24,7 +24,7 @@ export class SwaggerBuilder {
*/ */
async init() { async init() {
if (this.epsConfig) { if (this.epsConfig) {
await this.build(); this.build();
} }
} }
@ -257,6 +257,21 @@ export class SwaggerBuilder {
}, },
], ],
tags: [moduleName || '其他'], tags: [moduleName || '其他'],
requestBody:
method == 'post'
? {
description: '请求体',
required: true,
content: {
'application/json': {
schema: {
type: 'object',
properties: {},
},
},
},
}
: {},
responses: schemas responses: schemas
? { ? {
'200': { '200': {