mirror of https://github.com/certd/certd
perf: 任务配置不需要的字段可以自动隐藏
parent
d0d3c2b588
commit
192d9dc7e3
|
@ -15,6 +15,7 @@ export abstract class CertApplyBasePlugin extends AbstractTaskPlugin {
|
|||
vModel: "value",
|
||||
mode: "tags",
|
||||
open: false,
|
||||
tokenSeparators: [",", " ", ",", "、", "|"],
|
||||
},
|
||||
required: true,
|
||||
col: {
|
||||
|
@ -25,7 +26,7 @@ export abstract class CertApplyBasePlugin extends AbstractTaskPlugin {
|
|||
"1、支持通配符域名,例如: *.foo.com、foo.com、*.test.handsfree.work\n" +
|
||||
"2、支持多个域名、多个子域名、多个通配符域名打到一个证书上(域名必须是在同一个DNS提供商解析)\n" +
|
||||
"3、多级子域名要分成多个域名输入(*.foo.com的证书不能用于xxx.yyy.foo.com、foo.com)\n" +
|
||||
"4、输入一个回车之后,再输入下一个",
|
||||
"4、输入一个空格之后,再输入下一个",
|
||||
})
|
||||
domains!: string[];
|
||||
|
||||
|
@ -77,13 +78,6 @@ export abstract class CertApplyBasePlugin extends AbstractTaskPlugin {
|
|||
})
|
||||
successNotify = true;
|
||||
|
||||
@TaskInput({
|
||||
title: "配置说明",
|
||||
order: 9999,
|
||||
helper: "运行策略请选择总是运行,其他证书部署任务请选择成功后跳过;当证书快到期前将会自动重新申请证书,然后会清空后续任务的成功状态,部署任务将会重新运行",
|
||||
})
|
||||
intro!: string;
|
||||
|
||||
// @TaskInput({
|
||||
// title: "CsrInfo",
|
||||
// helper: "暂时没有用",
|
||||
|
|
|
@ -37,11 +37,31 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
|||
{ value: "zerossl", label: "ZeroSSL" },
|
||||
],
|
||||
},
|
||||
helper: "如果letsencrypt.org或dv.acme-v02.api.pki.goog无法访问,请尝试开启代理选项\n如果使用ZeroSSL、google证书,需要提供EAB授权",
|
||||
helper: "Let's Encrypt最简单,如果使用ZeroSSL、google证书,需要提供EAB授权",
|
||||
required: true,
|
||||
})
|
||||
sslProvider!: SSLProvider;
|
||||
|
||||
@TaskInput({
|
||||
title: "EAB授权",
|
||||
component: {
|
||||
name: "pi-access-selector",
|
||||
type: "eab",
|
||||
},
|
||||
maybeNeed: true,
|
||||
required: true,
|
||||
helper:
|
||||
"需要提供EAB授权\nZeroSSL:请前往[zerossl开发者中心](https://app.zerossl.com/developer),生成 'EAB Credentials' \n Google:请查看[google获取eab帮助文档](https://github.com/certd/certd/blob/v2/doc/google/google.md)",
|
||||
mergeScript: `
|
||||
return {
|
||||
show: ctx.compute(({form})=>{
|
||||
return form.sslProvider === 'zerossl' || form.sslProvider === 'google'
|
||||
})
|
||||
}
|
||||
`,
|
||||
})
|
||||
eabAccessId!: number;
|
||||
|
||||
@TaskInput({
|
||||
title: "加密算法",
|
||||
value: "rsa_2048",
|
||||
|
@ -62,18 +82,6 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
|||
})
|
||||
privateKeyType!: PrivateKeyType;
|
||||
|
||||
@TaskInput({
|
||||
title: "EAB授权",
|
||||
component: {
|
||||
name: "pi-access-selector",
|
||||
type: "eab",
|
||||
},
|
||||
maybeNeed: true,
|
||||
helper:
|
||||
"如果使用ZeroSSL或者google证书,需要提供EAB授权\nZeroSSL:请前往 https://app.zerossl.com/developer 生成 'EAB Credentials' \n Google:请前往https://github.com/certd/certd/blob/v2/doc/google/google.md",
|
||||
})
|
||||
eabAccessId!: number;
|
||||
|
||||
@TaskInput({
|
||||
title: "DNS提供商",
|
||||
component: {
|
||||
|
@ -81,7 +89,7 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
|||
},
|
||||
required: true,
|
||||
helper:
|
||||
"请选择dns解析提供商,您的域名是在哪里注册的,或者域名的dns解析服务器属于哪个平台\n如果这里没有您的dns解析提供商,您可以将域名解析服务器设置成上面的任意一个提供商",
|
||||
"请选择dns解析提供商,您的域名是在哪里注册的,或者域名的dns解析服务器属于哪个平台\n如果这里没有您需要的dns解析提供商,您需要将域名解析服务器设置成上面的任意一个提供商",
|
||||
})
|
||||
dnsProviderType!: string;
|
||||
|
||||
|
@ -92,13 +100,14 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
|||
},
|
||||
required: true,
|
||||
helper: "请选择dns解析提供商授权",
|
||||
reference: [
|
||||
{
|
||||
src: "form.dnsProviderType",
|
||||
dest: "component.type",
|
||||
type: "computed",
|
||||
},
|
||||
],
|
||||
mergeScript: `return {
|
||||
component:{
|
||||
type: ctx.compute(({form})=>{
|
||||
return form.dnsProviderType
|
||||
})
|
||||
}
|
||||
}
|
||||
`,
|
||||
})
|
||||
dnsProviderAccess!: string;
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@ const onError = (error: any) => {
|
|||
}
|
||||
.vcron-select-input {
|
||||
min-height: 22px;
|
||||
background-color: #fff;
|
||||
}
|
||||
.vcron-select-container {
|
||||
display: flex;
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
import _ from "lodash-es";
|
||||
import { compute } from "@fast-crud/fast-crud";
|
||||
|
||||
export function useReference(form: any) {
|
||||
if (!form.reference) {
|
||||
return;
|
||||
}
|
||||
for (const reference of form.reference) {
|
||||
_.set(
|
||||
form,
|
||||
reference.dest,
|
||||
compute<any>((scope) => {
|
||||
return _.get(scope, reference.src);
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
import _ from "lodash-es";
|
||||
import { compute } from "@fast-crud/fast-crud";
|
||||
|
||||
export function useReference(formItem: any) {
|
||||
if (formItem.reference) {
|
||||
for (const reference of formItem.reference) {
|
||||
_.set(
|
||||
formItem,
|
||||
reference.dest,
|
||||
compute<any>((scope) => {
|
||||
return _.get(scope, reference.src);
|
||||
})
|
||||
);
|
||||
}
|
||||
delete formItem.reference;
|
||||
}
|
||||
|
||||
if (formItem.mergeScript) {
|
||||
const ctx = {
|
||||
compute
|
||||
};
|
||||
const script = formItem.mergeScript;
|
||||
const func = new Function("ctx", script);
|
||||
const merged = func(ctx);
|
||||
_.merge(formItem, merged);
|
||||
|
||||
delete formItem.mergeScript;
|
||||
}
|
||||
//helper
|
||||
if (formItem.helper && typeof formItem.helper === "string") {
|
||||
//正则表达式替换 [name](url) 成 <a href="url" >
|
||||
let helper = formItem.helper.replace(/\[(.*)\]\((.*)\)/g, '<a href="$2" target="_blank">$1</a>');
|
||||
helper = helper.replace(/\n/g, "<br/>");
|
||||
formItem.helper = {
|
||||
render: () => {
|
||||
return <div innerHTML={helper}></div>;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
import { ColumnCompositionProps, dict } from "@fast-crud/fast-crud";
|
||||
import { ColumnCompositionProps, dict, compute } from "@fast-crud/fast-crud";
|
||||
// @ts-ignore
|
||||
import * as api from "./api";
|
||||
// @ts-ignore
|
||||
|
@ -32,11 +32,25 @@ export function getCommonColumnDefine(crudExpose: any, typeRef: any) {
|
|||
...value,
|
||||
key
|
||||
};
|
||||
const column = _.merge({ title: key }, defaultPluginConfig, field);
|
||||
let column = _.merge({ title: key }, defaultPluginConfig, field);
|
||||
|
||||
//eval
|
||||
if (column.mergeScript) {
|
||||
const ctx = {
|
||||
compute
|
||||
};
|
||||
const script = column.mergeScript;
|
||||
delete column.mergeScript;
|
||||
const func = new Function("ctx", script);
|
||||
const merged = func(ctx);
|
||||
column = _.merge(column, merged);
|
||||
}
|
||||
|
||||
//设置默认值
|
||||
if (column.value != null && _.get(form, key) == null) {
|
||||
//设置默认值
|
||||
_.set(form, key, column.value);
|
||||
}
|
||||
//字段配置赋值
|
||||
columnsRef.value[key] = column;
|
||||
console.log("form", columnsRef.value);
|
||||
});
|
||||
|
@ -55,7 +69,12 @@ export function getCommonColumnDefine(crudExpose: any, typeRef: any) {
|
|||
},
|
||||
form: {
|
||||
component: {
|
||||
disabled: false
|
||||
disabled: false,
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any) => {
|
||||
input = input?.toLowerCase();
|
||||
return option.value.toLowerCase().indexOf(input) >= 0 || option.label.toLowerCase().indexOf(input) >= 0;
|
||||
}
|
||||
},
|
||||
rules: [{ required: true, message: "请选择类型" }],
|
||||
valueChange: {
|
||||
|
|
|
@ -22,12 +22,17 @@ export default function (certPluginGroup: PluginGroup, formWrapperRef: any): Cre
|
|||
form: {
|
||||
...inputDefine,
|
||||
show: compute((ctx) => {
|
||||
console.log(formWrapperRef);
|
||||
const form = formWrapperRef.value.getFormData();
|
||||
if (!form) {
|
||||
return false;
|
||||
}
|
||||
return form?.certApplyPlugin === plugin.name;
|
||||
|
||||
let inputDefineShow = true;
|
||||
if (inputDefine.show != null) {
|
||||
const computeShow = inputDefine.show as any;
|
||||
inputDefineShow = computeShow.computeFn({ form });
|
||||
}
|
||||
return form?.certApplyPlugin === plugin.name && inputDefineShow;
|
||||
})
|
||||
}
|
||||
};
|
||||
|
@ -60,8 +65,8 @@ export default function (certPluginGroup: PluginGroup, formWrapperRef: any): Cre
|
|||
render: () => {
|
||||
return (
|
||||
<ul>
|
||||
<li>Lego-ACME:基于Lego实现,支持海量DNS提供商</li>
|
||||
<li>JS-ACME:如果你的域名DNS属于阿里云、腾讯云、Cloudflare可以选择用它来申请</li>
|
||||
<li>JS-ACME:如果你的域名DNS属于阿里云、腾讯云、Cloudflare、西部数码可以选择用它来申请</li>
|
||||
<li>Lego-ACME:基于Lego实现,支持海量DNS提供商,熟悉LEGO的用户可以使用</li>
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
|
@ -78,7 +83,7 @@ export default function (certPluginGroup: PluginGroup, formWrapperRef: any): Cre
|
|||
vModel: "modelValue",
|
||||
placeholder: "0 0 4 * * *"
|
||||
},
|
||||
helper: "请输入cron表达式, 例如:0 0 4 * * *,每天凌晨4点触发",
|
||||
helper: "点击上面的按钮,选择每天几点几分定时执行, 例如:0 0 4 * * *,每天凌晨4点0分0秒触发",
|
||||
order: 100
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<a-drawer v-model:open="stepDrawerVisible" placement="right" :closable="true" width="700px" @after-open-change="stepDrawerOnAfterVisibleChange">
|
||||
<a-drawer v-model:open="stepDrawerVisible" placement="right" :closable="true" width="700px">
|
||||
<template #title>
|
||||
编辑步骤
|
||||
<a-button v-if="editMode" @click="stepDelete()">
|
||||
|
@ -59,7 +59,7 @@
|
|||
:get-context-fn="blankFn"
|
||||
/>
|
||||
<template v-for="(item, key) in currentPlugin.input" :key="key">
|
||||
<fs-form-item v-model="currentStep.input[key]" :item="item" :get-context-fn="blankFn" />
|
||||
<fs-form-item v-if="item.show !== false" v-model="currentStep.input[key]" :item="item" :get-context-fn="blankFn" />
|
||||
</template>
|
||||
|
||||
<fs-form-item v-model="currentStep.strategy.runStrategy" :item="runStrategyProps" :get-context-fn="blankFn" />
|
||||
|
@ -83,9 +83,12 @@ import { nanoid } from "nanoid";
|
|||
import { CopyOutlined } from "@ant-design/icons-vue";
|
||||
import { PluginGroups } from "/@/views/certd/pipeline/pipeline/type";
|
||||
import { useUserStore } from "/@/store/modules/user";
|
||||
import { compute, useCompute } from "@fast-crud/fast-crud";
|
||||
import { useReference } from "/@/use/use-refrence";
|
||||
|
||||
export default {
|
||||
name: "PiStepForm",
|
||||
// eslint-disable-next-line vue/no-unused-components
|
||||
components: { CopyOutlined },
|
||||
props: {
|
||||
editMode: {
|
||||
|
@ -106,7 +109,6 @@ export default {
|
|||
const mode: Ref = ref("add");
|
||||
const callback: Ref = ref();
|
||||
const currentStep: Ref = ref({ title: undefined, input: {} });
|
||||
const currentPlugin: Ref = ref({});
|
||||
const stepFormRef: Ref = ref(null);
|
||||
const stepDrawerVisible: Ref = ref(false);
|
||||
const rules: Ref = ref({
|
||||
|
@ -150,15 +152,10 @@ export default {
|
|||
stepDrawerVisible.value = false;
|
||||
};
|
||||
|
||||
const stepDrawerOnAfterVisibleChange = (val: any) => {
|
||||
console.log("stepDrawerOnAfterVisibleChange", val);
|
||||
};
|
||||
|
||||
const stepOpen = (step: any, emit: any) => {
|
||||
callback.value = emit;
|
||||
currentStep.value = _.merge({ input: {}, strategy: {} }, step);
|
||||
|
||||
console.log("currentStepOpen", currentStep.value);
|
||||
if (step.type) {
|
||||
changeCurrentPlugin(currentStep.value);
|
||||
}
|
||||
|
@ -189,33 +186,41 @@ export default {
|
|||
stepOpen(step, emit);
|
||||
};
|
||||
|
||||
const currentPluginDefine = ref();
|
||||
|
||||
function getContext() {
|
||||
return {
|
||||
form: currentStep.value.input
|
||||
};
|
||||
}
|
||||
const { doComputed } = useCompute();
|
||||
const currentPlugin = doComputed(() => {
|
||||
return currentPluginDefine.value;
|
||||
}, getContext);
|
||||
const changeCurrentPlugin = (step: any) => {
|
||||
const stepType = step.type;
|
||||
const pluginDefine = pluginGroups.get(stepType);
|
||||
if (pluginDefine) {
|
||||
step.type = stepType;
|
||||
step._isAdd = false;
|
||||
currentPlugin.value = _.cloneDeep(pluginDefine);
|
||||
for (let key in currentPlugin.value.input) {
|
||||
const input = currentPlugin.value.input[key];
|
||||
if (input?.reference) {
|
||||
for (const reference of input.reference) {
|
||||
_.set(
|
||||
input,
|
||||
reference.dest,
|
||||
computed<any>(() => {
|
||||
const scope = {
|
||||
form: currentStep.value.input
|
||||
};
|
||||
return _.get(scope, reference.src);
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
//设置初始值
|
||||
if ((input.default != null || input.value != null) && currentStep.value.input[key] == null) {
|
||||
currentStep.value.input[key] = input.default ?? input.value;
|
||||
}
|
||||
step.type = stepType;
|
||||
step._isAdd = false;
|
||||
|
||||
let pluginDefine = pluginGroups.get(stepType);
|
||||
if (pluginDefine == null) {
|
||||
console.log("插件未找到", stepType);
|
||||
return;
|
||||
}
|
||||
pluginDefine = _.cloneDeep(pluginDefine);
|
||||
const columns = pluginDefine.input;
|
||||
for (let key in columns) {
|
||||
const column = columns[key];
|
||||
useReference(column);
|
||||
}
|
||||
|
||||
currentPluginDefine.value = pluginDefine;
|
||||
|
||||
for (let key in pluginDefine.input) {
|
||||
const column = pluginDefine.input[key];
|
||||
//设置初始值
|
||||
if ((column.default != null || column.value != null) && currentStep.value.input[key] == null) {
|
||||
currentStep.value.input[key] = column.default ?? column.value;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -269,7 +274,6 @@ export default {
|
|||
stepView,
|
||||
stepDrawerShow,
|
||||
stepDrawerVisible,
|
||||
stepDrawerOnAfterVisibleChange,
|
||||
currentStep,
|
||||
currentPlugin,
|
||||
stepSave,
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
name: 'cron-editor',
|
||||
vModel: 'modelValue'
|
||||
},
|
||||
helper: 'cron表达式,例如: 0 0 3 * * * ,表示每天凌晨3点触发',
|
||||
helper: '点击上面的按钮,选择每天几点几分定时执行, 例如:0 0 4 * * *,每天凌晨4点0分0秒触发',
|
||||
rules: [{ required: true, message: '此项必填' }]
|
||||
}"
|
||||
/>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import type { Pipeline } from "@certd/pipeline";
|
||||
import { FormItemProps } from "@fast-crud/fast-crud";
|
||||
import { DynamicType, FormItemProps } from "@fast-crud/fast-crud";
|
||||
export type PipelineDetail = {
|
||||
pipeline: Pipeline;
|
||||
};
|
||||
|
@ -24,7 +24,7 @@ export type PluginDefine = {
|
|||
title: string;
|
||||
desc?: string;
|
||||
input: {
|
||||
[key: string]: FormItemProps;
|
||||
[key: string]: DynamicType<FormItemProps>;
|
||||
};
|
||||
output: {
|
||||
[key: string]: any;
|
||||
|
|
|
@ -34,6 +34,7 @@ export class DemoAccess implements IAccess {
|
|||
},
|
||||
//是否必填
|
||||
required: true,
|
||||
//改属性是否需要加密
|
||||
encrypt: true,
|
||||
})
|
||||
//属性名称
|
||||
|
|
|
@ -10,16 +10,81 @@ import { IsAccess, AccessInput } from '@certd/pipeline';
|
|||
desc: '',
|
||||
})
|
||||
export class WestAccess {
|
||||
/**
|
||||
* 授权属性配置
|
||||
*/
|
||||
@AccessInput({
|
||||
title: '权限范围',
|
||||
component: {
|
||||
name: 'a-select',
|
||||
vModel: 'value',
|
||||
options: [
|
||||
{ value: 'account', label: '账户级别,对所有域名都有权限管理' },
|
||||
{ value: 'domain', label: '域名级别,仅能管理单个域名' },
|
||||
],
|
||||
},
|
||||
helper: '选择权限范围',
|
||||
required: true,
|
||||
})
|
||||
scope = '';
|
||||
|
||||
/**
|
||||
* 授权属性配置
|
||||
*/
|
||||
@AccessInput({
|
||||
title: '账号',
|
||||
helper: '你的登录账号',
|
||||
encrypt: false,
|
||||
required: false,
|
||||
mergeScript: `
|
||||
return {
|
||||
show:ctx.compute(({form})=>{
|
||||
return form.access.scope === 'account'
|
||||
})
|
||||
}
|
||||
`,
|
||||
})
|
||||
username = '';
|
||||
|
||||
/**
|
||||
* 授权属性配置
|
||||
*/
|
||||
@AccessInput({
|
||||
title: 'ApiKey',
|
||||
component: {
|
||||
placeholder: 'apidomainkey',
|
||||
placeholder: '账户级别的key,对整个账户都有管理权限',
|
||||
},
|
||||
helper:'前往https://www.west.cn/manager/domain/ 进入对应域名管理页面,上方点击ApiKey获取密钥',
|
||||
required: true,
|
||||
helper: '账户级别的key,对整个账户都有管理权限\n前往https://www.west.cn/manager/API/APIconfig.asp,手动设置“api连接密码”',
|
||||
encrypt: true,
|
||||
required: false,
|
||||
mergeScript: `
|
||||
return {
|
||||
show:ctx.compute(({form})=>{
|
||||
return form.access.scope === 'account'
|
||||
})
|
||||
}
|
||||
`,
|
||||
})
|
||||
apikey = '';
|
||||
|
||||
/**
|
||||
* 授权属性配置
|
||||
*/
|
||||
@AccessInput({
|
||||
title: 'apidomainkey',
|
||||
component: {
|
||||
placeholder: '域名级别的key,仅对单个域名有权限',
|
||||
},
|
||||
helper: '域名级别的key,仅对单个域名有权限。 \n前往[西部数据域名管理](https://www.west.cn/manager/domain/),点击域名,右上方点击ApiKey获取密钥',
|
||||
encrypt: true,
|
||||
required: false,
|
||||
mergeScript: `
|
||||
return {
|
||||
show:ctx.compute(({form})=>{
|
||||
return form.access.scope === 'domain'
|
||||
})
|
||||
}
|
||||
`,
|
||||
})
|
||||
apidomainkey = '';
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue