useFieldValueTransform.js
5.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/**
* 字段值转换 Composable
*
* @description 封装字段值转换逻辑,提供统一的转换 API
* @module composables/useFieldValueTransform
* @author Claude Code
* @created 2026-02-14
* @version 1.1.0 - 简化转换逻辑,减少重复代码
*/
import { computed, isRef } from 'vue'
import { PLAN_FIELD_DEFINITIONS, TRANSFORM_TYPES } from '@/config/plan-fields'
import { transformFieldValue, batchTransformFields } from '@/utils/planFieldTransformers'
/**
* 使用字段值转换
*
* @description 提供字段值的双向转换能力
* @param {Object} formData - 表单数据
* @returns {Object} 转换方法和计算属性
*
* @example
* const { yuanFormData, fenFormData, toYuan, toFen, reset } = useFieldValueTransform(formData)
*
* // 转换为分值用于显示
* toYuan('coverage', 10000) // '100.00'
*
* // 转换为元值用于提交
* toFen('coverage', '100.00') // 10000
*/
// eslint-disable-next-line react-hooks/rules-of-hooks
export function useFieldValueTransform(formData, fieldDefinitions = PLAN_FIELD_DEFINITIONS) {
const getFieldDefinitions = () => {
const definitions = isRef(fieldDefinitions) ? fieldDefinitions.value : fieldDefinitions
return definitions || {}
}
const getReverseTransform = (transform) => {
if (!transform || transform === TRANSFORM_TYPES.NONE) return TRANSFORM_TYPES.NONE
if (transform === TRANSFORM_TYPES.FEN_TO_YUAN) return TRANSFORM_TYPES.YUAN_TO_FEN
if (transform === TRANSFORM_TYPES.YUAN_TO_FEN) return TRANSFORM_TYPES.FEN_TO_YUAN
return TRANSFORM_TYPES.NONE
}
const getReverseFieldDefinitions = () => {
return Object.entries(getFieldDefinitions()).reduce((result, [key, definition]) => {
if (!definition || typeof definition === 'string') {
result[key] = { transform: TRANSFORM_TYPES.NONE }
return result
}
const reverseTransform = getReverseTransform(definition.transform)
result[key] = {
...definition,
transform: reverseTransform
}
return result
}, {})
}
/**
* 转换为分值(用于显示)
*
* @description 将表单中的值统一转换为分值显示
* @param {string} fieldKey - 字段名称
* @param {*} value - 原始值(可能是元或分)
* @returns {*} 转换后的分值
*
* @example
* toYuan('annual_premium', 10000) // '100.00' (分转元显示)
* toYuan('coverage', '100.00') // '100.00' (元值直接显示)
*/
const toYuan = (fieldKey, value) => {
if (value === undefined) return undefined
if (value === null) return null
const definition = getFieldDefinitions()[fieldKey]
if (!definition || typeof definition === 'string') return value
if (!definition.transform || definition.transform === TRANSFORM_TYPES.NONE) {
return value
}
return transformFieldValue(value, definition.transform)
}
/**
* 转换为分值(用于提交)
*
* @description 将表单中的值统一转换为分值提交
* @param {string} fieldKey - 字段名称
* @param {*} value - 原始值(可能是元或分)
* @returns {*} 转换后的分值
*
* @example
* toFen('annual_premium', '100.00') // 10000 (元转分提交:×100)
* toFen('coverage', 10000) // 10000 (元值,转为分值:×100)
* toFen('withdrawal_period', 3) // 3 (无转换,直接返回)
*/
const toFen = (fieldKey, value) => {
if (value === undefined) return undefined
if (value === null) return null
const definition = getFieldDefinitions()[fieldKey]
if (!definition || typeof definition === 'string') return value
const reverseTransform = getReverseTransform(definition.transform)
if (!reverseTransform || reverseTransform === TRANSFORM_TYPES.NONE) {
return value
}
return transformFieldValue(value, reverseTransform)
}
/**
* 批量转换为分值(用于初始化表单显示)
*
* @description 将表单数据(元值)转换为分值格式(带两位小数)用于显示
* @param {Object} formData - 表单数据
* @returns {Object} 分值格式的数据
*
* @example
* batchToYuan({ coverage: 10000, name: 'Test' })
* // { coverage: '100.00', name: 'Test' }
*/
const batchToYuan = (sourceData) => {
return batchTransformFields(sourceData, getFieldDefinitions())
}
/**
* 批量转换为分值(用于提交 API)
*
* @description 将表单的元值数据批量转换为分值整数
* @param {Object} yuanData - 元值数据
* @returns {Object} 分值数据
*
* @example
* batchToFen({ coverage: '100.00', name: 'Test' })
* // { coverage: 10000, name: 'Test' }
*/
const batchToFen = (yuanData) => {
return batchTransformFields(yuanData, getReverseFieldDefinitions())
}
// 计算属性:表单显示数据(元值转分值显示)
const displayData = computed(() => batchToYuan(formData.value))
// 计算属性:API 提交数据(元值转分值提交)
const submitData = computed(() => batchToFen(formData.value))
return {
toYuan,
toFen,
batchToYuan,
batchToFen,
displayData, // 计算属性:表单显示数据(元值转分值显示)
submitData // 计算属性:API 提交数据(元值转分值提交)
}
}