|
@@ -1,109 +1,101 @@
|
|
|
<template>
|
|
<template>
|
|
|
<view class="container">
|
|
<view class="container">
|
|
|
- <!-- 家庭信息头部 -->
|
|
|
|
|
|
|
+ <!-- ===== 家庭信息头部 (带齿轮入口) ===== -->
|
|
|
<view class="family-header" v-if="familyName">
|
|
<view class="family-header" v-if="familyName">
|
|
|
- <view class="family-header-icon">🏠</view>
|
|
|
|
|
- <text class="family-name">{{ familyName }}</text>
|
|
|
|
|
- <text class="family-member-count">{{ members.length }} 位成员</text>
|
|
|
|
|
|
|
+ <view class="family-header-content">
|
|
|
|
|
+ <view class="family-header-icon">🏠</view>
|
|
|
|
|
+ <view class="family-header-text">
|
|
|
|
|
+ <text class="family-name">{{ familyName }}</text>
|
|
|
|
|
+ <text class="family-member-count">{{ members.length }} 位成员</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="header-settings-btn" @click="showSettings = true">
|
|
|
|
|
+ <text class="settings-gear-icon">⚙️</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
- <!-- 操作按钮组 -->
|
|
|
|
|
- <view class="action-bar">
|
|
|
|
|
- <view class="action-btn add-btn" @click="onAddMember">
|
|
|
|
|
- <text class="action-icon">+</text>
|
|
|
|
|
- <text class="action-text">添加成员</text>
|
|
|
|
|
- </view>
|
|
|
|
|
- <view class="action-btn invite-btn" @click="onInvite">
|
|
|
|
|
- <text class="action-icon">📨</text>
|
|
|
|
|
- <text class="action-text">邀请成员</text>
|
|
|
|
|
- </view>
|
|
|
|
|
|
|
+ <!-- ===== 关系标签筛选项 ===== -->
|
|
|
|
|
+ <view class="filter-tabs">
|
|
|
|
|
+ <view class="filter-tab" :class="{active: filterType === 'all'}" @click="filterType = 'all'">全部</view>
|
|
|
|
|
+ <view class="filter-tab" :class="{active: filterType === 'parent'}" @click="filterType = 'parent'">家长</view>
|
|
|
|
|
+ <view class="filter-tab" :class="{active: filterType === 'child'}" @click="filterType = 'child'">孩子</view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
- <!-- 家长组 -->
|
|
|
|
|
- <view class="section-title">家长 ({{ parentMembers.length }})</view>
|
|
|
|
|
|
|
+ <!-- ===== 成员列表(点击行→详情弹窗) ===== -->
|
|
|
<view class="member-list">
|
|
<view class="member-list">
|
|
|
- <view class="member-item" v-for="m in parentMembers" :key="m.id">
|
|
|
|
|
|
|
+ <view class="member-item" v-for="m in filteredMembers" :key="m.id" @click="showMemberDetail(m)">
|
|
|
<image class="member-avatar" :src="m.avatar || '/static/default-avatar.png'" mode="aspectFill"></image>
|
|
<image class="member-avatar" :src="m.avatar || '/static/default-avatar.png'" mode="aspectFill"></image>
|
|
|
<view class="member-detail">
|
|
<view class="member-detail">
|
|
|
<text class="member-name">{{ m.nickname || '未设置' }}</text>
|
|
<text class="member-name">{{ m.nickname || '未设置' }}</text>
|
|
|
<view class="member-tags">
|
|
<view class="member-tags">
|
|
|
- <text class="member-role-tag">{{ m.relativeLabel || m.roleLabel || '家长' }}</text>
|
|
|
|
|
|
|
+ <text class="member-role-tag">{{ m.relativeLabel || m.roleLabel || (m.effectiveRole === 'parent' ? '家长' : '孩子') }}</text>
|
|
|
<text class="member-source-tag" v-if="m.source === 'family_member'">手动添加</text>
|
|
<text class="member-source-tag" v-if="m.source === 'family_member'">手动添加</text>
|
|
|
|
|
+ <text class="member-extra" v-if="m.age"> {{ m.age }}岁</text>
|
|
|
|
|
+ <text class="member-extra" v-if="m.gender"> · {{ m.gender === 'male' ? '男' : '女' }}</text>
|
|
|
</view>
|
|
</view>
|
|
|
<!-- 三维评分进度条 -->
|
|
<!-- 三维评分进度条 -->
|
|
|
- <view class="member-quality-scores" v-if="qualityScores[m.id]">
|
|
|
|
|
|
|
+ <view class="member-quality-scores" v-if="memberScores[m.id]">
|
|
|
<view class="score-item">
|
|
<view class="score-item">
|
|
|
<text class="score-label">信任</text>
|
|
<text class="score-label">信任</text>
|
|
|
<view class="score-bar-bg">
|
|
<view class="score-bar-bg">
|
|
|
- <view class="score-bar-fill trust" :style="{width: (qualityScores[m.id].trustScore || 0) + '%'}"></view>
|
|
|
|
|
|
|
+ <view class="score-bar-fill trust" :style="{width: (memberScores[m.id].trustScore || 0) + '%'}"></view>
|
|
|
</view>
|
|
</view>
|
|
|
- <text class="score-value">{{ Math.round(qualityScores[m.id].trustScore || 0) }}</text>
|
|
|
|
|
|
|
+ <text class="score-value">{{ Math.round(memberScores[m.id].trustScore || 0) }}</text>
|
|
|
</view>
|
|
</view>
|
|
|
<view class="score-item">
|
|
<view class="score-item">
|
|
|
<text class="score-label">亲密</text>
|
|
<text class="score-label">亲密</text>
|
|
|
<view class="score-bar-bg">
|
|
<view class="score-bar-bg">
|
|
|
- <view class="score-bar-fill intimacy" :style="{width: (qualityScores[m.id].intimacyScore || 0) + '%'}"></view>
|
|
|
|
|
|
|
+ <view class="score-bar-fill intimacy" :style="{width: (memberScores[m.id].intimacyScore || 0) + '%'}"></view>
|
|
|
</view>
|
|
</view>
|
|
|
- <text class="score-value">{{ Math.round(qualityScores[m.id].intimacyScore || 0) }}</text>
|
|
|
|
|
|
|
+ <text class="score-value">{{ Math.round(memberScores[m.id].intimacyScore || 0) }}</text>
|
|
|
</view>
|
|
</view>
|
|
|
<view class="score-item">
|
|
<view class="score-item">
|
|
|
<text class="score-label">沟通</text>
|
|
<text class="score-label">沟通</text>
|
|
|
<view class="score-bar-bg">
|
|
<view class="score-bar-bg">
|
|
|
- <view class="score-bar-fill communication" :style="{width: (qualityScores[m.id].communicationScore || 0) + '%'}"></view>
|
|
|
|
|
|
|
+ <view class="score-bar-fill communication" :style="{width: (memberScores[m.id].communicationScore || 0) + '%'}"></view>
|
|
|
</view>
|
|
</view>
|
|
|
- <text class="score-value">{{ Math.round(qualityScores[m.id].communicationScore || 0) }}</text>
|
|
|
|
|
|
|
+ <text class="score-value">{{ Math.round(memberScores[m.id].communicationScore || 0) }}</text>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
- <button class="btn-switch" v-if="m.source !== 'parent' || m.id !== userId" @click="onSwitchMember(m)">切换</button>
|
|
|
|
|
- <button class="btn-edit" v-if="m.source === 'family_member'" @click="onEditRelation(m)">编辑</button>
|
|
|
|
|
- <button class="btn-kick" v-if="isAdmin && m.source === 'family_member'" @click="confirmKick(m)">移除</button>
|
|
|
|
|
|
|
+ <text class="member-arrow">›</text>
|
|
|
</view>
|
|
</view>
|
|
|
- <view v-if="parentMembers.length === 0" class="empty-row">
|
|
|
|
|
- <text class="empty-text">暂无家长成员</text>
|
|
|
|
|
|
|
+ <view v-if="filteredMembers.length === 0" class="empty-row">
|
|
|
|
|
+ <text class="empty-text">暂无成员</text>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
- <!-- 孩子组 -->
|
|
|
|
|
- <view class="section-title">
|
|
|
|
|
- 孩子 ({{ childMembers.length }})
|
|
|
|
|
- </view>
|
|
|
|
|
- <view class="member-list">
|
|
|
|
|
- <view class="member-item" v-for="m in childMembers" :key="m.id">
|
|
|
|
|
- <view class="member-avatar child-avatar">👶</view>
|
|
|
|
|
- <view class="member-detail">
|
|
|
|
|
- <text class="member-name">{{ m.nickname || '未设置' }}</text>
|
|
|
|
|
- <view class="member-tags">
|
|
|
|
|
- <text class="member-role-tag">{{ m.relativeLabel || m.roleLabel || '孩子' }}</text>
|
|
|
|
|
- <text class="member-source-tag" v-if="m.source === 'family_member'">手动添加</text>
|
|
|
|
|
- <text class="member-extra" v-if="m.age"> {{ m.age }}岁</text>
|
|
|
|
|
- <text class="member-extra" v-if="m.gender"> · {{ m.gender === 'male' ? '男' : '女' }}</text>
|
|
|
|
|
|
|
+ <!-- ===== Settings 弹窗(齿轮入口) ===== -->
|
|
|
|
|
+ <view class="modal-mask" v-if="showSettings" @click="showSettings = false">
|
|
|
|
|
+ <view class="settings-card" @click.stop>
|
|
|
|
|
+ <view class="settings-header">
|
|
|
|
|
+ <text class="settings-title">成员管理</text>
|
|
|
|
|
+ <text class="settings-close" @click="showSettings = false">×</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="settings-body">
|
|
|
|
|
+ <view class="settings-item" @click="onAddMember">
|
|
|
|
|
+ <text class="settings-item-icon">+</text>
|
|
|
|
|
+ <text class="settings-item-text">添加成员</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="settings-item" @click="onInvite">
|
|
|
|
|
+ <text class="settings-item-icon">📨</text>
|
|
|
|
|
+ <text class="settings-item-text">邀请成员</text>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
- <button class="btn-switch" @click="onSwitchMember(m)">切换</button>
|
|
|
|
|
- <button class="btn-edit" v-if="m.source === 'family_member'" @click="onEditRelation(m)">编辑</button>
|
|
|
|
|
- <button class="btn-kick" v-if="isAdmin && m.source === 'family_member'" @click="confirmKick(m)">移除</button>
|
|
|
|
|
- </view>
|
|
|
|
|
- <view v-if="childMembers.length === 0" class="empty-row">
|
|
|
|
|
- <text class="empty-text">暂无孩子成员</text>
|
|
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
- <!-- 邀请卡片弹窗 -->
|
|
|
|
|
|
|
+ <!-- ===== 邀请卡片弹窗 ===== -->
|
|
|
<view class="modal-mask" v-if="showInviteCard" @click="showInviteCard = false">
|
|
<view class="modal-mask" v-if="showInviteCard" @click="showInviteCard = false">
|
|
|
<view class="invite-card" @click.stop>
|
|
<view class="invite-card" @click.stop>
|
|
|
<text class="invite-card-title">邀请家庭成员</text>
|
|
<text class="invite-card-title">邀请家庭成员</text>
|
|
|
<text class="invite-card-family">{{ familyName }}</text>
|
|
<text class="invite-card-family">{{ familyName }}</text>
|
|
|
-
|
|
|
|
|
- <!-- 二维码 -->
|
|
|
|
|
<view class="invite-qr-wrap" v-if="inviteQrCode">
|
|
<view class="invite-qr-wrap" v-if="inviteQrCode">
|
|
|
<image class="invite-qr" :src="inviteQrCode" mode="widthFix" />
|
|
<image class="invite-qr" :src="inviteQrCode" mode="widthFix" />
|
|
|
</view>
|
|
</view>
|
|
|
<view class="invite-qr-wrap loading-qr" v-else>
|
|
<view class="invite-qr-wrap loading-qr" v-else>
|
|
|
<text class="loading-text">生成二维码中...</text>
|
|
<text class="loading-text">生成二维码中...</text>
|
|
|
</view>
|
|
</view>
|
|
|
-
|
|
|
|
|
- <!-- 邀请码 -->
|
|
|
|
|
<view class="invite-code-section">
|
|
<view class="invite-code-section">
|
|
|
<text class="invite-code-label">邀请码</text>
|
|
<text class="invite-code-label">邀请码</text>
|
|
|
<view class="invite-code-row">
|
|
<view class="invite-code-row">
|
|
@@ -111,28 +103,68 @@
|
|
|
<button class="copy-btn" @click="onCopyCode">复制</button>
|
|
<button class="copy-btn" @click="onCopyCode">复制</button>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
-
|
|
|
|
|
<text class="invite-tip">让好友在「我的」页面输入邀请码加入家庭</text>
|
|
<text class="invite-tip">让好友在「我的」页面输入邀请码加入家庭</text>
|
|
|
<button class="close-btn" @click="showInviteCard = false">关闭</button>
|
|
<button class="close-btn" @click="showInviteCard = false">关闭</button>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
- <!-- 编辑关系弹窗 -->
|
|
|
|
|
- <view class="modal-mask" v-if="showEditRelation" @click="showEditRelation = false">
|
|
|
|
|
- <view class="edit-relation-card" @click.stop>
|
|
|
|
|
- <text class="edit-relation-title">编辑成员关系</text>
|
|
|
|
|
- <view class="edit-relation-member">
|
|
|
|
|
- <text class="edit-relation-name">{{ editTargetMember && editTargetMember.nickname || '' }}</text>
|
|
|
|
|
|
|
+ <!-- ===== 成员详情弹窗 ===== -->
|
|
|
|
|
+ <view class="modal-mask" v-if="showMemberDetailModal" @click="showMemberDetailModal = false">
|
|
|
|
|
+ <view class="member-detail-card" @click.stop>
|
|
|
|
|
+ <view class="detail-header">
|
|
|
|
|
+ <image class="detail-avatar" :src="detailMember && (detailMember.avatar || '/static/default-avatar.png')" mode="aspectFill"></image>
|
|
|
|
|
+ <view class="detail-info">
|
|
|
|
|
+ <text class="detail-name">{{ detailMember && detailMember.nickname || '' }}</text>
|
|
|
|
|
+ <text class="detail-relation">{{ detailMember && (detailMember.relativeLabel || detailMember.roleLabel || '') }}</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <text class="detail-close" @click="showMemberDetailModal = false">×</text>
|
|
|
</view>
|
|
</view>
|
|
|
- <relationship-picker v-model="editRelationType" />
|
|
|
|
|
- <view class="edit-relation-actions">
|
|
|
|
|
- <button class="btn-cancel" @click="showEditRelation = false">取消</button>
|
|
|
|
|
- <button class="btn-save" @click="onSaveRelation">保存</button>
|
|
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 详情:性别/年龄/手机号 -->
|
|
|
|
|
+ <view class="detail-meta">
|
|
|
|
|
+ <text class="detail-meta-item" v-if="detailMember && detailMember.gender">性别: {{ detailMember.gender === 'male' ? '男' : '女' }}</text>
|
|
|
|
|
+ <text class="detail-meta-item" v-if="detailMember && detailMember.age">{{ detailMember.age }}岁</text>
|
|
|
|
|
+ <text class="detail-meta-item" v-if="detailMember && detailMember.phone">{{ detailMember.phone }}</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 三维评分展示 -->
|
|
|
|
|
+ <view class="detail-scores">
|
|
|
|
|
+ <text class="detail-section-title">关系质量</text>
|
|
|
|
|
+ <view class="detail-score-item">
|
|
|
|
|
+ <text class="detail-score-label">信任</text>
|
|
|
|
|
+ <view class="detail-score-bar-bg">
|
|
|
|
|
+ <view class="detail-score-bar-fill trust" :style="{width: (detailMemberScores.trustScore || 0) + '%'}"></view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <text class="detail-score-value">{{ Math.round(detailMemberScores.trustScore || 0) }}</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="detail-score-item">
|
|
|
|
|
+ <text class="detail-score-label">亲密</text>
|
|
|
|
|
+ <view class="detail-score-bar-bg">
|
|
|
|
|
+ <view class="detail-score-bar-fill intimacy" :style="{width: (detailMemberScores.intimacyScore || 0) + '%'}"></view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <text class="detail-score-value">{{ Math.round(detailMemberScores.intimacyScore || 0) }}</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="detail-score-item">
|
|
|
|
|
+ <text class="detail-score-label">沟通</text>
|
|
|
|
|
+ <view class="detail-score-bar-bg">
|
|
|
|
|
+ <view class="detail-score-bar-fill communication" :style="{width: (detailMemberScores.communicationScore || 0) + '%'}"></view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <text class="detail-score-value">{{ Math.round(detailMemberScores.communicationScore || 0) }}</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 操作按钮 -->
|
|
|
|
|
+ <view class="detail-actions">
|
|
|
|
|
+ <button class="detail-action-btn action-switch" @click="onSwitchMember(detailMember)" v-if="!(detailMember.source === 'parent' && detailMember.userId === userId)">切换身份</button>
|
|
|
|
|
+ <button class="detail-action-btn action-edit" @click="onEditRelation(detailMember)" v-if="canEditMember(detailMember)">编辑资料</button>
|
|
|
|
|
+ <button class="detail-action-btn action-questionnaire" @click="doQuestionnaire(detailMember)">关系问卷</button>
|
|
|
|
|
+ <button class="detail-action-btn action-interaction" @click="recordInteraction(detailMember)">记录互动</button>
|
|
|
|
|
+ <button class="detail-action-btn action-kick" @click="confirmKick(detailMember)" v-if="isAdmin && detailMember.source === 'family_member'">移出家庭</button>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
- <!-- 加载状态 -->
|
|
|
|
|
|
|
+ <!-- ===== 加载状态 ===== -->
|
|
|
<view v-if="loading" class="loading-wrap">
|
|
<view v-if="loading" class="loading-wrap">
|
|
|
<text class="loading-text">加载中...</text>
|
|
<text class="loading-text">加载中...</text>
|
|
|
</view>
|
|
</view>
|
|
@@ -146,16 +178,11 @@ import {
|
|
|
kickFamilyMemberById,
|
|
kickFamilyMemberById,
|
|
|
generateFamilyInviteQrCode,
|
|
generateFamilyInviteQrCode,
|
|
|
getFamilyMembers,
|
|
getFamilyMembers,
|
|
|
- updateFamilyMember,
|
|
|
|
|
- getRelationshipScores,
|
|
|
|
|
- generateQuestionnaire,
|
|
|
|
|
- addInteraction
|
|
|
|
|
|
|
+ updateFamilyMember
|
|
|
} from '../../utils/api.js'
|
|
} from '../../utils/api.js'
|
|
|
import store from '../../store/index.js'
|
|
import store from '../../store/index.js'
|
|
|
-import RelationshipPicker from '../../components/RelationshipPicker.vue'
|
|
|
|
|
|
|
|
|
|
export default {
|
|
export default {
|
|
|
- components: { RelationshipPicker },
|
|
|
|
|
data() {
|
|
data() {
|
|
|
return {
|
|
return {
|
|
|
userId: 0,
|
|
userId: 0,
|
|
@@ -167,22 +194,25 @@ export default {
|
|
|
members: [],
|
|
members: [],
|
|
|
isAdmin: false,
|
|
isAdmin: false,
|
|
|
loading: false,
|
|
loading: false,
|
|
|
|
|
+ filterType: 'all',
|
|
|
|
|
+ showSettings: false,
|
|
|
showInviteCard: false,
|
|
showInviteCard: false,
|
|
|
- showEditRelation: false,
|
|
|
|
|
- editTargetMember: null,
|
|
|
|
|
- editRelationType: '',
|
|
|
|
|
- qualityScores: {}
|
|
|
|
|
|
|
+ showMemberDetailModal: false,
|
|
|
|
|
+ detailMember: null,
|
|
|
|
|
+ memberScores: {}
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
computed: {
|
|
computed: {
|
|
|
- parentMembers() {
|
|
|
|
|
- return this.members.filter(function(m) { return m.effectiveRole === 'parent' })
|
|
|
|
|
- },
|
|
|
|
|
- childMembers() {
|
|
|
|
|
- return this.members.filter(function(m) { return m.effectiveRole === 'child' })
|
|
|
|
|
|
|
+ filteredMembers() {
|
|
|
|
|
+ var self = this
|
|
|
|
|
+ if (this.filterType === 'all') return this.members
|
|
|
|
|
+ return this.members.filter(function(m) {
|
|
|
|
|
+ return m.effectiveRole === self.filterType
|
|
|
|
|
+ })
|
|
|
},
|
|
},
|
|
|
- editableMembers() {
|
|
|
|
|
- return this.members.filter(function(m) { return m.source === 'family_member' })
|
|
|
|
|
|
|
+ detailMemberScores() {
|
|
|
|
|
+ if (!this.detailMember) return {}
|
|
|
|
|
+ return this.memberScores[this.detailMember.id] || {}
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
onShow() {
|
|
onShow() {
|
|
@@ -197,8 +227,7 @@ export default {
|
|
|
var res = await listFamilyMembers()
|
|
var res = await listFamilyMembers()
|
|
|
if (res.code === 200 && res.data) {
|
|
if (res.code === 200 && res.data) {
|
|
|
this.members = res.data || []
|
|
this.members = res.data || []
|
|
|
- // 从members中提取家庭信息(取第一个parent的familyId等)
|
|
|
|
|
- // 仍需调用旧接口获取家庭名/邀请码/creatorId
|
|
|
|
|
|
|
+ this.buildScoreMap(res.data)
|
|
|
this.loadFamilyInfo()
|
|
this.loadFamilyInfo()
|
|
|
}
|
|
}
|
|
|
} catch (e) {
|
|
} catch (e) {
|
|
@@ -207,6 +236,20 @@ export default {
|
|
|
this.loading = false
|
|
this.loading = false
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
|
|
+ buildScoreMap(members) {
|
|
|
|
|
+ var map = {}
|
|
|
|
|
+ if (members && members.length) {
|
|
|
|
|
+ for (var i = 0; i < members.length; i++) {
|
|
|
|
|
+ var m = members[i]
|
|
|
|
|
+ map[m.id] = {
|
|
|
|
|
+ trustScore: m.trustScore || 0,
|
|
|
|
|
+ intimacyScore: m.intimacyScore || 0,
|
|
|
|
|
+ communicationScore: m.communicationScore || 0
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ this.memberScores = map
|
|
|
|
|
+ },
|
|
|
async loadFamilyInfo() {
|
|
async loadFamilyInfo() {
|
|
|
try {
|
|
try {
|
|
|
var res = await getFamilyMembers()
|
|
var res = await getFamilyMembers()
|
|
@@ -222,11 +265,21 @@ export default {
|
|
|
// 静默处理
|
|
// 静默处理
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
|
|
+ showMemberDetail(member) {
|
|
|
|
|
+ this.detailMember = member
|
|
|
|
|
+ this.showMemberDetailModal = true
|
|
|
|
|
+ },
|
|
|
|
|
+ canEditMember(member) {
|
|
|
|
|
+ // 可编辑规则:非登录用户(无userId关联)
|
|
|
|
|
+ if (member.userId) return false
|
|
|
|
|
+ return member.source === 'family_member'
|
|
|
|
|
+ },
|
|
|
onAddMember() {
|
|
onAddMember() {
|
|
|
|
|
+ this.showSettings = false
|
|
|
uni.navigateTo({ url: '/pages/family/add-member' })
|
|
uni.navigateTo({ url: '/pages/family/add-member' })
|
|
|
},
|
|
},
|
|
|
-
|
|
|
|
|
async onSwitchMember(member) {
|
|
async onSwitchMember(member) {
|
|
|
|
|
+ this.showMemberDetailModal = false
|
|
|
try {
|
|
try {
|
|
|
var res = await switchToFamilyMember(member.id, member.source)
|
|
var res = await switchToFamilyMember(member.id, member.source)
|
|
|
if (res.code === 200 && res.data) {
|
|
if (res.code === 200 && res.data) {
|
|
@@ -258,6 +311,7 @@ export default {
|
|
|
})
|
|
})
|
|
|
},
|
|
},
|
|
|
async onKickMember(member) {
|
|
async onKickMember(member) {
|
|
|
|
|
+ this.showMemberDetailModal = false
|
|
|
try {
|
|
try {
|
|
|
var res = await kickFamilyMemberById(member.id)
|
|
var res = await kickFamilyMemberById(member.id)
|
|
|
if (res.code === 200) {
|
|
if (res.code === 200) {
|
|
@@ -271,6 +325,7 @@ export default {
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
async onInvite() {
|
|
async onInvite() {
|
|
|
|
|
+ this.showSettings = false
|
|
|
this.showInviteCard = true
|
|
this.showInviteCard = true
|
|
|
this.inviteQrCode = ''
|
|
this.inviteQrCode = ''
|
|
|
try {
|
|
try {
|
|
@@ -294,36 +349,16 @@ export default {
|
|
|
})
|
|
})
|
|
|
},
|
|
},
|
|
|
onEditRelation(member) {
|
|
onEditRelation(member) {
|
|
|
- this.editTargetMember = member
|
|
|
|
|
- this.editRelationType = member.relationshipType || ''
|
|
|
|
|
- this.showEditRelation = true
|
|
|
|
|
|
|
+ this.showMemberDetailModal = false
|
|
|
|
|
+ uni.navigateTo({ url: '/pages/profile/user-edit?memberId=' + member.id + '&nickname=' + encodeURIComponent(member.nickname || '') })
|
|
|
},
|
|
},
|
|
|
doQuestionnaire(member) {
|
|
doQuestionnaire(member) {
|
|
|
|
|
+ this.showMemberDetailModal = false
|
|
|
uni.navigateTo({ url: '/pages/action/relationship-questionnaire?memberId=' + member.id })
|
|
uni.navigateTo({ url: '/pages/action/relationship-questionnaire?memberId=' + member.id })
|
|
|
},
|
|
},
|
|
|
recordInteraction(member) {
|
|
recordInteraction(member) {
|
|
|
|
|
+ this.showMemberDetailModal = false
|
|
|
uni.navigateTo({ url: '/pages/action/interaction-log?memberId=' + member.id })
|
|
uni.navigateTo({ url: '/pages/action/interaction-log?memberId=' + member.id })
|
|
|
- },
|
|
|
|
|
- async onSaveRelation() {
|
|
|
|
|
- if (!this.editTargetMember || !this.editRelationType) {
|
|
|
|
|
- uni.showToast({ title: '请选择关系类型', icon: 'none' })
|
|
|
|
|
- return
|
|
|
|
|
- }
|
|
|
|
|
- try {
|
|
|
|
|
- var res = await updateFamilyMember({
|
|
|
|
|
- memberId: this.editTargetMember.id,
|
|
|
|
|
- relationshipType: this.editRelationType
|
|
|
|
|
- })
|
|
|
|
|
- if (res.code === 200) {
|
|
|
|
|
- uni.showToast({ title: '修改成功', icon: 'success' })
|
|
|
|
|
- this.showEditRelation = false
|
|
|
|
|
- this.loadMembers()
|
|
|
|
|
- } else {
|
|
|
|
|
- uni.showToast({ title: res.message || '修改失败', icon: 'none' })
|
|
|
|
|
- }
|
|
|
|
|
- } catch (e) {
|
|
|
|
|
- uni.showToast({ title: '修改失败', icon: 'none' })
|
|
|
|
|
- }
|
|
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -336,72 +371,76 @@ export default {
|
|
|
background: #f5f7fa;
|
|
background: #f5f7fa;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/* 家庭信息头部 */
|
|
|
|
|
|
|
+/* ===== 家庭信息头部(带齿轮入口) ===== */
|
|
|
.family-header {
|
|
.family-header {
|
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
|
border-radius: 20rpx;
|
|
border-radius: 20rpx;
|
|
|
- padding: 40rpx 30rpx;
|
|
|
|
|
- margin-bottom: 24rpx;
|
|
|
|
|
- text-align: center;
|
|
|
|
|
|
|
+ padding: 30rpx 30rpx;
|
|
|
|
|
+ margin-bottom: 20rpx;
|
|
|
color: #fff;
|
|
color: #fff;
|
|
|
}
|
|
}
|
|
|
|
|
+.family-header-content {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+}
|
|
|
.family-header-icon {
|
|
.family-header-icon {
|
|
|
- font-size: 56rpx;
|
|
|
|
|
- margin-bottom: 12rpx;
|
|
|
|
|
|
|
+ font-size: 48rpx;
|
|
|
|
|
+ margin-right: 16rpx;
|
|
|
|
|
+}
|
|
|
|
|
+.family-header-text {
|
|
|
|
|
+ flex: 1;
|
|
|
}
|
|
}
|
|
|
.family-name {
|
|
.family-name {
|
|
|
- font-size: 36rpx;
|
|
|
|
|
|
|
+ font-size: 34rpx;
|
|
|
font-weight: bold;
|
|
font-weight: bold;
|
|
|
display: block;
|
|
display: block;
|
|
|
}
|
|
}
|
|
|
.family-member-count {
|
|
.family-member-count {
|
|
|
- font-size: 26rpx;
|
|
|
|
|
|
|
+ font-size: 24rpx;
|
|
|
opacity: 0.85;
|
|
opacity: 0.85;
|
|
|
- margin-top: 8rpx;
|
|
|
|
|
|
|
+ margin-top: 4rpx;
|
|
|
display: block;
|
|
display: block;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-/* 操作按钮栏 */
|
|
|
|
|
-.action-bar {
|
|
|
|
|
- display: flex;
|
|
|
|
|
- gap: 20rpx;
|
|
|
|
|
- margin-bottom: 24rpx;
|
|
|
|
|
-}
|
|
|
|
|
-.action-btn {
|
|
|
|
|
- flex: 1;
|
|
|
|
|
|
|
+.header-settings-btn {
|
|
|
|
|
+ width: 64rpx;
|
|
|
|
|
+ height: 64rpx;
|
|
|
display: flex;
|
|
display: flex;
|
|
|
align-items: center;
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
justify-content: center;
|
|
|
- background: #fff;
|
|
|
|
|
- border-radius: 16rpx;
|
|
|
|
|
- padding: 24rpx 0;
|
|
|
|
|
- box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
|
|
|
|
|
-}
|
|
|
|
|
-.action-btn:active {
|
|
|
|
|
- opacity: 0.8;
|
|
|
|
|
|
|
+ border-radius: 50%;
|
|
|
|
|
+ background: rgba(255,255,255,0.2);
|
|
|
}
|
|
}
|
|
|
-.action-icon {
|
|
|
|
|
- font-size: 32rpx;
|
|
|
|
|
- margin-right: 8rpx;
|
|
|
|
|
|
|
+.header-settings-btn:active {
|
|
|
|
|
+ background: rgba(255,255,255,0.35);
|
|
|
}
|
|
}
|
|
|
-.action-text {
|
|
|
|
|
- font-size: 28rpx;
|
|
|
|
|
- font-weight: 500;
|
|
|
|
|
- color: #333;
|
|
|
|
|
|
|
+.settings-gear-icon {
|
|
|
|
|
+ font-size: 36rpx;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/* 分区标题 */
|
|
|
|
|
-.section-title {
|
|
|
|
|
- font-size: 30rpx;
|
|
|
|
|
- font-weight: bold;
|
|
|
|
|
- margin: 20rpx 0 16rpx;
|
|
|
|
|
- padding-left: 10rpx;
|
|
|
|
|
|
|
+/* ===== 筛选标签 ===== */
|
|
|
|
|
+.filter-tabs {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
- align-items: center;
|
|
|
|
|
- justify-content: space-between;
|
|
|
|
|
|
|
+ gap: 12rpx;
|
|
|
|
|
+ margin-bottom: 20rpx;
|
|
|
|
|
+}
|
|
|
|
|
+.filter-tab {
|
|
|
|
|
+ padding: 8rpx 28rpx;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ border-radius: 30rpx;
|
|
|
|
|
+ font-size: 26rpx;
|
|
|
|
|
+ color: #666;
|
|
|
|
|
+ box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.04);
|
|
|
|
|
+}
|
|
|
|
|
+.filter-tab.active {
|
|
|
|
|
+ background: #667eea;
|
|
|
|
|
+ color: #fff;
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+}
|
|
|
|
|
+.filter-tab:active {
|
|
|
|
|
+ opacity: 0.8;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/* 成员列表 */
|
|
|
|
|
|
|
+/* ===== 成员列表 ===== */
|
|
|
.member-list {
|
|
.member-list {
|
|
|
background: #fff;
|
|
background: #fff;
|
|
|
border-radius: 16rpx;
|
|
border-radius: 16rpx;
|
|
@@ -417,6 +456,9 @@ export default {
|
|
|
.member-item:last-child {
|
|
.member-item:last-child {
|
|
|
border-bottom: none;
|
|
border-bottom: none;
|
|
|
}
|
|
}
|
|
|
|
|
+.member-item:active {
|
|
|
|
|
+ background: #f8f8ff;
|
|
|
|
|
+}
|
|
|
.member-avatar {
|
|
.member-avatar {
|
|
|
width: 72rpx;
|
|
width: 72rpx;
|
|
|
height: 72rpx;
|
|
height: 72rpx;
|
|
@@ -425,12 +467,6 @@ export default {
|
|
|
background: #f0f0f0;
|
|
background: #f0f0f0;
|
|
|
flex-shrink: 0;
|
|
flex-shrink: 0;
|
|
|
}
|
|
}
|
|
|
-.child-avatar {
|
|
|
|
|
- display: flex;
|
|
|
|
|
- align-items: center;
|
|
|
|
|
- justify-content: center;
|
|
|
|
|
- font-size: 40rpx;
|
|
|
|
|
-}
|
|
|
|
|
.member-detail {
|
|
.member-detail {
|
|
|
flex: 1;
|
|
flex: 1;
|
|
|
min-width: 0;
|
|
min-width: 0;
|
|
@@ -467,25 +503,9 @@ export default {
|
|
|
margin-top: 4rpx;
|
|
margin-top: 4rpx;
|
|
|
display: inline;
|
|
display: inline;
|
|
|
}
|
|
}
|
|
|
-.btn-switch {
|
|
|
|
|
- font-size: 24rpx;
|
|
|
|
|
- color: #0EA5E9;
|
|
|
|
|
- background: #f0f9ff;
|
|
|
|
|
- border: none;
|
|
|
|
|
- padding: 8rpx 20rpx;
|
|
|
|
|
- border-radius: 8rpx;
|
|
|
|
|
- line-height: 1.5;
|
|
|
|
|
- margin-left: 12rpx;
|
|
|
|
|
- flex-shrink: 0;
|
|
|
|
|
-}
|
|
|
|
|
-.btn-kick {
|
|
|
|
|
- font-size: 24rpx;
|
|
|
|
|
- color: #f56c6c;
|
|
|
|
|
- background: #fef0f0;
|
|
|
|
|
- border: none;
|
|
|
|
|
- padding: 8rpx 20rpx;
|
|
|
|
|
- border-radius: 8rpx;
|
|
|
|
|
- line-height: 1.5;
|
|
|
|
|
|
|
+.member-arrow {
|
|
|
|
|
+ font-size: 36rpx;
|
|
|
|
|
+ color: #ccc;
|
|
|
margin-left: 12rpx;
|
|
margin-left: 12rpx;
|
|
|
flex-shrink: 0;
|
|
flex-shrink: 0;
|
|
|
}
|
|
}
|
|
@@ -498,7 +518,45 @@ export default {
|
|
|
color: #bbb;
|
|
color: #bbb;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/* 弹窗遮罩 */
|
|
|
|
|
|
|
+/* ===== 三维评分进度条(列表行内) ===== */
|
|
|
|
|
+.member-quality-scores {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ gap: 6rpx;
|
|
|
|
|
+ padding: 8rpx 0;
|
|
|
|
|
+}
|
|
|
|
|
+.score-item {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 8rpx;
|
|
|
|
|
+}
|
|
|
|
|
+.score-label {
|
|
|
|
|
+ width: 56rpx;
|
|
|
|
|
+ font-size: 20rpx;
|
|
|
|
|
+ color: #999;
|
|
|
|
|
+}
|
|
|
|
|
+.score-bar-bg {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ height: 10rpx;
|
|
|
|
|
+ background: #f0f0f0;
|
|
|
|
|
+ border-radius: 5rpx;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+}
|
|
|
|
|
+.score-bar-fill {
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ border-radius: 5rpx;
|
|
|
|
|
+}
|
|
|
|
|
+.score-bar-fill.trust { background: #10B981; }
|
|
|
|
|
+.score-bar-fill.intimacy { background: #FF6B9D; }
|
|
|
|
|
+.score-bar-fill.communication { background: #6366F1; }
|
|
|
|
|
+.score-value {
|
|
|
|
|
+ width: 44rpx;
|
|
|
|
|
+ font-size: 18rpx;
|
|
|
|
|
+ color: #999;
|
|
|
|
|
+ text-align: right;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* ===== 弹窗遮罩 ===== */
|
|
|
.modal-mask {
|
|
.modal-mask {
|
|
|
position: fixed;
|
|
position: fixed;
|
|
|
top: 0;
|
|
top: 0;
|
|
@@ -512,7 +570,53 @@ export default {
|
|
|
z-index: 100;
|
|
z-index: 100;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/* 邀请卡片 */
|
|
|
|
|
|
|
+/* ===== Settings 弹窗 ===== */
|
|
|
|
|
+.settings-card {
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ border-radius: 24rpx;
|
|
|
|
|
+ width: 500rpx;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+}
|
|
|
|
|
+.settings-header {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ padding: 30rpx 30rpx 0;
|
|
|
|
|
+}
|
|
|
|
|
+.settings-title {
|
|
|
|
|
+ font-size: 32rpx;
|
|
|
|
|
+ font-weight: bold;
|
|
|
|
|
+}
|
|
|
|
|
+.settings-close {
|
|
|
|
|
+ font-size: 44rpx;
|
|
|
|
|
+ color: #999;
|
|
|
|
|
+ padding: 4rpx 8rpx;
|
|
|
|
|
+}
|
|
|
|
|
+.settings-body {
|
|
|
|
|
+ padding: 20rpx 30rpx 30rpx;
|
|
|
|
|
+}
|
|
|
|
|
+.settings-item {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ padding: 22rpx 16rpx;
|
|
|
|
|
+ border-radius: 12rpx;
|
|
|
|
|
+ margin-bottom: 8rpx;
|
|
|
|
|
+}
|
|
|
|
|
+.settings-item:active {
|
|
|
|
|
+ background: #f5f5f5;
|
|
|
|
|
+}
|
|
|
|
|
+.settings-item-icon {
|
|
|
|
|
+ font-size: 32rpx;
|
|
|
|
|
+ margin-right: 16rpx;
|
|
|
|
|
+ width: 40rpx;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+}
|
|
|
|
|
+.settings-item-text {
|
|
|
|
|
+ font-size: 28rpx;
|
|
|
|
|
+ color: #333;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* ===== 邀请卡片 ===== */
|
|
|
.invite-card {
|
|
.invite-card {
|
|
|
background: #fff;
|
|
background: #fff;
|
|
|
border-radius: 24rpx;
|
|
border-radius: 24rpx;
|
|
@@ -593,105 +697,158 @@ export default {
|
|
|
color: #666;
|
|
color: #666;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/* 加载 */
|
|
|
|
|
-.loading-wrap {
|
|
|
|
|
- text-align: center;
|
|
|
|
|
- padding: 60rpx 0;
|
|
|
|
|
|
|
+/* ===== 成员详情弹窗 ===== */
|
|
|
|
|
+.member-detail-card {
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ border-radius: 24rpx;
|
|
|
|
|
+ width: 600rpx;
|
|
|
|
|
+ max-height: 80vh;
|
|
|
|
|
+ overflow-y: auto;
|
|
|
|
|
+ padding: 36rpx 32rpx 32rpx;
|
|
|
}
|
|
}
|
|
|
-.loading-text {
|
|
|
|
|
- font-size: 28rpx;
|
|
|
|
|
- color: #999;
|
|
|
|
|
|
|
+.detail-header {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ margin-bottom: 20rpx;
|
|
|
}
|
|
}
|
|
|
-.btn-edit {
|
|
|
|
|
- font-size: 24rpx;
|
|
|
|
|
- color: #67c23a;
|
|
|
|
|
- background: #f0f9eb;
|
|
|
|
|
- border: none;
|
|
|
|
|
- padding: 8rpx 20rpx;
|
|
|
|
|
- border-radius: 8rpx;
|
|
|
|
|
- line-height: 1.5;
|
|
|
|
|
- margin-left: 12rpx;
|
|
|
|
|
|
|
+.detail-avatar {
|
|
|
|
|
+ width: 100rpx;
|
|
|
|
|
+ height: 100rpx;
|
|
|
|
|
+ border-radius: 50%;
|
|
|
|
|
+ margin-right: 20rpx;
|
|
|
|
|
+ background: #f0f0f0;
|
|
|
flex-shrink: 0;
|
|
flex-shrink: 0;
|
|
|
}
|
|
}
|
|
|
-.edit-relation-card {
|
|
|
|
|
- background: #fff;
|
|
|
|
|
- border-radius: 24rpx;
|
|
|
|
|
- padding: 40rpx;
|
|
|
|
|
- width: 580rpx;
|
|
|
|
|
|
|
+.detail-info {
|
|
|
|
|
+ flex: 1;
|
|
|
}
|
|
}
|
|
|
-.edit-relation-title {
|
|
|
|
|
- font-size: 32rpx;
|
|
|
|
|
|
|
+.detail-name {
|
|
|
|
|
+ font-size: 34rpx;
|
|
|
font-weight: bold;
|
|
font-weight: bold;
|
|
|
display: block;
|
|
display: block;
|
|
|
- text-align: center;
|
|
|
|
|
- margin-bottom: 20rpx;
|
|
|
|
|
}
|
|
}
|
|
|
-.edit-relation-member {
|
|
|
|
|
- text-align: center;
|
|
|
|
|
- margin-bottom: 24rpx;
|
|
|
|
|
|
|
+.detail-relation {
|
|
|
|
|
+ font-size: 26rpx;
|
|
|
|
|
+ color: #667eea;
|
|
|
|
|
+ margin-top: 4rpx;
|
|
|
|
|
+ display: block;
|
|
|
}
|
|
}
|
|
|
-.edit-relation-name {
|
|
|
|
|
- font-size: 28rpx;
|
|
|
|
|
- color: #333;
|
|
|
|
|
|
|
+.detail-close {
|
|
|
|
|
+ font-size: 44rpx;
|
|
|
|
|
+ color: #999;
|
|
|
|
|
+ padding: 4rpx 8rpx;
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ top: -12rpx;
|
|
|
|
|
+ right: -8rpx;
|
|
|
}
|
|
}
|
|
|
-.edit-relation-actions {
|
|
|
|
|
|
|
+.detail-meta {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
- gap: 20rpx;
|
|
|
|
|
- margin-top: 30rpx;
|
|
|
|
|
|
|
+ gap: 16rpx;
|
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
|
+ margin-bottom: 20rpx;
|
|
|
|
|
+ padding: 16rpx 0;
|
|
|
|
|
+ border-bottom: 1rpx solid #f0f0f0;
|
|
|
}
|
|
}
|
|
|
-.btn-cancel {
|
|
|
|
|
- flex: 1;
|
|
|
|
|
- background: #f5f5f5;
|
|
|
|
|
- border: none;
|
|
|
|
|
- border-radius: 12rpx;
|
|
|
|
|
- padding: 18rpx 0;
|
|
|
|
|
- font-size: 28rpx;
|
|
|
|
|
- color: #666;
|
|
|
|
|
|
|
+.detail-meta-item {
|
|
|
|
|
+ font-size: 24rpx;
|
|
|
|
|
+ color: #888;
|
|
|
}
|
|
}
|
|
|
-.btn-save {
|
|
|
|
|
- flex: 1;
|
|
|
|
|
- background: #F97316;
|
|
|
|
|
- border: none;
|
|
|
|
|
- border-radius: 12rpx;
|
|
|
|
|
- padding: 18rpx 0;
|
|
|
|
|
- font-size: 28rpx;
|
|
|
|
|
- color: #fff;
|
|
|
|
|
|
|
+
|
|
|
|
|
+/* 详情三维评分 */
|
|
|
|
|
+.detail-scores {
|
|
|
|
|
+ margin-bottom: 24rpx;
|
|
|
}
|
|
}
|
|
|
-/* 三维评分进度条 */
|
|
|
|
|
-.member-quality-scores {
|
|
|
|
|
- display: flex;
|
|
|
|
|
- flex-direction: column;
|
|
|
|
|
- gap: 6rpx;
|
|
|
|
|
- padding: 8rpx 0;
|
|
|
|
|
|
|
+.detail-section-title {
|
|
|
|
|
+ font-size: 28rpx;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ display: block;
|
|
|
|
|
+ margin-bottom: 12rpx;
|
|
|
|
|
+ padding-left: 12rpx;
|
|
|
|
|
+ border-left: 4rpx solid #667eea;
|
|
|
}
|
|
}
|
|
|
-.score-item {
|
|
|
|
|
|
|
+.detail-score-item {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
align-items: center;
|
|
align-items: center;
|
|
|
- gap: 8rpx;
|
|
|
|
|
|
|
+ gap: 10rpx;
|
|
|
|
|
+ margin-bottom: 8rpx;
|
|
|
}
|
|
}
|
|
|
-.score-label {
|
|
|
|
|
|
|
+.detail-score-label {
|
|
|
width: 56rpx;
|
|
width: 56rpx;
|
|
|
- font-size: 20rpx;
|
|
|
|
|
- color: #999;
|
|
|
|
|
|
|
+ font-size: 22rpx;
|
|
|
|
|
+ color: #888;
|
|
|
}
|
|
}
|
|
|
-.score-bar-bg {
|
|
|
|
|
|
|
+.detail-score-bar-bg {
|
|
|
flex: 1;
|
|
flex: 1;
|
|
|
- height: 10rpx;
|
|
|
|
|
|
|
+ height: 12rpx;
|
|
|
background: #f0f0f0;
|
|
background: #f0f0f0;
|
|
|
- border-radius: 5rpx;
|
|
|
|
|
|
|
+ border-radius: 6rpx;
|
|
|
overflow: hidden;
|
|
overflow: hidden;
|
|
|
}
|
|
}
|
|
|
-.score-bar-fill {
|
|
|
|
|
|
|
+.detail-score-bar-fill {
|
|
|
height: 100%;
|
|
height: 100%;
|
|
|
- border-radius: 5rpx;
|
|
|
|
|
|
|
+ border-radius: 6rpx;
|
|
|
|
|
+ transition: width 0.3s ease;
|
|
|
}
|
|
}
|
|
|
-.score-bar-fill.trust { background: #10B981; }
|
|
|
|
|
-.score-bar-fill.intimacy { background: #FF6B9D; }
|
|
|
|
|
-.score-bar-fill.communication { background: #6366F1; }
|
|
|
|
|
-.score-value {
|
|
|
|
|
|
|
+.detail-score-bar-fill.trust { background: #10B981; }
|
|
|
|
|
+.detail-score-bar-fill.intimacy { background: #FF6B9D; }
|
|
|
|
|
+.detail-score-bar-fill.communication { background: #6366F1; }
|
|
|
|
|
+.detail-score-value {
|
|
|
width: 44rpx;
|
|
width: 44rpx;
|
|
|
- font-size: 18rpx;
|
|
|
|
|
- color: #999;
|
|
|
|
|
|
|
+ font-size: 22rpx;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ color: #555;
|
|
|
text-align: right;
|
|
text-align: right;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+/* ===== 操作按钮区(2列flex网格) ===== */
|
|
|
|
|
+.detail-actions {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
|
+ gap: 16rpx;
|
|
|
|
|
+ padding-top: 8rpx;
|
|
|
|
|
+ border-top: 1rpx solid #f0f0f0;
|
|
|
|
|
+}
|
|
|
|
|
+.detail-action-btn {
|
|
|
|
|
+ width: calc(50% - 8rpx);
|
|
|
|
|
+ border: none;
|
|
|
|
|
+ border-radius: 12rpx;
|
|
|
|
|
+ padding: 20rpx 0;
|
|
|
|
|
+ font-size: 26rpx;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ line-height: 1.4;
|
|
|
|
|
+}
|
|
|
|
|
+.detail-action-btn:active {
|
|
|
|
|
+ opacity: 0.8;
|
|
|
|
|
+}
|
|
|
|
|
+.action-switch {
|
|
|
|
|
+ background: #f0f9ff;
|
|
|
|
|
+ color: #0EA5E9;
|
|
|
|
|
+}
|
|
|
|
|
+.action-edit {
|
|
|
|
|
+ background: #f0f9eb;
|
|
|
|
|
+ color: #67c23a;
|
|
|
|
|
+}
|
|
|
|
|
+.action-questionnaire {
|
|
|
|
|
+ background: #f3e8ff;
|
|
|
|
|
+ color: #8b5cf6;
|
|
|
|
|
+}
|
|
|
|
|
+.action-interaction {
|
|
|
|
|
+ background: #fff7ed;
|
|
|
|
|
+ color: #F97316;
|
|
|
|
|
+}
|
|
|
|
|
+.action-kick {
|
|
|
|
|
+ background: #fef0f0;
|
|
|
|
|
+ color: #f56c6c;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* ===== 加载 ===== */
|
|
|
|
|
+.loading-wrap {
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ padding: 60rpx 0;
|
|
|
|
|
+}
|
|
|
|
|
+.loading-text {
|
|
|
|
|
+ font-size: 28rpx;
|
|
|
|
|
+ color: #999;
|
|
|
|
|
+}
|
|
|
</style>
|
|
</style>
|