feat: 小程序连接服务器IP + 同步未提交开发

- miniprogram/config.js: BASE_URL 指向 http://192.227.237.8:3001
- 动作标题中文化(nameZh),搜索匹配 name/nameZh/nameEn
- 新增计划/收藏/我的 等页面与组件
- 后端 Docker 化(Dockerfile/.dockerignore)与翻译脚本
- .gitignore 补充 .DS_Store
This commit is contained in:
2026-07-22 14:05:30 +08:00
parent b3b58e66fb
commit 70ff806042
79 changed files with 2397 additions and 146070 deletions

View File

@@ -0,0 +1,44 @@
const app = getApp();
const planSvc = require('../../services/plan');
const auth = require('../../utils/auth');
Page({
data: {
statusBarHeight: 20,
plans: [],
loading: true
},
onLoad() {
this.setData({ statusBarHeight: app.globalData.statusBarHeight || 20 });
},
onShow() {
if (auth.isLogin()) this.load();
else {
wx.showToast({ title: '请先登录', icon: 'none' });
setTimeout(() => wx.navigateBack(), 600);
}
},
load() {
this.setData({ loading: true });
planSvc.listMine().then((plans) => {
this.setData({ plans: plans || [], loading: false });
}).catch(() => {
this.setData({ plans: [], loading: false });
});
},
onNew() {
wx.navigateTo({ url: '/pages/plan-edit/plan-edit?mode=new' });
},
onOpen(e) {
wx.navigateTo({ url: '/pages/plan-detail/plan-detail?id=' + encodeURIComponent(e.currentTarget.dataset.id) });
},
goOfficial() {
wx.navigateTo({ url: '/pages/collection/collection' });
}
});

View File

@@ -0,0 +1,8 @@
{
"navigationStyle": "custom",
"usingComponents": {
"navbar": "/components/navbar/index",
"plan-card": "/components/plan-card/index",
"bottom-nav": "/components/bottom-nav/index"
}
}

View File

@@ -0,0 +1,30 @@
<view class="page">
<navbar title="我的训练计划" show-back />
<view class="newbar">
<view class="newbar__btn" bindtap="onNew"> 新建计划</view>
</view>
<view class="section" style="padding-top: 8rpx;">
<block wx:if="{{plans.length}}">
<view class="grid">
<view class="grid__item" wx:for="{{plans}}" wx:key="id">
<plan-card
plan="{{item}}"
target="/pages/plan-detail/plan-detail?id={{item.id}}" />
</view>
</view>
</block>
<view wx:elif="{{!loading}}" class="empty-box">
<view class="empty-box__emoji">📋</view>
<view class="empty-box__t">还没有计划,创建一个开始训练吧</view>
<view class="empty-box__btn" bindtap="onNew"> 新建计划</view>
<view class="empty-box__link" bindtap="goOfficial">或浏览官方训练计划 </view>
</view>
<view wx:else class="empty">加载中…</view>
</view>
<view style="height: 160rpx;"></view>
<bottom-nav active="plans" />
</view>

View File

@@ -0,0 +1,25 @@
.page { min-height: 100vh; background: var(--bg-grad); }
.newbar { padding: 16rpx 32rpx; }
.newbar__btn {
display: flex; align-items: center; justify-content: center;
background: linear-gradient(135deg, var(--gold) 0%, var(--gold-2) 100%);
color: #0E1110; font-weight: 700; font-size: 32rpx;
border-radius: 999rpx; padding: 26rpx;
}
.grid { display: flex; flex-wrap: wrap; gap: 18rpx; }
.grid__item { width: calc((100% - 18rpx) / 2); }
.empty { color: var(--text-3); font-size: 26rpx; text-align: center; padding: 120rpx 0; }
.empty-box { display: flex; flex-direction: column; align-items: center; padding: 120rpx 40rpx; }
.empty-box__emoji {
width: 160rpx; height: 160rpx; border-radius: 36rpx;
background: var(--surface-2); display: flex; align-items: center; justify-content: center;
font-size: 88rpx;
}
.empty-box__t { font-size: 30rpx; color: var(--text-2); margin-top: 36rpx; text-align: center; }
.empty-box__btn {
margin-top: 44rpx; padding: 24rpx 88rpx; border-radius: 999rpx;
background: linear-gradient(135deg, var(--gold) 0%, var(--gold-2) 100%);
color: #0E1110; font-weight: 700; font-size: 30rpx;
}
.empty-box__link { margin-top: 28rpx; font-size: 26rpx; color: var(--gold); }