Files
hejiu/App.vue
T
cg adf6b684b9 feat(calendar): 更新日历接口并优化记录流程
- 将GetRecords接口替换为GetCalendar接口获取日历数据
- 重构首页日历数据显示逻辑,支持年月维度的数据获取
- 优化打卡记录流程,合并选酒和记量步骤为单一添加酒水步骤
- 移除登录页面的游客模式选项,简化首次启动逻辑
- 调整引导页逻辑,移除登录跳转改为直接进入首页
- 优化记录页面UI布局,添加状态栏安全距离适配
- 新增酒水列表管理功能,支持添加和删除已选酒水
- 更新依赖包HaveADrink至v1.0.3版本,同步API变更
2026-07-17 23:51:43 +08:00

398 lines
8.2 KiB
Vue

<script>
import { getCurrentTheme, applyTheme } from './common/utils'
import client, { refreshAuthToken } from './common/api'
export default {
onLaunch() {
console.log('喝了么 App Launch')
// 初始化主题
this.initTheme()
// 尝试刷新 token
this.restoreAuth()
// 数据迁移:清除旧版 logo.png 头像引用
this.migrateUserData()
// 启动路由守卫
this.checkLaunchRoute()
},
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 {
const raw = uni.getStorageSync('user_info')
if (raw) {
const user = JSON.parse(raw)
if (user.avatar && user.avatar.includes('logo.png')) {
user.avatar = ''
uni.setStorageSync('user_info', JSON.stringify(user))
}
}
} catch (e) { /* ignore */ }
},
// 启动时检查引导状态,决定跳转目标
checkLaunchRoute() {
const isFirst = uni.getStorageSync('is_first_launch')
if (!isFirst || isFirst === 'true') {
// 首次使用 → 引导页
uni.reLaunch({ url: '/pages/onboarding/onboarding' })
}
// 否则正常进入首页(index)
}
}
}
</script>
<style lang="scss">
/* ==========================================
* 喝了么 - 全局样式
* 设计概念: 琥珀夜光 Amber Night
* ========================================== */
page {
background-color: $bg-base;
color: $text-primary;
font-family: $font-base;
font-size: $fs-base;
line-height: $lh-normal;
-webkit-font-smoothing: antialiased;
}
/* --- 通用工具类 --- */
.page-container {
min-height: 100vh;
background-color: $bg-base;
color: $text-primary;
padding-bottom: env(safe-area-inset-bottom);
box-sizing: border-box;
}
.card {
background-color: $bg-card;
color: $text-primary;
border-radius: $radius-lg;
padding: $sp-lg;
box-shadow: $shadow-sm;
}
.card-elevated {
background-color: $bg-elevated;
color: $text-primary;
border-radius: $radius-lg;
padding: $sp-lg;
box-shadow: $shadow-md;
}
/* --- 文本层级 --- */
.text-hero {
font-size: $fs-hero;
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 {
font-size: $fs-sm;
color: $text-secondary;
line-height: $lh-normal;
}
.text-tiny {
font-size: $fs-xs;
color: $text-tertiary;
}
/* --- 数字专用 --- */
.text-num {
font-family: $font-num;
font-weight: $fw-bold;
letter-spacing: -1rpx;
}
/* --- 色彩文字 --- */
.text-amber {
color: $amber;
}
.text-mint {
color: $mint;
}
.text-coral {
color: $coral;
}
.text-secondary {
color: $text-secondary;
}
/* --- 按钮系统 --- */
.btn-primary {
background: linear-gradient(135deg, $amber, $amber-deep);
color: $text-on-amber;
font-size: $fs-md;
font-weight: $fw-bold;
padding: $sp-md $sp-xl;
border-radius: $radius-full;
border: none;
text-align: center;
box-shadow: $shadow-amber;
transition: all $duration-fast $ease-out;
&:active {
transform: scale(0.97);
box-shadow: 0 4rpx 16rpx rgba(232, 168, 56, 0.2);
}
}
.btn-primary-lg {
@extend .btn-primary;
padding: $sp-lg $sp-xl;
font-size: $fs-lg;
border-radius: $radius-full;
}
.btn-secondary {
background-color: $bg-elevated;
color: $text-primary;
font-size: $fs-base;
font-weight: $fw-medium;
padding: $sp-md $sp-xl;
border-radius: $radius-full;
border: 2rpx solid var(--border-subtle, rgba(255, 255, 255, 0.10));
transition: all $duration-fast $ease-out;
display: flex;
align-items: center;
justify-content: center;
&:active {
background-color: $bg-card-alt;
transform: scale(0.97);
}
}
.btn-ghost {
background-color: transparent;
color: $amber;
font-size: $fs-base;
font-weight: $fw-medium;
padding: $sp-sm $sp-lg;
border: 2rpx solid $amber;
border-radius: $radius-full;
text-align: center;
transition: all $duration-fast $ease-out;
&:active {
background-color: $amber-glow;
}
}
/* 添加酒水按钮(Step 1 底部) */
.btn-add-drink {
background: linear-gradient(135deg, $amber, $amber-deep);
color: $text-on-amber;
font-size: $fs-md;
font-weight: $fw-bold;
padding: $sp-md $sp-xl;
border-radius: $radius-full;
border: none;
text-align: center;
box-shadow: $shadow-amber;
transition: all $duration-fast $ease-out;
display: flex;
align-items: center;
justify-content: center;
&:active {
transform: scale(0.97);
box-shadow: 0 4rpx 16rpx rgba(232, 168, 56, 0.2);
}
&[disabled] {
background: transparent;
color: $text-tertiary;
border: 2rpx solid var(--border-subtle, rgba(255, 255, 255, 0.10));
box-shadow: none;
}
}
.btn-text {
background: none;
border: none;
color: $text-secondary;
font-size: $fs-sm;
padding: $sp-xs $sp-sm;
}
/* --- 琥珀CTA大按钮(签名元素) --- */
.btn-cta {
background: linear-gradient(135deg, $amber-light, $amber, $amber-deep);
color: $text-on-amber;
font-size: $fs-xl;
font-weight: $fw-bold;
padding: $sp-lg 0;
border-radius: $radius-xl;
border: none;
text-align: center;
box-shadow: $shadow-amber;
width: 100%;
position: relative;
overflow: hidden;
&::after {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, var(--btn-shimmer, rgba(255, 255, 255, 0.15)), transparent);
animation: shimmer 3s infinite;
}
&:active {
transform: scale(0.98);
}
}
@keyframes shimmer {
0% { left: -100%; }
100% { left: 100%; }
}
/* --- 标签 --- */
.tag {
display: inline-flex;
align-items: center;
padding: $sp-xs $sp-md;
border-radius: $radius-full;
font-size: $fs-sm;
font-weight: $fw-medium;
background-color: $bg-elevated;
color: $text-secondary;
&.tag-active {
background-color: $amber-glow;
color: $amber;
border: 2rpx solid rgba(232, 168, 56, 0.3);
}
}
/* --- 分隔线 --- */
.divider {
height: 2rpx;
background: linear-gradient(90deg, transparent, var(--divider-color, rgba(255, 255, 255, 0.08)), transparent);
margin: $sp-lg 0;
}
/* --- 弹性布局辅助 --- */
.flex {
display: flex;
}
.flex-col {
display: flex;
flex-direction: column;
}
.flex-center {
display: flex;
align-items: center;
justify-content: center;
}
.flex-between {
display: flex;
align-items: center;
justify-content: space-between;
}
.flex-1 {
flex: 1;
}
/* --- 安全区域 --- */
.safe-bottom {
padding-bottom: calc(env(safe-area-inset-bottom) + 120rpx);
}
/* --- 健康提示条 --- */
.health-bar {
display: flex;
align-items: center;
justify-content: center;
padding: $sp-sm;
font-size: $fs-xs;
color: $text-tertiary;
background-color: var(--bg-subtle, rgba(255, 255, 255, 0.03));
text {
opacity: 0.5;
}
}
</style>