diff --git a/package.json b/package.json index 48e15cc..08dc1c5 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,12 @@ { "name": "cool-admin", - "version": "7.0.0", + "version": "7.1.0", "description": "一个项目用COOL就够了", "private": true, "dependencies": { "@cool-midway/cache-manager-fs-hash": "^7.0.0", "@cool-midway/cloud": "^7.0.0", - "@cool-midway/core": "^7.1.0", + "@cool-midway/core": "^7.1.1", "@cool-midway/file": "^7.0.5", "@cool-midway/iot": "^7.0.0", "@cool-midway/pay": "^7.0.0", @@ -24,20 +24,12 @@ "@midwayjs/static-file": "^3.14.0", "@midwayjs/task": "^3.6.0", "@midwayjs/typeorm": "^3.14.0", + "@midwayjs/upload": "^3.14.3", "@midwayjs/validate": "^3.14.0", "@midwayjs/view-ejs": "^3.14.0", - "axios": "^1.6.5", "ipip-ipdb": "^0.6.0", - "jsonwebtoken": "^9.0.2", - "lodash": "^4.17.21", - "md5": "^2.3.0", - "mini-svg-data-uri": "^1.4.4", - "moment": "^2.30.1", "mysql2": "^3.7.0", - "svg-captcha": "^1.4.0", - "svg2png-wasm": "^1.4.1", - "typeorm": "^0.3.19", - "uuid": "^9.0.1" + "typeorm": "^0.3.19" }, "devDependencies": { "@midwayjs/cli": "^2.1.1", diff --git a/src/config/config.local.ts b/src/config/config.local.ts index 1c8e879..4a47c8e 100644 --- a/src/config/config.local.ts +++ b/src/config/config.local.ts @@ -1,6 +1,5 @@ import { CoolConfig } from '@cool-midway/core'; import { MidwayConfig } from '@midwayjs/core'; -// import * as path from 'path'; /** * 本地开发 npm run dev 读取的配置文件 diff --git a/src/configuration.ts b/src/configuration.ts index 077cb91..e432eed 100644 --- a/src/configuration.ts +++ b/src/configuration.ts @@ -1,5 +1,5 @@ import * as orm from '@midwayjs/typeorm'; -import { Configuration, App, Config, Inject } from '@midwayjs/decorator'; +import { Configuration, App, Inject } from '@midwayjs/decorator'; import * as koa from '@midwayjs/koa'; import * as validate from '@midwayjs/validate'; import * as info from '@midwayjs/info'; @@ -13,8 +13,7 @@ import * as cloud from '@cool-midway/cloud'; import * as file from '@cool-midway/file'; import * as sms from '@cool-midway/sms'; import { ILogger } from '@midwayjs/logger'; -import { Repository } from 'typeorm'; -import { BaseSysRoleMenuEntity } from './modules/base/entity/sys/role_menu'; +import { IMidwayApplication } from '@midwayjs/core'; // import * as swagger from '@midwayjs/swagger'; // import * as rpc from '@cool-midway/rpc'; // import * as task from '@cool-midway/task'; @@ -64,16 +63,10 @@ import { BaseSysRoleMenuEntity } from './modules/base/entity/sys/role_menu'; }) export class ContainerLifeCycle { @App() - app: koa.Application; + app: IMidwayApplication; @Inject() logger: ILogger; - @Config('module') - config; - - @orm.InjectEntityModel(BaseSysRoleMenuEntity) - baseSysRoleMenuEntity: Repository; - async onReady() {} } diff --git a/src/modules/base/menu.json b/src/modules/base/menu.json index edb23bf..597aabb 100644 --- a/src/modules/base/menu.json +++ b/src/modules/base/menu.json @@ -401,6 +401,44 @@ ] } ] + }, + { + "name": "任务管理", + "router": null, + "perms": null, + "type": 0, + "icon": "icon-activity", + "orderNum": 9, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "任务列表", + "router": "/task/list", + "perms": null, + "type": 1, + "icon": "icon-menu", + "orderNum": 0, + "viewPath": "modules/task/views/list.vue", + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "权限", + "router": null, + "perms": "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", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + } + ] + } + ] } ] }, @@ -416,7 +454,7 @@ "isShow": true, "childMenus": [ { - "name": "文档", + "name": "文档官网", "router": "/tutorial/doc", "perms": null, "type": 1, @@ -428,16 +466,65 @@ "childMenus": [] }, { - "name": "插件市场", - "router": "/tutorial/plugin", + "name": "示例组件", + "router": null, "perms": null, - "type": 1, - "icon": "icon-app", + "type": 0, + "icon": "icon-workbench", "orderNum": 1, - "viewPath": "https://cool-js.com/plugin/list.html", + "viewPath": null, "keepAlive": true, "isShow": true, - "childMenus": [] + "childMenus": [ + { + "name": "组件预览", + "router": "/demo", + "perms": null, + "type": 1, + "icon": "icon-favor", + "orderNum": 1, + "viewPath": "modules/demo/views/demo.vue", + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "crud 示例", + "router": "/demo/crud", + "perms": null, + "type": 1, + "icon": "icon-favor", + "orderNum": 1, + "viewPath": "modules/demo/views/crud/index.vue", + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "编辑器", + "router": "/demo/editor", + "perms": null, + "type": 1, + "icon": "icon-favor", + "orderNum": 4, + "viewPath": "modules/demo/views/editor.vue", + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "文件上传", + "router": "/demo/upload", + "perms": null, + "type": 1, + "icon": "icon-favor", + "orderNum": 3, + "viewPath": "modules/demo/views/upload.vue", + "keepAlive": true, + "isShow": true, + "childMenus": [] + } + ] } ] }, @@ -466,79 +553,6 @@ } ] }, - { - "name": "页面设计", - "router": "/design/page", - "perms": null, - "type": 1, - "icon": "icon-design", - "orderNum": 7, - "viewPath": "modules/design/views/page.vue", - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "工作台", - "router": null, - "perms": null, - "type": 0, - "icon": "icon-workbench", - "orderNum": 1, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [ - { - "name": "组件预览", - "router": "/demo", - "perms": null, - "type": 1, - "icon": "icon-favor", - "orderNum": 1, - "viewPath": "modules/demo/views/demo.vue", - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "crud 示例", - "router": "/demo/crud", - "perms": null, - "type": 1, - "icon": "icon-favor", - "orderNum": 1, - "viewPath": "modules/demo/views/crud.vue", - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "编辑器", - "router": "/demo/editor", - "perms": null, - "type": 1, - "icon": "icon-favor", - "orderNum": 4, - "viewPath": "modules/demo/views/editor.vue", - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "文件上传", - "router": "/demo/upload", - "perms": null, - "type": 1, - "icon": "icon-favor", - "orderNum": 3, - "viewPath": "modules/demo/views/upload.vue", - "keepAlive": true, - "isShow": true, - "childMenus": [] - } - ] - }, { "name": "首页", "router": "/", @@ -550,5 +564,690 @@ "keepAlive": true, "isShow": false, "childMenus": [] + }, + { + "name": "函数开发", + "router": null, + "perms": null, + "type": 0, + "icon": "icon-fx", + "orderNum": 12, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "云数据库", + "router": "/cloud/db", + "perms": null, + "type": 1, + "icon": "icon-db", + "orderNum": 1, + "viewPath": "modules/cloud/views/db.vue", + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "初始化Entity", + "router": null, + "perms": "cloud:db:initEntity", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "删除", + "router": null, + "perms": "cloud:db:delete", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "修改", + "router": null, + "perms": "cloud:db:update,cloud:db:info", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "数据操作测试", + "router": null, + "perms": "cloud:db:data", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "单个信息", + "router": null, + "perms": "cloud:db:info", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "列表查询", + "router": null, + "perms": "cloud:db:list", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "分页查询", + "router": null, + "perms": "cloud:db:page", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "新增", + "router": null, + "perms": "cloud:db:add", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + } + ] + }, + { + "name": "云函数", + "router": "/cloud/func/info", + "perms": null, + "type": 1, + "icon": "icon-menu", + "orderNum": 2, + "viewPath": "modules/cloud/views/func/info.vue", + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "调用云函数", + "router": null, + "perms": "cloud:func:info:invoke", + "type": 2, + "icon": null, + "orderNum": 98, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "删除", + "router": null, + "perms": "cloud:func:info:delete", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "修改", + "router": null, + "perms": "cloud:func:info:update,cloud:func:info:info", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "单个信息", + "router": null, + "perms": "cloud:func:info:info", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "列表查询", + "router": null, + "perms": "cloud:func:info:list", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "分页查询", + "router": null, + "perms": "cloud:func:info:page", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "新增", + "router": null, + "perms": "cloud:func:info:add", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "云函数开发", + "router": null, + "perms": "cloud:func:info:info,cloud:func:info:update,cloud:func:info:invoke", + "type": 2, + "icon": null, + "orderNum": 99, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "查看日志", + "router": null, + "perms": "cloud:func:log:page", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + } + ] + } + ] + }, + { + "name": "物联管理", + "router": null, + "perms": null, + "type": 0, + "icon": "icon-iot", + "orderNum": 12, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "MQTT", + "router": "/iot/device", + "perms": null, + "type": 1, + "icon": "icon-device", + "orderNum": 1, + "viewPath": "modules/iot/views/device.vue", + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "删除", + "router": null, + "perms": "iot:device:delete", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "单个信息", + "router": null, + "perms": "iot:device:info", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "列表查询", + "router": null, + "perms": "iot:device:list", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "分页查询", + "router": null, + "perms": "iot:device:page", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "修改", + "router": null, + "perms": "iot:device:info,iot:device:update", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "新增", + "router": null, + "perms": "iot:device:add", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + } + ] + } + ] + }, + { + "name": "数据管理", + "router": null, + "perms": null, + "type": 0, + "icon": "icon-data", + "orderNum": 7, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "字典管理", + "router": "/dict/list", + "perms": null, + "type": 1, + "icon": "icon-dict", + "orderNum": 3, + "viewPath": "modules/dict/views/list.vue", + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "删除", + "router": null, + "perms": "dict:info:delete", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "修改", + "router": null, + "perms": "dict:info:update,dict:info:info", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "获得字典数据", + "router": null, + "perms": "dict:info:data", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "单个信息", + "router": null, + "perms": "dict:info:info", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "列表查询", + "router": null, + "perms": "dict:info:list", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "分页查询", + "router": null, + "perms": "dict:info:page", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "新增", + "router": null, + "perms": "dict:info:add", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "组权限", + "router": null, + "perms": "dict:type:list,dict:type:update,dict:type:delete,dict:type:add", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + } + ] + }, + { + "name": "数据回收站", + "router": "/recycle/data", + "perms": null, + "type": 1, + "icon": "icon-delete", + "orderNum": 6, + "viewPath": "modules/recycle/views/data.vue", + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "恢复数据", + "router": null, + "perms": "recycle:data:restore", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "单个信息", + "router": null, + "perms": "recycle:data:info", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "分页查询", + "router": null, + "perms": "recycle:data:page", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + } + ] + }, + { + "name": "文件管理", + "router": "/upload/list", + "perms": null, + "type": 1, + "icon": "icon-log", + "orderNum": 5, + "viewPath": "modules/space/views/list.vue", + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "权限", + "router": null, + "perms": "space:type:delete,space:type:update,space:type:info,space:type:list,space:type:page,space:type:add,space:info:getConfig,space:info:delete,space:info:update,space:info:info,space:info:list,space:info:page,space:info:add", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + } + ] + } + ] + }, + { + "name": "用户管理", + "router": null, + "perms": null, + "type": 0, + "icon": "icon-user", + "orderNum": 11, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "用户列表", + "router": "/user/list", + "perms": null, + "type": 1, + "icon": "icon-menu", + "orderNum": 1, + "viewPath": "modules/user/views/list.vue", + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "删除", + "router": null, + "perms": "user:info:delete", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "修改", + "router": null, + "perms": "user:info:update,user:info:info", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "单个信息", + "router": null, + "perms": "user:info:info", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "列表查询", + "router": null, + "perms": "user:info:list", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "分页查询", + "router": null, + "perms": "user:info:page", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "新增", + "router": null, + "perms": "user:info:add", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + } + ] + } + ] + }, + { + "name": "扩展管理", + "router": null, + "perms": null, + "type": 0, + "icon": "icon-favor", + "orderNum": 8, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "页面设计", + "router": "/design/page", + "perms": null, + "type": 1, + "icon": "icon-design", + "orderNum": 95, + "viewPath": "modules/design/views/page.vue", + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "插件管理", + "router": "/helper/plugin", + "perms": null, + "type": 1, + "icon": "icon-component", + "orderNum": 4, + "viewPath": "modules/helper/views/plugin.vue", + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "权限", + "router": null, + "perms": "plugin:info:install,plugin:info:delete,plugin:info:update,plugin:info:page,plugin:info:info", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + } + ] + } + ] } ] \ No newline at end of file diff --git a/src/modules/cloud/event/app.ts b/src/modules/cloud/event/app.ts index 98776e9..2f53618 100644 --- a/src/modules/cloud/event/app.ts +++ b/src/modules/cloud/event/app.ts @@ -11,11 +11,7 @@ export class AppEvent { @App() app: IMidwayApplication; - @Event('onDBInit') - async onDBInit() { - this.initEntity(); - } - + @Event('onServerReady') async initEntity() { const cloudDBService = await this.app .getApplicationContext() diff --git a/src/modules/cloud/menu.json b/src/modules/cloud/menu.json deleted file mode 100644 index 135ac13..0000000 --- a/src/modules/cloud/menu.json +++ /dev/null @@ -1,245 +0,0 @@ -[ - { - "name": "函数开发", - "router": null, - "perms": null, - "type": 0, - "icon": "icon-fx", - "orderNum": 6, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [ - { - "name": "云数据库", - "router": "/cloud/db", - "perms": null, - "type": 1, - "icon": "icon-db", - "orderNum": 1, - "viewPath": "modules/cloud/views/db.vue", - "keepAlive": true, - "isShow": true, - "childMenus": [ - { - "name": "初始化Entity", - "router": null, - "perms": "cloud:db:initEntity", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "删除", - "router": null, - "perms": "cloud:db:delete", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "修改", - "router": null, - "perms": "cloud:db:update,cloud:db:info", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "数据操作测试", - "router": null, - "perms": "cloud:db:data", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "单个信息", - "router": null, - "perms": "cloud:db:info", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "列表查询", - "router": null, - "perms": "cloud:db:list", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "分页查询", - "router": null, - "perms": "cloud:db:page", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "新增", - "router": null, - "perms": "cloud:db:add", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - } - ] - }, - { - "name": "云函数", - "router": "/cloud/func/info", - "perms": null, - "type": 1, - "icon": "icon-menu", - "orderNum": 2, - "viewPath": "modules/cloud/views/func/info.vue", - "keepAlive": true, - "isShow": true, - "childMenus": [ - { - "name": "调用云函数", - "router": null, - "perms": "cloud:func:info:invoke", - "type": 2, - "icon": null, - "orderNum": 98, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "删除", - "router": null, - "perms": "cloud:func:info:delete", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "修改", - "router": null, - "perms": "cloud:func:info:update,cloud:func:info:info", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "单个信息", - "router": null, - "perms": "cloud:func:info:info", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "列表查询", - "router": null, - "perms": "cloud:func:info:list", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "分页查询", - "router": null, - "perms": "cloud:func:info:page", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "新增", - "router": null, - "perms": "cloud:func:info:add", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "云函数开发", - "router": null, - "perms": "cloud:func:info:info,cloud:func:info:update,cloud:func:info:invoke", - "type": 2, - "icon": null, - "orderNum": 99, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "查看日志", - "router": null, - "perms": "cloud:func:log:page", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - } - ] - } - ] - } -] \ No newline at end of file diff --git a/src/modules/demo/entity/goods.ts b/src/modules/demo/entity/goods.ts index ebb9f5c..833bada 100644 --- a/src/modules/demo/entity/goods.ts +++ b/src/modules/demo/entity/goods.ts @@ -29,10 +29,4 @@ export class DemoGoodsEntity extends BaseEntity { @Column({ comment: '库存', default: 0 }) stock: number; - - @BeforeRemove() - async beforeRemove() { - // await this.service.beforeRemove(this); - console.log('数据被删除11'); - } } diff --git a/src/modules/dict/menu.json b/src/modules/dict/menu.json deleted file mode 100644 index dd1cc35..0000000 --- a/src/modules/dict/menu.json +++ /dev/null @@ -1,124 +0,0 @@ -[ - { - "name": "字典管理", - "router": null, - "perms": null, - "type": 0, - "icon": "icon-dict", - "orderNum": 3, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [ - { - "name": "字典列表", - "router": "/dict/list", - "perms": null, - "type": 1, - "icon": "icon-menu", - "orderNum": 1, - "viewPath": "modules/dict/views/list.vue", - "keepAlive": true, - "isShow": true, - "childMenus": [ - { - "name": "删除", - "router": null, - "perms": "dict:info:delete", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "修改", - "router": null, - "perms": "dict:info:update,dict:info:info", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "获得字典数据", - "router": null, - "perms": "dict:info:data", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "单个信息", - "router": null, - "perms": "dict:info:info", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "列表查询", - "router": null, - "perms": "dict:info:list", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "分页查询", - "router": null, - "perms": "dict:info:page", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "新增", - "router": null, - "perms": "dict:info:add", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "组权限", - "router": null, - "perms": "dict:type:list,dict:type:update,dict:type:delete,dict:type:add", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - } - ] - } - ] - } -] \ No newline at end of file diff --git a/src/modules/iot/menu.json b/src/modules/iot/menu.json deleted file mode 100644 index a172443..0000000 --- a/src/modules/iot/menu.json +++ /dev/null @@ -1,100 +0,0 @@ -[ - { - "name": "物联管理", - "router": null, - "perms": null, - "type": 0, - "icon": "icon-iot", - "orderNum": 4, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [ - { - "name": "MQTT", - "router": "/iot/device", - "perms": null, - "type": 1, - "icon": "icon-device", - "orderNum": 1, - "viewPath": "modules/iot/views/device.vue", - "keepAlive": true, - "isShow": true, - "childMenus": [ - { - "name": "删除", - "router": null, - "perms": "iot:device:delete", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "单个信息", - "router": null, - "perms": "iot:device:info", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "列表查询", - "router": null, - "perms": "iot:device:list", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "分页查询", - "router": null, - "perms": "iot:device:page", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "修改", - "router": null, - "perms": "iot:device:info,iot:device:update", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "新增", - "router": null, - "perms": "iot:device:add", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - } - ] - } - ] - } -] \ No newline at end of file diff --git a/src/modules/plugin/config.ts b/src/modules/plugin/config.ts new file mode 100644 index 0000000..74aa56b --- /dev/null +++ b/src/modules/plugin/config.ts @@ -0,0 +1,27 @@ +import { ModuleConfig } from '@cool-midway/core'; + +/** + * 模块配置 + */ +export default options => { + return { + // 模块名称 + name: '插件模块', + // 模块描述 + description: '插件查看、安装、卸载、配置等', + // 中间件,只对本模块有效 + middlewares: [], + // 中间件,全局有效 + globalMiddlewares: [], + // 模块加载顺序,默认为0,值越大越优先加载 + order: 0, + // 基础插件配置 + hooks: { + // 文件上传 + upload: { + // 地址前缀 + domain: `http://127.0.0.1:${options?.app?.getConfig('koa.port')}`, + }, + }, + } as ModuleConfig; +}; diff --git a/src/modules/plugin/controller/admin/info.ts b/src/modules/plugin/controller/admin/info.ts new file mode 100644 index 0000000..3afd53c --- /dev/null +++ b/src/modules/plugin/controller/admin/info.ts @@ -0,0 +1,35 @@ +import { + CoolController, + BaseController, + CoolTag, + CoolUrlTag, + TagTypes, +} from '@cool-midway/core'; +import { PluginInfoEntity } from '../../entity/info'; +import { Body, Fields, Files, Inject, Post } from '@midwayjs/core'; +import { PluginService } from '../../service/info'; + +/** + * 插件信息 + */ +@CoolUrlTag({ + key: TagTypes.IGNORE_TOKEN, + value: [], +}) +@CoolController({ + api: ['add', 'delete', 'update', 'info', 'list', 'page'], + entity: PluginInfoEntity, + service: PluginService, +}) +export class AdminPluginInfoController extends BaseController { + @Inject() + pluginService: PluginService; + + @CoolTag(TagTypes.IGNORE_TOKEN) + @Post('/install', { summary: '安装插件' }) + async install(@Files() files, @Fields() fields) { + return this.ok( + await this.pluginService.install(files[0].data, fields.force) + ); + } +} diff --git a/src/modules/plugin/entity/info.ts b/src/modules/plugin/entity/info.ts new file mode 100644 index 0000000..750e5d9 --- /dev/null +++ b/src/modules/plugin/entity/info.ts @@ -0,0 +1,49 @@ +import { BaseEntity } from '@cool-midway/core'; +import { Column, Entity, DataSource } from 'typeorm'; + +console.log(DataSource); + +/** + * 插件信息 + */ +@Entity('plugin_info') +export class PluginInfoEntity extends BaseEntity { + @Column({ comment: '名称' }) + name: string; + + @Column({ comment: '简介' }) + description: string; + + @Column({ comment: 'Key名' }) + keyName: string; + + @Column({ comment: 'Hook' }) + hook: string; + + @Column({ comment: '描述', type: 'text' }) + readme: string; + + @Column({ comment: '版本' }) + version: string; + + @Column({ comment: 'Logo(base64)', type: 'text', nullable: true }) + logo: string; + + @Column({ comment: '作者' }) + author: string; + + @Column({ comment: '状态 0-禁用 1-启用', default: 0 }) + status: number; + + @Column({ comment: '内容', type: 'json' }) + content: { + type: 'comm' | 'module'; + data: string; + }; + + @Column({ comment: '插件的plugin.json', type: 'json', nullable: true }) + pluginJson: any; + + @Column({ comment: '配置', type: 'json', nullable: true }) + config: any; +} diff --git a/src/modules/plugin/event/app.ts b/src/modules/plugin/event/app.ts new file mode 100644 index 0000000..1509ad2 --- /dev/null +++ b/src/modules/plugin/event/app.ts @@ -0,0 +1,24 @@ +import { CoolEvent, Event } from '@cool-midway/core'; +import { App, Config, ILogger, Logger } from '@midwayjs/core'; +import { IMidwayKoaApplication } from '@midwayjs/koa'; +import { PluginCenterService } from '../service/center'; + +/** + * 修改jwt.secret + */ +@CoolEvent() +export class BaseAppEvent { + @Logger() + coreLogger: ILogger; + + @Config('module') + config; + + @App() + app: IMidwayKoaApplication; + + @Event('onServerReady') + async onServerReady() { + await this.app.getApplicationContext().getAsync(PluginCenterService); + } +} diff --git a/src/modules/plugin/hooks/base.ts b/src/modules/plugin/hooks/base.ts new file mode 100644 index 0000000..05aa206 --- /dev/null +++ b/src/modules/plugin/hooks/base.ts @@ -0,0 +1,26 @@ +import { IMidwayContext, IMidwayApplication } from '@midwayjs/core'; +import { PluginInfo } from '../interface'; + +/** + * hook基类 + */ +export class BasePluginHook { + /** 请求上下文,用到此项无法本地调试,需安装到cool-admin中才能调试 */ + ctx: IMidwayContext; + /** 应用实例,用到此项无法本地调试,需安装到cool-admin中才能调试 */ + app: IMidwayApplication; + /** 插件信息 */ + pluginInfo: PluginInfo; + /** + * 初始化 + */ + async init( + pluginInfo: PluginInfo, + ctx?: IMidwayContext, + app?: IMidwayApplication + ) { + this.pluginInfo = pluginInfo; + this.ctx = ctx; + this.app = app; + } +} diff --git a/src/modules/plugin/hooks/upload/index.ts b/src/modules/plugin/hooks/upload/index.ts new file mode 100644 index 0000000..ae63f8a --- /dev/null +++ b/src/modules/plugin/hooks/upload/index.ts @@ -0,0 +1,114 @@ +import { BaseUpload, MODETYPE } from './interface'; +import { BasePluginHook } from '../base'; +import * as fs from 'fs'; +import * as download from 'download'; +import * as path from 'path'; +import * as moment from 'moment'; +import { v1 as uuid } from 'uuid'; +import { CoolCommException } from '@cool-midway/core'; +import * as _ from 'lodash'; + +/** + * 文件上传 + */ +export class PluginUpload extends BasePluginHook implements BaseUpload { + /** + * 获得上传模式 + * @returns + */ + async getMode() { + return { + mode: MODETYPE.LOCAL, + type: MODETYPE.LOCAL, + }; + } + + /** + * 获得原始操作对象 + * @returns + */ + async getMetaFileObj() { + return; + } + + /** + * 下载并上传 + * @param url + * @param fileName + */ + async downAndUpload(url: string, fileName?: string) { + const { domain } = this.pluginInfo.config; + // 从url获取扩展名 + const extend = path.extname(url); + // 数据 + const data = url.includes('http') + ? await download(url) + : fs.readFileSync(url); + // 创建文件夹 + const dirPath = path.join( + this.app.getBaseDir(), + '..', + `public/uploads/${moment().format('YYYYMMDD')}` + ); + if (!fs.existsSync(dirPath)) { + fs.mkdirSync(dirPath, { recursive: true }); + } + fs.writeFileSync( + `${dirPath}/${fileName ? fileName : uuid() + extend}`, + data + ); + return `${domain}/public/${name}`; + } + + /** + * 指定Key(路径)上传,本地文件上传到存储服务 + * @param filePath 文件路径 + * @param key 路径一致会覆盖源文件 + */ + async uploadWithKey(filePath: any, key: any) { + const { domain } = this.pluginInfo.config; + const data = fs.readFileSync(filePath); + fs.writeFileSync(path.join(this.app.getBaseDir(), '..', key), data); + return domain + key; + } + + /** + * 上传文件 + * @param ctx + * @param key 文件路径 + */ + async upload(ctx: any) { + const { domain } = this.pluginInfo.config; + try { + const { key } = ctx.fields; + if (_.isEmpty(ctx.files)) { + throw new CoolCommException('上传文件为空'); + } + const file = ctx.files[0]; + const extension = file.filename.split('.').pop(); + const name = + moment().format('YYYYMMDD') + '/' + (key || `${uuid()}.${extension}`); + const target = path.join( + this.app.getBaseDir(), + '..', + `public/uploads/${name}` + ); + const dirPath = path.join( + this.app.getBaseDir(), + '..', + `public/uploads/${moment().format('YYYYMMDD')}` + ); + if (!fs.existsSync(dirPath)) { + fs.mkdirSync(dirPath); + } + const data = fs.readFileSync(file.data); + fs.writeFileSync(target, data); + return domain + '/public/uploads/' + name; + } catch (err) { + throw new CoolCommException('上传失败'); + } + } +} + +// 导出插件实例, Plugin名称不可修改 +export const Plugin = PluginUpload; diff --git a/src/modules/plugin/hooks/upload/interface.ts b/src/modules/plugin/hooks/upload/interface.ts new file mode 100644 index 0000000..4f0cdfc --- /dev/null +++ b/src/modules/plugin/hooks/upload/interface.ts @@ -0,0 +1,56 @@ +// 模式 +export enum MODETYPE { + // 本地 + LOCAL = 'local', + // 云存储 + CLOUD = 'cloud', + // 其他 + OTHER = 'other', +} + +/** + * 上传模式 + */ +export interface Mode { + // 模式 + mode: MODETYPE; + // 类型 + type: string; +} + +/** + * 文件上传 + */ +export interface BaseUpload { + /** + * 获得上传模式 + */ + getMode(): Promise; + + /** + * 获得原始操作对象 + * @returns + */ + getMetaFileObj(): Promise; + + /** + * 下载并上传 + * @param url + * @param fileName 文件名 + */ + downAndUpload(url: string, fileName?: string): Promise; + + /** + * 指定Key(路径)上传,本地文件上传到存储服务 + * @param filePath 文件路径 + * @param key 路径一致会覆盖源文件 + */ + uploadWithKey(filePath, key): Promise; + + /** + * 上传文件 + * @param ctx + * @param key 文件路径 + */ + upload(ctx): Promise; +} diff --git a/src/modules/plugin/interface.ts b/src/modules/plugin/interface.ts new file mode 100644 index 0000000..dffc225 --- /dev/null +++ b/src/modules/plugin/interface.ts @@ -0,0 +1,23 @@ +/** + * 插件信息 + */ +export interface PluginInfo { + /** 名称 */ + name?: string; + /** 唯一标识 */ + key?: string; + /** 钩子 */ + hook?: string; + /** 版本 */ + version?: string; + /** 描述 */ + description?: string; + /** 作者 */ + author?: string; + /** logo */ + logo?: string; + /** README 使用说明 */ + readme?: string; + /** 配置 */ + config?: any; +} diff --git a/src/modules/plugin/service/center.ts b/src/modules/plugin/service/center.ts new file mode 100644 index 0000000..a981958 --- /dev/null +++ b/src/modules/plugin/service/center.ts @@ -0,0 +1,106 @@ +import { Provide } from '@midwayjs/decorator'; +import { + App, + IMidwayApplication, + Init, + Scope, + ScopeEnum, +} from '@midwayjs/core'; +import * as fs from 'fs'; +import * as path from 'path'; +import { PluginInfoEntity } from '../entity/info'; +import { InjectEntityModel } from '@midwayjs/typeorm'; +import { Repository } from 'typeorm'; +import { PluginInfo } from '../interface'; + +/** + * 插件中心 + */ +@Provide() +@Scope(ScopeEnum.Singleton) +export class PluginCenterService { + // 插件列表 + plugins: Map = new Map(); + + // 插件配置 + pluginInfos: Map = new Map(); + + @App() + app: IMidwayApplication; + + @InjectEntityModel(PluginInfoEntity) + pluginInfoEntity: Repository; + + @Init() + async init() { + this.plugins.clear(); + await this.initHooks(); + await this.initPlugin(); + } + + /** + * 注册插件 + * @param key + * @param cls + */ + async register(key: string, cls: any) { + this.plugins.set(key, cls); + } + + /** + * 初始化钩子 + */ + async initHooks() { + const hooksPath = path.join( + this.app.getBaseDir(), + 'modules', + 'plugin', + 'hooks' + ); + for (const key of fs.readdirSync(hooksPath)) { + const stat = fs.statSync(path.join(hooksPath, key)); + if (!stat.isDirectory()) { + continue; + } + const { Plugin } = await import(path.join(hooksPath, key, 'index')); + await this.register(key, Plugin); + this.pluginInfos.set(key, { + name: key, + config: this.app.getConfig('module.plugin.hooks.' + key), + }); + } + } + + /** + * 初始化插件 + */ + async initPlugin() { + const plugins = await this.pluginInfoEntity.findBy({ status: 1 }); + for (const plugin of plugins) { + const instance = await this.getInstance(plugin.content.data); + this.pluginInfos.set(plugin.keyName, { + ...plugin.pluginJson, + config: plugin.config, + }); + if (plugin.hook) { + await this.register(plugin.hook, instance); + } else { + await this.register(plugin.keyName, instance); + } + } + } + + /** + * 获得实例 + * @param content + * @returns + */ + async getInstance(content: string) { + let _instance; + eval(` + ${content} + _instance = Plugin; + `); + return _instance; + } +} diff --git a/src/modules/plugin/service/info.ts b/src/modules/plugin/service/info.ts new file mode 100644 index 0000000..b25dd94 --- /dev/null +++ b/src/modules/plugin/service/info.ts @@ -0,0 +1,204 @@ +import { App, Inject, Provide } from '@midwayjs/decorator'; +import { BaseService, CoolCommException } from '@cool-midway/core'; +import { InjectEntityModel } from '@midwayjs/typeorm'; +import { Not, Repository } from 'typeorm'; +import { PluginInfoEntity } from '../entity/info'; +import { IMidwayApplication, IMidwayContext } from '@midwayjs/core'; +import * as decompress from 'decompress'; +import * as _ from 'lodash'; +import { PluginInfo } from '../interface'; +import { PluginCenterService } from './center'; +import * as fs from 'fs'; + +/** + * 插件信息 + */ +@Provide() +export class PluginService extends BaseService { + @InjectEntityModel(PluginInfoEntity) + pluginInfoEntity: Repository; + + @Inject() + ctx: IMidwayContext; + + @App() + app: IMidwayApplication; + + @Inject() + pluginCenterService: PluginCenterService; + + /** + * 初始化 + * @param data + * @param type + */ + async modifyAfter() { + await this.pluginCenterService.init(); + } + + /** + * 更新 + * @param param + */ + async update(param: any) { + const old = await this.pluginInfoEntity.findOneBy({ id: param.id }); + // 启用插件,禁用同名插件 + if (old.hook && param.status == 1 && old.status != param.status) { + await this.pluginInfoEntity.update( + { hook: old.hook, status: 1, id: Not(old.id) }, + { status: 0 } + ); + } + await super.update(param); + } + + /** + * 调用插件 + * @param key 插件key + * @param method 方法 + * @param params 参数 + * @returns + */ + async invoke(key: string, method: string, ...params) { + // 实例化 + const instance = new (await this.pluginCenterService.plugins.get(key))(); + await instance.init( + this.pluginCenterService.pluginInfos.get(key), + this.ctx, + this.app + ); + return await instance[method](...params); + } + + /** + * 检查 + * @param filePath + */ + async check(filePath: string) { + let data; + try { + data = await this.data(filePath); + } catch (e) { + return { + type: 0, + message: `插件信息不完整,请检查${data.errorData}`, + }; + } + const check = await this.pluginInfoEntity.findOneBy({ + keyName: data.pluginJson.key, + }); + if (check && !check.hook) { + return { + type: 1, + message: '插件已存在,继续安装将覆盖', + }; + } + if (check && check.hook && check.status == 1) { + return { + type: 2, + message: + '已存在同名Hook插件,你可以继续安装,但是多个相同的Hook插件只能同时开启一个', + }; + } + return { + type: 3, + message: '检查通过', + }; + } + + /** + * 获得插件数据 + * @param filePath + */ + async data(filePath: string): Promise<{ + pluginJson: any; + readme: string; + logo: string; + content: string; + errorData: string; + }> { + // const plugin = await download(encodeURI(url)); + const files = await decompress(filePath); + let errorData; + let pluginJson: PluginInfo, readme: string, logo: string, content: string; + try { + errorData = 'plugin.json'; + pluginJson = JSON.parse( + _.find(files, { path: 'plugin.json', type: 'file' }).data.toString() + ); + errorData = 'readme'; + readme = _.find(files, { + path: pluginJson.readme, + type: 'file', + }).data.toString(); + errorData = 'logo'; + logo = _.find(files, { + path: pluginJson.logo, + type: 'file', + }).data.toString('base64'); + content = _.find(files, { + path: 'src/index.js', + type: 'file', + }).data.toString(); + } catch (e) { + throw new CoolCommException('插件信息不完整'); + } + return { + pluginJson, + readme, + logo, + content, + errorData, + }; + } + + /** + * 安装插件 + * @param file 文件 + * @param force 是否强制安装 + */ + async install(filePath: string, force = false) { + const forceBool = typeof force === 'string' ? force === 'true' : force; + const checkResult = await this.check(filePath); + if (checkResult.type != 3 && !forceBool) { + return checkResult; + } + const { pluginJson, readme, logo, content } = await this.data(filePath); + const check = await this.pluginInfoEntity.findOneBy({ + keyName: pluginJson.key, + }); + const data = { + name: pluginJson.name, + keyName: pluginJson.key, + version: pluginJson.version, + author: pluginJson.author, + hook: pluginJson.hook, + readme, + logo, + content: { + type: 'comm', + data: content, + }, + description: pluginJson.description, + pluginJson, + config: pluginJson.config, + status: 1, + } as PluginInfoEntity; + // 存在同名插件,更新,保留配置 + if (check) { + await this.pluginInfoEntity.update(check.id, { + ...data, + status: check.status, + config: { + ...pluginJson.config, + ...check.config, + }, + }); + } else { + // 全新安装 + await this.pluginInfoEntity.insert(data); + } + // 初始化插件 + await this.pluginCenterService.init(); + } +} diff --git a/src/modules/recycle/menu.json b/src/modules/recycle/menu.json deleted file mode 100644 index 031d25d..0000000 --- a/src/modules/recycle/menu.json +++ /dev/null @@ -1,64 +0,0 @@ -[ - { - "name": "数据管理", - "router": null, - "perms": null, - "type": 0, - "icon": "icon-data", - "orderNum": 3, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [ - { - "name": "数据回收站", - "router": "/recycle/data", - "perms": null, - "type": 1, - "icon": "icon-delete", - "orderNum": 1, - "viewPath": "modules/recycle/views/data.vue", - "keepAlive": true, - "isShow": true, - "childMenus": [ - { - "name": "恢复数据", - "router": null, - "perms": "recycle:data:restore", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "单个信息", - "router": null, - "perms": "recycle:data:info", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "分页查询", - "router": null, - "perms": "recycle:data:page", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - } - ] - } - ] - } -] \ No newline at end of file diff --git a/src/modules/space/menu.json b/src/modules/space/menu.json deleted file mode 100644 index 73e2e7f..0000000 --- a/src/modules/space/menu.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "name": "文件管理", - "router": "/upload/list", - "perms": null, - "type": 1, - "icon": "icon-log", - "orderNum": 97, - "viewPath": "modules/upload/views/list.vue", - "keepAlive": true, - "isShow": true, - "childMenus": [] - } -] \ No newline at end of file diff --git a/src/modules/task/menu.json b/src/modules/task/menu.json deleted file mode 100644 index 8de8962..0000000 --- a/src/modules/task/menu.json +++ /dev/null @@ -1,40 +0,0 @@ -[ - { - "name": "任务管理", - "router": null, - "perms": null, - "type": 0, - "icon": "icon-activity", - "orderNum": 97, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [ - { - "name": "任务列表", - "router": "/task/list", - "perms": null, - "type": 1, - "icon": "icon-menu", - "orderNum": 0, - "viewPath": "modules/task/views/list.vue", - "keepAlive": true, - "isShow": true, - "childMenus": [ - { - "name": "权限", - "router": null, - "perms": "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", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - } - ] - } - ] - } -] \ No newline at end of file diff --git a/src/modules/user/menu.json b/src/modules/user/menu.json deleted file mode 100644 index 4031c91..0000000 --- a/src/modules/user/menu.json +++ /dev/null @@ -1,100 +0,0 @@ -[ - { - "name": "用户管理", - "router": null, - "perms": null, - "type": 0, - "icon": "icon-user", - "orderNum": 8, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [ - { - "name": "用户列表", - "router": "/user/list", - "perms": null, - "type": 1, - "icon": "icon-menu", - "orderNum": 1, - "viewPath": "modules/user/views/list.vue", - "keepAlive": true, - "isShow": true, - "childMenus": [ - { - "name": "删除", - "router": null, - "perms": "user:info:delete", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "修改", - "router": null, - "perms": "user:info:update,user:info:info", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "单个信息", - "router": null, - "perms": "user:info:info", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "列表查询", - "router": null, - "perms": "user:info:list", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "分页查询", - "router": null, - "perms": "user:info:page", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - }, - { - "name": "新增", - "router": null, - "perms": "user:info:add", - "type": 2, - "icon": null, - "orderNum": 0, - "viewPath": null, - "keepAlive": true, - "isShow": true, - "childMenus": [] - } - ] - } - ] - } -] \ No newline at end of file diff --git a/src/welcome.ts b/src/welcome.ts index 16031d4..f7481ab 100644 --- a/src/welcome.ts +++ b/src/welcome.ts @@ -1,5 +1,6 @@ import { Controller, Get, Inject } from '@midwayjs/decorator'; import { Context } from '@midwayjs/koa'; +import * as packageJson from '../package.json'; /** * 欢迎界面 @@ -12,7 +13,7 @@ export class WelcomeController { @Get('/', { summary: '欢迎界面' }) public async welcome() { await this.ctx.render('welcome', { - text: 'HELLO COOL-ADMIN v7.0 一个项目用COOL就够了!!!', + text: `HELLO COOL-ADMIN v${packageJson.version} 一个项目用COOL就够了!!!`, }); } } diff --git a/tsconfig.json b/tsconfig.json index 4ec9192..ea66150 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,9 +8,10 @@ "emitDecoratorMetadata": true, "inlineSourceMap":true, "noImplicitThis": true, - "noUnusedLocals": true, + "noUnusedLocals": false, "stripInternal": true, "skipLibCheck": true, + "resolveJsonModule": true, "pretty": true, "declaration": true, "noImplicitAny": false,