mirror of
https://github.com/cool-team-official/cool-admin-midway.git
synced 2026-02-01 14:08:12 +00:00
发布6.x
This commit is contained in:
parent
95545591f2
commit
375a93638b
9
.gitignore
vendored
Executable file → Normal file
9
.gitignore
vendored
Executable file → Normal file
@ -1,4 +1,5 @@
|
|||||||
logs/
|
logs/
|
||||||
|
cache/
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
yarn-error.log
|
yarn-error.log
|
||||||
node_modules/
|
node_modules/
|
||||||
@ -9,11 +10,11 @@ dist/
|
|||||||
.idea/
|
.idea/
|
||||||
run/
|
run/
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
launch.json
|
||||||
*.sw*
|
*.sw*
|
||||||
*.un~
|
*.un~
|
||||||
.tsbuildinfo
|
.tsbuildinfo
|
||||||
.tsbuildinfo.*
|
.tsbuildinfo.*
|
||||||
.audit
|
data/*
|
||||||
typings/
|
pnpm-lock.yaml
|
||||||
public/uploads/
|
public/uploads/*
|
||||||
cache/
|
|
||||||
|
|||||||
9
.hintrc
Normal file
9
.hintrc
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"extends": [
|
||||||
|
"development"
|
||||||
|
],
|
||||||
|
"hints": {
|
||||||
|
"typescript-config/consistent-casing": "off",
|
||||||
|
"typescript-config/strict": "off"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
.vscode/controller.code-snippets
vendored
1
.vscode/controller.code-snippets
vendored
@ -8,7 +8,6 @@
|
|||||||
"/**",
|
"/**",
|
||||||
" * 描述",
|
" * 描述",
|
||||||
" */",
|
" */",
|
||||||
"@Provide()",
|
|
||||||
"@CoolController({",
|
"@CoolController({",
|
||||||
" api: ['add', 'delete', 'update', 'info', 'list', 'page'],",
|
" api: ['add', 'delete', 'update', 'info', 'list', 'page'],",
|
||||||
" entity: 实体,",
|
" entity: 实体,",
|
||||||
|
|||||||
5
.vscode/entity.code-snippets
vendored
5
.vscode/entity.code-snippets
vendored
@ -2,14 +2,13 @@
|
|||||||
"entity": {
|
"entity": {
|
||||||
"prefix": "entity",
|
"prefix": "entity",
|
||||||
"body": [
|
"body": [
|
||||||
"import { EntityModel } from '@midwayjs/orm';",
|
|
||||||
"import { BaseEntity } from '@cool-midway/core';",
|
"import { BaseEntity } from '@cool-midway/core';",
|
||||||
"import { Column } from 'typeorm';",
|
"import { Column, Entity } from 'typeorm';",
|
||||||
"",
|
"",
|
||||||
"/**",
|
"/**",
|
||||||
" * 描述",
|
" * 描述",
|
||||||
" */",
|
" */",
|
||||||
"@EntityModel('xxx_xxx_xxx')",
|
"@Entity('xxx_xxx_xxx')",
|
||||||
"export class XxxEntity extends BaseEntity {",
|
"export class XxxEntity extends BaseEntity {",
|
||||||
" @Column({ comment: '描述' })",
|
" @Column({ comment: '描述' })",
|
||||||
" xxx: string;",
|
" xxx: string;",
|
||||||
|
|||||||
1
.vscode/event.code-snippets
vendored
1
.vscode/event.code-snippets
vendored
@ -2,7 +2,6 @@
|
|||||||
"event": {
|
"event": {
|
||||||
"prefix": "event",
|
"prefix": "event",
|
||||||
"body": [
|
"body": [
|
||||||
"import { Provide, Scope, ScopeEnum } from '@midwayjs/decorator';",
|
|
||||||
"import { CoolEvent, Event } from '@cool-midway/core';",
|
"import { CoolEvent, Event } from '@cool-midway/core';",
|
||||||
"",
|
"",
|
||||||
"/**",
|
"/**",
|
||||||
|
|||||||
21
.vscode/launch.json
vendored
21
.vscode/launch.json
vendored
@ -1,21 +0,0 @@
|
|||||||
{
|
|
||||||
// 使用 IntelliSense 了解相关属性。
|
|
||||||
// 悬停以查看现有属性的描述。
|
|
||||||
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
|
|
||||||
"version": "0.2.0",
|
|
||||||
"configurations": [
|
|
||||||
{
|
|
||||||
"type": "pwa-node",
|
|
||||||
"request": "launch",
|
|
||||||
"name": "Launch Program",
|
|
||||||
"skipFiles": [
|
|
||||||
"<node_internals>/**"
|
|
||||||
],
|
|
||||||
"program": "${workspaceFolder}/bootstrap.js",
|
|
||||||
"preLaunchTask": "tsc: build - tsconfig.json",
|
|
||||||
"outFiles": [
|
|
||||||
"${workspaceFolder}/dist/**/*.js"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
2
.vscode/service.code-snippets
vendored
2
.vscode/service.code-snippets
vendored
@ -4,7 +4,7 @@
|
|||||||
"body": [
|
"body": [
|
||||||
"import { Provide } from '@midwayjs/decorator';",
|
"import { Provide } from '@midwayjs/decorator';",
|
||||||
"import { BaseService } from '@cool-midway/core';",
|
"import { BaseService } from '@cool-midway/core';",
|
||||||
"import { InjectEntityModel } from '@midwayjs/orm';",
|
"import { InjectEntityModel } from '@midwayjs/typeorm';",
|
||||||
"import { Repository } from 'typeorm';",
|
"import { Repository } from 'typeorm';",
|
||||||
"",
|
"",
|
||||||
"/**",
|
"/**",
|
||||||
|
|||||||
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"liveServer.settings.port": 5501
|
|
||||||
}
|
|
||||||
2
LICENSE
2
LICENSE
@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2021 cool-team-official
|
Copyright (c) 2023 cool-team-official
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
36
docker-compose.yml
Normal file
36
docker-compose.yml
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
# 本地数据库环境
|
||||||
|
# 数据存放在当前目录下的 data里
|
||||||
|
# 推荐使用安装了docker扩展的vscode打开目录 在本文件上右键可以快速启动,停止
|
||||||
|
# 如不需要相关容器开机自启动,可注释掉 restart: always
|
||||||
|
# 如遇端口冲突 可调整ports下 :前面的端口号
|
||||||
|
version: "3.1"
|
||||||
|
|
||||||
|
services:
|
||||||
|
coolDB:
|
||||||
|
image: mysql
|
||||||
|
command:
|
||||||
|
--default-authentication-plugin=mysql_native_password
|
||||||
|
--sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
|
||||||
|
--group_concat_max_len=102400
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- ./data/mysql/:/var/lib/mysql/
|
||||||
|
environment:
|
||||||
|
TZ: Asia/Shanghai # 指定时区
|
||||||
|
MYSQL_ROOT_PASSWORD: "123456" # 配置root用户密码
|
||||||
|
MYSQL_DATABASE: "cool" # 业务库名
|
||||||
|
MYSQL_USER: "root" # 业务库用户名
|
||||||
|
MYSQL_PASSWORD: "123456" # 业务库密码
|
||||||
|
ports:
|
||||||
|
- 3306:3306
|
||||||
|
|
||||||
|
coolRedis:
|
||||||
|
image: redis
|
||||||
|
#command: --requirepass "12345678" # redis库密码,不需要密码注释本行
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
TZ: Asia/Shanghai # 指定时区
|
||||||
|
volumes:
|
||||||
|
- ./data/redis/:/data/
|
||||||
|
ports:
|
||||||
|
- 6379:6379
|
||||||
83
package.json
Executable file → Normal file
83
package.json
Executable file → Normal file
@ -1,61 +1,68 @@
|
|||||||
{
|
{
|
||||||
"name": "cool-admin",
|
"name": "cool-admin",
|
||||||
"version": "5.0.0",
|
"version": "6.0.0",
|
||||||
"description": "",
|
"description": "一个项目用COOL就够了",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@cool-midway/core": "^5.1.7",
|
"@cool-midway/cloud": "^6.0.0",
|
||||||
"@cool-midway/es": "^5.0.2",
|
"@cool-midway/core": "^6.0.0",
|
||||||
"@cool-midway/file": "^5.0.7",
|
"@cool-midway/file": "^6.0.0",
|
||||||
"@cool-midway/pay": "^5.0.0",
|
"@cool-midway/iot": "^6.0.0",
|
||||||
"@cool-midway/rpc": "^5.0.1",
|
"@cool-midway/pay": "^6.0.0",
|
||||||
"@cool-midway/task": "^5.0.1",
|
"@cool-midway/rpc": "^6.0.1",
|
||||||
"@midwayjs/bootstrap": "^3.2.0",
|
"@cool-midway/task": "^6.0.0",
|
||||||
"@midwayjs/core": "^3.2.0",
|
"@midwayjs/bootstrap": "^3.10.7",
|
||||||
"@midwayjs/decorator": "^3.1.6",
|
"@midwayjs/cache": "^3.10.9",
|
||||||
"@midwayjs/info": "^3.2.0",
|
"@midwayjs/core": "^3.10.7",
|
||||||
"@midwayjs/koa": "^3.2.0",
|
"@midwayjs/cross-domain": "^3.10.8",
|
||||||
"@midwayjs/logger": "^2.16.3",
|
"@midwayjs/decorator": "^3.10.7",
|
||||||
"@midwayjs/orm": "^3.2.0",
|
"@midwayjs/info": "^3.10.7",
|
||||||
"@midwayjs/socketio": "^3.2.0",
|
"@midwayjs/koa": "^3.10.7",
|
||||||
"@midwayjs/static-file": "^3.2.0",
|
"@midwayjs/logger": "^2.17.0",
|
||||||
"@midwayjs/task": "^3.2.2",
|
"@midwayjs/static-file": "^3.10.8",
|
||||||
"@midwayjs/validate": "^3.2.0",
|
"@midwayjs/task": "^3.6.0",
|
||||||
"@midwayjs/view-ejs": "^3.2.0",
|
"@midwayjs/typeorm": "^3.10.7",
|
||||||
"cfork": "^1.8.0",
|
"@midwayjs/validate": "^3.10.7",
|
||||||
|
"@midwayjs/view-ejs": "^3.10.7",
|
||||||
|
"cache-manager-fs-hash": "^1.0.0",
|
||||||
"ipip-ipdb": "^0.6.0",
|
"ipip-ipdb": "^0.6.0",
|
||||||
"jsonwebtoken": "^8.5.1",
|
"jsonwebtoken": "^9.0.0",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
|
"md5": "^2.3.0",
|
||||||
"mini-svg-data-uri": "^1.4.4",
|
"mini-svg-data-uri": "^1.4.4",
|
||||||
"mysql2": "^2.3.3",
|
"moment": "^2.29.4",
|
||||||
|
"mysql2": "^3.1.2",
|
||||||
"svg-captcha": "^1.4.0",
|
"svg-captcha": "^1.4.0",
|
||||||
"typeorm": "0.2.45"
|
"typeorm": "^0.3.12",
|
||||||
|
"uuid": "^9.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@midwayjs/cli": "1.3.12-beta.1",
|
"@midwayjs/cli": "^2.0.11",
|
||||||
"@midwayjs/mock": "^3.2.0",
|
"@midwayjs/mock": "^3.10.7",
|
||||||
"@types/jest": "^27.4.1",
|
"@types/jest": "^29.4.0",
|
||||||
"@types/koa": "^2.13.4",
|
"@types/koa": "^2.13.5",
|
||||||
"@types/node": "17",
|
"@types/node": "18",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"jest": "^27.5.1",
|
"jest": "^29.4.2",
|
||||||
"mwts": "^1.3.0",
|
"mwts": "^1.3.0",
|
||||||
"swagger-ui-dist": "^4.9.1",
|
"ts-jest": "^29.0.5",
|
||||||
"ts-jest": "^27.1.4",
|
"typescript": "~4.9.5"
|
||||||
"typescript": "^4.6.3"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12.0.0"
|
"node": ">=12.0.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start_single": "NODE_ENV=prod node ./bootstrap.js",
|
"start": "NODE_ENV=production node ./bootstrap.js",
|
||||||
"start": "NODE_ENV=prod node ./server.js",
|
|
||||||
"dev": "cross-env && cross-env NODE_ENV=local TS_NODE_TYPE_CHECK=false TS_NODE_TRANSPILE_ONLY=true midway-bin dev --ts",
|
"dev": "cross-env && cross-env NODE_ENV=local TS_NODE_TYPE_CHECK=false TS_NODE_TRANSPILE_ONLY=true midway-bin dev --ts",
|
||||||
"test": "midway-bin test --ts",
|
"test": "midway-bin test --ts",
|
||||||
"cov": "midway-bin cov --ts",
|
"cov": "midway-bin cov --ts",
|
||||||
"lint": "mwts check",
|
"lint": "mwts check",
|
||||||
"lint:fix": "mwts fix",
|
"lint:fix": "mwts fix",
|
||||||
"ci": "npm run cov",
|
"ci": "npm run cov",
|
||||||
"build": "midway-bin build -c"
|
"build": "midway-bin build -c",
|
||||||
|
"pm2:start": "pm2 start ./bootstrap.js -i max --name cool-admin",
|
||||||
|
"pm2:stop": "pm2 stop cool-admin & pm2 delete cool-admin",
|
||||||
|
"pm2:debug": "pm2-runtime start ./bootstrap.js -i max --name cool-admin"
|
||||||
},
|
},
|
||||||
"midway-bin-clean": [
|
"midway-bin-clean": [
|
||||||
".vscode/.tsbuildinfo",
|
".vscode/.tsbuildinfo",
|
||||||
@ -63,8 +70,8 @@
|
|||||||
],
|
],
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": ""
|
"url": "https://cool-js.com"
|
||||||
},
|
},
|
||||||
"author": "anonymous",
|
"author": "COOL",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 5.7 KiB |
51
server.js
51
server.js
@ -1,51 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
const cfork = require('cfork');
|
|
||||||
const util = require('util');
|
|
||||||
const path = require('path');
|
|
||||||
const os = require('os');
|
|
||||||
|
|
||||||
// 获取 cpu 核数
|
|
||||||
const cpuNumbers = os.cpus().length;
|
|
||||||
|
|
||||||
cfork({
|
|
||||||
exec: path.join(__dirname, './bootstrap.js'),
|
|
||||||
count: cpuNumbers,
|
|
||||||
})
|
|
||||||
.on('fork', worker => {
|
|
||||||
console.warn(
|
|
||||||
'[%s] [worker:%d] new worker start',
|
|
||||||
Date(),
|
|
||||||
worker.process.pid
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.on('disconnect', worker => {
|
|
||||||
console.warn(
|
|
||||||
'[%s] [master:%s] wroker:%s disconnect, exitedAfterDisconnect: %s, state: %s.',
|
|
||||||
Date(),
|
|
||||||
process.pid,
|
|
||||||
worker.process.pid,
|
|
||||||
worker.exitedAfterDisconnect,
|
|
||||||
worker.state
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.on('exit', (worker, code, signal) => {
|
|
||||||
const exitCode = worker.process.exitCode;
|
|
||||||
const err = new Error(
|
|
||||||
util.format(
|
|
||||||
'worker %s died (code: %s, signal: %s, exitedAfterDisconnect: %s, state: %s)',
|
|
||||||
worker.process.pid,
|
|
||||||
exitCode,
|
|
||||||
signal,
|
|
||||||
worker.exitedAfterDisconnect,
|
|
||||||
worker.state
|
|
||||||
)
|
|
||||||
);
|
|
||||||
err.name = 'WorkerDiedError';
|
|
||||||
console.error(
|
|
||||||
'[%s] [master:%s] wroker exit: %s',
|
|
||||||
Date(),
|
|
||||||
process.pid,
|
|
||||||
err.stack
|
|
||||||
);
|
|
||||||
});
|
|
||||||
@ -1,27 +1,25 @@
|
|||||||
import { CoolConfig } from '@cool-midway/core';
|
import { CoolConfig, MODETYPE } from '@cool-midway/core';
|
||||||
import { MODETYPE } from '@cool-midway/file';
|
|
||||||
import { MidwayConfig } from '@midwayjs/core';
|
import { MidwayConfig } from '@midwayjs/core';
|
||||||
// import * as redisStore from 'cache-manager-ioredis';
|
|
||||||
import * as fsStore from 'cache-manager-fs-hash';
|
import * as fsStore from 'cache-manager-fs-hash';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
// 修改成你自己独有的key
|
// use for cookie sign key, should change to your own and keep security
|
||||||
keys: 'cool-admin for node',
|
keys: 'cool-admin for node',
|
||||||
koa: {
|
koa: {
|
||||||
port: 8001,
|
port: 8001,
|
||||||
},
|
},
|
||||||
// 文件上传
|
|
||||||
upload: {
|
|
||||||
fileSize: '200mb',
|
|
||||||
whitelist: null,
|
|
||||||
},
|
|
||||||
// 模板渲染
|
// 模板渲染
|
||||||
view: {
|
view: {
|
||||||
mapping: {
|
mapping: {
|
||||||
'.html': 'ejs',
|
'.html': 'ejs',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// 本地缓存
|
// 文件上传
|
||||||
|
upload: {
|
||||||
|
fileSize: '200mb',
|
||||||
|
whitelist: null,
|
||||||
|
},
|
||||||
|
// 缓存 可切换成其他缓存如:redis http://midwayjs.org/docs/extensions/cache
|
||||||
cache: {
|
cache: {
|
||||||
store: fsStore,
|
store: fsStore,
|
||||||
options: {
|
options: {
|
||||||
@ -29,34 +27,12 @@ export default {
|
|||||||
ttl: -1,
|
ttl: -1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// redis缓存
|
|
||||||
// cache: {
|
|
||||||
// store: redisStore,
|
|
||||||
// options: {
|
|
||||||
// host: '127.0.0.1',
|
|
||||||
// port: 6379,
|
|
||||||
// password: '',
|
|
||||||
// db: 1,
|
|
||||||
// ttl: null,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// cool配置
|
|
||||||
cool: {
|
cool: {
|
||||||
// redis: {
|
|
||||||
// host: '127.0.0.1',
|
|
||||||
// port: 6379,
|
|
||||||
// db: 0,
|
|
||||||
// },
|
|
||||||
// 是否自动导入数据库
|
|
||||||
file: {
|
file: {
|
||||||
// 上传模式 本地上传或云存储
|
// 上传模式 本地上传或云存储
|
||||||
mode: MODETYPE.LOCAL,
|
mode: MODETYPE.LOCAL,
|
||||||
// 本地上传 文件地址前缀,当且仅当mode为LOCAL时生效
|
// 本地上传 文件地址前缀
|
||||||
domain: 'http://127.0.0.1:8001',
|
domain: 'http://127.0.0.1:8001',
|
||||||
},
|
},
|
||||||
} as CoolConfig,
|
} as CoolConfig,
|
||||||
} as
|
} as MidwayConfig;
|
||||||
| MidwayConfig
|
|
||||||
| {
|
|
||||||
cache: any;
|
|
||||||
};
|
|
||||||
|
|||||||
@ -5,22 +5,35 @@ import { MidwayConfig } from '@midwayjs/core';
|
|||||||
* 本地开发 npm run dev 读取的配置文件
|
* 本地开发 npm run dev 读取的配置文件
|
||||||
*/
|
*/
|
||||||
export default {
|
export default {
|
||||||
orm: {
|
typeorm: {
|
||||||
type: 'mysql',
|
dataSource: {
|
||||||
host: '127.0.0.1',
|
default: {
|
||||||
port: 3306,
|
type: 'mysql',
|
||||||
username: 'root',
|
host: '127.0.0.1',
|
||||||
password: '123456',
|
port: 3306,
|
||||||
database: 'cool',
|
username: 'root',
|
||||||
// 自动建表 注意:线上部署的时候不要使用,有可能导致数据丢失
|
password: '123456',
|
||||||
synchronize: true,
|
database: 'cool',
|
||||||
// 打印日志
|
// 自动建表 注意:线上部署的时候不要使用,有可能导致数据丢失
|
||||||
logging: true,
|
synchronize: true,
|
||||||
// 字符集
|
// 打印日志
|
||||||
charset: 'utf8mb4',
|
logging: false,
|
||||||
|
// 字符集
|
||||||
|
charset: 'utf8mb4',
|
||||||
|
// 是否开启缓存
|
||||||
|
cache: true,
|
||||||
|
// 实体路径
|
||||||
|
entities: ['**/modules/*/entity'],
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
cool: {
|
cool: {
|
||||||
// 是否自动导入数据库
|
// 是否自动导入数据库
|
||||||
initDB: true,
|
initDB: true,
|
||||||
|
// crud配置
|
||||||
|
crud: {
|
||||||
|
// 软删除
|
||||||
|
softDelete: true,
|
||||||
|
},
|
||||||
} as CoolConfig,
|
} as CoolConfig,
|
||||||
} as MidwayConfig;
|
} as MidwayConfig;
|
||||||
|
|||||||
@ -5,22 +5,30 @@ import { MidwayConfig } from '@midwayjs/core';
|
|||||||
* 本地开发 npm run dev 读取的配置文件
|
* 本地开发 npm run dev 读取的配置文件
|
||||||
*/
|
*/
|
||||||
export default {
|
export default {
|
||||||
orm: {
|
typeorm: {
|
||||||
type: 'mysql',
|
dataSource: {
|
||||||
host: '127.0.0.1',
|
default: {
|
||||||
port: 3306,
|
type: 'mysql',
|
||||||
username: 'root',
|
host: '127.0.0.1',
|
||||||
password: '123456',
|
port: 3306,
|
||||||
database: 'cool',
|
username: 'root',
|
||||||
// 自动建表 注意:线上部署的时候不要使用,有可能导致数据丢失
|
password: '123456',
|
||||||
synchronize: false,
|
database: 'cool',
|
||||||
// 打印日志
|
// 自动建表 注意:线上部署的时候不要使用,有可能导致数据丢失
|
||||||
logging: false,
|
synchronize: false,
|
||||||
// 字符集
|
// 打印日志
|
||||||
charset: 'utf8mb4',
|
logging: false,
|
||||||
|
// 字符集
|
||||||
|
charset: 'utf8mb4',
|
||||||
|
// 是否开启缓存
|
||||||
|
cache: true,
|
||||||
|
// 实体路径
|
||||||
|
entities: ['**/modules/*/entity'],
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
cool: {
|
cool: {
|
||||||
// 是否自动导入数据库
|
// 是否自动导入数据库,生产环境不建议开,用本地的数据库手动初始化
|
||||||
initDB: false,
|
initDB: false,
|
||||||
} as CoolConfig,
|
} as CoolConfig,
|
||||||
} as MidwayConfig;
|
} as MidwayConfig;
|
||||||
|
|||||||
@ -1,48 +1,51 @@
|
|||||||
|
import * as orm from '@midwayjs/typeorm';
|
||||||
import { Configuration, App } from '@midwayjs/decorator';
|
import { Configuration, App } from '@midwayjs/decorator';
|
||||||
import * as koa from '@midwayjs/koa';
|
import * as koa from '@midwayjs/koa';
|
||||||
import * as validate from '@midwayjs/validate';
|
import * as validate from '@midwayjs/validate';
|
||||||
import * as info from '@midwayjs/info';
|
import * as info from '@midwayjs/info';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
import * as staticFile from '@midwayjs/static-file';
|
|
||||||
import * as view from '@midwayjs/view-ejs';
|
import * as view from '@midwayjs/view-ejs';
|
||||||
import * as orm from '@midwayjs/orm';
|
import * as staticFile from '@midwayjs/static-file';
|
||||||
import * as cool from '@cool-midway/core';
|
|
||||||
import * as file from '@cool-midway/file';
|
|
||||||
import * as localTask from '@midwayjs/task';
|
import * as localTask from '@midwayjs/task';
|
||||||
// import * as socketio from '@midwayjs/socketio';
|
// import * as crossDomain from '@midwayjs/cross-domain';
|
||||||
|
import * as cool from '@cool-midway/core';
|
||||||
|
import * as cloud from '@cool-midway/cloud';
|
||||||
|
import * as file from '@cool-midway/file';
|
||||||
|
// import * as rpc from '@cool-midway/rpc';
|
||||||
// import * as task from '@cool-midway/task';
|
// import * as task from '@cool-midway/task';
|
||||||
// import * as pay from '@cool-midway/pay';
|
// import * as pay from '@cool-midway/pay';
|
||||||
// import * as es from '@cool-midway/es';
|
// import * as iot from '@cool-midway/iot';
|
||||||
// import * as rpc from '@cool-midway/rpc';
|
|
||||||
|
|
||||||
@Configuration({
|
@Configuration({
|
||||||
imports: [
|
imports: [
|
||||||
// http://koajs.cn/
|
// https://koajs.com/
|
||||||
koa,
|
koa,
|
||||||
// 参数验证 http://midwayjs.org/docs/extensions/validate
|
// 是否开启跨域(注:顺序不能乱放!!!) http://www.midwayjs.org/docs/extensions/cross_domain
|
||||||
validate,
|
// crossDomain,
|
||||||
// 本地任务 http://midwayjs.org/docs/extensions/task
|
// 模板渲染 https://midwayjs.org/docs/extensions/render
|
||||||
localTask,
|
|
||||||
// 模板渲染 http://midwayjs.org/docs/extensions/render
|
|
||||||
view,
|
view,
|
||||||
// 静态文件托管 http://midwayjs.org/docs/extensions/static_file
|
// 静态文件托管 https://midwayjs.org/docs/extensions/static_file
|
||||||
staticFile,
|
staticFile,
|
||||||
// typeorm https://typeorm.io 打不开? https://typeorm.biunav.com/zh/
|
// orm https://midwayjs.org/docs/extensions/orm
|
||||||
orm,
|
orm,
|
||||||
// socketio http://www.midwayjs.org/docs/extensions/socketio
|
// 参数验证 https://midwayjs.org/docs/extensions/validate
|
||||||
// socketio,
|
validate,
|
||||||
// cool-admin 官方组件 https://www.cool-js.com
|
// 本地任务 http://midwayjs.org/docs/legacy/task
|
||||||
|
localTask,
|
||||||
|
// cool-admin 官方组件 https://cool-js.com
|
||||||
cool,
|
cool,
|
||||||
// 文件上传 阿里云存储 腾讯云存储 七牛云存储
|
// 文件上传 本地 阿里云存储 腾讯云存储 七牛云存储
|
||||||
file,
|
file,
|
||||||
// 任务与队列
|
|
||||||
// task,
|
|
||||||
// 支付 微信与支付宝
|
|
||||||
// pay,
|
|
||||||
// elasticsearch
|
|
||||||
// es,
|
|
||||||
// rpc 微服务 远程调用
|
// rpc 微服务 远程调用
|
||||||
// rpc,
|
// rpc,
|
||||||
|
// 任务与队列
|
||||||
|
// task,
|
||||||
|
// cool-admin 云开发组件
|
||||||
|
cloud,
|
||||||
|
// 支付(微信、支付宝) https://cool-js.com/admin/node/core/pay.html
|
||||||
|
// pay,
|
||||||
|
// 物联网开发,如MQTT支持等
|
||||||
|
// iot,
|
||||||
{
|
{
|
||||||
component: info,
|
component: info,
|
||||||
enabledEnvironment: ['local'],
|
enabledEnvironment: ['local'],
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Inject, Provide } from '@midwayjs/decorator';
|
import { Body, Inject, Post, Provide } from '@midwayjs/decorator';
|
||||||
import { CoolController, BaseController } from '@cool-midway/core';
|
import { CoolController, BaseController } from '@cool-midway/core';
|
||||||
import { BaseSysMenuEntity } from '../../../entity/sys/menu';
|
import { BaseSysMenuEntity } from '../../../entity/sys/menu';
|
||||||
import { BaseSysMenuService } from '../../../service/sys/menu';
|
import { BaseSysMenuService } from '../../../service/sys/menu';
|
||||||
@ -15,4 +15,21 @@ import { BaseSysMenuService } from '../../../service/sys/menu';
|
|||||||
export class BaseSysMenuController extends BaseController {
|
export class BaseSysMenuController extends BaseController {
|
||||||
@Inject()
|
@Inject()
|
||||||
baseSysMenuService: BaseSysMenuService;
|
baseSysMenuService: BaseSysMenuService;
|
||||||
|
|
||||||
|
@Post('/parse', { summary: '解析' })
|
||||||
|
async parse(
|
||||||
|
@Body('entity') entity: string,
|
||||||
|
@Body('controller') controller: string,
|
||||||
|
@Body('module') module: string
|
||||||
|
) {
|
||||||
|
return this.ok(
|
||||||
|
await this.baseSysMenuService.parse(entity, controller, module)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('/create', { summary: '创建代码' })
|
||||||
|
async create(@Body() body) {
|
||||||
|
await this.baseSysMenuService.create(body);
|
||||||
|
return this.ok();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,10 @@
|
|||||||
import { Column, Index } from 'typeorm';
|
import { Column, Index, Entity } from 'typeorm';
|
||||||
import { EntityModel } from '@midwayjs/orm';
|
|
||||||
import { BaseEntity } from '@cool-midway/core';
|
import { BaseEntity } from '@cool-midway/core';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 系统配置
|
* 系统配置
|
||||||
*/
|
*/
|
||||||
@EntityModel('base_sys_conf')
|
@Entity('base_sys_conf')
|
||||||
export class BaseSysConfEntity extends BaseEntity {
|
export class BaseSysConfEntity extends BaseEntity {
|
||||||
@Index({ unique: true })
|
@Index({ unique: true })
|
||||||
@Column({ comment: '配置键' })
|
@Column({ comment: '配置键' })
|
||||||
|
|||||||
@ -1,11 +1,10 @@
|
|||||||
import { EntityModel } from '@midwayjs/orm';
|
|
||||||
import { BaseEntity } from '@cool-midway/core';
|
import { BaseEntity } from '@cool-midway/core';
|
||||||
import { Column } from 'typeorm';
|
import { Column, Entity } from 'typeorm';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 部门
|
* 部门
|
||||||
*/
|
*/
|
||||||
@EntityModel('base_sys_department')
|
@Entity('base_sys_department')
|
||||||
export class BaseSysDepartmentEntity extends BaseEntity {
|
export class BaseSysDepartmentEntity extends BaseEntity {
|
||||||
@Column({ comment: '部门名称' })
|
@Column({ comment: '部门名称' })
|
||||||
name: string;
|
name: string;
|
||||||
|
|||||||
@ -1,11 +1,10 @@
|
|||||||
import { EntityModel } from '@midwayjs/orm';
|
|
||||||
import { BaseEntity } from '@cool-midway/core';
|
import { BaseEntity } from '@cool-midway/core';
|
||||||
import { Column, Index } from 'typeorm';
|
import { Column, Index, Entity } from 'typeorm';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 系统日志
|
* 系统日志
|
||||||
*/
|
*/
|
||||||
@EntityModel('base_sys_log')
|
@Entity('base_sys_log')
|
||||||
export class BaseSysLogEntity extends BaseEntity {
|
export class BaseSysLogEntity extends BaseEntity {
|
||||||
@Index()
|
@Index()
|
||||||
@Column({ comment: '用户ID', nullable: true, type: 'bigint' })
|
@Column({ comment: '用户ID', nullable: true, type: 'bigint' })
|
||||||
@ -16,13 +15,13 @@ export class BaseSysLogEntity extends BaseEntity {
|
|||||||
action: string;
|
action: string;
|
||||||
|
|
||||||
@Index()
|
@Index()
|
||||||
@Column({ comment: 'ip', nullable: true, length: 50 })
|
@Column({ comment: 'ip', nullable: true })
|
||||||
ip: string;
|
ip: string;
|
||||||
|
|
||||||
@Index()
|
@Index()
|
||||||
@Column({ comment: 'ip地址', nullable: true, length: 50 })
|
@Column({ comment: 'ip地址', nullable: true, length: 50 })
|
||||||
ipAddr: string;
|
ipAddr: string;
|
||||||
|
|
||||||
@Column({ comment: '参数', nullable: true, type: 'text' })
|
@Column({ comment: '参数', nullable: true, type: 'json' })
|
||||||
params: string;
|
params: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,10 @@
|
|||||||
import { EntityModel } from '@midwayjs/orm';
|
|
||||||
import { BaseEntity } from '@cool-midway/core';
|
import { BaseEntity } from '@cool-midway/core';
|
||||||
import { Column } from 'typeorm';
|
import { Column, Entity } from 'typeorm';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 菜单
|
* 菜单
|
||||||
*/
|
*/
|
||||||
@EntityModel('base_sys_menu')
|
@Entity('base_sys_menu')
|
||||||
export class BaseSysMenuEntity extends BaseEntity {
|
export class BaseSysMenuEntity extends BaseEntity {
|
||||||
@Column({ comment: '父菜单ID', type: 'bigint', nullable: true })
|
@Column({ comment: '父菜单ID', type: 'bigint', nullable: true })
|
||||||
parentId: number;
|
parentId: number;
|
||||||
@ -20,7 +19,7 @@ export class BaseSysMenuEntity extends BaseEntity {
|
|||||||
perms: string;
|
perms: string;
|
||||||
|
|
||||||
@Column({
|
@Column({
|
||||||
comment: '类型 0:目录 1:菜单 2:按钮',
|
comment: '类型 0-目录 1-菜单 2-按钮',
|
||||||
default: 0,
|
default: 0,
|
||||||
type: 'tinyint',
|
type: 'tinyint',
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,11 +1,10 @@
|
|||||||
import { EntityModel } from '@midwayjs/orm';
|
|
||||||
import { BaseEntity } from '@cool-midway/core';
|
import { BaseEntity } from '@cool-midway/core';
|
||||||
import { Column, Index } from 'typeorm';
|
import { Column, Index, Entity } from 'typeorm';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 参数配置
|
* 参数配置
|
||||||
*/
|
*/
|
||||||
@EntityModel('base_sys_param')
|
@Entity('base_sys_param')
|
||||||
export class BaseSysParamEntity extends BaseEntity {
|
export class BaseSysParamEntity extends BaseEntity {
|
||||||
@Index()
|
@Index()
|
||||||
@Column({ comment: '键位' })
|
@Column({ comment: '键位' })
|
||||||
|
|||||||
@ -1,11 +1,10 @@
|
|||||||
import { EntityModel } from '@midwayjs/orm';
|
|
||||||
import { BaseEntity } from '@cool-midway/core';
|
import { BaseEntity } from '@cool-midway/core';
|
||||||
import { Column, Index } from 'typeorm';
|
import { Column, Index, Entity } from 'typeorm';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 角色
|
* 角色
|
||||||
*/
|
*/
|
||||||
@EntityModel('base_sys_role')
|
@Entity('base_sys_role')
|
||||||
export class BaseSysRoleEntity extends BaseEntity {
|
export class BaseSysRoleEntity extends BaseEntity {
|
||||||
@Column({ comment: '用户ID' })
|
@Column({ comment: '用户ID' })
|
||||||
userId: string;
|
userId: string;
|
||||||
@ -23,4 +22,10 @@ export class BaseSysRoleEntity extends BaseEntity {
|
|||||||
|
|
||||||
@Column({ comment: '数据权限是否关联上下级', default: 1 })
|
@Column({ comment: '数据权限是否关联上下级', default: 1 })
|
||||||
relevance: number;
|
relevance: number;
|
||||||
|
|
||||||
|
@Column({ comment: '菜单权限', type: 'json' })
|
||||||
|
menuIdList: number[];
|
||||||
|
|
||||||
|
@Column({ comment: '部门权限', type: 'json' })
|
||||||
|
departmentIdList: number[];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,10 @@
|
|||||||
import { EntityModel } from '@midwayjs/orm';
|
|
||||||
import { BaseEntity } from '@cool-midway/core';
|
import { BaseEntity } from '@cool-midway/core';
|
||||||
import { Column } from 'typeorm';
|
import { Column, Entity } from 'typeorm';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 角色部门
|
* 角色部门
|
||||||
*/
|
*/
|
||||||
@EntityModel('base_sys_role_department')
|
@Entity('base_sys_role_department')
|
||||||
export class BaseSysRoleDepartmentEntity extends BaseEntity {
|
export class BaseSysRoleDepartmentEntity extends BaseEntity {
|
||||||
@Column({ comment: '角色ID', type: 'bigint' })
|
@Column({ comment: '角色ID', type: 'bigint' })
|
||||||
roleId: number;
|
roleId: number;
|
||||||
|
|||||||
@ -1,11 +1,10 @@
|
|||||||
import { EntityModel } from '@midwayjs/orm';
|
|
||||||
import { BaseEntity } from '@cool-midway/core';
|
import { BaseEntity } from '@cool-midway/core';
|
||||||
import { Column } from 'typeorm';
|
import { Column, Entity } from 'typeorm';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 角色菜单
|
* 角色菜单
|
||||||
*/
|
*/
|
||||||
@EntityModel('base_sys_role_menu')
|
@Entity('base_sys_role_menu')
|
||||||
export class BaseSysRoleMenuEntity extends BaseEntity {
|
export class BaseSysRoleMenuEntity extends BaseEntity {
|
||||||
@Column({ comment: '角色ID', type: 'bigint' })
|
@Column({ comment: '角色ID', type: 'bigint' })
|
||||||
roleId: number;
|
roleId: number;
|
||||||
|
|||||||
@ -1,11 +1,10 @@
|
|||||||
import { EntityModel } from '@midwayjs/orm';
|
|
||||||
import { BaseEntity } from '@cool-midway/core';
|
import { BaseEntity } from '@cool-midway/core';
|
||||||
import { Column, Index } from 'typeorm';
|
import { Column, Index, Entity } from 'typeorm';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 系统用户
|
* 系统用户
|
||||||
*/
|
*/
|
||||||
@EntityModel('base_sys_user')
|
@Entity('base_sys_user')
|
||||||
export class BaseSysUserEntity extends BaseEntity {
|
export class BaseSysUserEntity extends BaseEntity {
|
||||||
@Index()
|
@Index()
|
||||||
@Column({ comment: '部门ID', type: 'bigint', nullable: true })
|
@Column({ comment: '部门ID', type: 'bigint', nullable: true })
|
||||||
|
|||||||
@ -1,11 +1,10 @@
|
|||||||
import { EntityModel } from '@midwayjs/orm';
|
|
||||||
import { BaseEntity } from '@cool-midway/core';
|
import { BaseEntity } from '@cool-midway/core';
|
||||||
import { Column } from 'typeorm';
|
import { Column, Entity } from 'typeorm';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户角色
|
* 用户角色
|
||||||
*/
|
*/
|
||||||
@EntityModel('base_sys_user_role')
|
@Entity('base_sys_user_role')
|
||||||
export class BaseSysUserRoleEntity extends BaseEntity {
|
export class BaseSysUserRoleEntity extends BaseEntity {
|
||||||
@Column({ comment: '用户ID', type: 'bigint' })
|
@Column({ comment: '用户ID', type: 'bigint' })
|
||||||
userId: number;
|
userId: number;
|
||||||
|
|||||||
@ -17,6 +17,45 @@
|
|||||||
SET NAMES utf8mb4;
|
SET NAMES utf8mb4;
|
||||||
SET FOREIGN_KEY_CHECKS = 0;
|
SET FOREIGN_KEY_CHECKS = 0;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for base_app_space_info
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `base_app_space_info`;
|
||||||
|
CREATE TABLE `base_app_space_info` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
|
||||||
|
`createTime` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间',
|
||||||
|
`updateTime` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) COMMENT '更新时间',
|
||||||
|
`url` varchar(255) NOT NULL COMMENT '地址',
|
||||||
|
`type` varchar(255) NOT NULL COMMENT '类型',
|
||||||
|
`classifyId` bigint(20) DEFAULT NULL COMMENT '分类ID',
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
KEY `IDX_4aed04cbfa2ecdc01485b86e51` (`createTime`),
|
||||||
|
KEY `IDX_abd5de4a4895eb253a5cabb20f` (`updateTime`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for base_app_space_type
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `base_app_space_type`;
|
||||||
|
CREATE TABLE `base_app_space_type` (
|
||||||
|
`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 '更新时间',
|
||||||
|
`name` varchar(255) NOT NULL COMMENT '类别名称',
|
||||||
|
`parentId` tinyint(4) DEFAULT NULL COMMENT '父分类ID',
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
KEY `IDX_5e8376603f89fdf3e7bb05103a` (`createTime`),
|
||||||
|
KEY `IDX_500ea9e8b2c5c08c9b86a0667e` (`updateTime`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Records of base_app_space_type
|
||||||
|
-- ----------------------------
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO `base_app_space_type` VALUES (1, '2021-02-26 14:07:48.867045', '2021-02-26 14:07:48.867045', 'a', NULL);
|
||||||
|
INSERT INTO `base_app_space_type` VALUES (2, '2021-02-26 14:07:52.285531', '2021-02-26 14:07:52.285531', 'b', NULL);
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for base_sys_conf
|
-- Table structure for base_sys_conf
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
@ -133,7 +172,7 @@ INSERT INTO `base_sys_menu` VALUES (30, '2019-09-12 17:37:03.000000', '2021-03-0
|
|||||||
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 (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 (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 (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://cool-js.com', 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 (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 (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 (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);
|
||||||
@ -158,6 +197,14 @@ INSERT INTO `base_sys_menu` VALUES (99, '1900-01-20 14:14:22.823000', '1900-01-2
|
|||||||
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 (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 (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 (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 (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 (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);
|
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);
|
||||||
|
|||||||
@ -16,7 +16,7 @@ export class BaseLogMiddleware implements IMiddleware<Context, NextFunction> {
|
|||||||
);
|
);
|
||||||
baseSysLogService.record(
|
baseSysLogService.record(
|
||||||
ctx,
|
ctx,
|
||||||
ctx.url.split('?')[0],
|
ctx.url,
|
||||||
ctx.req.method === 'GET' ? ctx.request.query : ctx.request.body,
|
ctx.req.method === 'GET' ? ctx.request.query : ctx.request.body,
|
||||||
ctx.admin ? ctx.admin.userId : null
|
ctx.admin ? ctx.admin.userId : null
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { Provide } from '@midwayjs/decorator';
|
import { Provide } from '@midwayjs/decorator';
|
||||||
import { BaseService } from '@cool-midway/core';
|
import { BaseService } from '@cool-midway/core';
|
||||||
import { InjectEntityModel } from '@midwayjs/orm';
|
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
import { BaseSysConfEntity } from '../../entity/sys/conf';
|
import { BaseSysConfEntity } from '../../entity/sys/conf';
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ export class BaseSysConfService extends BaseService {
|
|||||||
* @param key
|
* @param key
|
||||||
*/
|
*/
|
||||||
async getValue(key) {
|
async getValue(key) {
|
||||||
const conf = await this.baseSysConfEntity.findOne({ cKey: key });
|
const conf = await this.baseSysConfEntity.findOneBy({ cKey: key });
|
||||||
if (conf) {
|
if (conf) {
|
||||||
return conf.cValue;
|
return conf.cValue;
|
||||||
}
|
}
|
||||||
|
|||||||
10
src/modules/base/service/sys/data.ts
Normal file
10
src/modules/base/service/sys/data.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { DataSource } from 'typeorm';
|
||||||
|
|
||||||
|
export class TempDataSource extends DataSource {
|
||||||
|
/**
|
||||||
|
* 重新构造元数据
|
||||||
|
*/
|
||||||
|
async buildMetadatas() {
|
||||||
|
await super.buildMetadatas();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import { Inject, Provide } from '@midwayjs/decorator';
|
import { Inject, Provide } from '@midwayjs/decorator';
|
||||||
import { BaseService } from '@cool-midway/core';
|
import { BaseService } from '@cool-midway/core';
|
||||||
import { InjectEntityModel } from '@midwayjs/orm';
|
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
import { BaseSysDepartmentEntity } from '../../entity/sys/department';
|
import { BaseSysDepartmentEntity } from '../../entity/sys/department';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
@ -101,7 +101,7 @@ export class BaseSysDepartmentService extends BaseService {
|
|||||||
*/
|
*/
|
||||||
async delete(ids: number[]) {
|
async delete(ids: number[]) {
|
||||||
const { deleteUser } = this.ctx.request.body;
|
const { deleteUser } = this.ctx.request.body;
|
||||||
await this.baseSysDepartmentEntity.delete(ids);
|
await super.delete(ids);
|
||||||
if (deleteUser) {
|
if (deleteUser) {
|
||||||
await this.nativeQuery(
|
await this.nativeQuery(
|
||||||
'delete from base_sys_user where departmentId in (?)',
|
'delete from base_sys_user where departmentId in (?)',
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { Inject, Provide } from '@midwayjs/decorator';
|
import { Inject, Provide } from '@midwayjs/decorator';
|
||||||
import { BaseService } from '@cool-midway/core';
|
import { BaseService } from '@cool-midway/core';
|
||||||
import { InjectEntityModel } from '@midwayjs/orm';
|
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import { BaseSysLogEntity } from '../../entity/sys/log';
|
import { BaseSysLogEntity } from '../../entity/sys/log';
|
||||||
@ -41,10 +41,8 @@ export class BaseSysLogService extends BaseService {
|
|||||||
for (const e of sysLog.ip.split(','))
|
for (const e of sysLog.ip.split(','))
|
||||||
ipAddrArr.push(await await this.utils.getIpAddr(context, e));
|
ipAddrArr.push(await await this.utils.getIpAddr(context, e));
|
||||||
sysLog.ipAddr = ipAddrArr.join(',');
|
sysLog.ipAddr = ipAddrArr.join(',');
|
||||||
sysLog.action = url;
|
sysLog.action = url.split('?')[0];
|
||||||
if (!_.isEmpty(params)) {
|
sysLog.params = params;
|
||||||
sysLog.params = JSON.stringify(params);
|
|
||||||
}
|
|
||||||
await this.baseSysLogEntity.insert(sysLog);
|
await this.baseSysLogEntity.insert(sysLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import * as svgCaptcha from 'svg-captcha';
|
|||||||
import { v1 as uuid } from 'uuid';
|
import { v1 as uuid } from 'uuid';
|
||||||
import { BaseSysUserEntity } from '../../entity/sys/user';
|
import { BaseSysUserEntity } from '../../entity/sys/user';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
import { InjectEntityModel } from '@midwayjs/orm';
|
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||||
import * as md5 from 'md5';
|
import * as md5 from 'md5';
|
||||||
import { BaseSysRoleService } from './role';
|
import { BaseSysRoleService } from './role';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
@ -51,7 +51,7 @@ export class BaseSysLoginService extends BaseService {
|
|||||||
// 校验验证码
|
// 校验验证码
|
||||||
const checkV = await this.captchaCheck(captchaId, verifyCode);
|
const checkV = await this.captchaCheck(captchaId, verifyCode);
|
||||||
if (checkV) {
|
if (checkV) {
|
||||||
const user = await this.baseSysUserEntity.findOne({ username });
|
const user = await this.baseSysUserEntity.findOneBy({ username });
|
||||||
// 校验用户
|
// 校验用户
|
||||||
if (user) {
|
if (user) {
|
||||||
// 校验用户状态及密码
|
// 校验用户状态及密码
|
||||||
|
|||||||
@ -1,11 +1,17 @@
|
|||||||
import { Inject, Provide } from '@midwayjs/decorator';
|
import { App, IMidwayApplication } from '@midwayjs/core';
|
||||||
import { BaseService } from '@cool-midway/core';
|
import { ALL, Config, Inject, Provide } from '@midwayjs/decorator';
|
||||||
import { InjectEntityModel } from '@midwayjs/orm';
|
import { BaseService, CoolCommException } from '@cool-midway/core';
|
||||||
|
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
import { BaseSysMenuEntity } from '../../entity/sys/menu';
|
import { BaseSysMenuEntity } from '../../entity/sys/menu';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import { BaseSysPermsService } from './perms';
|
import { BaseSysPermsService } from './perms';
|
||||||
import { Context } from '@midwayjs/koa';
|
import { Context } from '@midwayjs/koa';
|
||||||
|
import { TempDataSource } from './data';
|
||||||
|
// eslint-disable-next-line node/no-unpublished-import
|
||||||
|
import * as ts from 'typescript';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as pathUtil from 'path';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 菜单
|
* 菜单
|
||||||
@ -21,6 +27,12 @@ export class BaseSysMenuService extends BaseService {
|
|||||||
@Inject()
|
@Inject()
|
||||||
baseSysPermsService: BaseSysPermsService;
|
baseSysPermsService: BaseSysPermsService;
|
||||||
|
|
||||||
|
@Config(ALL)
|
||||||
|
config;
|
||||||
|
|
||||||
|
@App()
|
||||||
|
app: IMidwayApplication;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得所有菜单
|
* 获得所有菜单
|
||||||
*/
|
*/
|
||||||
@ -131,7 +143,7 @@ export class BaseSysMenuService extends BaseService {
|
|||||||
*/
|
*/
|
||||||
private async delChildMenu(id) {
|
private async delChildMenu(id) {
|
||||||
await this.refreshPerms(id);
|
await this.refreshPerms(id);
|
||||||
const delMenu = await this.baseSysMenuEntity.find({ parentId: id });
|
const delMenu = await this.baseSysMenuEntity.findBy({ parentId: id });
|
||||||
if (_.isEmpty(delMenu)) {
|
if (_.isEmpty(delMenu)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -162,4 +174,139 @@ export class BaseSysMenuService extends BaseService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析实体和Controller
|
||||||
|
* @param entityString
|
||||||
|
* @param controller
|
||||||
|
* @param module
|
||||||
|
*/
|
||||||
|
async parse(entityString: string, controller: string, module: string) {
|
||||||
|
const tempDataSource = new TempDataSource({
|
||||||
|
...this.config.typeorm.dataSource.default,
|
||||||
|
entities: [],
|
||||||
|
});
|
||||||
|
// 连接数据库
|
||||||
|
await tempDataSource.initialize();
|
||||||
|
const { newCode, className } = this.parseCode(entityString);
|
||||||
|
const code = ts.transpile(
|
||||||
|
`${newCode}
|
||||||
|
tempDataSource.options.entities.push(${className})
|
||||||
|
`,
|
||||||
|
{
|
||||||
|
emitDecoratorMetadata: true,
|
||||||
|
module: ts.ModuleKind.CommonJS,
|
||||||
|
target: ts.ScriptTarget.ES2018,
|
||||||
|
removeComments: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
eval(code);
|
||||||
|
await tempDataSource.buildMetadatas();
|
||||||
|
const columns = tempDataSource.getMetadata(className).columns;
|
||||||
|
await tempDataSource.destroy();
|
||||||
|
const fileName = await this.fileName(controller);
|
||||||
|
return {
|
||||||
|
columns: columns.map(e => {
|
||||||
|
return {
|
||||||
|
propertyName: e.propertyName,
|
||||||
|
type: typeof e.type == 'string' ? e.type : e.type.name.toLowerCase(),
|
||||||
|
length: e.length,
|
||||||
|
comment: e.comment,
|
||||||
|
nullable: e.isNullable,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
path: `/admin/${module}/${fileName}`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析Entity类名
|
||||||
|
* @param code
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
parseCode(code: string) {
|
||||||
|
try {
|
||||||
|
const oldClassName = code
|
||||||
|
.match('class(.*)extends')[1]
|
||||||
|
.replace(/\s*/g, '');
|
||||||
|
const oldTableStart = code.indexOf('@Entity(');
|
||||||
|
const oldTableEnd = code.indexOf(')');
|
||||||
|
|
||||||
|
const oldTableName = code
|
||||||
|
.substring(oldTableStart + 9, oldTableEnd - 1)
|
||||||
|
.replace(/\s*/g, '')
|
||||||
|
// eslint-disable-next-line no-useless-escape
|
||||||
|
.replace(/\"/g, '')
|
||||||
|
// eslint-disable-next-line no-useless-escape
|
||||||
|
.replace(/\'/g, '');
|
||||||
|
const className = `${oldClassName}TEMP`;
|
||||||
|
return {
|
||||||
|
newCode: code
|
||||||
|
.replace(oldClassName, className)
|
||||||
|
.replace(oldTableName, `func_${oldTableName}`),
|
||||||
|
className,
|
||||||
|
tableName: `func_${oldTableName}`,
|
||||||
|
};
|
||||||
|
} catch (err) {
|
||||||
|
throw new CoolCommException('代码结构不正确,请检查');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建代码
|
||||||
|
* @param body body
|
||||||
|
*/
|
||||||
|
async create(body) {
|
||||||
|
const { module, entity, controller } = body;
|
||||||
|
const basePath = this.app.getBaseDir();
|
||||||
|
const fileName = await this.fileName(controller);
|
||||||
|
// 生成Entity
|
||||||
|
const entityPath = pathUtil.join(
|
||||||
|
basePath,
|
||||||
|
'modules',
|
||||||
|
module,
|
||||||
|
'entity',
|
||||||
|
`${fileName}.ts`
|
||||||
|
);
|
||||||
|
this.createFile(entityPath, entity);
|
||||||
|
// // 生成Controller
|
||||||
|
const controllerPath = pathUtil.join(
|
||||||
|
basePath,
|
||||||
|
'modules',
|
||||||
|
module,
|
||||||
|
'controller',
|
||||||
|
'admin',
|
||||||
|
`${fileName}.ts`
|
||||||
|
);
|
||||||
|
this.createFile(controllerPath, controller);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 找到文件名
|
||||||
|
* @param controller
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async fileName(controller: string) {
|
||||||
|
const regex = /import\s*{\s*\w+\s*}\s*from\s*'[^']*\/([\w-]+)';/;
|
||||||
|
const match = regex.exec(controller);
|
||||||
|
|
||||||
|
if (match && match.length > 1) {
|
||||||
|
return match[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建文件
|
||||||
|
* @param filePath
|
||||||
|
* @param content
|
||||||
|
*/
|
||||||
|
async createFile(filePath: string, content: string) {
|
||||||
|
const folderPath = pathUtil.dirname(filePath);
|
||||||
|
if (!fs.existsSync(folderPath)) {
|
||||||
|
fs.mkdirSync(folderPath, { recursive: true });
|
||||||
|
}
|
||||||
|
fs.writeFileSync(filePath, content);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { Inject, Provide } from '@midwayjs/decorator';
|
import { Inject, Provide } from '@midwayjs/decorator';
|
||||||
import { BaseService } from '@cool-midway/core';
|
import { BaseService } from '@cool-midway/core';
|
||||||
import { InjectEntityModel } from '@midwayjs/orm';
|
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
import { BaseSysParamEntity } from '../../entity/sys/param';
|
import { BaseSysParamEntity } from '../../entity/sys/param';
|
||||||
import { CacheManager } from '@midwayjs/cache';
|
import { CacheManager } from '@midwayjs/cache';
|
||||||
@ -23,7 +23,7 @@ export class BaseSysParamService extends BaseService {
|
|||||||
async dataByKey(key) {
|
async dataByKey(key) {
|
||||||
let result: any = await this.cacheManager.get(`param:${key}`);
|
let result: any = await this.cacheManager.get(`param:${key}`);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
result = await this.baseSysParamEntity.findOne({ keyName: key });
|
result = await this.baseSysParamEntity.findOneBy({ keyName: key });
|
||||||
}
|
}
|
||||||
if (result) {
|
if (result) {
|
||||||
if (typeof result == 'string') {
|
if (typeof result == 'string') {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { Inject, Provide } from '@midwayjs/decorator';
|
import { Inject, Provide } from '@midwayjs/decorator';
|
||||||
import { BaseService } from '@cool-midway/core';
|
import { BaseService } from '@cool-midway/core';
|
||||||
import { InjectEntityModel } from '@midwayjs/orm';
|
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
import { BaseSysRoleEntity } from '../../entity/sys/role';
|
import { BaseSysRoleEntity } from '../../entity/sys/role';
|
||||||
import { BaseSysUserRoleEntity } from '../../entity/sys/user_role';
|
import { BaseSysUserRoleEntity } from '../../entity/sys/user_role';
|
||||||
@ -38,7 +38,7 @@ export class BaseSysRoleService extends BaseService {
|
|||||||
* @param userId
|
* @param userId
|
||||||
*/
|
*/
|
||||||
async getByUser(userId: number): Promise<number[]> {
|
async getByUser(userId: number): Promise<number[]> {
|
||||||
const userRole = await this.baseSysUserRoleEntity.find({ userId });
|
const userRole = await this.baseSysUserRoleEntity.findBy({ userId });
|
||||||
if (!_.isEmpty(userRole)) {
|
if (!_.isEmpty(userRole)) {
|
||||||
return userRole.map(e => {
|
return userRole.map(e => {
|
||||||
return e.roleId;
|
return e.roleId;
|
||||||
@ -75,7 +75,7 @@ export class BaseSysRoleService extends BaseService {
|
|||||||
await this.baseSysRoleDepartmentEntity.save({ roleId, departmentId });
|
await this.baseSysRoleDepartmentEntity.save({ roleId, departmentId });
|
||||||
}
|
}
|
||||||
// 刷新权限
|
// 刷新权限
|
||||||
const userRoles = await this.baseSysUserRoleEntity.find({ roleId });
|
const userRoles = await this.baseSysUserRoleEntity.findBy({ roleId });
|
||||||
for (const userRole of userRoles) {
|
for (const userRole of userRoles) {
|
||||||
await this.baseSysPermsService.refreshPerms(userRole.userId);
|
await this.baseSysPermsService.refreshPerms(userRole.userId);
|
||||||
}
|
}
|
||||||
@ -86,15 +86,15 @@ export class BaseSysRoleService extends BaseService {
|
|||||||
* @param id
|
* @param id
|
||||||
*/
|
*/
|
||||||
async info(id) {
|
async info(id) {
|
||||||
const info = await this.baseSysRoleEntity.findOne({ id });
|
const info = await this.baseSysRoleEntity.findOneBy({ id });
|
||||||
if (info) {
|
if (info) {
|
||||||
const menus = await this.baseSysRoleMenuEntity.find(
|
const menus = await this.baseSysRoleMenuEntity.findBy(
|
||||||
id !== 1 ? { roleId: id } : {}
|
id !== 1 ? { roleId: id } : {}
|
||||||
);
|
);
|
||||||
const menuIdList = menus.map(e => {
|
const menuIdList = menus.map(e => {
|
||||||
return parseInt(e.menuId + '');
|
return parseInt(e.menuId + '');
|
||||||
});
|
});
|
||||||
const departments = await this.baseSysRoleDepartmentEntity.find(
|
const departments = await this.baseSysRoleDepartmentEntity.findBy(
|
||||||
id !== 1 ? { roleId: id } : {}
|
id !== 1 ? { roleId: id } : {}
|
||||||
);
|
);
|
||||||
const departmentIdList = departments.map(e => {
|
const departmentIdList = departments.map(e => {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { Inject, Provide } from '@midwayjs/decorator';
|
import { Inject, Provide } from '@midwayjs/decorator';
|
||||||
import { BaseService, CoolCommException } from '@cool-midway/core';
|
import { BaseService, CoolCommException } from '@cool-midway/core';
|
||||||
import { InjectEntityModel } from '@midwayjs/orm';
|
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
import { BaseSysUserEntity } from '../../entity/sys/user';
|
import { BaseSysUserEntity } from '../../entity/sys/user';
|
||||||
import { BaseSysPermsService } from './perms';
|
import { BaseSysPermsService } from './perms';
|
||||||
@ -92,7 +92,7 @@ export class BaseSysUserService extends BaseService {
|
|||||||
* 获得个人信息
|
* 获得个人信息
|
||||||
*/
|
*/
|
||||||
async person() {
|
async person() {
|
||||||
const info = await this.baseSysUserEntity.findOne({
|
const info = await this.baseSysUserEntity.findOneBy({
|
||||||
id: this.ctx.admin?.userId,
|
id: this.ctx.admin?.userId,
|
||||||
});
|
});
|
||||||
delete info?.password;
|
delete info?.password;
|
||||||
@ -124,7 +124,7 @@ export class BaseSysUserService extends BaseService {
|
|||||||
* @param param
|
* @param param
|
||||||
*/
|
*/
|
||||||
async add(param) {
|
async add(param) {
|
||||||
const exists = await this.baseSysUserEntity.findOne({
|
const exists = await this.baseSysUserEntity.findOneBy({
|
||||||
username: param.username,
|
username: param.username,
|
||||||
});
|
});
|
||||||
if (!_.isEmpty(exists)) {
|
if (!_.isEmpty(exists)) {
|
||||||
@ -141,12 +141,12 @@ export class BaseSysUserService extends BaseService {
|
|||||||
* @param id
|
* @param id
|
||||||
*/
|
*/
|
||||||
public async info(id) {
|
public async info(id) {
|
||||||
const info = await this.baseSysUserEntity.findOne({ id });
|
const info = await this.baseSysUserEntity.findOneBy({ id });
|
||||||
const userRoles = await this.nativeQuery(
|
const userRoles = await this.nativeQuery(
|
||||||
'select a.roleId from base_sys_user_role a where a.userId = ?',
|
'select a.roleId from base_sys_user_role a where a.userId = ?',
|
||||||
[id]
|
[id]
|
||||||
);
|
);
|
||||||
const department = await this.baseSysDepartmentEntity.findOne({
|
const department = await this.baseSysDepartmentEntity.findOneBy({
|
||||||
id: info.departmentId,
|
id: info.departmentId,
|
||||||
});
|
});
|
||||||
if (info) {
|
if (info) {
|
||||||
@ -172,7 +172,7 @@ export class BaseSysUserService extends BaseService {
|
|||||||
param.id = this.ctx.admin.userId;
|
param.id = this.ctx.admin.userId;
|
||||||
if (!_.isEmpty(param.password)) {
|
if (!_.isEmpty(param.password)) {
|
||||||
param.password = md5(param.password);
|
param.password = md5(param.password);
|
||||||
const userInfo = await this.baseSysUserEntity.findOne({ id: param.id });
|
const userInfo = await this.baseSysUserEntity.findOneBy({ id: param.id });
|
||||||
if (!userInfo) {
|
if (!userInfo) {
|
||||||
throw new CoolCommException('用户不存在');
|
throw new CoolCommException('用户不存在');
|
||||||
}
|
}
|
||||||
@ -197,7 +197,7 @@ export class BaseSysUserService extends BaseService {
|
|||||||
}
|
}
|
||||||
if (!_.isEmpty(param.password)) {
|
if (!_.isEmpty(param.password)) {
|
||||||
param.password = md5(param.password);
|
param.password = md5(param.password);
|
||||||
const userInfo = await this.baseSysUserEntity.findOne({ id: param.id });
|
const userInfo = await this.baseSysUserEntity.findOneBy({ id: param.id });
|
||||||
if (!userInfo) {
|
if (!userInfo) {
|
||||||
throw new CoolCommException('用户不存在');
|
throw new CoolCommException('用户不存在');
|
||||||
}
|
}
|
||||||
|
|||||||
19
src/modules/cloud/config.ts
Normal file
19
src/modules/cloud/config.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { ModuleConfig } from '@cool-midway/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模块配置
|
||||||
|
*/
|
||||||
|
export default () => {
|
||||||
|
return {
|
||||||
|
// 模块名称
|
||||||
|
name: '云服务',
|
||||||
|
// 模块描述
|
||||||
|
description: '云函数、云数据库、云存储等',
|
||||||
|
// 中间件,只对本模块有效
|
||||||
|
middlewares: [],
|
||||||
|
// 中间件,全局有效
|
||||||
|
globalMiddlewares: [],
|
||||||
|
// 模块加载顺序,默认为0,值越大越优先加载
|
||||||
|
order: 0,
|
||||||
|
} as ModuleConfig;
|
||||||
|
};
|
||||||
34
src/modules/cloud/controller/admin/db.ts
Normal file
34
src/modules/cloud/controller/admin/db.ts
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import { CloudDBService } from './../../service/db';
|
||||||
|
import { CloudDBEntity } from './../../entity/db';
|
||||||
|
import { Body, Inject, Post, Provide } from '@midwayjs/decorator';
|
||||||
|
import { CoolController, BaseController } from '@cool-midway/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云数据库
|
||||||
|
*/
|
||||||
|
@Provide()
|
||||||
|
@CoolController({
|
||||||
|
api: ['add', 'delete', 'update', 'info', 'list', 'page'],
|
||||||
|
entity: CloudDBEntity,
|
||||||
|
service: CloudDBService,
|
||||||
|
pageQueryOp: {
|
||||||
|
fieldEq: ['status'],
|
||||||
|
keyWordLikeFields: ['name'],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
export class CloudDBController extends BaseController {
|
||||||
|
@Inject()
|
||||||
|
cloudDBService: CloudDBService;
|
||||||
|
|
||||||
|
@Post('/initEntity', { summary: '初始化Entity' })
|
||||||
|
async initEntity() {
|
||||||
|
await this.cloudDBService.initEntity();
|
||||||
|
return this.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('/data', { summary: '数据操作' })
|
||||||
|
async data(@Body() body) {
|
||||||
|
const { id, method, params } = body;
|
||||||
|
return this.ok(await this.cloudDBService.data(id, method, params));
|
||||||
|
}
|
||||||
|
}
|
||||||
31
src/modules/cloud/controller/admin/func/info.ts
Normal file
31
src/modules/cloud/controller/admin/func/info.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { CloudFuncService } from './../../../service/func';
|
||||||
|
import { CloudFuncInfoEntity } from '../../../entity/func/info';
|
||||||
|
import { Body, Inject, Post, Provide } from '@midwayjs/decorator';
|
||||||
|
import { CoolController, BaseController } from '@cool-midway/core';
|
||||||
|
import { CloudReq } from '@cool-midway/cloud';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云函数
|
||||||
|
*/
|
||||||
|
@Provide()
|
||||||
|
@CoolController({
|
||||||
|
api: ['add', 'delete', 'update', 'info', 'list', 'page'],
|
||||||
|
entity: CloudFuncInfoEntity,
|
||||||
|
pageQueryOp: {
|
||||||
|
keyWordLikeFields: ['name'],
|
||||||
|
fieldEq: ['status'],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
export class AdminCloudFuncInfoController extends BaseController {
|
||||||
|
@Inject()
|
||||||
|
cloudFuncService: CloudFuncService;
|
||||||
|
|
||||||
|
@Post('/invoke', { summary: '调用云函数' })
|
||||||
|
async invoke(
|
||||||
|
@Body() req: CloudReq,
|
||||||
|
@Body('id') id: number,
|
||||||
|
@Body('content') content: string
|
||||||
|
) {
|
||||||
|
return this.ok(await this.cloudFuncService.invoke(req, id, content));
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/modules/cloud/controller/admin/func/log.ts
Normal file
16
src/modules/cloud/controller/admin/func/log.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { CloudFuncLogEntity } from './../../../entity/func/log';
|
||||||
|
import { Provide } from '@midwayjs/decorator';
|
||||||
|
import { CoolController, BaseController } from '@cool-midway/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日志
|
||||||
|
*/
|
||||||
|
@Provide()
|
||||||
|
@CoolController({
|
||||||
|
api: ['add', 'delete', 'update', 'info', 'list', 'page'],
|
||||||
|
entity: CloudFuncLogEntity,
|
||||||
|
pageQueryOp: {
|
||||||
|
fieldEq: ['infoId'],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
export class AdminCloudFuncLogController extends BaseController {}
|
||||||
12
src/modules/cloud/controller/app/func.ts
Normal file
12
src/modules/cloud/controller/app/func.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { Body, Post, Provide } from '@midwayjs/decorator';
|
||||||
|
import { CoolController, BaseController } from '@cool-midway/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云函数
|
||||||
|
*/
|
||||||
|
@Provide()
|
||||||
|
@CoolController()
|
||||||
|
export class AppCloudFuncController extends BaseController {
|
||||||
|
@Post('/invoke', { summary: '调用云函数' })
|
||||||
|
async invoke(@Body() body) {}
|
||||||
|
}
|
||||||
28
src/modules/cloud/entity/db.ts
Normal file
28
src/modules/cloud/entity/db.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { BaseEntity } from '@cool-midway/core';
|
||||||
|
import { Column, Entity, Index } from 'typeorm';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云数据库
|
||||||
|
*/
|
||||||
|
@Entity('cloud_db')
|
||||||
|
export class CloudDBEntity extends BaseEntity {
|
||||||
|
@Column({ comment: '名称' })
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
@Column({ comment: '说明', nullable: true })
|
||||||
|
readme: string;
|
||||||
|
|
||||||
|
@Column({ comment: '内容', type: 'text' })
|
||||||
|
content: string;
|
||||||
|
|
||||||
|
@Index({ unique: true })
|
||||||
|
@Column({ comment: '类名', nullable: true })
|
||||||
|
className: string;
|
||||||
|
|
||||||
|
@Index({ unique: true })
|
||||||
|
@Column({ comment: '表名', nullable: true })
|
||||||
|
tableName: string;
|
||||||
|
|
||||||
|
@Column({ comment: '状态 0-禁用 1-启用', default: 1 })
|
||||||
|
status: number;
|
||||||
|
}
|
||||||
20
src/modules/cloud/entity/func/info.ts
Normal file
20
src/modules/cloud/entity/func/info.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { BaseEntity } from '@cool-midway/core';
|
||||||
|
import { Column, Entity } from 'typeorm';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云函数
|
||||||
|
*/
|
||||||
|
@Entity('cloud_func_info')
|
||||||
|
export class CloudFuncInfoEntity extends BaseEntity {
|
||||||
|
@Column({ comment: '名称' })
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
@Column({ comment: '说明', nullable: true })
|
||||||
|
readme: string;
|
||||||
|
|
||||||
|
@Column({ comment: '内容', type: 'text' })
|
||||||
|
content: string;
|
||||||
|
|
||||||
|
@Column({ comment: '状态 0-禁用 1-启用', default: 1 })
|
||||||
|
status: number;
|
||||||
|
}
|
||||||
28
src/modules/cloud/entity/func/log.ts
Normal file
28
src/modules/cloud/entity/func/log.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { CloudReq } from '@cool-midway/cloud';
|
||||||
|
import { BaseEntity } from '@cool-midway/core';
|
||||||
|
import { Column, Entity, Index } from 'typeorm';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云函数日志
|
||||||
|
*/
|
||||||
|
@Entity('cloud_func_log')
|
||||||
|
export class CloudFuncLogEntity extends BaseEntity {
|
||||||
|
@Index()
|
||||||
|
@Column({ comment: '云函数ID' })
|
||||||
|
infoId: number;
|
||||||
|
|
||||||
|
@Column({ comment: '请求', type: 'json', nullable: true })
|
||||||
|
request: CloudReq;
|
||||||
|
|
||||||
|
@Column({ comment: '结果', type: 'json', nullable: true })
|
||||||
|
result: string;
|
||||||
|
|
||||||
|
@Column({ comment: '类型 0-失败 1-成功', default: 1, type: 'tinyint' })
|
||||||
|
type: number;
|
||||||
|
|
||||||
|
@Column({ comment: '异常信息', nullable: true, type: 'text' })
|
||||||
|
error: string;
|
||||||
|
|
||||||
|
@Column({ comment: '耗时(毫秒)', default: 0 })
|
||||||
|
time: number;
|
||||||
|
}
|
||||||
21
src/modules/cloud/event/app.ts
Normal file
21
src/modules/cloud/event/app.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { IMidwayApplication } from '@midwayjs/core';
|
||||||
|
import { CoolEvent, Event } from '@cool-midway/core';
|
||||||
|
import { App } from '@midwayjs/decorator';
|
||||||
|
import { CloudDBService } from '../service/db';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应用事件
|
||||||
|
*/
|
||||||
|
@CoolEvent()
|
||||||
|
export class AppEvent {
|
||||||
|
@App()
|
||||||
|
app: IMidwayApplication;
|
||||||
|
|
||||||
|
@Event('onServerReady')
|
||||||
|
async onServerReady() {
|
||||||
|
const cloudDBService = await this.app
|
||||||
|
.getApplicationContext()
|
||||||
|
.getAsync(CloudDBService);
|
||||||
|
cloudDBService.initEntity();
|
||||||
|
}
|
||||||
|
}
|
||||||
151
src/modules/cloud/service/db.ts
Normal file
151
src/modules/cloud/service/db.ts
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
import { Config, Singleton } from '@midwayjs/core';
|
||||||
|
import { CloudDBEntity } from './../entity/db';
|
||||||
|
import { Inject, Provide } from '@midwayjs/decorator';
|
||||||
|
import { BaseService, CoolCommException, CoolConfig } from '@cool-midway/core';
|
||||||
|
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||||
|
import { Repository } from 'typeorm';
|
||||||
|
import { CoolCloudDb } from '@cool-midway/cloud';
|
||||||
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云数据库
|
||||||
|
*/
|
||||||
|
@Provide()
|
||||||
|
@Singleton()
|
||||||
|
export class CloudDBService extends BaseService {
|
||||||
|
@InjectEntityModel(CloudDBEntity)
|
||||||
|
cloudDBEntity: Repository<CloudDBEntity>;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
coolCloudDb: CoolCloudDb;
|
||||||
|
|
||||||
|
@Config('cool')
|
||||||
|
coolConfig: CoolConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据
|
||||||
|
* @param id
|
||||||
|
* @param method
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async data(id, method, params: any = {}) {
|
||||||
|
const db = await this.cloudDBEntity.findOneBy({ id });
|
||||||
|
const repository = await this.getRepository(db?.className);
|
||||||
|
if (method == 'add' || method == 'update') {
|
||||||
|
await repository.save(params);
|
||||||
|
return {
|
||||||
|
id: params.id,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (method == 'delete') {
|
||||||
|
await repository.delete(params.ids);
|
||||||
|
}
|
||||||
|
if (method == 'clear') {
|
||||||
|
await repository.clear();
|
||||||
|
}
|
||||||
|
if (method == 'page') {
|
||||||
|
const { page = 1, size = this.coolConfig.crud.pageSize } = params;
|
||||||
|
const find = repository
|
||||||
|
.createQueryBuilder()
|
||||||
|
.offset((page - 1) * size)
|
||||||
|
.limit(size)
|
||||||
|
.orderBy('createTime', 'DESC');
|
||||||
|
return {
|
||||||
|
list: await find.getMany(),
|
||||||
|
pagination: {
|
||||||
|
page: parseInt(page),
|
||||||
|
size: parseInt(size),
|
||||||
|
total: await find.getCount(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得数据操作实例
|
||||||
|
* @param className
|
||||||
|
*/
|
||||||
|
async getRepository(className: string): Promise<Repository<any>> {
|
||||||
|
const info = await this.cloudDBEntity.findOneBy({
|
||||||
|
className,
|
||||||
|
});
|
||||||
|
if (!info) {
|
||||||
|
throw new CoolCommException('云数据表不存在');
|
||||||
|
}
|
||||||
|
return await this.coolCloudDb.getRepository(info.className);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增
|
||||||
|
* @param param
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async addOrUpdate(param) {
|
||||||
|
const { tableName, className } = this.coolCloudDb.parseCode(param.content);
|
||||||
|
// 更新
|
||||||
|
if (param.id) {
|
||||||
|
const old = await this.cloudDBEntity.findOneBy({ id: param.id });
|
||||||
|
if (tableName != old.tableName) {
|
||||||
|
const check = await this.cloudDBEntity.findOneBy({ tableName });
|
||||||
|
if (check) {
|
||||||
|
throw new CoolCommException('已存在相同的表名');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (className != old.className) {
|
||||||
|
const checkClass = await this.cloudDBEntity.findOneBy({ className });
|
||||||
|
if (checkClass) {
|
||||||
|
throw new CoolCommException('已存在相同的类名');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const check = await this.cloudDBEntity.findOneBy({ tableName });
|
||||||
|
if (check) {
|
||||||
|
throw new CoolCommException('已存在相同的表名');
|
||||||
|
}
|
||||||
|
const checkClass = await this.cloudDBEntity.findOneBy({ className });
|
||||||
|
if (checkClass) {
|
||||||
|
throw new CoolCommException('已存在相同的类名');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await super.addOrUpdate({
|
||||||
|
...param,
|
||||||
|
tableName,
|
||||||
|
className: className.replace('CLOUD', ''),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化
|
||||||
|
*/
|
||||||
|
async initEntity() {
|
||||||
|
const tables = await this.cloudDBEntity.findBy({ status: 1 });
|
||||||
|
const tableNames = [];
|
||||||
|
for (const table of tables) {
|
||||||
|
const parseData = this.coolCloudDb.parseCode(table.content);
|
||||||
|
tableNames.push(parseData.tableName);
|
||||||
|
await this.coolCloudDb.createTable(table.content, true);
|
||||||
|
}
|
||||||
|
// 所有云函数表
|
||||||
|
const allTables = (
|
||||||
|
await this.coolCloudDb.coolDataSource.query(
|
||||||
|
"SELECT table_name from information_schema.columns where table_name like 'func_%' group by table_name"
|
||||||
|
)
|
||||||
|
).map(e => {
|
||||||
|
return e.TABLE_NAME;
|
||||||
|
});
|
||||||
|
// 需要删除的云函数表
|
||||||
|
const deleteTables = allTables.filter(e => {
|
||||||
|
return !tableNames.includes(e);
|
||||||
|
});
|
||||||
|
if (!_.isEmpty(deleteTables)) {
|
||||||
|
await this.coolCloudDb.coolDataSource.query(
|
||||||
|
`drop table ${deleteTables.join(',')}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async modifyAfter() {
|
||||||
|
await this.initEntity();
|
||||||
|
}
|
||||||
|
}
|
||||||
130
src/modules/cloud/service/func.ts
Normal file
130
src/modules/cloud/service/func.ts
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
import { CloudFuncLogEntity } from './../entity/func/log';
|
||||||
|
import { Config, IMidwayApplication } from '@midwayjs/core';
|
||||||
|
import { CloudFuncInfoEntity } from './../entity/func/info';
|
||||||
|
import { App, Provide, Inject } from '@midwayjs/decorator';
|
||||||
|
import { BaseService, CoolConfig, CoolCommException } from '@cool-midway/core';
|
||||||
|
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||||
|
import { Repository } from 'typeorm';
|
||||||
|
import * as moment from 'moment';
|
||||||
|
|
||||||
|
// eslint-disable-next-line node/no-unpublished-import
|
||||||
|
import * as ts from 'typescript';
|
||||||
|
import { Context } from '@midwayjs/koa';
|
||||||
|
import {
|
||||||
|
CloudCrud,
|
||||||
|
CloudReq,
|
||||||
|
CoolCloudDb,
|
||||||
|
CoolCloudFunc,
|
||||||
|
} from '@cool-midway/cloud';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云函数
|
||||||
|
*/
|
||||||
|
@Provide()
|
||||||
|
export class CloudFuncService extends BaseService {
|
||||||
|
@InjectEntityModel(CloudFuncInfoEntity)
|
||||||
|
cloudFuncInfoEntity: Repository<CloudFuncInfoEntity>;
|
||||||
|
|
||||||
|
@InjectEntityModel(CloudFuncLogEntity)
|
||||||
|
cloudFuncLogEntity: Repository<CloudFuncLogEntity>;
|
||||||
|
|
||||||
|
@App()
|
||||||
|
app: IMidwayApplication;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
ctx: Context;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
coolCloudDb: CoolCloudDb;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
coolCloudFunc: CoolCloudFunc;
|
||||||
|
|
||||||
|
@Config('cool')
|
||||||
|
coolConfig: CoolConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 调用云函数
|
||||||
|
* @param req
|
||||||
|
* @param id
|
||||||
|
* @param content 内容 调试的时候传过来
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async invoke(req: CloudReq, id: number, content?: string) {
|
||||||
|
const start = moment().valueOf();
|
||||||
|
let funcInfo: CloudFuncInfoEntity;
|
||||||
|
if (id) {
|
||||||
|
funcInfo = await this.cloudFuncInfoEntity
|
||||||
|
.createQueryBuilder()
|
||||||
|
.cache(true)
|
||||||
|
.where({ id, status: 1 })
|
||||||
|
.getOne();
|
||||||
|
req.name = funcInfo?.name;
|
||||||
|
} else {
|
||||||
|
funcInfo = await this.cloudFuncInfoEntity
|
||||||
|
.createQueryBuilder()
|
||||||
|
.cache(true)
|
||||||
|
.where({ name: req.name, status: 1 })
|
||||||
|
.getOne();
|
||||||
|
}
|
||||||
|
if (!funcInfo) {
|
||||||
|
throw new CoolCommException('云函数不存在或被禁用');
|
||||||
|
}
|
||||||
|
if (!req.method) {
|
||||||
|
throw new CoolCommException('调用方法不能为空');
|
||||||
|
}
|
||||||
|
let result;
|
||||||
|
let func: CloudCrud;
|
||||||
|
const code = content ? content : funcInfo.content;
|
||||||
|
const className = this.coolCloudFunc.getClassName(code);
|
||||||
|
const newCode = ts.transpile(
|
||||||
|
`${code}
|
||||||
|
func = new ${className}();
|
||||||
|
`,
|
||||||
|
{
|
||||||
|
emitDecoratorMetadata: true,
|
||||||
|
module: ts.ModuleKind.CommonJS,
|
||||||
|
target: ts.ScriptTarget.ES2018,
|
||||||
|
removeComments: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const log = new CloudFuncLogEntity();
|
||||||
|
try {
|
||||||
|
eval(newCode);
|
||||||
|
|
||||||
|
func.ctx = this.ctx;
|
||||||
|
func.app = this.app;
|
||||||
|
func.coolCloudDb = this.coolCloudDb;
|
||||||
|
func.coolConfig = this.coolConfig;
|
||||||
|
await func.init(req);
|
||||||
|
const apis: string[] = func.curdOption.api || [];
|
||||||
|
// 判断是否可以执行6个通用方法
|
||||||
|
if (
|
||||||
|
['add', 'delete', 'update', 'info', 'list', 'page'].includes(
|
||||||
|
req.method
|
||||||
|
) &&
|
||||||
|
!apis.includes(req.method)
|
||||||
|
) {
|
||||||
|
throw new CoolCommException(
|
||||||
|
`${req.method} 方法未在curdOption.api 中配置`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// result = func.add({ name: 'aa', age: 22, test2: 1 });
|
||||||
|
result = await func[req.method](req.params);
|
||||||
|
} catch (error) {
|
||||||
|
log.error = error.message;
|
||||||
|
}
|
||||||
|
log.infoId = funcInfo.id;
|
||||||
|
log.request = req;
|
||||||
|
log.result = result;
|
||||||
|
log.type = log.error ? 0 : 1;
|
||||||
|
const end = moment().valueOf();
|
||||||
|
log.time = end - start;
|
||||||
|
this.cloudFuncLogEntity.insert(log);
|
||||||
|
if (id) {
|
||||||
|
return log;
|
||||||
|
} else {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,4 @@
|
|||||||
import { ModuleConfig } from '@cool-midway/core';
|
import { ModuleConfig } from '@cool-midway/core';
|
||||||
import { DemoMiddleware } from './middleware/demo';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 模块配置
|
* 模块配置
|
||||||
@ -7,16 +6,14 @@ import { DemoMiddleware } from './middleware/demo';
|
|||||||
export default () => {
|
export default () => {
|
||||||
return {
|
return {
|
||||||
// 模块名称
|
// 模块名称
|
||||||
name: 'xxx',
|
name: 'demo模块',
|
||||||
// 模块描述
|
// 模块描述
|
||||||
description: 'xxx',
|
description: '演示用',
|
||||||
// 中间件,只对本模块有效
|
// 中间件,只对本模块有效
|
||||||
middlewares: [DemoMiddleware],
|
middlewares: [],
|
||||||
// 中间件,全局有效
|
// 中间件,全局有效
|
||||||
globalMiddlewares: [],
|
globalMiddlewares: [],
|
||||||
// 模块加载顺序,默认为0,值越大越优先加载
|
// 模块加载顺序,默认为0,值越大越优先加载
|
||||||
order: 0,
|
order: 0,
|
||||||
// 其他配置
|
|
||||||
a: 1,
|
|
||||||
} as ModuleConfig;
|
} as ModuleConfig;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
|
import { CoolController, BaseController } from '@cool-midway/core';
|
||||||
import { DemoGoodsEntity } from '../../entity/goods';
|
import { DemoGoodsEntity } from '../../entity/goods';
|
||||||
import { BaseController, CoolController } from '@cool-midway/core';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 测试
|
* 商品模块-商品信息
|
||||||
*/
|
*/
|
||||||
@CoolController({
|
@CoolController({
|
||||||
api: ['add', 'delete', 'update', 'info', 'page', 'list'],
|
api: ['add', 'delete', 'update', 'info', 'list', 'page'],
|
||||||
entity: DemoGoodsEntity,
|
entity: DemoGoodsEntity,
|
||||||
})
|
})
|
||||||
export class CoolGoodsController extends BaseController {}
|
export class AdminDemoGoodsController extends BaseController {}
|
||||||
|
|||||||
@ -24,7 +24,7 @@ export class AppDemoCacheController extends BaseController {
|
|||||||
await this.cacheManager.set('a', 1);
|
await this.cacheManager.set('a', 1);
|
||||||
// 缓存10秒
|
// 缓存10秒
|
||||||
await this.cacheManager.set('a', 1, {
|
await this.cacheManager.set('a', 1, {
|
||||||
ttl: 10,
|
ttl: 30,
|
||||||
});
|
});
|
||||||
return this.ok(await this.cacheManager.get('a'));
|
return this.ok(await this.cacheManager.get('a'));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,18 +0,0 @@
|
|||||||
import { Config, Get, Provide } from '@midwayjs/decorator';
|
|
||||||
import { CoolController, BaseController } from '@cool-midway/core';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 配置
|
|
||||||
*/
|
|
||||||
@Provide()
|
|
||||||
@CoolController()
|
|
||||||
export class DemoConfigController extends BaseController {
|
|
||||||
//获得模块配置,格式: module.模块名,模块文件夹名称,如demo
|
|
||||||
@Config('module.demo')
|
|
||||||
demoConfig;
|
|
||||||
|
|
||||||
@Get('/get')
|
|
||||||
async get() {
|
|
||||||
return this.ok(this.demoConfig);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
import { Inject, Post, Provide } from '@midwayjs/decorator';
|
|
||||||
import { CoolController, BaseController } from '@cool-midway/core';
|
|
||||||
import { TestEsIndex } from '../../es/test';
|
|
||||||
import { CoolElasticSearch } from '@cool-midway/es';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* elasticsearch
|
|
||||||
*/
|
|
||||||
@Provide()
|
|
||||||
@CoolController()
|
|
||||||
export class AppDemoEsController extends BaseController {
|
|
||||||
@Inject()
|
|
||||||
testEsIndex: TestEsIndex;
|
|
||||||
|
|
||||||
@Inject()
|
|
||||||
es: CoolElasticSearch;
|
|
||||||
|
|
||||||
@Post('/test')
|
|
||||||
async test() {
|
|
||||||
// es 客户端实例
|
|
||||||
this.es.client;
|
|
||||||
// 新增与修改
|
|
||||||
await this.testEsIndex.upsert({
|
|
||||||
name: '你好啊你是谁',
|
|
||||||
age: 18,
|
|
||||||
});
|
|
||||||
return this.ok(await this.testEsIndex.find());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import { Inject, Post, Provide } from '@midwayjs/decorator';
|
import { Inject, Post } from '@midwayjs/decorator';
|
||||||
import {
|
import {
|
||||||
CoolController,
|
CoolController,
|
||||||
BaseController,
|
BaseController,
|
||||||
@ -8,7 +8,6 @@ import {
|
|||||||
/**
|
/**
|
||||||
* 事件
|
* 事件
|
||||||
*/
|
*/
|
||||||
@Provide()
|
|
||||||
@CoolController()
|
@CoolController()
|
||||||
export class AppDemoEventController extends BaseController {
|
export class AppDemoEventController extends BaseController {
|
||||||
@Inject()
|
@Inject()
|
||||||
|
|||||||
@ -1,34 +0,0 @@
|
|||||||
import { Get, Inject, Post, Provide } from '@midwayjs/decorator';
|
|
||||||
import { CoolController, BaseController } from '@cool-midway/core';
|
|
||||||
import { Context } from 'koa';
|
|
||||||
import { CoolFile } from '@cool-midway/file';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 文件上传
|
|
||||||
*/
|
|
||||||
@Provide()
|
|
||||||
@CoolController()
|
|
||||||
export class AppDemoFileController extends BaseController {
|
|
||||||
@Inject()
|
|
||||||
ctx: Context;
|
|
||||||
|
|
||||||
@Inject()
|
|
||||||
file: CoolFile;
|
|
||||||
|
|
||||||
@Post('/upload', { summary: '文件上传' })
|
|
||||||
async uplod() {
|
|
||||||
return this.ok(await this.file.upload(this.ctx));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Get('/uploadMode', { summary: '获得上传模式' })
|
|
||||||
async uploadMode() {
|
|
||||||
return this.ok(await this.file.getMode());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Post('/downAndUpload', { summary: '下载并上传' })
|
|
||||||
async downAndUpload() {
|
|
||||||
return this.ok(
|
|
||||||
await this.file.downAndUpload('https://cool-js.com/admin/show.png')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,13 +1,33 @@
|
|||||||
import { DemoGoodsEntity } from '../../entity/goods';
|
|
||||||
import { BaseController, CoolController } from '@cool-midway/core';
|
|
||||||
import { DemoGoodsService } from '../../service/goods';
|
import { DemoGoodsService } from '../../service/goods';
|
||||||
|
import { DemoGoodsEntity } from '../../entity/goods';
|
||||||
|
import { Body, Inject, Post, Provide } from '@midwayjs/decorator';
|
||||||
|
import { CoolController, BaseController } from '@cool-midway/core';
|
||||||
|
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||||
|
import { Repository } from 'typeorm';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 测试
|
* 测试
|
||||||
*/
|
*/
|
||||||
|
@Provide()
|
||||||
@CoolController({
|
@CoolController({
|
||||||
api: ['add', 'delete', 'update', 'info', 'page', 'list'],
|
api: ['add', 'delete', 'update', 'info', 'list', 'page'],
|
||||||
entity: DemoGoodsEntity,
|
entity: DemoGoodsEntity,
|
||||||
service: DemoGoodsService,
|
service: DemoGoodsService,
|
||||||
})
|
})
|
||||||
export class CoolGoodsController extends BaseController {}
|
export class AppDemoGoodsController extends BaseController {
|
||||||
|
@InjectEntityModel(DemoGoodsEntity)
|
||||||
|
demoGoodsEntity: Repository<DemoGoodsEntity>;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
demoGoodsService: DemoGoodsService;
|
||||||
|
|
||||||
|
@Post('/sqlPage', { summary: 'sql分页查询' })
|
||||||
|
async sqlPage(@Body() query) {
|
||||||
|
return this.ok(await this.demoGoodsService.sqlPage(query));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('/entityPage', { summary: 'entity分页查询' })
|
||||||
|
async entityPage(@Body() query) {
|
||||||
|
return this.ok(await this.demoGoodsService.entityPage(query));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,16 +1,20 @@
|
|||||||
import { ALL, App, Body, Inject, Post, Provide } from '@midwayjs/decorator';
|
import { Body, Config, Inject, Post, Provide } from '@midwayjs/decorator';
|
||||||
import { CoolController, BaseController } from '@cool-midway/core';
|
import {
|
||||||
import { CoolWxPay, CoolAliPay } from '@cool-midway/pay';
|
CoolController,
|
||||||
import { parseString } from 'xml2js';
|
BaseController,
|
||||||
import { Context } from '@midwayjs/koa';
|
CoolWxPayConfig,
|
||||||
import { IMidwayApplication } from '@midwayjs/core';
|
CoolAliPayConfig,
|
||||||
|
} from '@cool-midway/core';
|
||||||
|
import { CoolAliPay, CoolWxPay } from '@cool-midway/pay';
|
||||||
|
import AlipayFormData from 'alipay-sdk/lib/form';
|
||||||
|
import { sign } from 'alipay-sdk/lib/util';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付示例
|
* 微信支付
|
||||||
*/
|
*/
|
||||||
@Provide()
|
@Provide()
|
||||||
@CoolController()
|
@CoolController()
|
||||||
export class DemoPayController extends BaseController {
|
export class AppDemoPayController extends BaseController {
|
||||||
// 微信支付
|
// 微信支付
|
||||||
@Inject()
|
@Inject()
|
||||||
wxPay: CoolWxPay;
|
wxPay: CoolWxPay;
|
||||||
@ -20,10 +24,13 @@ export class DemoPayController extends BaseController {
|
|||||||
aliPay: CoolAliPay;
|
aliPay: CoolAliPay;
|
||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
ctx: Context;
|
ctx;
|
||||||
|
|
||||||
@App()
|
@Config('cool.pay.wx')
|
||||||
app: IMidwayApplication;
|
wxPayConfig: CoolWxPayConfig;
|
||||||
|
|
||||||
|
@Config('cool.pay.ali')
|
||||||
|
aliPayConfig: CoolAliPayConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信扫码支付
|
* 微信扫码支付
|
||||||
@ -31,78 +38,92 @@ export class DemoPayController extends BaseController {
|
|||||||
@Post('/wx')
|
@Post('/wx')
|
||||||
async wx() {
|
async wx() {
|
||||||
const orderNum = await this.wxPay.createOrderNum();
|
const orderNum = await this.wxPay.createOrderNum();
|
||||||
const data = await this.wxPay.getInstance().unifiedOrder({
|
const params = {
|
||||||
|
description: '测试',
|
||||||
out_trade_no: orderNum,
|
out_trade_no: orderNum,
|
||||||
body: '测试微信支付',
|
notify_url: this.wxPayConfig.notify_url,
|
||||||
total_fee: 1,
|
amount: {
|
||||||
trade_type: 'NATIVE',
|
total: 1,
|
||||||
product_id: 'test001',
|
},
|
||||||
});
|
scene_info: {
|
||||||
return this.ok(data);
|
payer_client_ip: 'ip',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const result = await this.wxPay.getInstance().transactions_native(params);
|
||||||
|
return this.ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信支付通知回调
|
* 微信支付回调通知
|
||||||
*/
|
*/
|
||||||
@Post('/wxNotify')
|
@Post('/wxNotify')
|
||||||
async wxNotify() {
|
async wxNotify(@Body() body) {
|
||||||
let data = '';
|
const check = await this.wxPay.signVerify(this.ctx);
|
||||||
this.ctx.req.setEncoding('utf8');
|
// 验签通过,处理业务逻辑
|
||||||
this.ctx.req.on('data', chunk => {
|
if (check) {
|
||||||
data += chunk;
|
|
||||||
});
|
|
||||||
const results = await new Promise((resolve, reject) => {
|
|
||||||
this.ctx.req.on('end', () => {
|
|
||||||
parseString(data, { explicitArray: false }, async (err, json) => {
|
|
||||||
if (err) {
|
|
||||||
return reject('success');
|
|
||||||
}
|
|
||||||
const checkSign = await this.wxPay.signVerify(json.xml);
|
|
||||||
if (checkSign && json.xml.result_code === 'SUCCESS') {
|
|
||||||
// 处理业务逻辑
|
|
||||||
console.log('微信支付成功', json.xml);
|
|
||||||
return resolve(true);
|
|
||||||
}
|
|
||||||
return resolve(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
if (results) {
|
|
||||||
this.ctx.body =
|
|
||||||
'<xml><return_msg>OK</return_msg><return_code>SUCCESS</return_code></xml>';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付宝app支付
|
* 支付宝PC网站支付
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
@Post('/alipay')
|
@Post('/aliPc')
|
||||||
async alipay() {
|
async aliPc() {
|
||||||
const orderNum = await this.aliPay.createOrderNum();
|
const orderNum = await this.aliPay.createOrderNum();
|
||||||
// app支付
|
const formData = new AlipayFormData();
|
||||||
const params = await this.aliPay.getInstance().appPay({
|
// 调用 setMethod 并传入 get,会返回可以跳转到支付页面的 url
|
||||||
subject: '测试商品',
|
formData.setMethod('get');
|
||||||
body: '测试商品描述',
|
formData.addField('notifyUrl', this.aliPayConfig.notifyUrl);
|
||||||
outTradeId: orderNum,
|
formData.addField('bizContent', {
|
||||||
timeout: '10m',
|
outTradeNo: orderNum,
|
||||||
amount: '10.00',
|
productCode: 'FAST_INSTANT_TRADE_PAY',
|
||||||
goodsType: '0',
|
totalAmount: '0.01',
|
||||||
|
subject: '商品',
|
||||||
|
body: '商品详情',
|
||||||
});
|
});
|
||||||
return this.ok(params);
|
// 返回支付链接
|
||||||
|
const result = await this.aliPay
|
||||||
|
.getInstance()
|
||||||
|
.exec('alipay.trade.page.pay', {}, { formData });
|
||||||
|
return this.ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付宝支付回调
|
* 支付宝APP支付
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
@Post('/aliApp')
|
||||||
|
async aliApp() {
|
||||||
|
const orderNum = await this.aliPay.createOrderNum();
|
||||||
|
|
||||||
|
// 返回支付链接
|
||||||
|
const data = sign(
|
||||||
|
'alipay.trade.app.pay',
|
||||||
|
{
|
||||||
|
notifyUrl: this.aliPayConfig.notifyUrl,
|
||||||
|
bizContent: {
|
||||||
|
subject: '商品标题',
|
||||||
|
totalAmount: '0.01',
|
||||||
|
outTradeNo: orderNum,
|
||||||
|
productCode: 'QUICK_MSECURITY_PAY',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
this.aliPay.getInstance().config
|
||||||
|
);
|
||||||
|
const payInfo = new URLSearchParams(data).toString();
|
||||||
|
return this.ok(payInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信支付回调通知
|
||||||
*/
|
*/
|
||||||
@Post('/aliNotify')
|
@Post('/aliNotify')
|
||||||
async aliNotify(@Body(ALL) body: any) {
|
async aliNotify(@Body() body) {
|
||||||
const { trade_status, out_trade_no } = body;
|
|
||||||
const check = await this.aliPay.signVerify(body);
|
const check = await this.aliPay.signVerify(body);
|
||||||
if (check && trade_status === 'TRADE_SUCCESS') {
|
// 验签通过,处理业务逻辑
|
||||||
// 处理逻辑
|
if (check) {
|
||||||
console.log('支付宝支付成功', out_trade_no);
|
|
||||||
}
|
}
|
||||||
this.ctx.body = 'success';
|
return 'success';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,34 +1,28 @@
|
|||||||
import { Inject, Post, Provide } from '@midwayjs/decorator';
|
import { Inject, Provide, Get } from '@midwayjs/decorator';
|
||||||
import { CoolController, BaseController } from '@cool-midway/core';
|
import { CoolController, BaseController } from '@cool-midway/core';
|
||||||
import { CoolRpc } from '@cool-midway/rpc';
|
|
||||||
import { DemoRpcService } from '../../service/rpc';
|
import { DemoRpcService } from '../../service/rpc';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微服务
|
* 远程RPC调用
|
||||||
*/
|
*/
|
||||||
@Provide()
|
@Provide()
|
||||||
@CoolController()
|
@CoolController()
|
||||||
export class DemoRpcController extends BaseController {
|
export class AppDemoRpcController extends BaseController {
|
||||||
@Inject()
|
|
||||||
rpc: CoolRpc;
|
|
||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
demoRpcService: DemoRpcService;
|
demoRpcService: DemoRpcService;
|
||||||
|
|
||||||
@Post('/call', { summary: '远程调用' })
|
@Get('/call', { summary: '远程调用' })
|
||||||
async call() {
|
async call() {
|
||||||
return this.ok(
|
return this.ok(await this.demoRpcService.call());
|
||||||
await this.rpc.call('goods', 'demoGoodsService', 'test', { a: 1 })
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('/event', { summary: '集群事件' })
|
@Get('/event', { summary: '集群事件' })
|
||||||
async event() {
|
async event() {
|
||||||
this.rpc.broadcastEvent('test', { a: 1 });
|
await this.demoRpcService.event();
|
||||||
return this.ok();
|
return this.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('/transaction', { summary: '分布式事务' })
|
@Get('/transaction', { summary: '分布式事务' })
|
||||||
async transaction() {
|
async transaction() {
|
||||||
await this.demoRpcService.transaction({ a: 1 });
|
await this.demoRpcService.transaction({ a: 1 });
|
||||||
return this.ok();
|
return this.ok();
|
||||||
|
|||||||
@ -1,16 +0,0 @@
|
|||||||
import { Param, Post, Provide } from '@midwayjs/decorator';
|
|
||||||
import { CoolController, BaseController } from '@cool-midway/core';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* swagger 文档
|
|
||||||
*/
|
|
||||||
@Provide()
|
|
||||||
@CoolController(null, {
|
|
||||||
tagName: 'swagger demo',
|
|
||||||
})
|
|
||||||
export class AppSwaggerController extends BaseController {
|
|
||||||
@Post('/create', { summary: '创建' })
|
|
||||||
async create(@Param('id') id: number) {
|
|
||||||
return this.ok(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
import { Get, Inject, Provide } from '@midwayjs/decorator';
|
|
||||||
import {
|
|
||||||
CoolController,
|
|
||||||
BaseController,
|
|
||||||
CoolUrlTag,
|
|
||||||
TagTypes,
|
|
||||||
CoolUrlTagData,
|
|
||||||
} from '@cool-midway/core';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 测试给URL打标签
|
|
||||||
*/
|
|
||||||
@Provide()
|
|
||||||
@CoolController({
|
|
||||||
api: [],
|
|
||||||
entity: '',
|
|
||||||
pageQueryOp: () => {},
|
|
||||||
})
|
|
||||||
@CoolUrlTag({
|
|
||||||
key: TagTypes.IGNORE_TOKEN,
|
|
||||||
value: ['add'],
|
|
||||||
})
|
|
||||||
export class DemoAppTagController extends BaseController {
|
|
||||||
@Inject()
|
|
||||||
tag: CoolUrlTagData;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得标签数据, 如可以标记忽略token的url,然后在中间件判断
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
@Get('/data')
|
|
||||||
async data() {
|
|
||||||
return this.ok(this.tag.byKey(TagTypes.IGNORE_TOKEN));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
15
src/modules/demo/controller/app/transaction.ts
Normal file
15
src/modules/demo/controller/app/transaction.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { DemoGoodsEntity } from './../../entity/goods';
|
||||||
|
import { Provide } from '@midwayjs/decorator';
|
||||||
|
import { CoolController, BaseController } from '@cool-midway/core';
|
||||||
|
import { DemoTransactionService } from '../../service/transaction';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 事务
|
||||||
|
*/
|
||||||
|
@Provide()
|
||||||
|
@CoolController({
|
||||||
|
api: ['add', 'delete', 'update', 'info', 'list', 'page'],
|
||||||
|
entity: DemoGoodsEntity,
|
||||||
|
service: DemoTransactionService,
|
||||||
|
})
|
||||||
|
export class AppDemoTransactionController extends BaseController {}
|
||||||
@ -1,23 +0,0 @@
|
|||||||
// import { EntityModel } from '@midwayjs/orm';
|
|
||||||
// import { BaseEntity } from '@cool-midway/core';
|
|
||||||
// import { Column } from 'typeorm';
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * 商品(多数据库连接)
|
|
||||||
// */
|
|
||||||
// @EntityModel('demo_goods_1', {
|
|
||||||
// connectionName: 'test',
|
|
||||||
// })
|
|
||||||
// export class DemoGoodsTestEntity extends BaseEntity {
|
|
||||||
// @Column({ comment: '标题' })
|
|
||||||
// title: string;
|
|
||||||
|
|
||||||
// @Column({ comment: '图片' })
|
|
||||||
// pic: string;
|
|
||||||
|
|
||||||
// @Column({ comment: '价格', type: 'decimal', precision: 5, scale: 2 })
|
|
||||||
// price: number;
|
|
||||||
|
|
||||||
// @Column({ comment: '分类', type: 'tinyint', default: 0 })
|
|
||||||
// type: number;
|
|
||||||
// }
|
|
||||||
@ -1,21 +1,32 @@
|
|||||||
import { EntityModel } from '@midwayjs/orm';
|
|
||||||
import { BaseEntity } from '@cool-midway/core';
|
import { BaseEntity } from '@cool-midway/core';
|
||||||
import { Column } from 'typeorm';
|
import { Column, Entity, Index } from 'typeorm';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 商品
|
* 商品模块-商品信息
|
||||||
*/
|
*/
|
||||||
@EntityModel('demo_goods')
|
@Entity('demo_goods')
|
||||||
export class DemoGoodsEntity extends BaseEntity {
|
export class DemoGoodsEntity extends BaseEntity {
|
||||||
@Column({ comment: '标题' })
|
@Index()
|
||||||
|
@Column({ comment: '标题', length: 50 })
|
||||||
title: string;
|
title: string;
|
||||||
|
|
||||||
@Column({ comment: '图片' })
|
@Column({
|
||||||
pic: string;
|
comment: '价格',
|
||||||
|
type: 'decimal',
|
||||||
@Column({ comment: '价格', type: 'decimal', precision: 5, scale: 2 })
|
precision: 5,
|
||||||
|
scale: 2,
|
||||||
|
})
|
||||||
price: number;
|
price: number;
|
||||||
|
|
||||||
@Column({ comment: '分类 0-衣服 1-鞋子 2-裤子', type: 'tinyint', default: 0 })
|
@Column({ comment: '描述', nullable: true })
|
||||||
type: number;
|
description: string;
|
||||||
|
|
||||||
|
@Column({ comment: '主图', nullable: true })
|
||||||
|
mainImage: string;
|
||||||
|
|
||||||
|
@Column({ comment: '示例图', nullable: true, type: 'json' })
|
||||||
|
exampleImages: string[];
|
||||||
|
|
||||||
|
@Column({ comment: '库存', default: 0 })
|
||||||
|
stock: number;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,26 +0,0 @@
|
|||||||
import { CoolEsIndex, ICoolEs, BaseEsIndex } from '@cool-midway/es';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 测试索引
|
|
||||||
*/
|
|
||||||
@CoolEsIndex({ name: 'test', replicas: 0 })
|
|
||||||
export class TestEsIndex extends BaseEsIndex implements ICoolEs {
|
|
||||||
indexInfo() {
|
|
||||||
return {
|
|
||||||
// 需要安装ik分词器 https://github.com/medcl/elasticsearch-analysis-ik
|
|
||||||
name: {
|
|
||||||
type: 'text',
|
|
||||||
analyzer: 'ik_max_word',
|
|
||||||
search_analyzer: 'ik_max_word',
|
|
||||||
fields: {
|
|
||||||
raw: {
|
|
||||||
type: 'keyword',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
age: {
|
|
||||||
type: 'long',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,8 +1,11 @@
|
|||||||
|
import { Provide, Scope, ScopeEnum } from '@midwayjs/decorator';
|
||||||
import { CoolEvent, Event } from '@cool-midway/core';
|
import { CoolEvent, Event } from '@cool-midway/core';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 接收事件
|
* 接收事件
|
||||||
*/
|
*/
|
||||||
|
@Provide()
|
||||||
|
@Scope(ScopeEnum.Singleton)
|
||||||
@CoolEvent()
|
@CoolEvent()
|
||||||
export class DemoEvent {
|
export class DemoEvent {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1,28 +0,0 @@
|
|||||||
import { CoolUrlTagData, TagTypes } from '@cool-midway/core';
|
|
||||||
import { IMiddleware } from '@midwayjs/core';
|
|
||||||
import { Inject, Middleware } from '@midwayjs/decorator';
|
|
||||||
import { NextFunction, Context } from '@midwayjs/koa';
|
|
||||||
|
|
||||||
@Middleware()
|
|
||||||
export class DemoMiddleware implements IMiddleware<Context, NextFunction> {
|
|
||||||
@Inject()
|
|
||||||
tag: CoolUrlTagData;
|
|
||||||
|
|
||||||
resolve() {
|
|
||||||
return async (ctx: Context, next: NextFunction) => {
|
|
||||||
const urls = this.tag.byKey(TagTypes.IGNORE_TOKEN);
|
|
||||||
|
|
||||||
console.log('忽略token的URL数组', urls);
|
|
||||||
|
|
||||||
// 控制器前执行的逻辑
|
|
||||||
const startTime = Date.now();
|
|
||||||
// 执行下一个 Web 中间件,最后执行到控制器
|
|
||||||
// 这里可以拿到下一个中间件或者控制器的返回值
|
|
||||||
const result = await next();
|
|
||||||
// 控制器之后执行的逻辑
|
|
||||||
console.log(Date.now() - startTime);
|
|
||||||
// 返回给上一个中间件的结果
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
20
src/modules/demo/queue/single.ts
Normal file
20
src/modules/demo/queue/single.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { BaseCoolQueue, CoolQueue } from '@cool-midway/task';
|
||||||
|
import { IMidwayApplication } from '@midwayjs/core';
|
||||||
|
import { App } from '@midwayjs/decorator';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单例队列,cluster 或 集群模式下 只会有一个实例消费数据
|
||||||
|
*/
|
||||||
|
@CoolQueue({ type: 'single' })
|
||||||
|
export class DemoSingleQueue extends BaseCoolQueue {
|
||||||
|
@App()
|
||||||
|
app: IMidwayApplication;
|
||||||
|
|
||||||
|
async data(job: any, done: any): Promise<void> {
|
||||||
|
// 这边可以执行定时任务具体的业务或队列的业务
|
||||||
|
console.log('数据', job.data);
|
||||||
|
// 抛出错误 可以让队列重试,默认重试5次
|
||||||
|
//throw new Error('错误');
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,12 +1,33 @@
|
|||||||
|
import { DemoGoodsEntity } from './../entity/goods';
|
||||||
import { Provide } from '@midwayjs/decorator';
|
import { Provide } from '@midwayjs/decorator';
|
||||||
import { BaseService } from '@cool-midway/core';
|
import { BaseService } from '@cool-midway/core';
|
||||||
|
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||||
|
import { Repository } from 'typeorm';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 缓存
|
* 商品示例
|
||||||
*/
|
*/
|
||||||
@Provide()
|
@Provide()
|
||||||
export class DemoGoodsService extends BaseService {
|
export class DemoGoodsService extends BaseService {
|
||||||
async test() {
|
@InjectEntityModel(DemoGoodsEntity)
|
||||||
console.log('调用');
|
demoGoodsEntity: Repository<DemoGoodsEntity>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行sql分页
|
||||||
|
*/
|
||||||
|
async sqlPage(query) {
|
||||||
|
return this.sqlRenderPage(
|
||||||
|
'select * from demo_goods ORDER BY id ASC',
|
||||||
|
query,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行entity分页
|
||||||
|
*/
|
||||||
|
async entityPage(query) {
|
||||||
|
const find = this.demoGoodsEntity.createQueryBuilder();
|
||||||
|
return this.entityRenderPage(find, query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { App, Inject, Provide } from '@midwayjs/decorator';
|
import { App, Provide } from '@midwayjs/decorator';
|
||||||
import { DemoGoodsEntity } from '../entity/goods';
|
import { DemoGoodsEntity } from '../entity/goods';
|
||||||
import { IMidwayApplication } from '@midwayjs/core';
|
import { IMidwayApplication, Inject } from '@midwayjs/core';
|
||||||
import {
|
import {
|
||||||
BaseRpcService,
|
BaseRpcService,
|
||||||
CoolRpc,
|
CoolRpc,
|
||||||
@ -22,12 +22,34 @@ export class DemoRpcService extends BaseRpcService {
|
|||||||
rpc: CoolRpc;
|
rpc: CoolRpc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分布式事务
|
* 远程调用
|
||||||
* @param params 方法参数
|
* @returns
|
||||||
* @param rpcTransactionId 无需调用者传参, 本次事务的ID,ID会自动注入无需调用者传参
|
|
||||||
* @param queryRunner 无需调用者传参,操作数据库,需要用queryRunner操作数据库,才能统一提交或回滚事务
|
|
||||||
*/
|
*/
|
||||||
// 注解启用分布式事务,参数可以指定事务类型
|
async call() {
|
||||||
|
return await this.rpc.call('goods', 'demoGoodsService', 'test', {
|
||||||
|
a: 1,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 集群事件
|
||||||
|
*/
|
||||||
|
async event() {
|
||||||
|
this.rpc.event('test', { a: 1 });
|
||||||
|
}
|
||||||
|
|
||||||
|
async info(params) {
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
async getUser() {
|
||||||
|
return {
|
||||||
|
uid: '123',
|
||||||
|
username: 'mockedName',
|
||||||
|
phone: '12345678901',
|
||||||
|
email: 'xxx.xxx@xxx.com',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@CoolRpcTransaction()
|
@CoolRpcTransaction()
|
||||||
async transaction(params, rpcTransactionId?, queryRunner?: QueryRunner) {
|
async transaction(params, rpcTransactionId?, queryRunner?: QueryRunner) {
|
||||||
console.log('获得的参数', params);
|
console.log('获得的参数', params);
|
||||||
@ -42,18 +64,7 @@ export class DemoRpcService extends BaseRpcService {
|
|||||||
// 将事务id传给调用的远程服务方法
|
// 将事务id传给调用的远程服务方法
|
||||||
await this.rpc.call('goods', 'demoGoodsService', 'transaction', {
|
await this.rpc.call('goods', 'demoGoodsService', 'transaction', {
|
||||||
rpcTransactionId,
|
rpcTransactionId,
|
||||||
|
...params,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async info(params) {
|
|
||||||
return params;
|
|
||||||
}
|
|
||||||
async getUser() {
|
|
||||||
return {
|
|
||||||
uid: '123',
|
|
||||||
username: 'mockedName',
|
|
||||||
phone: '12345678901',
|
|
||||||
email: 'xxx.xxx@xxx.com',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
23
src/modules/demo/service/transaction.ts
Normal file
23
src/modules/demo/service/transaction.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { DemoGoodsEntity } from './../entity/goods';
|
||||||
|
import { Provide } from '@midwayjs/decorator';
|
||||||
|
import { BaseService, CoolTransaction } from '@cool-midway/core';
|
||||||
|
import { QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作事务
|
||||||
|
*/
|
||||||
|
@Provide()
|
||||||
|
export class DemoTransactionService extends BaseService {
|
||||||
|
/**
|
||||||
|
* 事务操作
|
||||||
|
*/
|
||||||
|
@CoolTransaction({
|
||||||
|
connectionName: 'default',
|
||||||
|
})
|
||||||
|
async add(param, queryRunner?: QueryRunner) {
|
||||||
|
await queryRunner.manager.insert<DemoGoodsEntity>(DemoGoodsEntity, param);
|
||||||
|
return {
|
||||||
|
id: param.id,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,27 +0,0 @@
|
|||||||
import {
|
|
||||||
WSController,
|
|
||||||
OnWSConnection,
|
|
||||||
Inject,
|
|
||||||
OnWSMessage,
|
|
||||||
} from '@midwayjs/decorator';
|
|
||||||
import { Context } from '@midwayjs/socketio';
|
|
||||||
/**
|
|
||||||
* 测试
|
|
||||||
*/
|
|
||||||
@WSController('/')
|
|
||||||
export class HelloController {
|
|
||||||
@Inject()
|
|
||||||
ctx: Context;
|
|
||||||
|
|
||||||
@OnWSConnection()
|
|
||||||
async onConnectionMethod() {
|
|
||||||
console.log('on client connect', this.ctx.id);
|
|
||||||
console.log('参数', this.ctx.handshake.query);
|
|
||||||
this.ctx.emit('data', '连接成功');
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnWSMessage('myEvent')
|
|
||||||
async gotMessage(data) {
|
|
||||||
console.log('on data got', this.ctx.id, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,11 +1,10 @@
|
|||||||
import { EntityModel } from '@midwayjs/orm';
|
|
||||||
import { BaseEntity } from '@cool-midway/core';
|
import { BaseEntity } from '@cool-midway/core';
|
||||||
import { Column } from 'typeorm';
|
import { Column, Entity } from 'typeorm';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 字典信息
|
* 字典信息
|
||||||
*/
|
*/
|
||||||
@EntityModel('dict_info')
|
@Entity('dict_info')
|
||||||
export class DictInfoEntity extends BaseEntity {
|
export class DictInfoEntity extends BaseEntity {
|
||||||
@Column({ comment: '类型ID' })
|
@Column({ comment: '类型ID' })
|
||||||
typeId: number;
|
typeId: number;
|
||||||
|
|||||||
@ -1,11 +1,10 @@
|
|||||||
import { EntityModel } from '@midwayjs/orm';
|
|
||||||
import { BaseEntity } from '@cool-midway/core';
|
import { BaseEntity } from '@cool-midway/core';
|
||||||
import { Column } from 'typeorm';
|
import { Column, Entity } from 'typeorm';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 字典类别
|
* 字典类别
|
||||||
*/
|
*/
|
||||||
@EntityModel('dict_type')
|
@Entity('dict_type')
|
||||||
export class DictTypeEntity extends BaseEntity {
|
export class DictTypeEntity extends BaseEntity {
|
||||||
@Column({ comment: '名称' })
|
@Column({ comment: '名称' })
|
||||||
name: string;
|
name: string;
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { DictTypeEntity } from './../entity/type';
|
|||||||
import { DictInfoEntity } from './../entity/info';
|
import { DictInfoEntity } from './../entity/info';
|
||||||
import { Provide } from '@midwayjs/decorator';
|
import { Provide } from '@midwayjs/decorator';
|
||||||
import { BaseService } from '@cool-midway/core';
|
import { BaseService } from '@cool-midway/core';
|
||||||
import { InjectEntityModel } from '@midwayjs/orm';
|
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||||
import { Repository, In } from 'typeorm';
|
import { Repository, In } from 'typeorm';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ export class DictInfoService extends BaseService {
|
|||||||
}
|
}
|
||||||
const data = await this.dictInfoEntity
|
const data = await this.dictInfoEntity
|
||||||
.createQueryBuilder('a')
|
.createQueryBuilder('a')
|
||||||
.select(['a.id', 'a.name', 'a.typeId', 'a.parentId'])
|
.select(['a.id', 'a.name', 'a.typeId', 'a.parentId', 'a.orderNum'])
|
||||||
.where('typeId in(:typeIds)', {
|
.where('typeId in(:typeIds)', {
|
||||||
typeIds: typeData.map(e => {
|
typeIds: typeData.map(e => {
|
||||||
return e.id;
|
return e.id;
|
||||||
@ -54,7 +54,7 @@ export class DictInfoService extends BaseService {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async value(infoId: number) {
|
async value(infoId: number) {
|
||||||
const info = await this.dictInfoEntity.findOne({ id: infoId });
|
const info = await this.dictInfoEntity.findOneBy({ id: infoId });
|
||||||
return info?.name;
|
return info?.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ export class DictInfoService extends BaseService {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async values(infoIds: number[]) {
|
async values(infoIds: number[]) {
|
||||||
const infos = await this.dictInfoEntity.find({ id: In(infoIds) });
|
const infos = await this.dictInfoEntity.findBy({ id: In(infoIds) });
|
||||||
return infos.map(e => {
|
return infos.map(e => {
|
||||||
return e.name;
|
return e.name;
|
||||||
});
|
});
|
||||||
@ -88,7 +88,7 @@ export class DictInfoService extends BaseService {
|
|||||||
* @param id
|
* @param id
|
||||||
*/
|
*/
|
||||||
private async delChildDict(id) {
|
private async delChildDict(id) {
|
||||||
const delDict = await this.dictInfoEntity.find({ parentId: id });
|
const delDict = await this.dictInfoEntity.findBy({ parentId: id });
|
||||||
if (_.isEmpty(delDict)) {
|
if (_.isEmpty(delDict)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { DictInfoEntity } from './../entity/info';
|
import { DictInfoEntity } from './../entity/info';
|
||||||
import { Provide } from '@midwayjs/decorator';
|
import { Provide } from '@midwayjs/decorator';
|
||||||
import { BaseService } from '@cool-midway/core';
|
import { BaseService } from '@cool-midway/core';
|
||||||
import { InjectEntityModel } from '@midwayjs/orm';
|
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||||
import { Repository, In } from 'typeorm';
|
import { Repository, In } from 'typeorm';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
19
src/modules/iot/config.ts
Normal file
19
src/modules/iot/config.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { ModuleConfig } from '@cool-midway/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模块配置
|
||||||
|
*/
|
||||||
|
export default () => {
|
||||||
|
return {
|
||||||
|
// 模块名称
|
||||||
|
name: '物联网',
|
||||||
|
// 模块描述
|
||||||
|
description: '物联网模块,主要提供物联交互,状态监测等',
|
||||||
|
// 中间件,只对本模块有效
|
||||||
|
middlewares: [],
|
||||||
|
// 中间件,全局有效
|
||||||
|
globalMiddlewares: [],
|
||||||
|
// 模块加载顺序,默认为0,值越大越优先加载
|
||||||
|
order: 0,
|
||||||
|
} as ModuleConfig;
|
||||||
|
};
|
||||||
17
src/modules/iot/controller/admin/device.ts
Normal file
17
src/modules/iot/controller/admin/device.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { IotDeviceEntity } from './../../entity/device';
|
||||||
|
import { Provide } from '@midwayjs/decorator';
|
||||||
|
import { CoolController, BaseController } from '@cool-midway/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备信息
|
||||||
|
*/
|
||||||
|
@Provide()
|
||||||
|
@CoolController({
|
||||||
|
api: ['add', 'delete', 'update', 'info', 'list', 'page'],
|
||||||
|
entity: IotDeviceEntity,
|
||||||
|
pageQueryOp: {
|
||||||
|
keyWordLikeFields: ['label', 'uniqueId'],
|
||||||
|
fieldEq: ['status'],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
export class AdminIotDeviceController extends BaseController {}
|
||||||
16
src/modules/iot/controller/admin/message.ts
Normal file
16
src/modules/iot/controller/admin/message.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { IotMessageEntity } from './../../entity/message';
|
||||||
|
import { Provide } from '@midwayjs/decorator';
|
||||||
|
import { CoolController, BaseController } from '@cool-midway/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备消息
|
||||||
|
*/
|
||||||
|
@Provide()
|
||||||
|
@CoolController({
|
||||||
|
api: ['page'],
|
||||||
|
entity: IotMessageEntity,
|
||||||
|
pageQueryOp: {
|
||||||
|
fieldEq: ['deviceId'],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
export class AdminIotMessageController extends BaseController {}
|
||||||
27
src/modules/iot/controller/admin/mqtt.ts
Normal file
27
src/modules/iot/controller/admin/mqtt.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { IotMqttService } from './../../service/mqtt';
|
||||||
|
import { Provide, Get, Post, Body, Inject } from '@midwayjs/decorator';
|
||||||
|
import { CoolController, BaseController } from '@cool-midway/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MQTT相关
|
||||||
|
*/
|
||||||
|
@Provide()
|
||||||
|
@CoolController()
|
||||||
|
export class AdminIotMqttController extends BaseController {
|
||||||
|
@Inject()
|
||||||
|
iotMqttService: IotMqttService;
|
||||||
|
|
||||||
|
@Get('/config', { summary: 'MQTT配置信息' })
|
||||||
|
async config() {
|
||||||
|
return this.ok(await this.iotMqttService.config());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('/publish', { summary: '推送消息' })
|
||||||
|
async publish(
|
||||||
|
@Body('uniqueId') uniqueId: string,
|
||||||
|
@Body('data') data: string
|
||||||
|
) {
|
||||||
|
await this.iotMqttService.publish(uniqueId, data);
|
||||||
|
return this.ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
19
src/modules/iot/controller/mqtt.ts
Normal file
19
src/modules/iot/controller/mqtt.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { Get, Inject, Provide } from '@midwayjs/decorator';
|
||||||
|
import { CoolController, BaseController } from '@cool-midway/core';
|
||||||
|
import { CoolMqttServe } from '@cool-midway/iot';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MQTT
|
||||||
|
*/
|
||||||
|
@Provide()
|
||||||
|
@CoolController()
|
||||||
|
export class IotMqttController extends BaseController {
|
||||||
|
@Inject()
|
||||||
|
coolMqttServe: CoolMqttServe;
|
||||||
|
|
||||||
|
@Get('/publish')
|
||||||
|
async publish() {
|
||||||
|
await this.coolMqttServe.publish('presence', 'hello');
|
||||||
|
return this.ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
25
src/modules/iot/entity/device.ts
Normal file
25
src/modules/iot/entity/device.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { BaseEntity } from '@cool-midway/core';
|
||||||
|
import { Column, Entity, Index } from 'typeorm';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备
|
||||||
|
*/
|
||||||
|
@Entity('iot_device')
|
||||||
|
export class IotDeviceEntity extends BaseEntity {
|
||||||
|
@Column({ comment: '图标', nullable: true })
|
||||||
|
icon: string;
|
||||||
|
|
||||||
|
@Column({ comment: '名称' })
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
@Index({ unique: true })
|
||||||
|
@Column({ comment: '设备唯一ID' })
|
||||||
|
uniqueId: string;
|
||||||
|
|
||||||
|
@Index()
|
||||||
|
@Column({ comment: '状态 0-离线 1-在线', type: 'tinyint', default: 0 })
|
||||||
|
status: number;
|
||||||
|
|
||||||
|
@Column({ comment: '客户端ID', nullable: true })
|
||||||
|
clientId: string;
|
||||||
|
}
|
||||||
19
src/modules/iot/entity/message.ts
Normal file
19
src/modules/iot/entity/message.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { BaseEntity } from '@cool-midway/core';
|
||||||
|
import { Column, Entity, Index } from 'typeorm';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备消息
|
||||||
|
*/
|
||||||
|
@Entity('iot_message')
|
||||||
|
export class IotMessageEntity extends BaseEntity {
|
||||||
|
@Index()
|
||||||
|
@Column({ comment: '设备ID' })
|
||||||
|
deviceId: number;
|
||||||
|
|
||||||
|
@Column({ comment: '数据' })
|
||||||
|
data: string;
|
||||||
|
|
||||||
|
@Index()
|
||||||
|
@Column({ comment: '类型 0-推送 1-接收', type: 'tinyint', default: 1 })
|
||||||
|
type: number;
|
||||||
|
}
|
||||||
18
src/modules/iot/event/app.ts
Normal file
18
src/modules/iot/event/app.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { Inject } from '@midwayjs/core';
|
||||||
|
import { CoolEvent, Event } from '@cool-midway/core';
|
||||||
|
import { IotDeviceService } from '../service/device';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应用事件
|
||||||
|
*/
|
||||||
|
@CoolEvent()
|
||||||
|
export class AppEvent {
|
||||||
|
@Inject()
|
||||||
|
iotDeviceService: IotDeviceService;
|
||||||
|
|
||||||
|
@Event('onServerReady')
|
||||||
|
async onServerReady() {
|
||||||
|
// 重置设备状态
|
||||||
|
await this.iotDeviceService.resetStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
86
src/modules/iot/event/mqtt.ts
Normal file
86
src/modules/iot/event/mqtt.ts
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
import { IotMessageService } from './../service/message';
|
||||||
|
import { IotDeviceService } from './../service/device';
|
||||||
|
import { ILogger, Inject } from '@midwayjs/core';
|
||||||
|
import { CoolMqtt, CoolMqttEvent, CoolMqttServe } from '@cool-midway/iot';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应用事件
|
||||||
|
*/
|
||||||
|
@CoolMqtt()
|
||||||
|
export class IotMQTTEvent {
|
||||||
|
@Inject()
|
||||||
|
iotDeviceService: IotDeviceService;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
iotMessageService: IotMessageService;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
logger: ILogger;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
coolMqttServe: CoolMqttServe;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 客户端连接
|
||||||
|
* @param client
|
||||||
|
*/
|
||||||
|
@CoolMqttEvent('client')
|
||||||
|
async client(client) {
|
||||||
|
this.logger.info('mqtt client event clientId:', client.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送消息
|
||||||
|
* @param packet
|
||||||
|
* @param client
|
||||||
|
*/
|
||||||
|
@CoolMqttEvent('publish')
|
||||||
|
async publish(packet, client) {
|
||||||
|
if (packet.cmd) {
|
||||||
|
// console.log(11);
|
||||||
|
await this.iotMessageService.record(
|
||||||
|
packet.topic,
|
||||||
|
packet.payload.toString(),
|
||||||
|
packet.properties?.contentType == 'push' ? 0 : 1
|
||||||
|
);
|
||||||
|
if (
|
||||||
|
!packet.topic.includes('@admin') &&
|
||||||
|
packet.properties?.contentType != 'push'
|
||||||
|
) {
|
||||||
|
this.coolMqttServe.publish(
|
||||||
|
`${packet.topic}@admin`,
|
||||||
|
packet.payload.toString()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订阅事件 注册设备
|
||||||
|
* @param subscriptions
|
||||||
|
* @param client
|
||||||
|
*/
|
||||||
|
@CoolMqttEvent('subscribe')
|
||||||
|
async subscribe(subscriptions, client) {
|
||||||
|
await this.iotDeviceService.register(subscriptions[0].topic, client.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消订阅
|
||||||
|
* @param subscriptions
|
||||||
|
* @param client
|
||||||
|
*/
|
||||||
|
@CoolMqttEvent('unsubscribe')
|
||||||
|
async unsubscribe(subscriptions, client) {
|
||||||
|
await this.iotDeviceService.changeStatus(subscriptions[0], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 断开连接
|
||||||
|
* @param client
|
||||||
|
*/
|
||||||
|
@CoolMqttEvent('clientDisconnect')
|
||||||
|
async clientDisconnect(client) {
|
||||||
|
this.logger.info('mqtt clientDisconnect event clientId:', client.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
49
src/modules/iot/service/device.ts
Normal file
49
src/modules/iot/service/device.ts
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import { IotDeviceEntity } from './../entity/device';
|
||||||
|
import { Provide, Scope, ScopeEnum } from '@midwayjs/decorator';
|
||||||
|
import { BaseService } from '@cool-midway/core';
|
||||||
|
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||||
|
import { Repository } from 'typeorm';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备
|
||||||
|
*/
|
||||||
|
@Provide()
|
||||||
|
@Scope(ScopeEnum.Request, { allowDowngrade: true })
|
||||||
|
export class IotDeviceService extends BaseService {
|
||||||
|
@InjectEntityModel(IotDeviceEntity)
|
||||||
|
iotDeviceEntity: Repository<IotDeviceEntity>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册设备
|
||||||
|
* @param uniqueId
|
||||||
|
* @param clientId
|
||||||
|
*/
|
||||||
|
async register(uniqueId: string, clientId: string) {
|
||||||
|
const info = await this.iotDeviceEntity.findOneBy({ uniqueId });
|
||||||
|
if (info) {
|
||||||
|
await this.iotDeviceEntity.update({ uniqueId }, { status: 1, clientId });
|
||||||
|
} else {
|
||||||
|
// await this.iotDeviceEntity.insert({ uniqueId, clientId, status: 1 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置所有设备状态
|
||||||
|
*/
|
||||||
|
async resetStatus() {
|
||||||
|
await this.iotDeviceEntity
|
||||||
|
.createQueryBuilder()
|
||||||
|
.update()
|
||||||
|
.set({ status: 0 })
|
||||||
|
.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 改变设备状态
|
||||||
|
* @param uniqueId
|
||||||
|
* @param status
|
||||||
|
*/
|
||||||
|
async changeStatus(uniqueId: string, status: number) {
|
||||||
|
await this.iotDeviceEntity.update({ uniqueId }, { status });
|
||||||
|
}
|
||||||
|
}
|
||||||
32
src/modules/iot/service/message.ts
Normal file
32
src/modules/iot/service/message.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { IotMessageEntity } from './../entity/message';
|
||||||
|
import { IotDeviceEntity } from './../entity/device';
|
||||||
|
import { BaseService } from '@cool-midway/core';
|
||||||
|
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||||
|
import { Repository } from 'typeorm';
|
||||||
|
import { Provide, Singleton } from '@midwayjs/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息
|
||||||
|
*/
|
||||||
|
@Provide()
|
||||||
|
@Singleton()
|
||||||
|
export class IotMessageService extends BaseService {
|
||||||
|
@InjectEntityModel(IotDeviceEntity)
|
||||||
|
iotDeviceEntity: Repository<IotDeviceEntity>;
|
||||||
|
|
||||||
|
@InjectEntityModel(IotMessageEntity)
|
||||||
|
iotMessageEntity: Repository<IotMessageEntity>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 记录消息
|
||||||
|
* @param uniqueId 设备唯一ID
|
||||||
|
* @param data 数据
|
||||||
|
* @param type 类型 0-推送 1-接收
|
||||||
|
*/
|
||||||
|
async record(uniqueId: string, data: string, type: number) {
|
||||||
|
const device = await this.iotDeviceEntity.findOneBy({ uniqueId });
|
||||||
|
if (device) {
|
||||||
|
await this.iotMessageEntity.insert({ deviceId: device.id, data, type });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
43
src/modules/iot/service/mqtt.ts
Normal file
43
src/modules/iot/service/mqtt.ts
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import { CoolMqttServe } from '@cool-midway/iot';
|
||||||
|
import { IotMessageEntity } from './../entity/message';
|
||||||
|
import { Config, Inject, Provide } from '@midwayjs/decorator';
|
||||||
|
import { BaseService, CoolIotConfig } from '@cool-midway/core';
|
||||||
|
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||||
|
import { Repository } from 'typeorm';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MQTT
|
||||||
|
*/
|
||||||
|
@Provide()
|
||||||
|
export class IotMqttService extends BaseService {
|
||||||
|
@InjectEntityModel(IotMessageEntity)
|
||||||
|
iotMessageEntity: Repository<IotMessageEntity>;
|
||||||
|
|
||||||
|
@Config('cool.iot')
|
||||||
|
coolIotConfig: CoolIotConfig;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
coolMqttServe: CoolMqttServe;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置信息
|
||||||
|
*/
|
||||||
|
async config() {
|
||||||
|
return {
|
||||||
|
port: this.coolIotConfig.port,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 推送消息
|
||||||
|
* @param uniqueId 设备唯一ID
|
||||||
|
* @param data 推送数据
|
||||||
|
*/
|
||||||
|
async publish(uniqueId: string, data: string) {
|
||||||
|
await this.coolMqttServe.publish(uniqueId, data, {
|
||||||
|
properties: {
|
||||||
|
contentType: 'push',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
19
src/modules/recycle/config.ts
Normal file
19
src/modules/recycle/config.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { ModuleConfig } from '@cool-midway/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模块配置
|
||||||
|
*/
|
||||||
|
export default () => {
|
||||||
|
return {
|
||||||
|
// 模块名称
|
||||||
|
name: '数据回收',
|
||||||
|
// 模块描述
|
||||||
|
description: '收集被删除的数据,管理和恢复',
|
||||||
|
// 中间件,只对本模块有效
|
||||||
|
middlewares: [],
|
||||||
|
// 中间件,全局有效
|
||||||
|
globalMiddlewares: [],
|
||||||
|
// 模块加载顺序,默认为0,值越大越优先加载
|
||||||
|
order: 0,
|
||||||
|
} as ModuleConfig;
|
||||||
|
};
|
||||||
34
src/modules/recycle/controller/admin/data.ts
Normal file
34
src/modules/recycle/controller/admin/data.ts
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import { BaseSysUserEntity } from './../../../base/entity/sys/user';
|
||||||
|
import { RecycleDataEntity } from './../../entity/data';
|
||||||
|
import { Body, Inject, Post, Provide } from '@midwayjs/decorator';
|
||||||
|
import { CoolController, BaseController } from '@cool-midway/core';
|
||||||
|
import { RecycleDataService } from '../../service/data';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据回收
|
||||||
|
*/
|
||||||
|
@Provide()
|
||||||
|
@CoolController({
|
||||||
|
api: ['info', 'page'],
|
||||||
|
entity: RecycleDataEntity,
|
||||||
|
pageQueryOp: {
|
||||||
|
select: ['a.*', 'b.name as userName'],
|
||||||
|
join: [
|
||||||
|
{
|
||||||
|
entity: BaseSysUserEntity,
|
||||||
|
alias: 'b',
|
||||||
|
condition: 'a.userId = b.id',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
export class AdminRecycleDataController extends BaseController {
|
||||||
|
@Inject()
|
||||||
|
recycleDataService: RecycleDataService;
|
||||||
|
|
||||||
|
@Post('/restore', { summary: '恢复数据' })
|
||||||
|
async restore(@Body('ids') ids: number[]) {
|
||||||
|
await this.recycleDataService.restore(ids);
|
||||||
|
return this.ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
32
src/modules/recycle/entity/data.ts
Normal file
32
src/modules/recycle/entity/data.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { BaseEntity } from '@cool-midway/core';
|
||||||
|
import { Entity, Column, Index } from 'typeorm';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据回收站 软删除的时候数据会回收到该表
|
||||||
|
*/
|
||||||
|
@Entity('recycle_data')
|
||||||
|
export class RecycleDataEntity extends BaseEntity {
|
||||||
|
@Column({ comment: '表', type: 'json' })
|
||||||
|
entityInfo: {
|
||||||
|
// 数据源名称
|
||||||
|
dataSourceName: string;
|
||||||
|
// entity
|
||||||
|
entity: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
@Index()
|
||||||
|
@Column({ comment: '操作人', nullable: true })
|
||||||
|
userId: string;
|
||||||
|
|
||||||
|
@Column({ comment: '被删除的数据', type: 'json' })
|
||||||
|
data: object[];
|
||||||
|
|
||||||
|
@Column({ comment: '请求的接口', nullable: true })
|
||||||
|
url: string;
|
||||||
|
|
||||||
|
@Column({ comment: '请求参数', nullable: true, type: 'json' })
|
||||||
|
params: string;
|
||||||
|
|
||||||
|
@Column({ comment: '删除数据条数', default: 1 })
|
||||||
|
count: number;
|
||||||
|
}
|
||||||
21
src/modules/recycle/event/data.ts
Normal file
21
src/modules/recycle/event/data.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { CoolEvent, EVENT, Event } from '@cool-midway/core';
|
||||||
|
import { Inject } from '@midwayjs/core';
|
||||||
|
import { RecycleDataService } from '../service/data';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接受数据事件
|
||||||
|
*/
|
||||||
|
@CoolEvent()
|
||||||
|
export class RecycleDataEvent {
|
||||||
|
@Inject()
|
||||||
|
recycleDataService: RecycleDataService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据被删除
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
@Event(EVENT.SOFT_DELETE)
|
||||||
|
async softDelete(params) {
|
||||||
|
await this.recycleDataService.record(params);
|
||||||
|
}
|
||||||
|
}
|
||||||
3
src/modules/recycle/init.sql
Normal file
3
src/modules/recycle/init.sql
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
BEGIN;
|
||||||
|
INSERT INTO `base_sys_conf` VALUES (2, '2021-02-25 14:23:26.810981', '2021-02-25 14:23:26.810981', 'recycleKeep', '31');
|
||||||
|
COMMIT;
|
||||||
32
src/modules/recycle/schedule/data.ts
Normal file
32
src/modules/recycle/schedule/data.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import {
|
||||||
|
Provide,
|
||||||
|
Inject,
|
||||||
|
CommonSchedule,
|
||||||
|
TaskLocal,
|
||||||
|
FORMAT,
|
||||||
|
} from '@midwayjs/decorator';
|
||||||
|
import { ILogger } from '@midwayjs/logger';
|
||||||
|
import { RecycleDataService } from '../service/data';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据定时清除定时任务
|
||||||
|
*/
|
||||||
|
@Provide()
|
||||||
|
export class BaseRecycleSchedule implements CommonSchedule {
|
||||||
|
@Inject()
|
||||||
|
recycleDataService: RecycleDataService;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
logger: ILogger;
|
||||||
|
|
||||||
|
// 定时执行的具体任务
|
||||||
|
@TaskLocal(FORMAT.CRONTAB.EVERY_DAY)
|
||||||
|
async exec() {
|
||||||
|
this.logger.info('清除回收站数据定时任务开始执行');
|
||||||
|
const startTime = Date.now();
|
||||||
|
await this.recycleDataService.clear();
|
||||||
|
this.logger.info(
|
||||||
|
`清除回收站数据定时任务结束,耗时:${Date.now() - startTime}ms`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
89
src/modules/recycle/service/data.ts
Normal file
89
src/modules/recycle/service/data.ts
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
import { RecycleDataEntity } from './../entity/data';
|
||||||
|
import { Inject, Provide, Scope, ScopeEnum } from '@midwayjs/decorator';
|
||||||
|
import { BaseService } from '@cool-midway/core';
|
||||||
|
import { InjectEntityModel, TypeORMDataSourceManager } from '@midwayjs/typeorm';
|
||||||
|
import { Repository } from 'typeorm';
|
||||||
|
import * as _ from 'lodash';
|
||||||
|
import * as moment from 'moment';
|
||||||
|
import { BaseSysConfService } from '../../base/service/sys/conf';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据回收
|
||||||
|
*/
|
||||||
|
@Provide()
|
||||||
|
@Scope(ScopeEnum.Request, { allowDowngrade: true })
|
||||||
|
export class RecycleDataService extends BaseService {
|
||||||
|
@InjectEntityModel(RecycleDataEntity)
|
||||||
|
recycleDataEntity: Repository<RecycleDataEntity>;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
typeORMDataSourceManager: TypeORMDataSourceManager;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
baseSysConfService: BaseSysConfService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 恢复数据
|
||||||
|
* @param ids
|
||||||
|
*/
|
||||||
|
async restore(ids: number[]) {
|
||||||
|
for (const id of ids) {
|
||||||
|
const info = await this.recycleDataEntity.findOneBy({ id });
|
||||||
|
if (!info) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let entityModel = this.typeORMDataSourceManager
|
||||||
|
.getDataSource(info.entityInfo.dataSourceName)
|
||||||
|
.getRepository(info.entityInfo.entity);
|
||||||
|
await entityModel.save(info.data);
|
||||||
|
await this.recycleDataEntity.delete(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 记录数据
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
async record(params) {
|
||||||
|
const { ctx, data, entity } = params;
|
||||||
|
const dataSourceName =
|
||||||
|
this.typeORMDataSourceManager.getDataSourceNameByModel(entity.target);
|
||||||
|
const url = ctx?.url;
|
||||||
|
await this.recycleDataEntity.save({
|
||||||
|
entityInfo: {
|
||||||
|
dataSourceName,
|
||||||
|
entity: entity.target.name,
|
||||||
|
},
|
||||||
|
url,
|
||||||
|
params:
|
||||||
|
ctx?.req.method === 'GET' ? ctx?.request.query : ctx?.request.body,
|
||||||
|
data,
|
||||||
|
count: data.length,
|
||||||
|
userId: _.startsWith(url, '/admin/') ? ctx?.admin.userId : ctx?.user?.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日志
|
||||||
|
* @param isAll 是否清除全部
|
||||||
|
*/
|
||||||
|
async clear(isAll?) {
|
||||||
|
if (isAll) {
|
||||||
|
await this.recycleDataEntity.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const keepDay = await this.baseSysConfService.getValue('recycleKeep');
|
||||||
|
if (keepDay) {
|
||||||
|
const beforeDate = `${moment()
|
||||||
|
.add(-keepDay, 'days')
|
||||||
|
.format('YYYY-MM-DD')} 00:00:00`;
|
||||||
|
await this.recycleDataEntity
|
||||||
|
.createQueryBuilder()
|
||||||
|
.delete()
|
||||||
|
.where('createTime < :createTime', { createTime: beforeDate })
|
||||||
|
.execute();
|
||||||
|
} else {
|
||||||
|
await this.recycleDataEntity.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -15,5 +15,10 @@ export default () => {
|
|||||||
globalMiddlewares: [],
|
globalMiddlewares: [],
|
||||||
// 模块加载顺序,默认为0,值越大越优先加载
|
// 模块加载顺序,默认为0,值越大越优先加载
|
||||||
order: 0,
|
order: 0,
|
||||||
|
// wps的配置
|
||||||
|
wps: {
|
||||||
|
// 这是个测试的appId,会有水印
|
||||||
|
appId: 'SX20230111NDUAGQ',
|
||||||
|
},
|
||||||
} as ModuleConfig;
|
} as ModuleConfig;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { Provide } from '@midwayjs/decorator';
|
import { Config, Get, Provide } from '@midwayjs/decorator';
|
||||||
import { CoolController, BaseController } from '@cool-midway/core';
|
import { CoolController, BaseController } from '@cool-midway/core';
|
||||||
import { SpaceInfoEntity } from '../../entity/info';
|
import { SpaceInfoEntity } from '../../entity/info';
|
||||||
|
import { SpaceInfoService } from '../../service/info';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 图片空间信息
|
* 图片空间信息
|
||||||
@ -9,8 +10,17 @@ import { SpaceInfoEntity } from '../../entity/info';
|
|||||||
@CoolController({
|
@CoolController({
|
||||||
api: ['add', 'delete', 'update', 'info', 'list', 'page'],
|
api: ['add', 'delete', 'update', 'info', 'list', 'page'],
|
||||||
entity: SpaceInfoEntity,
|
entity: SpaceInfoEntity,
|
||||||
|
service: SpaceInfoService,
|
||||||
pageQueryOp: {
|
pageQueryOp: {
|
||||||
fieldEq: ['type', 'classifyId'],
|
fieldEq: ['type', 'classifyId'],
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
export class BaseAppSpaceInfoController extends BaseController {}
|
export class BaseAppSpaceInfoController extends BaseController {
|
||||||
|
@Config('module.space.wps')
|
||||||
|
config;
|
||||||
|
|
||||||
|
@Get('/getConfig', { summary: '获得WPS配置' })
|
||||||
|
async getConfig() {
|
||||||
|
return this.ok({ appId: this.config.appId });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
65
src/modules/space/controller/app/wps.ts
Normal file
65
src/modules/space/controller/app/wps.ts
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import {
|
||||||
|
ALL,
|
||||||
|
Body,
|
||||||
|
Files,
|
||||||
|
Get,
|
||||||
|
Inject,
|
||||||
|
Param,
|
||||||
|
Post,
|
||||||
|
Provide,
|
||||||
|
Query,
|
||||||
|
} from '@midwayjs/decorator';
|
||||||
|
import { CoolController, BaseController } from '@cool-midway/core';
|
||||||
|
import { SpaceWpsService } from '../../service/wps';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wps回调
|
||||||
|
*/
|
||||||
|
@Provide()
|
||||||
|
@CoolController('/wps')
|
||||||
|
export class AppSpaceWpsController extends BaseController {
|
||||||
|
@Inject()
|
||||||
|
spaceWpsService: SpaceWpsService;
|
||||||
|
|
||||||
|
@Get('/v3/3rd/files/:file_id', { summary: '获取文件信息' })
|
||||||
|
async files(@Param('file_id') file_id: string) {
|
||||||
|
return await this.spaceWpsService.getFiles(file_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('/v3/3rd/files/:file_id/download', { summary: '获取文件下载地址' })
|
||||||
|
async download(@Param('file_id') file_id: string) {
|
||||||
|
return await this.spaceWpsService.download(file_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('/v3/3rd/files/:file_id/permission', { summary: '获取文档用户权限' })
|
||||||
|
async permission(@Param('file_id') file_id: string) {
|
||||||
|
return await this.spaceWpsService.permission(file_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('/v3/3rd/files/:file_id/upload', { summary: '文件上传' })
|
||||||
|
async upload(@Param('file_id') file_id: string, @Files() files) {
|
||||||
|
return await this.spaceWpsService.upload(file_id, files);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('/v3/3rd/files/:file_id/upload/prepare', { summary: '准备上传阶段' })
|
||||||
|
async uploadPrepare(@Param('file_id') file_id: string) {
|
||||||
|
return await this.spaceWpsService.uploadPrepare(file_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('/v3/3rd/files/:file_id/upload/address', { summary: '获取上传地址' })
|
||||||
|
async uploadAddress(@Param('file_id') file_id: string, @Body(ALL) body) {
|
||||||
|
return await this.spaceWpsService.uploadAddress(file_id, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('/v3/3rd/files/:file_id/upload/complete', {
|
||||||
|
summary: '上传完成后,回调通知上传结果',
|
||||||
|
})
|
||||||
|
async uploadComplete(@Param('file_id') file_id: string, @Body(ALL) body) {
|
||||||
|
return await this.spaceWpsService.uploadComplete(file_id, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('/v3/3rd/users', { summary: '用户信息' })
|
||||||
|
async users(@Query('user_ids') user_ids: string[]) {
|
||||||
|
return await this.spaceWpsService.users(user_ids);
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user