mirror of
https://gitee.com/mirrors/AllinSSL.git
synced 2026-03-09 16:21:10 +08:00
【调整】新增部署插件扩展功能
【新增】多吉云cdn配置 【优化】分页新增本地存储功能
This commit is contained in:
@@ -15,7 +15,7 @@ import BaseComponent from '@components/BaseLayout'
|
||||
export default defineComponent({
|
||||
name: 'AuthApiManage',
|
||||
setup() {
|
||||
const { ApiTable, ApiTablePage, param, fetch, total, openAddForm } = useController()
|
||||
const { TableComponent, PageComponent, param, fetch, total, openAddForm } = useController()
|
||||
const cssVar = useThemeCssVar(['contentPadding', 'borderColor', 'headerHeight', 'iconColorHover'])
|
||||
|
||||
return () => (
|
||||
@@ -50,7 +50,7 @@ export default defineComponent({
|
||||
),
|
||||
content: () => (
|
||||
<div class="rounded-lg">
|
||||
<ApiTable
|
||||
<TableComponent
|
||||
size="medium"
|
||||
v-slots={{
|
||||
empty: () => <EmptyState addButtonText={$t('t_0_1745289355714')} onAddClick={openAddForm} />,
|
||||
@@ -60,7 +60,7 @@ export default defineComponent({
|
||||
),
|
||||
footerRight: () => (
|
||||
<div class="mt-4 flex justify-end">
|
||||
<ApiTablePage
|
||||
<PageComponent
|
||||
v-slots={{
|
||||
prefix: () => (
|
||||
<span>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import {
|
||||
FormInst,
|
||||
FormItemRule,
|
||||
FormProps,
|
||||
FormRules,
|
||||
@@ -14,13 +13,13 @@ import {
|
||||
NSpace,
|
||||
NTag,
|
||||
NText,
|
||||
NTooltip,
|
||||
type DataTableColumns,
|
||||
} from 'naive-ui'
|
||||
import {
|
||||
useModal,
|
||||
useDialog,
|
||||
useTable,
|
||||
useTablePage,
|
||||
useModalHooks,
|
||||
useFormHooks,
|
||||
useForm,
|
||||
@@ -47,9 +46,12 @@ import type {
|
||||
BunnyAccessConfig,
|
||||
GcoreAccessConfig,
|
||||
JdcloudAccessConfig,
|
||||
DogeAccessConfig,
|
||||
PluginAccessConfig,
|
||||
} from '@/types/access'
|
||||
import type { VNode, Ref } from 'vue'
|
||||
import { testAccess } from '@/api/access'
|
||||
import { testAccess, getPlugins } from '@/api/access'
|
||||
// import { useLocalStorage } from '@vueuse/core'
|
||||
|
||||
import ApiManageForm from './components/ApiManageModel'
|
||||
import SvgIcon from '@components/SvgIcon'
|
||||
@@ -63,8 +65,8 @@ import { JSX } from 'vue/jsx-runtime'
|
||||
interface AuthApiManageControllerExposes {
|
||||
loading: Ref<boolean>
|
||||
fetch: () => Promise<void>
|
||||
ApiTable: (props: Record<string, unknown>, context: Record<string, unknown>) => JSX.Element
|
||||
ApiTablePage: (props: Record<string, unknown>, context: Record<string, unknown>) => JSX.Element
|
||||
TableComponent: (props: Record<string, unknown>, context: Record<string, unknown>) => VNode
|
||||
PageComponent: (props: Record<string, unknown>, context: Record<string, unknown>) => VNode
|
||||
param: Ref<AccessListParams>
|
||||
total: Ref<number>
|
||||
openAddForm: () => void
|
||||
@@ -181,31 +183,17 @@ export const useController = (): AuthApiManageControllerExposes => {
|
||||
]
|
||||
|
||||
// 表格实例
|
||||
const {
|
||||
component: ApiTable,
|
||||
loading,
|
||||
param,
|
||||
total,
|
||||
fetch,
|
||||
} = useTable<AccessItem, AccessListParams>({
|
||||
const { TableComponent, PageComponent, loading, param, total, fetch } = useTable<AccessItem, AccessListParams>({
|
||||
config: createColumns(),
|
||||
request: fetchAccessList,
|
||||
watchValue: ['p', 'limit'],
|
||||
storage: 'authApiManage',
|
||||
alias: { page: 'p', pageSize: 'limit' },
|
||||
defaultValue: {
|
||||
p: 1,
|
||||
limit: 10,
|
||||
search: '',
|
||||
},
|
||||
watchValue: ['p', 'limit'],
|
||||
})
|
||||
|
||||
// 分页实例
|
||||
const { component: ApiTablePage } = useTablePage({
|
||||
param,
|
||||
total,
|
||||
alias: {
|
||||
page: 'p',
|
||||
pageSize: 'limit',
|
||||
},
|
||||
})
|
||||
|
||||
/**
|
||||
@@ -265,8 +253,8 @@ export const useController = (): AuthApiManageControllerExposes => {
|
||||
return {
|
||||
loading,
|
||||
fetch,
|
||||
ApiTable,
|
||||
ApiTablePage,
|
||||
TableComponent,
|
||||
PageComponent,
|
||||
param,
|
||||
total,
|
||||
openAddForm,
|
||||
@@ -280,6 +268,15 @@ interface ApiFormControllerProps {
|
||||
data?: AccessItem
|
||||
}
|
||||
|
||||
interface PluginOption {
|
||||
label: string
|
||||
value: string
|
||||
description?: string
|
||||
pluginName?: string
|
||||
config?: Record<string, any>
|
||||
params?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 授权API表单控制器
|
||||
* @description 处理授权API表单相关的业务逻辑
|
||||
@@ -293,6 +290,10 @@ export const useApiFormController = (props: ApiFormControllerProps): ApiFormCont
|
||||
const param = (props.data?.id ? ref({ ...props.data, config: JSON.parse(props.data.config) }) : apiFormProps) as Ref<
|
||||
AddAccessParams | UpdateAccessParams
|
||||
>
|
||||
const pluginActionTips = ref('')
|
||||
|
||||
// 插件列表
|
||||
const pluginList = ref<Array<PluginOption>>([])
|
||||
|
||||
// 表单规则
|
||||
const rules = {
|
||||
@@ -403,14 +404,30 @@ export const useApiFormController = (props: ApiFormControllerProps): ApiFormCont
|
||||
trigger: 'input',
|
||||
},
|
||||
access_key_id: {
|
||||
required: true,
|
||||
message: $t('t_4_1745317314054'),
|
||||
trigger: 'input',
|
||||
validator: (rule: FormItemRule, value: string, callback: (error?: Error) => void) => {
|
||||
if (!value) {
|
||||
const mapTips = {
|
||||
aliyun: $t('t_4_1745317314054'),
|
||||
doge: '请输入多吉云AccessKeyId',
|
||||
}
|
||||
return callback(new Error(mapTips[param.value.type as keyof typeof mapTips] || $t('t_4_1745317314054')))
|
||||
}
|
||||
callback()
|
||||
},
|
||||
},
|
||||
access_key_secret: {
|
||||
required: true,
|
||||
message: $t('t_5_1745317315285'),
|
||||
trigger: 'input',
|
||||
validator: (rule: FormItemRule, value: string, callback: (error?: Error) => void) => {
|
||||
if (!value) {
|
||||
const mapTips = {
|
||||
aliyun: $t('t_5_1745317315285'),
|
||||
doge: '请输入多吉云AccessKeySecret',
|
||||
}
|
||||
return callback(new Error(mapTips[param.value.type as keyof typeof mapTips] || $t('t_5_1745317315285')))
|
||||
}
|
||||
callback()
|
||||
},
|
||||
},
|
||||
secret_access_key: {
|
||||
required: true,
|
||||
@@ -491,6 +508,11 @@ export const useApiFormController = (props: ApiFormControllerProps): ApiFormCont
|
||||
callback()
|
||||
},
|
||||
},
|
||||
'config.name': {
|
||||
required: true,
|
||||
message: $t('t_0_1750144125193'),
|
||||
trigger: 'change',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -689,6 +711,73 @@ export const useApiFormController = (props: ApiFormControllerProps): ApiFormCont
|
||||
useFormInput('Secret Access Key', 'config.secret_access_key', { allowInput: noSideSpace }),
|
||||
)
|
||||
break
|
||||
case 'doge':
|
||||
items.push(
|
||||
useFormInput('AccessKeyId', 'config.access_key_id', { allowInput: noSideSpace }),
|
||||
useFormInput('AccessKeySecret', 'config.access_key_secret', { allowInput: noSideSpace }),
|
||||
)
|
||||
break
|
||||
case 'plugin':
|
||||
items.push(
|
||||
useFormCustom(() => {
|
||||
return (
|
||||
<NFormItem label={$t('t_1_1750144122230')} path="config.name" showRequireMark={true}>
|
||||
<NSelect
|
||||
class="w-full"
|
||||
options={pluginList.value}
|
||||
placeholder={$t('t_2_1750144123753')}
|
||||
filterable
|
||||
renderLabel={renderPluginLabel}
|
||||
renderTag={renderPluginTag}
|
||||
v-model:value={(param.value.config as PluginAccessConfig).name}
|
||||
onUpdateValue={(value: string, option: PluginOption) => {
|
||||
;(param.value.config as PluginAccessConfig).name = value
|
||||
pluginActionTips.value = renderPluginTips(option.config || {})
|
||||
}}
|
||||
v-slots={{
|
||||
empty: () => {
|
||||
return <span class="text-[1.4rem]">{$t('t_0_1750210698345')}</span>
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</NFormItem>
|
||||
)
|
||||
}),
|
||||
useFormCustom(() => {
|
||||
const pluginConfig = param.value.config as PluginAccessConfig
|
||||
const getConfigValue = () => {
|
||||
return typeof pluginConfig.config === 'string'
|
||||
? pluginConfig.config
|
||||
: JSON.stringify(pluginConfig.config, null, 2)
|
||||
}
|
||||
return (
|
||||
<NFormItem
|
||||
path="config.params"
|
||||
v-slots={{
|
||||
label: () => (
|
||||
<div>
|
||||
<NText>自定义参数</NText>
|
||||
<NTooltip
|
||||
v-slots={{
|
||||
trigger: () => (
|
||||
<span class="inline-flex ml-2 -mt-1 cursor-pointer text-base rounded-full w-[14px] h-[14px] justify-center items-center text-orange-600 border border-orange-600">
|
||||
?
|
||||
</span>
|
||||
),
|
||||
}}
|
||||
>
|
||||
{pluginActionTips.value}
|
||||
</NTooltip>
|
||||
</div>
|
||||
),
|
||||
}}
|
||||
>
|
||||
<NInput type="textarea" value={getConfigValue()} placeholder={pluginActionTips.value} rows={4} />
|
||||
</NFormItem>
|
||||
)
|
||||
}),
|
||||
)
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
@@ -813,10 +902,47 @@ export const useApiFormController = (props: ApiFormControllerProps): ApiFormCont
|
||||
secret_access_key: '',
|
||||
} as JdcloudAccessConfig
|
||||
break
|
||||
case 'doge':
|
||||
param.value.config = {
|
||||
access_key_id: '',
|
||||
access_key_secret: '',
|
||||
} as DogeAccessConfig
|
||||
break
|
||||
case 'plugin':
|
||||
param.value.config = {
|
||||
name: pluginList.value[0]?.value || '',
|
||||
config: '',
|
||||
} as PluginAccessConfig
|
||||
break
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
// 获取插件列表
|
||||
const loadPlugins = async (): Promise<void> => {
|
||||
try {
|
||||
const { data } = await getPlugins().fetch()
|
||||
if (data && Array.isArray(data)) {
|
||||
// 处理插件数据,将每个插件的 actions 展开为选项
|
||||
const pluginOptions: Array<PluginOption> = []
|
||||
data.forEach((plugin: { name: string; actions: { name: string; description: string }[] }) => {
|
||||
// 如果没有 actions,直接使用插件名称
|
||||
pluginOptions.push({
|
||||
label: plugin.name,
|
||||
value: plugin.name,
|
||||
description: plugin.actions.map((action: { description: string }) => action.description).join('、'),
|
||||
pluginName: plugin.name,
|
||||
config: plugin.config,
|
||||
})
|
||||
})
|
||||
pluginList.value = pluginOptions
|
||||
pluginActionTips.value = renderPluginTips(pluginOptions[0]?.config || {})
|
||||
}
|
||||
} catch (error) {
|
||||
console.error($t('t_1_1750210699272'), error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染单选标签
|
||||
* @param {Record<string, any>} option - 选项
|
||||
@@ -839,36 +965,64 @@ export const useApiFormController = (props: ApiFormControllerProps): ApiFormCont
|
||||
* @param {Record<string, any>} option - 选项
|
||||
* @returns {VNode} 渲染后的VNode
|
||||
*/
|
||||
const renderLabel = (option: { value: string; label: string; access: string[] }): VNode => {
|
||||
const renderLabel = (option: PluginOption): VNode => {
|
||||
return (
|
||||
<NFlex justify="space-between" class="w-[38rem]">
|
||||
<NFlex align="center" size="small">
|
||||
<SvgIcon icon={`resources-${option.value}`} size="1.6rem" />
|
||||
<NText>{option.label}</NText>
|
||||
{option.description && <div class="text-[1.2rem] text-gray-500 mt-[0.2rem]">{option.description}</div>}
|
||||
</NFlex>
|
||||
<NFlex class="pr-[1rem]">
|
||||
{option.access &&
|
||||
option.access.map((item: string) => {
|
||||
return (
|
||||
<NTag type={item === 'dns' ? 'success' : 'info'} size="small" key={item}>
|
||||
{accessTypeMap[item as keyof typeof accessTypeMap]}
|
||||
</NTag>
|
||||
)
|
||||
})}
|
||||
</NFlex>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染插件标签
|
||||
* @param {Record<string, any>} option - 选项
|
||||
* @returns {VNode} 渲染后的VNode
|
||||
*/
|
||||
const renderPluginLabel = (option: PluginOption): VNode => {
|
||||
return (
|
||||
<NFlex justify="space-between" class="w-full">
|
||||
<NFlex align="center" size="small">
|
||||
<SvgIcon icon={`resources-${option.value}`} size="1.6rem" />
|
||||
<div>
|
||||
<NText>{option.label}</NText>
|
||||
{option.description && <div class="text-[1.2rem] text-gray-500 mt-[0.2rem]">{option.description}</div>}
|
||||
</div>
|
||||
</NFlex>
|
||||
</NFlex>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染插件选中标签
|
||||
* @param props - 属性对象
|
||||
* @returns {VNode} 渲染后的VNode
|
||||
*/
|
||||
const renderPluginTag = (props: { option: PluginOption }): VNode => {
|
||||
const { option } = props
|
||||
return (
|
||||
<NFlex class="w-full">
|
||||
{option?.label ? (
|
||||
<NFlex align="center" size="small">
|
||||
<SvgIcon icon={`resources-${option.value}`} size="1.4rem" />
|
||||
<NText>{option.label}</NText>
|
||||
</NFlex>
|
||||
) : (
|
||||
<span class="text-[1.4rem] text-gray-400">{$t('t_2_1750210698518')}</span>
|
||||
)}
|
||||
</NFlex>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交授权API表单
|
||||
* @param {UpdateAccessParams | AddAccessParams} param 请求参数
|
||||
* @param {Ref<FormInst>} formRef 表单实例
|
||||
*/
|
||||
const submitApiManageForm = async (
|
||||
param: UpdateAccessParams | AddAccessParams,
|
||||
_formRef: Ref<FormInst>,
|
||||
): Promise<void> => {
|
||||
const submitApiManageForm = async (param: UpdateAccessParams | AddAccessParams): Promise<void> => {
|
||||
try {
|
||||
const data = { ...param, config: JSON.stringify(param.config) } as UpdateAccessParams<string>
|
||||
if ('id' in param) {
|
||||
@@ -882,6 +1036,15 @@ export const useApiFormController = (props: ApiFormControllerProps): ApiFormCont
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 渲染插件tips
|
||||
* @param {PluginOption} option - 插件选项
|
||||
* @returns {VNode} 渲染后的VNode
|
||||
*/
|
||||
const renderPluginTips = (tips: Record<string, any>): string => {
|
||||
return $t('t_3_1750210706775') + JSON.stringify(tips || {})
|
||||
}
|
||||
|
||||
// 使用表单hooks
|
||||
const { component: ApiManageForm, fetch } = useForm({
|
||||
config,
|
||||
@@ -904,8 +1067,10 @@ export const useApiFormController = (props: ApiFormControllerProps): ApiFormCont
|
||||
}
|
||||
})
|
||||
|
||||
// 组件初始化时获取插件列表
|
||||
onMounted(loadPlugins)
|
||||
|
||||
return {
|
||||
ApiManageForm,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ interface AuthApiManageStoreExposes {
|
||||
const accessTypeMap = {
|
||||
dns: $t('t_3_1745735765112'),
|
||||
host: $t('t_0_1746754500246'),
|
||||
plugin: '插件',
|
||||
}
|
||||
|
||||
// -------------------- 请求方法 --------------------
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { NFormItem, NSwitch, NText, SelectOption } from 'naive-ui'
|
||||
import { NFormItem, NInput, NSwitch, NText, NTooltip, SelectOption } from 'naive-ui'
|
||||
import { $t } from '@locales/index'
|
||||
import { Ref } from 'vue'
|
||||
import { useFormHooks } from '@baota/naive-ui/hooks'
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { NButton, NCard, NStep, NSteps, NText, NTooltip, NTabs, NTabPane, NInput, NDivider } from 'naive-ui'
|
||||
import { NButton, NCard, NStep, NSteps, NText, NTooltip, NTabs, NTabPane, NInput, NDivider, NFormItem } from 'naive-ui'
|
||||
import { useForm, useModalClose, useModalOptions, useMessage } from '@baota/naive-ui/hooks'
|
||||
import { useThemeCssVar } from '@baota/naive-ui/theme'
|
||||
import { useError } from '@baota/hooks/error'
|
||||
import { useStore } from '@components/FlowChart/useStore'
|
||||
import { getSites } from '@api/access'
|
||||
import { getSites, getPlugins } from '@api/access'
|
||||
|
||||
import { $t } from '@locales/index'
|
||||
import { deepClone } from '@baota/utils/data'
|
||||
@@ -84,6 +84,12 @@ export default defineComponent({
|
||||
const siteOptions = ref<FormOption[]>([])
|
||||
// 网站选项加载状态
|
||||
const siteOptionsLoading = ref(false)
|
||||
// 插件选项
|
||||
const pluginOptions = ref<FormOption[]>([])
|
||||
// 插件方法选项
|
||||
const pluginActionOptions = ref<FormOption[]>([])
|
||||
// 插件方法选项加载状态
|
||||
const pluginActionOptionsLoading = ref(false)
|
||||
// 当前步骤
|
||||
const current = ref(1)
|
||||
// 是否是下一步
|
||||
@@ -95,6 +101,9 @@ export default defineComponent({
|
||||
// 搜索关键字
|
||||
const searchKeyword = ref('')
|
||||
|
||||
// 插件方法提示
|
||||
const pluginActionTips = ref('')
|
||||
|
||||
// 表单参数
|
||||
const param = ref(deepClone(props.node.config))
|
||||
// 本地提供商
|
||||
@@ -125,7 +134,7 @@ export default defineComponent({
|
||||
value: param.value.provider_id,
|
||||
valueType: 'value' as const,
|
||||
isAddMode: true,
|
||||
'onUpdate:value': (val: { value: number | string; type: string }) => {
|
||||
'onUpdate:value': (val: { value: number | string; type: string; data: string }) => {
|
||||
if (
|
||||
val.value !== '' &&
|
||||
param.value.provider_id !== '' &&
|
||||
@@ -136,6 +145,7 @@ export default defineComponent({
|
||||
}
|
||||
param.value.provider_id = val.value
|
||||
param.value.type = val.type
|
||||
param.value.provider_data = val?.data || ''
|
||||
},
|
||||
}
|
||||
return (<DnsProviderSelect {...dnsProviderProps} />) as VNode
|
||||
@@ -155,7 +165,6 @@ export default defineComponent({
|
||||
}),
|
||||
)
|
||||
|
||||
console.log(param.value.provider)
|
||||
// 根据不同的部署类型添加不同的表单配置
|
||||
switch (param.value.provider) {
|
||||
case 'localhost':
|
||||
@@ -198,6 +207,7 @@ export default defineComponent({
|
||||
case 'qiniu-cdn':
|
||||
case 'qiniu-oss':
|
||||
case 'huaweicloud-cdn':
|
||||
case 'doge-cdn':
|
||||
config.push(...formConfig.cdnDeploy())
|
||||
break
|
||||
case 'volcengine-cdn':
|
||||
@@ -215,6 +225,60 @@ export default defineComponent({
|
||||
case 'aliyun-oss':
|
||||
config.push(...formConfig.storageDeploy())
|
||||
break
|
||||
case 'plugin':
|
||||
// 插件部署配置
|
||||
config.push(
|
||||
// ...formConfig.pluginDeploy(param, pluginActionOptions, pluginActionOptionsLoading, pluginActionTips.value),
|
||||
...[
|
||||
formConfig.select('插件方法', 'action', pluginActionOptions.value, {
|
||||
placeholder: '请选择插件方法',
|
||||
filterable: true,
|
||||
clearable: true,
|
||||
loading: pluginActionOptionsLoading.value,
|
||||
onUpdateValue: (value: string, option: FormOption) => {
|
||||
param.value.action = value
|
||||
pluginActionTips.value = renderPluginActionTips(option?.params || {})
|
||||
},
|
||||
}),
|
||||
{
|
||||
type: 'custom' as const,
|
||||
render: () => {
|
||||
return (
|
||||
<NFormItem
|
||||
label="自定义参数"
|
||||
path="params"
|
||||
v-slots={{
|
||||
label: () => (
|
||||
<div>
|
||||
<NText>自定义参数</NText>
|
||||
<NTooltip
|
||||
v-slots={{
|
||||
trigger: () => (
|
||||
<span class="inline-flex ml-2 -mt-1 cursor-pointer text-base rounded-full w-[14px] h-[14px] justify-center items-center text-orange-600 border border-orange-600">
|
||||
?
|
||||
</span>
|
||||
),
|
||||
}}
|
||||
>
|
||||
{pluginActionTips.value}
|
||||
</NTooltip>
|
||||
</div>
|
||||
),
|
||||
}}
|
||||
>
|
||||
<NInput
|
||||
type="textarea"
|
||||
v-model:value={param.value['params']}
|
||||
placeholder={pluginActionTips.value}
|
||||
rows={4}
|
||||
/>
|
||||
</NFormItem>
|
||||
)
|
||||
},
|
||||
},
|
||||
],
|
||||
)
|
||||
break
|
||||
}
|
||||
|
||||
// 添加跳过选项
|
||||
@@ -224,7 +288,13 @@ export default defineComponent({
|
||||
|
||||
watch(
|
||||
() => param.value.provider_id,
|
||||
() => handleSiteSearch(''),
|
||||
() => {
|
||||
handleSiteSearch('')
|
||||
// 如果是插件类型,加载插件方法
|
||||
if (param.value.provider === 'plugin') {
|
||||
loadPluginActions()
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
/**
|
||||
@@ -256,6 +326,47 @@ export default defineComponent({
|
||||
}
|
||||
}, 1000)
|
||||
|
||||
/**
|
||||
* @description 渲染插件方法提示
|
||||
*/
|
||||
const renderPluginActionTips = (tips: Record<string, any>): string => {
|
||||
return '请输入JSON格式的参数,例如: ' + JSON.stringify(tips || {})
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载插件方法
|
||||
*/
|
||||
const loadPluginActions = async (): Promise<void> => {
|
||||
if (!param.value.provider_id) return
|
||||
try {
|
||||
pluginActionOptionsLoading.value = true
|
||||
// 先获取插件列表,找到对应的插件
|
||||
const config = JSON.parse(param.value.provider_data?.data?.config || '{}')
|
||||
if (config.name) {
|
||||
const { data } = await getPlugins().fetch()
|
||||
const selectedPlugin = data?.find((plugin: { name: string }) => plugin.name === config.name)
|
||||
const actions = selectedPlugin?.actions || []
|
||||
pluginActionOptions.value = actions.map((item: any) => ({
|
||||
label: `${item.description}`,
|
||||
value: item.name,
|
||||
params: item.params,
|
||||
}))
|
||||
if (!param.value.action) {
|
||||
const action = actions[0]
|
||||
param.value.action = action?.name
|
||||
pluginActionTips.value = renderPluginActionTips(action?.params || {})
|
||||
}
|
||||
|
||||
delete param.value.provider_data
|
||||
}
|
||||
} catch (error) {
|
||||
handleError(error)
|
||||
pluginActionOptions.value = []
|
||||
} finally {
|
||||
pluginActionOptionsLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 下一步
|
||||
*/
|
||||
@@ -345,6 +456,10 @@ export default defineComponent({
|
||||
}
|
||||
handleSiteSearch('')
|
||||
}
|
||||
// 如果是插件类型,加载插件方法
|
||||
if (param.value.provider === 'plugin') {
|
||||
loadPluginActions()
|
||||
}
|
||||
nextStep()
|
||||
}
|
||||
})
|
||||
|
||||
@@ -60,4 +60,7 @@ export default {
|
||||
// 存储桶相关字段验证
|
||||
region: validator.required('region', $t('t_25_1745735766651'), 'input'),
|
||||
bucket: validator.required('bucket', $t('t_26_1745735767144'), 'input'),
|
||||
|
||||
// 插件相关字段验证
|
||||
action: validator.required('action', '请选择插件方法', 'select'),
|
||||
} as FormRules
|
||||
|
||||
@@ -1,13 +1,28 @@
|
||||
import { defineComponent } from 'vue'
|
||||
import { useCAFormController } from '../useController'
|
||||
|
||||
interface CAManageFormProps {
|
||||
isEdit?: boolean
|
||||
editId?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* CA授权表单组件
|
||||
* ACME账户表单组件
|
||||
*/
|
||||
export default defineComponent({
|
||||
name: 'CAManageForm',
|
||||
setup() {
|
||||
const { CAForm } = useCAFormController()
|
||||
props: {
|
||||
isEdit: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
editId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
setup(props: CAManageFormProps) {
|
||||
const { CAForm } = useCAFormController(props)
|
||||
return () => <CAForm labelPlacement="top" />
|
||||
},
|
||||
})
|
||||
|
||||
@@ -7,7 +7,7 @@ import EmptyState from '@components/TableEmptyState'
|
||||
import BaseComponent from '@components/BaseLayout'
|
||||
|
||||
/**
|
||||
* CA授权管理模态框组件
|
||||
* ACME账户管理模态框组件
|
||||
*/
|
||||
export default defineComponent({
|
||||
name: 'CAManageModal',
|
||||
@@ -18,7 +18,7 @@ export default defineComponent({
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const { CATable, CATablePage, handleOpenAddForm, total } = useCAManageController(props)
|
||||
const { TableComponent, PageComponent, handleOpenAddForm, total } = useCAManageController(props)
|
||||
return () => (
|
||||
<BaseComponent
|
||||
v-slots={{
|
||||
@@ -30,7 +30,7 @@ export default defineComponent({
|
||||
),
|
||||
content: () => (
|
||||
<div class="rounded-lg">
|
||||
<CATable
|
||||
<TableComponent
|
||||
size="medium"
|
||||
v-slots={{
|
||||
empty: () => <EmptyState addButtonText={$t('t_4_1747903685371')} onAddClick={handleOpenAddForm} />,
|
||||
@@ -40,7 +40,7 @@ export default defineComponent({
|
||||
),
|
||||
footerRight: () => (
|
||||
<div class="flex justify-end mt-4">
|
||||
<CATablePage
|
||||
<PageComponent
|
||||
v-slots={{
|
||||
prefix: () => (
|
||||
<span>
|
||||
|
||||
@@ -15,7 +15,7 @@ export default defineComponent({
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const { WorkflowHistoryTable, WorkflowHistoryTablePage, fetch } = useHistoryController(props.id)
|
||||
const { TableComponent, PageComponent, fetch } = useHistoryController(props.id)
|
||||
onMounted(() => {
|
||||
fetch()
|
||||
})
|
||||
@@ -30,8 +30,8 @@ export default defineComponent({
|
||||
</NButton>
|
||||
</div>
|
||||
),
|
||||
content: () => <WorkflowHistoryTable />,
|
||||
footerRight: () => <WorkflowHistoryTablePage />,
|
||||
content: () => <TableComponent />,
|
||||
footerRight: () => <PageComponent />,
|
||||
}}
|
||||
></BaseComponent>
|
||||
</div>
|
||||
|
||||
@@ -16,8 +16,8 @@ export default defineComponent({
|
||||
name: 'WorkflowManager',
|
||||
setup() {
|
||||
const {
|
||||
WorkflowTable,
|
||||
WorkflowTablePage,
|
||||
TableComponent,
|
||||
PageComponent,
|
||||
isDetectionAddWorkflow,
|
||||
isDetectionOpenCAManage,
|
||||
isDetectionOpenAddCAForm,
|
||||
@@ -87,18 +87,19 @@ export default defineComponent({
|
||||
),
|
||||
content: () => (
|
||||
<div class="rounded-lg ">
|
||||
<WorkflowTable size="medium">
|
||||
{{
|
||||
<TableComponent
|
||||
size="medium"
|
||||
v-slots={{
|
||||
empty: () => (
|
||||
<EmptyState addButtonText={$t('t_0_1747047213730')} onAddClick={handleAddWorkflow} />
|
||||
),
|
||||
}}
|
||||
</WorkflowTable>
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
footerRight: () => (
|
||||
<div class="mt-4 flex justify-end">
|
||||
<WorkflowTablePage
|
||||
<PageComponent
|
||||
v-slots={{
|
||||
prefix: () => <span>{$t('t_0_1746773350551', [data.value.total])}</span>,
|
||||
}}
|
||||
|
||||
@@ -1,21 +1,12 @@
|
||||
import { NSwitch, NTag, NButton, NSpace, NFlex, NText, NFormItem, NSelect } from 'naive-ui'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { useStore } from '@autoDeploy/useStore'
|
||||
import {
|
||||
useDialog,
|
||||
useTable,
|
||||
useTablePage,
|
||||
useModal,
|
||||
useFormHooks,
|
||||
useForm,
|
||||
useModalHooks,
|
||||
useMessage,
|
||||
} from '@baota/naive-ui/hooks'
|
||||
import { useDialog, useTable, useModal, useFormHooks, useForm, useModalHooks, useMessage } from '@baota/naive-ui/hooks'
|
||||
import { useStore as useWorkflowViewStore } from '@autoDeploy/children/workflowView/useStore'
|
||||
import { useError } from '@baota/hooks/error'
|
||||
import AddWorkflowModal from './components/WorkflowModal'
|
||||
import HistoryModal from './components/HistoryModal'
|
||||
import HistoryLogsModal from './components/HistoryLogsModal'
|
||||
import HistoryLogsModal from './components/historyLogsModal'
|
||||
import CAManageModal from './components/CAManageModal'
|
||||
import { $t } from '@/locales'
|
||||
import { router } from '@router/index'
|
||||
@@ -41,6 +32,7 @@ const {
|
||||
caFormData,
|
||||
fetchEabList,
|
||||
addNewEab,
|
||||
updateExistingEab,
|
||||
deleteExistingEab,
|
||||
resetCaForm,
|
||||
} = useStore()
|
||||
@@ -127,7 +119,13 @@ export const useController = () => {
|
||||
width: 180,
|
||||
render: (row: WorkflowItem) => row.create_time || '-',
|
||||
},
|
||||
statusCol<WorkflowItem>('last_run_status', $t('t_0_1746677882486')),
|
||||
{
|
||||
title: $t('t_1_1750129254278'),
|
||||
key: 'last_run_time',
|
||||
width: 180,
|
||||
render: (row: WorkflowItem) => row.last_run_time || '-',
|
||||
},
|
||||
statusCol<WorkflowItem>('last_run_status', $t('t_2_1750129253921')),
|
||||
{
|
||||
title: $t('t_8_1745215914610'),
|
||||
key: 'actions',
|
||||
@@ -154,34 +152,15 @@ export const useController = () => {
|
||||
]
|
||||
|
||||
// 表格实例
|
||||
const {
|
||||
component: WorkflowTable,
|
||||
loading,
|
||||
param,
|
||||
data,
|
||||
total,
|
||||
fetch,
|
||||
} = useTable<WorkflowItem, WorkflowListParams>({
|
||||
const { TableComponent, PageComponent, loading, param, data, fetch } = useTable<WorkflowItem, WorkflowListParams>({
|
||||
config: createColumns(),
|
||||
request: fetchWorkflowList,
|
||||
defaultValue: {
|
||||
p: 1,
|
||||
limit: 10,
|
||||
search: '',
|
||||
},
|
||||
storage: 'autoDeployPageSize',
|
||||
defaultValue: { p: 1, limit: 10, search: '' },
|
||||
alias: { page: 'p', pageSize: 'limit' },
|
||||
watchValue: ['p', 'limit'],
|
||||
})
|
||||
|
||||
// 分页实例
|
||||
const { component: WorkflowTablePage } = useTablePage({
|
||||
param,
|
||||
total,
|
||||
alias: {
|
||||
page: 'p',
|
||||
pageSize: 'limit',
|
||||
},
|
||||
})
|
||||
|
||||
// 节流渲染
|
||||
const throttleFn = useThrottleFn(() => {
|
||||
setTimeout(() => {
|
||||
@@ -354,8 +333,8 @@ export const useController = () => {
|
||||
}
|
||||
|
||||
return {
|
||||
WorkflowTable,
|
||||
WorkflowTablePage,
|
||||
TableComponent,
|
||||
PageComponent,
|
||||
isDetectionAddWorkflow, // 检测是否需要添加工作流
|
||||
isDetectionOpenCAManage, // 检测是否需要打开CA授权管理弹窗
|
||||
isDetectionOpenAddCAForm, // 检测是否需要打开添加CA授权弹窗
|
||||
@@ -502,40 +481,33 @@ export const useHistoryController = (id: string) => {
|
||||
]
|
||||
|
||||
// 表格实例
|
||||
const {
|
||||
component: WorkflowHistoryTable,
|
||||
loading,
|
||||
param,
|
||||
total,
|
||||
fetch,
|
||||
} = useTable<WorkflowHistoryItem, WorkflowHistoryParams>({
|
||||
const { TableComponent, PageComponent, loading, fetch } = useTable<WorkflowHistoryItem, WorkflowHistoryParams>({
|
||||
config: createColumns(),
|
||||
request: fetchWorkflowHistory,
|
||||
defaultValue: {
|
||||
id,
|
||||
p: 1,
|
||||
limit: 10,
|
||||
},
|
||||
defaultValue: { id, p: 1, limit: 10 },
|
||||
alias: { page: 'p', pageSize: 'limit' },
|
||||
watchValue: ['p', 'limit'],
|
||||
})
|
||||
|
||||
const { component: WorkflowHistoryTablePage } = useTablePage({
|
||||
param,
|
||||
total,
|
||||
alias: {
|
||||
page: 'p',
|
||||
pageSize: 'limit',
|
||||
},
|
||||
storage: 'autoDeployHistoryPageSize',
|
||||
})
|
||||
|
||||
return {
|
||||
WorkflowHistoryTable,
|
||||
WorkflowHistoryTablePage,
|
||||
TableComponent,
|
||||
PageComponent,
|
||||
loading,
|
||||
fetch,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 处理CA授权类型
|
||||
* @param type - CA授权类型
|
||||
* @returns 返回CA授权类型名称
|
||||
*/
|
||||
const handleCertAuth = (type: string) => {
|
||||
const name = type.replaceAll('.', '').replaceAll("'", '').replaceAll(' ', '').toLowerCase() // 处理类型中的特殊字符
|
||||
return CACertificateAuthorization[name as keyof typeof CACertificateAuthorization].type
|
||||
}
|
||||
|
||||
/**
|
||||
* @description CA授权管理业务逻辑控制器
|
||||
* @returns {Object} 返回CA授权管理控制器对象
|
||||
@@ -543,17 +515,10 @@ export const useHistoryController = (id: string) => {
|
||||
export const useCAManageController = (props: { type: string }) => {
|
||||
const { handleError } = useError()
|
||||
// 表格配置
|
||||
const columns = [
|
||||
{
|
||||
title: $t('t_2_1745289353944'),
|
||||
key: 'name',
|
||||
ellipsis: {
|
||||
tooltip: true,
|
||||
},
|
||||
},
|
||||
const columns: DataTableColumn<EabItem>[] = [
|
||||
{
|
||||
title: $t('t_1_1745735764953'),
|
||||
key: 'mail',
|
||||
key: 'email',
|
||||
ellipsis: {
|
||||
tooltip: true,
|
||||
},
|
||||
@@ -561,13 +526,16 @@ export const useCAManageController = (props: { type: string }) => {
|
||||
{
|
||||
title: $t('t_9_1747903669360'),
|
||||
key: 'ca',
|
||||
width: 120,
|
||||
render: (row: EabItem) => (
|
||||
<NFlex align="center">
|
||||
<SvgIcon icon={`cert-${row.ca}`} size="2rem" />
|
||||
<NText>{CACertificateAuthorization[row.ca as keyof typeof CACertificateAuthorization].name}</NText>
|
||||
</NFlex>
|
||||
),
|
||||
width: 200,
|
||||
render: (row: EabItem) => {
|
||||
const name = handleCertAuth(row.ca)
|
||||
return (
|
||||
<NFlex align="center">
|
||||
<SvgIcon icon={`cert-${name}`} size="2rem" />
|
||||
<NText>{name}</NText>
|
||||
</NFlex>
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
title: $t('t_7_1745215914189'),
|
||||
@@ -578,11 +546,14 @@ export const useCAManageController = (props: { type: string }) => {
|
||||
{
|
||||
title: $t('t_8_1745215914610'),
|
||||
key: 'actions',
|
||||
width: 80,
|
||||
width: 120,
|
||||
align: 'right' as const,
|
||||
fixed: 'right' as const,
|
||||
render: (row: EabItem) => (
|
||||
<NSpace justify="end">
|
||||
<NButton size="tiny" strong secondary type="primary" onClick={() => handleEdit(row)}>
|
||||
{$t('t_11_1745215915429')}
|
||||
</NButton>
|
||||
<NButton size="tiny" strong secondary type="error" onClick={() => confirmDelete(row.id.toString())}>
|
||||
{$t('t_12_1745215914312')}
|
||||
</NButton>
|
||||
@@ -592,31 +563,24 @@ export const useCAManageController = (props: { type: string }) => {
|
||||
]
|
||||
|
||||
// 表格实例
|
||||
const {
|
||||
component: CATable,
|
||||
loading,
|
||||
param,
|
||||
total,
|
||||
fetch,
|
||||
} = useTable<EabItem, EabListParams>({
|
||||
const { TableComponent, PageComponent, loading, param, total, fetch } = useTable<EabItem, EabListParams>({
|
||||
config: columns,
|
||||
request: fetchEabList,
|
||||
defaultValue: {
|
||||
p: 1,
|
||||
limit: 10,
|
||||
},
|
||||
defaultValue: { p: 1, limit: 10 },
|
||||
alias: { page: 'p', pageSize: 'limit' },
|
||||
watchValue: ['p', 'limit'],
|
||||
storage: 'caManagePageSize',
|
||||
})
|
||||
|
||||
// 分页实例
|
||||
const { component: CATablePage } = useTablePage({
|
||||
param,
|
||||
total,
|
||||
alias: {
|
||||
page: 'p',
|
||||
pageSize: 'limit',
|
||||
},
|
||||
})
|
||||
// // 分页实例
|
||||
// const { component: CATablePage } = useTablePage({
|
||||
// param,
|
||||
// total,
|
||||
// alias: {
|
||||
// page: 'p',
|
||||
// pageSize: 'limit',
|
||||
// },
|
||||
// })
|
||||
|
||||
/**
|
||||
* 确认删除CA授权
|
||||
@@ -637,6 +601,31 @@ export const useCAManageController = (props: { type: string }) => {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑CA授权
|
||||
* @param {EabItem} row - CA授权数据
|
||||
*/
|
||||
const handleEdit = (row: EabItem) => {
|
||||
// 填充表单数据 - 添加编辑模式标识
|
||||
Object.assign(caFormData.value, {
|
||||
email: row.email,
|
||||
ca: row.ca,
|
||||
Kid: row.Kid || '',
|
||||
HmacEncoded: row.HmacEncoded || '',
|
||||
CADirURL: row.CADirURL || '',
|
||||
})
|
||||
useModal({
|
||||
title: $t('t_3_1750129254533'),
|
||||
area: 500,
|
||||
component: () => import('./components/CAManageForm').then((m) => m.default),
|
||||
footer: true,
|
||||
componentProps: { isEdit: true, editId: row.id.toString() },
|
||||
onUpdateShow: (show) => {
|
||||
if (!show) fetch()
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开添加CA授权表单
|
||||
*/
|
||||
@@ -660,13 +649,14 @@ export const useCAManageController = (props: { type: string }) => {
|
||||
})
|
||||
|
||||
return {
|
||||
CATable,
|
||||
CATablePage,
|
||||
TableComponent,
|
||||
PageComponent,
|
||||
loading,
|
||||
param,
|
||||
total,
|
||||
fetch,
|
||||
handleOpenAddForm,
|
||||
handleEdit,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -674,46 +664,60 @@ export const useCAManageController = (props: { type: string }) => {
|
||||
* @description CA授权表单控制器
|
||||
* @returns {Object} 返回CA授权表单控制器对象
|
||||
*/
|
||||
export const useCAFormController = () => {
|
||||
export const useCAFormController = (props?: { isEdit?: boolean; editId?: string }) => {
|
||||
const { handleError } = useError()
|
||||
const message = useMessage()
|
||||
const { confirm } = useModalHooks()
|
||||
const { useFormInput, useFormCustom } = useFormHooks()
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = {
|
||||
name: {
|
||||
required: true,
|
||||
message: $t('t_25_1746773349596'),
|
||||
trigger: ['blur', 'input'],
|
||||
},
|
||||
mail: {
|
||||
required: true,
|
||||
message: $t('t_6_1747817644358'),
|
||||
trigger: ['blur', 'input'],
|
||||
validator: (rule: any, value: string) => {
|
||||
if (!value) return true
|
||||
if (!isEmail(value)) {
|
||||
return new Error($t('t_7_1747817613773'))
|
||||
}
|
||||
return true
|
||||
// 动态验证规则
|
||||
const getFormRules = () => {
|
||||
const rules: any = {
|
||||
email: {
|
||||
required: true,
|
||||
message: $t('t_6_1747817644358'),
|
||||
trigger: ['blur', 'input'],
|
||||
validator: (rule: any, value: string) => {
|
||||
if (!value) return new Error($t('t_6_1747817644358'))
|
||||
if (!isEmail(value)) {
|
||||
return new Error($t('t_7_1747817613773'))
|
||||
}
|
||||
return true
|
||||
},
|
||||
},
|
||||
},
|
||||
Kid: {
|
||||
required: true,
|
||||
message: $t('t_5_1747903671439'),
|
||||
trigger: ['blur', 'input'],
|
||||
},
|
||||
HmacEncoded: {
|
||||
required: true,
|
||||
message: $t('t_6_1747903672931'),
|
||||
trigger: ['blur', 'input'],
|
||||
},
|
||||
ca: {
|
||||
required: true,
|
||||
message: $t('t_7_1747903678624'),
|
||||
trigger: 'change',
|
||||
},
|
||||
ca: {
|
||||
required: true,
|
||||
message: $t('t_7_1747903678624'),
|
||||
trigger: 'change',
|
||||
},
|
||||
}
|
||||
|
||||
const currentCa = caFormData.value.ca
|
||||
|
||||
// SSL.com 和 Google 必填 EAB 参数
|
||||
if (currentCa === 'sslcom' || currentCa === 'google') {
|
||||
rules.Kid = {
|
||||
required: true,
|
||||
message: $t('t_5_1747903671439'),
|
||||
trigger: ['blur', 'input'],
|
||||
}
|
||||
rules.HmacEncoded = {
|
||||
required: true,
|
||||
message: $t('t_6_1747903672931'),
|
||||
trigger: ['blur', 'input'],
|
||||
}
|
||||
}
|
||||
|
||||
// 自定义类型必填 CADirURL
|
||||
if (currentCa === 'custom') {
|
||||
rules.CADirURL = {
|
||||
required: true,
|
||||
message: $t('t_4_1750129259795'),
|
||||
trigger: ['blur', 'input'],
|
||||
}
|
||||
}
|
||||
|
||||
return rules
|
||||
}
|
||||
|
||||
// 渲染标签函数
|
||||
@@ -745,12 +749,27 @@ export const useCAFormController = () => {
|
||||
value: item.type,
|
||||
}))
|
||||
|
||||
// 判断是否显示EAB字段
|
||||
const shouldShowEab = computed(() => {
|
||||
const ca = caFormData.value.ca
|
||||
// Buypass和Letsencrypt不显示EAB字段
|
||||
return ca !== 'buypass' && ca !== 'letsencrypt'
|
||||
})
|
||||
|
||||
// 判断是否显示CADirURL字段
|
||||
const shouldShowCADirURL = computed(() => {
|
||||
return caFormData.value.ca === 'custom'
|
||||
})
|
||||
|
||||
// 判断是否显示必填标记
|
||||
const shouldShowRequireMark = computed(() => {
|
||||
const ca = caFormData.value.ca
|
||||
return ca !== 'zerossl' && ca !== 'custom'
|
||||
})
|
||||
|
||||
// 表单配置
|
||||
const formConfig = [
|
||||
useFormInput($t('t_2_1745289353944'), 'name', {
|
||||
placeholder: $t('t_8_1747903675532'),
|
||||
}),
|
||||
useFormInput($t('t_1_1745735764953'), 'mail', {
|
||||
const formConfig = computed(() => [
|
||||
useFormInput($t('t_1_1745735764953'), 'email', {
|
||||
placeholder: $t('t_0_1747965909665'),
|
||||
}),
|
||||
useFormCustom(() => {
|
||||
@@ -773,21 +792,49 @@ export const useCAFormController = () => {
|
||||
</NFormItem>
|
||||
)
|
||||
}),
|
||||
useFormInput($t('t_10_1747903662994'), 'Kid', {
|
||||
placeholder: $t('t_11_1747903674802'),
|
||||
}),
|
||||
useFormInput($t('t_12_1747903662994'), 'HmacEncoded', {
|
||||
type: 'textarea',
|
||||
placeholder: $t('t_13_1747903673007'),
|
||||
rows: 3,
|
||||
}),
|
||||
]
|
||||
// 条件显示CADirURL字段
|
||||
...(shouldShowCADirURL.value
|
||||
? [
|
||||
useFormInput($t('t_5_1750129253961'), 'CADirURL', {
|
||||
placeholder: $t('t_6_1750129255766'),
|
||||
}),
|
||||
]
|
||||
: []),
|
||||
// 条件显示EAB字段
|
||||
...(shouldShowEab.value
|
||||
? [
|
||||
useFormInput(
|
||||
$t('t_10_1747903662994'),
|
||||
'Kid',
|
||||
{
|
||||
placeholder: $t('t_11_1747903674802'),
|
||||
},
|
||||
{ showRequireMark: shouldShowRequireMark.value },
|
||||
),
|
||||
useFormInput(
|
||||
$t('t_12_1747903662994'),
|
||||
'HmacEncoded',
|
||||
{
|
||||
type: 'textarea',
|
||||
placeholder: $t('t_13_1747903673007'),
|
||||
rows: 3,
|
||||
},
|
||||
{ showRequireMark: shouldShowRequireMark.value },
|
||||
),
|
||||
]
|
||||
: []),
|
||||
])
|
||||
|
||||
// 提交表单
|
||||
const submitForm = async (formData: any) => {
|
||||
try {
|
||||
await addNewEab(formData)
|
||||
message.success($t('t_40_1745289355715'))
|
||||
if (props?.isEdit && props?.editId) {
|
||||
// 编辑模式
|
||||
await updateExistingEab({ ...formData, id: props.editId })
|
||||
} else {
|
||||
// 新增模式
|
||||
await addNewEab(formData)
|
||||
}
|
||||
return true
|
||||
} catch (error) {
|
||||
handleError(error)
|
||||
@@ -798,7 +845,7 @@ export const useCAFormController = () => {
|
||||
// 表单实例
|
||||
const { component: CAForm } = useForm({
|
||||
config: formConfig,
|
||||
rules: formRules,
|
||||
rules: getFormRules(),
|
||||
defaultValue: caFormData,
|
||||
request: submitForm,
|
||||
})
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
enableWorkflow,
|
||||
stopWorkflow,
|
||||
} from '@/api/workflow'
|
||||
import { getEabList, addEab, deleteEab } from '@/api/access'
|
||||
import { getEabList, addEab, deleteEab, updateEab } from '@/api/access'
|
||||
import { useError } from '@baota/hooks/error'
|
||||
// import { useMessage } from '@baota/naive-ui/hooks'
|
||||
import { $t } from '@locales/index'
|
||||
@@ -18,9 +18,8 @@ import type {
|
||||
WorkflowItem,
|
||||
UpdateWorkflowExecTypeParams,
|
||||
EnableWorkflowParams,
|
||||
StopWorkflowParams,
|
||||
} from '@/types/workflow'
|
||||
import type { EabItem, EabListParams, EabAddParams } from '@/types/access'
|
||||
import type { EabItem, EabListParams, EabAddParams, EabUpdateParams } from '@/types/access'
|
||||
import type { TableResponse } from '@baota/naive-ui/types/table'
|
||||
|
||||
const { handleError } = useError()
|
||||
@@ -46,12 +45,13 @@ export const useWorkflowStore = defineStore('workflow-store', () => {
|
||||
])
|
||||
|
||||
// CA授权管理相关数据
|
||||
// CA授权表单数据
|
||||
const caFormData = ref<EabAddParams>({
|
||||
name: '',
|
||||
// ACME账户表单数据
|
||||
const caFormData = ref<EabAddParams & { id?: string }>({
|
||||
email: '',
|
||||
Kid: '',
|
||||
HmacEncoded: '',
|
||||
ca: 'zerossl',
|
||||
CADirURL: '',
|
||||
})
|
||||
|
||||
// -------------------- 工具方法 --------------------
|
||||
@@ -196,6 +196,21 @@ export const useWorkflowStore = defineStore('workflow-store', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新CA授权
|
||||
* @param {EabUpdateParams} params - CA授权更新数据
|
||||
*/
|
||||
const updateExistingEab = async (formData: EabUpdateParams): Promise<void> => {
|
||||
try {
|
||||
const { message, fetch } = updateEab(formData)
|
||||
message.value = true
|
||||
await fetch()
|
||||
resetCaForm() // 重置表单
|
||||
} catch (error) {
|
||||
handleError(error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除CA授权
|
||||
* @param {string} id - CA授权ID
|
||||
@@ -211,14 +226,15 @@ export const useWorkflowStore = defineStore('workflow-store', () => {
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置CA表单
|
||||
* 重置ACME账户表单
|
||||
*/
|
||||
const resetCaForm = () => {
|
||||
caFormData.value = {
|
||||
name: '',
|
||||
email: '',
|
||||
Kid: '',
|
||||
HmacEncoded: '',
|
||||
ca: 'zerossl',
|
||||
CADirURL: '',
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,6 +256,7 @@ export const useWorkflowStore = defineStore('workflow-store', () => {
|
||||
setWorkflowExecType,
|
||||
fetchEabList,
|
||||
addNewEab,
|
||||
updateExistingEab,
|
||||
deleteExistingEab,
|
||||
resetCaForm,
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import EmptyState from '@components/TableEmptyState'
|
||||
export default defineComponent({
|
||||
name: 'CertManage',
|
||||
setup() {
|
||||
const { CertTable, CertTablePage, fetch, data, param, openUploadModal, getRowClassName } = useController()
|
||||
const { TableComponent, PageComponent, fetch, data, param, openUploadModal, getRowClassName } = useController()
|
||||
const cssVar = useThemeCssVar(['contentPadding', 'borderColor', 'headerHeight', 'iconColorHover'])
|
||||
// 挂载时请求数据
|
||||
onMounted(() => fetch())
|
||||
@@ -51,16 +51,18 @@ export default defineComponent({
|
||||
),
|
||||
content: () => (
|
||||
<div class="rounded-lg">
|
||||
<CertTable size="medium" rowClassName={getRowClassName}>
|
||||
{{
|
||||
<TableComponent
|
||||
size="medium"
|
||||
rowClassName={getRowClassName}
|
||||
v-slots={{
|
||||
empty: () => <EmptyState addButtonText={$t('t_1_1747047213009')} onAddClick={openUploadModal} />,
|
||||
}}
|
||||
</CertTable>
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
footerRight: () => (
|
||||
<div class="mt-4 flex justify-end">
|
||||
<CertTablePage
|
||||
<PageComponent
|
||||
v-slots={{
|
||||
prefix: () => (
|
||||
<span>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { NButton, NSpace, NTag, useMessage, type DataTableColumns } from 'naive-ui'
|
||||
import { NButton, NSpace, NTag, type DataTableColumns } from 'naive-ui'
|
||||
import {
|
||||
useModal,
|
||||
useTable,
|
||||
useTablePage,
|
||||
useDialog,
|
||||
useFormHooks,
|
||||
useModalHooks,
|
||||
useForm,
|
||||
useLoadingMask,
|
||||
useMessage,
|
||||
} from '@baota/naive-ui/hooks'
|
||||
import { useError } from '@baota/hooks/error'
|
||||
import { $t } from '@locales/index'
|
||||
@@ -126,32 +126,13 @@ export const useController = () => {
|
||||
}
|
||||
|
||||
// 表格实例
|
||||
const {
|
||||
component: CertTable,
|
||||
loading,
|
||||
param,
|
||||
data,
|
||||
total,
|
||||
fetch,
|
||||
} = useTable<CertItem, CertListParams>({
|
||||
const { TableComponent, PageComponent, loading, param, data, fetch } = useTable<CertItem, CertListParams>({
|
||||
config: createColumns(),
|
||||
request: fetchCertList,
|
||||
defaultValue: {
|
||||
p: 1,
|
||||
limit: 10,
|
||||
search: '',
|
||||
},
|
||||
defaultValue: { p: 1, limit: 10, search: '' },
|
||||
alias: { page: 'p', pageSize: 'limit' },
|
||||
watchValue: ['p', 'limit'],
|
||||
})
|
||||
|
||||
// 分页实例
|
||||
const { component: CertTablePage } = useTablePage({
|
||||
param,
|
||||
total,
|
||||
alias: {
|
||||
page: 'p',
|
||||
pageSize: 'limit',
|
||||
},
|
||||
storage: 'certManagePageSize',
|
||||
})
|
||||
|
||||
/**
|
||||
@@ -211,8 +192,8 @@ export const useController = () => {
|
||||
return {
|
||||
loading,
|
||||
fetch,
|
||||
CertTable,
|
||||
CertTablePage,
|
||||
TableComponent,
|
||||
PageComponent,
|
||||
getRowClassName,
|
||||
param,
|
||||
data,
|
||||
|
||||
@@ -129,9 +129,9 @@ export const useLayoutStore = defineStore('layout-store', (): LayoutStoreInterfa
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取DNS提供商
|
||||
* @description 获取提供商
|
||||
* @param type - 类型 (简化了联合类型,实际使用时可根据需要定义更精确的类型别名)
|
||||
* @returns DNS提供商
|
||||
* @returns 提供商
|
||||
*/
|
||||
const fetchDnsProvider = async (type: string = ''): Promise<void> => {
|
||||
try {
|
||||
@@ -142,6 +142,7 @@ export const useLayoutStore = defineStore('layout-store', (): LayoutStoreInterfa
|
||||
label: item.name,
|
||||
value: item.id.toString(),
|
||||
type: item.type,
|
||||
data: item,
|
||||
})) || []
|
||||
} catch (error) {
|
||||
dnsProvider.value = []
|
||||
|
||||
@@ -18,7 +18,7 @@ export default defineComponent({
|
||||
name: 'MonitorManage',
|
||||
setup() {
|
||||
// 使用控制器获取数据和方法
|
||||
const { MonitorTable, MonitorTablePage, param, fetch, data, openAddForm, isDetectionAddMonitor } = useController()
|
||||
const { TableComponent, PageComponent, param, fetch, data, openAddForm, isDetectionAddMonitor } = useController()
|
||||
|
||||
// 获取主题CSS变量
|
||||
const cssVar = useThemeCssVar(['contentPadding', 'borderColor', 'headerHeight', 'iconColorHover'])
|
||||
@@ -67,17 +67,18 @@ export default defineComponent({
|
||||
// 内容区域 - 监控表格
|
||||
content: () => (
|
||||
<div class="rounded-lg">
|
||||
<MonitorTable size="medium">
|
||||
{{
|
||||
<TableComponent
|
||||
size="medium"
|
||||
v-slots={{
|
||||
empty: () => <EmptyState addButtonText={$t('t_11_1745289354516')} onAddClick={openAddForm} />,
|
||||
}}
|
||||
</MonitorTable>
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
// 底部右侧区域 - 分页组件
|
||||
footerRight: () => (
|
||||
<div class="mt-4 flex justify-end">
|
||||
<MonitorTablePage
|
||||
<PageComponent
|
||||
v-slots={{
|
||||
prefix: () => (
|
||||
<span>
|
||||
|
||||
@@ -6,7 +6,6 @@ import { FormRules, NButton, NSpace, NSwitch, type DataTableColumns } from 'naiv
|
||||
import {
|
||||
useModal,
|
||||
useTable,
|
||||
useTablePage,
|
||||
useDialog,
|
||||
useModalHooks,
|
||||
useForm,
|
||||
@@ -37,8 +36,8 @@ import type {
|
||||
*/
|
||||
interface MonitorControllerExposes {
|
||||
// 表格相关
|
||||
MonitorTable: ReturnType<typeof useTable>['component']
|
||||
MonitorTablePage: ReturnType<typeof useTablePage>['component']
|
||||
TableComponent: ReturnType<typeof useTable>['TableComponent']
|
||||
PageComponent: ReturnType<typeof useTable>['PageComponent']
|
||||
loading: Ref<boolean>
|
||||
param: Ref<SiteMonitorListParams>
|
||||
data: Ref<{ list: SiteMonitorItem[]; total: number }>
|
||||
@@ -197,36 +196,27 @@ export const useController = (): MonitorControllerExposes => {
|
||||
* 表格实例
|
||||
* @description 创建表格实例并管理相关状态
|
||||
*/
|
||||
const {
|
||||
component: MonitorTable,
|
||||
loading,
|
||||
param,
|
||||
data,
|
||||
total,
|
||||
fetch,
|
||||
} = useTable<SiteMonitorItem, SiteMonitorListParams>({
|
||||
const { TableComponent, PageComponent, loading, param, data, total, fetch } = useTable<
|
||||
SiteMonitorItem,
|
||||
SiteMonitorListParams
|
||||
>({
|
||||
config: createColumns(),
|
||||
request: fetchMonitorList,
|
||||
defaultValue: {
|
||||
p: 1,
|
||||
limit: 10,
|
||||
search: '',
|
||||
},
|
||||
defaultValue: { p: 1, limit: 10, search: '' },
|
||||
alias: { page: 'p', pageSize: 'limit' },
|
||||
watchValue: ['p', 'limit'],
|
||||
storage: 'monitorPageSize',
|
||||
})
|
||||
|
||||
/**
|
||||
* 分页实例
|
||||
* @description 创建表格分页组件
|
||||
*/
|
||||
const { component: MonitorTablePage } = useTablePage({
|
||||
param,
|
||||
total,
|
||||
alias: {
|
||||
page: 'p',
|
||||
pageSize: 'limit',
|
||||
},
|
||||
})
|
||||
// /**
|
||||
// * 分页实例
|
||||
// * @description 创建表格分页组件
|
||||
// */
|
||||
// const { component: MonitorTablePage } = useTablePage({
|
||||
// param,
|
||||
// total,
|
||||
// ,
|
||||
// })
|
||||
|
||||
/**
|
||||
* 打开添加监控弹窗
|
||||
@@ -305,8 +295,8 @@ export const useController = (): MonitorControllerExposes => {
|
||||
return {
|
||||
loading,
|
||||
fetch,
|
||||
MonitorTable,
|
||||
MonitorTablePage,
|
||||
TableComponent,
|
||||
PageComponent,
|
||||
isDetectionAddMonitor,
|
||||
param,
|
||||
data,
|
||||
|
||||
Reference in New Issue
Block a user