diff --git a/package.json b/package.json index 6ef672e..5f3dabb 100755 --- a/package.json +++ b/package.json @@ -1,82 +1,84 @@ { - "name": "cool-admin", - "version": "3.0.0", - "description": "", - "private": true, - "dependencies": { - "@midwayjs/decorator": "^2.7.5", - "@midwayjs/orm": "^1.3.0", - "@midwayjs/web": "^2.7.7", - "egg": "^2.29.3", - "egg-scripts": "^2.13.0", - "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-core": "/Users/ap/Documents/srcs/cool-admin/midway-core/core/dist", - "midwayjs-cool-oss": "/Users/ap/Documents/srcs/cool-admin/midway-core/oss/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" - }, - "devDependencies": { - "@midwayjs/cli": "^1.2.41", - "@midwayjs/cli-plugin-faas": "^1.2.49", - "@midwayjs/egg-ts-helper": "^1.0.5", - "@midwayjs/fcli-plugin-fc": "^1.2.49", - "@midwayjs/luckyeye": "^1.0.2", - "@midwayjs/mock": "^2.7.7", - "@types/jest": "^26.0.20", - "@types/jsonwebtoken": "^8.5.0", - "@types/node": "14", - "cross-env": "^7.0.3", - "jest": "^26.6.3", - "mwts": "^1.1.2", - "ts-jest": "^26.5.2", - "typescript": "^4.2.2" - }, - "engines": { - "node": ">=12.0.0" - }, - "scripts": { - "start": "egg-scripts start --daemon --title=cool-admin-midway --framework=@midwayjs/web --port=8001 --sticky", - "stop": "egg-scripts stop --title=cool-admin-midway", - "start_build": "npm run build && cross-env NODE_ENV=development midway-bin dev", - "docker": "egg-scripts start --title=cool-admin-midway --framework=@midwayjs/web", - "dev": "cross-env ets && cross-env NODE_ENV=local TS_NODE_TYPE_CHECK=false TS_NODE_TRANSPILE_ONLY=true midway-bin dev --ts --port=8001 --sticky", - "test": "midway-bin test", - "cov": "midway-bin cov", - "lint": "mwts check", - "lint:fix": "mwts fix", - "ci": "npm run cov", - "build": "midway-bin build -c", - "check": "luckyeye", - "deploy": "midway-bin deploy" - }, - "midway-bin-clean": [ - ".vscode/.tsbuildinfo", - "dist" - ], - "midway-luckyeye": { - "packages": [ - "midway_v2" - ] - }, - "midway-integration": { - "lifecycle": { - "before:package:cleanup": "npm run build" - } - }, - "egg": { - "framework": "@midwayjs/web" - }, - "repository": { - "type": "git", - "url": "" - }, - "author": "cool-js.com", - "license": "MIT" + "name": "cool-admin", + "version": "3.0.0", + "description": "", + "private": true, + "dependencies": { + "@midwayjs/decorator": "^2.7.5", + "@midwayjs/orm": "^1.3.0", + "@midwayjs/web": "^2.7.7", + "egg": "^2.29.3", + "egg-scripts": "^2.13.0", + "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.3", + "midwayjs-cool-core": "^3.1.1", + "midwayjs-cool-oss": "^1.0.12", + "midwayjs-cool-queue": "^1.0.6", + "midwayjs-cool-redis": "^1.0.9", + "midwayjs-cool-wxpay": "^1.0.12", + "mysql2": "^2.2.5", + "svg-captcha": "^1.4.0", + "svg-to-dataurl": "^1.0.0" + }, + "devDependencies": { + "@midwayjs/cli": "^1.2.41", + "@midwayjs/cli-plugin-faas": "^1.2.49", + "@midwayjs/egg-ts-helper": "^1.0.5", + "@midwayjs/fcli-plugin-fc": "^1.2.49", + "@midwayjs/luckyeye": "^1.0.2", + "@midwayjs/mock": "^2.7.7", + "@types/jest": "^26.0.20", + "@types/jsonwebtoken": "^8.5.0", + "@types/node": "14", + "cross-env": "^7.0.3", + "jest": "^26.6.3", + "mwts": "^1.1.2", + "ts-jest": "^26.5.2", + "typescript": "^4.2.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "scripts": { + "start": "egg-scripts start --daemon --title=cool-admin-midway --framework=@midwayjs/web --port=8001 --sticky", + "stop": "egg-scripts stop --title=cool-admin-midway", + "start_build": "npm run build && cross-env NODE_ENV=development midway-bin dev", + "docker": "egg-scripts start --title=cool-admin-midway --framework=@midwayjs/web", + "dev": "cross-env ets && cross-env NODE_ENV=local TS_NODE_TYPE_CHECK=false TS_NODE_TRANSPILE_ONLY=true midway-bin dev --ts --port=8001 --sticky", + "test": "midway-bin test", + "cov": "midway-bin cov", + "lint": "mwts check", + "lint:fix": "mwts fix", + "ci": "npm run cov", + "build": "midway-bin build -c", + "check": "luckyeye", + "deploy": "midway-bin deploy" + }, + "midway-bin-clean": [ + ".vscode/.tsbuildinfo", + "dist" + ], + "midway-luckyeye": { + "packages": [ + "midway_v2" + ] + }, + "midway-integration": { + "lifecycle": { + "before:package:cleanup": "npm run build" + } + }, + "egg": { + "framework": "@midwayjs/web" + }, + "repository": { + "type": "git", + "url": "" + }, + "author": "cool-js.com", + "license": "MIT" } diff --git a/public/uploads/20210310/58564110-80f6-11eb-b397-8744a989342b.jpg b/public/uploads/20210310/58564110-80f6-11eb-b397-8744a989342b.jpg deleted file mode 100644 index 2bee603..0000000 Binary files a/public/uploads/20210310/58564110-80f6-11eb-b397-8744a989342b.jpg and /dev/null differ diff --git a/public/uploads/20210310/7f62bea0-80f6-11eb-b397-8744a989342b.jpg b/public/uploads/20210310/7f62bea0-80f6-11eb-b397-8744a989342b.jpg deleted file mode 100644 index 559d886..0000000 Binary files a/public/uploads/20210310/7f62bea0-80f6-11eb-b397-8744a989342b.jpg and /dev/null differ diff --git a/public/uploads/20210310/b22e6ff0-80f6-11eb-b397-8744a989342b.png b/public/uploads/20210310/b22e6ff0-80f6-11eb-b397-8744a989342b.png deleted file mode 100644 index f8ff77d..0000000 Binary files a/public/uploads/20210310/b22e6ff0-80f6-11eb-b397-8744a989342b.png and /dev/null differ diff --git a/public/uploads/说明.md b/public/uploads/说明.md deleted file mode 100644 index 22a298f..0000000 --- a/public/uploads/说明.md +++ /dev/null @@ -1 +0,0 @@ -文件上传目录 \ No newline at end of file diff --git a/src/app/modules/base/controller/admin/open.ts b/src/app/modules/base/controller/admin/open.ts index 0455596..920eba3 100644 --- a/src/app/modules/base/controller/admin/open.ts +++ b/src/app/modules/base/controller/admin/open.ts @@ -18,7 +18,7 @@ import { BaseSysParamService } from '../../service/sys/param'; */ @Provide() @CoolController() -export class BaseSysOpenController extends BaseController { +export class BaseOpenController extends BaseController { @Inject() baseSysLoginService: BaseSysLoginService; diff --git a/src/app/modules/base/init.sql b/src/app/modules/base/init.sql index bb81a4e..4a2cba2 100644 --- a/src/app/modules/base/init.sql +++ b/src/app/modules/base/init.sql @@ -1,17 +1,17 @@ /* Navicat Premium Data Transfer - Source Server : localhost_3306 + Source Server : cool-admin-next Source Server Type : MySQL - Source Server Version : 50725 - Source Host : localhost:3306 - Source Schema : cool + Source Server Version : 50727 + Source Host : 139.196.196.203:3306 + Source Schema : cooladmin Target Server Type : MySQL - Target Server Version : 50725 + Target Server Version : 50727 File Encoding : 65001 - Date: 05/03/2021 16:41:26 + Date: 10/03/2021 14:04:34 */ SET NAMES utf8mb4; @@ -31,7 +31,7 @@ CREATE TABLE `base_app_space_info` ( PRIMARY KEY (`id`), KEY `IDX_4aed04cbfa2ecdc01485b86e51` (`createTime`), KEY `IDX_abd5de4a4895eb253a5cabb20f` (`updateTime`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4; -- ---------------------------- -- Table structure for base_app_space_type @@ -125,14 +125,7 @@ CREATE TABLE `base_sys_log` ( KEY `IDX_a03a27f75cf8d502b3060823e1` (`ipAddr`), KEY `IDX_c9382b76219a1011f7b8e7bcd1` (`createTime`), KEY `IDX_bfd44e885b470da43bcc39aaa7` (`updateTime`) -) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4; - --- ---------------------------- --- Records of base_sys_log --- ---------------------------- -BEGIN; -INSERT INTO `base_sys_log` VALUES (1, '2021-03-05 16:41:02.053440', '2021-03-05 16:41:02.053440', 1, '/admin/base/sys/log/page', '117.30.38.56,127.0.0.1, 117.30.115.254', '中国福建厦门,本机地址,中国福建厦门', '{\"page\":1,\"size\":20,\"sort\":\"desc\",\"order\":\"createTime\"}'); -COMMIT; +) ENGINE=InnoDB AUTO_INCREMENT=4844 DEFAULT CHARSET=utf8mb4; -- ---------------------------- -- Table structure for base_sys_menu @@ -152,7 +145,6 @@ CREATE TABLE `base_sys_menu` ( `viewPath` varchar(255) DEFAULT NULL COMMENT '视图地址', `keepAlive` tinyint(4) NOT NULL DEFAULT '1' COMMENT '路由缓存', `isShow` tinyint(4) NOT NULL DEFAULT '1' COMMENT '父菜单名称', - `moduleName` varchar(255) DEFAULT NULL COMMENT '模块名', PRIMARY KEY (`id`), KEY `IDX_05e3d6a56604771a6da47ebf8e` (`createTime`), KEY `IDX_d5203f18daaf7c3fe0ab34497f` (`updateTime`) @@ -162,60 +154,60 @@ CREATE TABLE `base_sys_menu` ( -- Records of base_sys_menu -- ---------------------------- BEGIN; -INSERT INTO `base_sys_menu` VALUES (1, '2019-09-11 11:14:44.000000', '2019-11-18 15:56:36.000000', NULL, '工作台', '/', NULL, 0, 'icon-workbench', 1, NULL, 1, 1, ''); -INSERT INTO `base_sys_menu` VALUES (2, '2019-09-11 11:14:47.000000', '2021-02-27 17:16:05.000000', NULL, '系统管理', '/sys', NULL, 0, 'icon-system', 2, NULL, 1, 1, ''); -INSERT INTO `base_sys_menu` VALUES (8, '1900-01-20 23:19:57.000000', '2019-09-12 15:53:39.000000', 27, '菜单列表', '/sys/menu', NULL, 1, 'icon-menu', 2, 'cool/components/base/views/menu.vue', 1, 1, 'sys-menu'); -INSERT INTO `base_sys_menu` VALUES (10, '1900-01-20 00:19:27.325000', '1900-01-20 00:19:27.325000', 8, '新增', NULL, 'base:sys:menu:add', 2, NULL, 1, NULL, 0, 1, ''); -INSERT INTO `base_sys_menu` VALUES (11, '1900-01-20 00:19:51.101000', '1900-01-20 00:19:51.101000', 8, '删除', NULL, 'base:sys:menu:delete', 2, NULL, 2, NULL, 0, 1, ''); -INSERT INTO `base_sys_menu` VALUES (12, '1900-01-20 00:20:05.150000', '1900-01-20 00:20:05.150000', 8, '修改', NULL, 'base:sys:menu:update', 2, NULL, 3, NULL, 0, 1, ''); -INSERT INTO `base_sys_menu` VALUES (13, '1900-01-20 00:20:19.341000', '1900-01-20 00:20:19.341000', 8, '查询', NULL, 'base:sys:menu:page,base:sys:menu:list,base:sys:menu:info', 2, NULL, 4, NULL, 0, 1, ''); -INSERT INTO `base_sys_menu` VALUES (22, '2019-09-12 00:34:01.000000', '2019-09-15 23:47:27.000000', 27, '角色列表', '/sys/role', NULL, 1, 'icon-common', 3, 'cool/components/base/views/role.vue', 1, 1, 'sys-role'); -INSERT INTO `base_sys_menu` VALUES (23, '1900-01-20 00:34:23.459000', '1900-01-20 00:34:23.459000', 22, '新增', NULL, 'base:sys:role:add', 2, NULL, 1, NULL, 0, 1, ''); -INSERT INTO `base_sys_menu` VALUES (24, '1900-01-20 00:34:40.523000', '1900-01-20 00:34:40.523000', 22, '删除', NULL, 'base:sys:role:delete', 2, NULL, 2, NULL, 0, 1, ''); -INSERT INTO `base_sys_menu` VALUES (25, '1900-01-20 00:34:53.306000', '1900-01-20 00:34:53.306000', 22, '修改', NULL, 'base:sys:role:update', 2, NULL, 3, NULL, 0, 1, ''); -INSERT INTO `base_sys_menu` VALUES (26, '1900-01-20 00:35:05.024000', '1900-01-20 00:35:05.024000', 22, '查询', NULL, 'base:sys:role:page,base:sys:role:list,base:sys:role:info', 2, NULL, 4, NULL, 0, 1, ''); -INSERT INTO `base_sys_menu` VALUES (27, '2019-09-12 15:52:44.000000', '2019-09-15 22:11:56.000000', 2, '权限管理', NULL, NULL, 0, 'icon-auth', 1, NULL, 0, 1, ''); -INSERT INTO `base_sys_menu` VALUES (29, '2019-09-12 17:35:51.000000', '2019-11-26 23:46:53.000000', 105, '请求日志', '/sys/log', NULL, 1, 'icon-log', 1, 'cool/components/log/views/log.vue', 1, 1, 'sys.log'); -INSERT INTO `base_sys_menu` VALUES (30, '2019-09-12 17:37:03.000000', '2021-03-03 10:16:26.000000', 29, '权限', NULL, 'base:sys:log:page,base:sys:log:clear,base:sys:log:getKeep,base:sys:log:setKeep', 2, NULL, 1, NULL, 0, 1, ''); -INSERT INTO `base_sys_menu` VALUES (43, '2019-11-07 14:22:34.000000', '2021-02-27 14:22:23.000000', 45, 'crud 示例', '/crud', NULL, 1, 'icon-favor', 1, 'cool/components/demo/views/crud.vue', 1, 1, 'crud'); -INSERT INTO `base_sys_menu` VALUES (45, '2019-11-07 22:36:57.000000', '2019-11-11 15:21:10.000000', 1, '组件库', '/ui-lib', NULL, 0, 'icon-common', 2, NULL, 1, 1, ''); -INSERT INTO `base_sys_menu` VALUES (47, '2019-11-08 09:35:08.000000', '2021-02-27 17:16:35.000000', NULL, '框架教程', '/tutorial', NULL, 0, 'icon-task', 4, NULL, 1, 1, ''); -INSERT INTO `base_sys_menu` VALUES (48, '2019-11-08 09:35:53.000000', '2021-03-03 11:03:21.000000', 47, '文档', '/tutorial/doc', NULL, 1, 'icon-log', 0, 'https://admin.cool-js.com', 1, 1, ''); -INSERT INTO `base_sys_menu` VALUES (49, '2019-11-09 22:11:13.000000', '2021-02-27 14:22:28.000000', 45, 'quill 富文本编辑器', '/editor-quill', NULL, 1, 'icon-favor', 2, 'cool/components/demo/views/editor-quill.vue', 1, 1, 'editor-quill'); -INSERT INTO `base_sys_menu` VALUES (59, '2019-11-18 16:50:27.000000', '2019-11-18 16:50:27.000000', 97, '部门列表', NULL, 'base:sys:department:list', 2, NULL, 0, NULL, 1, 1, ''); -INSERT INTO `base_sys_menu` VALUES (60, '2019-11-18 16:50:45.000000', '2019-11-18 16:50:45.000000', 97, '新增部门', NULL, 'base:sys:department:add', 2, NULL, 0, NULL, 1, 1, ''); -INSERT INTO `base_sys_menu` VALUES (61, '2019-11-18 16:50:59.000000', '2019-11-18 16:50:59.000000', 97, '更新部门', NULL, 'base:sys:department:update', 2, NULL, 0, NULL, 1, 1, ''); -INSERT INTO `base_sys_menu` VALUES (62, '2019-11-18 16:51:13.000000', '2019-11-18 16:51:13.000000', 97, '删除部门', NULL, 'base:sys:department:delete', 2, NULL, 0, NULL, 1, 1, ''); -INSERT INTO `base_sys_menu` VALUES (63, '2019-11-18 17:49:35.000000', '2019-11-18 17:49:35.000000', 97, '部门排序', NULL, 'base:sys:department:order', 2, NULL, 0, NULL, 1, 1, ''); -INSERT INTO `base_sys_menu` VALUES (65, '2019-11-18 23:59:21.000000', '2019-11-18 23:59:21.000000', 97, '用户转移', NULL, 'base:sys:user:move', 2, NULL, 0, NULL, 1, 1, ''); -INSERT INTO `base_sys_menu` VALUES (78, '2019-12-10 13:27:56.000000', '2021-02-27 17:08:53.000000', 2, '参数配置', NULL, NULL, 0, 'icon-common', 4, NULL, 1, 1, ''); -INSERT INTO `base_sys_menu` VALUES (79, '1900-01-20 13:29:33.000000', '1900-01-20 13:29:33.000000', 78, '参数列表', '/sys/param', NULL, 1, 'icon-menu', 0, 'cool/components/param/views/param.vue', 1, 1, 'sys.param'); -INSERT INTO `base_sys_menu` VALUES (80, '1900-01-20 13:29:50.146000', '1900-01-20 13:29:50.146000', 79, '新增', NULL, 'base:sys:param:add', 2, NULL, 0, NULL, 1, 1, ''); -INSERT INTO `base_sys_menu` VALUES (81, '1900-01-20 13:30:10.030000', '1900-01-20 13:30:10.030000', 79, '修改', NULL, 'base:sys:param:info,base:sys:param:update', 2, NULL, 0, NULL, 1, 1, ''); -INSERT INTO `base_sys_menu` VALUES (82, '1900-01-20 13:30:25.791000', '1900-01-20 13:30:25.791000', 79, '删除', NULL, 'base:sys:param:delete', 2, NULL, 0, NULL, 1, 1, ''); -INSERT INTO `base_sys_menu` VALUES (83, '1900-01-20 13:30:40.469000', '1900-01-20 13:30:40.469000', 79, '查看', NULL, 'base:sys:param:page,base:sys:param:list,base:sys:param:info', 2, NULL, 0, NULL, 1, 1, ''); -INSERT INTO `base_sys_menu` VALUES (84, '2020-07-25 16:21:30.000000', '2020-07-25 16:21:30.000000', NULL, '通用', NULL, NULL, 0, 'icon-radioboxfill', 99, NULL, 1, 0, ''); -INSERT INTO `base_sys_menu` VALUES (85, '2020-07-25 16:22:14.000000', '2021-03-03 10:36:00.000000', 84, '图片上传', NULL, 'space:info:page,space:info:list,space:info:info,space:info:add,space:info:delete,space:info:update,space:type:page,space:type:list,space:type:info,space:type:add,space:type:delete,space:type:update', 2, NULL, 1, NULL, 1, 1, ''); -INSERT INTO `base_sys_menu` VALUES (86, '2020-08-12 09:56:27.000000', '2021-02-27 14:22:35.000000', 45, '文件上传', '/upload', NULL, 1, 'icon-favor', 3, 'cool/components/demo/views/upload.vue', 1, 1, 'upload'); -INSERT INTO `base_sys_menu` VALUES (90, '1900-01-20 10:26:58.615000', '1900-01-20 10:26:58.615000', 84, '客服聊天', NULL, 'base:app:im:message:read,base:app:im:message:page,base:app:im:session:page,base:app:im:session:list,base:app:im:session:unreadCount,base:app:im:session:delete', 2, NULL, 0, NULL, 1, 1, ''); -INSERT INTO `base_sys_menu` VALUES (96, '2021-01-12 14:12:20.000000', '2021-02-27 14:22:17.000000', 1, '组件预览', '/demo', NULL, 1, 'icon-favor', 0, 'cool/components/demo/views/demo.vue', 1, 1, 'demo'); -INSERT INTO `base_sys_menu` VALUES (97, '1900-01-20 14:14:02.000000', '2021-02-27 14:18:22.000000', 27, '用户列表', '/sys/user', NULL, 1, 'icon-user', 0, 'cool/components/base/views/user.vue', 1, 1, 'sys-user'); -INSERT INTO `base_sys_menu` VALUES (98, '1900-01-20 14:14:13.528000', '1900-01-20 14:14:13.528000', 97, '新增', NULL, 'base:sys:user:add', 2, NULL, 0, NULL, 1, 1, ''); -INSERT INTO `base_sys_menu` VALUES (99, '1900-01-20 14:14:22.823000', '1900-01-20 14:14:22.823000', 97, '删除', NULL, 'base:sys:user:delete', 2, NULL, 0, NULL, 1, 1, ''); -INSERT INTO `base_sys_menu` VALUES (100, '1900-01-20 14:14:33.973000', '1900-01-20 14:14:33.973000', 97, '修改', NULL, 'base:sys:user:delete,base:sys:user:update', 2, NULL, 0, NULL, 1, 1, ''); -INSERT INTO `base_sys_menu` VALUES (101, '2021-01-12 14:14:51.000000', '2021-01-12 14:14:51.000000', 97, '查询', NULL, 'base:sys:user:page,base:sys:user:list,base:sys:user:info', 2, NULL, 0, NULL, 1, 1, ''); -INSERT INTO `base_sys_menu` VALUES (105, '2021-01-21 10:42:55.000000', '2021-01-21 10:42:55.000000', 2, '监控管理', NULL, NULL, 0, 'icon-rank', 6, NULL, 1, 1, ''); -INSERT INTO `base_sys_menu` VALUES (109, '2021-02-27 14:13:56.000000', '2021-02-27 17:09:19.000000', NULL, '插件管理', NULL, NULL, 0, 'icon-menu', 3, NULL, 1, 1, NULL); -INSERT INTO `base_sys_menu` VALUES (110, '2021-02-27 14:14:13.000000', '2021-02-27 14:14:13.000000', 109, '插件列表', '/plugin', NULL, 1, 'icon-menu', 0, 'cool/components/base/views/plugin.vue', 1, 1, 'plugin'); -INSERT INTO `base_sys_menu` VALUES (111, '2021-02-27 14:24:41.877000', '2021-02-27 14:24:41.877000', 110, '编辑', NULL, 'base:plugin:info:info,base:plugin:info:update', 2, NULL, 0, NULL, 1, 1, NULL); -INSERT INTO `base_sys_menu` VALUES (112, '2021-02-27 14:24:52.159000', '2021-02-27 14:24:52.159000', 110, '列表', NULL, 'base:plugin:info:list', 2, NULL, 0, NULL, 1, 1, NULL); -INSERT INTO `base_sys_menu` VALUES (113, '2021-02-27 14:25:02.066000', '2021-02-27 14:25:02.066000', 110, '删除', NULL, 'base:plugin:info:delete', 2, NULL, 0, NULL, 1, 1, NULL); -INSERT INTO `base_sys_menu` VALUES (114, '2021-02-27 16:36:59.322000', '2021-02-27 16:36:59.322000', 110, '保存配置', NULL, 'base:plugin:info:config', 2, NULL, 0, NULL, 1, 1, NULL); -INSERT INTO `base_sys_menu` VALUES (115, '2021-02-27 16:38:21.000000', '2021-02-27 18:18:22.000000', 110, '获取配置', NULL, 'base:plugin:info:getConfig', 2, NULL, 0, NULL, 1, 1, NULL); -INSERT INTO `base_sys_menu` VALUES (116, '2021-02-27 17:57:42.000000', '2021-02-27 18:19:35.000000', 110, '开启、关闭', NULL, 'base:plugin:info:enable', 2, NULL, 0, NULL, 1, 1, NULL); -INSERT INTO `base_sys_menu` VALUES (117, '2021-03-05 10:58:25.000000', '2021-03-05 10:58:25.000000', NULL, '任务管理', NULL, NULL, 0, 'icon-activity', 5, NULL, 1, 1, NULL); -INSERT INTO `base_sys_menu` VALUES (118, '2021-03-05 10:59:42.113522', '2021-03-05 10:59:42.113522', 117, '任务列表', '/task', NULL, 1, 'icon-menu', 0, 'cool/modules/task/views/task.vue', 1, 1, 'task'); -INSERT INTO `base_sys_menu` VALUES (119, '2021-03-05 11:00:00.000000', '2021-03-05 11:00:00.000000', 118, '权限', NULL, 'task:info:page,task:info:list,task:info:info,task:info:add,task:info:delete,task:info:update,task:info:stop,task:info:start,task:info:once,task:info:log', 2, NULL, 0, NULL, 1, 1, NULL); +INSERT INTO `base_sys_menu` VALUES (1, '2019-09-11 11:14:44.000000', '2019-11-18 15:56:36.000000', NULL, '工作台', '/', NULL, 0, 'icon-workbench', 1, NULL, 1, 1); +INSERT INTO `base_sys_menu` VALUES (2, '2019-09-11 11:14:47.000000', '2021-02-27 17:16:05.000000', NULL, '系统管理', '/sys', NULL, 0, 'icon-system', 2, NULL, 1, 1); +INSERT INTO `base_sys_menu` VALUES (8, '1900-01-20 23:19:57.000000', '2021-03-08 22:59:12.000000', 27, '菜单列表', '/sys/menu', NULL, 1, 'icon-menu', 2, 'cool/modules/base/views/menu.vue', 1, 1); +INSERT INTO `base_sys_menu` VALUES (10, '1900-01-20 00:19:27.325000', '1900-01-20 00:19:27.325000', 8, '新增', NULL, 'base:sys:menu:add', 2, NULL, 1, NULL, 0, 1); +INSERT INTO `base_sys_menu` VALUES (11, '1900-01-20 00:19:51.101000', '1900-01-20 00:19:51.101000', 8, '删除', NULL, 'base:sys:menu:delete', 2, NULL, 2, NULL, 0, 1); +INSERT INTO `base_sys_menu` VALUES (12, '1900-01-20 00:20:05.150000', '1900-01-20 00:20:05.150000', 8, '修改', NULL, 'base:sys:menu:update', 2, NULL, 3, NULL, 0, 1); +INSERT INTO `base_sys_menu` VALUES (13, '1900-01-20 00:20:19.341000', '1900-01-20 00:20:19.341000', 8, '查询', NULL, 'base:sys:menu:page,base:sys:menu:list,base:sys:menu:info', 2, NULL, 4, NULL, 0, 1); +INSERT INTO `base_sys_menu` VALUES (22, '2019-09-12 00:34:01.000000', '2021-03-08 22:59:23.000000', 27, '角色列表', '/sys/role', NULL, 1, 'icon-common', 3, 'cool/modules/base/views/role.vue', 1, 1); +INSERT INTO `base_sys_menu` VALUES (23, '1900-01-20 00:34:23.459000', '1900-01-20 00:34:23.459000', 22, '新增', NULL, 'base:sys:role:add', 2, NULL, 1, NULL, 0, 1); +INSERT INTO `base_sys_menu` VALUES (24, '1900-01-20 00:34:40.523000', '1900-01-20 00:34:40.523000', 22, '删除', NULL, 'base:sys:role:delete', 2, NULL, 2, NULL, 0, 1); +INSERT INTO `base_sys_menu` VALUES (25, '1900-01-20 00:34:53.306000', '1900-01-20 00:34:53.306000', 22, '修改', NULL, 'base:sys:role:update', 2, NULL, 3, NULL, 0, 1); +INSERT INTO `base_sys_menu` VALUES (26, '1900-01-20 00:35:05.024000', '1900-01-20 00:35:05.024000', 22, '查询', NULL, 'base:sys:role:page,base:sys:role:list,base:sys:role:info', 2, NULL, 4, NULL, 0, 1); +INSERT INTO `base_sys_menu` VALUES (27, '2019-09-12 15:52:44.000000', '2019-09-15 22:11:56.000000', 2, '权限管理', NULL, NULL, 0, 'icon-auth', 1, NULL, 0, 1); +INSERT INTO `base_sys_menu` VALUES (29, '2019-09-12 17:35:51.000000', '2021-03-08 23:01:39.000000', 105, '请求日志', '/sys/log', NULL, 1, 'icon-log', 1, 'cool/modules/base/views/log.vue', 1, 1); +INSERT INTO `base_sys_menu` VALUES (30, '2019-09-12 17:37:03.000000', '2021-03-03 10:16:26.000000', 29, '权限', NULL, 'base:sys:log:page,base:sys:log:clear,base:sys:log:getKeep,base:sys:log:setKeep', 2, NULL, 1, NULL, 0, 1); +INSERT INTO `base_sys_menu` VALUES (43, '2019-11-07 14:22:34.000000', '2021-03-08 23:02:51.000000', 45, 'crud 示例', '/crud', NULL, 1, 'icon-favor', 1, 'cool/modules/demo/views/crud.vue', 1, 1); +INSERT INTO `base_sys_menu` VALUES (45, '2019-11-07 22:36:57.000000', '2019-11-11 15:21:10.000000', 1, '组件库', '/ui-lib', NULL, 0, 'icon-common', 2, NULL, 1, 1); +INSERT INTO `base_sys_menu` VALUES (47, '2019-11-08 09:35:08.000000', '2021-02-27 17:16:35.000000', NULL, '框架教程', '/tutorial', NULL, 0, 'icon-task', 4, NULL, 1, 1); +INSERT INTO `base_sys_menu` VALUES (48, '2019-11-08 09:35:53.000000', '2021-03-03 11:03:21.000000', 47, '文档', '/tutorial/doc', NULL, 1, 'icon-log', 0, 'https://admin.cool-js.com', 1, 1); +INSERT INTO `base_sys_menu` VALUES (49, '2019-11-09 22:11:13.000000', '2021-03-09 09:50:46.000000', 45, 'quill 富文本编辑器', '/editor-quill', NULL, 1, 'icon-favor', 2, 'cool/modules/demo/views/editor-quill.vue', 1, 1); +INSERT INTO `base_sys_menu` VALUES (59, '2019-11-18 16:50:27.000000', '2019-11-18 16:50:27.000000', 97, '部门列表', NULL, 'base:sys:department:list', 2, NULL, 0, NULL, 1, 1); +INSERT INTO `base_sys_menu` VALUES (60, '2019-11-18 16:50:45.000000', '2019-11-18 16:50:45.000000', 97, '新增部门', NULL, 'base:sys:department:add', 2, NULL, 0, NULL, 1, 1); +INSERT INTO `base_sys_menu` VALUES (61, '2019-11-18 16:50:59.000000', '2019-11-18 16:50:59.000000', 97, '更新部门', NULL, 'base:sys:department:update', 2, NULL, 0, NULL, 1, 1); +INSERT INTO `base_sys_menu` VALUES (62, '2019-11-18 16:51:13.000000', '2019-11-18 16:51:13.000000', 97, '删除部门', NULL, 'base:sys:department:delete', 2, NULL, 0, NULL, 1, 1); +INSERT INTO `base_sys_menu` VALUES (63, '2019-11-18 17:49:35.000000', '2019-11-18 17:49:35.000000', 97, '部门排序', NULL, 'base:sys:department:order', 2, NULL, 0, NULL, 1, 1); +INSERT INTO `base_sys_menu` VALUES (65, '2019-11-18 23:59:21.000000', '2019-11-18 23:59:21.000000', 97, '用户转移', NULL, 'base:sys:user:move', 2, NULL, 0, NULL, 1, 1); +INSERT INTO `base_sys_menu` VALUES (78, '2019-12-10 13:27:56.000000', '2021-02-27 17:08:53.000000', 2, '参数配置', NULL, NULL, 0, 'icon-common', 4, NULL, 1, 1); +INSERT INTO `base_sys_menu` VALUES (79, '1900-01-20 13:29:33.000000', '2021-03-08 23:01:48.000000', 78, '参数列表', '/sys/param', NULL, 1, 'icon-menu', 0, 'cool/modules/base/views/param.vue', 1, 1); +INSERT INTO `base_sys_menu` VALUES (80, '1900-01-20 13:29:50.146000', '1900-01-20 13:29:50.146000', 79, '新增', NULL, 'base:sys:param:add', 2, NULL, 0, NULL, 1, 1); +INSERT INTO `base_sys_menu` VALUES (81, '1900-01-20 13:30:10.030000', '1900-01-20 13:30:10.030000', 79, '修改', NULL, 'base:sys:param:info,base:sys:param:update', 2, NULL, 0, NULL, 1, 1); +INSERT INTO `base_sys_menu` VALUES (82, '1900-01-20 13:30:25.791000', '1900-01-20 13:30:25.791000', 79, '删除', NULL, 'base:sys:param:delete', 2, NULL, 0, NULL, 1, 1); +INSERT INTO `base_sys_menu` VALUES (83, '1900-01-20 13:30:40.469000', '1900-01-20 13:30:40.469000', 79, '查看', NULL, 'base:sys:param:page,base:sys:param:list,base:sys:param:info', 2, NULL, 0, NULL, 1, 1); +INSERT INTO `base_sys_menu` VALUES (84, '2020-07-25 16:21:30.000000', '2020-07-25 16:21:30.000000', NULL, '通用', NULL, NULL, 0, 'icon-radioboxfill', 99, NULL, 1, 0); +INSERT INTO `base_sys_menu` VALUES (85, '2020-07-25 16:22:14.000000', '2021-03-03 10:36:00.000000', 84, '图片上传', NULL, 'space:info:page,space:info:list,space:info:info,space:info:add,space:info:delete,space:info:update,space:type:page,space:type:list,space:type:info,space:type:add,space:type:delete,space:type:update', 2, NULL, 1, NULL, 1, 1); +INSERT INTO `base_sys_menu` VALUES (86, '2020-08-12 09:56:27.000000', '2021-03-08 23:03:03.000000', 45, '文件上传', '/upload', NULL, 1, 'icon-favor', 3, 'cool/modules/demo/views/upload.vue', 1, 1); +INSERT INTO `base_sys_menu` VALUES (90, '1900-01-20 10:26:58.615000', '1900-01-20 10:26:58.615000', 84, '客服聊天', NULL, 'base:app:im:message:read,base:app:im:message:page,base:app:im:session:page,base:app:im:session:list,base:app:im:session:unreadCount,base:app:im:session:delete', 2, NULL, 0, NULL, 1, 1); +INSERT INTO `base_sys_menu` VALUES (96, '2021-01-12 14:12:20.000000', '2021-03-08 23:02:40.000000', 1, '组件预览', '/demo', NULL, 1, 'icon-favor', 0, 'cool/modules/demo/views/demo.vue', 1, 1); +INSERT INTO `base_sys_menu` VALUES (97, '1900-01-20 14:14:02.000000', '2021-03-09 11:03:09.000000', 27, '用户列表', '/sys/user', NULL, 1, 'icon-user', 0, 'cool/modules/base/views/user.vue', 1, 1); +INSERT INTO `base_sys_menu` VALUES (98, '1900-01-20 14:14:13.528000', '1900-01-20 14:14:13.528000', 97, '新增', NULL, 'base:sys:user:add', 2, NULL, 0, NULL, 1, 1); +INSERT INTO `base_sys_menu` VALUES (99, '1900-01-20 14:14:22.823000', '1900-01-20 14:14:22.823000', 97, '删除', NULL, 'base:sys:user:delete', 2, NULL, 0, NULL, 1, 1); +INSERT INTO `base_sys_menu` VALUES (100, '1900-01-20 14:14:33.973000', '1900-01-20 14:14:33.973000', 97, '修改', NULL, 'base:sys:user:delete,base:sys:user:update', 2, NULL, 0, NULL, 1, 1); +INSERT INTO `base_sys_menu` VALUES (101, '2021-01-12 14:14:51.000000', '2021-01-12 14:14:51.000000', 97, '查询', NULL, 'base:sys:user:page,base:sys:user:list,base:sys:user:info', 2, NULL, 0, NULL, 1, 1); +INSERT INTO `base_sys_menu` VALUES (105, '2021-01-21 10:42:55.000000', '2021-01-21 10:42:55.000000', 2, '监控管理', NULL, NULL, 0, 'icon-rank', 6, NULL, 1, 1); +INSERT INTO `base_sys_menu` VALUES (109, '2021-02-27 14:13:56.000000', '2021-02-27 17:09:19.000000', NULL, '插件管理', NULL, NULL, 0, 'icon-menu', 3, NULL, 1, 1); +INSERT INTO `base_sys_menu` VALUES (110, '2021-02-27 14:14:13.000000', '2021-03-08 23:01:30.000000', 109, '插件列表', '/plugin', NULL, 1, 'icon-menu', 0, 'cool/modules/base/views/plugin.vue', 1, 1); +INSERT INTO `base_sys_menu` VALUES (111, '2021-02-27 14:24:41.877000', '2021-02-27 14:24:41.877000', 110, '编辑', NULL, 'base:plugin:info:info,base:plugin:info:update', 2, NULL, 0, NULL, 1, 1); +INSERT INTO `base_sys_menu` VALUES (112, '2021-02-27 14:24:52.159000', '2021-02-27 14:24:52.159000', 110, '列表', NULL, 'base:plugin:info:list', 2, NULL, 0, NULL, 1, 1); +INSERT INTO `base_sys_menu` VALUES (113, '2021-02-27 14:25:02.066000', '2021-02-27 14:25:02.066000', 110, '删除', NULL, 'base:plugin:info:delete', 2, NULL, 0, NULL, 1, 1); +INSERT INTO `base_sys_menu` VALUES (114, '2021-02-27 16:36:59.322000', '2021-02-27 16:36:59.322000', 110, '保存配置', NULL, 'base:plugin:info:config', 2, NULL, 0, NULL, 1, 1); +INSERT INTO `base_sys_menu` VALUES (115, '2021-02-27 16:38:21.000000', '2021-02-27 18:18:22.000000', 110, '获取配置', NULL, 'base:plugin:info:getConfig', 2, NULL, 0, NULL, 1, 1); +INSERT INTO `base_sys_menu` VALUES (116, '2021-02-27 17:57:42.000000', '2021-02-27 18:19:35.000000', 110, '开启、关闭', NULL, 'base:plugin:info:enable', 2, NULL, 0, NULL, 1, 1); +INSERT INTO `base_sys_menu` VALUES (117, '2021-03-05 10:58:25.000000', '2021-03-05 10:58:25.000000', NULL, '任务管理', NULL, NULL, 0, 'icon-activity', 5, NULL, 1, 1); +INSERT INTO `base_sys_menu` VALUES (118, '2021-03-05 10:59:42.000000', '2021-03-05 10:59:42.000000', 117, '任务列表', '/task', NULL, 1, 'icon-menu', 0, 'cool/modules/task/views/task.vue', 1, 1); +INSERT INTO `base_sys_menu` VALUES (119, '2021-03-05 11:00:00.000000', '2021-03-05 11:00:00.000000', 118, '权限', NULL, 'task:info:page,task:info:list,task:info:info,task:info:add,task:info:delete,task:info:update,task:info:stop,task:info:start,task:info:once,task:info:log', 2, NULL, 0, NULL, 1, 1); COMMIT; -- ---------------------------- @@ -696,23 +688,6 @@ INSERT INTO `base_sys_user_role` VALUES (43, '2021-02-26 14:36:58.477817', '2021 INSERT INTO `base_sys_user_role` VALUES (44, '2021-02-26 14:36:58.577114', '2021-02-26 14:36:58.577114', 28, 10); COMMIT; --- ---------------------------- --- Table structure for core_config --- ---------------------------- -DROP TABLE IF EXISTS `core_config`; -CREATE TABLE `core_config` ( - `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 '更新时间', - `cKey` varchar(255) NOT NULL COMMENT '配置键 唯一性', - `cValue` text NOT NULL COMMENT '配置值', - PRIMARY KEY (`id`), - UNIQUE KEY `IDX_fd61f44f8fc57eaf4694a4fd56` (`cKey`), - KEY `IDX_bd838f3b2d5bfa596c57412646` (`createTime`), - KEY `IDX_ad74623a3e9a43335eac8d1154` (`updateTime`) -) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4; - - -- ---------------------------- -- Table structure for demo_app_goods -- ---------------------------- diff --git a/src/app/modules/base/middleware/authority.ts b/src/app/modules/base/middleware/authority.ts index 0db2e72..8e00e5e 100644 --- a/src/app/modules/base/middleware/authority.ts +++ b/src/app/modules/base/middleware/authority.ts @@ -25,10 +25,11 @@ export class BaseAuthorityMiddleware implements IWebMiddleware { resolve() { return async (ctx: Context, next: IMidwayWebNext) => { let statusCode = 200; - const { url } = ctx; - const token = ctx.get('Authorization'); + let { url } = ctx; const { prefix } = this.coolConfig.router; - const adminUrl = prefix ? `${prefix}/admin/` : '/admin/'; + url = url.replace(prefix, ''); + const token = ctx.get('Authorization'); + const adminUrl = '/admin/'; // 路由地址为 admin前缀的 需要权限校验 if (_.startsWith(url, adminUrl)) { try { diff --git a/src/app/modules/demo/service/order.ts b/src/app/modules/demo/service/order.ts deleted file mode 100644 index ee03c7b..0000000 --- a/src/app/modules/demo/service/order.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Provide } from '@midwayjs/decorator'; -import { BaseService } from 'midwayjs-cool-core'; - -/** - * 描述 - */ -@Provide() -export class DemoOrderService extends BaseService { - /** - * 描述 - */ - async test() { - console.log('我被调用了'); - } -} diff --git a/src/app/modules/task/config.ts b/src/app/modules/task/config.ts new file mode 100644 index 0000000..ef68592 --- /dev/null +++ b/src/app/modules/task/config.ts @@ -0,0 +1,16 @@ +import { Application } from 'egg'; +import { ModuleConfig } from 'midwayjs-cool-core'; + +/** + * 模块配置 + */ +export default (app: Application) => { + return { + // 模块名称 + name: '任务调度', + // 模块描述 + description: '任务调度模块,支持分布式任务,由redis整个集群的任务', + // 中间件 + middlewares: [], + } as ModuleConfig; +}; diff --git a/src/app/modules/task/controller/admin/info.ts b/src/app/modules/task/controller/admin/info.ts new file mode 100644 index 0000000..c4ae591 --- /dev/null +++ b/src/app/modules/task/controller/admin/info.ts @@ -0,0 +1,64 @@ +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)); + } +} diff --git a/src/app/modules/task/controller/说明.md b/src/app/modules/task/controller/说明.md new file mode 100644 index 0000000..440a373 --- /dev/null +++ b/src/app/modules/task/controller/说明.md @@ -0,0 +1 @@ +编写接口 \ No newline at end of file diff --git a/src/app/modules/task/entity/info.ts b/src/app/modules/task/entity/info.ts new file mode 100644 index 0000000..b8f0687 --- /dev/null +++ b/src/app/modules/task/entity/info.ts @@ -0,0 +1,57 @@ +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 }) + limit: 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; +} diff --git a/src/app/modules/task/entity/log.ts b/src/app/modules/task/entity/log.ts new file mode 100644 index 0000000..fc296ce --- /dev/null +++ b/src/app/modules/task/entity/log.ts @@ -0,0 +1,19 @@ +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; +} diff --git a/src/app/modules/task/init.sql b/src/app/modules/task/init.sql new file mode 100644 index 0000000..4417665 --- /dev/null +++ b/src/app/modules/task/init.sql @@ -0,0 +1,17 @@ +BEGIN; +INSERT INTO `task_info` VALUES (1, '2021-03-10 14:25:13.381172', '2021-03-10 14:25:19.011000', NULL, '{\"count\":1,\"type\":1,\"limit\":5,\"name\":\"每秒执行,总共5次\",\"taskType\":1,\"every\":1000,\"service\":\"taskDemoService.test()\",\"status\":1,\"id\":1,\"createTime\":\"2021-03-10 14:25:13\",\"updateTime\":\"2021-03-10 14:25:13\",\"jobId\":1}', '每秒执行,总共5次', NULL, 5, 1000, NULL, 0, NULL, NULL, NULL, 'taskDemoService.test()', 1, '2021-03-10 14:25:18', 1); +INSERT INTO `task_info` VALUES (2, '2021-03-10 14:25:53.000000', '2021-03-10 14:26:18.209202', NULL, '{\"count\":1,\"id\":2,\"createTime\":\"2021-03-10 14:25:53\",\"updateTime\":\"2021-03-10 14:25:55\",\"name\":\"cron任务,5秒执行一次\",\"cron\":\"0/5 * * * * ? \",\"status\":1,\"service\":\"taskDemoService.test()\",\"type\":1,\"nextRunTime\":\"2021-03-10 14:26:00\",\"taskType\":0,\"jobId\":2}', 'cron任务,5秒执行一次', '0/5 * * * * ? ', NULL, NULL, NULL, 0, NULL, NULL, NULL, 'taskDemoService.test()', 1, NULL, 0); +COMMIT; + +BEGIN; +INSERT INTO `task_log` VALUES (1, '2021-03-10 14:25:14.020930', '2021-03-10 14:25:14.020930', 1, 1, '\"任务执行成功\"'); +INSERT INTO `task_log` VALUES (2, '2021-03-10 14:25:15.012030', '2021-03-10 14:25:15.012030', 1, 1, '\"任务执行成功\"'); +INSERT INTO `task_log` VALUES (3, '2021-03-10 14:25:16.011443', '2021-03-10 14:25:16.011443', 1, 1, '\"任务执行成功\"'); +INSERT INTO `task_log` VALUES (4, '2021-03-10 14:25:17.009939', '2021-03-10 14:25:17.009939', 1, 1, '\"任务执行成功\"'); +INSERT INTO `task_log` VALUES (5, '2021-03-10 14:25:18.010410', '2021-03-10 14:25:18.010410', 1, 1, '\"任务执行成功\"'); +INSERT INTO `task_log` VALUES (6, '2021-03-10 14:25:55.012816', '2021-03-10 14:25:55.012816', 2, 1, ''); +INSERT INTO `task_log` VALUES (7, '2021-03-10 14:26:00.011880', '2021-03-10 14:26:00.011880', 2, 1, ''); +INSERT INTO `task_log` VALUES (8, '2021-03-10 14:26:05.016832', '2021-03-10 14:26:05.016832', 2, 1, '\"任务执行成功\"'); +INSERT INTO `task_log` VALUES (9, '2021-03-10 14:26:10.011763', '2021-03-10 14:26:10.011763', 2, 1, '\"任务执行成功\"'); +INSERT INTO `task_log` VALUES (10, '2021-03-10 14:26:15.010246', '2021-03-10 14:26:15.010246', 2, 1, '\"任务执行成功\"'); +COMMIT; \ No newline at end of file diff --git a/src/app/modules/task/queue/task.ts b/src/app/modules/task/queue/task.ts new file mode 100644 index 0000000..2ce7740 --- /dev/null +++ b/src/app/modules/task/queue/task.ts @@ -0,0 +1,30 @@ +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 { + 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(); + } +} diff --git a/src/app/modules/task/service/demo.ts b/src/app/modules/task/service/demo.ts new file mode 100644 index 0000000..2d057fa --- /dev/null +++ b/src/app/modules/task/service/demo.ts @@ -0,0 +1,19 @@ +import { Logger, Provide } from '@midwayjs/decorator'; +import { BaseService } from 'midwayjs-cool-core'; +import { ILogger } from '@midwayjs/logger'; + +/** + * 描述 + */ +@Provide() +export class TaskDemoService extends BaseService { + @Logger() + logger: ILogger; + /** + * 描述 + */ + async test() { + this.logger.info('我被调用了'); + return '任务执行成功'; + } +} diff --git a/src/app/modules/task/service/info.ts b/src/app/modules/task/service/info.ts new file mode 100644 index 0000000..9b569c4 --- /dev/null +++ b/src/app/modules/task/service/info.ts @@ -0,0 +1,307 @@ +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; + + @Logger() + logger: ILogger; + + @InjectEntityModel(TaskLogEntity) + taskLogEntity: Repository; + + @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) { + console.log(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.limit = 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)); + } + } + } + } + } +} diff --git a/src/config/config.default.ts b/src/config/config.default.ts index 969699c..47700fc 100644 --- a/src/config/config.default.ts +++ b/src/config/config.default.ts @@ -23,7 +23,7 @@ export default (appInfo: EggAppInfo) => { // 靜態目錄及緩存設置 config.static = { - prefix: '/', + prefix: '', dir: path.join(appInfo.baseDir, '..', 'public'), dynamic: true, preload: false, @@ -74,7 +74,7 @@ export default (appInfo: EggAppInfo) => { // 文件上传 file: { // 文件路径前缀 本地上传模式下 有效 - domain: 'https://admin.cn.utools.club', + domain: 'https://admin.cool-js.cool', }, }; diff --git a/src/config/config.local.ts b/src/config/config.local.ts index 768ffe3..c37f1ee 100644 --- a/src/config/config.local.ts +++ b/src/config/config.local.ts @@ -7,11 +7,11 @@ export default (appInfo: EggAppInfo) => { config.orm = { type: 'mysql', - host: '139.196.196.203', + host: '127.0.0.1', port: 3306, - username: 'cooladmin', + username: 'root', password: '123123', - database: 'cooladmin', + database: 'cool', // 自动建表 注意:线上部署的时候不要使用,有可能导致数据丢失 synchronize: true, // 打印日志 diff --git a/src/config/config.prod.ts b/src/config/config.prod.ts index c3ef4e3..4a71ac0 100644 --- a/src/config/config.prod.ts +++ b/src/config/config.prod.ts @@ -7,11 +7,11 @@ export default (appInfo: EggAppInfo) => { config.orm = { type: 'mysql', - host: '139.196.196.203', + host: '127.0.0.1', port: 3306, - username: 'cooladmin', + username: 'root', password: '123123', - database: 'cooladmin', + database: 'cool', // 自动建表 注意:线上部署的时候不要使用,有可能导致数据丢失 synchronize: false, // 打印日志 diff --git a/src/configuration.ts b/src/configuration.ts index 9c0f3b4..365b3f3 100644 --- a/src/configuration.ts +++ b/src/configuration.ts @@ -6,9 +6,9 @@ import * as cool from 'midwayjs-cool-core'; import * as wxpay from 'midwayjs-cool-wxpay'; 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'; +import * as queue from 'midwayjs-cool-queue'; +import * as alipay from 'midwayjs-cool-alipay'; +//import * as socket from 'midwayjs-cool-socket'; @Configuration({ // 注意组件顺序 cool 有依赖orm组件, 所以必须放在,orm组件之后 cool的其他组件必须放在cool 核心组件之后 @@ -22,11 +22,11 @@ import * as redis from 'midwayjs-cool-redis'; // 将缓存替换成redis redis, // 队列 - //queue, + queue, // 微信支付 wxpay, // 支付宝支付 - //alipay + alipay, // socket //socket ],