useFieldValueTransform.js
5.31 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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/**
* 字段值转换 Composable
*
* @description 封装字段值转换逻辑,提供统一的转换 API
* @module composables/useFieldValueTransform
* @author Claude Code
* @created 2026-02-14
*/
import { computed } from 'vue'
import {
fenToYuan,
yuanToFen,
transformFieldValue,
batchTransformFields,
reverseTransformFields
} from '@/utils/planFieldTransformers'
import { PLAN_FIELD_DEFINITIONS, TRANSFORM_TYPES } from '@/config/plan-fields'
/**
* 使用字段值转换
*
* @description 提供字段值的双向转换能力
* @param {Object} formData - 表单数据
* @param {Object} fieldDefinitions - 字段定义(来自 PLAN_FIELD_DEFINITIONS)
* @returns {Object} 转换方法和计算属性
*
* @example
* const { yuanFormData, fenFormData, toYuan, toFen, reset } = useFieldValueTransform(formData, fieldDefinitions)
*
* // 元转分(用于显示)
* toYuan('annual_premium', 10000) // => '10000.00' (分)
*
* // 分转元(用于提交)
* toFen('annual_premium', 1000) // => 10000 (元)
*/
// eslint-disable-next-line react-hooks/rules-of-hooks
export function useFieldValueTransform(formData, fieldDefinitions) {
/**
* 转换为分值(用于显示)
*
* @description 将表单中的值统一转换为分值显示
* @param {string} fieldKey - 字段名称
* @param {*} value - 原始值(可能是元或分)
* @returns {*} 转换后的分值
*
* @example
* toYuan('annual_premium', 10000) // => '10000.00' (分字符串,10000元×100=1000000分)
* toYuan('annual_premium', 10000) // => 10000 (分整数,API存储的是分)
*/
const toYuan = (fieldKey, value) => {
const definition = PLAN_FIELD_DEFINITIONS[fieldKey]
if (!definition) return value
const { transform } = definition
// 如果字段定义了 fen_to_yuan,表示API存的是分,需要转为元显示
if (transform === TRANSFORM_TYPES.FEN_TO_YUAN) {
// API存的是分(整数),转为元显示(带两位小数)
return fenToYuan(value)
}
// 默认返回原值(元值直接显示)
return value
}
/**
* 转换为分值(用于提交)
*
* @description 将表单中的值统一转换为分值提交
* @param {string} fieldKey - 字段名称
* @param {*} value - 原始值(可能是元或分)
* @returns {*} 转换后的分值
*
* @example
* toFen('annual_premium', '100.00') // => 10000 (分值整数,元值×100)
* toFen('withdrawal_period', 3) // => 3 (直接是元)
*/
const toFen = (fieldKey, value) => {
const definition = PLAN_FIELD_DEFINITIONS[fieldKey]
if (!definition) return value
const { transform } = definition
// 如果字段定义了 fen_to_yuan,表示API存的是分,需要转为元显示
// 所以提交时,元→分转换(×100)
if (transform === TRANSFORM_TYPES.FEN_TO_YUAN) {
// 元值转分值:10000 → 1000000(API存分值)
const numValue = parseFloat(value)
if (!Number.isNaN(numValue)) {
return Math.round(numValue * 100)
}
return value
}
// 默认返回原值(分值直接提交)
return value
}
/**
* 批量转换为分值(用于初始化表单显示)
*
* @description 将表单数据(元值)转换为分值格式(带两位小数)用于显示
* @param {Object} formData - 表单数据
* @returns {Object} 分值格式的数据
*/
const batchToYuanFunc = (formData) => {
// 遍历所有字段,转换为元值显示格式
const result = {}
for (const [key, value] of Object.entries(formData)) {
const definition = PLAN_FIELD_DEFINITIONS[key]
if (!definition) {
result[key] = value
continue
}
// 如果字段定义了 fen_to_yuan,表示 API 存的是分,需要转为元显示
if (definition.transform === TRANSFORM_TYPES.FEN_TO_YUAN) {
result[key] = fenToYuan(value)
} else {
result[key] = value
}
}
return result
}
/**
* 批量转换为分值(用于提交 API)
*
* @description 将表单的元值数据批量转换为分值整数
* @param {Object} yuanData - 元值数据
* @returns {Object} 分值数据
*/
const batchToFenFunc = (yuanData) => {
const result = {}
for (const [key, value] of Object.entries(yuanData)) {
const definition = PLAN_FIELD_DEFINITIONS[key]
if (!definition) {
result[key] = value
continue
}
// 元值转分值:×100
if (definition.transform === TRANSFORM_TYPES.FEN_TO_YUAN) {
const numValue = parseFloat(value)
if (!Number.isNaN(numValue)) {
result[key] = Math.round(numValue * 100)
} else {
result[key] = value
}
} else {
result[key] = value
}
}
return result
}
// 计算属性:表单显示数据(元值转分值显示)
const displayData = computed(() => {
return batchToYuanFunc(formData.value)
})
// 计算属性:API 提交数据(元值转分值)
const submitData = computed(() => {
return batchToFenFunc(formData.value)
})
return {
toYuan,
toFen,
batchToFen: batchToFenFunc, // 批量转换元→分
displayData, // 计算属性:表单显示数据(元值转分值显示)
submitData // 计算属性:API 提交数据(元值转分值)
}
}