- 替换所有文件中的品牌名称引用,包括App.vue、pages.json、uni.scss等 - 更新全局样式、导航栏标题和组件中的文案显示 - 修改分享功能中的应用名称显示 - 调整聊天页面的输入栏键盘适配逻辑 - 在多个页面组件中添加事件发射声明以支持交互功能
412 lines
8.6 KiB
Vue
412 lines
8.6 KiB
Vue
<script>
|
|
import { getCurrentTheme, applyTheme } from './common/utils'
|
|
import client, { refreshAuthToken } from './common/api'
|
|
import wsManager from './common/websocket'
|
|
|
|
export default {
|
|
onLaunch() {
|
|
console.log('碰盏日记 App Launch')
|
|
// 初始化主题
|
|
this.initTheme()
|
|
// 尝试刷新 token
|
|
this.restoreAuth()
|
|
// 初始化 WebSocket 连接(私信功能)
|
|
this.initWebSocket()
|
|
// 数据迁移:清除旧版 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' ? '#F2F5F9' : '#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(() => {})
|
|
}
|
|
},
|
|
// 初始化 WebSocket 连接(私信实时通信)
|
|
initWebSocket() {
|
|
const token = uni.getStorageSync('auth_token')
|
|
if (token) {
|
|
wsManager.connect(token)
|
|
}
|
|
},
|
|
// 数据迁移:清除旧版 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%;
|
|
right: auto;
|
|
bottom: auto;
|
|
width: 100%;
|
|
height: 100%;
|
|
border: none;
|
|
transform: none;
|
|
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>
|