|
|
@@ -1,27 +1,43 @@
|
|
|
<template>
|
|
|
<view class="tab-bar-wrap">
|
|
|
- <!-- 普通用户 TabBar:4 Tab + 中间五维按钮 -->
|
|
|
+ <!-- 普通用户 TabBar:4 Tab(5等分,中间放按钮) -->
|
|
|
<view v-if="currentRole !== 'teacher'" class="tab-bar">
|
|
|
<view
|
|
|
- v-for="(item, index) in normalTabs"
|
|
|
+ v-for="(item, index) in leftTabs"
|
|
|
:key="index"
|
|
|
class="tab-item"
|
|
|
- :class="{ active: currentIndex === index }"
|
|
|
- @click="switchTab(item, index)"
|
|
|
+ :class="{ active: isActive(item) }"
|
|
|
+ @click="switchTab(item)"
|
|
|
>
|
|
|
<image
|
|
|
class="tab-icon"
|
|
|
- :src="currentIndex === index ? item.selectedIcon : item.icon"
|
|
|
+ :src="isActive(item) ? item.selectedIcon : item.icon"
|
|
|
mode="aspectFit"
|
|
|
></image>
|
|
|
<text class="tab-text">{{ item.text }}</text>
|
|
|
</view>
|
|
|
|
|
|
- <!-- 中间五维启动器按钮 -->
|
|
|
+ <!-- 中间五维按钮(占 20% 槽位) -->
|
|
|
<view class="center-btn" @click="openDimPanel">
|
|
|
<view class="center-btn-inner">
|
|
|
<text class="center-btn-icon">⭐</text>
|
|
|
</view>
|
|
|
+ <text class="center-btn-label">五维</text>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view
|
|
|
+ v-for="(item, index) in rightTabs"
|
|
|
+ :key="index"
|
|
|
+ class="tab-item"
|
|
|
+ :class="{ active: isActive(item) }"
|
|
|
+ @click="switchTab(item)"
|
|
|
+ >
|
|
|
+ <image
|
|
|
+ class="tab-icon"
|
|
|
+ :src="isActive(item) ? item.selectedIcon : item.icon"
|
|
|
+ mode="aspectFit"
|
|
|
+ ></image>
|
|
|
+ <text class="tab-text">{{ item.text }}</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
@@ -31,37 +47,39 @@
|
|
|
v-for="(item, index) in teacherTabs"
|
|
|
:key="index"
|
|
|
class="tab-item"
|
|
|
- :class="{ active: currentIndex === index }"
|
|
|
- @click="switchTab(item, index)"
|
|
|
+ :class="{ active: isActive(item) }"
|
|
|
+ @click="switchTab(item)"
|
|
|
>
|
|
|
<image
|
|
|
class="tab-icon"
|
|
|
- :src="currentIndex === index ? item.selectedIcon : item.icon"
|
|
|
+ :src="isActive(item) ? item.selectedIcon : item.icon"
|
|
|
mode="aspectFit"
|
|
|
></image>
|
|
|
<text class="tab-text">{{ item.text }}</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
- <!-- 五维半屏浮层 -->
|
|
|
- <view class="dim-overlay" v-if="showDimPanel" @click="closeDimPanel">
|
|
|
- <view class="dim-panel" @click.stop>
|
|
|
- <view class="dim-header">
|
|
|
- <text class="dim-title">五维能量</text>
|
|
|
- <text class="dim-close" @click="closeDimPanel">✕</text>
|
|
|
- </view>
|
|
|
- <view class="dim-grid">
|
|
|
+ <!-- 五维横排展开 -->
|
|
|
+ <view class="dim-fan-overlay" v-if="showDimPanel" @click="closeDimPanel">
|
|
|
+ <view class="dim-fan-row">
|
|
|
+ <view
|
|
|
+ v-for="(dim, idx) in dimensions"
|
|
|
+ :key="idx"
|
|
|
+ :class="['dim-fan-item', { 'dim-fan-item-up': dim.code === 'mind', 'dim-fan-item-mid': dim.code === 'action' || dim.code === 'body' }]"
|
|
|
+ @click.stop="goDimension(dim)"
|
|
|
+ >
|
|
|
<view
|
|
|
- v-for="(dim, idx) in dimensions"
|
|
|
- :key="idx"
|
|
|
- class="dim-card"
|
|
|
- :style="{ backgroundColor: dim.bgColor }"
|
|
|
- @click="goDimension(dim)"
|
|
|
+ class="dim-fan-circle"
|
|
|
+ :class="{ 'fan-active': fanActive }"
|
|
|
+ :style="{ backgroundColor: dim.color, transitionDelay: (0.05 * idx) + 's' }"
|
|
|
>
|
|
|
- <text class="dim-icon">{{ dim.icon }}</text>
|
|
|
- <text class="dim-name">{{ dim.name }}</text>
|
|
|
- <text class="dim-desc">{{ dim.desc }}</text>
|
|
|
+ <text class="dim-fan-emoji">{{ dim.icon }}</text>
|
|
|
</view>
|
|
|
+ <text
|
|
|
+ class="dim-fan-label"
|
|
|
+ :class="{ 'fan-active': fanActive }"
|
|
|
+ :style="{ transitionDelay: (0.05 * idx) + 's' }"
|
|
|
+ >{{ dim.name }}</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
@@ -74,6 +92,7 @@ export default {
|
|
|
return {
|
|
|
currentIndex: 0,
|
|
|
showDimPanel: false,
|
|
|
+ fanActive: false,
|
|
|
normalTabs: [
|
|
|
{ text: '首页', pagePath: '/pages/index-home/index', icon: '/static/tab-home.png', selectedIcon: '/static/tab-home-active.png' },
|
|
|
{ text: '健康', pagePath: '/pages/health-main/index', icon: '/static/tab-health.png', selectedIcon: '/static/tab-health-active.png' },
|
|
|
@@ -88,17 +107,23 @@ export default {
|
|
|
{ text: '我的', pagePath: '/pages/teacher/teacher-profile', icon: '/static/tab-profile.png', selectedIcon: '/static/tab-profile-active.png' }
|
|
|
],
|
|
|
dimensions: [
|
|
|
+ { code: 'wealth', name: '富', desc: '利他创富', icon: '💧', color: '#F59E0B', bgColor: 'rgba(245,158,11,0.15)' },
|
|
|
{ code: 'action', name: '行', desc: '知行合一', icon: '🌿', color: '#10B981', bgColor: 'rgba(16,185,129,0.15)' },
|
|
|
{ code: 'mind', name: '心', desc: '大爱传承', icon: '🔥', color: '#FF6B9D', bgColor: 'rgba(255,107,157,0.15)' },
|
|
|
{ code: 'body', name: '身', desc: '主动健康', icon: '🌏', color: '#FF8C42', bgColor: 'rgba(255,140,66,0.15)' },
|
|
|
- { code: 'wisdom', name: '智', desc: '赋能未来', icon: '⚡', color: '#6366F1', bgColor: 'rgba(99,102,241,0.15)' },
|
|
|
- { code: 'wealth', name: '富', desc: '利他创富', icon: '💧', color: '#F59E0B', bgColor: 'rgba(245,158,11,0.15)' }
|
|
|
+ { code: 'wisdom', name: '智', desc: '赋能未来', icon: '⚡', color: '#6366F1', bgColor: 'rgba(99,102,241,0.15)' }
|
|
|
]
|
|
|
}
|
|
|
},
|
|
|
computed: {
|
|
|
currentRole() {
|
|
|
return uni.getStorageSync('currentRole') || 'parent'
|
|
|
+ },
|
|
|
+ leftTabs() {
|
|
|
+ return this.normalTabs.slice(0, 2)
|
|
|
+ },
|
|
|
+ rightTabs() {
|
|
|
+ return this.normalTabs.slice(2)
|
|
|
}
|
|
|
},
|
|
|
mounted() {
|
|
|
@@ -108,19 +133,23 @@ export default {
|
|
|
})
|
|
|
},
|
|
|
methods: {
|
|
|
+ isActive(item) {
|
|
|
+ var pages = getCurrentPages()
|
|
|
+ if (!pages.length) return false
|
|
|
+ var currentPath = '/' + pages[pages.length - 1].route
|
|
|
+ return item.pagePath === currentPath
|
|
|
+ },
|
|
|
updateSelected() {
|
|
|
var pages = getCurrentPages()
|
|
|
if (pages.length) {
|
|
|
var currentPage = pages[pages.length - 1]
|
|
|
var currentPath = '/' + currentPage.route
|
|
|
-
|
|
|
var tabs = this.currentRole === 'teacher' ? this.teacherTabs : this.normalTabs
|
|
|
var idx = tabs.findIndex(function(t) { return t.pagePath === currentPath })
|
|
|
this.currentIndex = idx >= 0 ? idx : 0
|
|
|
}
|
|
|
},
|
|
|
- switchTab(item, index) {
|
|
|
- this.currentIndex = index
|
|
|
+ switchTab(item) {
|
|
|
// TabBar 注册页用 switchTab,非 TabBar 页用 redirectTo
|
|
|
var tabBarPages = ['/pages/index-home/index', '/pages/health-main/index', '/pages/growth-main/index', '/pages/profile-main/profile']
|
|
|
if (tabBarPages.indexOf(item.pagePath) !== -1) {
|
|
|
@@ -131,9 +160,18 @@ export default {
|
|
|
},
|
|
|
openDimPanel() {
|
|
|
this.showDimPanel = true
|
|
|
+ this.fanActive = false
|
|
|
+ var self = this
|
|
|
+ setTimeout(function() {
|
|
|
+ self.fanActive = true
|
|
|
+ }, 30)
|
|
|
},
|
|
|
closeDimPanel() {
|
|
|
- this.showDimPanel = false
|
|
|
+ this.fanActive = false
|
|
|
+ var self = this
|
|
|
+ setTimeout(function() {
|
|
|
+ self.showDimPanel = false
|
|
|
+ }, 200)
|
|
|
},
|
|
|
goDimension(dim) {
|
|
|
this.closeDimPanel()
|
|
|
@@ -176,7 +214,8 @@ export default {
|
|
|
}
|
|
|
|
|
|
.tab-item {
|
|
|
- flex: 1;
|
|
|
+ width: 20%;
|
|
|
+ flex: none;
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
align-items: center;
|
|
|
@@ -185,14 +224,6 @@ export default {
|
|
|
z-index: 1;
|
|
|
}
|
|
|
|
|
|
-.tab-item:first-child {
|
|
|
- margin-right: 40rpx;
|
|
|
-}
|
|
|
-
|
|
|
-.tab-item:nth-child(4) {
|
|
|
- margin-left: 40rpx;
|
|
|
-}
|
|
|
-
|
|
|
.tab-icon {
|
|
|
width: 48rpx;
|
|
|
height: 48rpx;
|
|
|
@@ -208,18 +239,17 @@ export default {
|
|
|
color: #F97316;
|
|
|
}
|
|
|
|
|
|
-/* 中间五维启动器按钮 */
|
|
|
+/* 中间五维按钮(占 20% 槽位) */
|
|
|
.center-btn {
|
|
|
- position: absolute;
|
|
|
- left: 50%;
|
|
|
- top: -20rpx;
|
|
|
- transform: translateX(-50%);
|
|
|
- width: 100rpx;
|
|
|
- height: 100rpx;
|
|
|
- z-index: 2;
|
|
|
+ width: 20%;
|
|
|
+ flex: none;
|
|
|
display: flex;
|
|
|
+ flex-direction: column;
|
|
|
align-items: center;
|
|
|
- justify-content: center;
|
|
|
+ justify-content: flex-start;
|
|
|
+ padding-top: 0;
|
|
|
+ position: relative;
|
|
|
+ z-index: 2;
|
|
|
}
|
|
|
|
|
|
.center-btn-inner {
|
|
|
@@ -230,6 +260,7 @@ export default {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
+ margin-top: -44rpx;
|
|
|
box-shadow: 0 4rpx 16rpx rgba(249,115,22,0.4);
|
|
|
}
|
|
|
|
|
|
@@ -237,89 +268,82 @@ export default {
|
|
|
font-size: 40rpx;
|
|
|
line-height: 1;
|
|
|
}
|
|
|
+.center-btn-label {
|
|
|
+ font-size: 20rpx;
|
|
|
+ color: #999;
|
|
|
+ text-align: center;
|
|
|
+ margin-top: 2rpx;
|
|
|
+}
|
|
|
|
|
|
-/* 五维半屏浮层 */
|
|
|
-.dim-overlay {
|
|
|
+/* 五维横排展开 */
|
|
|
+.dim-fan-overlay {
|
|
|
position: fixed;
|
|
|
top: 0;
|
|
|
left: 0;
|
|
|
right: 0;
|
|
|
bottom: 0;
|
|
|
- background: rgba(0,0,0,0.5);
|
|
|
z-index: 1000;
|
|
|
- display: flex;
|
|
|
- align-items: flex-end;
|
|
|
+ background: rgba(0,0,0,0.4);
|
|
|
animation: fadeIn 0.2s ease;
|
|
|
}
|
|
|
-
|
|
|
-.dim-panel {
|
|
|
- width: 100%;
|
|
|
- background: #fff;
|
|
|
- border-radius: 32rpx 32rpx 0 0;
|
|
|
- padding: 40rpx 32rpx;
|
|
|
- padding-bottom: calc(100rpx + env(safe-area-inset-bottom) + 32rpx);
|
|
|
- animation: slideUp 0.3s ease;
|
|
|
+.dim-fan-row {
|
|
|
+ position: absolute;
|
|
|
+ bottom: 140rpx;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ padding: 0 16rpx;
|
|
|
}
|
|
|
-
|
|
|
-.dim-header {
|
|
|
+.dim-fan-item {
|
|
|
display: flex;
|
|
|
+ flex-direction: column;
|
|
|
align-items: center;
|
|
|
- justify-content: space-between;
|
|
|
- margin-bottom: 32rpx;
|
|
|
+ width: 120rpx;
|
|
|
}
|
|
|
-
|
|
|
-.dim-title {
|
|
|
- font-size: 32rpx;
|
|
|
- font-weight: 600;
|
|
|
- color: #333;
|
|
|
-}
|
|
|
-
|
|
|
-.dim-close {
|
|
|
- font-size: 32rpx;
|
|
|
- color: #999;
|
|
|
- padding: 8rpx;
|
|
|
+.dim-fan-item.dim-fan-item-up {
|
|
|
+ margin-top: -120rpx;
|
|
|
}
|
|
|
-
|
|
|
-.dim-grid {
|
|
|
- display: flex;
|
|
|
- flex-wrap: wrap;
|
|
|
- gap: 20rpx;
|
|
|
+.dim-fan-item.dim-fan-item-mid {
|
|
|
+ margin-top: -60rpx;
|
|
|
}
|
|
|
-
|
|
|
-.dim-card {
|
|
|
- width: calc(33.33% - 14rpx);
|
|
|
- border-radius: 20rpx;
|
|
|
- padding: 24rpx 16rpx;
|
|
|
+.dim-fan-circle {
|
|
|
+ width: 88rpx;
|
|
|
+ height: 88rpx;
|
|
|
+ border-radius: 50%;
|
|
|
display: flex;
|
|
|
- flex-direction: column;
|
|
|
align-items: center;
|
|
|
- box-sizing: border-box;
|
|
|
+ justify-content: center;
|
|
|
+ opacity: 0;
|
|
|
+ transform: scale(0);
|
|
|
+ transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
|
+ box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.15);
|
|
|
}
|
|
|
-
|
|
|
-.dim-icon {
|
|
|
- font-size: 48rpx;
|
|
|
- margin-bottom: 8rpx;
|
|
|
+.dim-fan-circle.fan-active {
|
|
|
+ opacity: 1;
|
|
|
+ transform: scale(1);
|
|
|
}
|
|
|
-
|
|
|
-.dim-name {
|
|
|
- font-size: 28rpx;
|
|
|
+.dim-fan-emoji {
|
|
|
+ font-size: 40rpx;
|
|
|
+ line-height: 1;
|
|
|
+}
|
|
|
+.dim-fan-label {
|
|
|
+ font-size: 22rpx;
|
|
|
+ color: #fff;
|
|
|
font-weight: 600;
|
|
|
- color: #333;
|
|
|
- margin-bottom: 4rpx;
|
|
|
+ margin-top: 8rpx;
|
|
|
+ text-align: center;
|
|
|
+ opacity: 0;
|
|
|
+ transform: translateY(-10rpx);
|
|
|
+ transition: all 0.3s ease;
|
|
|
}
|
|
|
-
|
|
|
-.dim-desc {
|
|
|
- font-size: 20rpx;
|
|
|
- color: #999;
|
|
|
+.dim-fan-label.fan-active {
|
|
|
+ opacity: 1;
|
|
|
+ transform: translateY(0);
|
|
|
}
|
|
|
|
|
|
@keyframes fadeIn {
|
|
|
from { opacity: 0; }
|
|
|
to { opacity: 1; }
|
|
|
}
|
|
|
-
|
|
|
-@keyframes slideUp {
|
|
|
- from { transform: translateY(100%); }
|
|
|
- to { transform: translateY(0); }
|
|
|
-}
|
|
|
</style>
|