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 { CoolEvent, Event } from '@cool-midway/core';
|
||||||
import { Inject } from '@midwayjs/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_INIT = 'globalPluginInit';
|
||||||
|
// 插件移除全局事件
|
||||||
|
export const GLOBAL_EVENT_PLUGIN_REMOVE = 'globalPluginRemove';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 接收事件
|
* 接收事件
|
||||||
@ -11,10 +13,24 @@ export const GLOBAL_EVENT_PLUGIN_INIT = 'globalPluginInit';
|
|||||||
@CoolEvent()
|
@CoolEvent()
|
||||||
export class PluginInitEvent {
|
export class PluginInitEvent {
|
||||||
@Inject()
|
@Inject()
|
||||||
pluginService: PluginService;
|
pluginCenterService: PluginCenterService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 插件初始化事件,某个插件重新初始化
|
||||||
|
* @param key
|
||||||
|
*/
|
||||||
@Event(GLOBAL_EVENT_PLUGIN_INIT)
|
@Event(GLOBAL_EVENT_PLUGIN_INIT)
|
||||||
async globalPluginInit() {
|
async globalPluginInit(key: string) {
|
||||||
await this.pluginService.reInit();
|
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;
|
key?: string;
|
||||||
/** 钩子 */
|
/** 钩子 */
|
||||||
hook?: string;
|
hook?: string;
|
||||||
|
/** 是否单例 */
|
||||||
|
singleton?: boolean;
|
||||||
/** 版本 */
|
/** 版本 */
|
||||||
version?: string;
|
version?: string;
|
||||||
/** 描述 */
|
/** 描述 */
|
||||||
|
@ -2,7 +2,6 @@ import { Provide } from '@midwayjs/decorator';
|
|||||||
import {
|
import {
|
||||||
App,
|
App,
|
||||||
IMidwayApplication,
|
IMidwayApplication,
|
||||||
Init,
|
|
||||||
Inject,
|
Inject,
|
||||||
InjectClient,
|
InjectClient,
|
||||||
Scope,
|
Scope,
|
||||||
@ -17,6 +16,7 @@ import { PluginInfo } from '../interface';
|
|||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import { CachingFactory, MidwayCache } from '@midwayjs/cache-manager';
|
import { CachingFactory, MidwayCache } from '@midwayjs/cache-manager';
|
||||||
import { CoolEventManager } from '@cool-midway/core';
|
import { CoolEventManager } from '@cool-midway/core';
|
||||||
|
import { PluginService } from './info';
|
||||||
|
|
||||||
export const PLUGIN_CACHE_KEY = 'plugin:init';
|
export const PLUGIN_CACHE_KEY = 'plugin:init';
|
||||||
|
|
||||||
@ -46,28 +46,62 @@ export class PluginCenterService {
|
|||||||
@Inject()
|
@Inject()
|
||||||
coolEventManager: CoolEventManager;
|
coolEventManager: CoolEventManager;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
pluginService: PluginService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化
|
* 初始化
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async init() {
|
async init() {
|
||||||
const inits: any[] = (await this.midwayCache.get(PLUGIN_CACHE_KEY)) || [];
|
|
||||||
const pid = process.pid;
|
|
||||||
if (inits.includes(pid)) return;
|
|
||||||
this.plugins.clear();
|
this.plugins.clear();
|
||||||
await this.initHooks();
|
await this.initHooks();
|
||||||
await this.initPlugin();
|
await this.initPlugin();
|
||||||
await this.midwayCache.set(PLUGIN_CACHE_KEY, inits.concat([process.pid]));
|
|
||||||
this.coolEventManager.emit(EVENT_PLUGIN_READY);
|
this.coolEventManager.emit(EVENT_PLUGIN_READY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注册插件
|
* 初始化一个
|
||||||
* @param key
|
* @param keyName key名
|
||||||
* @param cls
|
|
||||||
*/
|
*/
|
||||||
async register(key: string, cls: any) {
|
async initOne(keyName: string) {
|
||||||
this.plugins.set(key, cls);
|
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) {
|
async initPlugin(condition?: {
|
||||||
const find: any = { status: 1 };
|
hook?: string;
|
||||||
if (hook) {
|
id?: number;
|
||||||
find.hook = hook;
|
keyName?: string;
|
||||||
|
}) {
|
||||||
|
let find: any = { status: 1 };
|
||||||
|
if (condition) {
|
||||||
|
find = {
|
||||||
|
...find,
|
||||||
|
...condition,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
const plugins = await this.pluginInfoEntity.findBy(find);
|
const plugins = await this.pluginInfoEntity.findBy(find);
|
||||||
for (const plugin of plugins) {
|
for (const plugin of plugins) {
|
||||||
const instance = await this.getInstance(plugin.content.data);
|
const instance = await this.getInstance(plugin.content.data);
|
||||||
|
const pluginInfo = {
|
||||||
|
...plugin.pluginJson,
|
||||||
|
config: this.getConfig(plugin.config),
|
||||||
|
};
|
||||||
if (plugin.hook) {
|
if (plugin.hook) {
|
||||||
this.pluginInfos.set(plugin.hook, {
|
this.pluginInfos.set(plugin.hook, pluginInfo);
|
||||||
...plugin.pluginJson,
|
await this.register(plugin.hook, instance, pluginInfo);
|
||||||
config: this.getConfig(plugin.config),
|
|
||||||
});
|
|
||||||
await this.register(plugin.hook, instance);
|
|
||||||
} else {
|
} else {
|
||||||
this.pluginInfos.set(plugin.keyName, {
|
this.pluginInfos.set(plugin.keyName, pluginInfo);
|
||||||
...plugin.pluginJson,
|
await this.register(plugin.keyName, instance, pluginInfo);
|
||||||
config: this.getConfig(plugin.config),
|
|
||||||
});
|
|
||||||
await this.register(plugin.keyName, instance);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import {
|
|||||||
CoolEventManager,
|
CoolEventManager,
|
||||||
} from '@cool-midway/core';
|
} from '@cool-midway/core';
|
||||||
import { InjectEntityModel } from '@midwayjs/typeorm';
|
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||||
import { Equal, Not, Repository } from 'typeorm';
|
import { Equal, In, Not, Repository } from 'typeorm';
|
||||||
import { PluginInfoEntity } from '../entity/info';
|
import { PluginInfoEntity } from '../entity/info';
|
||||||
import {
|
import {
|
||||||
Config,
|
Config,
|
||||||
@ -15,9 +15,12 @@ import {
|
|||||||
} from '@midwayjs/core';
|
} from '@midwayjs/core';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import { PluginInfo } from '../interface';
|
import { PluginInfo } from '../interface';
|
||||||
import { PLUGIN_CACHE_KEY, PluginCenterService } from './center';
|
import { PluginCenterService } from './center';
|
||||||
import { CachingFactory, MidwayCache } from '@midwayjs/cache-manager';
|
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;
|
coolEventManager: CoolEventManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化
|
* 新增或更新
|
||||||
* @param data
|
* @param param
|
||||||
* @param type
|
* @param type
|
||||||
*/
|
*/
|
||||||
async modifyAfter() {
|
async addOrUpdate(param: any, type?: 'add' | 'update') {
|
||||||
// 多进程发送全局事件,pm2下生效
|
await super.addOrUpdate(param, type);
|
||||||
this.coolEventManager.globalEmit(GLOBAL_EVENT_PLUGIN_INIT, false);
|
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() {
|
async reInit(keyName: string) {
|
||||||
await this.midwayCache.set(PLUGIN_CACHE_KEY, []);
|
// 多进程发送全局事件,pm2下生效,本地开发则通过普通事件
|
||||||
await this.pluginCenterService.init();
|
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
|
* @param ids
|
||||||
*/
|
*/
|
||||||
async delete(ids: any) {
|
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.pluginInfoEntity.delete(ids);
|
||||||
await this.reInit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -115,18 +141,19 @@ export class PluginService extends BaseService {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async getInstance(key: string) {
|
async getInstance(key: string) {
|
||||||
await this.checkStatus(key);
|
const check = await this.checkStatus(key);
|
||||||
await this.pluginCenterService.init();
|
if (!check) throw new CoolCommException(`插件[${key}]不存在或已禁用`);
|
||||||
const instance = new (await this.pluginCenterService.plugins.get(key))();
|
let instance;
|
||||||
await instance.init(
|
const pluginInfo = this.pluginCenterService.pluginInfos.get(key);
|
||||||
this.pluginCenterService.pluginInfos.get(key),
|
if (pluginInfo.singleton) {
|
||||||
this.ctx,
|
instance = this.pluginCenterService.plugins.get(key);
|
||||||
this.app,
|
} else {
|
||||||
{
|
instance = new (await this.pluginCenterService.plugins.get(key))();
|
||||||
cache: this.midwayCache,
|
}
|
||||||
pluginService: this,
|
await instance.init(pluginInfo, this.ctx, this.app, {
|
||||||
}
|
cache: this.midwayCache,
|
||||||
);
|
pluginService: this,
|
||||||
|
});
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,15 +163,14 @@ export class PluginService extends BaseService {
|
|||||||
*/
|
*/
|
||||||
async checkStatus(key: string) {
|
async checkStatus(key: string) {
|
||||||
if (Object.keys(this.hooksConfig).includes(key)) {
|
if (Object.keys(this.hooksConfig).includes(key)) {
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
const info = await this.pluginInfoEntity
|
const info = await this.pluginInfoEntity
|
||||||
.createQueryBuilder('a')
|
.createQueryBuilder('a')
|
||||||
.where({ status: 1, keyName: Equal(key) })
|
.where({ status: 1, keyName: Equal(key) })
|
||||||
.getOne();
|
.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.pluginInfoEntity.insert(data);
|
||||||
}
|
}
|
||||||
// 初始化插件
|
// 初始化插件
|
||||||
await this.reInit();
|
await this.reInit(pluginJson.key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user