perf: 通知管理

This commit is contained in:
xiaojunnuo
2024-11-22 17:12:39 +08:00
parent 131ed13df1
commit d9a00eeaf7
30 changed files with 1031 additions and 30 deletions
@@ -0,0 +1,91 @@
import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
import { Constants, CrudController } from '@certd/lib-server';
import { NotificationService } from '../../modules/pipeline/service/notification-service.js';
import { AuthService } from '../../modules/sys/authority/service/auth-service.js';
/**
* 通知
*/
@Provide()
@Controller('/api/pi/notification')
export class NotificationController extends CrudController<NotificationService> {
@Inject()
service: NotificationService;
@Inject()
authService: AuthService;
getService(): NotificationService {
return this.service;
}
@Post('/page', { summary: Constants.per.authOnly })
async page(@Body(ALL) body) {
body.query = body.query ?? {};
delete body.query.userId;
const buildQuery = qb => {
qb.andWhere('user_id = :userId', { userId: this.getUserId() });
};
const res = await this.service.page({
query: body.query,
page: body.page,
sort: body.sort,
buildQuery,
});
return this.ok(res);
}
@Post('/list', { summary: Constants.per.authOnly })
async list(@Body(ALL) body) {
body.userId = this.getUserId();
return super.list(body);
}
@Post('/add', { summary: Constants.per.authOnly })
async add(@Body(ALL) bean) {
bean.userId = this.getUserId();
return super.add(bean);
}
@Post('/update', { summary: Constants.per.authOnly })
async update(@Body(ALL) bean) {
await this.service.checkUserId(bean.id, this.getUserId());
return super.update(bean);
}
@Post('/info', { summary: Constants.per.authOnly })
async info(@Query('id') id: number) {
await this.service.checkUserId(id, this.getUserId());
return super.info(id);
}
@Post('/delete', { summary: Constants.per.authOnly })
async delete(@Query('id') id: number) {
await this.service.checkUserId(id, this.getUserId());
return super.delete(id);
}
@Post('/define', { summary: Constants.per.authOnly })
async define(@Query('type') type: string) {
const notification = this.service.getDefineByType(type);
return this.ok(notification);
}
@Post('/getTypeDict', { summary: Constants.per.authOnly })
async getTypeDict() {
const list = this.service.getDefineList();
const dict = [];
for (const item of list) {
dict.push({
value: item.name,
label: item.title,
});
}
return this.ok(dict);
}
@Post('/simpleInfo', { summary: Constants.per.authOnly })
async simpleInfo(@Query('id') id: number) {
await this.authService.checkEntityUserId(this.ctx, this.service, id);
const res = await this.service.getSimpleInfo(id);
return this.ok(res);
}
}
@@ -0,0 +1,32 @@
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
@Entity('pi_notification')
export class NotificationEntity {
@PrimaryGeneratedColumn()
id: number;
@Column({ name: 'user_id', comment: 'UserId' })
userId: string;
@Column({ name: 'type', comment: '通知类型' })
type: string;
@Column({ name: 'name', comment: '名称' })
name: string;
@Column({ name: 'setting', comment: '通知配置', length: 10240 })
setting: string;
@Column({
name: 'create_time',
comment: '创建时间',
default: () => 'CURRENT_TIMESTAMP',
})
createTime: Date;
@Column({
name: 'update_time',
comment: '修改时间',
default: () => 'CURRENT_TIMESTAMP',
})
updateTime: Date;
}
@@ -0,0 +1,38 @@
import { Provide, Scope, ScopeEnum } from '@midwayjs/core';
import { BaseService, ValidateException } from '@certd/lib-server';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';
import { NotificationEntity } from '../entity/notification.js';
import { notificationRegistry } from '@certd/pipeline';
@Provide()
@Scope(ScopeEnum.Singleton)
export class NotificationService extends BaseService<NotificationEntity> {
@InjectEntityModel(NotificationEntity)
repository: Repository<NotificationEntity>;
//@ts-ignore
getRepository() {
return this.repository;
}
async getSimpleInfo(id: number) {
const entity = await this.info(id);
if (entity == null) {
throw new ValidateException('该通知配置不存在,请确认是否已被删除');
}
return {
id: entity.id,
name: entity.name,
userId: entity.userId,
};
}
getDefineList() {
return notificationRegistry.getDefineList();
}
getDefineByType(type: string) {
return notificationRegistry.getDefine(type);
}
}
@@ -0,0 +1,30 @@
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from '@certd/pipeline';
@IsNotification({
name: 'email',
title: '电子邮件',
desc: '电子邮件通知',
})
export class EmailNotification extends BaseNotification {
@NotificationInput({
title: '收件人邮箱',
component: {
name: 'a-select',
vModel: 'value',
mode: 'tags',
open: false,
},
required: true,
helper: '可以填写多个,填写一个按回车键再填写下一个',
})
receivers!: string[];
async send(body: NotificationBody) {
await this.ctx.emailService.send({
userId: body.userId,
subject: body.title,
content: body.content,
receivers: this.receivers,
});
}
}
@@ -0,0 +1,2 @@
export * from './qywx/index.js';
export * from './email/index.js';
@@ -0,0 +1,54 @@
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from '@certd/pipeline';
@IsNotification({
name: 'qywx',
title: '企业微信通知',
desc: '企业微信群聊机器人通知',
})
export class QywxNotification extends BaseNotification {
@NotificationInput({
title: 'webhook地址',
component: {
placeholder: 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxx',
},
required: true,
})
webhook = '';
@NotificationInput({
title: '提醒指定成员',
component: {
name: 'a-select',
vModel: 'value',
mode: 'tags',
open: false,
},
required: false,
helper: '填写成员名字,@all 为提醒所有人',
})
mentionedList!: string[];
async send(body: NotificationBody) {
console.log('send qywx');
/**
*
* "msgtype": "text",
* "text": {
* "content": "hello world"
* }
* }
*/
await this.http.request({
url: this.webhook,
data: {
msgtype: 'markdown',
text: {
content: `# ${body.title}\n\n${body.content}\n[查看详情](${body.url})`,
mentioned_list: this.mentionedList,
},
},
});
}
}