mirror of
https://github.com/cool-team-official/cool-admin-midway.git
synced 2025-12-31 14:38:17 +00:00
动态配置,无需重启
This commit is contained in:
parent
04ab0562e1
commit
5563a4adbf
10
package.json
10
package.json
@ -12,13 +12,11 @@
|
||||
"egg-view-nunjucks": "^2.3.0",
|
||||
"ipip-ipdb": "^0.3.0",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"lodash": "^4.17.21",
|
||||
"md5": "^2.3.0",
|
||||
"midwayjs-cool-alipay": "^1.0.1",
|
||||
"midwayjs-cool-core": "^3.0.16",
|
||||
"midwayjs-cool-oss": "^1.0.10",
|
||||
"midwayjs-cool-queue": "^1.0.3",
|
||||
"midwayjs-cool-redis": "^1.0.6",
|
||||
"midwayjs-cool-wxpay": "^1.0.7",
|
||||
"midwayjs-cool-core": "/Users/ap/Documents/srcs/cool-admin/midway-core/core/dist",
|
||||
"midwayjs-cool-redis": "/Users/ap/Documents/srcs/cool-admin/midway-core/redis/dist",
|
||||
"midwayjs-cool-wxpay": "^1.0.10",
|
||||
"mysql2": "^2.2.5",
|
||||
"svg-captcha": "^1.4.0",
|
||||
"svg-to-dataurl": "^1.0.0"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { Provide, Inject, Get, Post, Body, ALL } from '@midwayjs/decorator';
|
||||
import { Context } from 'egg';
|
||||
import { CoolController, BaseController, CoolFile } from 'midwayjs-cool-core';
|
||||
import { CoolController, BaseController, ICoolFile } from 'midwayjs-cool-core';
|
||||
import { BaseSysUserEntity } from '../../entity/sys/user';
|
||||
import { BaseSysLoginService } from '../../service/sys/login';
|
||||
import { BaseSysPermsService } from '../../service/sys/perms';
|
||||
@ -25,7 +25,7 @@ export class BaseCommController extends BaseController {
|
||||
ctx: Context;
|
||||
|
||||
@Inject('cool:file')
|
||||
coolFile: CoolFile;
|
||||
coolFile: ICoolFile;
|
||||
|
||||
/**
|
||||
* 获得个人信息
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { Inject, Provide } from '@midwayjs/decorator';
|
||||
import { BaseService, CoolCache, CoolPlugin } from 'midwayjs-cool-core';
|
||||
import { BaseService, ICoolCache, CoolPlugin } from 'midwayjs-cool-core';
|
||||
|
||||
/**
|
||||
* 插件
|
||||
@ -10,7 +10,7 @@ export class BasePluginInfoService extends BaseService {
|
||||
coolPlugin: CoolPlugin;
|
||||
|
||||
@Inject('cool:cache')
|
||||
coolCache: CoolCache;
|
||||
coolCache: ICoolCache;
|
||||
|
||||
/**
|
||||
* 列表
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { Inject, Provide, Config } from '@midwayjs/decorator';
|
||||
import {
|
||||
BaseService,
|
||||
CoolCache,
|
||||
ICoolCache,
|
||||
CoolCommException,
|
||||
CoolConfig,
|
||||
RESCODE,
|
||||
@ -27,7 +27,7 @@ import { Context } from 'egg';
|
||||
@Provide()
|
||||
export class BaseSysLoginService extends BaseService {
|
||||
@Inject('cool:cache')
|
||||
coolCache: CoolCache;
|
||||
coolCache: ICoolCache;
|
||||
|
||||
@InjectEntityModel(BaseSysUserEntity)
|
||||
baseSysUserEntity: Repository<BaseSysUserEntity>;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { Inject, Provide } from '@midwayjs/decorator';
|
||||
import { BaseService, CoolCache } from 'midwayjs-cool-core';
|
||||
import { BaseService, ICoolCache } from 'midwayjs-cool-core';
|
||||
import { InjectEntityModel } from '@midwayjs/orm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { BaseSysParamEntity } from '../../entity/sys/param';
|
||||
@ -13,7 +13,7 @@ export class BaseSysParamService extends BaseService {
|
||||
baseSysParamEntity: Repository<BaseSysParamEntity>;
|
||||
|
||||
@Inject('cool:cache')
|
||||
coolCache: CoolCache;
|
||||
coolCache: ICoolCache;
|
||||
|
||||
/**
|
||||
* 根据key获得对应的参数
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { Inject, Provide } from '@midwayjs/decorator';
|
||||
import { BaseService, CoolCache } from 'midwayjs-cool-core';
|
||||
import { BaseService, ICoolCache } from 'midwayjs-cool-core';
|
||||
import { BaseSysMenuService } from './menu';
|
||||
import { BaseSysRoleService } from './role';
|
||||
import { BaseSysDepartmentService } from './department';
|
||||
@ -11,7 +11,7 @@ import { Context } from 'egg';
|
||||
@Provide()
|
||||
export class BaseSysPermsService extends BaseService {
|
||||
@Inject('cool:cache')
|
||||
coolCache: CoolCache;
|
||||
coolCache: ICoolCache;
|
||||
|
||||
@Inject()
|
||||
baseSysMenuService: BaseSysMenuService;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { Inject, Provide } from '@midwayjs/decorator';
|
||||
import { BaseService, CoolCache, CoolCommException } from 'midwayjs-cool-core';
|
||||
import { BaseService, ICoolCache, CoolCommException } from 'midwayjs-cool-core';
|
||||
import { InjectEntityModel } from '@midwayjs/orm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { BaseSysUserEntity } from '../../entity/sys/user';
|
||||
@ -24,7 +24,7 @@ export class BaseSysUserService extends BaseService {
|
||||
baseSysDepartmentEntity: Repository<BaseSysDepartmentEntity>;
|
||||
|
||||
@Inject('cool:cache')
|
||||
coolCache: CoolCache;
|
||||
coolCache: ICoolCache;
|
||||
|
||||
@Inject()
|
||||
baseSysPermsService: BaseSysPermsService;
|
||||
|
||||
@ -13,4 +13,4 @@ export default (app: Application) => {
|
||||
// 中间件
|
||||
middlewares: [],
|
||||
} as ModuleConfig;
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { Inject, Post, Provide } from '@midwayjs/decorator';
|
||||
import { App, Inject, Post, Provide } from '@midwayjs/decorator';
|
||||
import { IMidwayWebApplication } from '@midwayjs/web';
|
||||
import { Context } from 'egg';
|
||||
import { CoolController, BaseController } from 'midwayjs-cool-core';
|
||||
import { ICoolWxPay } from 'midwayjs-cool-wxpay';
|
||||
@ -11,19 +12,24 @@ import { parseString } from 'xml2js';
|
||||
@CoolController()
|
||||
export class DemoPayController extends BaseController {
|
||||
// 微信支付
|
||||
@Inject()
|
||||
wxpay: ICoolWxPay;
|
||||
@Inject('wxpay:sdk')
|
||||
wxPay: ICoolWxPay;
|
||||
|
||||
@Inject()
|
||||
ctx: Context;
|
||||
|
||||
@App()
|
||||
app: IMidwayWebApplication;
|
||||
|
||||
/**
|
||||
* 扫码支付
|
||||
*/
|
||||
@Post('/wx')
|
||||
async wx() {
|
||||
const orderNum = await this.wxpay.createOrderNum();
|
||||
const data = await this.wxpay.getInstance().unifiedOrder({
|
||||
// const a = this.app.getApplicationContext().registry.keys();
|
||||
// console.log(a);
|
||||
const orderNum = await this.wxPay.createOrderNum();
|
||||
const data = await this.wxPay.getInstance().unifiedOrder({
|
||||
out_trade_no: orderNum,
|
||||
body: '测试微信支付',
|
||||
total_fee: 1,
|
||||
@ -49,7 +55,7 @@ export class DemoPayController extends BaseController {
|
||||
if (err) {
|
||||
return reject('success');
|
||||
}
|
||||
const checkSign = await this.wxpay.signVerify(json.xml);
|
||||
const checkSign = await this.wxPay.signVerify(json.xml);
|
||||
if (checkSign && json.xml.result_code === 'SUCCESS') {
|
||||
// 处理业务逻辑
|
||||
console.log('微信支付成功', json.xml);
|
||||
|
||||
@ -1,14 +0,0 @@
|
||||
import { Provide } from '@midwayjs/decorator';
|
||||
import { ICoolQueue, Queue } from 'midwayjs-cool-queue';
|
||||
|
||||
/**
|
||||
* 队列
|
||||
*/
|
||||
@Queue()
|
||||
@Provide()
|
||||
export abstract class DemoOrderQueue implements ICoolQueue {
|
||||
data(job: any, done: any): void {
|
||||
console.log('收到的数据', job.data);
|
||||
done();
|
||||
}
|
||||
}
|
||||
@ -1,16 +0,0 @@
|
||||
import { Application } from 'egg';
|
||||
import { ModuleConfig } from 'midwayjs-cool-core';
|
||||
|
||||
/**
|
||||
* 模块配置
|
||||
*/
|
||||
export default (app: Application) => {
|
||||
return {
|
||||
// 模块名称
|
||||
name: '任务调度',
|
||||
// 模块描述
|
||||
description: '任务调度模块,支持分布式任务,由redis整个集群的任务',
|
||||
// 中间件
|
||||
middlewares: [],
|
||||
} as ModuleConfig;
|
||||
};
|
||||
@ -1,64 +0,0 @@
|
||||
import {
|
||||
ALL,
|
||||
Body,
|
||||
Get,
|
||||
Inject,
|
||||
Post,
|
||||
Provide,
|
||||
Query,
|
||||
} from '@midwayjs/decorator';
|
||||
import { CoolController, BaseController } from 'midwayjs-cool-core';
|
||||
import { TaskInfoEntity } from '../../entity/info';
|
||||
import { TaskInfoService } from '../../service/info';
|
||||
|
||||
/**
|
||||
* 任务
|
||||
*/
|
||||
@Provide()
|
||||
@CoolController({
|
||||
api: ['add', 'delete', 'update', 'info', 'page'],
|
||||
entity: TaskInfoEntity,
|
||||
service: TaskInfoService,
|
||||
pageQueryOp: {
|
||||
fieldEq: ['status', 'type'],
|
||||
},
|
||||
})
|
||||
export class TaskInfoController extends BaseController {
|
||||
@Inject()
|
||||
taskInfoService: TaskInfoService;
|
||||
|
||||
/**
|
||||
* 手动执行一次
|
||||
*/
|
||||
@Post('/once')
|
||||
async once(@Body() id: number) {
|
||||
await this.taskInfoService.once(id);
|
||||
this.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 暂停任务
|
||||
*/
|
||||
@Post('/stop')
|
||||
async stop(@Body() id: number) {
|
||||
await this.taskInfoService.stop(id);
|
||||
this.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始任务
|
||||
*/
|
||||
@Post('/start')
|
||||
async start(@Body() id: number, @Body() type: number) {
|
||||
await this.taskInfoService.start(id, type);
|
||||
this.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 日志
|
||||
*/
|
||||
@Get('/log')
|
||||
async log(@Query(ALL) params: any) {
|
||||
return this.ok(await this.taskInfoService.log(params));
|
||||
}
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
编写接口
|
||||
@ -1,57 +0,0 @@
|
||||
import { EntityModel } from '@midwayjs/orm';
|
||||
import { BaseEntity } from 'midwayjs-cool-core';
|
||||
import { Column } from 'typeorm';
|
||||
|
||||
/**
|
||||
* 任务信息
|
||||
*/
|
||||
@EntityModel('task_info')
|
||||
export class TaskInfoEntity extends BaseEntity {
|
||||
@Column({ comment: '任务ID', nullable: true })
|
||||
jobId: string;
|
||||
|
||||
@Column({ comment: '任务配置', nullable: true, length: 1000 })
|
||||
repeatConf: string;
|
||||
|
||||
@Column({ comment: '名称' })
|
||||
name: string;
|
||||
|
||||
@Column({ comment: 'cron', nullable: true })
|
||||
cron: string;
|
||||
|
||||
@Column({ comment: '最大执行次数 不传为无限次', nullable: true })
|
||||
limitCount: number;
|
||||
|
||||
@Column({
|
||||
comment: '每间隔多少毫秒执行一次 如果cron设置了 这项设置就无效',
|
||||
nullable: true,
|
||||
})
|
||||
every: number;
|
||||
|
||||
@Column({ comment: '备注', nullable: true })
|
||||
remark: string;
|
||||
|
||||
@Column({ comment: '状态 0:停止 1:运行', default: 1, type: 'tinyint' })
|
||||
status: number;
|
||||
|
||||
@Column({ comment: '开始时间', nullable: true })
|
||||
startDate: Date;
|
||||
|
||||
@Column({ comment: '结束时间', nullable: true })
|
||||
endDate: Date;
|
||||
|
||||
@Column({ comment: '数据', nullable: true })
|
||||
data: string;
|
||||
|
||||
@Column({ comment: '执行的service实例ID', nullable: true })
|
||||
service: string;
|
||||
|
||||
@Column({ comment: '状态 0:系统 1:用户', default: 0, type: 'tinyint' })
|
||||
type: number;
|
||||
|
||||
@Column({ comment: '下一次执行时间', nullable: true })
|
||||
nextRunTime: Date;
|
||||
|
||||
@Column({ comment: '状态 0:cron 1:时间间隔', default: 0, type: 'tinyint' })
|
||||
taskType: number;
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
import { EntityModel } from '@midwayjs/orm';
|
||||
import { BaseEntity } from 'midwayjs-cool-core';
|
||||
import { Column, Index } from 'typeorm';
|
||||
|
||||
/**
|
||||
* 任务日志
|
||||
*/
|
||||
@EntityModel('task_log')
|
||||
export class TaskLogEntity extends BaseEntity {
|
||||
@Index()
|
||||
@Column({ comment: '任务ID', nullable: true, type: 'bigint' })
|
||||
taskId: number;
|
||||
|
||||
@Column({ comment: '状态 0:失败 1:成功', default: 0, type: 'tinyint' })
|
||||
status: number;
|
||||
|
||||
@Column({ comment: '详情描述', nullable: true, type: 'text' })
|
||||
detail: string;
|
||||
}
|
||||
@ -1,99 +0,0 @@
|
||||
/*
|
||||
Navicat Premium Data Transfer
|
||||
|
||||
Source Server : localhost_3306
|
||||
Source Server Type : MySQL
|
||||
Source Server Version : 50725
|
||||
Source Host : localhost:3306
|
||||
Source Schema : cool
|
||||
|
||||
Target Server Type : MySQL
|
||||
Target Server Version : 50725
|
||||
File Encoding : 65001
|
||||
|
||||
Date: 05/03/2021 16:41:26
|
||||
*/
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for task_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `task_info`;
|
||||
CREATE TABLE `task_info` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
|
||||
`createTime` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间',
|
||||
`updateTime` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) COMMENT '更新时间',
|
||||
`repeatConf` varchar(1000) DEFAULT NULL COMMENT '任务配置',
|
||||
`name` varchar(255) NOT NULL COMMENT '名称',
|
||||
`cron` varchar(255) DEFAULT NULL COMMENT 'cron',
|
||||
`limitCount` int(11) DEFAULT NULL COMMENT '最大执行次数 不传为无限次',
|
||||
`every` int(11) DEFAULT NULL COMMENT '每间隔多少毫秒执行一次 如果cron设置了 这项设置就无效',
|
||||
`remark` varchar(255) DEFAULT NULL COMMENT '备注',
|
||||
`status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '状态 0:停止 1:运行',
|
||||
`startDate` datetime DEFAULT NULL COMMENT '开始时间',
|
||||
`endDate` datetime DEFAULT NULL COMMENT '结束时间',
|
||||
`data` varchar(255) DEFAULT NULL COMMENT '数据',
|
||||
`service` varchar(255) DEFAULT NULL COMMENT '执行的service实例ID',
|
||||
`type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '状态 0:系统 1:用户',
|
||||
`nextRunTime` datetime DEFAULT NULL COMMENT '下一次执行时间',
|
||||
`taskType` tinyint(4) NOT NULL DEFAULT '0' COMMENT '状态 0:cron 1:时间间隔',
|
||||
`jobId` varchar(255) DEFAULT NULL COMMENT '任务ID',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `IDX_6ced02f467e59bd6306b549bb0` (`createTime`),
|
||||
KEY `IDX_2adc6f9c241391126f27dac145` (`updateTime`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of task_info
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `task_info` VALUES (1, '2021-03-05 11:46:24.000000', '2021-03-05 16:33:44.081230', '{\"count\":1,\"id\":1,\"createTime\":\"2021-03-05 11:46:24\",\"updateTime\":\"2021-03-05 16:33:37\",\"jobId\":1,\"name\":\"测试\",\"every\":1000,\"status\":1,\"service\":\"demoOrderService.test()\",\"type\":\"0\",\"taskType\":1}', '测试', NULL, NULL, 1000, NULL, 0, NULL, NULL, NULL, 'demoOrderService.test()', 0, NULL, 1, 'repeat:73bac7c57dd4c1ffd6dc41c3c3cb40e1:1614932670000');
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for task_log
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `task_log`;
|
||||
CREATE TABLE `task_log` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
|
||||
`createTime` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间',
|
||||
`updateTime` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) COMMENT '更新时间',
|
||||
`taskId` bigint(20) DEFAULT NULL COMMENT '任务ID',
|
||||
`status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '状态 0:失败 1:成功',
|
||||
`detail` text COMMENT '详情描述',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `IDX_b9af0e100be034924b270aab31` (`createTime`),
|
||||
KEY `IDX_8857d8d43d38bebd7159af1fa6` (`updateTime`),
|
||||
KEY `IDX_1142dfec452e924b346f060fda` (`taskId`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=541 DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of task_log
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `task_log` VALUES (521, '2021-03-05 16:32:09.017824', '2021-03-05 16:32:09.017824', 1, 1, '');
|
||||
INSERT INTO `task_log` VALUES (522, '2021-03-05 16:32:10.015478', '2021-03-05 16:32:10.015478', 1, 1, '');
|
||||
INSERT INTO `task_log` VALUES (523, '2021-03-05 16:32:11.017549', '2021-03-05 16:32:11.017549', 1, 1, '');
|
||||
INSERT INTO `task_log` VALUES (524, '2021-03-05 16:32:12.015647', '2021-03-05 16:32:12.015647', 1, 1, '');
|
||||
INSERT INTO `task_log` VALUES (525, '2021-03-05 16:32:35.349964', '2021-03-05 16:32:35.349964', 1, 1, '');
|
||||
INSERT INTO `task_log` VALUES (526, '2021-03-05 16:33:22.020797', '2021-03-05 16:33:22.020797', 1, 1, '');
|
||||
INSERT INTO `task_log` VALUES (527, '2021-03-05 16:33:23.015415', '2021-03-05 16:33:23.015415', 1, 1, '');
|
||||
INSERT INTO `task_log` VALUES (528, '2021-03-05 16:33:24.013962', '2021-03-05 16:33:24.013962', 1, 1, '');
|
||||
INSERT INTO `task_log` VALUES (529, '2021-03-05 16:33:29.017289', '2021-03-05 16:33:29.017289', 1, 1, '');
|
||||
INSERT INTO `task_log` VALUES (530, '2021-03-05 16:33:30.014388', '2021-03-05 16:33:30.014388', 1, 1, '');
|
||||
INSERT INTO `task_log` VALUES (531, '2021-03-05 16:33:31.019317', '2021-03-05 16:33:31.019317', 1, 1, '');
|
||||
INSERT INTO `task_log` VALUES (532, '2021-03-05 16:33:32.016401', '2021-03-05 16:33:32.016401', 1, 1, '');
|
||||
INSERT INTO `task_log` VALUES (533, '2021-03-05 16:33:33.014518', '2021-03-05 16:33:33.014518', 1, 1, '');
|
||||
INSERT INTO `task_log` VALUES (534, '2021-03-05 16:33:38.019010', '2021-03-05 16:33:38.019010', 1, 1, '');
|
||||
INSERT INTO `task_log` VALUES (535, '2021-03-05 16:33:39.015834', '2021-03-05 16:33:39.015834', 1, 1, '');
|
||||
INSERT INTO `task_log` VALUES (536, '2021-03-05 16:33:40.015489', '2021-03-05 16:33:40.015489', 1, 1, '');
|
||||
INSERT INTO `task_log` VALUES (537, '2021-03-05 16:33:41.013458', '2021-03-05 16:33:41.013458', 1, 1, '');
|
||||
INSERT INTO `task_log` VALUES (538, '2021-03-05 16:33:42.015814', '2021-03-05 16:33:42.015814', 1, 1, '');
|
||||
INSERT INTO `task_log` VALUES (539, '2021-03-05 16:33:43.014712', '2021-03-05 16:33:43.014712', 1, 1, '');
|
||||
INSERT INTO `task_log` VALUES (540, '2021-03-05 16:33:44.014487', '2021-03-05 16:33:44.014487', 1, 1, '');
|
||||
COMMIT;
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
@ -1,30 +0,0 @@
|
||||
import { App, Inject, Provide } from '@midwayjs/decorator';
|
||||
import { IMidwayWebApplication } from '@midwayjs/web';
|
||||
import { ICoolQueue, Queue } from 'midwayjs-cool-queue';
|
||||
import { TaskInfoService } from '../service/info';
|
||||
|
||||
/**
|
||||
* 任务
|
||||
*/
|
||||
@Queue()
|
||||
@Provide()
|
||||
export abstract class TaskInfoQueue implements ICoolQueue {
|
||||
@App()
|
||||
app: IMidwayWebApplication;
|
||||
|
||||
@Inject()
|
||||
taskInfoService: TaskInfoService;
|
||||
|
||||
async data(job: any, done: any): Promise<void> {
|
||||
try {
|
||||
console.log('收到的数据', job.data);
|
||||
const result = await this.taskInfoService.invokeService(job.data.service);
|
||||
this.taskInfoService.record(job.data, 1, JSON.stringify(result));
|
||||
} catch (error) {
|
||||
this.taskInfoService.record(job.data, 0, error);
|
||||
}
|
||||
this.taskInfoService.updateNextRunTime(job.data.id);
|
||||
this.taskInfoService.updateStatus();
|
||||
done();
|
||||
}
|
||||
}
|
||||
@ -1,306 +0,0 @@
|
||||
import { App, Inject, Logger, Provide } from '@midwayjs/decorator';
|
||||
import { BaseService } from 'midwayjs-cool-core';
|
||||
import { InjectEntityModel } from '@midwayjs/orm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { TaskInfoEntity } from '../entity/info';
|
||||
import { TaskLogEntity } from '../entity/log';
|
||||
import { IQueue } from 'midwayjs-cool-queue';
|
||||
import { ILogger } from '@midwayjs/logger';
|
||||
import { IMidwayWebApplication } from '@midwayjs/web';
|
||||
import * as _ from 'lodash';
|
||||
import { Utils } from '../../../comm/utils';
|
||||
|
||||
/**
|
||||
* 任务
|
||||
*/
|
||||
@Provide()
|
||||
export class TaskInfoService extends BaseService {
|
||||
@InjectEntityModel(TaskInfoEntity)
|
||||
taskInfoEntity: Repository<TaskInfoEntity>;
|
||||
|
||||
@Logger()
|
||||
logger: ILogger;
|
||||
|
||||
@InjectEntityModel(TaskLogEntity)
|
||||
taskLogEntity: Repository<TaskLogEntity>;
|
||||
|
||||
@Inject()
|
||||
taskInfoQueue: IQueue;
|
||||
|
||||
@App()
|
||||
app: IMidwayWebApplication;
|
||||
|
||||
@Inject()
|
||||
utils: Utils;
|
||||
|
||||
/**
|
||||
* 停止任务
|
||||
* @param id
|
||||
*/
|
||||
async stop(id) {
|
||||
const task = await this.taskInfoEntity.findOne({ id });
|
||||
if (task) {
|
||||
const job = await this.exist(task.id);
|
||||
if (job) {
|
||||
await this.taskInfoQueue.queue.removeRepeatable(
|
||||
JSON.parse(task.repeatConf)
|
||||
);
|
||||
}
|
||||
task.status = 0;
|
||||
await this.taskInfoEntity.update(task.id, task);
|
||||
await this.updateNextRunTime(task.id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始任务
|
||||
* @param id
|
||||
* @param type
|
||||
*/
|
||||
async start(id, type?) {
|
||||
const task = await this.taskInfoEntity.findOne({ id });
|
||||
task.status = 1;
|
||||
if (type) {
|
||||
task.type = type;
|
||||
}
|
||||
await this.addOrUpdate(task);
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动执行一次
|
||||
* @param id
|
||||
*/
|
||||
async once(id) {
|
||||
const task = await this.taskInfoEntity.findOne({ id });
|
||||
if (task) {
|
||||
await this.taskInfoQueue.queue.add(task, {
|
||||
jobId: task.id,
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查任务是否存在
|
||||
* @param jobId
|
||||
*/
|
||||
async exist(jobId) {
|
||||
const result = await this.taskInfoQueue.queue.getRepeatableJobs();
|
||||
const ids = result.map(e => {
|
||||
return e.id;
|
||||
});
|
||||
return ids.includes(jobId.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增或修改
|
||||
* @param params
|
||||
*/
|
||||
async addOrUpdate(params) {
|
||||
let repeatConf;
|
||||
await this.getOrmManager().transaction(async transactionalEntityManager => {
|
||||
if (params.taskType === 0) {
|
||||
params.limitCount = null;
|
||||
params.every = null;
|
||||
} else {
|
||||
params.cron = null;
|
||||
}
|
||||
await transactionalEntityManager.save(TaskInfoEntity, params);
|
||||
|
||||
if (params.status === 1) {
|
||||
const exist = await this.exist(params.id);
|
||||
if (exist) {
|
||||
await this.taskInfoQueue.queue.removeRepeatable(
|
||||
JSON.parse(params.repeatConf)
|
||||
);
|
||||
}
|
||||
const jobOp = Object.assign(params);
|
||||
await this.utils.removeEmptyP(jobOp);
|
||||
delete jobOp.repeatConf;
|
||||
const { opts } = await this.taskInfoQueue.queue.add(params, {
|
||||
jobId: params.id,
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
repeat: jobOp,
|
||||
});
|
||||
if (!opts) {
|
||||
throw new Error('任务添加失败,可能由于格式不正确~');
|
||||
}
|
||||
// await transactionalEntityManager.update(TaskInfoEntity, params.id, {
|
||||
// jobId: opts.jobId,
|
||||
// });
|
||||
repeatConf = opts;
|
||||
}
|
||||
});
|
||||
if (params.status === 1) {
|
||||
this.utils.sleep(1000);
|
||||
await this.updateNextRunTime(params.id);
|
||||
await this.nativeQuery(
|
||||
'update task_info a set a.repeatConf = ? where a.id = ?',
|
||||
[JSON.stringify(repeatConf.repeat), params.id]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
* @param ids
|
||||
*/
|
||||
async delete(ids) {
|
||||
let idArr;
|
||||
if (ids instanceof Array) {
|
||||
idArr = ids;
|
||||
} else {
|
||||
idArr = ids.split(',');
|
||||
}
|
||||
for (const id of idArr) {
|
||||
const task = await this.taskInfoEntity.findOne({ id });
|
||||
const exist = await this.exist(task.id);
|
||||
if (exist) {
|
||||
await this.taskInfoQueue.queue.removeRepeatable(
|
||||
JSON.parse(task.repeatConf)
|
||||
);
|
||||
}
|
||||
await this.taskInfoEntity.delete({ id });
|
||||
await this.taskLogEntity.delete({ taskId: id });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务日志
|
||||
* @param query
|
||||
*/
|
||||
async log(query) {
|
||||
const { id, status } = query;
|
||||
return await this.sqlRenderPage(
|
||||
`
|
||||
SELECT
|
||||
a.*,
|
||||
b.NAME AS taskName
|
||||
FROM
|
||||
task_log a
|
||||
JOIN task_info b ON a.taskId = b.id
|
||||
where 1=1
|
||||
${this.setSql(id, 'and a.taskId = ?', [id])}
|
||||
${this.setSql(status, 'and a.status = ?', [status])}
|
||||
`,
|
||||
query
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存任务记录,成功任务每个任务保留最新20条日志,失败日志不会删除
|
||||
* @param task
|
||||
* @param status
|
||||
* @param detail
|
||||
*/
|
||||
async record(task, status, detail?) {
|
||||
await this.taskLogEntity.save({
|
||||
taskId: task.id,
|
||||
status,
|
||||
detail: detail || '',
|
||||
});
|
||||
await this.nativeQuery(
|
||||
`DELETE a
|
||||
FROM
|
||||
task_log a,
|
||||
( SELECT id FROM task_log where taskId = ? AND status = 1 ORDER BY id DESC LIMIT ?, 1 ) b
|
||||
WHERE
|
||||
a.taskId = ? AND
|
||||
a.status = 1 AND
|
||||
a.id < b.id`,
|
||||
[task.id, 19, task.id]
|
||||
); // 日志保留最新的20条
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化任务
|
||||
*/
|
||||
async initTask() {
|
||||
const runningTasks = await this.taskInfoEntity.find({ status: 1 });
|
||||
if (!_.isEmpty(runningTasks)) {
|
||||
for (const task of runningTasks) {
|
||||
const job = await this.exist(task.id); // 任务已存在就不添加
|
||||
if (!job) {
|
||||
this.logger.info(`init task ${task.name}`);
|
||||
await this.addOrUpdate(task);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务ID
|
||||
* @param jobId
|
||||
*/
|
||||
async getNextRunTime(jobId) {
|
||||
let nextRunTime;
|
||||
const result = await this.taskInfoQueue.queue.getRepeatableJobs();
|
||||
for (const task of result) {
|
||||
if (task.id === jobId.toString()) {
|
||||
nextRunTime = new Date(task.next);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return nextRunTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新下次执行时间
|
||||
* @param jobId
|
||||
*/
|
||||
async updateNextRunTime(jobId) {
|
||||
await this.nativeQuery(
|
||||
'update task_info a set a.nextRunTime = ? where a.id = ?',
|
||||
[await this.getNextRunTime(jobId), jobId]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新任务状态
|
||||
*/
|
||||
async updateStatus() {
|
||||
const result = await this.taskInfoQueue.queue.getRepeatableJobs();
|
||||
for (const job of result) {
|
||||
const task = await this.taskInfoEntity.findOne({ id: job.id });
|
||||
if (task) {
|
||||
setTimeout(async () => {
|
||||
// 2秒后清空任务
|
||||
const nextTime = await this.getNextRunTime(task.id);
|
||||
if (nextTime && nextTime.getTime() <= new Date().getTime() - 999) {
|
||||
this.nativeQuery(
|
||||
'update task_info a set a.status = ?, a.updateTime = ? where a.id = ?',
|
||||
[0, new Date(), task.id]
|
||||
);
|
||||
this.taskInfoQueue.queue.removeRepeatable(
|
||||
JSON.parse(task.repeatConf)
|
||||
);
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用service
|
||||
* @param serviceStr
|
||||
*/
|
||||
async invokeService(serviceStr) {
|
||||
if (serviceStr) {
|
||||
const arr = serviceStr.split('.');
|
||||
const service = await this.app.getApplicationContext().getAsync(arr[0]);
|
||||
for (const child of arr) {
|
||||
if (child.includes('(')) {
|
||||
const lastArr = child.split('(');
|
||||
const param = lastArr[1].replace(')', '');
|
||||
if (!param) {
|
||||
return service[lastArr[0]]();
|
||||
} else {
|
||||
return service[lastArr[0]](JSON.parse(param));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,5 @@
|
||||
import { EggAppConfig, EggAppInfo, PowerPartial } from 'egg';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
|
||||
export type DefaultConfig = PowerPartial<EggAppConfig>;
|
||||
|
||||
@ -33,12 +32,12 @@ export default (appInfo: EggAppInfo) => {
|
||||
buffer: false,
|
||||
};
|
||||
|
||||
// 修改默认的 favicon.ico
|
||||
config.siteFile = {
|
||||
'/favicon.ico': fs.readFileSync(
|
||||
path.join(appInfo.baseDir, 'app/public/favicon.ico')
|
||||
),
|
||||
};
|
||||
// 修改默认的 favicon.ico serverless 环境下无用
|
||||
// config.siteFile = {
|
||||
// '/favicon.ico': fs.readFileSync(
|
||||
// path.join(appInfo.baseDir, 'app/public/favicon.ico')
|
||||
// ),
|
||||
// };
|
||||
|
||||
// 关闭安全校验
|
||||
config.security = {
|
||||
@ -85,7 +84,8 @@ export default (appInfo: EggAppInfo) => {
|
||||
mode: 'file',
|
||||
whitelist: [
|
||||
// images
|
||||
'.jpg', '.jpeg', // image/jpeg
|
||||
'.jpg',
|
||||
'.jpeg', // image/jpeg
|
||||
'.png', // image/png, image/x-png
|
||||
'.gif', // image/gif
|
||||
'.bmp', // image/bmp
|
||||
@ -95,22 +95,27 @@ export default (appInfo: EggAppInfo) => {
|
||||
'.psd',
|
||||
// text
|
||||
'.svg',
|
||||
'.js', '.jsx',
|
||||
'.js',
|
||||
'.jsx',
|
||||
'.json',
|
||||
'.css', '.less',
|
||||
'.html', '.htm',
|
||||
'.css',
|
||||
'.less',
|
||||
'.html',
|
||||
'.htm',
|
||||
'.xml',
|
||||
// tar
|
||||
'.zip',
|
||||
'.gz', '.tgz', '.gzip',
|
||||
'.gz',
|
||||
'.tgz',
|
||||
'.gzip',
|
||||
// video
|
||||
'.mp3',
|
||||
'.mp4',
|
||||
'.avi',
|
||||
// 证书
|
||||
'.p12',
|
||||
'.pem'
|
||||
]
|
||||
'.pem',
|
||||
],
|
||||
};
|
||||
|
||||
// 将egg日志替换成midway
|
||||
|
||||
@ -3,11 +3,11 @@ import { ILifeCycle, IMidwayContainer } from '@midwayjs/core';
|
||||
import { Application } from 'egg';
|
||||
import * as orm from '@midwayjs/orm';
|
||||
import * as cool from 'midwayjs-cool-core';
|
||||
import * as oss from 'midwayjs-cool-oss';
|
||||
import * as redis from 'midwayjs-cool-redis';
|
||||
import * as queue from 'midwayjs-cool-queue';
|
||||
import * as wxpay from 'midwayjs-cool-wxpay';
|
||||
import * as alipay from 'midwayjs-cool-alipay';
|
||||
// import * as oss from 'midwayjs-cool-oss';
|
||||
import * as redis from 'midwayjs-cool-redis';
|
||||
// import * as queue from 'midwayjs-cool-queue';
|
||||
// import * as alipay from 'midwayjs-cool-alipay';
|
||||
// import * as socket from 'midwayjs-cool-socket';
|
||||
|
||||
@Configuration({
|
||||
@ -18,15 +18,15 @@ import * as alipay from 'midwayjs-cool-alipay';
|
||||
// 必须,不可移除, cool-admin 官方组件 https://www.cool-js.com
|
||||
cool,
|
||||
// oss插件,需要到后台配置之后才有用,默认是本地上传
|
||||
oss,
|
||||
//oss,
|
||||
// 将缓存替换成redis
|
||||
redis,
|
||||
// 队列
|
||||
queue,
|
||||
//queue,
|
||||
// 微信支付
|
||||
wxpay,
|
||||
// 支付宝支付
|
||||
alipay
|
||||
//alipay
|
||||
// socket
|
||||
//socket
|
||||
],
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user