import { defineComponent, PropType, VNode } from 'vue' import { NButton, NFormItemGi, NGrid, NSelect, NText, NSpin, NFlex } from 'naive-ui' // 类型导入 import type { DnsProviderSelectProps, DnsProviderOption, DnsProviderType, DnsProviderSelectEmits } from './types' // 绝对内部导入 - Controller import { useDnsProviderSelectController } from './useController' // 绝对内部导入 - Components import SvgIcon from '@components/SvgIcon' // 绝对内部导入 - Utilities import { $t } from '@locales/index' /** * @component DnsProviderSelect * @description DNS提供商选择组件,支持多种DNS提供商类型,并提供刷新和跳转到授权页面的功能。 * 遵循 MVC/MV* 模式,将业务逻辑、状态管理与视图渲染分离。 * * @example 基础使用 * * * @property {DnsProviderType} type - DNS提供商类型。 * @property {string} path - 表单路径,用于表单校验。 * @property {string} value - 当前选中的值 (通过 v-model:value 绑定)。 * @property {'value' | 'type'} valueType - 表单值的类型,决定 emit 'update:value' 时传递的是选项的 'value' 还是 'type'。 * @property {boolean} isAddMode - 是否为添加模式,显示添加和刷新按钮。 * @property {boolean} [disabled=false] - 是否禁用。 * @property {string} [customClass] - 自定义CSS类名。 * * @emits update:value - (value: DnsProviderOption) 当选择的DNS提供商变更时触发,传递整个选项对象。 */ export default defineComponent({ name: 'DnsProviderSelect', props: { type: { type: String as PropType, required: true, }, path: { type: String, required: true, }, value: { type: String, required: true, }, valueType: { type: String as PropType<'value' | 'type'>, default: 'value', }, isAddMode: { type: Boolean, default: true, }, disabled: { type: Boolean, default: false, }, customClass: { type: String, default: '', }, }, emits: ['update:value'] as unknown as DnsProviderSelectEmits, // 类型断言以匹配严格的 emits 定义 setup(props: DnsProviderSelectProps, { emit }: { emit: DnsProviderSelectEmits }) { const controller = useDnsProviderSelectController(props, emit) /** * 渲染标签 * @param option - 选项 * @returns 渲染后的VNode */ const renderLabel = (option: DnsProviderOption): VNode => { return ( {option.label} ) } /** * 渲染单选标签 * @param option - 选项 (Record 来自 naive-ui 的类型) * @returns 渲染后的VNode */ const renderSingleSelectTag = ({ option }: { option: DnsProviderOption }): VNode => { return (
{option.label ? ( renderLabel(option) ) : ( {props.type === 'dns' ? $t('t_0_1747019621052') : $t('t_0_1746858920894')} )}
) } return () => ( renderSingleSelectTag({ option: option as DnsProviderOption }) } filter={(pattern: string, option: any) => controller.handleFilter(pattern, option as DnsProviderOption)} placeholder={props.type === 'dns' ? $t('t_3_1745490735059') : $t('t_0_1746858920894')} value={controller.param.value.value} // 使用 controller 中的 param.value.value onUpdateValue={controller.handleUpdateValue} disabled={props.disabled} v-slots={{ empty: () => { return ( {controller.errorMessage.value || (props.type === 'dns' ? $t('t_1_1746858922914') : $t('t_2_1746858923964'))} ) }, }} /> {props.isAddMode && ( {props.type === 'dns' ? $t('t_1_1746004861166') : $t('t_3_1746858920060')} controller.loadDnsProviders(props.type)} loading={controller.isLoading.value} disabled={props.disabled} > {$t('t_0_1746497662220')} )} ) }, })