hookehuyr

fix(plan): 支持从出生年月日推算年龄判断多阶段提取方案

当用户只填了生日而没填年龄时,现在可以从 birthday 自动
推算年龄,用于判断是 3 阶段还是 1 阶段提取方案。

- 新增 effectiveAge 计算属性,优先使用 age,否则从 birthday 推算
- 更新 canAddStage、canRemoveStage、initializeStages 使用有效年龄
- 监听 effectiveAge 变化而不是只监听 form.age

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
## 2026-03-04
### 16:28:49 - fix(plan): 支持从出生年月日推算年龄判断多阶段提取方案
**影响文件**:
- `无`
**变更摘要**:
- 支持从出生年月日推算年龄判断多阶段提取方案
---
# 变更日志
记录项目开发过程中的重要变更和完成任务。
......
......@@ -363,6 +363,40 @@ const isMultiStageMode = computed(() => {
})
/**
* 有效年龄(用于阶段判断)
* @description 优先使用填写的 age,否则从 birthday 推算年龄
*/
const effectiveAge = computed(() => {
// 1. 优先使用填写的年龄
if (form.age && form.age !== '') {
const parsedAge = parseInt(form.age)
if (!Number.isNaN(parsedAge)) {
return parsedAge
}
}
// 2. 从生日推算年龄
if (form.birthday && form.birthday !== '') {
const birthDate = new Date(form.birthday)
if (!Number.isNaN(birthDate.getTime())) {
const today = new Date()
let age = today.getFullYear() - birthDate.getFullYear()
const monthDiff = today.getMonth() - birthDate.getMonth()
// 如果还没到生日,年龄减1
if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {
age--
}
return age
}
}
// 3. 都没有,返回0
return 0
})
/**
* 多阶段配置对象(便捷访问)
*/
const multiStageConfig = computed(() => {
......@@ -386,10 +420,10 @@ const stages = ref([])
/**
* 是否可添加阶段
* @description 年龄 ≥ 阈值且未达上限
* @description 有效年龄 ≥ 阈值且未达上限
*/
const canAddStage = computed(() => {
const age = parseInt(form.age) || 0
const age = effectiveAge.value
const threshold = multiStageConfig.value.age_threshold || 12
const limit = multiStageConfig.value.stage_limit || 4
return age >= threshold && stages.value.length < limit
......@@ -397,10 +431,10 @@ const canAddStage = computed(() => {
/**
* 是否可删除阶段
* @description 年龄 ≥ 阈值且至少有2个阶段
* @description 有效年龄 ≥ 阈值且至少有2个阶段
*/
const canRemoveStage = computed(() => {
const age = parseInt(form.age) || 0
const age = effectiveAge.value
const threshold = multiStageConfig.value.age_threshold || 12
return age >= threshold && stages.value.length > 1
})
......@@ -468,25 +502,26 @@ const createStage = () => {
/**
* 初始化阶段数据
* @description 根据年龄初始化阶段数量:
* @description 根据有效年龄初始化阶段数量:
* - 年龄 < 12岁:固定 3 组
* - 年龄 ≥ 12岁:初始 1 组
* - 有效年龄优先使用 age,否则从 birthday 推算
*/
const initializeStages = () => {
console.log('=== initializeStages() 调用 ===')
console.log('form.age:', form.age)
const age = parseInt(form.age) || 0
console.log('form.age:', form.age, 'form.birthday:', form.birthday)
const age = effectiveAge.value
const threshold = multiStageConfig.value.age_threshold || 12
console.log('age:', age, 'threshold:', threshold)
console.log('effectiveAge:', age, 'threshold:', threshold)
if (age < threshold) {
// 固定 3 组
stages.value = [createStage(), createStage(), createStage()]
console.log('初始化 3 组阶段')
console.log('初始化 3 组阶段(年龄 < 12')
} else {
// 初始 1 组
stages.value = [createStage()]
console.log('初始化 1 组阶段')
console.log('初始化 1 组阶段(年龄 12')
}
console.log('stages.value:', stages.value)
}
......@@ -608,18 +643,19 @@ watch(
{ deep: true }
)
// 监听年龄变化,重新初始化阶段(仅在多阶段模式下)
// 监听有效年龄变化,重新初始化阶段(仅在多阶段模式下)
// 有效年龄变化可能由 age 或 birthday 引起
watch(
() => form.age,
effectiveAge,
(newAge, oldAge) => {
if (isMultiStageMode.value && newAge !== oldAge && newAge !== undefined) {
if (isMultiStageMode.value && newAge !== oldAge) {
const threshold = multiStageConfig.value.age_threshold || 12
const newAgeInt = parseInt(newAge) || 0
const oldAgeInt = parseInt(oldAge) || 0
// 跨越阈值时重新初始化
if ((newAgeInt < threshold && oldAgeInt >= threshold) ||
(newAgeInt >= threshold && oldAgeInt < threshold)) {
if ((newAge < threshold && oldAge >= threshold) ||
(newAge >= threshold && oldAge < threshold)) {
console.log('=== 有效年龄跨越阈值,重新初始化阶段 ===')
console.log('oldAge:', oldAge, 'newAge:', newAge, 'threshold:', threshold)
initializeStages()
}
}
......