|
|
@@ -47,13 +47,16 @@
|
|
|
class="member-item"
|
|
|
v-for="member in familyMembers"
|
|
|
:key="member.id"
|
|
|
- :class="{ 'member-selected': selectedMemberId === member.userId }"
|
|
|
+ :class="{ 'member-selected': selectedMemberId === (member.userId || member.id) }"
|
|
|
@click="selectMember(member)"
|
|
|
>
|
|
|
<text class="member-avatar">{{ member.nickname ? member.nickname.substring(0, 1) : '?' }}</text>
|
|
|
<text class="member-name">{{ member.nickname || '未知' }}</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
+ <view class="add-member-btn" v-if="parsedInfo && parsedInfo.personName" @click="chooseRelationAndAdd">
|
|
|
+ <text class="add-member-text">+ 将「{{ parsedInfo.personName }}」添加为新成员</text>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
|
|
|
<!-- 表单 -->
|
|
|
@@ -209,7 +212,7 @@
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-import { createHealthReport, parseReportPreview, productList } from '../../utils/api.js'
|
|
|
+import { createHealthReport, parseReportPreview, productList, getFamilyMembers, addFamilyMember } from '../../utils/api.js'
|
|
|
import config from '@/config.js'
|
|
|
|
|
|
// 报告类型 → 维度映射(用于推荐商品)
|
|
|
@@ -424,6 +427,10 @@ export default {
|
|
|
if (detail.needBind) {
|
|
|
self.showMemberSelector = true
|
|
|
self.loadFamilyMembers()
|
|
|
+ // 未匹配到成员时,主动询问是否把解析到的人添加为新成员
|
|
|
+ if (self.parsedInfo.personName) {
|
|
|
+ self.promptAddParsedMember()
|
|
|
+ }
|
|
|
}
|
|
|
// 从解析结果自动填充报告日期
|
|
|
if (detail.extractedReportDate) {
|
|
|
@@ -438,22 +445,114 @@ export default {
|
|
|
},
|
|
|
loadFamilyMembers() {
|
|
|
var self = this
|
|
|
- // 从Vuex store获取家庭成员
|
|
|
- var store = uni.getStorageSync('familyChildren')
|
|
|
- if (store) {
|
|
|
- try {
|
|
|
- this.familyMembers = typeof store === 'string' ? JSON.parse(store) : store
|
|
|
- } catch (e) {
|
|
|
- this.familyMembers = []
|
|
|
- }
|
|
|
- }
|
|
|
+ // 从后端获取真实家庭成员(家长 + 孩子),storage 中并无该数据
|
|
|
+ getFamilyMembers().then(function(res) {
|
|
|
+ var data = (res && res.data) || {}
|
|
|
+ var parents = (data.parents || []).map(function(p) {
|
|
|
+ return { id: p.id, nickname: p.realName || p.nickname, gender: p.gender, role: 'parent' }
|
|
|
+ })
|
|
|
+ var children = (data.children || []).map(function(c) {
|
|
|
+ return { id: c.id, nickname: c.nickname, gender: c.gender, age: c.age, role: 'child' }
|
|
|
+ })
|
|
|
+ self.familyMembers = parents.concat(children)
|
|
|
+ }).catch(function(e) {
|
|
|
+ console.log('加载家庭成员失败', e)
|
|
|
+ self.familyMembers = []
|
|
|
+ })
|
|
|
},
|
|
|
selectMember(member) {
|
|
|
- this.selectedMemberId = member.userId || member.id
|
|
|
+ this.selectedMemberId = member.id || member.userId
|
|
|
this.parsedInfo = this.parsedInfo || {}
|
|
|
+ // 手动选择的成员通过 matchedMemberId 传递给确认页
|
|
|
+ this.parsedInfo.matchedMemberId = this.selectedMemberId
|
|
|
this.parsedInfo.needManualSelect = false
|
|
|
this.showMemberSelector = false
|
|
|
},
|
|
|
+ genderText(gender) {
|
|
|
+ if (gender === 'male') return '男'
|
|
|
+ if (gender === 'female') return '女'
|
|
|
+ return ''
|
|
|
+ },
|
|
|
+ // 询问是否将解析到的人添加为家庭成员
|
|
|
+ promptAddParsedMember() {
|
|
|
+ var self = this
|
|
|
+ if (!this.parsedInfo || !this.parsedInfo.personName) return
|
|
|
+ var name = this.parsedInfo.personName
|
|
|
+ var desc = name
|
|
|
+ var extra = []
|
|
|
+ var g = this.genderText(this.parsedInfo.extractedGender)
|
|
|
+ if (g) extra.push(g)
|
|
|
+ if (this.parsedInfo.extractedAge) extra.push(this.parsedInfo.extractedAge + '岁')
|
|
|
+ if (extra.length > 0) desc = name + '(' + extra.join(',') + ')'
|
|
|
+ uni.showModal({
|
|
|
+ title: '未匹配到家庭成员',
|
|
|
+ content: '是否将解析到的「' + desc + '」添加为家庭成员?',
|
|
|
+ confirmText: '添加',
|
|
|
+ cancelText: '手动选择',
|
|
|
+ success: function(res) {
|
|
|
+ if (res.confirm) {
|
|
|
+ self.chooseRelationAndAdd()
|
|
|
+ }
|
|
|
+ // 取消则保留下方的手动选择列表
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 选择新成员与家庭的关系(后端要求辈分必填)后添加
|
|
|
+ chooseRelationAndAdd() {
|
|
|
+ var self = this
|
|
|
+ var relOptions = [
|
|
|
+ { label: '孩子', generationLevel: 'child' },
|
|
|
+ { label: '配偶', generationLevel: 'peer', peerType: 'spouse' },
|
|
|
+ { label: '父母', generationLevel: 'parent' },
|
|
|
+ { label: '兄弟姐妹', generationLevel: 'peer', peerType: 'sibling' },
|
|
|
+ { label: '祖父母', generationLevel: 'grandparent' }
|
|
|
+ ]
|
|
|
+ uni.showActionSheet({
|
|
|
+ itemList: relOptions.map(function(o) { return o.label }),
|
|
|
+ success: function(res) {
|
|
|
+ var rel = relOptions[res.tapIndex]
|
|
|
+ if (rel) {
|
|
|
+ self.doAddParsedMember(rel)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 调用后端添加成员,并将其作为本次报告对象
|
|
|
+ doAddParsedMember(rel) {
|
|
|
+ var self = this
|
|
|
+ var name = this.parsedInfo.personName
|
|
|
+ var dto = {
|
|
|
+ nickname: name,
|
|
|
+ gender: this.parsedInfo.extractedGender || '',
|
|
|
+ generationLevel: rel.generationLevel
|
|
|
+ }
|
|
|
+ if (rel.peerType) dto.peerType = rel.peerType
|
|
|
+ // 由年龄推算大致出生年份(用于展示,用户后续可修改)
|
|
|
+ var age = parseInt(this.parsedInfo.extractedAge)
|
|
|
+ if (!isNaN(age) && age > 0 && age < 130) {
|
|
|
+ dto.birthday = (new Date().getFullYear() - age) + '-01-01'
|
|
|
+ }
|
|
|
+ uni.showLoading({ title: '添加成员...' })
|
|
|
+ addFamilyMember(dto).then(function(res) {
|
|
|
+ uni.hideLoading()
|
|
|
+ if (res && res.code === 200) {
|
|
|
+ var newId = res.data && (res.data.id || res.data.userId)
|
|
|
+ self.selectedMemberId = newId
|
|
|
+ self.parsedInfo.matchedMemberId = newId
|
|
|
+ self.parsedInfo.matchedMemberName = name
|
|
|
+ self.parsedInfo.needManualSelect = false
|
|
|
+ self.showMemberSelector = false
|
|
|
+ self.loadFamilyMembers()
|
|
|
+ uni.showToast({ title: '已添加并选中', icon: 'success' })
|
|
|
+ } else {
|
|
|
+ uni.showToast({ title: (res && res.message) || '添加失败', icon: 'none' })
|
|
|
+ }
|
|
|
+ }).catch(function(e) {
|
|
|
+ uni.hideLoading()
|
|
|
+ console.log('添加成员失败', e)
|
|
|
+ uni.showToast({ title: '添加失败,请重试', icon: 'none' })
|
|
|
+ })
|
|
|
+ },
|
|
|
removeFile() {
|
|
|
this.selectedFile = null
|
|
|
this.parsedInfo = null
|
|
|
@@ -915,6 +1014,18 @@ uni.showToast({ title: '提交成功', icon: 'success' })
|
|
|
font-size: 24rpx;
|
|
|
color: #333;
|
|
|
}
|
|
|
+.add-member-btn {
|
|
|
+ margin-top: 16rpx;
|
|
|
+ padding: 20rpx;
|
|
|
+ border: 1rpx dashed #4caf50;
|
|
|
+ border-radius: 12rpx;
|
|
|
+ text-align: center;
|
|
|
+ background: #f6fbf6;
|
|
|
+}
|
|
|
+.add-member-text {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #4caf50;
|
|
|
+}
|
|
|
|
|
|
/* ===== 舌诊拍照区 ===== */
|
|
|
.photo-area {
|