mirror of
https://gitee.com/mirrors/AllinSSL.git
synced 2026-03-11 09:11:10 +08:00
【新增】部署类型七牛云oss、七牛云cdn、百度cdn、腾讯waf、腾讯edgeone、阿里云waf
【新增】解析类型godaddy 【新增】自定义CA授权管理 【调整】优化部署流程,减少代码冗余,提升类型添加效率
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
import { defineComponent, PropType, VNode } from 'vue'
|
||||
import { NButton, NFormItemGi, NGrid, NSelect, NText, NSpin, NFlex } from 'naive-ui'
|
||||
|
||||
// 类型导入
|
||||
import type { CAProviderSelectProps, CAProviderOption, CAProviderSelectEmits } from './types'
|
||||
|
||||
// 绝对内部导入 - Controller
|
||||
import { useCAProviderSelectController } from './useController'
|
||||
// 绝对内部导入 - Components
|
||||
import SvgIcon from '@components/SvgIcon'
|
||||
// 绝对内部导入 - Utilities
|
||||
import { $t } from '@locales/index'
|
||||
|
||||
/**
|
||||
* @component CAProviderSelect
|
||||
* @description CA授权选择组件,支持选择Let's Encrypt和其他CA授权,并提供跳转到CA授权管理页面的功能。
|
||||
* 遵循 MVC/MV* 模式,将业务逻辑、状态管理与视图渲染分离。
|
||||
*
|
||||
* @example 基础使用
|
||||
* <CAProviderSelect
|
||||
* path="form.eabId"
|
||||
* v-model:value="formValue.eabId"
|
||||
* v-model:ca="formValue.ca"
|
||||
* />
|
||||
*
|
||||
* @property {string} path - 表单路径,用于表单校验。
|
||||
* @property {string} value - 当前选中的值 (通过 v-model:value 绑定)。
|
||||
* @property {string} ca - 当前选中的CA类型 (通过 v-model:ca 绑定)。
|
||||
* @property {boolean} [disabled=false] - 是否禁用。
|
||||
* @property {string} [customClass] - 自定义CSS类名。
|
||||
*
|
||||
* @emits update:value - (value: { value: string; ca: string }) 当选择的CA授权变更时触发,传递值和CA类型。
|
||||
*/
|
||||
export default defineComponent<CAProviderSelectProps>({
|
||||
name: 'CAProviderSelect',
|
||||
props: {
|
||||
path: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: '',
|
||||
},
|
||||
ca: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
customClass: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
emits: {
|
||||
'update:value': (value: { value: string; ca: string }) => true,
|
||||
},
|
||||
setup(props: CAProviderSelectProps, { emit }: { emit: CAProviderSelectEmits }) {
|
||||
const {
|
||||
isLoading,
|
||||
caProviderRef,
|
||||
param,
|
||||
handleUpdateValue,
|
||||
handleFilter,
|
||||
goToAddCAProvider,
|
||||
errorMessage,
|
||||
loadCAProviders,
|
||||
} = useCAProviderSelectController(props, emit)
|
||||
|
||||
/**
|
||||
* 渲染标签
|
||||
* @param option - 选项
|
||||
* @returns 渲染后的VNode
|
||||
*/
|
||||
const renderLabel = (option: CAProviderOption): VNode => {
|
||||
return (
|
||||
<NFlex align="center">
|
||||
<SvgIcon icon={`cert-${option.ca}`} size="2rem" />
|
||||
<NText>{option.label}</NText>
|
||||
</NFlex>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染单选标签
|
||||
* @param option - 选项 (Record<string, any> 来自 naive-ui 的类型)
|
||||
* @returns 渲染后的VNode
|
||||
*/
|
||||
const renderSingleSelectTag = ({ option }: { option: CAProviderOption }): VNode => {
|
||||
return (
|
||||
<div class="flex items-center">
|
||||
{option.label ? renderLabel(option) : <NText class="text-[#aaa]">{$t('t_0_1747990228780')}</NText>}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return () => (
|
||||
<NSpin show={isLoading.value}>
|
||||
<NGrid cols={24} class={props.customClass}>
|
||||
<NFormItemGi span={13} label={$t('t_1_1747990228492')} path={props.path}>
|
||||
<NSelect
|
||||
class="flex-1 w-full"
|
||||
options={caProviderRef.value}
|
||||
renderLabel={renderLabel}
|
||||
renderTag={({ option }: { option: any }) => renderSingleSelectTag({ option: option as CAProviderOption })}
|
||||
filterable
|
||||
filter={(pattern: string, option: any) => handleFilter(pattern, option as CAProviderOption)}
|
||||
placeholder={$t('t_0_1747990228780')}
|
||||
value={param.value.value} // 使用 controller 中的 param.value.value
|
||||
onUpdateValue={handleUpdateValue}
|
||||
disabled={props.disabled}
|
||||
v-slots={{
|
||||
header: () => {
|
||||
return (
|
||||
<div
|
||||
class="flex items-center cursor-pointer hover:text-[#333] hover:bg-[#eee]"
|
||||
onClick={goToAddCAProvider}
|
||||
>
|
||||
{$t('t_0_1747990626044')}
|
||||
</div>
|
||||
)
|
||||
},
|
||||
empty: () => {
|
||||
return <span class="text-[1.4rem]">{errorMessage.value || $t('t_2_1747990228008')}</span>
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</NFormItemGi>
|
||||
<NFormItemGi span={11}>
|
||||
<NButton class="mx-[8px]" onClick={goToAddCAProvider} disabled={props.disabled}>
|
||||
{$t('t_0_1747903670020')}
|
||||
</NButton>
|
||||
<NButton
|
||||
class="mx-[8px]"
|
||||
onClick={() => loadCAProviders()}
|
||||
loading={isLoading.value}
|
||||
disabled={props.disabled}
|
||||
>
|
||||
{$t('t_0_1746497662220')}
|
||||
</NButton>
|
||||
</NFormItemGi>
|
||||
</NGrid>
|
||||
</NSpin>
|
||||
)
|
||||
},
|
||||
})
|
||||
65
frontend/apps/allin-ssl/src/components/CAProviderSelect/types.d.ts
vendored
Normal file
65
frontend/apps/allin-ssl/src/components/CAProviderSelect/types.d.ts
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* @interface CAProviderOption
|
||||
* @description CA授权选项的结构
|
||||
*/
|
||||
export interface CAProviderOption {
|
||||
label: string
|
||||
value: string
|
||||
ca: string
|
||||
}
|
||||
|
||||
/**
|
||||
* @interface CAProviderSelectProps
|
||||
* @description CAProviderSelect 组件的 Props 定义
|
||||
*/
|
||||
export interface CAProviderSelectProps {
|
||||
/**
|
||||
* @property path
|
||||
* @description 表单路径,用于 naive-ui 表单校验
|
||||
*/
|
||||
path: string
|
||||
/**
|
||||
* @property value
|
||||
* @description 当前选中的值
|
||||
*/
|
||||
value: string
|
||||
/**
|
||||
* @property ca
|
||||
* @description 当前选中的CA类型
|
||||
*/
|
||||
ca: string
|
||||
/**
|
||||
* @property disabled
|
||||
* @description 是否禁用选择器
|
||||
* @default false
|
||||
*/
|
||||
disabled?: boolean
|
||||
/**
|
||||
* @property customClass
|
||||
* @description 自定义CSS类名,应用于 NGrid 组件
|
||||
*/
|
||||
customClass?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* @interface CAProviderSelectEmits
|
||||
* @description CAProviderSelect 组件的 Emits 定义
|
||||
*/
|
||||
export interface CAProviderSelectEmits {
|
||||
(e: 'update:value', value: { value: string; ca: string }): void
|
||||
}
|
||||
|
||||
/**
|
||||
* @interface CAProviderControllerExposes
|
||||
* @description useCAProviderSelectController 返回对象的类型接口
|
||||
*/
|
||||
export interface CAProviderControllerExposes {
|
||||
param: import('vue').Ref<CAProviderOption>
|
||||
caProviderRef: import('vue').Ref<CAProviderOption[]>
|
||||
isLoading: import('vue').Ref<boolean>
|
||||
errorMessage: import('vue').Ref<string>
|
||||
goToAddCAProvider: () => void
|
||||
handleUpdateValue: (value: string) => void
|
||||
loadCAProviders: () => Promise<void>
|
||||
handleFilter: (pattern: string, option: CAProviderOption) => boolean
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
import { ref, watch, onMounted } from 'vue'
|
||||
import type { CAProviderSelectProps, CAProviderOption, CAProviderSelectEmits } from './types'
|
||||
|
||||
// 绝对内部导入 - API
|
||||
import { getAllEabList } from '@api/access'
|
||||
// 绝对内部导入 - Hooks
|
||||
import { useError } from '@baota/hooks/error'
|
||||
// 绝对内部导入 - Utilities
|
||||
import { $t } from '@locales/index'
|
||||
|
||||
/**
|
||||
* @function useCAProviderSelectController
|
||||
* @description CAProviderSelect 组件的控制器逻辑
|
||||
* @param props - 组件的 props
|
||||
* @param emit - 组件的 emit 函数
|
||||
* @returns {CAProviderControllerExposes} 控制器暴露给视图的数据和方法
|
||||
*/
|
||||
export function useCAProviderSelectController(props: CAProviderSelectProps, emit: CAProviderSelectEmits) {
|
||||
const { handleError } = useError()
|
||||
|
||||
const param = ref<CAProviderOption>({
|
||||
label: '',
|
||||
value: '',
|
||||
ca: '',
|
||||
})
|
||||
const caProviderRef = ref<CAProviderOption[]>([])
|
||||
const isLoading = ref(false)
|
||||
const errorMessage = ref('')
|
||||
|
||||
/**
|
||||
* @function goToAddCAProvider
|
||||
* @description 跳转到CA授权管理页面
|
||||
*/
|
||||
const goToAddCAProvider = () => {
|
||||
window.open('http://localhost:5173/auto-deploy', '_blank')
|
||||
}
|
||||
|
||||
/**
|
||||
* @function handleUpdateType
|
||||
* @description 根据当前 param.value 更新 param 对象的 label 和 ca,并 emit 更新事件
|
||||
*/
|
||||
const handleUpdateType = () => {
|
||||
const selectedProvider = caProviderRef.value.find((item) => item.value === param.value.value)
|
||||
|
||||
if (selectedProvider) {
|
||||
param.value = {
|
||||
label: selectedProvider.label,
|
||||
value: selectedProvider.value,
|
||||
ca: selectedProvider.ca,
|
||||
}
|
||||
} else if (caProviderRef.value.length > 0 && param.value.value === '') {
|
||||
// 如果 param.value 为空(例如初始状态或清空后),且 caProviderRef 列表不为空,则默认选中第一个
|
||||
param.value = {
|
||||
label: caProviderRef.value[0]?.label || '',
|
||||
value: caProviderRef.value[0]?.value || '',
|
||||
ca: caProviderRef.value[0]?.ca || '',
|
||||
}
|
||||
}
|
||||
emit('update:value', { value: param.value.value, ca: param.value.ca })
|
||||
}
|
||||
|
||||
/**
|
||||
* @function handleUpdateValue
|
||||
* @description 更新 param.value 并触发类型更新
|
||||
* @param value - 新的选中值
|
||||
*/
|
||||
const handleUpdateValue = (value: string) => {
|
||||
param.value.value = value
|
||||
handleUpdateType()
|
||||
}
|
||||
|
||||
/**
|
||||
* @function loadCAProviders
|
||||
* @description 加载CA授权选项
|
||||
*/
|
||||
const loadCAProviders = async () => {
|
||||
isLoading.value = true
|
||||
errorMessage.value = ''
|
||||
try {
|
||||
// 添加Let's Encrypt作为首选项
|
||||
const letsEncryptOption: CAProviderOption = {
|
||||
label: "Let's Encrypt",
|
||||
value: '',
|
||||
ca: 'letsencrypt',
|
||||
}
|
||||
|
||||
// 获取其他CA授权列表
|
||||
const { data } = await getAllEabList({ ca: '' }).fetch()
|
||||
const eabOptions: CAProviderOption[] = (data || []).map((item) => ({
|
||||
label: item.name,
|
||||
value: item.id.toString(),
|
||||
ca: item.ca,
|
||||
}))
|
||||
|
||||
// 合并选项,Let's Encrypt在首位
|
||||
caProviderRef.value = [letsEncryptOption, ...eabOptions]
|
||||
|
||||
// 数据加载后,如果 props.value 有值,尝试根据 props.value 初始化 param
|
||||
if (props.value) {
|
||||
handleUpdateValue(props.value)
|
||||
} else {
|
||||
handleUpdateType() // 确保在 caProviderRef 更新后,param 也得到相应更新
|
||||
}
|
||||
} catch (error) {
|
||||
errorMessage.value = typeof error === 'string' ? error : $t('t_3_1747990229599')
|
||||
handleError(error)
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function handleFilter
|
||||
* @description NSelect 组件的搜索过滤函数
|
||||
* @param pattern - 搜索文本
|
||||
* @param option - 当前选项
|
||||
* @returns {boolean} 是否匹配
|
||||
*/
|
||||
const handleFilter = (pattern: string, option: CAProviderOption): boolean => {
|
||||
return option.label.toLowerCase().includes(pattern.toLowerCase())
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.value,
|
||||
(newValue) => {
|
||||
// 仅当外部 props.value 与内部 param.value.value 不一致时才更新
|
||||
if (newValue !== param.value.value) {
|
||||
handleUpdateValue(newValue)
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
|
||||
onMounted(() => {
|
||||
loadCAProviders()
|
||||
})
|
||||
|
||||
return {
|
||||
param,
|
||||
caProviderRef,
|
||||
isLoading,
|
||||
errorMessage,
|
||||
goToAddCAProvider,
|
||||
handleUpdateValue,
|
||||
loadCAProviders,
|
||||
handleFilter,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user