perf: 域名导入任务进度条

This commit is contained in:
xiaojunnuo
2026-01-25 00:50:36 +08:00
parent f7b13c69e9
commit 7058d5cb93
10 changed files with 308 additions and 48 deletions
@@ -2,8 +2,9 @@ import { useFormWrapper } from "@fast-crud/fast-crud";
export type FormOptionReq = {
title: string;
columns: any;
columns?: any;
onSubmit?: any;
body?: any;
};
export function useFormDialog() {
@@ -18,6 +19,9 @@ export function useFormDialog() {
wrapper: {
title: req.title,
saveRemind: false,
slots: {
"form-body-top": req.body,
},
},
async afterSubmit() {},
async doSubmit({ form }: any) {
@@ -58,17 +58,44 @@ export async function DeleteBatch(ids: any[]) {
});
}
export async function SyncSubmit(body: any) {
export async function ImportTaskAdd(body: any) {
return await request({
url: apiPrefix + "/sync/import",
url: apiPrefix + "/import/add",
method: "post",
data: body,
});
}
export async function SyncDomainsExpiration() {
export async function ImportTaskStatus() {
return await request({
url: apiPrefix + "/sync/expiration",
url: apiPrefix + "/import/status",
method: "post",
});
}
export async function ImportTaskDelete(key: any) {
return await request({
url: apiPrefix + "/import/delete",
method: "post",
params: { key },
});
}
export async function ImportTaskStart(key: any) {
return await request({
url: apiPrefix + "/import/start",
method: "post",
params: { key },
});
}
export async function SyncExpirationStart() {
return await request({
url: apiPrefix + "/sync/expiration/start",
method: "post",
});
}
export async function SyncExpirationStatus() {
return await request({
url: apiPrefix + "/sync/expiration/status",
method: "post",
});
}
@@ -1,15 +1,15 @@
import * as api from "./api";
import { useI18n } from "/src/locales";
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { Modal, notification } from "ant-design-vue";
import { Ref, ref } from "vue";
import { useRouter } from "vue-router";
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { useUserStore } from "/@/store/user";
import { useSettingStore } from "/@/store/settings";
import * as api from "./api";
import DomainImportTaskStatus from "./domain-import-task-status.vue";
import { Dicts } from "/@/components/plugins/lib/dicts";
import { useSettingStore } from "/@/store/settings";
import { useUserStore } from "/@/store/user";
import { useFormDialog } from "/@/use/use-dialog";
import { createAccessApi } from "/@/views/certd/access/api";
import { Modal, notification } from "ant-design-vue";
import { useDomainImport } from "./use";
import { useI18n } from "/src/locales";
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const router = useRouter();
const { t } = useI18n();
@@ -51,7 +51,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
url: "pi/dnsProvider/dnsProviderTypeDict",
});
const openDomainImportDialog = useDomainImport();
const { openFormDialog } = useFormDialog();
return {
crudOptions: {
settings: {
@@ -103,13 +103,15 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
needPlus: true,
color: "gold",
icon: "mingcute:vip-1-line",
click: () => {
click: async () => {
settingStore.checkPlus();
openDomainImportDialog({
afterSubmit: () => {
setTimeout(() => {
crudExpose.doRefresh();
}, 2000);
await openFormDialog({
title: "从域名提供商导入域名",
body: () => {
return <DomainImportTaskStatus />;
},
onSubmit: async (form: any) => {
crudExpose.doRefresh();
},
});
},
@@ -120,7 +122,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
icon: "ion:refresh-outline",
text: "同步域名过期时间",
click: async () => {
await api.SyncDomainsExpiration();
await api.SyncExpirationStart();
notification.success({
message: "同步任务已提交",
});
@@ -0,0 +1,76 @@
<template>
<div class="domain-import-task-status">
<div class="action">
<fs-button type="primary" size="small" icon="ion:add-outline" @click="addTask">添加导入任务</fs-button>
</div>
<table class="table table-striped">
<thead>
<tr>
<th>标题</th>
<th>进度</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="item in list" :key="item.taskId">
<td>{{ item.title }}</td>
<td>
<a-progress :percent="item.percent" size="small" status="active" />
</td>
<td>
<fs-button type="primary" size="small" icon="ion:play-outline" @click="startTask(item)">执行</fs-button>
<fs-button type="danger" size="small" icon="ion:stop-outline" @click="deleteTask(item)">删除</fs-button>
</td>
</tr>
</tbody>
</table>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref } from "vue";
import * as api from "./api";
import { Modal } from "ant-design-vue";
import { useDomainImport } from "./use";
defineOptions({
name: "DomainImportTaskStatus",
});
const list = ref([]);
async function loadImportTaskStatus() {
const res = await api.ImportTaskStatus();
list.value = res || [];
}
async function startTask(item: any) {
await api.ImportTaskStart(item);
await loadImportTaskStatus();
}
async function deleteTask(item: any) {
Modal.confirm({
title: "确认删除吗?",
okText: "确认",
okType: "danger",
onOk: async () => {
await api.ImportTaskDelete(item.taskId);
await loadImportTaskStatus();
},
});
}
const openDomainImportDialog = useDomainImport();
async function addTask() {
await openDomainImportDialog({
afterSubmit: async () => {
await loadImportTaskStatus();
},
});
}
onMounted(async () => {
await loadImportTaskStatus();
});
</script>
@@ -53,11 +53,10 @@ export function useDomainImport() {
title: "从域名提供商导入域名",
columns: columns,
onSubmit: async (form: any) => {
await api.SyncSubmit({
await api.ImportTaskAdd({
dnsProviderType: form.dnsProviderType,
dnsProviderAccessId: form.dnsProviderAccessId,
});
message.success("导入任务已提交");
if (req.afterSubmit) {
req.afterSubmit();
}