hookehuyr

refactor(plan): 提取提交数据转换逻辑为独立工具函数

将 PlanFormContainer 中内联的金额转换逻辑抽取到
planSubmitTransformers.js,支持函数式和字符串式 transform 策略,
新增 withdrawal_stages 字段的分转元转换。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
...@@ -50,6 +50,10 @@ import SavingsTemplate from './PlanTemplates/SavingsTemplate.vue' ...@@ -50,6 +50,10 @@ import SavingsTemplate from './PlanTemplates/SavingsTemplate.vue'
50 import { PLAN_TEMPLATES } from '@/config/plan-templates' 50 import { PLAN_TEMPLATES } from '@/config/plan-templates'
51 import { addAPI } from '@/api/plan' 51 import { addAPI } from '@/api/plan'
52 import { useFieldValueTransform } from '@/composables/useFieldValueTransform' 52 import { useFieldValueTransform } from '@/composables/useFieldValueTransform'
53 +import {
54 + transformSubmitValue,
55 + transformWithdrawalStagesForSubmit
56 +} from '@/utils/planSubmitTransformers'
53 57
54 /** 58 /**
55 * 组件属性 59 * 组件属性
...@@ -280,6 +284,7 @@ const submit = async () => { ...@@ -280,6 +284,7 @@ const submit = async () => {
280 withdrawal_method: { api_field: 'withdrawal_method' }, 284 withdrawal_method: { api_field: 'withdrawal_method' },
281 annual_withdrawal_amount: { api_field: 'annual_withdrawal_amount', transform: 'fen_to_yuan' }, 285 annual_withdrawal_amount: { api_field: 'annual_withdrawal_amount', transform: 'fen_to_yuan' },
282 annual_increase_percentage: { api_field: 'annual_increase_percentage' }, 286 annual_increase_percentage: { api_field: 'annual_increase_percentage' },
287 + withdrawal_stages: { api_field: 'withdrawal_stages', transform: transformWithdrawalStagesForSubmit },
283 withdrawal_start_age_specified: { api_field: 'withdrawal_start_age' }, 288 withdrawal_start_age_specified: { api_field: 'withdrawal_start_age' },
284 withdrawal_period_specified: { api_field: 'withdrawal_period' }, 289 withdrawal_period_specified: { api_field: 'withdrawal_period' },
285 withdrawal_start_age_fixed: { api_field: 'withdrawal_start_age' }, 290 withdrawal_start_age_fixed: { api_field: 'withdrawal_start_age' },
...@@ -301,10 +306,12 @@ const submit = async () => { ...@@ -301,10 +306,12 @@ const submit = async () => {
301 if (mapping) { 306 if (mapping) {
302 const apiField = typeof mapping === 'string' ? mapping : mapping.api_field 307 const apiField = typeof mapping === 'string' ? mapping : mapping.api_field
303 let value = formData.value[key] 308 let value = formData.value[key]
304 - // 金额字段从分转换为元 309 + value = transformSubmitValue({
305 - if (typeof mapping === 'object' && mapping.transform === 'fen_to_yuan' && value !== null && value !== undefined && value !== '') { 310 + fieldKey: key,
306 - value = toYuan(key, value) 311 + value,
307 - } 312 + mapping,
313 + toYuan
314 + })
308 requestData[apiField] = value 315 requestData[apiField] = value
309 } else { 316 } else {
310 requestData[key] = formData.value[key] 317 requestData[key] = formData.value[key]
......
...@@ -34,6 +34,8 @@ ...@@ -34,6 +34,8 @@
34 * form_sn: "life-insurance-wiop3e" // 对应下面的配置 key 34 * form_sn: "life-insurance-wiop3e" // 对应下面的配置 key
35 * } 35 * }
36 */ 36 */
37 +import { transformWithdrawalStagesForSubmit } from '@/utils/planSubmitTransformers'
38 +
37 // 基础提交字段映射(适用于人寿/重疾等通用表单) 39 // 基础提交字段映射(适用于人寿/重疾等通用表单)
38 const baseSubmitMapping = { 40 const baseSubmitMapping = {
39 customer_name: { api_field: 'customer_name' }, 41 customer_name: { api_field: 'customer_name' },
...@@ -76,6 +78,7 @@ const savingsSubmitMapping = { ...@@ -76,6 +78,7 @@ const savingsSubmitMapping = {
76 withdrawal_method: { api_field: 'withdrawal_method' }, 78 withdrawal_method: { api_field: 'withdrawal_method' },
77 annual_withdrawal_amount: { api_field: 'annual_withdrawal_amount', transform: 'fen_to_yuan' }, 79 annual_withdrawal_amount: { api_field: 'annual_withdrawal_amount', transform: 'fen_to_yuan' },
78 annual_increase_percentage: { api_field: 'annual_increase_percentage' }, 80 annual_increase_percentage: { api_field: 'annual_increase_percentage' },
81 + withdrawal_stages: { api_field: 'withdrawal_stages', transform: transformWithdrawalStagesForSubmit },
79 withdrawal_start_age_specified: { api_field: 'withdrawal_start_age' }, 82 withdrawal_start_age_specified: { api_field: 'withdrawal_start_age' },
80 withdrawal_period_specified: { api_field: 'withdrawal_period' }, 83 withdrawal_period_specified: { api_field: 'withdrawal_period' },
81 withdrawal_start_age_fixed: { api_field: 'withdrawal_start_age' }, 84 withdrawal_start_age_fixed: { api_field: 'withdrawal_start_age' },
......
1 +import { describe, expect, it, vi } from 'vitest'
2 +import {
3 + transformSubmitValue,
4 + transformWithdrawalStagesForSubmit
5 +} from '../planSubmitTransformers'
6 +
7 +describe('transformWithdrawalStagesForSubmit', () => {
8 + it('should convert withdrawal stage amount from fen to yuan', () => {
9 + const result = transformWithdrawalStagesForSubmit([
10 + {
11 + annual_withdrawal_amount: 12300,
12 + withdrawal_start_age: 18,
13 + withdrawal_period: '1年',
14 + annual_increase_percentage: '12'
15 + }
16 + ])
17 +
18 + expect(result).toEqual([
19 + {
20 + annual_withdrawal_amount: '123.00',
21 + withdrawal_start_age: 18,
22 + withdrawal_period: '1年',
23 + annual_increase_percentage: '12'
24 + }
25 + ])
26 + })
27 +
28 + it('should keep empty stage amount unchanged', () => {
29 + const result = transformWithdrawalStagesForSubmit([
30 + {
31 + annual_withdrawal_amount: null,
32 + withdrawal_start_age: 18
33 + }
34 + ])
35 +
36 + expect(result[0].annual_withdrawal_amount).toBeNull()
37 + })
38 +})
39 +
40 +describe('transformSubmitValue', () => {
41 + it('should use fen_to_yuan mapping for simple amount fields', () => {
42 + const toYuan = vi.fn().mockReturnValue('123.00')
43 +
44 + const result = transformSubmitValue({
45 + fieldKey: 'annual_withdrawal_amount',
46 + value: 12300,
47 + mapping: {
48 + api_field: 'annual_withdrawal_amount',
49 + transform: 'fen_to_yuan'
50 + },
51 + toYuan
52 + })
53 +
54 + expect(result).toBe('123.00')
55 + expect(toYuan).toHaveBeenCalledWith('annual_withdrawal_amount', 12300)
56 + })
57 +
58 + it('should use custom mapping transform for withdrawal stages', () => {
59 + const result = transformSubmitValue({
60 + fieldKey: 'withdrawal_stages',
61 + value: [
62 + {
63 + annual_withdrawal_amount: 12300,
64 + withdrawal_start_age: 18
65 + }
66 + ],
67 + mapping: {
68 + api_field: 'withdrawal_stages',
69 + transform: transformWithdrawalStagesForSubmit
70 + },
71 + toYuan: vi.fn()
72 + })
73 +
74 + expect(result).toEqual([
75 + {
76 + annual_withdrawal_amount: '123.00',
77 + withdrawal_start_age: 18
78 + }
79 + ])
80 + })
81 +})
1 +import { TRANSFORM_TYPES } from '@/config/plan-fields'
2 +import { fenToYuan } from './planFieldTransformers'
3 +
4 +const hasValue = (value) => value !== null && value !== undefined && value !== ''
5 +
6 +export function transformWithdrawalStagesForSubmit(value) {
7 + if (!Array.isArray(value)) {
8 + return value
9 + }
10 +
11 + return value.map(stage => {
12 + if (!stage || typeof stage !== 'object') {
13 + return stage
14 + }
15 +
16 + return {
17 + ...stage,
18 + annual_withdrawal_amount: hasValue(stage.annual_withdrawal_amount)
19 + ? fenToYuan(stage.annual_withdrawal_amount)
20 + : stage.annual_withdrawal_amount
21 + }
22 + })
23 +}
24 +
25 +export function transformSubmitValue({ fieldKey, value, mapping, toYuan }) {
26 + if (!mapping || typeof mapping === 'string') {
27 + return value
28 + }
29 +
30 + if (typeof mapping.transform === 'function') {
31 + return mapping.transform(value, { fieldKey, mapping, toYuan })
32 + }
33 +
34 + if (mapping.transform === TRANSFORM_TYPES.FEN_TO_YUAN && hasValue(value)) {
35 + return toYuan(fieldKey, value)
36 + }
37 +
38 + return value
39 +}