mirror of
https://github.com/certd/certd.git
synced 2026-04-14 12:30:54 +08:00
perf: 证书流水线创建域名输入框支持获取域名数据进行选择
This commit is contained in:
@@ -39,6 +39,7 @@ import { dict } from "@fast-crud/fast-crud";
|
||||
import * as api from "./api.js";
|
||||
import CnameTip from "./cname-tip.vue";
|
||||
import { Modal } from "ant-design-vue";
|
||||
import { utils } from "/@/utils/index.js";
|
||||
const statusDict = dict({
|
||||
data: [
|
||||
{ label: "待设置CNAME", value: "cname", color: "warning" },
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
<template>
|
||||
<div class="domain-select">
|
||||
<div class="flex flex-row">
|
||||
<a-select class="domain-select-input" show-search :filter-option="filterOption" :options="optionsRef" :value="value" v-bind="attrs" @click="onClick" @update:value="emit('update:value', $event)">
|
||||
<template #dropdownRender="{ menuNode }">
|
||||
<template v-if="search">
|
||||
<div class="flex w-full" style="padding: 4px 8px">
|
||||
<a-input
|
||||
ref="inputRef"
|
||||
v-model:value="searchKeyRef"
|
||||
class="flex-1"
|
||||
allow-clear
|
||||
placeholder="这里可以搜索域名(数据来自设置->域名管理),列表中没有的域名可以直接在上面输入框输入"
|
||||
@keydown.enter="doSearch"
|
||||
/>
|
||||
<a-button class="ml-2" :loading="loading" type="text" @click="doSearch">
|
||||
<template #icon>
|
||||
<search-outlined />
|
||||
</template>
|
||||
查询
|
||||
</a-button>
|
||||
</div>
|
||||
<div v-if="hasError" class="helper p-2" :class="{ error: hasError }">
|
||||
{{ message }}
|
||||
</div>
|
||||
<a-divider style="margin: 4px 0" />
|
||||
</template>
|
||||
<v-nodes :vnodes="menuNode" />
|
||||
|
||||
<div v-if="pager === true" class="pager text-center p-5" @click="paginationClick">
|
||||
<a-pagination v-model:current="pagerRef.pageNo" simple :total="pagerRef.total" :page-size="pagerRef.pageSize" @change="onPageChange" />
|
||||
</div>
|
||||
</template>
|
||||
</a-select>
|
||||
<div class="ml-5">
|
||||
<fs-button :loading="loading" title="刷新我的域名列表" icon="ion:refresh-outline" @click="refreshOptions"></fs-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="helper" :class="{ error: hasError }">
|
||||
{{ message }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { computed, defineComponent, ref, Ref, useAttrs } from "vue";
|
||||
import { request } from "/@/api/service";
|
||||
|
||||
defineOptions({
|
||||
name: "DomainSelector",
|
||||
});
|
||||
|
||||
const VNodes = defineComponent({
|
||||
props: {
|
||||
vnodes: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
render() {
|
||||
return this.vnodes;
|
||||
},
|
||||
});
|
||||
|
||||
const props = defineProps<{
|
||||
search?: boolean;
|
||||
pager?: boolean;
|
||||
value?: any[];
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
"update:value": any;
|
||||
}>();
|
||||
|
||||
const attrs = useAttrs();
|
||||
|
||||
const searchKeyRef = ref("");
|
||||
const optionsRef = ref([]);
|
||||
const message = ref("");
|
||||
const hasError = ref(false);
|
||||
const loading = ref(false);
|
||||
const pagerRef: Ref = ref({
|
||||
pageNo: 1,
|
||||
total: 0,
|
||||
pageSize: 20,
|
||||
});
|
||||
const getOptions = async () => {
|
||||
if (loading.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
message.value = "";
|
||||
hasError.value = false;
|
||||
loading.value = true;
|
||||
const pageNo = pagerRef.value.pageNo;
|
||||
const pageSize = pagerRef.value.pageSize;
|
||||
try {
|
||||
const res = await request({
|
||||
url: "/cert/domain/page",
|
||||
method: "POST",
|
||||
data: {
|
||||
query: {
|
||||
domain: props.search ? searchKeyRef.value : undefined,
|
||||
},
|
||||
page: {
|
||||
offset: (pageNo - 1) * pageSize,
|
||||
limit: pageSize,
|
||||
},
|
||||
},
|
||||
});
|
||||
const list = res?.records || res || [];
|
||||
|
||||
const options = [];
|
||||
for (let item of list) {
|
||||
options.push({
|
||||
value: item.domain,
|
||||
label: item.domain,
|
||||
});
|
||||
options.push({
|
||||
value: `*.${item.domain}`,
|
||||
label: `*.${item.domain}`,
|
||||
});
|
||||
}
|
||||
|
||||
optionsRef.value = options;
|
||||
pagerRef.value.total = list.length;
|
||||
if (props.pager) {
|
||||
if (res.total != null) {
|
||||
pagerRef.value.total = res.total;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const filterOption = (input: string, option: any) => {
|
||||
return option.label.toLowerCase().includes(input.toLowerCase()) || String(option.value).toLowerCase().includes(input.toLowerCase());
|
||||
};
|
||||
|
||||
async function onClick() {
|
||||
if (optionsRef.value?.length === 0) {
|
||||
await refreshOptions();
|
||||
}
|
||||
}
|
||||
|
||||
async function refreshOptions() {
|
||||
await getOptions();
|
||||
}
|
||||
|
||||
async function doSearch() {
|
||||
pagerRef.value.pageNo = 1;
|
||||
await refreshOptions();
|
||||
}
|
||||
|
||||
async function onPageChange(current: any) {
|
||||
await refreshOptions();
|
||||
}
|
||||
|
||||
async function paginationClick(e: any) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less"></style>
|
||||
@@ -85,7 +85,9 @@ const message = ref("");
|
||||
const hasError = ref(false);
|
||||
const loading = ref(false);
|
||||
const pagerRef: Ref = ref({
|
||||
current: 1,
|
||||
pageNo: 1,
|
||||
total: 0,
|
||||
pageSize: 100,
|
||||
});
|
||||
const getOptions = async () => {
|
||||
if (loading.value) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import RemoteSelect from "./common/remote-select.vue";
|
||||
import RemoteInput from "./common/remote-input.vue";
|
||||
import RemoteTreeSelect from "./common/remote-tree-select.vue";
|
||||
import CertDomainsGetter from "./common/cert-domains-getter.vue";
|
||||
import DomainSelector from "./common/domain-selector.vue";
|
||||
import OutputSelector from "/@/components/plugins/common/output-selector/index.vue";
|
||||
import DnsProviderSelector from "/@/components/plugins/cert/dns-provider-selector/index.vue";
|
||||
import DomainsVerifyPlanEditor from "/@/components/plugins/cert/domains-verify-plan-editor/index.vue";
|
||||
@@ -29,6 +30,7 @@ export default {
|
||||
app.component("RemoteTreeSelect", RemoteTreeSelect);
|
||||
app.component("RemoteInput", RemoteInput);
|
||||
app.component("CertDomainsGetter", CertDomainsGetter);
|
||||
app.component("DomainSelector", DomainSelector);
|
||||
app.component("InputPassword", InputPassword);
|
||||
app.component("ParamsShow", ParamsShow);
|
||||
},
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="tsx" setup>
|
||||
import { defineProps, inject, ref, useAttrs } from "vue";
|
||||
import { inject, ref, useAttrs } from "vue";
|
||||
import { Modal } from "ant-design-vue";
|
||||
import { ComponentPropsType, doRequest } from "/@/components/plugins/lib";
|
||||
|
||||
|
||||
@@ -12,16 +12,16 @@
|
||||
</div>
|
||||
</template>
|
||||
<script lang="tsx" setup>
|
||||
import { computed, onMounted, reactive, ref } from "vue";
|
||||
import dayjs from "dayjs";
|
||||
import { message, Modal } from "ant-design-vue";
|
||||
import dayjs from "dayjs";
|
||||
import { computed, onMounted, reactive, ref } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useRouter } from "vue-router";
|
||||
import * as api from "./api";
|
||||
import { useSettingStore } from "/@/store/settings";
|
||||
import { useRouter } from "vue-router";
|
||||
import { useUserStore } from "/@/store/user";
|
||||
import { mitter } from "/@/utils/util.mitt";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { env } from "/@/utils/util.env";
|
||||
import { mitter } from "/@/utils/util.mitt";
|
||||
const { t } = useI18n();
|
||||
|
||||
const settingStore = useSettingStore();
|
||||
|
||||
@@ -9,12 +9,14 @@ export abstract class CertApplyBaseConvertPlugin extends AbstractTaskPlugin {
|
||||
@TaskInput({
|
||||
title: "证书域名",
|
||||
component: {
|
||||
name: "a-select",
|
||||
name: "domain-selector",
|
||||
vModel: "value",
|
||||
mode: "tags",
|
||||
open: false,
|
||||
placeholder: "foo.com / *.foo.com / *.bar.com",
|
||||
// open: false,
|
||||
placeholder: "foo.com / *.foo.com / *.sub.foo.com / *.bar.com",
|
||||
tokenSeparators: [",", " ", ",", "、", "|"],
|
||||
search: true,
|
||||
pager:true,
|
||||
},
|
||||
rules: [{ type: "domains" }],
|
||||
required: true,
|
||||
|
||||
Reference in New Issue
Block a user