hookehuyr

feat(plan): 优化年龄与出生年月日联动逻辑

- 调整字段顺序:年龄在前,出生年月日在后
- 实现年龄 → 出生年月日自动计算(默认1月1日)
- 保留出生年月日 → 年龄双向联动
- 简化占位符文案,避免用户理解混乱
- 修复 AgePicker 组件不触发 change 事件的问题
- 添加调试日志便于排查问题

影响文件:
- src/components/PlanFields/AgePicker.vue: 添加 change 事件支持
- src/components/PlanTemplates/LifeInsuranceTemplate.vue: 调整逻辑
- src/components/PlanTemplates/CriticalIllnessTemplate.vue: 调整逻辑
- src/components/PlanTemplates/SavingsTemplate.vue: 调整逻辑

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
...@@ -109,6 +109,12 @@ const emit = defineEmits([ ...@@ -109,6 +109,12 @@ const emit = defineEmits([
109 */ 109 */
110 'update:modelValue', 110 'update:modelValue',
111 /** 111 /**
112 + * 值变化事件
113 + * @event change
114 + * @param {number} value - 选中的年龄(数字)
115 + */
116 + 'change',
117 + /**
112 * 弹窗打开事件 118 * 弹窗打开事件
113 * @event open 119 * @event open
114 */ 120 */
...@@ -245,7 +251,9 @@ const onConfirm = ({ selectedValue, selectedOptions }) => { ...@@ -245,7 +251,9 @@ const onConfirm = ({ selectedValue, selectedOptions }) => {
245 if (h !== undefined && t !== undefined && u !== undefined) { 251 if (h !== undefined && t !== undefined && u !== undefined) {
246 const age = parseInt(h) * 100 + parseInt(t) * 10 + parseInt(u) 252 const age = parseInt(h) * 100 + parseInt(t) * 10 + parseInt(u)
247 if (!Number.isNaN(age)) { 253 if (!Number.isNaN(age)) {
254 + console.log('[AgePicker] 确认选择年龄:', age)
248 emit('update:modelValue', age) 255 emit('update:modelValue', age)
256 + emit('change', age) // 触发 change 事件,供父组件监听
249 } else { 257 } else {
250 console.error('[AgePicker] 计算结果为 NaN', { h, t, u }) 258 console.error('[AgePicker] 计算结果为 NaN', { h, t, u })
251 } 259 }
......
...@@ -9,22 +9,23 @@ ...@@ -9,22 +9,23 @@
9 class="mb-5" 9 class="mb-5"
10 /> 10 />
11 11
12 - <!-- 出生年月日 --> 12 + <!-- 年龄(主字段,选择后自动计算出生年月日) -->
13 - <PlanFieldDatePicker 13 + <PlanFieldAgePicker
14 - v-model="form.birthday" 14 + v-model="form.age"
15 - label="出生年月日" 15 + label="年龄"
16 - placeholder="请选择日期" 16 + placeholder="请选择年龄"
17 :required="true" 17 :required="true"
18 - @change="onBirthdayChange" 18 + @change="onAgeChange"
19 class="mb-5" 19 class="mb-5"
20 /> 20 />
21 21
22 - <!-- 年龄(根据出生日期自动计算,可编辑 --> 22 + <!-- 出生年月日(根据年龄自动计算,可手动调整 -->
23 - <PlanFieldAgePicker 23 + <PlanFieldDatePicker
24 - v-model="form.age" 24 + v-model="form.birthday"
25 - label="年龄" 25 + label="出生年月日"
26 - placeholder="请选择出生日期自动计算" 26 + placeholder="请选择年月日"
27 :required="true" 27 :required="true"
28 + @change="onBirthdayChange"
28 class="mb-5" 29 class="mb-5"
29 /> 30 />
30 31
...@@ -142,6 +143,40 @@ watch( ...@@ -142,6 +143,40 @@ watch(
142 ) 143 )
143 144
144 /** 145 /**
146 + * 年龄变化时自动计算出生年月日
147 + * @param {number} age - 年龄
148 + *
149 + * @description 用户选择年龄后,自动计算并填充出生日期字段
150 + * 计算公式:当前年份 - 年龄 = 出生年份(默认1月1日)
151 + */
152 +const onAgeChange = (age) => {
153 + console.log('[CriticalIllnessTemplate] onAgeChange 触发,接收到的 age:', age, 'type:', typeof age)
154 +
155 + if (age !== undefined && age !== null && age !== '') {
156 + const currentYear = new Date().getFullYear()
157 + const birthYear = currentYear - age
158 +
159 + console.log('[CriticalIllnessTemplate] 计算出生年份:', {
160 + currentYear,
161 + age,
162 + birthYear
163 + })
164 +
165 + // 格式化为 YYYY-MM-DD,默认使用1月1日
166 + const month = String(1).padStart(2, '0')
167 + const day = String(1).padStart(2, '0')
168 + const birthday = `${birthYear}-${month}-${day}`
169 +
170 + console.log('[CriticalIllnessTemplate] 设置出生日期:', birthday)
171 + form.birthday = birthday
172 +
173 + console.log('[CriticalIllnessTemplate] form.birthday 设置后:', form.birthday)
174 + } else {
175 + console.log('[CriticalIllnessTemplate] age 无效,跳过计算')
176 + }
177 +}
178 +
179 +/**
145 * 出生日期变化时自动计算年龄 180 * 出生日期变化时自动计算年龄
146 * @param {string} birthday - 出生日期(格式:YYYY-MM-DD) 181 * @param {string} birthday - 出生日期(格式:YYYY-MM-DD)
147 * 182 *
......
...@@ -9,22 +9,23 @@ ...@@ -9,22 +9,23 @@
9 class="mb-5" 9 class="mb-5"
10 /> 10 />
11 11
12 - <!-- 出生年月日 --> 12 + <!-- 年龄(主字段,选择后自动计算出生年月日) -->
13 - <PlanFieldDatePicker 13 + <PlanFieldAgePicker
14 - v-model="form.birthday" 14 + v-model="form.age"
15 - label="出生年月日" 15 + label="年龄"
16 - placeholder="请选择日期" 16 + placeholder="请选择年龄"
17 :required="true" 17 :required="true"
18 - @change="onBirthdayChange" 18 + @change="onAgeChange"
19 class="mb-5" 19 class="mb-5"
20 /> 20 />
21 21
22 - <!-- 年龄(根据出生日期自动计算,可编辑 --> 22 + <!-- 出生年月日(根据年龄自动计算,可手动调整 -->
23 - <PlanFieldAgePicker 23 + <PlanFieldDatePicker
24 - v-model="form.age" 24 + v-model="form.birthday"
25 - label="年龄" 25 + label="出生年月日"
26 - placeholder="请选择出生日期自动计算" 26 + placeholder="请选择年月日"
27 :required="true" 27 :required="true"
28 + @change="onBirthdayChange"
28 class="mb-5" 29 class="mb-5"
29 /> 30 />
30 31
...@@ -142,6 +143,40 @@ watch( ...@@ -142,6 +143,40 @@ watch(
142 ) 143 )
143 144
144 /** 145 /**
146 + * 年龄变化时自动计算出生年月日
147 + * @param {number} age - 年龄
148 + *
149 + * @description 用户选择年龄后,自动计算并填充出生日期字段
150 + * 计算公式:当前年份 - 年龄 = 出生年份(默认1月1日)
151 + */
152 +const onAgeChange = (age) => {
153 + console.log('[LifeInsuranceTemplate] onAgeChange 触发,接收到的 age:', age, 'type:', typeof age)
154 +
155 + if (age !== undefined && age !== null && age !== '') {
156 + const currentYear = new Date().getFullYear()
157 + const birthYear = currentYear - age
158 +
159 + console.log('[LifeInsuranceTemplate] 计算出生年份:', {
160 + currentYear,
161 + age,
162 + birthYear
163 + })
164 +
165 + // 格式化为 YYYY-MM-DD,默认使用1月1日
166 + const month = String(1).padStart(2, '0')
167 + const day = String(1).padStart(2, '0')
168 + const birthday = `${birthYear}-${month}-${day}`
169 +
170 + console.log('[LifeInsuranceTemplate] 设置出生日期:', birthday)
171 + form.birthday = birthday
172 +
173 + console.log('[LifeInsuranceTemplate] form.birthday 设置后:', form.birthday)
174 + } else {
175 + console.log('[LifeInsuranceTemplate] age 无效,跳过计算')
176 + }
177 +}
178 +
179 +/**
145 * 出生日期变化时自动计算年龄 180 * 出生日期变化时自动计算年龄
146 * @param {string} birthday - 出生日期(格式:YYYY-MM-DD) 181 * @param {string} birthday - 出生日期(格式:YYYY-MM-DD)
147 * 182 *
......
...@@ -9,22 +9,23 @@ ...@@ -9,22 +9,23 @@
9 class="mb-5" 9 class="mb-5"
10 /> 10 />
11 11
12 - <!-- 出生年月日 --> 12 + <!-- 年龄(主字段,选择后自动计算出生年月日) -->
13 - <PlanFieldDatePicker 13 + <PlanFieldAgePicker
14 - v-model="form.birthday" 14 + v-model="form.age"
15 - label="出生年月日" 15 + label="年龄"
16 - placeholder="请选择日期" 16 + placeholder="请选择年龄"
17 :required="true" 17 :required="true"
18 - @change="onBirthdayChange" 18 + @change="onAgeChange"
19 class="mb-5" 19 class="mb-5"
20 /> 20 />
21 21
22 - <!-- 年龄(根据出生日期自动计算,可编辑 --> 22 + <!-- 出生年月日(根据年龄自动计算,可手动调整 -->
23 - <PlanFieldAgePicker 23 + <PlanFieldDatePicker
24 - v-model="form.age" 24 + v-model="form.birthday"
25 - label="年龄" 25 + label="出生年月日"
26 - placeholder="请选择出生日期自动计算" 26 + placeholder="请选择年月日"
27 :required="true" 27 :required="true"
28 + @change="onBirthdayChange"
28 class="mb-5" 29 class="mb-5"
29 /> 30 />
30 31
...@@ -304,6 +305,40 @@ const withdrawalPeriods = computed(() => { ...@@ -304,6 +305,40 @@ const withdrawalPeriods = computed(() => {
304 }) 305 })
305 306
306 /** 307 /**
308 + * 年龄变化时自动计算出生年月日
309 + * @param {number} age - 年龄
310 + *
311 + * @description 用户选择年龄后,自动计算并填充出生日期字段
312 + * 计算公式:当前年份 - 年龄 = 出生年份(默认1月1日)
313 + */
314 +const onAgeChange = (age) => {
315 + console.log('[SavingsTemplate] onAgeChange 触发,接收到的 age:', age, 'type:', typeof age)
316 +
317 + if (age !== undefined && age !== null && age !== '') {
318 + const currentYear = new Date().getFullYear()
319 + const birthYear = currentYear - age
320 +
321 + console.log('[SavingsTemplate] 计算出生年份:', {
322 + currentYear,
323 + age,
324 + birthYear
325 + })
326 +
327 + // 格式化为 YYYY-MM-DD,默认使用1月1日
328 + const month = String(1).padStart(2, '0')
329 + const day = String(1).padStart(2, '0')
330 + const birthday = `${birthYear}-${month}-${day}`
331 +
332 + console.log('[SavingsTemplate] 设置出生日期:', birthday)
333 + form.birthday = birthday
334 +
335 + console.log('[SavingsTemplate] form.birthday 设置后:', form.birthday)
336 + } else {
337 + console.log('[SavingsTemplate] age 无效,跳过计算')
338 + }
339 +}
340 +
341 +/**
307 * 出生日期变化时自动计算年龄 342 * 出生日期变化时自动计算年龄
308 * @param {string} birthday - 出生日期(格式:YYYY-MM-DD) 343 * @param {string} birthday - 出生日期(格式:YYYY-MM-DD)
309 * 344 *
...@@ -479,7 +514,4 @@ defineExpose({ ...@@ -479,7 +514,4 @@ defineExpose({
479 514
480 <style lang="less" scoped> 515 <style lang="less" scoped>
481 /* 提取计划区域样式 */ 516 /* 提取计划区域样式 */
482 -.withdrawal-plan-section {
483 - /* 可以在这里添加特殊的样式 */
484 -}
485 </style> 517 </style>
......