插件管理

This commit is contained in:
cool 2024-01-22 15:23:45 +08:00
parent f99203fdfe
commit 199d8af0f3
12 changed files with 322 additions and 139 deletions

View File

@ -36,6 +36,7 @@
"@midwayjs/typeorm": "^3.9.0", "@midwayjs/typeorm": "^3.9.0",
"@types/jest": "^29.2.4", "@types/jest": "^29.2.4",
"@types/node": "^18.11.15", "@types/node": "^18.11.15",
"@types/download": "^8.0.5",
"aedes": "^0.48.1", "aedes": "^0.48.1",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"jest": "^29.3.1", "jest": "^29.3.1",
@ -46,10 +47,17 @@
}, },
"dependencies": { "dependencies": {
"@midwayjs/cache": "^3.9.0", "@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", "lodash": "^4.17.21",
"md5": "^2.3.0", "md5": "^2.3.0",
"moment": "^2.29.4", "mini-svg-data-uri": "^1.4.4",
"mysql2-import": "^5.0.22", "moment": "^2.30.1",
"sqlstring": "^2.3.3" "svg-captcha": "^1.4.0",
"svg2png-wasm": "^1.4.1",
"uuid": "^9.0.1",
"decompress": "^4.2.1"
} }
} }

View File

@ -1,4 +1,4 @@
import { IMidwayApplication } from '@midwayjs/core'; import { IMidwayApplication } from "@midwayjs/core";
import { import {
ALL, ALL,
App, App,
@ -7,11 +7,11 @@ import {
Provide, Provide,
Scope, Scope,
ScopeEnum, ScopeEnum,
} from '@midwayjs/decorator'; } from "@midwayjs/decorator";
import * as fs from 'fs'; import * as fs from "fs";
import { CoolCoreException } from '../exception/core'; import { CoolCoreException } from "../exception/core";
import { ModuleConfig } from '../interface'; import { ModuleConfig } from "../interface";
import * as _ from 'lodash'; import * as _ from "lodash";
/** /**
* *
@ -35,8 +35,8 @@ export class CoolModuleConfig {
if (!fs.existsSync(moduleBasePath)) { if (!fs.existsSync(moduleBasePath)) {
return; return;
} }
if (!this.allConfig['module']) { if (!this.allConfig["module"]) {
this.allConfig['module'] = {}; this.allConfig["module"] = {};
} }
// 全局中间件 // 全局中间件
const globalMiddlewareArr = []; const globalMiddlewareArr = [];
@ -45,7 +45,7 @@ export class CoolModuleConfig {
const dirStats = fs.statSync(modulePath); const dirStats = fs.statSync(modulePath);
if (dirStats.isDirectory()) { if (dirStats.isDirectory()) {
const configPath = `${modulePath}/config.${ const configPath = `${modulePath}/config.${
this.app.getEnv() == 'local' ? 'ts' : 'js' this.app.getEnv() == "local" ? "ts" : "js"
}`; }`;
if (fs.existsSync(configPath)) { if (fs.existsSync(configPath)) {
const moduleConfig: ModuleConfig = require(configPath).default({ 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; return e.module;
}); });
await this.globalMiddlewareArr(globalMiddlewareArr); await this.globalMiddlewareArr(globalMiddlewareArr);
@ -82,7 +82,7 @@ export class CoolModuleConfig {
*/ */
async moduleConfig(module, config) { async moduleConfig(module, config) {
// 追加配置 // 追加配置
this.allConfig['module'][module] = config; this.allConfig["module"][module] = config;
} }
/** /**
@ -90,7 +90,7 @@ export class CoolModuleConfig {
* @param middleware * @param middleware
*/ */
async globalMiddlewareArr(middlewares: any[]) { async globalMiddlewareArr(middlewares: any[]) {
middlewares = _.orderBy(middlewares, ['order'], ['desc']); middlewares = _.orderBy(middlewares, ["order"], ["desc"]);
for (const middleware of middlewares) { for (const middleware of middlewares) {
for (const item of middleware.data) { for (const item of middleware.data) {
this.app.getMiddleware().insertLast(item); this.app.getMiddleware().insertLast(item);

View File

@ -9,7 +9,6 @@ import {
Scope, Scope,
ScopeEnum, ScopeEnum,
} from "@midwayjs/decorator"; } from "@midwayjs/decorator";
// import * as Importer from "mysql2-import";
import * as fs from "fs"; import * as fs from "fs";
import { CoolModuleConfig } from "./config"; import { CoolModuleConfig } from "./config";
import * as path from "path"; import * as path from "path";
@ -17,7 +16,7 @@ import { InjectDataSource, TypeORMDataSourceManager } from "@midwayjs/typeorm";
import { DataSource } from "typeorm"; import { DataSource } from "typeorm";
import { CoolEventManager } from "../event"; import { CoolEventManager } from "../event";
import { CoolModuleMenu } from "./menu"; import { CoolModuleMenu } from "./menu";
import * as _ from 'lodash'; import * as _ from "lodash";
/** /**
* sql * sql
@ -61,7 +60,7 @@ export class CoolModuleImport {
`${this.app.getBaseDir()}`, `${this.app.getBaseDir()}`,
"..", "..",
"lock", "lock",
'db' "db"
); );
if (!fs.existsSync(importLockPath)) { if (!fs.existsSync(importLockPath)) {
fs.mkdirSync(importLockPath, { recursive: true }); fs.mkdirSync(importLockPath, { recursive: true });
@ -92,29 +91,38 @@ export class CoolModuleImport {
// 数据路径 // 数据路径
const dataPath = `${modulePath}/db.json`; const dataPath = `${modulePath}/db.json`;
// 判断文件是否存在 // 判断文件是否存在
if(fs.existsSync(dataPath)) { if (fs.existsSync(dataPath)) {
// 获得所有的实体 // 获得所有的实体
const entityMetadatas = this.defaultDataSource.entityMetadatas; 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) { for (const key in data) {
try{ try {
const repository = this.defaultDataSource.getRepository(metadatas[key]); const repository = this.defaultDataSource.getRepository(
if(this.ormConfig.default.type == 'postgres') { metadatas[key]
for(const item of data[key]) { );
const result: any = await repository.save(repository.create(item)); if (this.ormConfig.default.type == "postgres") {
if(item.id) { 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 }); await repository.update(result.id, { id: item.id });
// 更新pgsql序列 // 更新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]); await repository.insert(data[key]);
} }
}catch(e){ } catch (e) {
this.coreLogger.error( this.coreLogger.error(
"\x1B[36m [cool:core] midwayjs cool core init " + "\x1B[36m [cool:core] midwayjs cool core init " +
module + module +
@ -124,76 +132,12 @@ export class CoolModuleImport {
} }
} }
const endTime = new Date().getTime(); const endTime = new Date().getTime();
fs.writeFileSync(lockPath, `time consuming${endTime-startTime}ms`); fs.writeFileSync(lockPath, `time consuming${endTime - startTime}ms`);
this.coreLogger.info( this.coreLogger.info(
"\x1B[36m [cool:core] midwayjs cool core init " + "\x1B[36m [cool:core] midwayjs cool core init " +
module + module +
" database complete \x1B[0m" " 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,请升级数据库版本"
// );
// }
// }
} }

View File

@ -45,10 +45,17 @@
}, },
"dependencies": { "dependencies": {
"@midwayjs/cache": "^3.9.0", "@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", "lodash": "^4.17.21",
"md5": "^2.3.0", "md5": "^2.3.0",
"moment": "^2.29.4", "mini-svg-data-uri": "^1.4.4",
"mysql2-import": "^5.0.22", "moment": "^2.30.1",
"sqlstring": "^2.3.3" "svg-captcha": "^1.4.0",
"svg2png-wasm": "^1.4.1",
"uuid": "^9.0.1",
"decompress": "^4.2.1"
} }
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "@cool-midway/plugin-cli", "name": "@cool-midway/plugin-cli",
"version": "7.0.0-beta4", "version": "7.0.0-beta6",
"description": "cool-admin midway plugin", "description": "cool-admin midway plugin",
"main": "dist/index.js", "main": "dist/index.js",
"scripts": { "scripts": {

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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
);
}
}

View File

@ -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
);
}
}

View File

@ -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
);
}
}

View File

@ -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<string>;
/**
*
* @returns
*/
getMetaFileObj(): Promise<any>;
/**
*
* @param url
* @param fileName
*/
downAndUpload(url: string, fileName?: string): Promise<string>;
/**
* Key()
* @param filePath
* @param key
*/
uploadWithKey(filePath, key): Promise<string>;
/**
*
* @param ctx
* @param key
*/
upload(ctx): Promise<string>;
}

View File

@ -1,4 +1,4 @@
import { IMidwayContext, IMidwayApplication } from '@midwayjs/core'; import { IMidwayContext, IMidwayApplication } from "@midwayjs/core";
/** /**
* *
@ -35,6 +35,14 @@ export abstract class BasePlugin {
/** 应用实例用到此项无法本地调试需安装到cool-admin中才能调试 */ /** 应用实例用到此项无法本地调试需安装到cool-admin中才能调试 */
app: IMidwayApplication; app: IMidwayApplication;
setCtx(ctx: IMidwayContext) {
this.ctx = ctx;
}
setApp(app: IMidwayApplication) {
this.app = app;
}
constructor() {} constructor() {}
/** /**
@ -43,9 +51,13 @@ export abstract class BasePlugin {
* @param ctx * @param ctx
* @param app * @param app
*/ */
async init(pluginInfo: PluginInfo, ctx?: IMidwayContext, app?: IMidwayApplication){ async init(
pluginInfo: PluginInfo,
ctx?: IMidwayContext,
app?: IMidwayApplication
) {
this.pluginInfo = pluginInfo; this.pluginInfo = pluginInfo;
this.ctx = ctx; this.ctx = ctx;
this.app = app; this.app = app;
}; }
} }