mirror of
https://gitee.com/mirrors/AllinSSL.git
synced 2026-03-09 16:21:10 +08:00
【修复】申请配置证书CA列表,授权api新增新增btdomain
This commit is contained in:
@@ -55,6 +55,7 @@ import type {
|
||||
ConstellixAccessConfig,
|
||||
WebhookAccessConfig,
|
||||
SpaceshipAccessConfig,
|
||||
BTDomainAccessConfig,
|
||||
} from "@/types/access";
|
||||
import type { VNode, Ref } from "vue";
|
||||
import { testAccess, getPlugins } from "@/api/access";
|
||||
@@ -494,7 +495,7 @@ export const useApiFormController = (
|
||||
value: string,
|
||||
callback: (error?: Error) => void
|
||||
) => {
|
||||
if (!value.length) {
|
||||
if (!value || !value.length) {
|
||||
const mapTips = {
|
||||
cloudflare: $t("t_0_1747042966820"),
|
||||
btpanel: $t("t_1_1747042969705"),
|
||||
@@ -523,6 +524,25 @@ export const useApiFormController = (
|
||||
const mapTips = {
|
||||
godaddy: $t("t_1_1747984133312"),
|
||||
spaceship: "请输入 Spaceship API Secret",
|
||||
btdomain: "请输入 BTDomain Secret Key",
|
||||
};
|
||||
return callback(
|
||||
new Error(mapTips[param.value.type as keyof typeof mapTips])
|
||||
);
|
||||
}
|
||||
callback();
|
||||
},
|
||||
},
|
||||
account_id: {
|
||||
trigger: "input",
|
||||
validator: (
|
||||
rule: FormItemRule,
|
||||
value: string,
|
||||
callback: (error?: Error) => void
|
||||
) => {
|
||||
if (!value) {
|
||||
const mapTips = {
|
||||
btdomain: "请输入 BTDomain Account ID",
|
||||
};
|
||||
return callback(
|
||||
new Error(mapTips[param.value.type as keyof typeof mapTips])
|
||||
@@ -621,6 +641,7 @@ export const useApiFormController = (
|
||||
volcengine: $t("t_3_1747365600828"),
|
||||
qiniu: $t("t_3_1747984134586"),
|
||||
doge: $t("t_0_1750320239265"),
|
||||
btdomain: "请输入 BTDomain Access Key",
|
||||
};
|
||||
return callback(
|
||||
new Error(mapTips[param.value.type as keyof typeof mapTips])
|
||||
@@ -636,7 +657,7 @@ export const useApiFormController = (
|
||||
value: string,
|
||||
callback: (error?: Error) => void
|
||||
) => {
|
||||
if (!value.length) {
|
||||
if (!value || !value.length) {
|
||||
const mapTips = {
|
||||
tencentcloud: $t("t_2_1747042967277"),
|
||||
huawei: $t("t_3_1747042967608"),
|
||||
@@ -644,6 +665,7 @@ export const useApiFormController = (
|
||||
volcengine: $t("t_4_1747365600137"),
|
||||
doge: $t("t_1_1750320241427"),
|
||||
constellix: "请输入Secret Key",
|
||||
btdomain: "请输入 BTDomain Secret Key",
|
||||
};
|
||||
return callback(
|
||||
new Error(mapTips[param.value.type as keyof typeof mapTips])
|
||||
@@ -1230,6 +1252,21 @@ export const useApiFormController = (
|
||||
})
|
||||
);
|
||||
break;
|
||||
case "btdomain":
|
||||
items.push(
|
||||
useFormInput("Access Key", "config.access_key", {
|
||||
allowInput: noSideSpace,
|
||||
}),
|
||||
useFormInput("Secret Key", "config.secret_key", {
|
||||
type: "password",
|
||||
showPasswordOn: "click",
|
||||
allowInput: noSideSpace,
|
||||
}),
|
||||
useFormInput("Account ID", "config.account_id", {
|
||||
allowInput: noSideSpace,
|
||||
})
|
||||
);
|
||||
break;
|
||||
case "plugin":
|
||||
items.push(
|
||||
useFormCustom(() => {
|
||||
@@ -1478,7 +1515,14 @@ export const useApiFormController = (
|
||||
api_key: "",
|
||||
api_secret: "",
|
||||
} as SpaceshipAccessConfig;
|
||||
break;
|
||||
break;
|
||||
case "btdomain":
|
||||
param.value.config = {
|
||||
access_key: "",
|
||||
secret_key: "",
|
||||
account_id: "",
|
||||
} as BTDomainAccessConfig;
|
||||
break;
|
||||
case "plugin":
|
||||
param.value.config = {
|
||||
name: pluginList.value[0]?.value || "",
|
||||
|
||||
@@ -77,7 +77,9 @@ export default defineComponent({
|
||||
const caOptions = ref<
|
||||
Array<{ label: string; value: string; icon: string }>
|
||||
>([]);
|
||||
const emailOptions = ref<string[]>([]);
|
||||
const emailOptions = ref<
|
||||
Array<{ label: string; value: string; id: number; email: string }>
|
||||
>([]);
|
||||
const isLoadingCA = ref(false);
|
||||
const isLoadingEmails = ref(false);
|
||||
const showEmailDropdown = ref(false);
|
||||
@@ -88,7 +90,7 @@ export default defineComponent({
|
||||
isLoadingCA.value = true;
|
||||
try {
|
||||
const { data } = await getEabList({
|
||||
ca: param.value.ca,
|
||||
ca: "",
|
||||
p: 1,
|
||||
limit: 1000,
|
||||
}).fetch();
|
||||
@@ -144,7 +146,14 @@ export default defineComponent({
|
||||
try {
|
||||
const { data } = await getEabList({ ca, p: 1, limit: 1000 }).fetch();
|
||||
emailOptions.value =
|
||||
data?.map((item) => item.email).filter(Boolean) || [];
|
||||
data
|
||||
?.map((item) => ({
|
||||
label: item.email,
|
||||
value: `${item.id}`, // 使用 id 作为 value 确保唯一性
|
||||
id: item.id,
|
||||
email: item.email,
|
||||
}))
|
||||
.filter((item) => item.email) || [];
|
||||
|
||||
// 检查是否为编辑模式且有外部传入的邮箱
|
||||
if (isEdit.value && routeEmail.value) {
|
||||
@@ -154,15 +163,19 @@ export default defineComponent({
|
||||
// 非编辑模式:保持原有逻辑
|
||||
if (!emailOptions.value.length) {
|
||||
param.value.email = "";
|
||||
param.value.eabId = "";
|
||||
} else {
|
||||
// 如果邮箱数组有内容,自动填充第一个邮箱地址
|
||||
// 移除 !param.value.email 条件,让切换CA时总是更新为第一个选项
|
||||
if (emailOptions.value[0]) {
|
||||
param.value.email = emailOptions.value[0].email;
|
||||
param.value.eabId = emailOptions.value[0].id.toString();
|
||||
}
|
||||
}
|
||||
// 如果邮箱数组有内容且当前邮箱为空,自动填充第一个邮箱地址
|
||||
if (
|
||||
emailOptions.value.length > 0 &&
|
||||
emailOptions.value[0] &&
|
||||
!param.value.email
|
||||
) {
|
||||
param.value.email = emailOptions.value[0];
|
||||
}
|
||||
}
|
||||
|
||||
if (example.value) {
|
||||
example.value.restoreValidation();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("加载邮件选项失败:", error);
|
||||
@@ -239,17 +252,35 @@ export default defineComponent({
|
||||
|
||||
// 创建邮箱下拉选项
|
||||
const emailDropdownOptions = computed(() => {
|
||||
return emailOptions.value.map((email) => ({
|
||||
label: email,
|
||||
key: email,
|
||||
return emailOptions.value.map((item) => ({
|
||||
label: item.email,
|
||||
key: item.email,
|
||||
}));
|
||||
});
|
||||
|
||||
// 计算输入框宽度用于下拉菜单
|
||||
const inputWidth = computed(() => {
|
||||
if (emailInputRef.value?.$el) {
|
||||
return emailInputRef.value.$el.offsetWidth;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
// 判断是否需要输入框(letsencrypt、buypass、zerossl)
|
||||
const shouldUseInputForEmail = computed(() => {
|
||||
return ["letsencrypt", "buypass", "zerossl"].includes(param.value.ca);
|
||||
});
|
||||
|
||||
// 计算当前选中的邮箱选项的 value(用于 NSelect)
|
||||
const currentEmailValue = computed(() => {
|
||||
if (!param.value.eabId) return null;
|
||||
// 优先使用 eabId 来查找匹配的选项
|
||||
const matchedOption = emailOptions.value.find(
|
||||
(item) => item.id.toString() === param.value.eabId
|
||||
);
|
||||
return matchedOption ? matchedOption.value : null;
|
||||
});
|
||||
|
||||
// 表单渲染配置
|
||||
const config = computed(() => {
|
||||
// 基本选项
|
||||
@@ -343,7 +374,20 @@ export default defineComponent({
|
||||
options={emailDropdownOptions.value}
|
||||
onSelect={handleSelectEmail}
|
||||
placement="bottom-start"
|
||||
style="width: 100%"
|
||||
menu-props={() => ({
|
||||
style: {
|
||||
width: `${inputWidth.value}px`,
|
||||
maxHeight: "40rem",
|
||||
overflowY: "auto",
|
||||
},
|
||||
})}
|
||||
node-props={(option: any) => ({
|
||||
style: {
|
||||
padding: "8px 12px",
|
||||
cursor: "pointer",
|
||||
},
|
||||
class: "hover:bg-gray-50",
|
||||
})}
|
||||
>
|
||||
<NInput
|
||||
ref={emailInputRef}
|
||||
@@ -358,16 +402,26 @@ export default defineComponent({
|
||||
</NDropdown>
|
||||
) : (
|
||||
<NSelect
|
||||
v-model:value={param.value.email}
|
||||
options={emailOptions.value.map((email) => ({
|
||||
label: email,
|
||||
value: email,
|
||||
}))}
|
||||
value={currentEmailValue.value}
|
||||
options={emailOptions.value}
|
||||
placeholder={$t("t_2_1748052862259")}
|
||||
clearable
|
||||
filterable
|
||||
loading={isLoadingEmails.value}
|
||||
class="w-full"
|
||||
onUpdateValue={(value: string) => {
|
||||
// 根据选择的 id 找到对应的邮箱地址和 eabId
|
||||
const selectedOption = emailOptions.value.find(
|
||||
(item) => item.value === value
|
||||
);
|
||||
if (selectedOption) {
|
||||
param.value.email = selectedOption.email;
|
||||
param.value.eabId = selectedOption.id.toString();
|
||||
} else {
|
||||
param.value.email = value;
|
||||
param.value.eabId = "";
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</NFormItem>
|
||||
@@ -545,6 +599,7 @@ export default defineComponent({
|
||||
} else {
|
||||
emailOptions.value = [];
|
||||
param.value.email = "";
|
||||
param.value.eabId = "";
|
||||
showEmailDropdown.value = false;
|
||||
}
|
||||
}
|
||||
@@ -564,14 +619,14 @@ export default defineComponent({
|
||||
advancedOptions.value = false;
|
||||
await loadCAOptions();
|
||||
|
||||
// 如果当前已经有CA值,主动加载对应的邮件选项
|
||||
if (param.value.ca) {
|
||||
await loadEmailOptions(param.value.ca);
|
||||
}
|
||||
|
||||
// 如果是编辑模式且有外部传入的邮箱,直接设置邮箱值
|
||||
if (isEdit.value && routeEmail.value) {
|
||||
param.value.email = routeEmail.value;
|
||||
} else {
|
||||
// 非编辑模式:如果当前已经有CA值,主动加载对应的邮件选项
|
||||
if (param.value.ca) {
|
||||
await loadEmailOptions(param.value.ca);
|
||||
}
|
||||
}
|
||||
|
||||
// 移除重复调用,让 watch 监听器处理 CA 值变化
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { defineComponent, ref, computed, watch } from 'vue';
|
||||
import { defineComponent, ref, computed, watch } from "vue";
|
||||
import {
|
||||
NForm,
|
||||
NFormItem,
|
||||
@@ -127,7 +127,7 @@ export default defineComponent({
|
||||
const selectedRootCa = rootCaList.value.find(
|
||||
(ca) => ca.id.toString() === newRootId
|
||||
);
|
||||
if (selectedRootCa) {
|
||||
if (selectedRootCa && selectedRootCa.algorithm) {
|
||||
addForm.value.algorithm = selectedRootCa.algorithm;
|
||||
if (selectedRootCa.algorithm === "ecdsa") {
|
||||
addForm.value.key_length = "256";
|
||||
@@ -269,45 +269,43 @@ export default defineComponent({
|
||||
</div>
|
||||
</NDivider>
|
||||
</div>
|
||||
{showAdvancedConfig.value && (
|
||||
<div class="space-y-4 mt-4">
|
||||
<NFormItem label="组织(O)">
|
||||
<NInput
|
||||
v-model:value={addForm.value.o}
|
||||
placeholder="请输入组织名称"
|
||||
/>
|
||||
</NFormItem>
|
||||
<div class="mt-4" v-show={showAdvancedConfig.value}>
|
||||
<NFormItem label="组织(O)">
|
||||
<NInput
|
||||
v-model:value={addForm.value.o}
|
||||
placeholder="请输入组织名称"
|
||||
/>
|
||||
</NFormItem>
|
||||
|
||||
<NFormItem label="国家(C)" path="c" required>
|
||||
<NSelect
|
||||
v-model:value={addForm.value.c}
|
||||
options={countryOptions}
|
||||
placeholder="请选择国家"
|
||||
/>
|
||||
</NFormItem>
|
||||
<NFormItem label="国家(C)" path="c" required>
|
||||
<NSelect
|
||||
v-model:value={addForm.value.c}
|
||||
options={countryOptions}
|
||||
placeholder="请选择国家"
|
||||
/>
|
||||
</NFormItem>
|
||||
|
||||
<NFormItem label="组织单位(OU)">
|
||||
<NInput
|
||||
v-model:value={addForm.value.ou}
|
||||
placeholder="请输入组织单位"
|
||||
/>
|
||||
</NFormItem>
|
||||
<NFormItem label="组织单位(OU)">
|
||||
<NInput
|
||||
v-model:value={addForm.value.ou}
|
||||
placeholder="请输入组织单位"
|
||||
/>
|
||||
</NFormItem>
|
||||
|
||||
<NFormItem label="省份">
|
||||
<NInput
|
||||
v-model:value={addForm.value.province}
|
||||
placeholder="请输入省份"
|
||||
/>
|
||||
</NFormItem>
|
||||
<NFormItem label="省份">
|
||||
<NInput
|
||||
v-model:value={addForm.value.province}
|
||||
placeholder="请输入省份"
|
||||
/>
|
||||
</NFormItem>
|
||||
|
||||
<NFormItem label="城市">
|
||||
<NInput
|
||||
v-model:value={addForm.value.locality}
|
||||
placeholder="请输入城市"
|
||||
/>
|
||||
</NFormItem>
|
||||
</div>
|
||||
)}
|
||||
<NFormItem label="城市">
|
||||
<NInput
|
||||
v-model:value={addForm.value.locality}
|
||||
placeholder="请输入城市"
|
||||
/>
|
||||
</NFormItem>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end gap-3 mt-6">
|
||||
<NButton onClick={handleCancel}>取消</NButton>
|
||||
|
||||
@@ -251,8 +251,10 @@ export const useController = () => {
|
||||
if (data.value?.status === true) {
|
||||
rootCaList.value = data.value.data;
|
||||
if (createType.value === 'intermediate' && rootCaList.value.length > 0 && rootCaList.value[0]) {
|
||||
addForm.value.root_id = rootCaList.value[0].id.toString();
|
||||
}
|
||||
addForm.value.root_id = rootCaList.value[0].id.toString();
|
||||
addForm.value.algorithm = rootCaList.value[0].algorithm;
|
||||
addForm.value.key_length = rootCaList.value[0].key_length.toString();
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取根证书列表失败:', error);
|
||||
|
||||
Reference in New Issue
Block a user