perf: 支持从提供商导入域名列表

This commit is contained in:
xiaojunnuo
2026-01-20 00:13:05 +08:00
parent 5ec9916817
commit f4423638a2
12 changed files with 138 additions and 23 deletions
@@ -31,7 +31,8 @@ export type DnsProviderContext = {
export type DomainRecord = { export type DomainRecord = {
id: string; id: string;
domain: string; domain: string;
thirdDns: boolean; registrationDate: number;
expirationDate: number;
}; };
export interface IDnsProvider<T = any> { export interface IDnsProvider<T = any> {
@@ -1,5 +1,5 @@
<template> <template>
<a-select> <a-select :value="value" @update:value="onChange">
<a-select-option v-for="item of options" :key="item.value" :value="item.value" :label="item.label"> <a-select-option v-for="item of options" :key="item.value" :value="item.value" :label="item.label">
<span class="flex-o"> <span class="flex-o">
<fs-icon :icon="item.icon" class="fs-16 color-blue mr-5" /> <fs-icon :icon="item.icon" class="fs-16 color-blue mr-5" />
@@ -12,5 +12,11 @@
<script lang="ts" setup> <script lang="ts" setup>
const props = defineProps<{ const props = defineProps<{
options: { value: any; label: string; icon: string }[]; options: { value: any; label: string; icon: string }[];
value: any;
}>(); }>();
const emit = defineEmits(["update:value"]);
function onChange(value: any) {
emit("update:value", value);
}
</script> </script>
@@ -1,5 +1,5 @@
<template> <template>
<icon-select class="dns-provider-selector" :value="modelValue" :options="options" @update:value="onChanged"> </icon-select> <icon-select class="dns-provider-selector" :value="modelValue" :options="options" @update:value="atChange"> </icon-select>
</template> </template>
<script lang="ts"> <script lang="ts">
@@ -37,7 +37,7 @@ export default {
} }
onCreate(); onCreate();
function onChanged(value: any) { function atChange(value: any) {
ctx.emit("update:modelValue", value); ctx.emit("update:modelValue", value);
onSelectedChange(value); onSelectedChange(value);
} }
@@ -52,7 +52,7 @@ export default {
} }
return { return {
options, options,
onChanged, atChange,
}; };
}, },
}; };
@@ -72,7 +72,7 @@ export default defineComponent({
} }
async function emitValue(value) { async function emitValue(value) {
if (pipeline?.value && target?.value && pipeline.value.userId !== target.value.userId) { if (pipeline && pipeline?.value && target?.value && pipeline.value.userId !== target.value.userId) {
message.error("对不起,您不能修改他人流水线的授权"); message.error("对不起,您不能修改他人流水线的授权");
return; return;
} }
@@ -57,3 +57,11 @@ export async function DeleteBatch(ids: any[]) {
data: { ids }, data: { ids },
}); });
} }
export async function SyncSubmit(body: any) {
return await request({
url: apiPrefix + "/sync/submit",
method: "post",
data: body,
});
}
@@ -8,6 +8,7 @@ import { useSettingStore } from "/@/store/settings";
import { Dicts } from "/@/components/plugins/lib/dicts"; import { Dicts } from "/@/components/plugins/lib/dicts";
import { createAccessApi } from "/@/views/certd/access/api"; import { createAccessApi } from "/@/views/certd/access/api";
import { Modal } from "ant-design-vue"; import { Modal } from "ant-design-vue";
import { useDomainImport } from "./use";
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet { export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const router = useRouter(); const router = useRouter();
@@ -49,6 +50,8 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
const dnsProviderTypeDict = dict({ const dnsProviderTypeDict = dict({
url: "pi/dnsProvider/dnsProviderTypeDict", url: "pi/dnsProvider/dnsProviderTypeDict",
}); });
const openDomainImportDialog = useDomainImport();
return { return {
crudOptions: { crudOptions: {
settings: { settings: {
@@ -88,6 +91,18 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
} }
}, },
}, },
actionbar: {
buttons: {
import: {
title: "从域名提供商导入域名",
type: "primary",
text: "从域名提供商导入",
click: () => {
openDomainImportDialog();
},
},
},
},
columns: { columns: {
id: { id: {
title: "ID", title: "ID",
@@ -1,5 +1,7 @@
import { message } from "ant-design-vue";
import * as api from "./api"; import * as api from "./api";
import { useFormDialog } from "/@/use/use-dialog"; import { useFormDialog } from "/@/use/use-dialog";
import { compute } from "@fast-crud/fast-crud";
export function useDomainImport() { export function useDomainImport() {
const { openFormDialog } = useFormDialog(); const { openFormDialog } = useFormDialog();
@@ -7,11 +9,42 @@ export function useDomainImport() {
const columns = { const columns = {
dnsProviderType: { dnsProviderType: {
title: "域名提供商", title: "域名提供商",
type: "select", type: "text",
form: {
component: {
name: "dns-provider-selector",
},
on: {
//@ts-ignore
onSelectedChange: ({ form, $event }) => {
form.dnsProviderAccessType = $event.accessType;
},
},
//@ts-ignore
valueChange({ form }) {
form.dnsProviderAccessId = null;
},
},
},
dnsProviderAccessType: {
title: "域名提供商访问类型",
type: "text",
form: {
show: false,
},
}, },
dnsProviderAccessId: { dnsProviderAccessId: {
title: "域名提供商访问ID", title: "域名提供商授权",
type: "input", type: "text",
form: {
component: {
name: "access-selector",
vModel: "modelValue",
type: compute(({ form }) => {
return form.dnsProviderAccessType || form.dnsProviderType;
}),
},
},
}, },
}; };
@@ -20,9 +53,11 @@ export function useDomainImport() {
title: "从域名提供商导入域名", title: "从域名提供商导入域名",
columns: columns, columns: columns,
onSubmit: async (form: any) => { onSubmit: async (form: any) => {
await api.Save({ await api.SyncSubmit({
title: form.title, dnsProviderType: form.dnsProviderType,
dnsProviderAccessId: form.dnsProviderAccessId,
}); });
message.success("导入任务已提交");
}, },
}); });
}; };
@@ -0,0 +1,3 @@
ALTER TABLE cd_domain ADD COLUMN from_type varchar(20);
ALTER TABLE cd_domain ADD COLUMN registration_date integer;
ALTER TABLE cd_domain ADD COLUMN expiration_date integer;
@@ -25,6 +25,15 @@ export class DomainEntity {
@Column({ comment: '是否禁用', name: 'disabled' }) @Column({ comment: '是否禁用', name: 'disabled' })
disabled: boolean; disabled: boolean;
@Column({ comment: '注册时间', name: 'registration_date' })
registrationDate: number;
@Column({ comment: '过期时间', name: 'expiration_date' })
expirationDate: number;
@Column({ comment: '来源', name: 'from', length: 50 })
fromType: string;
@Column({ comment: 'http上传类型', name: 'http_uploader_type', length: 50 }) @Column({ comment: 'http上传类型', name: 'http_uploader_type', length: 50 })
httpUploaderType: string; httpUploaderType: string;
@@ -226,13 +226,19 @@ export class DomainService extends BaseService<DomainEntity> {
} }
}) })
if (old) { if (old) {
const updateObj :any={
id: old.id,
registrationDate: domainRecord.registrationDate,
expirationDate: domainRecord.expirationDate,
}
if (old.fromType !== 'manual'){
//如果不是手动的,更新校验配置
updateObj.dnsProviderType = dnsProviderType
updateObj.dnsProviderAccess = dnsProviderAccessId
updateObj.challengeType = challengeType
}
//更新 //更新
await this.update({ await this.update(updateObj)
id: old.id,
dnsProviderType,
dnsProviderAccess: dnsProviderAccessId,
challengeType,
})
} else { } else {
//添加 //添加
await this.add({ await this.add({
@@ -241,6 +247,10 @@ export class DomainService extends BaseService<DomainEntity> {
dnsProviderType, dnsProviderType,
dnsProviderAccess: dnsProviderAccessId, dnsProviderAccess: dnsProviderAccessId,
challengeType, challengeType,
disabled: false,
fromType: 'auto',
registrationDate: domainRecord.registrationDate,
expirationDate: domainRecord.expirationDate,
}) })
} }
} }
@@ -254,10 +264,6 @@ export class DomainService extends BaseService<DomainEntity> {
} }
//处理 //处理
for (const domainRecord of pageRes.list) { for (const domainRecord of pageRes.list) {
if (domainRecord.thirdDns) {
//域名由第三方dns解析,不导入
continue
}
await importDomain(domainRecord) await importDomain(domainRecord)
} }
@@ -1,6 +1,7 @@
import {CreateRecordOptions, DnsProviderContext, IDnsProvider, RemoveRecordOptions} from '@certd/plugin-cert'; import {CreateRecordOptions, DnsProviderContext, DomainRecord, IDnsProvider, RemoveRecordOptions} from '@certd/plugin-cert';
import {PlusService} from '@certd/lib-server'; import {PlusService} from '@certd/lib-server';
import punycode from 'punycode.js' import punycode from 'punycode.js'
import { Pager, PageRes } from '@certd/pipeline';
export type CommonCnameProvider = { export type CommonCnameProvider = {
id: number; id: number;
domain: string; domain: string;
@@ -23,6 +24,9 @@ export class CommonDnsProvider implements IDnsProvider {
this.config = opts.config; this.config = opts.config;
this.plusService = opts.plusService; this.plusService = opts.plusService;
} }
getDomainListPage(pager: Pager): Promise<PageRes<DomainRecord>> {
throw new Error('公共CNAME服务不支持获取域名列表');
}
/** /**
* 中文转英文 * 中文转英文
@@ -1,6 +1,7 @@
import { AbstractDnsProvider, CreateRecordOptions, IsDnsProvider, RemoveRecordOptions } from '@certd/plugin-cert'; import { AbstractDnsProvider, CreateRecordOptions, DomainRecord, IsDnsProvider, RemoveRecordOptions } from '@certd/plugin-cert';
import { AliyunAccess } from '../../plugin-lib/aliyun/access/aliyun-access.js'; import { AliyunAccess } from '../../plugin-lib/aliyun/access/aliyun-access.js';
import { AliyunClient } from '../../plugin-lib/aliyun/index.js'; import { AliyunClient } from '../../plugin-lib/aliyun/index.js';
import { Pager, PageRes } from '@certd/pipeline';
@IsDnsProvider({ @IsDnsProvider({
@@ -153,6 +154,33 @@ export class AliyunDnsProvider extends AbstractDnsProvider {
throw e throw e
} }
} }
async getDomainListPage(pager: Pager) :Promise<PageRes<DomainRecord>> {
const params = {
RegionId: 'cn-hangzhou',
PageSize: pager.pageSize,
PageNumber: pager.pageNo,
};
const requestOption = {
method: 'POST',
};
const ret = await this.client.request(
'DescribeDomains',
params,
requestOption
);
const list = ret.Domains?.Domain?.map(item => ({
id: item.DomainId,
domain: item.DomainName,
})) || []
return {
list,
total: ret.TotalCount,
}
}
} }
new AliyunDnsProvider(); new AliyunDnsProvider();