feat: migrate static pages to native tabbar

This commit is contained in:
2026-04-23 21:25:24 +08:00
parent f3cd0c3a98
commit cd30f57f2c
116 changed files with 7143 additions and 311 deletions

131
pages/profile/index.js Normal file
View File

@@ -0,0 +1,131 @@
const { ROUTES, openStaticRoute } = require('../../utils/static-ux/route-map')
function createProfilePageData() {
return {
title: '我的',
userCard: {
avatarText: '?',
title: '点击登录',
subtitle: '登录后查看你的学习资产',
settingsText: '设',
route: ROUTES.tabs.login
},
vipCard: {
icon: '会员',
title: '开通会员',
subtitle: '解锁更多学习资料、AI 仪表与阅读辅助能力',
actionText: '成为会员',
route: `${ROUTES.tcm.placeholder}?kind=membership`
},
assetItems: [
{
key: 'notes',
icon: '记',
title: '我的笔记',
count: 0,
route: `${ROUTES.tcm.assets}?kind=notes`
},
{
key: 'bookshelf',
icon: '架',
title: '我的书架',
count: 0,
route: `${ROUTES.tcm.assets}?kind=bookshelf`
},
{
key: 'favorites',
icon: '藏',
title: '我的收藏',
count: 0,
route: `${ROUTES.tcm.assets}?kind=favorites`
},
{
key: 'history',
icon: '史',
title: '浏览历史',
count: 0,
route: `${ROUTES.tcm.assets}?kind=history`
}
],
recentRecord: {
title: '最近记录',
emptyTitle: '还没有回访记录',
emptyDescription: '去典籍阅读或 AI 页完成一次学习,记录会出现在这里。',
actionText: '去首页看看',
route: ROUTES.tabs.home
},
moreItems: [
{
key: 'learning-center',
title: '学习中心',
route: ROUTES.learning.center
},
{
key: 'ai-history',
title: 'AI历史',
route: ROUTES.tcm.aiHistory
},
{
key: 'feedback',
title: '意见反馈',
route: `${ROUTES.tcm.placeholder}?kind=feedback`
},
{
key: 'share',
title: '分享 APP',
route: `${ROUTES.tcm.placeholder}?kind=share`
},
{
key: 'about',
title: '关于我们',
route: `${ROUTES.tcm.placeholder}?kind=about`
},
{
key: 'settings',
title: '设置',
route: `${ROUTES.tcm.placeholder}?kind=settings`
}
]
}
}
function showNavigate(route) {
if (openStaticRoute(route, wx)) {
return
}
if (typeof wx?.showToast === 'function') {
wx.showToast({
title: '页面建设中',
icon: 'none'
})
}
}
Page({
data: createProfilePageData(),
handleUserTap() {
showNavigate(ROUTES.tabs.login)
},
handleVipTap() {
showNavigate(`${ROUTES.tcm.placeholder}?kind=membership`)
},
handleAssetTap(event) {
showNavigate(event.currentTarget.dataset.route)
},
handleRecentTap() {
openStaticRoute(ROUTES.tabs.home, wx)
},
handleMoreTap(event) {
showNavigate(event.currentTarget.dataset.route)
}
})
module.exports = {
createProfilePageData
}

5
pages/profile/index.json Normal file
View File

@@ -0,0 +1,5 @@
{
"navigationBarTitleText": "我的",
"navigationBarBackgroundColor": "#f8ecd8",
"navigationBarTextStyle": "black"
}

65
pages/profile/index.wxml Normal file
View File

@@ -0,0 +1,65 @@
<view class="profile-page xz-page--warm">
<view class="section-card xz-card profile-header" bindtap="handleUserTap">
<view class="profile-header__main">
<view class="profile-header__avatar">{{userCard.avatarText}}</view>
<view class="profile-header__body">
<text class="profile-header__title">{{userCard.title}}</text>
<text class="profile-header__subtitle">{{userCard.subtitle}}</text>
</view>
</view>
<text class="profile-header__settings">{{userCard.settingsText}}</text>
</view>
<view class="section-card xz-card vip-banner" bindtap="handleVipTap">
<view class="vip-banner__body">
<text class="vip-banner__icon">{{vipCard.icon}}</text>
<view class="vip-banner__copy">
<text class="vip-banner__title">{{vipCard.title}}</text>
<text class="vip-banner__subtitle">{{vipCard.subtitle}}</text>
</view>
</view>
<text class="vip-banner__action">{{vipCard.actionText}}</text>
</view>
<view class="section-card xz-card">
<view class="asset-grid">
<view
class="asset-grid__item"
wx:for="{{assetItems}}"
wx:key="key"
data-route="{{item.route}}"
bindtap="handleAssetTap"
>
<view class="asset-grid__icon">{{item.icon}}</view>
<text class="asset-grid__title">{{item.title}}</text>
<text class="asset-grid__count">{{item.count}}</text>
</view>
</view>
</view>
<view class="section-card xz-card recent-panel">
<view class="recent-panel__head">
<text class="recent-panel__title">{{recentRecord.title}}</text>
</view>
<view class="recent-panel__empty">
<text class="recent-panel__empty-title">{{recentRecord.emptyTitle}}</text>
<text class="recent-panel__empty-desc">{{recentRecord.emptyDescription}}</text>
<view class="recent-panel__action" bindtap="handleRecentTap">{{recentRecord.actionText}}</view>
</view>
</view>
<view class="section-card xz-card">
<view class="menu-list">
<view
class="menu-list__item"
wx:for="{{moreItems}}"
wx:key="key"
data-route="{{item.route}}"
bindtap="handleMoreTap"
>
<text class="menu-list__label">{{item.title}}</text>
<text class="menu-list__arrow">></text>
</view>
</view>
</view>
</view>

204
pages/profile/index.wxss Normal file
View File

@@ -0,0 +1,204 @@
page {
min-height: 100%;
background: linear-gradient(180deg, #f8edd6 0%, #f9f0de 24%, #f6ead4 100%);
}
.profile-page {
box-sizing: border-box;
min-height: 100vh;
padding: 28rpx 20rpx 88rpx;
background:
radial-gradient(circle at top right, rgba(189, 144, 86, 0.16) 0%, rgba(189, 144, 86, 0) 24%),
linear-gradient(135deg, rgba(255, 255, 255, 0.58) 0%, rgba(255, 248, 236, 0) 38%);
}
.section-card {
margin-top: 18rpx;
padding: 26rpx;
background: rgba(255, 250, 242, 0.92);
}
.section-card:first-child {
margin-top: 0;
}
.profile-header,
.vip-banner {
display: flex;
align-items: center;
justify-content: space-between;
}
.profile-header__main,
.vip-banner__body {
display: flex;
align-items: center;
}
.profile-header__avatar {
width: 104rpx;
height: 104rpx;
border-radius: 999rpx;
background: linear-gradient(135deg, #b47b40 0%, #8c5724 100%);
color: #fff7ea;
font-family: 'STSong', 'Songti SC', serif;
font-size: 42rpx;
font-weight: 700;
line-height: 104rpx;
text-align: center;
}
.profile-header__body {
margin-left: 18rpx;
}
.profile-header__title {
display: block;
color: #2f1f12;
font-family: 'STSong', 'Songti SC', serif;
font-size: 36rpx;
font-weight: 700;
line-height: 1.3;
}
.profile-header__subtitle,
.vip-banner__subtitle,
.recent-panel__empty-desc {
display: block;
margin-top: 8rpx;
color: #8f6a42;
font-size: 26rpx;
line-height: 1.7;
}
.profile-header__settings {
width: 68rpx;
height: 68rpx;
border-radius: 20rpx;
background: rgba(244, 233, 215, 0.92);
color: #8a6339;
font-size: 28rpx;
line-height: 68rpx;
text-align: center;
}
.vip-banner {
background: linear-gradient(135deg, rgba(255, 249, 241, 0.98) 0%, rgba(244, 230, 206, 0.96) 100%);
}
.vip-banner__icon {
width: 82rpx;
height: 82rpx;
border-radius: 24rpx;
background: rgba(130, 77, 25, 0.1);
color: #7d4a19;
font-size: 24rpx;
line-height: 82rpx;
text-align: center;
}
.vip-banner__copy {
margin-left: 18rpx;
}
.vip-banner__title,
.recent-panel__title,
.recent-panel__empty-title {
display: block;
color: #2f1f12;
font-family: 'STSong', 'Songti SC', serif;
font-size: 34rpx;
font-weight: 700;
line-height: 1.35;
}
.vip-banner__action,
.recent-panel__action {
min-width: 156rpx;
padding: 18rpx 24rpx;
border-radius: 999rpx;
background: linear-gradient(135deg, #9e652f 0%, #75441a 100%);
color: #fff7eb;
font-family: 'STSong', 'Songti SC', serif;
font-size: 26rpx;
line-height: 1;
text-align: center;
}
.asset-grid {
display: flex;
flex-wrap: wrap;
margin: -6rpx;
}
.asset-grid__item {
box-sizing: border-box;
width: 25%;
padding: 6rpx;
}
.asset-grid__icon,
.asset-grid__title,
.asset-grid__count {
display: block;
text-align: center;
}
.asset-grid__icon {
width: 72rpx;
height: 72rpx;
margin: 0 auto;
border-radius: 22rpx;
background: rgba(139, 96, 46, 0.1);
color: #76461b;
font-size: 30rpx;
line-height: 72rpx;
}
.asset-grid__title {
margin-top: 14rpx;
color: #3d2a1b;
font-size: 24rpx;
line-height: 1.5;
}
.asset-grid__count {
margin-top: 10rpx;
color: #9c754d;
font-size: 22rpx;
line-height: 1;
}
.recent-panel__empty {
margin-top: 18rpx;
padding: 8rpx 2rpx 2rpx;
}
.recent-panel__action {
margin-top: 22rpx;
}
.menu-list__item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 22rpx 2rpx;
border-bottom: 1rpx solid rgba(172, 137, 94, 0.12);
}
.menu-list__item:last-child {
padding-bottom: 2rpx;
border-bottom: 0;
}
.menu-list__label {
color: #2f1f12;
font-size: 28rpx;
line-height: 1.5;
}
.menu-list__arrow {
color: #9c7449;
font-size: 28rpx;
line-height: 1;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB