fix(plugin): 修复插件配置保存与加载的相关问题

1.  修复插件配置保存时使用fullName或name作为标识的问题
2.  为证书申请插件配置补充pluginType字段
3.  新增插件配置全局加载逻辑,启动时同步数据库插件配置到内存注册表
4.  优化配置编辑器默认值与选项添加交互
5.  补充vue依赖导入与上下文注入
This commit is contained in:
xiaojunnuo
2026-09-05 00:27:26 +08:00
parent 32ade8e4a3
commit bd9433478a
5 changed files with 77 additions and 9 deletions
@@ -113,7 +113,8 @@ const onFinishFailed = (errorInfo: any) => {
const { openConfigDialog } = usePluginConfig();
async function doPluginConfig() {
const certApplyInfo = await getPluginSetting("CertApply");
const certApplyInfo: any = await getPluginSetting("CertApply");
certApplyInfo.pluginType = "plugin";
await openConfigDialog({
row: certApplyInfo,
onSuccess: async () => {
@@ -45,7 +45,7 @@
<script setup lang="tsx">
import { dict, FsRender } from "@fast-crud/fast-crud";
import { cloneDeep, merge, unset } from "lodash-es";
import { computed, onMounted, reactive, ref } from "vue";
import { computed, onMounted, provide, reactive, ref } from "vue";
import { useRoute, useRouter } from "vue-router";
import Rollbackable from "./rollbackable.vue";
import { fillPluginDefine, usePluginStore } from "/@/store/plugin";
@@ -68,7 +68,7 @@ const labelCol = ref({
},
});
const wrapperCol = ref({ span: 16 });
const configForm: any = reactive({});
const configForm: any = reactive({ type: props.plugin.fullName || props.plugin.name });
const showDict = dict({
data: [
@@ -185,9 +185,11 @@ const optionsMappingKey = {
},
editRender(item: any) {
return () => {
const options = item.component?.options || [];
if (options.length === 0) {
return <span class="text-gray-400">该组件没有预设选项</span>;
const options = reactive(cloneDeep(item.component?.options || []));
const showAdd = options.length === 0;
function addOption(opt: any) {
options.push(opt);
}
const onLabelChange = (optValue: string, newLabel: string) => {
@@ -233,6 +235,13 @@ const optionsMappingKey = {
))}
</tbody>
</table>
{showAdd && (
<div class="mt-2">
<a-button type="primary" size={() => addOption({ value: "", label: "" })}>
添加选项
</a-button>
</div>
)}
<div class="helper mt-1">只需填写需要自定义的选项,留空则使用原始显示内容</div>
</div>
);
@@ -289,6 +298,17 @@ onMounted(async () => {
defineExpose({
getForm,
});
provide("getCurrentPluginDefine", () => {
return { value: props.plugin };
});
provide("get:scope", () => {
return getScope();
});
provide("get:plugin:type", () => {
debugger;
return props.plugin.pluginType;
});
</script>
<style lang="less">
@@ -49,7 +49,7 @@ export function usePluginConfig() {
}
}
const res = await api.savePluginSetting({
name: row.fullName,
name: row.fullName || row.name,
sysSetting: {
metadata: {
input: newForm,
@@ -6,6 +6,7 @@ import { getRuntimeDepsService, initRuntimeDepsService } from "@certd/pipeline";
import { pluginRegistry, accessRegistry, notificationRegistry } from "@certd/pipeline";
import { dnsProviderRegistry } from "@certd/plugin-lib";
import { addonRegistry } from "@certd/lib-server";
import { PluginConfigService } from "../plugin/service/plugin-config-service.js";
@Provide()
@Scope(ScopeEnum.Request, { allowDowngrade: true })
@@ -13,6 +14,9 @@ export class AutoLoadPlugins {
@Inject()
pluginService: PluginService;
@Inject()
pluginConfigService: PluginConfigService;
@Config("runtimeDeps")
runtimeDepsConfig: any;
@@ -34,8 +38,8 @@ export class AutoLoadPlugins {
}
// await import("../../plugins/index.js")
await this.pluginService.registerFromDb();
await registerPaymentProviders();
await this.pluginConfigService.loadAllPluginSetting();
registerPaymentProviders();
logger.info(`加载插件完成,加载模式:${process.env.certd_plugin_loadmode}`);
//初始化第三方依赖服务
@@ -1,5 +1,8 @@
import { Inject, Provide, Scope, ScopeEnum } from "@midwayjs/core";
import { PluginService } from "./plugin-service.js";
import { accessRegistry, notificationRegistry, pluginRegistry } from "@certd/pipeline";
import { dnsProviderRegistry } from "@certd/plugin-lib";
import { addonRegistry } from "@certd/lib-server";
export type PluginConfig = {
name: string;
@@ -66,15 +69,55 @@ export class PluginConfigService {
};
const { id } = await this.pluginService.add(pluginEntity);
pluginEntity.id = id;
this.loadPluginSetting(name, sysSetting);
} else {
const setting = JSON.parse(pluginEntity.sysSetting || "{}");
if (sysSetting.metadata) {
setting.metadata = sysSetting.metadata;
}
if (sysSetting.input) {
//如果没有新提交,不覆盖旧的input
setting.input = sysSetting.input;
}
await this.pluginService.getRepository().update({ fullName: name }, { sysSetting: JSON.stringify(setting) });
this.loadPluginSetting(name, setting);
}
}
async loadPluginSetting(name: string, sysSetting: any) {
let pluginDefine = null;
if (!pluginDefine){
pluginDefine = accessRegistry.getDefine(name);
}
if (!pluginDefine){
pluginDefine = pluginRegistry.getDefine(name);
}
if (!pluginDefine){
pluginDefine = dnsProviderRegistry.getDefine(name);
}
if (!pluginDefine){
pluginDefine = addonRegistry.getDefine(name);
}
if (!pluginDefine){
pluginDefine = notificationRegistry.getDefine(name);
}
if (!pluginDefine){
return
}
pluginDefine.sysSetting = sysSetting;
}
async loadAllPluginSetting() {
const pluginSettings = await this.pluginService.getRepository().find({
select:{
fullName: true,
type: true,
sysSetting: true,
}
});
for (const plugin of pluginSettings) {
this.loadPluginSetting(plugin.fullName, JSON.parse(plugin.sysSetting || "{}"));
}
}