import type { Ref } from 'vue' import type { PharmacyItem } from '@/services/modules/task/entitySelector/type' import { getListDrugTableApi } from '@/services/modules/task/taskFrom/index' import type { DynamicFormFieldValue, DynamicFormState, FieldValue, TaskFieldConfigViewItem, TaskFieldOption, } from './useTaskForm' export interface SingleSelectChangeEvent { previousValue: FieldValue value: string label: string selectedItem: TaskFieldOption } interface UseTaskSelectHandlersOptions { taskTypeId: Ref form: Ref taskFieldConfigList: Ref } /** * 动态表单选择器业务处理。 * * 统一处理: * 1. 单选打开前逻辑 * 2. 单选值变化逻辑 * 3. 多选打开前逻辑 * 4. 字段查找 * 5. 表单值读取和修改 * 6. 字段 options 修改 */ export const useTaskSelectHandlers = ({ taskTypeId, form, taskFieldConfigList, }: UseTaskSelectHandlersOptions) => { /** * 根据 alias 查找字段配置。 */ const findFieldByAlias = (alias: string): TaskFieldConfigViewItem | undefined => { return taskFieldConfigList.value.find((item) => item.alias === alias) } /** * 根据字段配置获取对应表单值。 */ const getFieldFormValue = (field: TaskFieldConfigViewItem): DynamicFormFieldValue | undefined => { return form.value.value[field.id] } /** * 根据 alias 获取对应表单值。 */ const getFieldFormValueByAlias = (alias: string): DynamicFormFieldValue | undefined => { const field = findFieldByAlias(alias) if (!field) { return undefined } return getFieldFormValue(field) } /** * 根据 alias 获取字段实际 value。 */ const getFieldValueByAlias = (alias: string): FieldValue => { return getFieldFormValueByAlias(alias)?.value } /** * 更新指定字段的表单值。 */ const setFieldFormValue = ( field: TaskFieldConfigViewItem, fieldValue: Partial ) => { const currentValue = getFieldFormValue(field) if (!currentValue) { return } if (fieldValue.label !== undefined) { currentValue.label = fieldValue.label } if (fieldValue.value !== undefined) { currentValue.value = fieldValue.value } } /** * 根据 alias 更新字段表单值。 */ const setFieldFormValueByAlias = (alias: string, fieldValue: Partial) => { const field = findFieldByAlias(alias) if (!field) { return } setFieldFormValue(field, fieldValue) } /** * 清空字段值。 */ const clearFieldValue = (field: TaskFieldConfigViewItem) => { const currentValue = getFieldFormValue(field) if (!currentValue) { return } currentValue.label = '' currentValue.value = '' } /** * 根据 alias 清空字段值。 */ const clearFieldValueByAlias = (alias: string) => { const field = findFieldByAlias(alias) if (!field) { return } clearFieldValue(field) } /** * 更新字段选项。 * * 没有选项时统一设置为 null。 */ const setFieldOptions = (field: TaskFieldConfigViewItem, options: TaskFieldOption[]) => { field.options = options.length ? options : null } /** * 根据 alias 更新字段选项。 */ const setFieldOptionsByAlias = (alias: string, options: TaskFieldOption[]) => { const field = findFieldByAlias(alias) if (!field) { return } setFieldOptions(field, options) } /** * 单选打开前处理。 * * 特殊接口请求和业务校验写在这里。 */ const handleSingleSelectBeforeOpen = async (field: TaskFieldConfigViewItem): Promise => { console.log('field', field) if (field.taskTypeId === '18' && field.alias === 'pharmacyName') { uni.navigateTo({ url: `/pages-common/entity-selector/index?alias=pharmacyName`, events: { pharmacyNameSelect: (selectedPharmacyItem: PharmacyItem | string) => { setPharmacyNameSelectEvent(selectedPharmacyItem) }, }, }) return false } if (taskTypeId.value === '47') { /** * OTC 推广任务示例。 */ const scorePackageValue = getFieldFormValueByAlias('scorePackage') console.log('scorePackageValue', scorePackageValue) if (field.taskFiledValue === '产品') { if (!scorePackageValue?.value) { uni.showToast({ title: '请先选择积分包', icon: 'none', }) return false } else { const arr = await getListDrugTable(String(scorePackageValue.value)) field.options = arr return true } } if (field.alias === 'realTaskTypeId') { return true } } return true } const getListDrugTable = async (packageId: string) => { try { const res = await getListDrugTableApi(packageId) const arr = res.data.map((item: string) => { return { label: item, value: item, } }) return arr } catch (error) { console.error('获取药品列表失败:', error) return [] } } /** * 单选值发生变化。 * * SingleSelect 内部已经保证新值与原值不同时 * 才会触发此方法。 */ const handleSingleSelectChange = ( field: TaskFieldConfigViewItem, event: SingleSelectChangeEvent ) => { console.log('单选字段:', field) console.log('单选变化:', event) /** * OTC 推广任务的字段联动示例。 */ if (taskTypeId.value === '47') { if (field.alias === 'scorePackage') { clearFieldValueByAlias('realTaskTypeId') } } } /** * 多选打开前处理。 */ const handleMultipleSelectBeforeOpen = async ( field: TaskFieldConfigViewItem ): Promise => { const currentFormValue = getFieldFormValue(field) if (!currentFormValue) { console.warn(`未找到字段对应的表单值:${field.id}`) return false } /** * 特殊多选接口请求写在这里。 * * 示例: * * if ( * taskTypeId.value === '47' && * field.alias === 'targetUsers' * ) { * const packageValue = * getFieldValueByAlias('scorePackage') * * if (!packageValue) { * uni.showToast({ * title: '请先选择分数包', * icon: 'none', * }) * * return false * } * * const res = await getTargetUserListApi({ * packageId: String(packageValue), * }) * * setFieldOptions( * field, * res.data.map((item) => ({ * label: String(item.name), * value: String(item.id), * })) * ) * } */ return true } const setPharmacyNameSelectEvent = (selectedPharmacyItem: PharmacyItem | string) => { if (typeof selectedPharmacyItem === 'string') { setFieldFormValueByAlias('pharmacyName', { label: selectedPharmacyItem, value: selectedPharmacyItem, }) return } setFieldFormValueByAlias('pharmacyName', { label: selectedPharmacyItem.pharmacyName, value: selectedPharmacyItem.pharmacyName, }) setFieldFormValueByAlias('pharmacyType', { label: undefined, value: selectedPharmacyItem.pharmacyType, }) setFieldFormValueByAlias('address', { label: selectedPharmacyItem.address, value: selectedPharmacyItem.address, }) const address = `${selectedPharmacyItem.province}-${selectedPharmacyItem.city}-${selectedPharmacyItem.area}` setFieldFormValueByAlias('shengshiqu', { label: address, value: address, }) } return { handleSingleSelectBeforeOpen, handleSingleSelectChange, handleMultipleSelectBeforeOpen, /** * 以下方法可按需在页面或其他业务逻辑中使用。 */ findFieldByAlias, getFieldFormValue, getFieldFormValueByAlias, getFieldValueByAlias, setFieldFormValue, setFieldFormValueByAlias, clearFieldValue, clearFieldValueByAlias, setFieldOptions, setFieldOptionsByAlias, } }