/** * 字段联动管理器 * 管理字段之间的依赖关系和联动逻辑 */ import type { FieldDependency, FormData } from '@/types/form' /** * 字段联动管理器类 */ export class FieldDependencyManager { /** 联动配置列表 */ private dependencies: FieldDependency[] = [] /** 字段变化回调 */ private callbacks: Map void>> = new Map() /** * 添加联动配置 * @param dep 联动配置 */ addDependency(dep: FieldDependency): void { // 检查是否已存在相同的联动配置 const existingIndex = this.dependencies.findIndex( (d) => d.sourceField === dep.sourceField && d.targetField === dep.targetField ) if (existingIndex >= 0) { // 替换现有配置 this.dependencies[existingIndex] = dep } else { // 添加新配置 this.dependencies.push(dep) } } /** * 批量添加联动配置 * @param deps 联动配置列表 */ addDependencies(deps: FieldDependency[]): void { deps.forEach((dep) => this.addDependency(dep)) } /** * 移除联动配置 * @param sourceField 源字段 * @param targetField 目标字段 */ removeDependency(sourceField: string, targetField: string): void { this.dependencies = this.dependencies.filter( (d) => !(d.sourceField === sourceField && d.targetField === targetField) ) } /** * 清空所有联动配置 */ clear(): void { this.dependencies = [] this.callbacks.clear() } /** * 触发联动 * @param sourceField 源字段名称 * @param sourceValue 源字段值 * @param allFormData 所有表单数据 * @returns 联动结果 { [targetField]: { type, value } } */ trigger( sourceField: string, sourceValue: any, allFormData: FormData ): Record { const results: Record = {} // 找到所有与源字段相关的联动配置 const relatedDeps = this.dependencies.filter((dep) => dep.sourceField === sourceField) relatedDeps.forEach((dep) => { // 检查条件是否满足 if (dep.condition(sourceValue, allFormData)) { let result: any = undefined // 执行联动动作 switch (dep.type) { case 'show': case 'hide': result = dep.type === 'show' break case 'enable': case 'disable': result = dep.type !== 'disable' break case 'setValue': if (dep.action) { result = dep.action( allFormData[dep.targetField], sourceValue, allFormData ) } break case 'setOptions': if (dep.action) { result = dep.action( allFormData[dep.targetField], sourceValue, allFormData ) } break } results[dep.targetField] = { type: dep.type, value: result } // 触发回调 this.emit(sourceField, dep.targetField, { type: dep.type, value: result }) } }) return results } /** * 注册字段变化回调 * @param sourceField 源字段 * @param callback 回调函数 */ on(sourceField: string, callback: (targetField: string, action: any) => void): void { if (!this.callbacks.has(sourceField)) { this.callbacks.set(sourceField, new Set()) } this.callbacks.get(sourceField)!.add(callback) } /** * 取消注册回调 * @param sourceField 源字段 * @param callback 回调函数 */ off(sourceField: string, callback: (targetField: string, action: any) => void): void { const callbacks = this.callbacks.get(sourceField) if (callbacks) { callbacks.delete(callback) } } /** * 触发回调 */ private emit(sourceField: string, targetField: string, action: any): void { const callbacks = this.callbacks.get(sourceField) if (callbacks) { callbacks.forEach((cb) => cb(targetField, action)) } } /** * 获取所有联动配置 */ getDependencies(): FieldDependency[] { return [...this.dependencies] } /** * 获取与指定字段相关的所有联动 * @param fieldName 字段名称 */ getFieldDependencies(fieldName: string): { asSource: FieldDependency[] asTarget: FieldDependency[] } { return { asSource: this.dependencies.filter((dep) => dep.sourceField === fieldName), asTarget: this.dependencies.filter((dep) => dep.targetField === fieldName) } } } /** * 创建常用的联动条件函数 */ export const DependencyConditions = { /** * 等于某个值 */ equals: (value: any) => (sourceValue: any) => sourceValue === value, /** * 不等于某个值 */ notEquals: (value: any) => (sourceValue: any) => sourceValue !== value, /** * 包含某个值(用于数组) */ contains: (value: any) => (sourceValue: any) => { if (Array.isArray(sourceValue)) { return sourceValue.includes(value) } return sourceValue === value }, /** * 不包含某个值 */ notContains: (value: any) => (sourceValue: any) => { if (Array.isArray(sourceValue)) { return !sourceValue.includes(value) } return sourceValue !== value }, /** * 大于某个值 */ greaterThan: (value: any) => (sourceValue: any) => Number(sourceValue) > Number(value), /** * 小于某个值 */ lessThan: (value: any) => (sourceValue: any) => Number(sourceValue) < Number(value), /** * 在某个范围内 */ between: (min: number, max: number) => (sourceValue: any) => { const num = Number(sourceValue) return num >= min && num <= max }, /** * 值为真 */ isTrue: () => (sourceValue: any) => Boolean(sourceValue), /** * 值为假 */ isFalse: () => (sourceValue: any) => !Boolean(sourceValue) } /** * 创建常用的联动动作函数 */ export const DependencyActions = { /** * 设置为固定值 */ setValue: (value: any) => () => value, /** * 清空值 */ clearValue: () => () => undefined, /** * 根据源值设置目标值 */ copyValue: () => (_target: any, source: any) => source, /** * 动态加载选项 */ loadOptions: (optionsLoader: (sourceValue: any) => Array<{ label: string; value: any }>) => { return () => async (_target: any, source: any, allData: FormData) => { return await optionsLoader(source) } } } /** * 导出单例实例 */ export const fieldDependencyManager = new FieldDependencyManager()