删除不再使用的文件和配置,优化项目结构以提升可维护性;新增环境变量配置示例,更新 Docker 和部署相关文件以支持灵活的端口设置;重构数据库连接逻辑,增强错误处理和配置管理,确保更好的兼容性和稳定性。

This commit is contained in:
乘风
2026-02-02 18:16:15 +08:00
parent 6dcc6a4709
commit 8eec1ab78c
126 changed files with 12536 additions and 20384 deletions

View File

@@ -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())
}
}
})

View File

@@ -1,3 +1,4 @@
{
"component": true
"component": true,
"usingComponents": {}
}

View File

@@ -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>

View File

@@ -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); }