import type { Ref } from 'vue' import type { DynamicFormFieldValue, DynamicFormState, TaskFieldConfigViewItem, TaskFieldOption, } from './useTaskForm' interface UseTaskFormFieldsOptions { form: Ref taskFieldConfigList: Ref } export type TaskFieldValuePatch = Partial const normalizeFieldText = (value: unknown): string => { return value === undefined || value === null ? '' : String(value) } /** * 集中管理动态表单字段的查找和更新,避免联动逻辑只修改展示文本, * 却遗留旧提交值。 */ export const useTaskFormFields = ({ form, taskFieldConfigList }: UseTaskFormFieldsOptions) => { const findFieldByAlias = (alias: string): TaskFieldConfigViewItem | undefined => { return taskFieldConfigList.value.find((field) => field.alias === alias) } const getFieldFormValue = (field: TaskFieldConfigViewItem): DynamicFormFieldValue | undefined => { return form.value.value[field.id] } const getFieldFormValueByAlias = (alias: string): DynamicFormFieldValue | undefined => { const field = findFieldByAlias(alias) return field ? getFieldFormValue(field) : undefined } const getFieldValueByAlias = (alias: string): string | undefined => { return getFieldFormValueByAlias(alias)?.value } const setFieldFormValue = ( field: TaskFieldConfigViewItem, fieldValue: TaskFieldValuePatch ): void => { const currentValue = getFieldFormValue(field) if (!currentValue) return if (fieldValue.label !== undefined) { currentValue.label = fieldValue.label } if (fieldValue.value !== undefined) { currentValue.value = fieldValue.value } } const setFieldFormValueByAlias = (alias: string, fieldValue: TaskFieldValuePatch): void => { const field = findFieldByAlias(alias) if (field) { setFieldFormValue(field, fieldValue) } } /** * 同步写入展示文本和提交值;若文本命中字典选项,则提交对应的 option value。 */ const setFieldTextByAlias = (alias: string, value: unknown): void => { const field = findFieldByAlias(alias) if (!field) return const normalizedValue = normalizeFieldText(value) const matchedOption = field.options?.find((option) => option.label === normalizedValue) setFieldFormValue(field, { label: matchedOption?.label ?? normalizedValue, value: matchedOption?.value ?? normalizedValue, }) } const clearFieldValue = (field: TaskFieldConfigViewItem): void => { setFieldFormValue(field, { label: '', value: '' }) } const clearFieldValueByAlias = (alias: string): void => { const field = findFieldByAlias(alias) if (field) { clearFieldValue(field) } } const clearFieldValuesByAlias = (aliases: Iterable): void => { for (const alias of aliases) { clearFieldValueByAlias(alias) } } const setFieldOptions = (field: TaskFieldConfigViewItem, options: TaskFieldOption[]): void => { field.options = options.length ? options : null } const setFieldOptionsByAlias = (alias: string, options: TaskFieldOption[]): void => { const field = findFieldByAlias(alias) if (field) { setFieldOptions(field, options) } } return { findFieldByAlias, getFieldFormValue, getFieldFormValueByAlias, getFieldValueByAlias, setFieldFormValue, setFieldFormValueByAlias, setFieldTextByAlias, clearFieldValue, clearFieldValueByAlias, clearFieldValuesByAlias, setFieldOptions, setFieldOptionsByAlias, } }