Compare commits

...

5 Commits

Author SHA1 Message Date
xiaojunnuo cc5154e04e perf: 为DNS解析器添加超时配置,避免查询时间过长
在util.js中为dns.Resolver添加超时配置,确保DNS查询在合理时间内完成
2026-04-25 04:45:39 +08:00
xiaojunnuo 77db5ecd12 perf: 优化权威域名服务器查询超时时长 2026-04-25 04:30:48 +08:00
xiaojunnuo 7ac789c9c7 perf: 商业版支持配置证书申请插件参数 2026-04-25 04:12:26 +08:00
xiaojunnuo 24dff05f64 fix: 修复商业版设置了公共eab,创建流水线仍然会显示需要配置eab的bug 2026-04-25 03:32:45 +08:00
xiaojunnuo 64a350364d fix: 修复流水线未编辑模式下也提示未保存的bug 2026-04-25 02:29:25 +08:00
12 changed files with 130 additions and 24 deletions
+1 -1
View File
@@ -252,7 +252,7 @@ async function resolveDomainBySoaRecord(recordName, logger = log) {
async function getAuthoritativeDnsResolver(recordName, logger = log) {
logger(`获取域名${recordName}的权威NS服务器: `);
const resolver = new dns.Resolver();
const resolver = new dns.Resolver({ timeout: 10000,maxTimeout: 60000 });
try {
/* Resolve root domain by SOA */
-1
View File
@@ -92,7 +92,6 @@ async function walkDnsChallengeRecord(recordName, resolver = dns,deep = 0) {
try {
log(`检查域名 ${recordName} 的TXT记录`);
const txtRecords = await resolver.resolveTxt(recordName);
if (txtRecords && txtRecords.length) {
log(`找到 ${txtRecords.length} 条 TXT记录( ${recordName}`);
log(`TXT records: ${JSON.stringify(txtRecords)}`);
@@ -85,7 +85,7 @@ export function useCertPipelineCreator() {
const settingStore = useSettingStore();
const router = useRouter();
function createCrudOptions(req: { certPlugin: any; doSubmit: any; title?: string }): CreateCrudOptionsRet {
function createCrudOptions(req: { certPlugin: any; doSubmit: any; title?: string; initialForm?: any }): CreateCrudOptionsRet {
const inputs: any = {};
const moreParams = [];
const doSubmit = req.doSubmit;
@@ -124,9 +124,11 @@ export function useCertPipelineCreator() {
},
},
});
return {
crudOptions: {
form: {
initialForm: req.initialForm || {},
doSubmit,
wrapper: {
wrapClassName: "cert_pipeline_create_form",
@@ -326,6 +328,15 @@ export function useCertPipelineCreator() {
//检查是否流水线数量超出限制
await checkPipelineLimit();
//设置系统初始值
const initialForm: any = {};
const pluginSysConfig = await pluginStore.getPluginConfig({ name: req.pluginName, type: "builtIn" });
if (pluginSysConfig.sysSetting?.input) {
for (const key in pluginSysConfig.sysSetting?.input) {
initialForm[key] = pluginSysConfig.sysSetting?.input[key];
}
}
async function doSubmit({ form }: any) {
// const certDetail = readCertDetail(form.cert.crt);
// 添加certd pipeline
@@ -399,6 +410,7 @@ export function useCertPipelineCreator() {
certPlugin,
doSubmit,
title: req.title,
initialForm,
});
//@ts-ignore
crudOptions.columns.groupId.form.value = req.defaultGroupId || undefined;
@@ -374,7 +374,7 @@ export default defineComponent({
setup(props, ctx) {
onBeforeRouteLeave((to, from) => {
const newPipelineStr = JSON.stringify(pipeline.value || {});
if (pipelineOriginStr.value && pipelineOriginStr.value !== newPipelineStr) {
if (props.editMode && pipelineOriginStr.value && pipelineOriginStr.value !== newPipelineStr) {
const answer = window.confirm("流水线还未保存,确定要离开吗?");
if (!answer) {
return false; // 返回 false 即可阻止本次路由跳转
@@ -1,4 +1,4 @@
import { dict, useFormWrapper } from "@fast-crud/fast-crud";
import { compute, dict, useFormWrapper } from "@fast-crud/fast-crud";
import { checkPipelineLimit, eachSteps } from "/@/views/certd/pipeline/utils";
import { templateApi } from "/@/views/certd/pipeline/template/api";
import TemplateForm from "./form.vue";
@@ -7,6 +7,7 @@ import GroupSelector from "/@/views/certd/pipeline/group/group-selector.vue";
import { ref } from "vue";
import { fillPipelineByDefaultForm } from "/@/views/certd/pipeline/certd-form/use";
import { cloneDeep } from "lodash-es";
import { $t } from "/@/locales";
export function createExtraColumns() {
const groupDictRef = dict({
@@ -14,24 +15,82 @@ export function createExtraColumns() {
value: "id",
label: "name",
});
const t = $t;
const randomHour = Math.floor(Math.random() * 6);
const randomMin = Math.floor(Math.random() * 60);
return {
triggerCron: {
title: "定时触发",
type: "text",
// triggerCron: {
// title: "定时触发",
// type: "text",
// form: {
// value: `0 ${randomMin} ${randomHour} * * *`,
// component: {
// name: "cron-editor",
// vModel: "modelValue",
// placeholder: "0 0 4 * * *",
// },
// col: {
// span: 24,
// },
// helper: "点击上面的按钮,选择每天几点定时执行。\n建议设置为每天触发一次,证书未到期之前任务会跳过,不会重复执行",
// order: 100,
// },
// },
random: {
title: "定时类型",
form: {
value: true,
helper: "是否给流水线随机设置一个时间",
show: compute(({ form }) => {
return form.clear !== true;
}),
component: {
name: "fs-dict-switch",
vModel: "checked",
dict: dict({
data: [
{
label: "随机时间",
value: true,
},
{
label: "固定时间",
value: false,
},
],
}),
},
},
},
randomRange: {
title: "随机时间范围",
form: {
value: ["00:00:00", "08:00:00"],
helper: "随机时间范围,单位秒",
component: {
// <a-time-range-picker :bordered="false" />
name: "a-time-range-picker",
vModel: "value",
valueFormat: "HH:mm:ss",
},
show: compute(({ form }) => {
return form.clear !== true && form.random === true;
}),
rules: [{ required: true, message: "请选择随机时间范围" }],
},
},
triggerCron: {
title: t("certd.schedule"),
form: {
value: `0 ${randomMin} ${randomHour} * * *`,
component: {
name: "cron-editor",
vModel: "modelValue",
placeholder: "0 0 4 * * *",
},
col: {
span: 24,
},
helper: "点击上面的按钮,选择每天几点定时执行。\n建议设置为每天触发一次,证书未到期之前任务会跳过,不会重复执行",
order: 100,
show: compute(({ form }) => {
return form.clear !== true && form?.random !== true;
}),
rules: [{ required: true, message: t("certd.selectCron") }],
},
},
notification: {
@@ -135,3 +135,11 @@ export async function DoTest(req: { id: number; input: any }): Promise<void> {
data: req,
});
}
export async function GetPluginByName(name: string): Promise<PluginConfigBean> {
return await request({
url: apiPrefix + "/getPluginByName",
method: "post",
data: { name },
});
}
@@ -36,6 +36,13 @@
</div>
</a-form-item>
<a-form-item label="其他配置">
<a-button type="primary" @click="doPluginConfig">证书申请插件默认值设置</a-button>
<div class="helper">
<div>自定义证书申请插件参数</div>
</div>
</a-form-item>
<a-form-item :wrapper-col="{ offset: 8, span: 16 }">
<a-button :loading="saveLoading" type="primary" html-type="submit">保存</a-button>
</a-form-item>
@@ -47,10 +54,10 @@
<script lang="ts" setup>
import AccessSelector from "/@/views/certd/access/access-selector/index.vue";
import { reactive, ref } from "vue";
import { CommPluginConfig, GetCommPluginConfigs, SaveCommPluginConfigs } from "/@/views/sys/plugin/api";
import { CommPluginConfig, GetCommPluginConfigs, SaveCommPluginConfigs, GetPluginByName } from "/@/views/sys/plugin/api";
import { merge } from "lodash-es";
import { notification } from "ant-design-vue";
import { usePluginConfig } from "./use-config";
defineOptions({
name: "SysPluginConfig",
});
@@ -87,5 +94,12 @@ const onFinish = async (form: any) => {
const onFinishFailed = (errorInfo: any) => {
console.log("Failed:", errorInfo);
};
const { openConfigDialog } = usePluginConfig();
async function doPluginConfig() {
const certApplyInfo = await GetPluginByName("CertApply");
await openConfigDialog({ row: certApplyInfo, crudExpose: null });
}
</script>
<style lang="less"></style>
@@ -43,13 +43,12 @@
</template>
<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";
import { cloneDeep, merge, unset } from "lodash-es";
import { computed, onMounted, reactive, ref } from "vue";
import { useRoute, useRouter } from "vue-router";
import Rollbackable from "./rollbackable.vue";
import { usePluginStore } from "/@/store/plugin";
const route = useRoute();
const router = useRouter();
const pluginStore = usePluginStore();
@@ -178,6 +178,9 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
type: "dict-select",
search: {
show: true,
component: {
disabled: false,
},
},
form: {
order: 0,
@@ -35,7 +35,9 @@ export function usePluginConfig() {
},
afterSubmit() {
notification.success({ message: t("certd.operationSuccess") });
crudExpose.doRefresh();
if (crudExpose) {
crudExpose.doRefresh();
}
},
async doSubmit({}: any) {
const form = configEditorRef.value.getForm();
@@ -84,6 +84,15 @@ export class PluginController extends CrudController<PluginService> {
const res = await this.pluginConfigService.saveCommPluginConfig(body);
return this.ok(res);
}
@Post('/getPluginByName', { description: 'sys:settings:view' })
async getPluginByName(@Body('name') name: string) {
const res = await this.pluginConfigService.getPluginConfig({
name: name,
type: 'builtIn'
});
return this.ok(res);
}
@Post('/saveSetting', { description: 'sys:settings:edit' })
async saveSetting(@Body(ALL) body: PluginConfig) {
const res = await this.pluginConfigService.savePluginConfig(body);
@@ -275,6 +275,7 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
mergeScript: `
return {
show: ctx.compute(({form})=>{
console.log("show",form)
return (form.sslProvider === 'zerossl' && !form.zerosslCommonEabAccessId)
|| (form.sslProvider === 'google' && !form.googleCommonEabAccessId)
|| (form.sslProvider === 'sslcom' && !form.sslcomCommonEabAccessId)