mirror of
https://github.com/cool-team-official/cool-admin-midway.git
synced 2024-11-01 22:20:30 +08:00
支持单例插件,完善插件初始化方式
This commit is contained in:
parent
64c00cbf16
commit
aab2c47898
@ -1,9 +1,11 @@
|
||||
import { CoolEvent, Event } from '@cool-midway/core';
|
||||
import { Inject } from '@midwayjs/core';
|
||||
import { PluginService } from '../service/info';
|
||||
import { PluginCenterService } from '../service/center';
|
||||
|
||||
// 插件初始化全局事件
|
||||
export const GLOBAL_EVENT_PLUGIN_INIT = 'globalPluginInit';
|
||||
// 插件移除全局事件
|
||||
export const GLOBAL_EVENT_PLUGIN_REMOVE = 'globalPluginRemove';
|
||||
|
||||
/**
|
||||
* 接收事件
|
||||
@ -11,10 +13,24 @@ export const GLOBAL_EVENT_PLUGIN_INIT = 'globalPluginInit';
|
||||
@CoolEvent()
|
||||
export class PluginInitEvent {
|
||||
@Inject()
|
||||
pluginService: PluginService;
|
||||
pluginCenterService: PluginCenterService;
|
||||
|
||||
/**
|
||||
* 插件初始化事件,某个插件重新初始化
|
||||
* @param key
|
||||
*/
|
||||
@Event(GLOBAL_EVENT_PLUGIN_INIT)
|
||||
async globalPluginInit() {
|
||||
await this.pluginService.reInit();
|
||||
async globalPluginInit(key: string) {
|
||||
await this.pluginCenterService.initOne(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件移除或者关闭事件
|
||||
* @param key
|
||||
* @param isHook
|
||||
*/
|
||||
@Event(GLOBAL_EVENT_PLUGIN_REMOVE)
|
||||
async globalPluginRemove(key: string, isHook: boolean) {
|
||||
await this.pluginCenterService.remove(key, isHook);
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,8 @@ export interface PluginInfo {
|
||||
key?: string;
|
||||
/** 钩子 */
|
||||
hook?: string;
|
||||
/** 是否单例 */
|
||||
singleton?: boolean;
|
||||
/** 版本 */
|
||||
version?: string;
|
||||
/** 描述 */
|
||||
|
@ -2,7 +2,6 @@ import { Provide } from '@midwayjs/decorator';
|
||||
import {
|
||||
App,
|
||||
IMidwayApplication,
|
||||
Init,
|
||||
Inject,
|
||||
InjectClient,
|
||||
Scope,
|
||||
@ -17,6 +16,7 @@ import { PluginInfo } from '../interface';
|
||||
import * as _ from 'lodash';
|
||||
import { CachingFactory, MidwayCache } from '@midwayjs/cache-manager';
|
||||
import { CoolEventManager } from '@cool-midway/core';
|
||||
import { PluginService } from './info';
|
||||
|
||||
export const PLUGIN_CACHE_KEY = 'plugin:init';
|
||||
|
||||
@ -46,28 +46,62 @@ export class PluginCenterService {
|
||||
@Inject()
|
||||
coolEventManager: CoolEventManager;
|
||||
|
||||
@Inject()
|
||||
pluginService: PluginService;
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
* @returns
|
||||
*/
|
||||
async init() {
|
||||
const inits: any[] = (await this.midwayCache.get(PLUGIN_CACHE_KEY)) || [];
|
||||
const pid = process.pid;
|
||||
if (inits.includes(pid)) return;
|
||||
this.plugins.clear();
|
||||
await this.initHooks();
|
||||
await this.initPlugin();
|
||||
await this.midwayCache.set(PLUGIN_CACHE_KEY, inits.concat([process.pid]));
|
||||
this.coolEventManager.emit(EVENT_PLUGIN_READY);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册插件
|
||||
* @param key
|
||||
* @param cls
|
||||
* 初始化一个
|
||||
* @param keyName key名
|
||||
*/
|
||||
async register(key: string, cls: any) {
|
||||
this.plugins.set(key, cls);
|
||||
async initOne(keyName: string) {
|
||||
await this.initPlugin({
|
||||
keyName,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除插件
|
||||
* @param keyName
|
||||
* @param isHook
|
||||
*/
|
||||
async remove(keyName: string, isHook = false) {
|
||||
this.plugins.delete(keyName);
|
||||
this.pluginInfos.delete(keyName);
|
||||
if (isHook) {
|
||||
await this.initHooks();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册插件
|
||||
* @param key 唯一标识
|
||||
* @param cls 类
|
||||
* @param pluginInfo 插件信息
|
||||
*/
|
||||
async register(key: string, cls: any, pluginInfo?: PluginInfo) {
|
||||
// 单例插件
|
||||
if (pluginInfo?.singleton) {
|
||||
const instance = new cls();
|
||||
await instance.init(this.pluginInfos.get(key), null, this.app, {
|
||||
cache: this.midwayCache,
|
||||
pluginService: this.pluginService,
|
||||
});
|
||||
this.plugins.set(key, instance);
|
||||
} else {
|
||||
// 普通插件
|
||||
this.plugins.set(key, cls);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -96,27 +130,33 @@ export class PluginCenterService {
|
||||
|
||||
/**
|
||||
* 初始化插件
|
||||
* @param condition 插件条件
|
||||
*/
|
||||
async initPlugin(hook?: string) {
|
||||
const find: any = { status: 1 };
|
||||
if (hook) {
|
||||
find.hook = hook;
|
||||
async initPlugin(condition?: {
|
||||
hook?: string;
|
||||
id?: number;
|
||||
keyName?: string;
|
||||
}) {
|
||||
let find: any = { status: 1 };
|
||||
if (condition) {
|
||||
find = {
|
||||
...find,
|
||||
...condition,
|
||||
};
|
||||
}
|
||||
const plugins = await this.pluginInfoEntity.findBy(find);
|
||||
for (const plugin of plugins) {
|
||||
const instance = await this.getInstance(plugin.content.data);
|
||||
const pluginInfo = {
|
||||
...plugin.pluginJson,
|
||||
config: this.getConfig(plugin.config),
|
||||
};
|
||||
if (plugin.hook) {
|
||||
this.pluginInfos.set(plugin.hook, {
|
||||
...plugin.pluginJson,
|
||||
config: this.getConfig(plugin.config),
|
||||
});
|
||||
await this.register(plugin.hook, instance);
|
||||
this.pluginInfos.set(plugin.hook, pluginInfo);
|
||||
await this.register(plugin.hook, instance, pluginInfo);
|
||||
} else {
|
||||
this.pluginInfos.set(plugin.keyName, {
|
||||
...plugin.pluginJson,
|
||||
config: this.getConfig(plugin.config),
|
||||
});
|
||||
await this.register(plugin.keyName, instance);
|
||||
this.pluginInfos.set(plugin.keyName, pluginInfo);
|
||||
await this.register(plugin.keyName, instance, pluginInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import {
|
||||
CoolEventManager,
|
||||
} from '@cool-midway/core';
|
||||
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||
import { Equal, Not, Repository } from 'typeorm';
|
||||
import { Equal, In, Not, Repository } from 'typeorm';
|
||||
import { PluginInfoEntity } from '../entity/info';
|
||||
import {
|
||||
Config,
|
||||
@ -15,9 +15,12 @@ import {
|
||||
} from '@midwayjs/core';
|
||||
import * as _ from 'lodash';
|
||||
import { PluginInfo } from '../interface';
|
||||
import { PLUGIN_CACHE_KEY, PluginCenterService } from './center';
|
||||
import { PluginCenterService } from './center';
|
||||
import { CachingFactory, MidwayCache } from '@midwayjs/cache-manager';
|
||||
import { GLOBAL_EVENT_PLUGIN_INIT } from '../event/init';
|
||||
import {
|
||||
GLOBAL_EVENT_PLUGIN_INIT,
|
||||
GLOBAL_EVENT_PLUGIN_REMOVE,
|
||||
} from '../event/init';
|
||||
|
||||
/**
|
||||
* 插件信息
|
||||
@ -46,21 +49,41 @@ export class PluginService extends BaseService {
|
||||
coolEventManager: CoolEventManager;
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
* @param data
|
||||
* 新增或更新
|
||||
* @param param
|
||||
* @param type
|
||||
*/
|
||||
async modifyAfter() {
|
||||
// 多进程发送全局事件,pm2下生效
|
||||
this.coolEventManager.globalEmit(GLOBAL_EVENT_PLUGIN_INIT, false);
|
||||
async addOrUpdate(param: any, type?: 'add' | 'update') {
|
||||
await super.addOrUpdate(param, type);
|
||||
const info = await this.pluginInfoEntity.findOneBy({ id: param.id });
|
||||
if (info.status == 1) {
|
||||
await this.reInit(info.keyName);
|
||||
} else {
|
||||
await this.remove(info.keyName, !!info.hook);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 需要重新初始化插件
|
||||
* 重新初始化插件
|
||||
*/
|
||||
async reInit() {
|
||||
await this.midwayCache.set(PLUGIN_CACHE_KEY, []);
|
||||
await this.pluginCenterService.init();
|
||||
async reInit(keyName: string) {
|
||||
// 多进程发送全局事件,pm2下生效,本地开发则通过普通事件
|
||||
this.coolEventManager.globalEmit(GLOBAL_EVENT_PLUGIN_INIT, false, keyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除插件
|
||||
* @param keyName
|
||||
* @param isHook
|
||||
*/
|
||||
async remove(keyName: string, isHook = false) {
|
||||
// 多进程发送全局事件,pm2下生效
|
||||
this.coolEventManager.globalEmit(
|
||||
GLOBAL_EVENT_PLUGIN_REMOVE,
|
||||
false,
|
||||
keyName,
|
||||
isHook
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -68,8 +91,11 @@ export class PluginService extends BaseService {
|
||||
* @param ids
|
||||
*/
|
||||
async delete(ids: any) {
|
||||
const list = await this.pluginInfoEntity.findBy({ id: In(ids) });
|
||||
for (const item of list) {
|
||||
await this.remove(item.keyName, !!item.hook);
|
||||
}
|
||||
await this.pluginInfoEntity.delete(ids);
|
||||
await this.reInit();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -115,18 +141,19 @@ export class PluginService extends BaseService {
|
||||
* @returns
|
||||
*/
|
||||
async getInstance(key: string) {
|
||||
await this.checkStatus(key);
|
||||
await this.pluginCenterService.init();
|
||||
const instance = new (await this.pluginCenterService.plugins.get(key))();
|
||||
await instance.init(
|
||||
this.pluginCenterService.pluginInfos.get(key),
|
||||
this.ctx,
|
||||
this.app,
|
||||
{
|
||||
cache: this.midwayCache,
|
||||
pluginService: this,
|
||||
}
|
||||
);
|
||||
const check = await this.checkStatus(key);
|
||||
if (!check) throw new CoolCommException(`插件[${key}]不存在或已禁用`);
|
||||
let instance;
|
||||
const pluginInfo = this.pluginCenterService.pluginInfos.get(key);
|
||||
if (pluginInfo.singleton) {
|
||||
instance = this.pluginCenterService.plugins.get(key);
|
||||
} else {
|
||||
instance = new (await this.pluginCenterService.plugins.get(key))();
|
||||
}
|
||||
await instance.init(pluginInfo, this.ctx, this.app, {
|
||||
cache: this.midwayCache,
|
||||
pluginService: this,
|
||||
});
|
||||
return instance;
|
||||
}
|
||||
|
||||
@ -136,15 +163,14 @@ export class PluginService extends BaseService {
|
||||
*/
|
||||
async checkStatus(key: string) {
|
||||
if (Object.keys(this.hooksConfig).includes(key)) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
const info = await this.pluginInfoEntity
|
||||
.createQueryBuilder('a')
|
||||
.where({ status: 1, keyName: Equal(key) })
|
||||
.getOne();
|
||||
if (!info) {
|
||||
throw new CoolCommException(`插件[${key}]不存在或已禁用`);
|
||||
}
|
||||
|
||||
return !!info;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -277,6 +303,6 @@ export class PluginService extends BaseService {
|
||||
await this.pluginInfoEntity.insert(data);
|
||||
}
|
||||
// 初始化插件
|
||||
await this.reInit();
|
||||
await this.reInit(pluginJson.key);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user