|
@@ -6,9 +6,9 @@
|
|
|
<image class="sandbox-logo" src="/static/logo.png" mode="aspectFit"></image>
|
|
<image class="sandbox-logo" src="/static/logo.png" mode="aspectFit"></image>
|
|
|
<text class="sandbox-title">浠艾福能量沙盘</text>
|
|
<text class="sandbox-title">浠艾福能量沙盘</text>
|
|
|
<!-- 右上角:live 模式显示个人/全家切换,preview 模式显示徽章文案 -->
|
|
<!-- 右上角:live 模式显示个人/全家切换,preview 模式显示徽章文案 -->
|
|
|
- <view class="sandbox-switch" v-if="mode !== 'preview'" @click="onToggle(currentView === 'family' ? 'personal' : 'family')">
|
|
|
|
|
- <text class="sandbox-switch-icon">{{ currentView === 'family' ? '👨👩👧👦' : '👤' }}</text>
|
|
|
|
|
- <text class="sandbox-switch-label">{{ currentView === 'family' ? '全家' : (currentMember ? currentMember.name : '个人') }}</text>
|
|
|
|
|
|
|
+ <view class="sandbox-switch" v-if="mode !== 'preview'" @click="onToggle">
|
|
|
|
|
+ <text class="sandbox-switch-icon">{{ activeMemberIcon }}</text>
|
|
|
|
|
+ <text class="sandbox-switch-label">{{ activeMemberLabel }}</text>
|
|
|
<text class="sandbox-switch-arrow">⇄</text>
|
|
<text class="sandbox-switch-arrow">⇄</text>
|
|
|
</view>
|
|
</view>
|
|
|
<text class="sandbox-badge" v-else>{{ displayBadgeText }}</text>
|
|
<text class="sandbox-badge" v-else>{{ displayBadgeText }}</text>
|
|
@@ -78,6 +78,23 @@
|
|
|
<view class="dim-item dim-item--water">💧富 {{ activeScores[4] }}%</view>
|
|
<view class="dim-item dim-item--water">💧富 {{ activeScores[4] }}%</view>
|
|
|
</view>
|
|
</view>
|
|
|
</slot>
|
|
</slot>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 右上角成员选择面板 -->
|
|
|
|
|
+ <view v-if="memberPickerVisible" class="member-picker-mask" @click="memberPickerVisible = false">
|
|
|
|
|
+ <view class="member-picker-panel" @click.stop>
|
|
|
|
|
+ <view class="member-picker-title">切换视角</view>
|
|
|
|
|
+ <view
|
|
|
|
|
+ v-for="option in memberOptions"
|
|
|
|
|
+ :key="option.key"
|
|
|
|
|
+ class="member-picker-item"
|
|
|
|
|
+ :class="{ 'member-picker-item--active': isOptionActive(option) }"
|
|
|
|
|
+ @click="selectOption(option)"
|
|
|
|
|
+ >
|
|
|
|
|
+ <text class="member-picker-label">{{ option.label }}</text>
|
|
|
|
|
+ <text class="member-picker-check" v-if="isOptionActive(option)">✓</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
</view>
|
|
</view>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
@@ -86,6 +103,14 @@ import { renderStar, calcStarVertices } from './wuxing-sandbox-helpers/render.js
|
|
|
import { FillAnimator } from './wuxing-sandbox-helpers/animation.js'
|
|
import { FillAnimator } from './wuxing-sandbox-helpers/animation.js'
|
|
|
import { detectHitArm, armIndexToDomain } from './wuxing-sandbox-helpers/hitdetect.js'
|
|
import { detectHitArm, armIndexToDomain } from './wuxing-sandbox-helpers/hitdetect.js'
|
|
|
import { FlowAnimation } from './wuxing-sandbox-helpers/flow-animation.js'
|
|
import { FlowAnimation } from './wuxing-sandbox-helpers/flow-animation.js'
|
|
|
|
|
+import {
|
|
|
|
|
+ buildMemberOptions,
|
|
|
|
|
+ findMemberById,
|
|
|
|
|
+ getSelfMember,
|
|
|
|
|
+ nextSandboxSelection,
|
|
|
|
|
+ resolveSandboxOverall,
|
|
|
|
|
+ resolveSandboxScores
|
|
|
|
|
+} from '@/utils/wuxing-sandbox.js'
|
|
|
|
|
|
|
|
var DIM_KEYS = ['body', 'mind', 'wisdom', 'action', 'wealth']
|
|
var DIM_KEYS = ['body', 'mind', 'wisdom', 'action', 'wealth']
|
|
|
|
|
|
|
@@ -174,7 +199,8 @@ export default {
|
|
|
data: function() {
|
|
data: function() {
|
|
|
return {
|
|
return {
|
|
|
viewMode: 'personal',
|
|
viewMode: 'personal',
|
|
|
- selectedMemberIndex: 0,
|
|
|
|
|
|
|
+ selectedMemberId: null,
|
|
|
|
|
+ memberPickerVisible: false,
|
|
|
previewScores: [0, 0, 0, 0, 0],
|
|
previewScores: [0, 0, 0, 0, 0],
|
|
|
canvasReady: false,
|
|
canvasReady: false,
|
|
|
canvasWidth: 0,
|
|
canvasWidth: 0,
|
|
@@ -197,56 +223,50 @@ export default {
|
|
|
isPreview: function() {
|
|
isPreview: function() {
|
|
|
return this.mode === 'preview'
|
|
return this.mode === 'preview'
|
|
|
},
|
|
},
|
|
|
|
|
+ selfMember: function() {
|
|
|
|
|
+ return getSelfMember(this.personalData)
|
|
|
|
|
+ },
|
|
|
|
|
+ memberOptions: function() {
|
|
|
|
|
+ return buildMemberOptions(this.members, this.personalData)
|
|
|
|
|
+ },
|
|
|
|
|
+ totalMemberCount: function() {
|
|
|
|
|
+ if (this.memberCount > 0) return this.memberCount
|
|
|
|
|
+ return this.members ? this.members.length : 0
|
|
|
|
|
+ },
|
|
|
currentMember: function() {
|
|
currentMember: function() {
|
|
|
- if (this.isPreview) return null
|
|
|
|
|
- var m = this.members
|
|
|
|
|
- if (!m || m.length === 0) return null
|
|
|
|
|
- if (this.selectedMemberIndex >= m.length) return m[0]
|
|
|
|
|
- return m[this.selectedMemberIndex]
|
|
|
|
|
|
|
+ if (this.isPreview || this.viewMode === 'family') return null
|
|
|
|
|
+ if (this.viewMode === 'member') {
|
|
|
|
|
+ return findMemberById(this.members, this.selectedMemberId)
|
|
|
|
|
+ }
|
|
|
|
|
+ return this.selfMember
|
|
|
|
|
+ },
|
|
|
|
|
+ selectedMemberIndex: function() {
|
|
|
|
|
+ if (this.viewMode !== 'member' || this.selectedMemberId == null) return -1
|
|
|
|
|
+ var list = this.members || []
|
|
|
|
|
+ for (var i = 0; i < list.length; i++) {
|
|
|
|
|
+ if (String(list[i].memberId) === String(this.selectedMemberId)) return i
|
|
|
|
|
+ }
|
|
|
|
|
+ return -1
|
|
|
|
|
+ },
|
|
|
|
|
+ activeMemberLabel: function() {
|
|
|
|
|
+ if (this.viewMode === 'family') return '全家'
|
|
|
|
|
+ if (this.viewMode === 'member' && this.currentMember) return this.currentMember.name || '家庭成员'
|
|
|
|
|
+ return '本人'
|
|
|
|
|
+ },
|
|
|
|
|
+ activeMemberIcon: function() {
|
|
|
|
|
+ return this.viewMode === 'family' ? '👨👩👧👦' : '👤'
|
|
|
},
|
|
},
|
|
|
/** 当前活跃的五维值数组 [body, mind, wisdom, action, wealth] */
|
|
/** 当前活跃的五维值数组 [body, mind, wisdom, action, wealth] */
|
|
|
activeScores: function() {
|
|
activeScores: function() {
|
|
|
if (this.isPreview) return this.previewScores
|
|
if (this.isPreview) return this.previewScores
|
|
|
- if (this.viewMode === 'family') {
|
|
|
|
|
- var s = this.scores
|
|
|
|
|
- return [
|
|
|
|
|
- s.body || 0,
|
|
|
|
|
- s.mind || 0,
|
|
|
|
|
- s.wisdom || 0,
|
|
|
|
|
- s.action || 0,
|
|
|
|
|
- s.wealth || 0
|
|
|
|
|
- ]
|
|
|
|
|
- }
|
|
|
|
|
- var p = this.personalData
|
|
|
|
|
- if (p) {
|
|
|
|
|
- return [
|
|
|
|
|
- p.bodyScore || 0,
|
|
|
|
|
- p.mindScore || 0,
|
|
|
|
|
- p.wisdomScore || 0,
|
|
|
|
|
- p.actionScore || 0,
|
|
|
|
|
- p.wealthScore || 0
|
|
|
|
|
- ]
|
|
|
|
|
- }
|
|
|
|
|
- var m = this.currentMember
|
|
|
|
|
- if (!m) return [0, 0, 0, 0, 0]
|
|
|
|
|
- return [
|
|
|
|
|
- m.bodyScore || 0,
|
|
|
|
|
- m.mindScore || 0,
|
|
|
|
|
- m.wisdomScore || 0,
|
|
|
|
|
- m.actionScore || 0,
|
|
|
|
|
- m.wealthScore || 0
|
|
|
|
|
- ]
|
|
|
|
|
|
|
+ return resolveSandboxScores(this.viewMode, this.scores, this.personalData, this.currentMember)
|
|
|
},
|
|
},
|
|
|
activeOverall: function() {
|
|
activeOverall: function() {
|
|
|
if (this.isPreview) {
|
|
if (this.isPreview) {
|
|
|
var s = this.previewScores
|
|
var s = this.previewScores
|
|
|
return Math.round((s[0] + s[1] + s[2] + s[3] + s[4]) / 5)
|
|
return Math.round((s[0] + s[1] + s[2] + s[3] + s[4]) / 5)
|
|
|
}
|
|
}
|
|
|
- if (this.viewMode === 'family') return this.overallScore || 0
|
|
|
|
|
- var p = this.personalData
|
|
|
|
|
- if (p && p.overallScore != null) return p.overallScore
|
|
|
|
|
- var m = this.currentMember
|
|
|
|
|
- return m ? (m.overallScore || 0) : 0
|
|
|
|
|
|
|
+ return resolveSandboxOverall(this.viewMode, this.scores, this.personalData, this.currentMember)
|
|
|
},
|
|
},
|
|
|
activeTs: function() {
|
|
activeTs: function() {
|
|
|
return [
|
|
return [
|
|
@@ -259,14 +279,14 @@ export default {
|
|
|
},
|
|
},
|
|
|
displayBadgeText: function() {
|
|
displayBadgeText: function() {
|
|
|
if (this.badgeText) return this.badgeText
|
|
if (this.badgeText) return this.badgeText
|
|
|
- var label = this.viewMode === 'family' ? '家庭能量' : (this.currentMember ? this.currentMember.name : '个人能量')
|
|
|
|
|
|
|
+ var label = this.viewMode === 'family' ? '家庭能量' : (this.activeMemberLabel + '能量')
|
|
|
return label + ' ' + (this.activeOverall || 0) + '%'
|
|
return label + ' ' + (this.activeOverall || 0) + '%'
|
|
|
},
|
|
},
|
|
|
_allDimTs: function() {
|
|
_allDimTs: function() {
|
|
|
return this.activeTs
|
|
return this.activeTs
|
|
|
},
|
|
},
|
|
|
hasMultipleMembers: function() {
|
|
hasMultipleMembers: function() {
|
|
|
- return this.members && this.members.length > 1
|
|
|
|
|
|
|
+ return this.totalMemberCount > 1
|
|
|
},
|
|
},
|
|
|
activeClassName: function() {
|
|
activeClassName: function() {
|
|
|
return this.currentView === 'personal' ? 'toggle-item--active' : ''
|
|
return this.currentView === 'personal' ? 'toggle-item--active' : ''
|
|
@@ -280,18 +300,12 @@ export default {
|
|
|
var s = this.previewScores
|
|
var s = this.previewScores
|
|
|
return Math.round((s[0] + s[1] + s[2] + s[3] + s[4]) / 5)
|
|
return Math.round((s[0] + s[1] + s[2] + s[3] + s[4]) / 5)
|
|
|
}
|
|
}
|
|
|
- return this.viewMode === 'family' ? (this.overallScore || 0) : (this.overallScore || 0)
|
|
|
|
|
|
|
+ return this.overallScore || 0
|
|
|
},
|
|
},
|
|
|
- /** 个人能量值(用于太极阴面) */
|
|
|
|
|
|
|
+ /** 当前选中视角的能量值(用于太极阴面) */
|
|
|
personalEnergy: function() {
|
|
personalEnergy: function() {
|
|
|
if (this.isPreview) return 0
|
|
if (this.isPreview) return 0
|
|
|
- if (this.viewMode === 'member') {
|
|
|
|
|
- var m = this.currentMember
|
|
|
|
|
- return m ? (m.overallScore || 0) : 0
|
|
|
|
|
- }
|
|
|
|
|
- // 家庭模式下取当前选中成员
|
|
|
|
|
- var m = this.currentMember
|
|
|
|
|
- return m ? (m.overallScore || 0) : 0
|
|
|
|
|
|
|
+ return this.activeOverall || 0
|
|
|
},
|
|
},
|
|
|
/** 按五行顺序绕圈排列
|
|
/** 按五行顺序绕圈排列
|
|
|
* 固定序:心(火)→身(土)→智(金)→富(水)→行(木),心始终在顶部
|
|
* 固定序:心(火)→身(土)→智(金)→富(水)→行(木),心始终在顶部
|
|
@@ -299,6 +313,13 @@ export default {
|
|
|
*/
|
|
*/
|
|
|
sortedDimensions: function() {
|
|
sortedDimensions: function() {
|
|
|
var order = ['mind', 'body', 'wisdom', 'wealth', 'action']
|
|
var order = ['mind', 'body', 'wisdom', 'wealth', 'action']
|
|
|
|
|
+ var scoreByCode = {
|
|
|
|
|
+ body: this.activeScores[0] || 0,
|
|
|
|
|
+ mind: this.activeScores[1] || 0,
|
|
|
|
|
+ wisdom: this.activeScores[2] || 0,
|
|
|
|
|
+ action: this.activeScores[3] || 0,
|
|
|
|
|
+ wealth: this.activeScores[4] || 0
|
|
|
|
|
+ }
|
|
|
var dimMap = {}
|
|
var dimMap = {}
|
|
|
for (var i = 0; i < this.dimensions.length; i++) {
|
|
for (var i = 0; i < this.dimensions.length; i++) {
|
|
|
var d = this.dimensions[i]
|
|
var d = this.dimensions[i]
|
|
@@ -307,16 +328,17 @@ export default {
|
|
|
var all = []
|
|
var all = []
|
|
|
for (var j = 0; j < order.length; j++) {
|
|
for (var j = 0; j < order.length; j++) {
|
|
|
var code = order[j]
|
|
var code = order[j]
|
|
|
- var d = dimMap[code]
|
|
|
|
|
|
|
+ var d = dimMap[code] || {}
|
|
|
var meta = DIM_META[code] || {}
|
|
var meta = DIM_META[code] || {}
|
|
|
- if (d) {
|
|
|
|
|
- if (!d.name) d.name = meta.name || ''
|
|
|
|
|
- if (!d.icon) d.icon = meta.icon || ''
|
|
|
|
|
- if (!d.element) d.element = meta.element || ''
|
|
|
|
|
- all.push(d)
|
|
|
|
|
- } else {
|
|
|
|
|
- all.push({ code: code, name: meta.name || '', icon: meta.icon || '', element: meta.element || '', energy: 0, healthIndex: 0 })
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ var score = scoreByCode[code] || 0
|
|
|
|
|
+ all.push({
|
|
|
|
|
+ code: code,
|
|
|
|
|
+ name: d.name || meta.name || '',
|
|
|
|
|
+ icon: d.icon || meta.icon || '',
|
|
|
|
|
+ element: d.element || meta.element || '',
|
|
|
|
|
+ energy: score,
|
|
|
|
|
+ healthIndex: score
|
|
|
|
|
+ })
|
|
|
}
|
|
}
|
|
|
return all
|
|
return all
|
|
|
// all = [心→顶, 身→右, 智→右下, 富→左下, 行→左]
|
|
// all = [心→顶, 身→右, 智→右下, 富→左下, 行→左]
|
|
@@ -335,9 +357,28 @@ export default {
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
currentView: function(newVal) {
|
|
currentView: function(newVal) {
|
|
|
- if (newVal && newVal !== this.viewMode) {
|
|
|
|
|
|
|
+ if (!newVal) return
|
|
|
|
|
+ if (newVal !== this.viewMode) {
|
|
|
this.viewMode = newVal
|
|
this.viewMode = newVal
|
|
|
}
|
|
}
|
|
|
|
|
+ if (newVal === 'personal') {
|
|
|
|
|
+ this.selectedMemberId = null
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ memberOptions: function(options) {
|
|
|
|
|
+ if (this.viewMode !== 'member') return
|
|
|
|
|
+ var exists = false
|
|
|
|
|
+ for (var i = 0; i < options.length; i++) {
|
|
|
|
|
+ if (options[i].viewMode === 'member' &&
|
|
|
|
|
+ String(options[i].memberId) === String(this.selectedMemberId)) {
|
|
|
|
|
+ exists = true
|
|
|
|
|
+ break
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!exists) {
|
|
|
|
|
+ this.viewMode = 'personal'
|
|
|
|
|
+ this.selectedMemberId = null
|
|
|
|
|
+ }
|
|
|
},
|
|
},
|
|
|
hasMultipleMembers: function(newVal) {
|
|
hasMultipleMembers: function(newVal) {
|
|
|
if (!newVal && this.viewMode === 'family') {
|
|
if (!newVal && this.viewMode === 'family') {
|
|
@@ -384,36 +425,72 @@ export default {
|
|
|
视图切换
|
|
视图切换
|
|
|
=========================== */
|
|
=========================== */
|
|
|
|
|
|
|
|
|
|
+ selectionPayload: function() {
|
|
|
|
|
+ return {
|
|
|
|
|
+ viewMode: this.viewMode,
|
|
|
|
|
+ memberId: this.selectedMemberId,
|
|
|
|
|
+ selectedMemberIndex: this.selectedMemberIndex,
|
|
|
|
|
+ member: this.currentMember
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ applySelection: function(selection) {
|
|
|
|
|
+ if (!selection) return
|
|
|
|
|
+ this.memberPickerVisible = false
|
|
|
|
|
+ this.viewMode = selection.viewMode
|
|
|
|
|
+ this.selectedMemberId = selection.viewMode === 'member' ? selection.memberId : null
|
|
|
|
|
+ if (this.viewMode !== 'member') {
|
|
|
|
|
+ this.$emit('view-change', this.viewMode)
|
|
|
|
|
+ }
|
|
|
|
|
+ this.$emit('mode-change', this.selectionPayload())
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ showFamilyRequirement: function() {
|
|
|
|
|
+ uni.showModal({
|
|
|
|
|
+ title: '需要更多家庭成员',
|
|
|
|
|
+ content: '至少需要 2 位家庭成员才能查看全家能量,快去添加吧!',
|
|
|
|
|
+ confirmText: '去添加',
|
|
|
|
|
+ cancelText: '取消',
|
|
|
|
|
+ success: function(res) {
|
|
|
|
|
+ if (res.confirm) {
|
|
|
|
|
+ uni.navigateTo({ url: '/pages/profile-extra/family-members' })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ isOptionActive: function(option) {
|
|
|
|
|
+ if (!option) return false
|
|
|
|
|
+ if (option.viewMode !== this.viewMode) return false
|
|
|
|
|
+ if (option.viewMode === 'member') {
|
|
|
|
|
+ return String(option.memberId) === String(this.selectedMemberId)
|
|
|
|
|
+ }
|
|
|
|
|
+ return true
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ selectOption: function(option) {
|
|
|
|
|
+ if (!option) return
|
|
|
|
|
+ if (option.viewMode === 'family' && this.totalMemberCount < 2) {
|
|
|
|
|
+ this.memberPickerVisible = false
|
|
|
|
|
+ this.showFamilyRequirement()
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ this.applySelection(option)
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
onCenterClick: function() {
|
|
onCenterClick: function() {
|
|
|
// 预览模式不切换
|
|
// 预览模式不切换
|
|
|
if (this.isPreview) {
|
|
if (this.isPreview) {
|
|
|
- this.$emit('center-click', { viewMode: this.viewMode, selectedMemberIndex: this.selectedMemberIndex })
|
|
|
|
|
|
|
+ this.$emit('center-click', this.selectionPayload())
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
- var members = this.members
|
|
|
|
|
- if (!members || members.length === 0) {
|
|
|
|
|
- this.viewMode = 'family'
|
|
|
|
|
- this.$emit('center-click', { viewMode: this.viewMode, selectedMemberIndex: this.selectedMemberIndex })
|
|
|
|
|
- return
|
|
|
|
|
- }
|
|
|
|
|
- if (this.viewMode === 'family') {
|
|
|
|
|
- this.viewMode = 'member'
|
|
|
|
|
- } else {
|
|
|
|
|
- if (members.length === 1) {
|
|
|
|
|
- this.viewMode = 'family'
|
|
|
|
|
- this.selectedMemberIndex = 0
|
|
|
|
|
- } else {
|
|
|
|
|
- var nextIdx = this.selectedMemberIndex + 1
|
|
|
|
|
- if (nextIdx >= members.length) {
|
|
|
|
|
- this.viewMode = 'family'
|
|
|
|
|
- this.selectedMemberIndex = 0
|
|
|
|
|
- } else {
|
|
|
|
|
- this.selectedMemberIndex = nextIdx
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ var next = nextSandboxSelection(this.memberOptions, this.viewMode, this.selectedMemberId)
|
|
|
|
|
+ // 家庭成员不足 2 人时不进入全家视角
|
|
|
|
|
+ if (next.viewMode === 'family' && this.totalMemberCount < 2) {
|
|
|
|
|
+ next = { viewMode: 'personal', memberId: null, label: '本人' }
|
|
|
}
|
|
}
|
|
|
- this.$emit('center-click', { viewMode: this.viewMode, selectedMemberIndex: this.selectedMemberIndex })
|
|
|
|
|
- this.$emit('mode-change', { viewMode: this.viewMode, selectedMemberIndex: this.selectedMemberIndex })
|
|
|
|
|
|
|
+ this.applySelection(next)
|
|
|
|
|
+ this.$emit('center-click', this.selectionPayload())
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
onPointClick: function(code) {
|
|
onPointClick: function(code) {
|
|
@@ -424,28 +501,10 @@ export default {
|
|
|
})
|
|
})
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
- /** 个人/全家切换(由父组件控制数据源) */
|
|
|
|
|
- onToggle: function(view) {
|
|
|
|
|
- if (view === 'family') {
|
|
|
|
|
- var total = this.memberCount > 0 ? this.memberCount : (this.members ? this.members.length : 0)
|
|
|
|
|
- if (total < 2) {
|
|
|
|
|
- uni.showModal({
|
|
|
|
|
- title: '需要更多家庭成员',
|
|
|
|
|
- content: '至少需要 2 位家庭成员才能查看全家能量,快去添加吧!',
|
|
|
|
|
- confirmText: '去添加',
|
|
|
|
|
- cancelText: '取消',
|
|
|
|
|
- success: function(res) {
|
|
|
|
|
- if (res.confirm) {
|
|
|
|
|
- uni.navigateTo({ url: '/pages/profile-extra/family-members' })
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
- return
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- this.viewMode = view
|
|
|
|
|
- if (view === this.currentView) return
|
|
|
|
|
- this.$emit('view-change', view)
|
|
|
|
|
|
|
+ /** 右上角:打开成员选择面板(本人 / 各成员 / 全家) */
|
|
|
|
|
+ onToggle: function() {
|
|
|
|
|
+ if (this.isPreview) return
|
|
|
|
|
+ this.memberPickerVisible = true
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
/** 维度 code → CSS 颜色类名(不依赖 API 的 element 字段) */
|
|
/** 维度 code → CSS 颜色类名(不依赖 API 的 element 字段) */
|
|
@@ -668,6 +727,62 @@ export default {
|
|
|
.sandbox-switch-label { font-size: 22rpx; font-weight: 700; max-width: 140rpx; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
|
|
.sandbox-switch-label { font-size: 22rpx; font-weight: 700; max-width: 140rpx; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
|
|
|
.sandbox-switch-arrow { font-size: 20rpx; opacity: 0.8; }
|
|
.sandbox-switch-arrow { font-size: 20rpx; opacity: 0.8; }
|
|
|
|
|
|
|
|
|
|
+/* ---- 成员选择面板 ---- */
|
|
|
|
|
+.member-picker-mask {
|
|
|
|
|
+ position: fixed;
|
|
|
|
|
+ top: 0;
|
|
|
|
|
+ right: 0;
|
|
|
|
|
+ bottom: 0;
|
|
|
|
|
+ left: 0;
|
|
|
|
|
+ z-index: 999;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: flex-end;
|
|
|
|
|
+ background: rgba(0, 0, 0, 0.42);
|
|
|
|
|
+}
|
|
|
|
|
+.member-picker-panel {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ max-height: 70vh;
|
|
|
|
|
+ overflow-y: auto;
|
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
|
+ padding: 28rpx 28rpx calc(24rpx + env(safe-area-inset-bottom));
|
|
|
|
|
+ background: #ffffff;
|
|
|
|
|
+ border-radius: 28rpx 28rpx 0 0;
|
|
|
|
|
+ box-shadow: 0 -8rpx 32rpx rgba(0, 0, 0, 0.12);
|
|
|
|
|
+}
|
|
|
|
|
+.member-picker-title {
|
|
|
|
|
+ padding-bottom: 16rpx;
|
|
|
|
|
+ font-size: 26rpx;
|
|
|
|
|
+ font-weight: 700;
|
|
|
|
|
+ color: #333333;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+}
|
|
|
|
|
+.member-picker-item {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ min-height: 88rpx;
|
|
|
|
|
+ padding: 0 24rpx;
|
|
|
|
|
+ margin-top: 8rpx;
|
|
|
|
|
+ border-radius: 16rpx;
|
|
|
|
|
+ background: #f7f8fc;
|
|
|
|
|
+}
|
|
|
|
|
+.member-picker-item--active {
|
|
|
|
|
+ background: rgba(102, 126, 234, 0.12);
|
|
|
|
|
+}
|
|
|
|
|
+.member-picker-label {
|
|
|
|
|
+ font-size: 28rpx;
|
|
|
|
|
+ color: #333333;
|
|
|
|
|
+}
|
|
|
|
|
+.member-picker-item--active .member-picker-label {
|
|
|
|
|
+ color: #667eea;
|
|
|
|
|
+ font-weight: 700;
|
|
|
|
|
+}
|
|
|
|
|
+.member-picker-check {
|
|
|
|
|
+ font-size: 30rpx;
|
|
|
|
|
+ font-weight: 700;
|
|
|
|
|
+ color: #667eea;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
/* ---- 五角星区域 ---- */
|
|
/* ---- 五角星区域 ---- */
|
|
|
.sandbox-star {
|
|
.sandbox-star {
|
|
|
position: relative;
|
|
position: relative;
|