mirror of
https://github.com/certd/certd.git
synced 2026-05-16 21:27:34 +08:00
perf: 商业版支持自定义插件的参数配置
This commit is contained in:
@@ -138,6 +138,7 @@ export function useCertPipelineCreator() {
|
||||
form: {
|
||||
doSubmit,
|
||||
wrapper: {
|
||||
wrapClassName: "cert_pipeline_create_form",
|
||||
width: 1350,
|
||||
saveRemind: false,
|
||||
title: t("certd.pipelineForm.createTitle"),
|
||||
|
||||
@@ -115,4 +115,13 @@ function batchRerun() {
|
||||
padding-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.cert_pipeline_create_form {
|
||||
.ant-collapse {
|
||||
margin: 10px;
|
||||
}
|
||||
.ant-collapse-header {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
<a-form-item>
|
||||
<a-button type="primary" size="large" html-type="submit" :loading="loading" class="login-button">
|
||||
<a-button type="primary" size="large" html-type="button" :loading="loading" class="login-button" @click="handleFinish">
|
||||
{{ t("authentication.loginButton") }}
|
||||
</a-button>
|
||||
|
||||
@@ -217,7 +217,6 @@ export default defineComponent({
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
|
||||
.login-page.main {
|
||||
//margin: 20px !important;
|
||||
margin-bottom: 100px;
|
||||
|
||||
@@ -7,38 +7,49 @@
|
||||
</div>
|
||||
<div class="p-10">
|
||||
<div ref="formRef" class="config-form w-full" :label-col="labelCol" :wrapper-col="wrapperCol">
|
||||
<template v-for="(item, key) in originInputs" :key="key">
|
||||
<div>
|
||||
<div :label="item.title">
|
||||
<label class="flex mt-5">
|
||||
<span class="w-20 flex-shrink-0">默认值</span>
|
||||
<rollbackable :value="configForm[key].value" @set="configForm[key].value = item.value ?? null" @clear="unset(configForm, `${key}.value`)"></rollbackable>
|
||||
</label>
|
||||
<label class="flex mt-5">
|
||||
<span class="w-20 flex-shrink-0">是否显示</span>
|
||||
<rollbackable :value="configForm[key].show" @set="set(configForm, `${key}.show`, item.show ?? null)" @clear="unset(configForm, `${key}.show`)"></rollbackable>
|
||||
</label>
|
||||
<label class="flex mt-5">
|
||||
<span class="w-20 flex-shrink-0">帮助说明</span>
|
||||
{{ configForm[key].helper }}
|
||||
<rollbackable :value="configForm[key].helper" @setter="configForm[key].helper = item.helper" @clear1="delete configForm[key].helper"></rollbackable>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<table class="table-fixed w-full">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-left p-5" width="200px">插件参数</th>
|
||||
<th class="text-left p-5" width="100px">参数配置</th>
|
||||
<th class="text-left flex-1 p-5">自定义</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<template v-for="(item, key) in originInputs" :key="key">
|
||||
<template v-for="prop in editableKeys" :key="prop.key">
|
||||
<tr>
|
||||
<td v-if="prop.key === 'value'" class="border-t-2 p-5" rowspan="3" :class="{ 'border-t-2': prop.key === 'value' }">{{ item.title }}</td>
|
||||
<td class="border-t p-5" :class="{ 'border-t-2': prop.key === 'value' }">{{ prop.label }}</td>
|
||||
<td class="border-t p-5" :class="{ 'border-t-2': prop.key === 'value' }">
|
||||
<rollbackable :value="configForm[key][prop.key]" @set="configForm[key][prop.key] = item[prop.key] ?? null" @clear="delete configForm[key][prop.key]">
|
||||
<template #default>
|
||||
<fs-render :render-func="prop.defaultRender(key, item)"></fs-render>
|
||||
</template>
|
||||
<template #edit>
|
||||
<fs-render :render-func="prop.editRender(key, item)"></fs-render>
|
||||
</template>
|
||||
</rollbackable>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</template>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
<script setup lang="tsx">
|
||||
import { computed, nextTick, onMounted, reactive, ref, Ref, unref } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import * as api from "./api";
|
||||
import { usePluginStore } from "/@/store/plugin";
|
||||
import { cloneDeep, get, merge, set, unset } from "lodash-es";
|
||||
import Rollbackable from "./rollbackable.vue";
|
||||
import { FsRender } from "@fast-crud/fast-crud";
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const pluginStore = usePluginStore();
|
||||
@@ -48,7 +59,6 @@ const props = defineProps<{
|
||||
|
||||
const pluginMetadata = ref<any>("");
|
||||
const currentPlugin = ref();
|
||||
console.log("111111111111111111111");
|
||||
const labelCol = ref({
|
||||
span: null,
|
||||
style: {
|
||||
@@ -71,9 +81,49 @@ function getForm() {
|
||||
}
|
||||
|
||||
const editableKeys = ref([
|
||||
{ key: "value", label: "默认值" },
|
||||
{ key: "show", label: "是否显示", component: { name: "a-switch", vModel: "checked" } },
|
||||
{ key: "helper", label: "帮助说明", component: { name: "a-textarea", vModel: "value", rows: 4 } },
|
||||
{
|
||||
key: "value",
|
||||
label: "默认值",
|
||||
defaultRender(key: string, item: any) {
|
||||
return () => {
|
||||
return item["value"] ?? "";
|
||||
};
|
||||
},
|
||||
editRender(key: string, item: any) {
|
||||
return () => {
|
||||
return <fs-component-render {...item.component} vModel:modelValue={configForm[key]["value"]} scope={getScope()} />;
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "show",
|
||||
label: "是否显示",
|
||||
defaultRender(key: string, item: any) {
|
||||
return () => {
|
||||
const value = item["show"];
|
||||
return value === false ? "不显示" : "显示";
|
||||
};
|
||||
},
|
||||
editRender(key: string, item: any) {
|
||||
return () => {
|
||||
return <a-switch vModel:checked={configForm[key]["show"]} />;
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "helper",
|
||||
label: "帮助说明",
|
||||
defaultRender(key: string, item: any) {
|
||||
return () => {
|
||||
return <pre class={"helper"}>{item["helper"]}</pre>;
|
||||
};
|
||||
},
|
||||
editRender(key: string, item: any) {
|
||||
return () => {
|
||||
return <a-textarea rows={5} vModel:value={configForm[key]["helper"]} />;
|
||||
};
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
const originInputs = computed(() => {
|
||||
@@ -98,7 +148,7 @@ function clearFormValue(key: string) {
|
||||
}
|
||||
|
||||
async function loadPluginSetting() {
|
||||
currentPlugin.value = await pluginStore.getPluginDefine(props.plugin.name);
|
||||
currentPlugin.value = await pluginStore.getPluginDefineFromOrigin(props.plugin.name);
|
||||
for (const key in currentPlugin.value.input) {
|
||||
configForm[key] = {};
|
||||
}
|
||||
@@ -113,7 +163,9 @@ onMounted(async () => {
|
||||
await loadPluginSetting();
|
||||
});
|
||||
|
||||
function doSave() {}
|
||||
defineExpose({
|
||||
getForm,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
|
||||
@@ -1,32 +1,45 @@
|
||||
<script setup lang="ts">
|
||||
import { cloneDeep, get, merge, set, unset } from "lodash-es";
|
||||
import { defineProps } from "vue";
|
||||
|
||||
const props = defineProps<{ value: any }>();
|
||||
|
||||
const emits = defineEmits(["setter", "clear1"]);
|
||||
const emits = defineEmits(["set", "clear"]);
|
||||
function setValue() {
|
||||
console.log("33333");
|
||||
emits("setter");
|
||||
emits("set");
|
||||
}
|
||||
function clearValue() {
|
||||
console.log("4444");
|
||||
emits("clear1");
|
||||
emits("clear");
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="rollbackable">
|
||||
<div class="flex">
|
||||
<div>
|
||||
<div style="width: 100px">
|
||||
<a-tag v-if="value === undefined" color="green" size="small" class="pointer flex-inline items-center" @click.stop="setValue">
|
||||
<fs-icon icon="material-symbols:edit" class="mr-5"></fs-icon>
|
||||
自定义
|
||||
</a-tag>
|
||||
<a-tag v-else color="red" size="small" class="pointer flex-inline items-center" @click.stop="clearValue">
|
||||
<fs-icon icon="material-symbols:undo" class="mr-5"></fs-icon>
|
||||
还原
|
||||
</a-tag>
|
||||
</div>
|
||||
<div class="flex-1 overflow-hidden value-render">
|
||||
<slot v-if="value === undefined" name="default"></slot>
|
||||
<slot v-else name="edit"></slot>
|
||||
</div>
|
||||
<div>
|
||||
<div v-if="value === undefined" type="primary" size="small" @click.stop="setValue">自定义</div>
|
||||
<div v-else style="margin-left: 100px" type="primary" size="small" @click.stop="clearValue">还原</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less"></style>
|
||||
<style lang="less">
|
||||
.rollbackable {
|
||||
.value-render {
|
||||
.ant-select,
|
||||
.ant-input {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -4,54 +4,67 @@ import { useI18n } from "/@/locales";
|
||||
import { Modal, notification } from "ant-design-vue";
|
||||
import ConfigEditor from "./config-editor.vue";
|
||||
import { useModal } from "/@/use/use-modal";
|
||||
import { ref } from "vue";
|
||||
export function usePluginConfig() {
|
||||
const { openCrudFormDialog } = useFormWrapper();
|
||||
const { t } = useI18n();
|
||||
|
||||
const modal = useModal();
|
||||
async function openConfigDialog({ row, crudExpose }) {
|
||||
// function createCrudOptions() {
|
||||
// return {
|
||||
// crudOptions: {
|
||||
// columns: {},
|
||||
// form: {
|
||||
// wrapper: {
|
||||
// width: "80%",
|
||||
// title: "插件元数据配置",
|
||||
// saveRemind: false,
|
||||
// slots: {
|
||||
// "form-body-top": () => {
|
||||
// return (
|
||||
// <div>
|
||||
// <ConfigEditor plugin={row}></ConfigEditor>
|
||||
// </div>
|
||||
// );
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// afterSubmit() {
|
||||
// notification.success({ message: t("certd.operationSuccess") });
|
||||
// crudExpose.doRefresh();
|
||||
// },
|
||||
// async doSubmit({ form }: any) {
|
||||
// return await api.ImportPlugin({
|
||||
// ...form,
|
||||
// });
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// };
|
||||
// }
|
||||
// const { crudOptions } = createCrudOptions();
|
||||
// await openCrudFormDialog({ crudOptions });
|
||||
const configEditorRef = ref();
|
||||
function createCrudOptions() {
|
||||
return {
|
||||
crudOptions: {
|
||||
columns: {},
|
||||
form: {
|
||||
wrapper: {
|
||||
width: "80%",
|
||||
title: "插件元数据配置",
|
||||
saveRemind: false,
|
||||
slots: {
|
||||
"form-body-top": () => {
|
||||
return (
|
||||
<div>
|
||||
<ConfigEditor ref={configEditorRef} plugin={row}></ConfigEditor>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
},
|
||||
afterSubmit() {
|
||||
notification.success({ message: t("certd.operationSuccess") });
|
||||
crudExpose.doRefresh();
|
||||
},
|
||||
async doSubmit({}: any) {
|
||||
const form = configEditorRef.value.getForm();
|
||||
const newForm: any = {};
|
||||
for (const key in form) {
|
||||
const value = form[key];
|
||||
if (value && Object.keys(value).length > 0) {
|
||||
newForm[key] = value;
|
||||
}
|
||||
}
|
||||
return await api.savePluginSetting({
|
||||
name: row.name,
|
||||
sysSetting: {
|
||||
metadata: newForm,
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
const { crudOptions } = createCrudOptions();
|
||||
await openCrudFormDialog({ crudOptions });
|
||||
|
||||
modal.confirm({
|
||||
title: "插件元数据配置",
|
||||
width: "80%",
|
||||
content: () => {
|
||||
return <ConfigEditor plugin={row}></ConfigEditor>;
|
||||
},
|
||||
});
|
||||
// modal.confirm({
|
||||
// title: "插件元数据配置",
|
||||
// width: "80%",
|
||||
// content: () => {
|
||||
// return <ConfigEditor plugin={row}></ConfigEditor>;
|
||||
// },
|
||||
// });
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user