Эх сурвалжийг харах

fix: restore family member menu + auto-derive generationLevel + add birth/preference form fields

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Sisyphus 2 сар өмнө
parent
commit
79342aa2bd

+ 108 - 1
cfc-frontend/pages/family/add-member.vue

@@ -41,6 +41,38 @@
         <view class="age-display">{{ calculatedAge || '根据出生日期自动计算' }}</view>
       </view>
 
+      <!-- 出生时辰(选填) -->
+      <view class="form-item">
+        <text class="label">出生时辰(选填)</text>
+        <picker :range="birthHourOptions" @change="onBirthHourChange">
+          <view class="picker">
+            {{ form.birthHourName || '请选择出生时辰' }}
+          </view>
+        </picker>
+      </view>
+
+      <!-- 出生体重(选填) -->
+      <view class="form-item">
+        <text class="label">出生体重(选填,克)</text>
+        <input class="input" type="number" v-model="form.birthWeight" placeholder="如: 3500" maxlength="5" />
+      </view>
+
+      <!-- 出生地(选填) -->
+      <view class="form-item">
+        <text class="label">出生地(选填)</text>
+        <input class="input" v-model="form.birthPlace" placeholder="如: 北京市" maxlength="30" />
+      </view>
+
+      <!-- 是否剖腹产(选填) -->
+      <view class="form-item">
+        <text class="label">是否剖腹产(选填)</text>
+        <picker :range="cesareanOptions" range-key="label" @change="onCesareanChange">
+          <view class="picker">
+            {{ form.cesareanLabel || '请选择' }}
+          </view>
+        </picker>
+      </view>
+
       <!-- 手机号(选填) -->
       <view class="form-item">
         <text class="label">手机号(选填)</text>
@@ -67,12 +99,23 @@ export default {
         relationshipType: '',
         gender: '',
         birthday: '',
-        phone: ''
+        phone: '',
+        birthHour: '',
+        birthHourName: '',
+        birthWeight: '',
+        birthPlace: '',
+        isCesarean: null,
+        cesareanLabel: ''
       },
       genderOptions: [
         { value: 'male', label: '男' },
         { value: 'female', label: '女' }
       ],
+      birthHourOptions: ['', '子时(23-1点)', '丑时(1-3点)', '寅时(3-5点)', '卯时(5-7点)', '辰时(7-9点)', '巳时(9-11点)', '午时(11-13点)', '未时(13-15点)', '申时(15-17点)', '酉时(17-19点)', '戌时(19-21点)', '亥时(21-23点)'],
+      cesareanOptions: [
+        { value: 0, label: '顺产' },
+        { value: 1, label: '剖腹产' }
+      ],
       todayDate: ''
     }
   },
@@ -104,6 +147,21 @@ export default {
     onBirthdayChange(e) {
       this.form.birthday = e.detail.value
     },
+    onBirthHourChange(e) {
+      var idx = e.detail.value
+      if (idx === 0) {
+        this.form.birthHour = ''
+        this.form.birthHourName = ''
+      } else {
+        this.form.birthHour = this.birthHourOptions[idx]
+        this.form.birthHourName = this.birthHourOptions[idx]
+      }
+    },
+    onCesareanChange(e) {
+      var idx = e.detail.value
+      this.form.isCesarean = this.cesareanOptions[idx].value
+      this.form.cesareanLabel = this.cesareanOptions[idx].label
+    },
     async submit() {
       if (!this.form.nickname || !this.form.nickname.trim()) {
         uni.showToast({ title: '请输入成员昵称', icon: 'none' })
@@ -126,17 +184,66 @@ export default {
         return
       }
 
+      // 根据 relationshipType 推导 generationLevel 和 peerType
+      var generationLevel = ''
+      var peerType = null
+      switch (this.form.relationshipType) {
+        case 'spouse':
+          generationLevel = 'peer'
+          peerType = 'spouse'
+          break
+        case 'sibling':
+          generationLevel = 'peer'
+          peerType = 'sibling'
+          break
+        case 'parent':
+          generationLevel = 'parent'
+          break
+        case 'child':
+          generationLevel = 'child'
+          break
+        case 'grandparent':
+          generationLevel = 'grandparent'
+          break
+        case 'grandchild':
+          generationLevel = 'grandchild'
+          break
+        case 'great_grandparent':
+          generationLevel = 'great_grandparent'
+          break
+        case 'great_grandchild':
+          generationLevel = 'great_grandchild'
+          break
+        default:
+          uni.showToast({ title: '无效的关系类型: ' + this.form.relationshipType, icon: 'none' })
+          return
+      }
+
       try {
         this.submitting = true
         var payload = {
           nickname: this.form.nickname.trim(),
           relationshipType: this.form.relationshipType,
+          generationLevel: generationLevel,
+          peerType: peerType,
           gender: this.form.gender,
           birthday: this.form.birthday
         }
         if (this.form.phone) {
           payload.phone = this.form.phone
         }
+        if (this.form.birthHour) {
+          payload.birthHour = this.form.birthHour
+        }
+        if (this.form.birthWeight) {
+          payload.birthWeight = parseInt(this.form.birthWeight)
+        }
+        if (this.form.birthPlace) {
+          payload.birthPlace = this.form.birthPlace
+        }
+        if (this.form.isCesarean !== null && this.form.isCesarean !== undefined) {
+          payload.isCesarean = this.form.isCesarean
+        }
         var res = await addFamilyMember(payload)
         if (res.code === 200) {
           uni.showToast({ title: '添加成功', icon: 'success' })

+ 7 - 0
cfc-frontend/pages/profile/components/ProfileMenu.vue

@@ -4,6 +4,10 @@
       <!-- ===== 个人 ===== -->
       <view class="menu-group">
         <view class="menu-group-title">── 个人 ──</view>
+        <view class="menu-item" v-if="role === 'parent'" @click="goToFamilyMembers">
+          <text>👨‍👩‍👧‍👦 家庭成员</text>
+          <text class="arrow">›</text>
+        </view>
         <view class="menu-item" @click="goToDailyTasks">
           <text>📋 每日任务</text>
           <text class="arrow">›</text>
@@ -143,6 +147,9 @@ export default {
     goToOnboarding() {
       uni.navigateTo({ url: '/pages/profile/onboarding' })
     },
+    goToFamilyMembers() {
+      uni.navigateTo({ url: '/pages/profile/family-members' })
+    },
     goToDailyTasks() {
       uni.navigateTo({ url: '/pages/tasks/daily-tasks' })
     },

+ 20 - 2
cfc-frontend/pages/user-edit/user-edit.vue

@@ -136,6 +136,18 @@
 				</picker>
 			</view>
 
+			<!-- 兴趣爱好 -->
+			<view class="form-item">
+				<text class="label">兴趣爱好</text>
+				<input type="text" v-model="form.hobbies" placeholder="如: 阅读、运动、音乐" class="input" maxlength="200" />
+			</view>
+
+			<!-- 饮食偏好 -->
+			<view class="form-item">
+				<text class="label">饮食偏好</text>
+				<input type="text" v-model="form.dietPreferences" placeholder="如: 清淡、无辣、低糖" class="input" maxlength="200" />
+			</view>
+
 			<!-- 成长规划师额外字段 -->
 			<view class="form-section-title" v-if="form.role === 'teacher'">成长规划师信息</view>
 			
@@ -261,7 +273,9 @@ export default {
 				ethnicity: '',
 				bloodType: '',
 				highestEducation: '',
-				maritalStatus: ''
+				maritalStatus: '',
+				hobbies: '',
+				dietPreferences: ''
 			},
 			ethnicityOptions: ['汉族','蒙古族','回族','藏族','维吾尔族','苗族','彝族','壮族','布依族','朝鲜族','满族','侗族','瑶族','白族','土家族','哈尼族','哈萨克族','傣族','黎族','其他'],
 			bloodTypeOptions: ['A','B','AB','O','未知'],
@@ -413,6 +427,8 @@ export default {
 					this.form.bloodType = userData.bloodType || ''
 					this.form.highestEducation = userData.highestEducation || ''
 					this.form.maritalStatus = userData.maritalStatus || ''
+					this.form.hobbies = userData.hobbies || ''
+					this.form.dietPreferences = userData.dietPreferences || ''
 					this.form.mascot = userData.mascot || ''
 				}
 			} catch (e) {
@@ -439,7 +455,9 @@ export default {
 					ethnicity: this.form.ethnicity,
 					bloodType: this.form.bloodType,
 					highestEducation: this.form.highestEducation,
-					maritalStatus: this.form.maritalStatus
+					maritalStatus: this.form.maritalStatus,
+					hobbies: this.form.hobbies,
+					dietPreferences: this.form.dietPreferences
 				})
 				uni.showToast({ title: '保存成功', icon: 'success' })
 				setTimeout(() => {