diff --git a/core/package.json b/core/package.json index 4832058..ee43ca3 100644 --- a/core/package.json +++ b/core/package.json @@ -36,6 +36,7 @@ "@midwayjs/typeorm": "^3.9.0", "@types/jest": "^29.2.4", "@types/node": "^18.11.15", + "@types/download": "^8.0.5", "aedes": "^0.48.1", "cross-env": "^7.0.3", "jest": "^29.3.1", @@ -46,10 +47,17 @@ }, "dependencies": { "@midwayjs/cache": "^3.9.0", + "sqlstring": "^2.3.3", + "axios": "^1.6.5", + "download": "^8.0.0", + "jsonwebtoken": "^9.0.2", "lodash": "^4.17.21", "md5": "^2.3.0", - "moment": "^2.29.4", - "mysql2-import": "^5.0.22", - "sqlstring": "^2.3.3" + "mini-svg-data-uri": "^1.4.4", + "moment": "^2.30.1", + "svg-captcha": "^1.4.0", + "svg2png-wasm": "^1.4.1", + "uuid": "^9.0.1", + "decompress": "^4.2.1" } } diff --git a/core/src/module/config.ts b/core/src/module/config.ts index d3b510a..9e2f9c0 100644 --- a/core/src/module/config.ts +++ b/core/src/module/config.ts @@ -1,4 +1,4 @@ -import { IMidwayApplication } from '@midwayjs/core'; +import { IMidwayApplication } from "@midwayjs/core"; import { ALL, App, @@ -7,11 +7,11 @@ import { Provide, Scope, ScopeEnum, -} from '@midwayjs/decorator'; -import * as fs from 'fs'; -import { CoolCoreException } from '../exception/core'; -import { ModuleConfig } from '../interface'; -import * as _ from 'lodash'; +} from "@midwayjs/decorator"; +import * as fs from "fs"; +import { CoolCoreException } from "../exception/core"; +import { ModuleConfig } from "../interface"; +import * as _ from "lodash"; /** * 模块配置 @@ -35,8 +35,8 @@ export class CoolModuleConfig { if (!fs.existsSync(moduleBasePath)) { return; } - if (!this.allConfig['module']) { - this.allConfig['module'] = {}; + if (!this.allConfig["module"]) { + this.allConfig["module"] = {}; } // 全局中间件 const globalMiddlewareArr = []; @@ -45,7 +45,7 @@ export class CoolModuleConfig { const dirStats = fs.statSync(modulePath); if (dirStats.isDirectory()) { const configPath = `${modulePath}/config.${ - this.app.getEnv() == 'local' ? 'ts' : 'js' + this.app.getEnv() == "local" ? "ts" : "js" }`; if (fs.existsSync(configPath)) { const moduleConfig: ModuleConfig = require(configPath).default({ @@ -69,7 +69,7 @@ export class CoolModuleConfig { } } } - this.modules = _.orderBy(modules, ['order'], ['desc']).map(e => { + this.modules = _.orderBy(modules, ["order"], ["desc"]).map((e) => { return e.module; }); await this.globalMiddlewareArr(globalMiddlewareArr); @@ -82,7 +82,7 @@ export class CoolModuleConfig { */ async moduleConfig(module, config) { // 追加配置 - this.allConfig['module'][module] = config; + this.allConfig["module"][module] = config; } /** @@ -90,7 +90,7 @@ export class CoolModuleConfig { * @param middleware 中间件 */ async globalMiddlewareArr(middlewares: any[]) { - middlewares = _.orderBy(middlewares, ['order'], ['desc']); + middlewares = _.orderBy(middlewares, ["order"], ["desc"]); for (const middleware of middlewares) { for (const item of middleware.data) { this.app.getMiddleware().insertLast(item); diff --git a/core/src/module/import.ts b/core/src/module/import.ts index 49da425..1feb5bb 100644 --- a/core/src/module/import.ts +++ b/core/src/module/import.ts @@ -9,7 +9,6 @@ import { Scope, ScopeEnum, } from "@midwayjs/decorator"; -// import * as Importer from "mysql2-import"; import * as fs from "fs"; import { CoolModuleConfig } from "./config"; import * as path from "path"; @@ -17,7 +16,7 @@ import { InjectDataSource, TypeORMDataSourceManager } from "@midwayjs/typeorm"; import { DataSource } from "typeorm"; import { CoolEventManager } from "../event"; import { CoolModuleMenu } from "./menu"; -import * as _ from 'lodash'; +import * as _ from "lodash"; /** * 模块sql @@ -61,7 +60,7 @@ export class CoolModuleImport { `${this.app.getBaseDir()}`, "..", "lock", - 'db' + "db" ); if (!fs.existsSync(importLockPath)) { fs.mkdirSync(importLockPath, { recursive: true }); @@ -70,7 +69,7 @@ export class CoolModuleImport { for (const module of modules) { const lockPath = path.join(importLockPath, module + ".db.lock"); if (!fs.existsSync(lockPath)) { - await this.initDataBase(module, lockPath); + await this.initDataBase(module, lockPath); } } this.coolEventManager.emit("onDBInit", {}); @@ -92,29 +91,38 @@ export class CoolModuleImport { // 数据路径 const dataPath = `${modulePath}/db.json`; // 判断文件是否存在 - if(fs.existsSync(dataPath)) { + if (fs.existsSync(dataPath)) { // 获得所有的实体 const entityMetadatas = this.defaultDataSource.entityMetadatas; - const metadatas = _.mapValues(_.keyBy(entityMetadatas, 'tableName'), 'target'); + const metadatas = _.mapValues( + _.keyBy(entityMetadatas, "tableName"), + "target" + ); // 读取数据 - const data = JSON.parse(fs.readFileSync(dataPath).toString() || '{}'); + const data = JSON.parse(fs.readFileSync(dataPath).toString() || "{}"); // 导入数据 - for(const key in data) { - try{ - const repository = this.defaultDataSource.getRepository(metadatas[key]); - if(this.ormConfig.default.type == 'postgres') { - for(const item of data[key]) { - const result: any = await repository.save(repository.create(item)); - if(item.id) { + for (const key in data) { + try { + const repository = this.defaultDataSource.getRepository( + metadatas[key] + ); + if (this.ormConfig.default.type == "postgres") { + for (const item of data[key]) { + const result: any = await repository.save( + repository.create(item) + ); + if (item.id) { await repository.update(result.id, { id: item.id }); // 更新pgsql序列 - await this.defaultDataSource.query(`SELECT setval('${key}_id_seq', (SELECT MAX(id) FROM ${key}));`); + await this.defaultDataSource.query( + `SELECT setval('${key}_id_seq', (SELECT MAX(id) FROM ${key}));` + ); } } - }else{ + } else { await repository.insert(data[key]); } - }catch(e){ + } catch (e) { this.coreLogger.error( "\x1B[36m [cool:core] midwayjs cool core init " + module + @@ -124,76 +132,12 @@ export class CoolModuleImport { } } const endTime = new Date().getTime(); - fs.writeFileSync(lockPath, `time consuming:${endTime-startTime}ms`); + fs.writeFileSync(lockPath, `time consuming:${endTime - startTime}ms`); this.coreLogger.info( "\x1B[36m [cool:core] midwayjs cool core init " + module + " database complete \x1B[0m" ); } - // // sql 路径 - // const sqlPath = `${modulePath}/init.sql`; - // // 延迟2秒再导入数据库 - // if (fs.existsSync(sqlPath)) { - // let second = 0; - // const t = setInterval(() => { - // this.coreLogger.info( - // "\x1B[36m [cool:core] midwayjs cool core init " + - // module + - // " database... \x1B[0m" - // ); - // second++; - // }, 1000); - // const { host, username, password, database, charset, port } = this - // .ormConfig?.default - // ? this.ormConfig.default - // : this.ormConfig; - // const importer = new Importer({ - // host, - // password, - // database, - // charset, - // port, - // user: username, - // }); - // await importer - // .import(sqlPath) - // .then(async () => { - // clearInterval(t); - // this.coreLogger.info( - // "\x1B[36m [cool:core] midwayjs cool core init " + - // module + - // " database complete \x1B[0m" - // ); - // fs.writeFileSync(lockPath, `time consuming:${second}s`); - // }) - // .catch((err) => { - // clearTimeout(t); - // this.coreLogger.error( - // "\x1B[36m [cool:core] midwayjs cool core init " + - // module + - // " database err please manual import \x1B[0m" - // ); - // fs.writeFileSync(lockPath, `time consuming:${second}s`); - // this.coreLogger.error(err); - // this.coreLogger.error( - // `自动初始化模块[${module}]数据库失败,尝试手动导入数据库` - // ); - // }); - // } } - - /** - * 检查数据库版本 - */ - // async checkDbVersion() { - // const versions = ( - // await this.defaultDataSource.query("SELECT VERSION() AS version") - // )[0].version.split("."); - // if ((versions[0] == 5 && versions[1] < 7) || versions[0] < 5) { - // throw new CoolCoreException( - // "数据库不满足要求:mysql>=5.7,请升级数据库版本" - // ); - // } - // } } diff --git a/core/src/package.json b/core/src/package.json index 6c5f40e..b11c1bc 100644 --- a/core/src/package.json +++ b/core/src/package.json @@ -45,10 +45,17 @@ }, "dependencies": { "@midwayjs/cache": "^3.9.0", + "sqlstring": "^2.3.3", + "axios": "^1.6.5", + "download": "^8.0.0", + "jsonwebtoken": "^9.0.2", "lodash": "^4.17.21", "md5": "^2.3.0", - "moment": "^2.29.4", - "mysql2-import": "^5.0.22", - "sqlstring": "^2.3.3" + "mini-svg-data-uri": "^1.4.4", + "moment": "^2.30.1", + "svg-captcha": "^1.4.0", + "svg2png-wasm": "^1.4.1", + "uuid": "^9.0.1", + "decompress": "^4.2.1" } } diff --git a/plugin-cli/package.json b/plugin-cli/package.json index 2dbee3f..2f4a6e0 100644 --- a/plugin-cli/package.json +++ b/plugin-cli/package.json @@ -1,6 +1,6 @@ { "name": "@cool-midway/plugin-cli", - "version": "7.0.0-beta4", + "version": "7.0.0-beta6", "description": "cool-admin midway plugin", "main": "dist/index.js", "scripts": { diff --git a/plugin-cli/src/constant/global.ts b/plugin-cli/src/constant/global.ts new file mode 100644 index 0000000..ad18ebe --- /dev/null +++ b/plugin-cli/src/constant/global.ts @@ -0,0 +1,84 @@ +/** + * 返回码 + */ +export enum RESCODE { + // 成功 + SUCCESS = 1000, + // 失败 + COMMFAIL = 1001, + // 参数验证失败 + VALIDATEFAIL = 1002, + // 参数验证失败 + COREFAIL = 1003, +} + +/** + * 返回信息 + */ +export enum RESMESSAGE { + // 成功 + SUCCESS = "success", + // 失败 + COMMFAIL = "comm fail", + // 参数验证失败 + VALIDATEFAIL = "validate fail", + // 核心异常 + COREFAIL = "core fail", +} + +/** + * 错误提示 + */ +export enum ERRINFO { + NOENTITY = "未设置操作实体", + NOID = "查询参数[id]不存在", + SORTFIELD = "排序参数不正确", +} + +/** + * 事件 + */ +export enum EVENT { + // 软删除 + SOFT_DELETE = "onSoftDelete", + // 服务成功启动 + SERVER_READY = "onServerReady", + // 服务就绪 + READY = "onReady", + // ES 数据改变 + ES_DATA_CHANGE = "esDataChange", +} + + +export class GlobalConfig { + private static instance: GlobalConfig; + + RESCODE = { + SUCCESS: 1000, + COMMFAIL: 1001, + VALIDATEFAIL: 1002, + COREFAIL: 1003, + }; + + RESMESSAGE = { + SUCCESS: "success", + COMMFAIL: "comm fail", + VALIDATEFAIL: "validate fail", + COREFAIL: "core fail", + }; + + // ... 其他的配置 ... + + private constructor() {} + + static getInstance(): GlobalConfig { + if (!GlobalConfig.instance) { + GlobalConfig.instance = new GlobalConfig(); + } + return GlobalConfig.instance; + } +} + + + + diff --git a/plugin-cli/src/exception/base.ts b/plugin-cli/src/exception/base.ts new file mode 100644 index 0000000..177b46b --- /dev/null +++ b/plugin-cli/src/exception/base.ts @@ -0,0 +1,13 @@ +/** + * 异常基类 + */ +export class BaseException extends Error { + status: number; + + constructor(name: string, code: number, message: string) { + super(message); + + this.name = name; + this.status = code; + } +} diff --git a/plugin-cli/src/exception/comm.ts b/plugin-cli/src/exception/comm.ts new file mode 100644 index 0000000..d2c9525 --- /dev/null +++ b/plugin-cli/src/exception/comm.ts @@ -0,0 +1,16 @@ +import { GlobalConfig } from '../constant/global'; +import { BaseException } from './base'; + +/** + * 通用异常 + */ +export class CoolCommException extends BaseException { + constructor(message: string) { + const { RESCODE, RESMESSAGE } = GlobalConfig.getInstance(); + super( + 'CoolCommException', + RESCODE.COMMFAIL, + message ? message : RESMESSAGE.COMMFAIL + ); + } +} diff --git a/plugin-cli/src/exception/core.ts b/plugin-cli/src/exception/core.ts new file mode 100644 index 0000000..9dc3a7e --- /dev/null +++ b/plugin-cli/src/exception/core.ts @@ -0,0 +1,16 @@ +import { GlobalConfig } from '../constant/global'; +import { BaseException } from './base'; + +/** + * 核心异常 + */ +export class CoolCoreException extends BaseException { + constructor(message: string) { + const { RESCODE, RESMESSAGE } = GlobalConfig.getInstance(); + super( + 'CoolCoreException', + RESCODE.COREFAIL, + message ? message : RESMESSAGE.COREFAIL + ); + } +} diff --git a/plugin-cli/src/exception/validate.ts b/plugin-cli/src/exception/validate.ts new file mode 100644 index 0000000..9a49abb --- /dev/null +++ b/plugin-cli/src/exception/validate.ts @@ -0,0 +1,16 @@ +import { GlobalConfig } from "../constant/global"; +import { BaseException } from "./base"; + +/** + * 校验异常 + */ +export class CoolValidateException extends BaseException { + constructor(message: string) { + const { RESCODE, RESMESSAGE } = GlobalConfig.getInstance(); + super( + "CoolValidateException", + RESCODE.VALIDATEFAIL, + message ? message : RESMESSAGE.VALIDATEFAIL + ); + } +} diff --git a/plugin-cli/src/hook/upload.ts b/plugin-cli/src/hook/upload.ts new file mode 100644 index 0000000..afe1915 --- /dev/null +++ b/plugin-cli/src/hook/upload.ts @@ -0,0 +1,67 @@ +// 模式 +export enum MODETYPE { + // 本地 + LOCAL = "local", + // 云存储 + CLOUD = "cloud", + // 其他 + OTHER = "other", +} + +export enum CLOUDTYPE { + // 阿里云存储 + OSS = "oss", + // 腾讯云存储 + COS = "cos", + // 七牛云存储 + QINIU = "qiniu", + /** AWS S3 */ + AWS = "aws", +} + +/** + * 上传模式 + */ +export interface Mode { + // 模式 + mode: MODETYPE; + // 类型 + type: string; +} + +/** + * 文件上传 + */ +export interface BaseFile { + /** + * 获得上传模式 + */ + getMode(): Promise; + + /** + * 获得原始操作对象 + * @returns + */ + getMetaFileObj(): Promise; + + /** + * 下载并上传 + * @param url + * @param fileName 文件名 + */ + downAndUpload(url: string, fileName?: string): Promise; + + /** + * 指定Key(路径)上传,本地文件上传到存储服务 + * @param filePath 文件路径 + * @param key 路径一致会覆盖源文件 + */ + uploadWithKey(filePath, key): Promise; + + /** + * 上传文件 + * @param ctx + * @param key 文件路径 + */ + upload(ctx): Promise; +} diff --git a/plugin-cli/src/index.ts b/plugin-cli/src/index.ts index 07b05ac..2765d98 100644 --- a/plugin-cli/src/index.ts +++ b/plugin-cli/src/index.ts @@ -1,51 +1,63 @@ -import { IMidwayContext, IMidwayApplication } from '@midwayjs/core'; +import { IMidwayContext, IMidwayApplication } from "@midwayjs/core"; /** * 插件信息 */ export interface PluginInfo { - /** 名称 */ - name: string; - /** 唯一标识 */ - key: string; - /** 钩子 */ - hook: string; - /** 版本 */ - version: string; - /** 描述 */ - description: string; - /** 作者 */ - author: string; - /** logo */ - logo: string; - /** README 使用说明 */ - readme: string; - /** 配置 */ - config: any; + /** 名称 */ + name: string; + /** 唯一标识 */ + key: string; + /** 钩子 */ + hook: string; + /** 版本 */ + version: string; + /** 描述 */ + description: string; + /** 作者 */ + author: string; + /** logo */ + logo: string; + /** README 使用说明 */ + readme: string; + /** 配置 */ + config: any; } /** * 插件基类,不建议修改 */ export abstract class BasePlugin { - /** 插件信息 */ - pluginInfo: PluginInfo; - /** 请求上下文,用到此项无法本地调试,需安装到cool-admin中才能调试 */ - ctx: IMidwayContext; - /** 应用实例,用到此项无法本地调试,需安装到cool-admin中才能调试 */ - app: IMidwayApplication; + /** 插件信息 */ + pluginInfo: PluginInfo; + /** 请求上下文,用到此项无法本地调试,需安装到cool-admin中才能调试 */ + ctx: IMidwayContext; + /** 应用实例,用到此项无法本地调试,需安装到cool-admin中才能调试 */ + app: IMidwayApplication; - constructor() {} + setCtx(ctx: IMidwayContext) { + this.ctx = ctx; + } - /** - * 初始化插件 - * @param pluginInfo - * @param ctx - * @param app - */ - async init(pluginInfo: PluginInfo, ctx?: IMidwayContext, app?: IMidwayApplication){ - this.pluginInfo = pluginInfo; - this.ctx = ctx; - this.app = app; - }; -} \ No newline at end of file + setApp(app: IMidwayApplication) { + this.app = app; + } + + constructor() {} + + /** + * 初始化插件 + * @param pluginInfo + * @param ctx + * @param app + */ + async init( + pluginInfo: PluginInfo, + ctx?: IMidwayContext, + app?: IMidwayApplication + ) { + this.pluginInfo = pluginInfo; + this.ctx = ctx; + this.app = app; + } +}