删除不再使用的文件和配置,优化项目结构以提升可维护性;新增环境变量配置示例,更新 Docker 和部署相关文件以支持灵活的端口设置;重构数据库连接逻辑,增强错误处理和配置管理,确保更好的兼容性和稳定性。
This commit is contained in:
@@ -1,82 +1,44 @@
|
||||
/**
|
||||
* Soul创业实验 - 自定义TabBar组件
|
||||
* 实现中间突出的"找伙伴"按钮
|
||||
*/
|
||||
const app = getApp()
|
||||
|
||||
Component({
|
||||
data: {
|
||||
selected: 0,
|
||||
color: '#8e8e93',
|
||||
selectedColor: '#00CED1',
|
||||
list: [
|
||||
{
|
||||
pagePath: '/pages/index/index',
|
||||
text: '首页',
|
||||
iconType: 'home'
|
||||
},
|
||||
{
|
||||
pagePath: '/pages/chapters/chapters',
|
||||
text: '目录',
|
||||
iconType: 'list'
|
||||
},
|
||||
{
|
||||
pagePath: '/pages/match/match',
|
||||
text: '找伙伴',
|
||||
iconType: 'match',
|
||||
isSpecial: true,
|
||||
hidden: true // 默认隐藏,等配置加载后根据后台设置显示
|
||||
},
|
||||
{
|
||||
pagePath: '/pages/my/my',
|
||||
text: '我的',
|
||||
iconType: 'user'
|
||||
}
|
||||
],
|
||||
matchEnabled: false // 找伙伴功能开关(默认隐藏,等待后台配置加载)
|
||||
},
|
||||
|
||||
attached() {
|
||||
// 初始化时获取当前页面
|
||||
this.loadFeatureConfig()
|
||||
{ pagePath: '/pages/index/index', text: '首页', icon: '🏠' },
|
||||
{ pagePath: '/pages/chapters/chapters', text: '目录', icon: '📋' },
|
||||
{ pagePath: '/pages/match/match', text: '找伙伴', icon: '👥', hidden: true, isCenter: true },
|
||||
{ pagePath: '/pages/my/my', text: '我的', icon: '👤' }
|
||||
]
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 加载功能配置
|
||||
async loadFeatureConfig() {
|
||||
try {
|
||||
const app = getApp()
|
||||
const res = await app.request('/api/db/config')
|
||||
|
||||
if (res.success && res.features) {
|
||||
const matchEnabled = res.features.matchEnabled === true
|
||||
this.setData({ matchEnabled })
|
||||
|
||||
// 更新list,隐藏或显示找伙伴
|
||||
const list = this.data.list.map(item => {
|
||||
if (item.iconType === 'match') {
|
||||
return { ...item, hidden: !matchEnabled }
|
||||
}
|
||||
return item
|
||||
})
|
||||
this.setData({ list })
|
||||
|
||||
console.log('[TabBar] 功能配置加载成功,找伙伴功能:', matchEnabled ? '开启' : '关闭')
|
||||
syncMatchEnabled() {
|
||||
const matchEnabled = app.globalData.matchEnabled === true
|
||||
const list = this.data.list.map((item) => {
|
||||
if (item.text === '找伙伴') {
|
||||
return { ...item, hidden: !matchEnabled }
|
||||
}
|
||||
} catch (e) {
|
||||
console.log('[TabBar] 加载功能配置失败:', e)
|
||||
// 失败时默认隐藏找伙伴(与Web版保持一致)
|
||||
this.setData({ matchEnabled: false })
|
||||
}
|
||||
return item
|
||||
})
|
||||
this.setData({ list })
|
||||
},
|
||||
|
||||
|
||||
switchTab(e) {
|
||||
const data = e.currentTarget.dataset
|
||||
const url = data.path
|
||||
const index = data.index
|
||||
|
||||
if (this.data.selected === index) return
|
||||
|
||||
wx.switchTab({ url })
|
||||
const path = e.currentTarget.dataset.path
|
||||
const index = e.currentTarget.dataset.index
|
||||
this.setData({ selected: index })
|
||||
wx.switchTab({ url: path })
|
||||
}
|
||||
},
|
||||
|
||||
attached() {
|
||||
this.syncMatchEnabled()
|
||||
app.loadFeatureConfig().then(() => this.syncMatchEnabled())
|
||||
},
|
||||
|
||||
pageLifetimes: {
|
||||
show() {
|
||||
app.loadFeatureConfig().then(() => this.syncMatchEnabled())
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{
|
||||
"component": true
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
|
||||
@@ -1,56 +1,14 @@
|
||||
<!--custom-tab-bar/index.wxml-->
|
||||
<view class="tab-bar">
|
||||
<view class="tab-bar-border"></view>
|
||||
|
||||
<!-- 首页 -->
|
||||
<view class="tab-bar-item" data-path="{{list[0].pagePath}}" data-index="0" bindtap="switchTab">
|
||||
<view class="icon-wrapper">
|
||||
<!-- 首页图标 -->
|
||||
<view class="icon {{selected === 0 ? 'icon-active' : ''}}">
|
||||
<view class="icon-home">
|
||||
<view class="home-roof"></view>
|
||||
<view class="home-body"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="tab-bar-text" style="color: {{selected === 0 ? selectedColor : color}}">{{list[0].text}}</view>
|
||||
</view>
|
||||
|
||||
<!-- 目录 -->
|
||||
<view class="tab-bar-item" data-path="{{list[1].pagePath}}" data-index="1" bindtap="switchTab">
|
||||
<view class="icon-wrapper">
|
||||
<view class="icon {{selected === 1 ? 'icon-active' : ''}}">
|
||||
<view class="icon-list">
|
||||
<view class="list-line"></view>
|
||||
<view class="list-line"></view>
|
||||
<view class="list-line"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="tab-bar-text" style="color: {{selected === 1 ? selectedColor : color}}">{{list[1].text}}</view>
|
||||
</view>
|
||||
|
||||
<!-- 找伙伴 - 中间突出按钮(可通过后台隐藏) -->
|
||||
<view wx:if="{{matchEnabled}}" class="tab-bar-item special-item" data-path="{{list[2].pagePath}}" data-index="2" bindtap="switchTab">
|
||||
<view class="special-button {{selected === 2 ? 'special-active' : ''}}">
|
||||
<view class="icon-users">
|
||||
<view class="user-circle user-1"></view>
|
||||
<view class="user-circle user-2"></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="tab-bar-text special-text" style="color: {{selected === 2 ? selectedColor : color}}">{{list[2].text}}</view>
|
||||
</view>
|
||||
|
||||
<!-- 我的 -->
|
||||
<view class="tab-bar-item" data-path="{{list[3].pagePath}}" data-index="3" bindtap="switchTab">
|
||||
<view class="icon-wrapper">
|
||||
<view class="icon {{selected === 3 ? 'icon-active' : ''}}">
|
||||
<view class="icon-user">
|
||||
<view class="user-head"></view>
|
||||
<view class="user-body"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="tab-bar-text" style="color: {{selected === 3 ? selectedColor : color}}">{{list[3].text}}</view>
|
||||
<view
|
||||
wx:for="{{list}}"
|
||||
wx:key="pagePath"
|
||||
wx:if="{{!item.hidden}}"
|
||||
class="tab-item {{selected === index ? 'active' : ''}} {{item.isCenter ? 'center' : ''}}"
|
||||
data-path="{{item.pagePath}}"
|
||||
data-index="{{index}}"
|
||||
bindtap="switchTab"
|
||||
>
|
||||
<view class="tab-icon">{{item.icon}}</view>
|
||||
<text class="tab-text">{{item.text}}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -1,227 +1,8 @@
|
||||
/**
|
||||
* Soul创业实验 - 自定义TabBar样式
|
||||
* 实现中间突出的"找伙伴"按钮
|
||||
*/
|
||||
|
||||
.tab-bar {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 100rpx;
|
||||
background: rgba(28, 28, 30, 0.95);
|
||||
backdrop-filter: blur(40rpx);
|
||||
-webkit-backdrop-filter: blur(40rpx);
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.tab-bar-border {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 1rpx;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
.tab-bar-item {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 10rpx 0 16rpx;
|
||||
}
|
||||
|
||||
.icon-wrapper {
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 4rpx;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 44rpx;
|
||||
height: 44rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.tab-bar-text {
|
||||
font-size: 22rpx;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
/* ===== 首页图标 ===== */
|
||||
.icon-home {
|
||||
position: relative;
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
}
|
||||
|
||||
.home-roof {
|
||||
position: absolute;
|
||||
top: 4rpx;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 18rpx solid transparent;
|
||||
border-right: 18rpx solid transparent;
|
||||
border-bottom: 14rpx solid #8e8e93;
|
||||
}
|
||||
|
||||
.home-body {
|
||||
position: absolute;
|
||||
bottom: 4rpx;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 28rpx;
|
||||
height: 18rpx;
|
||||
background: #8e8e93;
|
||||
border-radius: 0 0 4rpx 4rpx;
|
||||
}
|
||||
|
||||
.icon-active .home-roof {
|
||||
border-bottom-color: #00CED1;
|
||||
}
|
||||
|
||||
.icon-active .home-body {
|
||||
background: #00CED1;
|
||||
}
|
||||
|
||||
/* ===== 目录图标 ===== */
|
||||
.icon-list {
|
||||
width: 36rpx;
|
||||
height: 32rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.list-line {
|
||||
width: 100%;
|
||||
height: 6rpx;
|
||||
background: #8e8e93;
|
||||
border-radius: 3rpx;
|
||||
}
|
||||
|
||||
.list-line:nth-child(2) {
|
||||
width: 75%;
|
||||
}
|
||||
|
||||
.list-line:nth-child(3) {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.icon-active .list-line {
|
||||
background: #00CED1;
|
||||
}
|
||||
|
||||
/* ===== 我的图标 ===== */
|
||||
.icon-user {
|
||||
position: relative;
|
||||
width: 36rpx;
|
||||
height: 40rpx;
|
||||
}
|
||||
|
||||
.user-head {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 16rpx;
|
||||
height: 16rpx;
|
||||
background: #8e8e93;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.user-body {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 28rpx;
|
||||
height: 18rpx;
|
||||
background: #8e8e93;
|
||||
border-radius: 14rpx 14rpx 0 0;
|
||||
}
|
||||
|
||||
.icon-active .user-head,
|
||||
.icon-active .user-body {
|
||||
background: #00CED1;
|
||||
}
|
||||
|
||||
/* ===== 找伙伴 - 中间特殊按钮 ===== */
|
||||
.special-item {
|
||||
position: relative;
|
||||
margin-top: -32rpx;
|
||||
}
|
||||
|
||||
.special-button {
|
||||
width: 112rpx;
|
||||
height: 112rpx;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, #00CED1 0%, #20B2AA 100%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 8rpx 32rpx rgba(0, 206, 209, 0.4);
|
||||
margin-bottom: 4rpx;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.special-button:active {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
.special-active {
|
||||
box-shadow: 0 8rpx 40rpx rgba(0, 206, 209, 0.6);
|
||||
}
|
||||
|
||||
.special-text {
|
||||
margin-top: 4rpx;
|
||||
}
|
||||
|
||||
/* ===== 找伙伴图标 (双人) ===== */
|
||||
.icon-users {
|
||||
position: relative;
|
||||
width: 56rpx;
|
||||
height: 44rpx;
|
||||
}
|
||||
|
||||
.user-circle {
|
||||
position: absolute;
|
||||
width: 28rpx;
|
||||
height: 28rpx;
|
||||
border-radius: 50%;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.user-circle::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -12rpx;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 22rpx;
|
||||
height: 14rpx;
|
||||
background: #ffffff;
|
||||
border-radius: 11rpx 11rpx 0 0;
|
||||
}
|
||||
|
||||
.user-1 {
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.user-2 {
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
.tab-bar { position: fixed; bottom: 0; left: 0; right: 0; height: 120rpx; background: #1c1c1e; border-top: 2rpx solid rgba(255,255,255,0.05); display: flex; align-items: flex-end; justify-content: space-around; padding-bottom: env(safe-area-inset-bottom); padding-top: 16rpx; }
|
||||
.tab-item { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 8rpx 0; }
|
||||
.tab-icon { font-size: 44rpx; line-height: 1; margin-bottom: 4rpx; opacity: 0.7; }
|
||||
.tab-item.active .tab-icon { opacity: 1; }
|
||||
.tab-text { font-size: 20rpx; color: #8e8e93; }
|
||||
.tab-item.active .tab-text { color: #00CED1; font-weight: 500; }
|
||||
.tab-item.center .tab-icon { width: 88rpx; height: 88rpx; line-height: 88rpx; text-align: center; font-size: 48rpx; margin-top: -40rpx; margin-bottom: 0; border-radius: 50%; background: linear-gradient(135deg, #00CED1 0%, #20B2AA 100%); box-shadow: 0 8rpx 24rpx rgba(0,206,209,0.3); }
|
||||
.tab-item.center.active .tab-icon { opacity: 1; box-shadow: 0 8rpx 28rpx rgba(0,206,209,0.4); }
|
||||
|
||||
Reference in New Issue
Block a user