|
@@ -1,325 +1,66 @@
|
|
|
<template>
|
|
<template>
|
|
|
- <view class="container">
|
|
|
|
|
- <view class="form-container">
|
|
|
|
|
- <view class="page-title">编辑孩子信息</view>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 姓名(必填) -->
|
|
|
|
|
- <view class="form-item required">
|
|
|
|
|
- <text class="label"><text class="required-mark">*</text>孩子姓名</text>
|
|
|
|
|
- <input class="input" v-model="form.nickname" placeholder="请输入孩子姓名" />
|
|
|
|
|
- </view>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 出生日期(必填) -->
|
|
|
|
|
- <view class="form-item required">
|
|
|
|
|
- <text class="label"><text class="required-mark">*</text>出生日期</text>
|
|
|
|
|
- <picker mode="date" :value="form.birthday" @change="onBirthdayChange" :end="todayDate">
|
|
|
|
|
- <view class="picker">
|
|
|
|
|
- {{ form.birthday || '请选择出生日期' }}
|
|
|
|
|
- </view>
|
|
|
|
|
- </picker>
|
|
|
|
|
- </view>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 性别(必填) -->
|
|
|
|
|
- <view class="form-item required">
|
|
|
|
|
- <text class="label"><text class="required-mark">*</text>性别</text>
|
|
|
|
|
- <picker :range="genderOptions" range-key="label" @change="onGenderChange">
|
|
|
|
|
- <view class="picker">
|
|
|
|
|
- {{ genderLabel || '请选择性别' }}
|
|
|
|
|
- </view>
|
|
|
|
|
- </picker>
|
|
|
|
|
- </view>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 年龄(根据出生日期自动计算) -->
|
|
|
|
|
- <view class="form-item">
|
|
|
|
|
- <text class="label">年龄</text>
|
|
|
|
|
- <view class="age-display">{{ calculatedAge || '根据出生日期自动计算' }}</view>
|
|
|
|
|
- </view>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 手机号(非必填) -->
|
|
|
|
|
- <view class="form-item">
|
|
|
|
|
- <text class="label">手机号(选填)</text>
|
|
|
|
|
- <input class="input" type="number" v-model="form.phone" placeholder="请输入手机号" maxlength="11" />
|
|
|
|
|
- </view>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 身份证号(非必填) -->
|
|
|
|
|
- <view class="form-item">
|
|
|
|
|
- <text class="label">身份证号(选填)</text>
|
|
|
|
|
- <input class="input" v-model="form.idCard" placeholder="请输入身份证号" maxlength="18" />
|
|
|
|
|
- </view>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 扣分开关(仅 children 系统支持) -->
|
|
|
|
|
- <view class="form-item" v-if="!isFamilyMember">
|
|
|
|
|
- <text class="label">扣分开关</text>
|
|
|
|
|
- <switch :checked="form.penaltyEnabled === 1" @change="onPenaltyChange" color="#F97316" />
|
|
|
|
|
- <text class="hint">开启后,超时未完成任务将扣减积分</text>
|
|
|
|
|
- </view>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 对家庭成员可见(仅 children 系统支持) -->
|
|
|
|
|
- <view class="form-item" v-if="!isFamilyMember">
|
|
|
|
|
- <text class="label">对家庭成员可见</text>
|
|
|
|
|
- <switch :checked="form.showToFamily !== 0" @change="onShowToFamilyChange" color="#5B9BD5" />
|
|
|
|
|
- <text class="hint">关闭后,其他家庭成员将看不到此孩子</text>
|
|
|
|
|
- </view>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 主题风格(仅 children 系统支持) -->
|
|
|
|
|
- <view class="form-item" v-if="!isFamilyMember">
|
|
|
|
|
- <text class="label">主题风格</text>
|
|
|
|
|
- <picker :range="themes" range-key="label" @change="onThemeChange">
|
|
|
|
|
- <view class="picker">
|
|
|
|
|
- {{ currentThemeLabel || '请选择主题' }}
|
|
|
|
|
- </view>
|
|
|
|
|
- </picker>
|
|
|
|
|
- </view>
|
|
|
|
|
-
|
|
|
|
|
- <button class="btn-primary" :loading="submitting" @click="submit">保存修改</button>
|
|
|
|
|
|
|
+ <view class="redirect-container">
|
|
|
|
|
+ <view class="redirect-card">
|
|
|
|
|
+ <text class="redirect-icon">👪</text>
|
|
|
|
|
+ <text class="redirect-title">请在「家庭成员」中编辑信息</text>
|
|
|
|
|
+ <text class="redirect-desc">孩子的信息编辑已整合到家庭成员管理中</text>
|
|
|
|
|
+ <button class="redirect-btn" @click="goToFamilyMembers">前往家庭成员</button>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
|
<script>
|
|
|
-import { getChildren, updateChild, updateFamilyMember } from '../../utils/api.js'
|
|
|
|
|
-
|
|
|
|
|
export default {
|
|
export default {
|
|
|
- data() {
|
|
|
|
|
- return {
|
|
|
|
|
- childId: '',
|
|
|
|
|
- memberId: '',
|
|
|
|
|
- isFamilyMember: false,
|
|
|
|
|
- submitting: false,
|
|
|
|
|
- form: {
|
|
|
|
|
- nickname: '',
|
|
|
|
|
- birthday: '',
|
|
|
|
|
- gender: '',
|
|
|
|
|
- age: '',
|
|
|
|
|
- phone: '',
|
|
|
|
|
- idCard: '',
|
|
|
|
|
- penaltyEnabled: 1,
|
|
|
|
|
- showToFamily: 1,
|
|
|
|
|
- theme: 'default'
|
|
|
|
|
- },
|
|
|
|
|
- genderOptions: [
|
|
|
|
|
- { value: 'male', label: '男' },
|
|
|
|
|
- { value: 'female', label: '女' }
|
|
|
|
|
- ],
|
|
|
|
|
- themes: [
|
|
|
|
|
- { value: 'default', label: '默认' },
|
|
|
|
|
- { value: 'ocean', label: '海洋' },
|
|
|
|
|
- { value: 'forest', label: '森林' },
|
|
|
|
|
- { value: 'sunset', label: '日落' }
|
|
|
|
|
- ]
|
|
|
|
|
- }
|
|
|
|
|
- },
|
|
|
|
|
- computed: {
|
|
|
|
|
- currentThemeLabel() {
|
|
|
|
|
- const theme = this.themes.find(t => t.value === this.form.theme)
|
|
|
|
|
- return theme ? theme.label : '默认'
|
|
|
|
|
- },
|
|
|
|
|
- genderLabel() {
|
|
|
|
|
- const gender = this.genderOptions.find(g => g.value === this.form.gender)
|
|
|
|
|
- return gender ? gender.label : ''
|
|
|
|
|
- },
|
|
|
|
|
- todayDate() {
|
|
|
|
|
- return new Date().toISOString().split('T')[0]
|
|
|
|
|
- },
|
|
|
|
|
- calculatedAge() {
|
|
|
|
|
- if (!this.form.birthday) return ''
|
|
|
|
|
- const birth = new Date(this.form.birthday)
|
|
|
|
|
- const today = new Date()
|
|
|
|
|
- let age = today.getFullYear() - birth.getFullYear()
|
|
|
|
|
- const monthDiff = today.getMonth() - birth.getMonth()
|
|
|
|
|
- if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birth.getDate())) {
|
|
|
|
|
- age--
|
|
|
|
|
- }
|
|
|
|
|
- return age > 0 ? age + '岁' : ''
|
|
|
|
|
- }
|
|
|
|
|
- },
|
|
|
|
|
- onLoad(options) {
|
|
|
|
|
- this.childId = options.childId || ''
|
|
|
|
|
- this.memberId = options.memberId || ''
|
|
|
|
|
- if (!this.childId && !this.memberId) {
|
|
|
|
|
- uni.showToast({ title: '参数错误', icon: 'none' })
|
|
|
|
|
- setTimeout(() => uni.navigateBack(), 1500)
|
|
|
|
|
- return
|
|
|
|
|
- }
|
|
|
|
|
- // 优先按 childId 从 children 系统加载,找不到则按 memberId 从 family-member 系统加载
|
|
|
|
|
- if (this.childId) {
|
|
|
|
|
- this.loadChildData()
|
|
|
|
|
- } else {
|
|
|
|
|
- this.isFamilyMember = true
|
|
|
|
|
- this.loadFamilyMemberData(options)
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ onShow() {
|
|
|
|
|
+ uni.redirectTo({ url: '/pages/profile-extra/family-members' })
|
|
|
},
|
|
},
|
|
|
methods: {
|
|
methods: {
|
|
|
- async loadChildData() {
|
|
|
|
|
- try {
|
|
|
|
|
- const res = await getChildren()
|
|
|
|
|
- const children = res.data || []
|
|
|
|
|
- const child = children.find(c => c.id == this.childId)
|
|
|
|
|
- if (child) {
|
|
|
|
|
- this.form = {
|
|
|
|
|
- nickname: child.nickname || '',
|
|
|
|
|
- birthday: child.birthday || '',
|
|
|
|
|
- gender: child.gender || '',
|
|
|
|
|
- age: child.age || '',
|
|
|
|
|
- phone: child.phone || '',
|
|
|
|
|
- idCard: child.idCard || '',
|
|
|
|
|
- penaltyEnabled: child.penaltyEnabled !== 0 ? 1 : 0,
|
|
|
|
|
- showToFamily: child.showToFamily !== 0 ? 1 : 0,
|
|
|
|
|
- theme: child.theme || 'default'
|
|
|
|
|
- }
|
|
|
|
|
- } else {
|
|
|
|
|
- // children 系统找不到,尝试作为 family member 加载
|
|
|
|
|
- this.isFamilyMember = true
|
|
|
|
|
- this.memberId = this.childId
|
|
|
|
|
- this.childId = ''
|
|
|
|
|
- }
|
|
|
|
|
- } catch (e) {
|
|
|
|
|
- console.error('加载孩子数据失败', e)
|
|
|
|
|
- uni.showToast({ title: '加载失败', icon: 'none' })
|
|
|
|
|
- }
|
|
|
|
|
- },
|
|
|
|
|
- loadFamilyMemberData(options) {
|
|
|
|
|
- // 从 URL 参数中填充基本信息(family member 系统字段有限)
|
|
|
|
|
- this.form.nickname = options.nickname ? decodeURIComponent(options.nickname) : ''
|
|
|
|
|
- this.form.gender = options.gender || ''
|
|
|
|
|
- this.form.phone = options.phone || ''
|
|
|
|
|
- this.form.birthday = options.birthday || ''
|
|
|
|
|
- },
|
|
|
|
|
- onBirthdayChange(e) {
|
|
|
|
|
- this.form.birthday = e.detail.value
|
|
|
|
|
- // 根据出生日期自动计算年龄
|
|
|
|
|
- const birth = new Date(e.detail.value)
|
|
|
|
|
- const today = new Date()
|
|
|
|
|
- let age = today.getFullYear() - birth.getFullYear()
|
|
|
|
|
- const monthDiff = today.getMonth() - birth.getMonth()
|
|
|
|
|
- if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birth.getDate())) {
|
|
|
|
|
- age--
|
|
|
|
|
- }
|
|
|
|
|
- this.form.age = age
|
|
|
|
|
- },
|
|
|
|
|
- onGenderChange(e) {
|
|
|
|
|
- this.form.gender = this.genderOptions[e.detail.value].value
|
|
|
|
|
- },
|
|
|
|
|
- onPenaltyChange(e) {
|
|
|
|
|
- this.form.penaltyEnabled = e.detail.value ? 1 : 0
|
|
|
|
|
- },
|
|
|
|
|
- onShowToFamilyChange(e) {
|
|
|
|
|
- this.form.showToFamily = e.detail.value ? 1 : 0
|
|
|
|
|
- },
|
|
|
|
|
- onThemeChange(e) {
|
|
|
|
|
- this.form.theme = this.themes[e.detail.value].value
|
|
|
|
|
- },
|
|
|
|
|
- async submit() {
|
|
|
|
|
- if (!this.form.nickname) {
|
|
|
|
|
- uni.showToast({ title: '请输入孩子姓名', icon: 'none' })
|
|
|
|
|
- return
|
|
|
|
|
- }
|
|
|
|
|
- if (!this.form.birthday) {
|
|
|
|
|
- uni.showToast({ title: '请选择出生日期', icon: 'none' })
|
|
|
|
|
- return
|
|
|
|
|
- }
|
|
|
|
|
- if (!this.form.gender) {
|
|
|
|
|
- uni.showToast({ title: '请选择性别', icon: 'none' })
|
|
|
|
|
- return
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- this.submitting = true
|
|
|
|
|
- try {
|
|
|
|
|
- if (this.isFamilyMember) {
|
|
|
|
|
- await updateFamilyMember({
|
|
|
|
|
- memberId: this.memberId,
|
|
|
|
|
- nickname: this.form.nickname,
|
|
|
|
|
- birthday: this.form.birthday,
|
|
|
|
|
- gender: this.form.gender,
|
|
|
|
|
- phone: this.form.phone
|
|
|
|
|
- })
|
|
|
|
|
- } else {
|
|
|
|
|
- await updateChild(this.childId, {
|
|
|
|
|
- nickname: this.form.nickname,
|
|
|
|
|
- birthday: this.form.birthday,
|
|
|
|
|
- gender: this.form.gender,
|
|
|
|
|
- age: this.form.age,
|
|
|
|
|
- phone: this.form.phone,
|
|
|
|
|
- idCard: this.form.idCard,
|
|
|
|
|
- penaltyEnabled: this.form.penaltyEnabled,
|
|
|
|
|
- showToFamily: this.form.showToFamily,
|
|
|
|
|
- theme: this.form.theme
|
|
|
|
|
- })
|
|
|
|
|
- }
|
|
|
|
|
- uni.showToast({ title: '保存成功', icon: 'success' })
|
|
|
|
|
- setTimeout(() => uni.navigateBack(), 1500)
|
|
|
|
|
- } catch (e) {
|
|
|
|
|
- console.error('保存失败', e)
|
|
|
|
|
- uni.showToast({ title: '保存失败', icon: 'none' })
|
|
|
|
|
- } finally {
|
|
|
|
|
- this.submitting = false
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ goToFamilyMembers() {
|
|
|
|
|
+ uni.redirectTo({ url: '/pages/profile-extra/family-members' })
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped>
|
|
<style scoped>
|
|
|
-.container {
|
|
|
|
|
- padding: 30rpx;
|
|
|
|
|
|
|
+.redirect-container {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ min-height: 100vh;
|
|
|
|
|
+ background: #f5f5f5;
|
|
|
|
|
+ padding: 40rpx;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-.form-container {
|
|
|
|
|
|
|
+.redirect-card {
|
|
|
background: #fff;
|
|
background: #fff;
|
|
|
border-radius: 20rpx;
|
|
border-radius: 20rpx;
|
|
|
- padding: 30rpx;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.page-title {
|
|
|
|
|
- font-size: 36rpx;
|
|
|
|
|
- font-weight: bold;
|
|
|
|
|
|
|
+ padding: 60rpx 40rpx;
|
|
|
text-align: center;
|
|
text-align: center;
|
|
|
- margin-bottom: 40rpx;
|
|
|
|
|
|
|
+ width: 100%;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-.form-item {
|
|
|
|
|
- margin-bottom: 30rpx;
|
|
|
|
|
|
|
+.redirect-icon {
|
|
|
|
|
+ font-size: 80rpx;
|
|
|
|
|
+ display: block;
|
|
|
|
|
+ margin-bottom: 24rpx;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-.form-item.required .label {
|
|
|
|
|
|
|
+.redirect-title {
|
|
|
|
|
+ font-size: 32rpx;
|
|
|
font-weight: bold;
|
|
font-weight: bold;
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.required-mark {
|
|
|
|
|
- color: #F97316;
|
|
|
|
|
- margin-right: 8rpx;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.label {
|
|
|
|
|
- display: block;
|
|
|
|
|
- font-size: 28rpx;
|
|
|
|
|
color: #333;
|
|
color: #333;
|
|
|
- margin-bottom: 10rpx;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.input, .picker {
|
|
|
|
|
- border: 1rpx solid #ddd;
|
|
|
|
|
- border-radius: 10rpx;
|
|
|
|
|
- padding: 20rpx;
|
|
|
|
|
- font-size: 28rpx;
|
|
|
|
|
|
|
+ display: block;
|
|
|
|
|
+ margin-bottom: 16rpx;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-.age-display {
|
|
|
|
|
|
|
+.redirect-desc {
|
|
|
font-size: 28rpx;
|
|
font-size: 28rpx;
|
|
|
color: #666;
|
|
color: #666;
|
|
|
- padding: 20rpx;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.hint {
|
|
|
|
|
display: block;
|
|
display: block;
|
|
|
- font-size: 24rpx;
|
|
|
|
|
- color: #999;
|
|
|
|
|
- margin-top: 10rpx;
|
|
|
|
|
|
|
+ margin-bottom: 40rpx;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-.btn-primary {
|
|
|
|
|
- background: linear-gradient(135deg, #F97316, #FB923C);
|
|
|
|
|
|
|
+.redirect-btn {
|
|
|
|
|
+ background: #07c160;
|
|
|
color: #fff;
|
|
color: #fff;
|
|
|
- margin-top: 40rpx;
|
|
|
|
|
|
|
+ border-radius: 44rpx;
|
|
|
|
|
+ font-size: 30rpx;
|
|
|
|
|
+ padding: 20rpx 60rpx;
|
|
|
}
|
|
}
|
|
|
</style>
|
|
</style>
|