feat(theme): 实现日夜主题自动切换功能

- 添加日夜主题CSS变量定义,支持琥珀夜光和暖白琥珀两种风格
- 实现主题切换逻辑,根据时间自动切换白天(light)和夜间(dark)主题
- 在App.vue中集成主题初始化和token恢复功能
- 更新全局样式类应用主题颜色变量,包括卡片、文本、边框等
- 创建主题混入(mixin)供各页面使用,确保主题同步更新
- 实现导航栏和TabBar主题动态切换,提升用户体验
- 添加API服务层封装HaveADrink SDK,统一处理认证和请求
- 优化DrinkCard组件显示饮酒感受信息,丰富打卡记录展示
- 更新项目依赖配置,集成新的API客户端库
This commit is contained in:
cg
2026-07-16 22:47:38 +08:00
parent 145976f221
commit 860136bceb
22 changed files with 7051 additions and 155 deletions
+45 -12
View File
@@ -1,15 +1,14 @@
<script>
import { getCurrentTheme, applyTheme } from './common/utils'
import client, { refreshAuthToken } from './common/api'
export default {
onLaunch() {
console.log('喝了么 App Launch')
// 初始化Mock数据(仅首次)
const hasData = uni.getStorageSync('drink_records')
if (!hasData) {
import('./common/mock-data').then(({ initMockData }) => {
initMockData()
console.log('Mock数据已初始化')
})
}
// 初始化主题
this.initTheme()
// 尝试刷新 token
this.restoreAuth()
// 数据迁移:清除旧版 logo.png 头像引用
this.migrateUserData()
// 启动路由守卫
@@ -17,11 +16,36 @@ export default {
},
onShow() {
console.log('App Show')
// 每次回到前台刷新主题(时间可能已变化)
this.initTheme()
},
onHide() {
console.log('App Hide')
},
methods: {
// 初始化并应用日夜主题
initTheme() {
const theme = getCurrentTheme()
applyTheme(theme)
// 同步设置page元素背景色
const bgColor = theme === 'light' ? '#FAF7F2' : '#0B0B14'
try {
uni.setBackgroundColor({
backgroundColor: bgColor,
backgroundColorTop: bgColor,
backgroundColorBottom: bgColor
})
} catch (e) {}
},
// 恢复登录态:从缓存恢复 token 并尝试刷新
async restoreAuth() {
const token = uni.getStorageSync('auth_token')
if (token) {
client.setToken(token)
// 后台尝试刷新 token(静默,不阻塞启动)
refreshAuthToken().catch(() => {})
}
},
// 数据迁移:清除旧版 logo.png 头像引用
migrateUserData() {
try {
@@ -72,11 +96,13 @@ page {
.page-container {
min-height: 100vh;
background-color: $bg-base;
color: $text-primary;
padding-bottom: env(safe-area-inset-bottom);
}
.card {
background-color: $bg-card;
color: $text-primary;
border-radius: $radius-lg;
padding: $sp-lg;
box-shadow: $shadow-sm;
@@ -84,6 +110,7 @@ page {
.card-elevated {
background-color: $bg-elevated;
color: $text-primary;
border-radius: $radius-lg;
padding: $sp-lg;
box-shadow: $shadow-md;
@@ -95,36 +122,42 @@ page {
font-weight: $fw-black;
line-height: $lh-tight;
letter-spacing: -2rpx;
color: $text-primary;
}
.text-display {
font-size: $fs-3xl;
font-weight: $fw-black;
line-height: $lh-tight;
color: $text-primary;
}
.text-h1 {
font-size: $fs-2xl;
font-weight: $fw-bold;
line-height: $lh-tight;
color: $text-primary;
}
.text-h2 {
font-size: $fs-xl;
font-weight: $fw-bold;
line-height: $lh-tight;
color: $text-primary;
}
.text-h3 {
font-size: $fs-lg;
font-weight: $fw-medium;
line-height: $lh-normal;
color: $text-primary;
}
.text-body {
font-size: $fs-base;
font-weight: $fw-normal;
line-height: $lh-normal;
color: $text-primary;
}
.text-caption {
@@ -195,7 +228,7 @@ page {
font-weight: $fw-medium;
padding: $sp-md $sp-xl;
border-radius: $radius-full;
border: 2rpx solid rgba(255, 255, 255, 0.08);
border: 2rpx solid var(--border-subtle, rgba(255, 255, 255, 0.10));
transition: all $duration-fast $ease-out;
display: flex;
align-items: center;
@@ -252,7 +285,7 @@ page {
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.15), transparent);
background: linear-gradient(90deg, transparent, var(--btn-shimmer, rgba(255, 255, 255, 0.15)), transparent);
animation: shimmer 3s infinite;
}
@@ -287,7 +320,7 @@ page {
/* --- 分隔线 --- */
.divider {
height: 2rpx;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.06), transparent);
background: linear-gradient(90deg, transparent, var(--divider-color, rgba(255, 255, 255, 0.08)), transparent);
margin: $sp-lg 0;
}
@@ -330,7 +363,7 @@ page {
padding: $sp-sm;
font-size: $fs-xs;
color: $text-tertiary;
background-color: rgba(255, 255, 255, 0.02);
background-color: var(--bg-subtle, rgba(255, 255, 255, 0.03));
text {
opacity: 0.5;