From 41b8b361cd7da37685c4ca380a82fc4ffb06a66f Mon Sep 17 00:00:00 2001 From: zuohuaijun Date: Sun, 14 Sep 2025 11:38:38 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=98=8E=E4=BC=98=E5=8C=96=E5=AD=97?= =?UTF-8?q?=E5=85=B8=E7=BB=84=E4=BB=B6=E3=80=81=E4=B8=8B=E6=8B=89=E7=BB=84?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Web/src/components/badgeTabs/index.vue | 1 - .../components/selector/pulldownSelecter.vue | 40 +- Web/src/components/sysDict/sysDict.vue | 759 +++++++++--------- 3 files changed, 420 insertions(+), 380 deletions(-) diff --git a/Web/src/components/badgeTabs/index.vue b/Web/src/components/badgeTabs/index.vue index cf2ae5e4..9ed64c52 100644 --- a/Web/src/components/badgeTabs/index.vue +++ b/Web/src/components/badgeTabs/index.vue @@ -99,7 +99,6 @@ watch( () => props.data, (newValue) => { state.data = newValue ?? []; - console.log(state.data); }, { immediate: true } ); diff --git a/Web/src/components/selector/pulldownSelecter.vue b/Web/src/components/selector/pulldownSelecter.vue index 272280d4..6cfb5bc9 100644 --- a/Web/src/components/selector/pulldownSelecter.vue +++ b/Web/src/components/selector/pulldownSelecter.vue @@ -112,7 +112,7 @@ const props = defineProps({ */ dropdownHeight: { type: String, - default: '400px', + default: '550px', }, /** * 占位符 @@ -128,6 +128,19 @@ const props = defineProps({ type: Array, default: [], }, + /** + * 查询表单高度偏移量 + */ + queryHeightOffset: { + type: Number, + default: 35, + }, + /** + * 查询表单标签宽度 + */ + queryLabelWidth: { + type: String, + }, /** * 查询参数 */ @@ -341,6 +354,7 @@ defineExpose({ :remote-method="remoteMethod" :default-first-option="allowCreate" @visible-change="selectVisibleChange" + :style="{ width: dropdownWidth }" popper-class="popper-class" ref="selectRef" remote-show-suffix @@ -355,14 +369,14 @@ defineExpose({
- + - 查询 - 重置 + 查询 + 重置 @@ -372,8 +386,7 @@ defineExpose({ ref="tableRef" @row-click="handleChange" :data="state.tableData?.items ?? []" - :height="`calc(${dropdownHeight} - 175px${$slots.queryForm ? ' - 35px' : ''}${state.tableQuery[keywordProp] && allowCreate ? ' - 35px' : ''})`" - :style="{ width: dropdownWidth }" + :height="`calc(${dropdownHeight} - 175px${$slots.queryForm ? ` - ${queryHeightOffset}px` : ''}${state.tableQuery[keywordProp] && allowCreate ? ` - ${queryHeightOffset}px` : ''})`" highlight-current-row > @@ -409,4 +422,19 @@ defineExpose({ .popper-class { min-width: 400px !important; } + +/* 组合多个深度选择器 */ +:deep(.popper-class) :deep(.el-select-dropdown__wrap) { + max-height: 600px !important; +} + + \ No newline at end of file diff --git a/Web/src/components/sysDict/sysDict.vue b/Web/src/components/sysDict/sysDict.vue index da63e598..dbfc097a 100644 --- a/Web/src/components/sysDict/sysDict.vue +++ b/Web/src/components/sysDict/sysDict.vue @@ -36,13 +36,13 @@ type TagType = (typeof TAG_TYPES)[number]; * @property {string|number} [value] - 值 */ interface DictItem { - [key: string]: any; - tagType?: TagType; - styleSetting?: string; - classSetting?: string; - disabled?: boolean; - label?: string; - value?: string | number; + [key: string]: any; + tagType?: TagType; + styleSetting?: string; + classSetting?: string; + disabled?: boolean; + label?: string; + value?: string | number; } /** @@ -52,8 +52,8 @@ interface DictItem { * @property {Array} excludes - 被互斥的选项值列表 */ interface MutexConfig { - value: string | number; - excludes: (string | number)[]; + value: string | number; + excludes: (string | number)[]; } /** @@ -63,8 +63,8 @@ interface MutexConfig { * @property {string} Comma - 逗号分隔模式,如'1,2,3' */ const MultipleModel = { - Array: 'array', - Comma: 'comma', + Array: 'array', + Comma: 'comma', } as const; // 多选值模式枚举类型 @@ -77,7 +77,7 @@ type MultipleModelType = (typeof MultipleModel)[keyof typeof MultipleModel]; * @returns {value is RenderType} - 是否为合法的渲染类型 */ function isRenderType(value: any): value is RenderType { - return RENDER_TYPES.includes(value); + return RENDER_TYPES.includes(value); } /** @@ -87,7 +87,7 @@ function isRenderType(value: any): value is RenderType { * @returns {value is MultipleModel} - 是否为合法的多选模式 */ function isMultipleModel(value: any): value is MultipleModelType { - return Object.values(MultipleModel).includes(value); + return Object.values(MultipleModel).includes(value); } @@ -103,147 +103,158 @@ const emit = defineEmits(['update:modelValue', 'change']); * 组件属性定义 */ const props = defineProps({ - /** - * 绑定值,支持多种类型 - * @type {string|number|boolean|Array|null} - * @required - * @example - * // 单选选择器 - * - * - * // 多选选择器(数组模式) - * - * - * // 多选选择器(逗号模式) - * - */ - modelValue: { - type: [String, Number, Boolean, Array, null] as PropType, - default: null, - required: true, - }, - /** - * 字典编码,用于从字典中获取数据 - * @type {string} - * @required - * @example 'gender' - */ - code: { - type: String, - required: false, - }, - /** - * 直接传入的字典数据源(优先级高于code) - * @type {DictItem[]} - * @example [{ label: '选项1', value: '1' }, { label: '选项2', value: '2' }] - */ - data: { - type: Array as PropType, - default: () => [], - }, - /** - * 是否为常量字典(true从常量列表获取,false从字典列表获取) - * @type {boolean} - * @default false - * @example true - */ - isConst: { - type: Boolean, - default: false, - }, - /** - * 字典项中用于显示的字段名 - * @type {string} - * @default 'label' - * @example 'name' - */ - propLabel: { - type: String, - default: 'label', - }, - /** - * 字典项中用于取值的字段名 - * @type {string} - * @default 'value' - * @example 'id' - */ - propValue: { - type: String, - default: 'value', - }, - /** - * 字典项过滤函数 - * @type {Function} - * @param {DictItem} dict - 当前字典项 - * @returns {boolean} - 是否保留该项 - * @default (dict) => true - * @example - * // 只显示启用的字典项 - * :onItemFilter="(dict) => dict.status === 1" - */ - onItemFilter: { - type: Function as PropType<(dict: DictItem) => boolean>, - default: () => true, - }, - /** - * 字典项显示内容格式化函数 - * @type {Function} - * @param {DictItem} dict - 当前字典项 - * @returns {string|undefined|null} - 格式化后的显示内容 - * @default () => undefined - * @example - * // 在标签前添加图标 - * :onItemFormatter="(dict) => `${dict.label} `" - */ - onItemFormatter: { - type: Function as PropType<(dict: DictItem) => string | undefined | null>, - default: () => undefined, - }, - /** - * 组件渲染方式 - * @type {'tag'|'select'|'radio'|'checkbox'|'radio-button'} - * @default 'tag' - * @example 'select' - */ - renderAs: { - type: String as PropType, - default: 'tag', - validator: isRenderType, - }, - /** - * 是否多选(仅在renderAs为select/checkbox时有效) - * @type {boolean} - * @default false - * @example true - */ - multiple: { - type: Boolean, - default: false, - }, - /** - * 多选值模式(仅在multiple为true时有效) - * @type {'array'|'comma'} - * @default 'array' - * @example 'comma' - */ - multipleModel: { - type: String as PropType, - default: MultipleModel.Array, - validator: isMultipleModel, - }, - /** - * 互斥配置项(仅在多选模式下有效) - * @type {Array} - * @example - * :mutex-configs="[ - * { value: 'all', excludes: ['1', '2', '3'] }, - * { value: '1', excludes: ['all'] } - * ]" - */ - mutexConfigs: { - type: Array as PropType, - default: () => [], - }, + /** + * 绑定值,支持多种类型 + * @type {string|number|boolean|Array|null} + * @required + * @example + * // 单选选择器 + * + * + * // 多选选择器(数组模式) + * + * + * // 多选选择器(逗号模式) + * + */ + modelValue: { + type: [String, Number, Boolean, Array, null] as PropType, + default: null, + required: true, + }, + /** + * 字典编码,用于从字典中获取数据 + * @type {string} + * @required + * @example 'gender' + */ + code: { + type: String, + required: false, + }, + /** + * 直接传入的字典数据源(优先级高于code) + * @type {DictItem[]} + * @example [{ label: '选项1', value: '1' }, { label: '选项2', value: '2' }] + */ + data: { + type: Array as PropType, + default: () => [], + }, + /** + * 是否为常量字典(true从常量列表获取,false从字典列表获取) + * @type {boolean} + * @default false + * @example true + */ + isConst: { + type: Boolean, + default: false, + }, + /** + * 字典项中用于显示的字段名 + * @type {string} + * @default 'label' + * @example 'name' + */ + propLabel: { + type: String, + default: 'label', + }, + /** + * 字典项中用于取值的字段名 + * @type {string} + * @default 'value' + * @example 'id' + */ + propValue: { + type: String, + default: 'value', + }, + /** + * 字典项过滤函数 + * @type {Function} + * @param {DictItem} dict - 当前字典项 + * @returns {boolean} - 是否保留该项 + * @default (dict) => true + * @example + * // 只显示启用的字典项 + * :onItemFilter="(dict) => dict.status === 1" + */ + onItemFilter: { + type: Function as PropType<(dict: DictItem) => boolean>, + default: () => true, + }, + /** + * 字典项显示内容格式化函数 + * @type {Function} + * @param {DictItem} dict - 当前字典项 + * @returns {string|undefined|null} - 格式化后的显示内容 + * @default () => undefined + * @example + * // 在标签前添加图标 + * :onItemFormatter="(dict) => `${dict.label} `" + */ + onItemFormatter: { + type: Function as PropType<(dict: DictItem) => string | undefined | null>, + default: () => undefined, + }, + /** + * 组件渲染方式 + * @type {'tag'|'select'|'radio'|'checkbox'|'radio-button'} + * @default 'tag' + * @example 'select' + */ + renderAs: { + type: String as PropType, + default: 'tag', + validator: isRenderType, + }, + /** + * 是否多选(仅在renderAs为select/checkbox时有效) + * @type {boolean} + * @default false + * @example true + */ + multiple: { + type: Boolean, + default: false, + }, + /** + * 多选值模式(仅在multiple为true时有效) + * @type {'array'|'comma'} + * @default 'array' + * @example 'comma' + */ + multipleModel: { + type: String as PropType, + default: MultipleModel.Array, + validator: isMultipleModel, + }, + /** + * 互斥配置项(仅在多选模式下有效) + * @type {Array} + * @example + * :mutex-configs="[ + * { value: 'all', excludes: ['1', '2', '3'] }, + * { value: '1', excludes: ['all'] } + * ]" + */ + mutexConfigs: { + type: Array as PropType, + default: () => [], + }, +}); + +/** + * 组件状态 + * @property {DictItem[]} dictData - 原始字典数据 + * @property {any} value - 当前值 + */ +const state = reactive({ + dictData: [] as DictItem[], + value: props.modelValue, + conversion: false, }); /** @@ -252,26 +263,26 @@ const props = defineProps({ * @returns {DictItem[]} - 过滤并格式化后的字典数据 */ const formattedDictData = computed(() => { - const baseData = state.dictData.filter(props.onItemFilter).map((item) => ({ - ...item, - label: item[props.propLabel], - value: item[props.propValue], - })); + const baseData = state.dictData.filter(props.onItemFilter).map((item) => ({ + ...item, + label: item[props.propLabel], + value: item[props.propValue], + })); - // 如果没有互斥配置或多选模式,直接返回基础数据 - if (!props.multiple || !props.mutexConfigs || props.mutexConfigs.length === 0) { - return baseData; - } + // 如果没有互斥配置或多选模式,直接返回基础数据 + if (!props.multiple || !props.mutexConfigs || props.mutexConfigs.length === 0) { + return baseData; + } - // 处理互斥逻辑,设置禁用状态 - return baseData.map((item) => { - // 检查当前项是否应该被禁用 - const isDisabled = isItemDisabled(item.value, state.value, props.mutexConfigs); - return { - ...item, - disabled: isDisabled || item.disabled, // 保持原有的disabled状态 - }; - }); + // 处理互斥逻辑,设置禁用状态 + return baseData.map((item) => { + // 检查当前项是否应该被禁用 + const isDisabled = isItemDisabled(item.value, state.value, props.mutexConfigs); + return { + ...item, + disabled: isDisabled || item.disabled, // 保持原有的disabled状态 + }; + }); }); /** @@ -280,15 +291,15 @@ const formattedDictData = computed(() => { * @returns {DictItem|DictItem[]|null} - 当前选中的字典项或字典项数组 */ const currentDictItems = computed(() => { - if (!state.value) return null; + if (!state.value) return null; - if (Array.isArray(state.value)) { - // 去重 - const uniqueValues = [...new Set(state.value)]; - return formattedDictData.value.filter((item) => uniqueValues.includes(item.value)); - } + if (Array.isArray(state.value)) { + // 去重 + const uniqueValues = [...new Set(state.value)]; + return formattedDictData.value.filter((item) => uniqueValues.includes(item.value)); + } - return formattedDictData.value.find((item) => item.value == state.value) || null; + return formattedDictData.value.find((item) => item.value == state.value) || null; }); /** @@ -298,34 +309,34 @@ const currentDictItems = computed(() => { * @throws {Error} - 获取数据失败时抛出错误 */ const getDataList = (): DictItem[] => { - try { - // 如果提供了 data 数据源,优先使用 - if (props.data && props.data.length > 0) { - return props.data.map((item: any) => ({ - ...item, - label: item[props.propLabel] ?? [item.name, item.desc].filter((x) => x).join('-'), - value: item[props.propValue] ?? item.code, - })); - } + try { + // 如果提供了 data 数据源,优先使用 + if (props.data && props.data.length > 0) { + return props.data.map((item: any) => ({ + ...item, + label: item[props.propLabel] ?? [item.name, item.desc].filter((x) => x).join('-'), + value: item[props.propValue] ?? item.code, + })); + } - if (!props.code) { - console.error('[g-sys-dict] code和data不能同时为空'); - return []; - } + if (!props.code) { + console.error('[g-sys-dict] code和data不能同时为空'); + return []; + } - const source = props.isConst ? userStore.constList : userStore.dictList; - const data = props.isConst ? (source?.find((x: any) => x.code === props.code)?.data?.result ?? []) : (source[props.code] ?? []); - data.sort((a: number, b: number) => a - b); + const source = props.isConst ? userStore.constList : userStore.dictList; + const data = props.isConst ? (source?.find((x: any) => x.code === props.code)?.data?.result ?? []) : (source[props.code] ?? []); + data.sort((a: number, b: number) => a - b); - return data.map((item: any) => ({ - ...item, - label: item[props.propLabel] ?? [item.name, item.desc].filter((x) => x).join('-'), - value: item[props.propValue] ?? item.code, - })); - } catch (error) { - console.error(`[g-sys-dict] 获取字典[${props.code}]数据失败:`, error); - return []; - } + return data.map((item: any) => ({ + ...item, + label: item[props.propLabel] ?? [item.name, item.desc].filter((x) => x).join('-'), + value: item[props.propValue] ?? item.code, + })); + } catch (error) { + console.error(`[g-sys-dict] 获取字典[${props.code}]数据失败:`, error); + return []; + } }; /** @@ -334,13 +345,13 @@ const getDataList = (): DictItem[] => { * @param {any} value - 待处理的值 */ const processNumericValues = (value: any) => { - if (typeof value === 'number' || (Array.isArray(value) && typeof value[0] === 'number')) { - state.dictData.forEach((item) => { - if (item.value) { - item.value = Number(item.value); - } - }); - } + if (typeof value === 'number' || (Array.isArray(value) && typeof value[0] === 'number')) { + state.dictData.forEach((item) => { + if (item.value) { + item.value = Number(item.value); + } + }); + } }; /** @@ -350,36 +361,48 @@ const processNumericValues = (value: any) => { * @returns {any} - 解析后的值 */ const parseMultipleValue = (value: any): any => { - // 处理空值情况 - if (value === null || value === undefined || value === '') { - return props.multiple ? [] : value; - } + // 处理空值情况 + if (value === null || value === undefined || value === '') { + return props.multiple ? [] : value; + } - // 处理字符串值 - if (typeof value === 'string') { - const trimmedValue = value.trim(); + // 处理数字 + if (typeof value === 'number' && !state.conversion) { + try { + state.dictData.forEach((item) => { + if (item.value) item.value = Number(item.value); + }); + state.conversion = true; + } catch (error) { + console.warn('[g-sys-dict] 数字转换失败:', error); + } + } - // 处理JSON数组格式 - if (trimmedValue.startsWith('[') && trimmedValue.endsWith(']')) { - try { - return JSON.parse(trimmedValue); - } catch (error) { - console.warn('[g-sys-dict] 解析多选值失败:', error); - return []; - } - } + // 处理字符串值 + if (typeof value === 'string') { + const trimmedValue = value.trim(); - // 处理逗号分隔格式 - if (props.multipleModel === MultipleModel.Comma && trimmedValue.includes(',')) { - return trimmedValue.split(','); - } + // 处理JSON数组格式 + if (trimmedValue.startsWith('[') && trimmedValue.endsWith(']')) { + try { + return JSON.parse(trimmedValue); + } catch (error) { + console.warn('[g-sys-dict] 解析多选值失败:', error); + return []; + } + } - // 处理单个值情况 - return props.multiple ? [trimmedValue] : trimmedValue; - } + // 处理逗号分隔格式 + if (props.multipleModel === MultipleModel.Comma && trimmedValue.includes(',')) { + return trimmedValue.split(','); + } - // 其他情况直接返回 - return value; + // 处理单个值情况 + return props.multiple ? [trimmedValue] : trimmedValue; + } + + // 其他情况直接返回 + return value; }; /** @@ -391,28 +414,28 @@ const parseMultipleValue = (value: any): any => { * @returns {boolean} - 是否应该禁用 */ const isItemDisabled = (itemValue: string | number, currentValue: any, mutexConfigs: MutexConfig[]): boolean => { - // 如果没有配置互斥规则,不禁用任何项 - if (!mutexConfigs || mutexConfigs.length === 0) { - return false; - } + // 如果没有配置互斥规则,不禁用任何项 + if (!mutexConfigs || mutexConfigs.length === 0) { + return false; + } - // 获取当前选中的值数组 - const selectedValues = Array.isArray(currentValue) ? currentValue : currentValue ? [currentValue] : []; + // 获取当前选中的值数组 + const selectedValues = Array.isArray(currentValue) ? currentValue : currentValue ? [currentValue] : []; - // 检查每个互斥配置 - for (const config of mutexConfigs) { - // 如果互斥触发项已被选中,且当前项是被互斥项,则禁用 - if (selectedValues.includes(config.value) && config.excludes.includes(itemValue)) { - return true; - } + // 检查每个互斥配置 + for (const config of mutexConfigs) { + // 如果互斥触发项已被选中,且当前项是被互斥项,则禁用 + if (selectedValues.includes(config.value) && config.excludes.includes(itemValue)) { + return true; + } - // 如果当前项是互斥触发项,且有被互斥项被选中,则禁用 - if (itemValue === config.value && config.excludes.some((exclude) => selectedValues.includes(exclude))) { - return true; - } - } + // 如果当前项是互斥触发项,且有被互斥项被选中,则禁用 + if (itemValue == config.value && config.excludes.some((exclude) => selectedValues.includes(exclude))) { + return true; + } + } - return false; + return false; }; /** @@ -423,20 +446,20 @@ const isItemDisabled = (itemValue: string | number, currentValue: any, mutexConf * @returns {any} - 处理后的值 */ const handleMutex = (newValue: any, mutexConfigs: MutexConfig[]): any => { - // 如果没有配置互斥规则,直接返回原值 - if (!mutexConfigs || mutexConfigs.length === 0) return newValue; + // 如果没有配置互斥规则,直接返回原值 + if (!mutexConfigs || mutexConfigs.length === 0) return newValue; - // 如果是单选模式,直接返回 - if (!props.multiple) return newValue; + // 如果是单选模式,直接返回 + if (!props.multiple) return newValue; - // 对于禁用模式,我们只需要确保新值是有效的(即没有违反互斥规则) - // 实际的禁用逻辑在formattedDictData中处理 - let resultValue = Array.isArray(newValue) ? [...newValue] : newValue ? [newValue] : []; + // 对于禁用模式,我们只需要确保新值是有效的(即没有违反互斥规则) + // 实际的禁用逻辑在formattedDictData中处理 + let resultValue = Array.isArray(newValue) ? [...newValue] : newValue ? [newValue] : []; - // 过滤掉无效的值(可能由于异步更新导致的无效选择) - const validValues = formattedDictData.value.filter((item) => !item.disabled).map((item) => item.value); + // 过滤掉无效的值(可能由于异步更新导致的无效选择) + const validValues = formattedDictData.value.filter((item) => !item.disabled).map((item) => item.value); - return resultValue.filter((val) => validValues.includes(val)); + return resultValue.filter((val) => validValues.includes(val)); }; /** @@ -445,30 +468,30 @@ const handleMutex = (newValue: any, mutexConfigs: MutexConfig[]): any => { * @param {any} newValue - 新值 */ const updateValue = (newValue: any) => { - // 如果有互斥配置,先处理互斥 - let processedValue = newValue; - if (props.mutexConfigs && props.mutexConfigs.length > 0) { - processedValue = handleMutex(newValue, props.mutexConfigs); - } + // 如果有互斥配置,先处理互斥 + let processedValue = newValue; + if (props.mutexConfigs && props.mutexConfigs.length > 0) { + processedValue = handleMutex(newValue, props.mutexConfigs); + } - let emitValue = processedValue; - if (props.multipleModel === MultipleModel.Comma) { - if (Array.isArray(processedValue)) { - emitValue = processedValue.length > 0 ? processedValue.sort().join(',') : undefined; - } else if (processedValue === null || processedValue === undefined) { - emitValue = undefined; - } - } else { - if (Array.isArray(processedValue)) { - emitValue = processedValue.length > 0 ? processedValue.sort() : undefined; - } else if (processedValue === null || processedValue === undefined) { - emitValue = undefined; - } - } + let emitValue = processedValue; + if (props.multipleModel === MultipleModel.Comma) { + if (Array.isArray(processedValue)) { + emitValue = processedValue.length > 0 ? processedValue.sort().join(',') : []; + } else if (processedValue === null || processedValue === undefined) { + emitValue = undefined; + } + } else { + if (Array.isArray(processedValue)) { + emitValue = processedValue.length > 0 ? processedValue.sort() : []; + } else if (processedValue === null || processedValue === undefined) { + emitValue = undefined; + } + } - state.value = processedValue; - emit('update:modelValue', emitValue === '' ? undefined : emitValue); - emit('change', state.value, currentDictItems, state.dictData); + state.value = processedValue; + emit('update:modelValue', emitValue === '' || emitValue.length === 0 ? undefined : emitValue); + emit('change', state.value, currentDictItems, state.dictData); }; /** @@ -478,7 +501,7 @@ const updateValue = (newValue: any) => { * @returns {TagType} - 合法的标签类型 */ const ensureTagType = (item: DictItem): TagType => { - return TAG_TYPES.includes(item.tagType as TagType) ? (item.tagType as TagType) : 'primary'; + return TAG_TYPES.includes(item.tagType as TagType) ? (item.tagType as TagType) : 'primary'; }; /** @@ -488,9 +511,9 @@ const ensureTagType = (item: DictItem): TagType => { * @returns {string} - 显示文本 */ const getDisplayText = (dict?: DictItem): string => { - if (!dict) return String(state.value || ''); - const formattedText = props.onItemFormatter?.(dict); - return formattedText ?? dict[props.propLabel] ?? ''; + if (!dict) return String(state.value || ''); + const formattedText = props.onItemFormatter?.(dict); + return formattedText ?? dict[props.propLabel] ?? ''; }; /** @@ -498,20 +521,20 @@ const getDisplayText = (dict?: DictItem): string => { * @function */ const initData = () => { - // 验证 code 和 data 不能同时为空 - if (!props.code && (!props.data || props.data.length === 0)) { - console.error('[g-sys-dict] code和data不能同时为空'); - state.dictData = []; - state.value = props.multiple ? [] : null; - return; - } + // 验证 code 和 data 不能同时为空 + if (!props.code && (!props.data || props.data.length === 0)) { + console.error('[g-sys-dict] code和data不能同时为空'); + state.dictData = []; + state.value = props.multiple ? [] : null; + return; + } - state.dictData = getDataList(); - processNumericValues(props.modelValue); - const initialValue = parseMultipleValue(props.modelValue); - if (initialValue !== state.value) { - state.value = initialValue; - } + state.dictData = getDataList(); + processNumericValues(props.modelValue); + const initialValue = parseMultipleValue(props.modelValue); + if (initialValue !== state.value) { + state.value = initialValue; + } }; /** @@ -519,88 +542,78 @@ const initData = () => { * @function */ const validateInitialValue = () => { - return new Promise((resolve, reject) => { - if (props.renderAs === 'tag' || !state.value) return resolve(undefined); - if (Array.isArray(state.value)) { - const errorValues = state.value.filter((val) => state.dictData.find((e) => e[props.propValue] == val) === undefined); - if (errorValues && errorValues.length > 0) { - reject(`[g-sys-dict] 未匹配到选项值:${JSON.stringify(errorValues)}`); - } - } else if (state.value) { - if (!state.dictData.find((e) => e[props.propValue] === state.value)) { - reject(`[g-sys-dict] 未匹配到选项值:${state.value}`); - } - } - resolve(undefined); - }); + return new Promise((resolve, reject) => { + if (props.renderAs === 'tag' || !state.value) return resolve(undefined); + if (Array.isArray(state.value)) { + const errorValues = state.value.filter((val) => state.dictData.find((e) => e[props.propValue] == val) === undefined); + if (errorValues && errorValues.length > 0) { + reject(`[g-sys-dict] 未匹配到选项值:${JSON.stringify(errorValues)}`); + } + } else if (state.value) { + if (!state.dictData.find((e) => e[props.propValue] == state.value)) { + reject(`[g-sys-dict] 未匹配到选项值:${state.value}`); + } + } + resolve(undefined); + }); }; -/** - * 组件状态 - * @property {DictItem[]} dictData - 原始字典数据 - * @property {any} value - 当前值 - */ -const state = reactive({ - dictData: [] as DictItem[], - value: parseMultipleValue(props.modelValue), -}); - // 监听数据变化 watch( - () => props.modelValue, - (newValue) => { - state.value = parseMultipleValue(newValue); - validateInitialValue(); - } + () => props.modelValue, + (newValue) => { + state.value = parseMultipleValue(newValue); + validateInitialValue(); + } ); watch(() => [userStore.dictList, userStore.constList, props.data, state], initData, { immediate: true }); - + \ No newline at end of file