Compare commits
2
Commits
5c861e6ba5
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d335ec290a | ||
|
|
a628b73a80 |
@@ -1,13 +1,18 @@
|
|||||||
<script>
|
<script>
|
||||||
import { getCurrentTheme, applyTheme } from './common/utils'
|
|
||||||
import client, { refreshAuthToken } from './common/api'
|
import client, { refreshAuthToken } from './common/api'
|
||||||
import wsManager from './common/websocket'
|
import wsManager from './common/websocket'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
onLaunch() {
|
onLaunch() {
|
||||||
console.log('碰盏日记 App Launch')
|
console.log('碰盏日记 App Launch')
|
||||||
// 初始化主题
|
// 一次性设置窗口背景色(深色主题),避免切换 tab 时露白底
|
||||||
this.initTheme()
|
try {
|
||||||
|
uni.setBackgroundColor({
|
||||||
|
backgroundColor: '#0B0B14',
|
||||||
|
backgroundColorTop: '#0B0B14',
|
||||||
|
backgroundColorBottom: '#0B0B14'
|
||||||
|
})
|
||||||
|
} catch (e) {}
|
||||||
// 尝试刷新 token
|
// 尝试刷新 token
|
||||||
this.restoreAuth()
|
this.restoreAuth()
|
||||||
// 初始化 WebSocket 连接(私信功能)
|
// 初始化 WebSocket 连接(私信功能)
|
||||||
@@ -19,27 +24,11 @@ export default {
|
|||||||
},
|
},
|
||||||
onShow() {
|
onShow() {
|
||||||
console.log('App Show')
|
console.log('App Show')
|
||||||
// 每次回到前台刷新主题(时间可能已变化)
|
|
||||||
this.initTheme()
|
|
||||||
},
|
},
|
||||||
onHide() {
|
onHide() {
|
||||||
console.log('App Hide')
|
console.log('App Hide')
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 初始化并应用深色主题
|
|
||||||
initTheme() {
|
|
||||||
const theme = getCurrentTheme()
|
|
||||||
applyTheme(theme)
|
|
||||||
// 同步设置page元素背景色(统一深色主题)
|
|
||||||
const bgColor = '#0B0B14'
|
|
||||||
try {
|
|
||||||
uni.setBackgroundColor({
|
|
||||||
backgroundColor: bgColor,
|
|
||||||
backgroundColorTop: bgColor,
|
|
||||||
backgroundColorBottom: bgColor
|
|
||||||
})
|
|
||||||
} catch (e) {}
|
|
||||||
},
|
|
||||||
// 恢复登录态:从缓存恢复 token 并尝试刷新
|
// 恢复登录态:从缓存恢复 token 并尝试刷新
|
||||||
async restoreAuth() {
|
async restoreAuth() {
|
||||||
const token = uni.getStorageSync('auth_token')
|
const token = uni.getStorageSync('auth_token')
|
||||||
@@ -79,7 +68,7 @@ export default {
|
|||||||
uni.reLaunch({ url: '/pages/onboarding/onboarding', fail: () => {} })
|
uni.reLaunch({ url: '/pages/onboarding/onboarding', fail: () => {} })
|
||||||
}, 100)
|
}, 100)
|
||||||
}
|
}
|
||||||
// 否则正常进入首页(index)
|
// 否则正常进入主容器(main),pages.json 中 main 为第一个页面
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
/* 碰盏日记 - 主题混入 (Theme Mixin)
|
|
||||||
* 全局统一深色主题(琥珀夜光),已移除白天主题
|
|
||||||
* 页面根视图需绑定 :class="themeClass"
|
|
||||||
*/
|
|
||||||
import { applyTheme } from './utils'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
themeClass: 'theme-dark',
|
|
||||||
currentTheme: 'dark'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this._refreshTheme()
|
|
||||||
},
|
|
||||||
onShow() {
|
|
||||||
this._refreshTheme()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
_refreshTheme() {
|
|
||||||
// 固定深色主题
|
|
||||||
this.currentTheme = 'dark'
|
|
||||||
this.themeClass = 'theme-dark'
|
|
||||||
applyTheme('dark')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -277,95 +277,6 @@ export function calcLocalStreak(records) {
|
|||||||
return { streak, streakType, drankStreak, abstainStreak }
|
return { streak, streakType, drankStreak, abstainStreak }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 主题系统:全局统一使用深色主题(琥珀夜光),已移除白天主题
|
|
||||||
*/
|
|
||||||
export function getCurrentTheme() {
|
|
||||||
return 'dark'
|
|
||||||
}
|
|
||||||
|
|
||||||
export function applyTheme(theme) {
|
|
||||||
// 同步存储当前主题
|
|
||||||
uni.setStorageSync('current_theme', theme)
|
|
||||||
// 应用导航栏和TabBar主题
|
|
||||||
applyNavBarTheme(theme)
|
|
||||||
applyTabBarTheme(theme)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function applyNavBarTheme(theme) {
|
|
||||||
// 仅深色主题
|
|
||||||
try {
|
|
||||||
uni.setNavigationBarColor({
|
|
||||||
frontColor: '#ffffff',
|
|
||||||
backgroundColor: '#0B0B14',
|
|
||||||
animation: { duration: 300, timingFunc: 'easeInOut' }
|
|
||||||
})
|
|
||||||
} catch (e) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function applyTabBarTheme(theme) {
|
|
||||||
// 仅在 tabBar 页面上调用 setTabBarStyle,避免报错
|
|
||||||
// 页面清单直接从 pages.json 读取,新增 tab 页无需改这里
|
|
||||||
let tabBarPages = []
|
|
||||||
try {
|
|
||||||
// #ifdef MP-WEIXIN
|
|
||||||
tabBarPages = (typeof __wxConfig !== 'undefined' && __wxConfig.tabBar && __wxConfig.tabBar.list)
|
|
||||||
? __wxConfig.tabBar.list.map(t => t.pagePath)
|
|
||||||
: []
|
|
||||||
// #endif
|
|
||||||
if (!tabBarPages.length && typeof require === 'function') {
|
|
||||||
const cfg = require('../pages.json')
|
|
||||||
tabBarPages = (cfg.tabBar && cfg.tabBar.list) ? cfg.tabBar.list.map(t => t.pagePath) : []
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
tabBarPages = []
|
|
||||||
}
|
|
||||||
// 两种方式都取不到清单时兜底,保证主题正常应用
|
|
||||||
if (!tabBarPages.length) {
|
|
||||||
tabBarPages = ['pages/index/index', 'pages/circle/circle', 'pages/profile/profile']
|
|
||||||
}
|
|
||||||
const pages = getCurrentPages()
|
|
||||||
if (!pages.length) return
|
|
||||||
const currentPath = pages[pages.length - 1].route
|
|
||||||
if (!tabBarPages.includes(currentPath)) return
|
|
||||||
|
|
||||||
// 仅深色主题
|
|
||||||
const s = {
|
|
||||||
color: '#9494AC',
|
|
||||||
selectedColor: '#E8A838',
|
|
||||||
backgroundColor: '#151520',
|
|
||||||
borderStyle: 'black'
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
uni.setTabBarStyle({
|
|
||||||
color: s.color,
|
|
||||||
selectedColor: s.selectedColor,
|
|
||||||
backgroundColor: s.backgroundColor,
|
|
||||||
borderStyle: s.borderStyle,
|
|
||||||
// 必须传 fail 回调吞错:不传时 uni API 返回 Promise,
|
|
||||||
// 异步 reject 无法被 try/catch 捕获,会产生 UnhandledPromiseRejection
|
|
||||||
fail: () => {}
|
|
||||||
})
|
|
||||||
} catch (e) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getThemeColors(theme) {
|
|
||||||
// 仅保留深色主题色值(参数保留以兼容既有调用)
|
|
||||||
return {
|
|
||||||
textPrimary: '#FFFFFF',
|
|
||||||
textSecondary: '#C0C0D2',
|
|
||||||
textTertiary: '#9494AC',
|
|
||||||
amber: '#E8A838',
|
|
||||||
bgBase: '#0B0B14',
|
|
||||||
bgCard: '#1A1A28',
|
|
||||||
cardGradStart: '#1A1510',
|
|
||||||
cardGradEnd: '#0D0B08',
|
|
||||||
borderSubtle: 'rgba(232,168,56,0.15)',
|
|
||||||
bgPlaceholder: 'rgba(255,255,255,0.03)',
|
|
||||||
emojiBg: 'rgba(232,168,56,0.08)'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查成就解锁
|
* 检查成就解锁
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -11,6 +11,16 @@ import client, { API_HOST } from './api'
|
|||||||
// SDK 具名导出的连接类(绕开 client.ChatWebSocket 方法内部使用的浏览器 API)
|
// SDK 具名导出的连接类(绕开 client.ChatWebSocket 方法内部使用的浏览器 API)
|
||||||
import { ChatWebSocketConn } from 'HaveADrink'
|
import { ChatWebSocketConn } from 'HaveADrink'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WebSocket 总开关
|
||||||
|
* 当前私信实时通道暂未启用,置为 false:
|
||||||
|
* - connect() 直接返回,不会发起任何 socket 连接/重连
|
||||||
|
* - send() 直接返回,不暂存消息
|
||||||
|
* - on()/off()/disconnect() 仍可安全调用(空操作),各页面无需改动
|
||||||
|
* 需要恢复实时通信时,将此值改为 true 即可。
|
||||||
|
*/
|
||||||
|
const WS_ENABLED = false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自行解析 host 并构造 ChatWebSocketConn
|
* 自行解析 host 并构造 ChatWebSocketConn
|
||||||
* SDK 的 client.ChatWebSocket() 内部使用 new URL() / new URLSearchParams(),
|
* SDK 的 client.ChatWebSocket() 内部使用 new URL() / new URLSearchParams(),
|
||||||
@@ -57,6 +67,7 @@ class WebSocketManager {
|
|||||||
* @param {string} token - 用户认证 token
|
* @param {string} token - 用户认证 token
|
||||||
*/
|
*/
|
||||||
connect(token) {
|
connect(token) {
|
||||||
|
if (!WS_ENABLED) return
|
||||||
if (this.conn || this.isConnecting) return
|
if (this.conn || this.isConnecting) return
|
||||||
this.token = token || uni.getStorageSync('auth_token') || ''
|
this.token = token || uni.getStorageSync('auth_token') || ''
|
||||||
if (!this.token) {
|
if (!this.token) {
|
||||||
@@ -149,6 +160,7 @@ class WebSocketManager {
|
|||||||
* @param {object} data - 消息数据
|
* @param {object} data - 消息数据
|
||||||
*/
|
*/
|
||||||
send(mesgType, data = {}) {
|
send(mesgType, data = {}) {
|
||||||
|
if (!WS_ENABLED) return
|
||||||
if (this.isConnected && this.conn) {
|
if (this.isConnected && this.conn) {
|
||||||
this._write(mesgType, data)
|
this._write(mesgType, data)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -0,0 +1,107 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 自绘底部导航:替代微信原生 tabBar。点击只 emit change 交给容器切 v-show,
|
||||||
|
不走 switchTab 页面过渡,从根源消除 iOS WKWebView 重新栅格化导致的闪白。
|
||||||
|
配色沿用原生 tabBar:未选中 #9494AC、选中 #E8A838、背景 #151520。 -->
|
||||||
|
<view class="self-tabbar" :style="{ paddingBottom: safeBottom + 'px' }">
|
||||||
|
<view
|
||||||
|
v-for="(item, i) in items"
|
||||||
|
:key="i"
|
||||||
|
class="tab-item"
|
||||||
|
@click="onClick(i)"
|
||||||
|
>
|
||||||
|
<image
|
||||||
|
class="tab-icon"
|
||||||
|
:src="current === i ? item.activeIcon : item.icon"
|
||||||
|
mode="aspectFit"
|
||||||
|
/>
|
||||||
|
<text class="tab-text" :class="{ active: current === i }">{{ item.text }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'TabBar',
|
||||||
|
props: {
|
||||||
|
// 当前选中的 tab 索引(home=0 / circle=1 / profile=2),由容器 main.vue 下发
|
||||||
|
current: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// Vue3 组件事件必须显式声明,否则可能触发异常/双触发
|
||||||
|
emits: ['change'],
|
||||||
|
data() {
|
||||||
|
// 底部安全区(iPhone 全面屏手势条),避免导航内容被手势条遮挡
|
||||||
|
let safeBottom = 0
|
||||||
|
try {
|
||||||
|
const sys = uni.getSystemInfoSync()
|
||||||
|
if (sys.safeAreaInsets && typeof sys.safeAreaInsets.bottom === 'number') {
|
||||||
|
safeBottom = sys.safeAreaInsets.bottom
|
||||||
|
} else if (sys.safeArea && sys.windowHeight) {
|
||||||
|
safeBottom = Math.max(0, sys.windowHeight - sys.safeArea.bottom)
|
||||||
|
}
|
||||||
|
} catch (e) { safeBottom = 0 }
|
||||||
|
return {
|
||||||
|
safeBottom,
|
||||||
|
items: [
|
||||||
|
{ text: '首页', icon: '/static/tab-home.png', activeIcon: '/static/tab-home-active.png' },
|
||||||
|
{ text: '酒友圈', icon: '/static/tab-circle.png', activeIcon: '/static/tab-circle-active.png' },
|
||||||
|
{ text: '我的', icon: '/static/tab-profile.png', activeIcon: '/static/tab-profile-active.png' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onClick(i) {
|
||||||
|
// 点击当前 tab 不重复触发,避免无谓的 pageShow 与滚动恢复
|
||||||
|
if (i === this.current) return
|
||||||
|
this.$emit('change', i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.self-tabbar {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
/* 高于子组件内部最高的 z-index:100(index/profile 存在 100 的 fixed/sticky 元素),确保导航稳定在最上层;
|
||||||
|
系统级 uni.showModal 不受此影响,仍会覆盖其上 */
|
||||||
|
z-index: 999;
|
||||||
|
display: flex;
|
||||||
|
/* 内容区固定 100rpx,安全区由 padding-bottom 额外承载;
|
||||||
|
box-sizing:content-box 确保总高 = 100rpx + safeBottom,与容器下发的 --tabbar-h 精确一致 */
|
||||||
|
height: 100rpx;
|
||||||
|
box-sizing: content-box;
|
||||||
|
background-color: #151520;
|
||||||
|
/* 顶部 1rpx 分隔线用 box-shadow 绘制,不占据高度(避免破坏 --tabbar-h 一致性) */
|
||||||
|
box-shadow: 0 -1rpx 0 0 rgba(255, 255, 255, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-icon {
|
||||||
|
width: 44rpx;
|
||||||
|
height: 44rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-text {
|
||||||
|
margin-top: 4rpx;
|
||||||
|
font-size: 20rpx;
|
||||||
|
line-height: 1;
|
||||||
|
color: #9494AC;
|
||||||
|
transition: color 0.2s ease;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: #E8A838;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
+5
-47
@@ -1,17 +1,13 @@
|
|||||||
{
|
{
|
||||||
"pages": [
|
"pages": [
|
||||||
{
|
{
|
||||||
"path": "pages/index/index",
|
"path": "pages/main/main",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationStyle": "custom",
|
"navigationStyle": "custom",
|
||||||
"navigationBarTitleText": ""
|
"navigationBarTitleText": "",
|
||||||
}
|
"backgroundColor": "#0B0B14",
|
||||||
},
|
"backgroundColorTop": "#0B0B14",
|
||||||
{
|
"backgroundColorBottom": "#0B0B14"
|
||||||
"path": "pages/profile/profile",
|
|
||||||
"style": {
|
|
||||||
"navigationStyle": "custom",
|
|
||||||
"navigationBarTitleText": ""
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -49,18 +45,6 @@
|
|||||||
"navigationBarTitleText": ""
|
"navigationBarTitleText": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"path": "pages/circle/circle",
|
|
||||||
"style": {
|
|
||||||
"navigationStyle": "custom",
|
|
||||||
"navigationBarTitleText": "",
|
|
||||||
"app-plus": {
|
|
||||||
"background": "#0B0B14",
|
|
||||||
"bounceBackground": "#0B0B14",
|
|
||||||
"animationAlphaBGColor": "#0B0B14"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"path": "pages/circle-detail/circle-detail",
|
"path": "pages/circle-detail/circle-detail",
|
||||||
"style": {
|
"style": {
|
||||||
@@ -139,31 +123,5 @@
|
|||||||
"backgroundColorTop": "#0B0B14",
|
"backgroundColorTop": "#0B0B14",
|
||||||
"backgroundColorBottom": "#0B0B14"
|
"backgroundColorBottom": "#0B0B14"
|
||||||
},
|
},
|
||||||
"tabBar": {
|
|
||||||
"color": "#9494AC",
|
|
||||||
"selectedColor": "#E8A838",
|
|
||||||
"backgroundColor": "#151520",
|
|
||||||
"borderStyle": "black",
|
|
||||||
"list": [
|
|
||||||
{
|
|
||||||
"pagePath": "pages/index/index",
|
|
||||||
"text": "首页",
|
|
||||||
"iconPath": "static/tab-home.png",
|
|
||||||
"selectedIconPath": "static/tab-home-active.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"pagePath": "pages/circle/circle",
|
|
||||||
"text": "酒友圈",
|
|
||||||
"iconPath": "static/tab-circle.png",
|
|
||||||
"selectedIconPath": "static/tab-circle-active.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"pagePath": "pages/profile/profile",
|
|
||||||
"text": "我的",
|
|
||||||
"iconPath": "static/tab-profile.png",
|
|
||||||
"selectedIconPath": "static/tab-profile-active.png"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"uniIdRouter": {}
|
"uniIdRouter": {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :class="themeClass" class="page-container agreement-page">
|
<view class="page-container agreement-page">
|
||||||
<!-- 自定义导航栏(避让胶囊) -->
|
<!-- 自定义导航栏(避让胶囊) -->
|
||||||
<view class="agree-nav" :style="{ paddingTop: navPaddingTop }">
|
<view class="agree-nav" :style="{ paddingTop: navPaddingTop }">
|
||||||
<view class="agree-nav-row" :style="{ paddingRight: navPaddingRight }">
|
<view class="agree-nav-row" :style="{ paddingRight: navPaddingRight }">
|
||||||
@@ -27,10 +27,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import themeMixin from '../../common/theme-mixin'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [themeMixin],
|
|
||||||
data() {
|
data() {
|
||||||
const menuBtn = uni.getMenuButtonBoundingClientRect()
|
const menuBtn = uni.getMenuButtonBoundingClientRect()
|
||||||
const sysInfo = uni.getSystemInfoSync()
|
const sysInfo = uni.getSystemInfoSync()
|
||||||
@@ -57,7 +54,7 @@ export default {
|
|||||||
if (pages.length > 1) {
|
if (pages.length > 1) {
|
||||||
uni.navigateBack()
|
uni.navigateBack()
|
||||||
} else {
|
} else {
|
||||||
uni.switchTab({ url: '/pages/index/index' })
|
uni.reLaunch({ url: '/pages/main/main?tab=0' })
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
userSections() {
|
userSections() {
|
||||||
|
|||||||
+5
-7
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :class="themeClass" class="page-container card-page">
|
<view class="page-container card-page">
|
||||||
<view class="card-nav" :style="{ paddingTop: (statusBarHeight + 12) + 'px' }">
|
<view class="card-nav" :style="{ paddingTop: (statusBarHeight + 12) + 'px' }">
|
||||||
<view class="step-back" @click="goBack">
|
<view class="step-back" @click="goBack">
|
||||||
<text class="step-back-arrow">‹</text>
|
<text class="step-back-arrow">‹</text>
|
||||||
@@ -42,12 +42,10 @@ import DrinkCard from '../../components/DrinkCard.vue'
|
|||||||
import client from '../../common/api'
|
import client from '../../common/api'
|
||||||
import { calcStandardCups, unitToMl } from '../../common/utils'
|
import { calcStandardCups, unitToMl } from '../../common/utils'
|
||||||
import { DRINK_CATEGORIES, FOOD_CATEGORIES, DRINK_QUOTES, FEELINGS } from '../../common/constants'
|
import { DRINK_CATEGORIES, FOOD_CATEGORIES, DRINK_QUOTES, FEELINGS } from '../../common/constants'
|
||||||
import themeMixin from '../../common/theme-mixin'
|
|
||||||
|
|
||||||
const UNIT_NAMES = { ml: 'ml', liang: '两', bottle: '瓶', cup: '杯', can: '听', shot: 'shot' }
|
const UNIT_NAMES = { ml: 'ml', liang: '两', bottle: '瓶', cup: '杯', can: '听', shot: 'shot' }
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [themeMixin],
|
|
||||||
components: { DrinkCard },
|
components: { DrinkCard },
|
||||||
data() {
|
data() {
|
||||||
const sysInfo = uni.getSystemInfoSync()
|
const sysInfo = uni.getSystemInfoSync()
|
||||||
@@ -761,7 +759,7 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
closeToHome() {
|
closeToHome() {
|
||||||
uni.switchTab({ url: '/pages/index/index' })
|
uni.reLaunch({ url: '/pages/main/main?tab=0' })
|
||||||
},
|
},
|
||||||
_doBack() {
|
_doBack() {
|
||||||
console.log('_doBack called, pages:', getCurrentPages().length)
|
console.log('_doBack called, pages:', getCurrentPages().length)
|
||||||
@@ -769,12 +767,12 @@ export default {
|
|||||||
uni.navigateBack({
|
uni.navigateBack({
|
||||||
fail: (err) => {
|
fail: (err) => {
|
||||||
console.error('navigateBack fail:', err)
|
console.error('navigateBack fail:', err)
|
||||||
uni.reLaunch({ url: '/pages/index/index' })
|
uni.reLaunch({ url: '/pages/main/main?tab=0' })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
console.log('no pages to go back to, reLaunch to index')
|
console.log('no pages to go back to, reLaunch to index')
|
||||||
uni.reLaunch({ url: '/pages/index/index' })
|
uni.reLaunch({ url: '/pages/main/main?tab=0' })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -788,7 +786,7 @@ export default {
|
|||||||
: '今晚的酒局记录 - 碰盏日记'
|
: '今晚的酒局记录 - 碰盏日记'
|
||||||
return {
|
return {
|
||||||
title,
|
title,
|
||||||
path: '/pages/index/index',
|
path: '/pages/main/main?tab=0',
|
||||||
imageUrl: this.posterPath || undefined
|
imageUrl: this.posterPath || undefined
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :class="themeClass" class="page-container chatlist-page">
|
<view class="page-container chatlist-page">
|
||||||
<!-- 自定义导航栏 -->
|
<!-- 自定义导航栏 -->
|
||||||
<view class="chatlist-nav" :style="{ paddingTop: headerPaddingTop }">
|
<view class="chatlist-nav" :style="{ paddingTop: headerPaddingTop }">
|
||||||
<view class="chatlist-nav-inner">
|
<view class="chatlist-nav-inner">
|
||||||
@@ -68,11 +68,9 @@
|
|||||||
import EmptyState from '../../components/EmptyState.vue'
|
import EmptyState from '../../components/EmptyState.vue'
|
||||||
import { GetConversations } from '../../common/api'
|
import { GetConversations } from '../../common/api'
|
||||||
import wsManager from '../../common/websocket'
|
import wsManager from '../../common/websocket'
|
||||||
import themeMixin from '../../common/theme-mixin'
|
|
||||||
import { isValidAvatar } from '../../common/utils'
|
import { isValidAvatar } from '../../common/utils'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [themeMixin],
|
|
||||||
components: { EmptyState },
|
components: { EmptyState },
|
||||||
data() {
|
data() {
|
||||||
const menuBtn = uni.getMenuButtonBoundingClientRect()
|
const menuBtn = uni.getMenuButtonBoundingClientRect()
|
||||||
@@ -119,7 +117,7 @@ export default {
|
|||||||
uni.navigateBack()
|
uni.navigateBack()
|
||||||
},
|
},
|
||||||
goCircle() {
|
goCircle() {
|
||||||
uni.switchTab({ url: '/pages/circle/circle' })
|
uni.reLaunch({ url: '/pages/main/main?tab=1' })
|
||||||
},
|
},
|
||||||
|
|
||||||
// === WebSocket 实时更新 ===
|
// === WebSocket 实时更新 ===
|
||||||
|
|||||||
+1
-3
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :class="themeClass" class="page-container chat-page">
|
<view class="page-container chat-page">
|
||||||
<!-- 自定义导航栏 -->
|
<!-- 自定义导航栏 -->
|
||||||
<view class="chat-nav" :style="{ paddingTop: headerPaddingTop }">
|
<view class="chat-nav" :style="{ paddingTop: headerPaddingTop }">
|
||||||
<view class="chat-nav-inner">
|
<view class="chat-nav-inner">
|
||||||
@@ -121,10 +121,8 @@
|
|||||||
<script>
|
<script>
|
||||||
import { GetMessages, MarkRead, GetConversations } from '../../common/api'
|
import { GetMessages, MarkRead, GetConversations } from '../../common/api'
|
||||||
import wsManager from '../../common/websocket'
|
import wsManager from '../../common/websocket'
|
||||||
import themeMixin from '../../common/theme-mixin'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [themeMixin],
|
|
||||||
data() {
|
data() {
|
||||||
const menuBtn = uni.getMenuButtonBoundingClientRect()
|
const menuBtn = uni.getMenuButtonBoundingClientRect()
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :class="themeClass" class="page-container detail-page">
|
<view class="page-container detail-page">
|
||||||
<!-- 顶部导航 -->
|
<!-- 顶部导航 -->
|
||||||
<view class="detail-nav" :style="{ paddingTop: navPaddingTop }">
|
<view class="detail-nav" :style="{ paddingTop: navPaddingTop }">
|
||||||
<view class="detail-nav-inner">
|
<view class="detail-nav-inner">
|
||||||
@@ -66,10 +66,8 @@ import FeedCard from '../../components/FeedCard.vue'
|
|||||||
import CommentItem from '../../components/CommentItem.vue'
|
import CommentItem from '../../components/CommentItem.vue'
|
||||||
import EmptyState from '../../components/EmptyState.vue'
|
import EmptyState from '../../components/EmptyState.vue'
|
||||||
import { GetFeedComments, AddComment, LikeFeed, UnlikeFeed, DeleteFeed, requireLogin } from '../../common/api'
|
import { GetFeedComments, AddComment, LikeFeed, UnlikeFeed, DeleteFeed, requireLogin } from '../../common/api'
|
||||||
import themeMixin from '../../common/theme-mixin'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [themeMixin],
|
|
||||||
components: { FeedCard, CommentItem, EmptyState },
|
components: { FeedCard, CommentItem, EmptyState },
|
||||||
data() {
|
data() {
|
||||||
const menuBtn = uni.getMenuButtonBoundingClientRect()
|
const menuBtn = uni.getMenuButtonBoundingClientRect()
|
||||||
@@ -98,17 +96,11 @@ export default {
|
|||||||
if (getCurrentPages().length > 1) {
|
if (getCurrentPages().length > 1) {
|
||||||
uni.navigateBack({
|
uni.navigateBack({
|
||||||
fail: () => {
|
fail: () => {
|
||||||
uni.switchTab({
|
uni.reLaunch({ url: '/pages/main/main?tab=0' })
|
||||||
url: '/pages/index/index',
|
|
||||||
fail: () => uni.reLaunch({ url: '/pages/index/index' })
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
uni.switchTab({
|
uni.reLaunch({ url: '/pages/main/main?tab=0' })
|
||||||
url: '/pages/index/index',
|
|
||||||
fail: () => uni.reLaunch({ url: '/pages/index/index' })
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async loadFeed() {
|
async loadFeed() {
|
||||||
@@ -219,7 +211,7 @@ export default {
|
|||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
title: '酒友圈 - 碰盏日记',
|
title: '酒友圈 - 碰盏日记',
|
||||||
path: '/pages/index/index'
|
path: '/pages/main/main?tab=0'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :class="themeClass" class="page-container publish-page">
|
<view class="page-container publish-page">
|
||||||
<!-- 顶部导航 -->
|
<!-- 顶部导航 -->
|
||||||
<view class="publish-nav" :style="{ paddingTop: navPaddingTop, paddingRight: navPaddingRight }">
|
<view class="publish-nav" :style="{ paddingTop: navPaddingTop, paddingRight: navPaddingRight }">
|
||||||
<view class="publish-nav-inner">
|
<view class="publish-nav-inner">
|
||||||
@@ -81,10 +81,8 @@
|
|||||||
<script>
|
<script>
|
||||||
import { PublishFeed, UploadImage } from '../../common/api'
|
import { PublishFeed, UploadImage } from '../../common/api'
|
||||||
import client from '../../common/api'
|
import client from '../../common/api'
|
||||||
import themeMixin from '../../common/theme-mixin'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [themeMixin],
|
|
||||||
data() {
|
data() {
|
||||||
const menuBtn = uni.getMenuButtonBoundingClientRect()
|
const menuBtn = uni.getMenuButtonBoundingClientRect()
|
||||||
const sysInfo = uni.getSystemInfoSync()
|
const sysInfo = uni.getSystemInfoSync()
|
||||||
|
|||||||
+31
-32
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :class="themeClass" class="page-container circle-page">
|
<view class="page-container circle-page">
|
||||||
<!-- 顶部导航 -->
|
<!-- 顶部导航 -->
|
||||||
<view class="circle-header" :style="{ paddingTop: headerPaddingTop }">
|
<view class="circle-header" :style="{ paddingTop: headerPaddingTop }">
|
||||||
<view class="circle-title-row" :style="{ paddingRight: headerPaddingRight }">
|
<view class="circle-title-row" :style="{ paddingRight: headerPaddingRight }">
|
||||||
@@ -81,10 +81,8 @@ import EmptyState from '../../components/EmptyState.vue'
|
|||||||
import { GetCircleFeeds, LikeFeed, UnlikeFeed, DeleteFeed, GetFriends, GetFriendRequests, GetEvents, DeleteEvent, GetUnreadCount, isLoggedIn, requireLogin } from '../../common/api'
|
import { GetCircleFeeds, LikeFeed, UnlikeFeed, DeleteFeed, GetFriends, GetFriendRequests, GetEvents, DeleteEvent, GetUnreadCount, isLoggedIn, requireLogin } from '../../common/api'
|
||||||
import wsManager from '../../common/websocket'
|
import wsManager from '../../common/websocket'
|
||||||
import { getMyInviteCode } from '../../common/invite'
|
import { getMyInviteCode } from '../../common/invite'
|
||||||
import themeMixin from '../../common/theme-mixin'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [themeMixin],
|
|
||||||
components: { FeedCard, FriendItem, EventCard, EmptyState },
|
components: { FeedCard, FriendItem, EventCard, EmptyState },
|
||||||
data() {
|
data() {
|
||||||
const menuBtn = uni.getMenuButtonBoundingClientRect()
|
const menuBtn = uni.getMenuButtonBoundingClientRect()
|
||||||
@@ -119,33 +117,34 @@ export default {
|
|||||||
isGuest: false
|
isGuest: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onShow() {
|
|
||||||
this.isGuest = !isLoggedIn()
|
|
||||||
if (this.isGuest) {
|
|
||||||
// 游客态不发起鉴权请求,展示空态与登录引导
|
|
||||||
this.feeds = []
|
|
||||||
this.loading = false
|
|
||||||
} else {
|
|
||||||
this.loadFeeds(true)
|
|
||||||
}
|
|
||||||
// 消息入口已隐藏,未读角标暂不展示,空转请求先停掉(恢复入口时打开)
|
|
||||||
// this.loadUnread()
|
|
||||||
// this.bindWsEvents()
|
|
||||||
// 读取当前用户ID(删除自己的动态时用)
|
|
||||||
try {
|
|
||||||
const user = JSON.parse(uni.getStorageSync('user_info') || '{}')
|
|
||||||
this.myUserId = user.id !== undefined && user.id !== null ? String(user.id) : ''
|
|
||||||
} catch (e) { this.myUserId = '' }
|
|
||||||
// 页面显示时确保 WS 已连接(登录后/断线后兼容)
|
|
||||||
wsManager.connect()
|
|
||||||
},
|
|
||||||
onHide() {
|
|
||||||
this.unbindWsEvents()
|
|
||||||
},
|
|
||||||
onUnload() {
|
|
||||||
this.unbindWsEvents()
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
|
// === 子组件生命周期(由 main.vue 容器通过 ref 调用)===
|
||||||
|
pageShow() {
|
||||||
|
this.isGuest = !isLoggedIn()
|
||||||
|
if (this.isGuest) {
|
||||||
|
// 游客态不发起鉴权请求,展示空态与登录引导
|
||||||
|
this.feeds = []
|
||||||
|
this.loading = false
|
||||||
|
} else {
|
||||||
|
this.loadFeeds(true)
|
||||||
|
}
|
||||||
|
// 消息入口已隐藏,未读角标暂不展示,空转请求先停掉(恢复入口时打开)
|
||||||
|
// this.loadUnread()
|
||||||
|
// this.bindWsEvents()
|
||||||
|
// 读取当前用户ID(删除自己的动态时用)
|
||||||
|
try {
|
||||||
|
const user = JSON.parse(uni.getStorageSync('user_info') || '{}')
|
||||||
|
this.myUserId = user.id !== undefined && user.id !== null ? String(user.id) : ''
|
||||||
|
} catch (e) { this.myUserId = '' }
|
||||||
|
// 页面显示时确保 WS 已连接(登录后/断线后兼容)
|
||||||
|
wsManager.connect()
|
||||||
|
},
|
||||||
|
pageHide() {
|
||||||
|
this.unbindWsEvents()
|
||||||
|
},
|
||||||
|
pageUnload() {
|
||||||
|
this.unbindWsEvents()
|
||||||
|
},
|
||||||
// === WebSocket 事件 ===
|
// === WebSocket 事件 ===
|
||||||
bindWsEvents() {
|
bindWsEvents() {
|
||||||
if (this._wsBound) return
|
if (this._wsBound) return
|
||||||
@@ -380,7 +379,7 @@ export default {
|
|||||||
const parts = []
|
const parts = []
|
||||||
if (this.inviteCode) parts.push(`inviteCode=${encodeURIComponent(this.inviteCode)}`)
|
if (this.inviteCode) parts.push(`inviteCode=${encodeURIComponent(this.inviteCode)}`)
|
||||||
if (user.nickname) parts.push(`inviterNick=${encodeURIComponent(user.nickname)}`)
|
if (user.nickname) parts.push(`inviterNick=${encodeURIComponent(user.nickname)}`)
|
||||||
const query = parts.length ? `?${parts.join('&')}` : ''
|
const query = parts.length ? `&${parts.join('&')}` : ''
|
||||||
const nick = user.nickname ? `「${user.nickname}」` : ''
|
const nick = user.nickname ? `「${user.nickname}」` : ''
|
||||||
// 本次分享已用掉当前邀请码,异步生成新码供下次使用
|
// 本次分享已用掉当前邀请码,异步生成新码供下次使用
|
||||||
this.inviteCode = ''
|
this.inviteCode = ''
|
||||||
@@ -388,7 +387,7 @@ export default {
|
|||||||
this.shareMode = 'default'
|
this.shareMode = 'default'
|
||||||
return {
|
return {
|
||||||
title: `${nick}邀请你成为酒友,一起记录饮酒生活 🍻`,
|
title: `${nick}邀请你成为酒友,一起记录饮酒生活 🍻`,
|
||||||
path: `/pages/index/index${query}`
|
path: `/pages/main/main?tab=0${query}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const feed = this.shareFeed
|
const feed = this.shareFeed
|
||||||
@@ -405,7 +404,7 @@ export default {
|
|||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
title: '酒友圈 - 碰盏日记',
|
title: '酒友圈 - 碰盏日记',
|
||||||
path: '/pages/index/index'
|
path: '/pages/main/main?tab=1'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onShareTimeline() {
|
onShareTimeline() {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :class="themeClass" class="page-container create-page">
|
<view class="page-container create-page">
|
||||||
<!-- 顶部导航 -->
|
<!-- 顶部导航 -->
|
||||||
<view class="create-nav" :style="{ paddingTop: navPaddingTop }">
|
<view class="create-nav" :style="{ paddingTop: navPaddingTop }">
|
||||||
<view class="create-nav-inner">
|
<view class="create-nav-inner">
|
||||||
@@ -109,10 +109,8 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { CreateEvent, UpdateEvent, GetEventDetail } from '../../common/api'
|
import { CreateEvent, UpdateEvent, GetEventDetail } from '../../common/api'
|
||||||
import themeMixin from '../../common/theme-mixin'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [themeMixin],
|
|
||||||
data() {
|
data() {
|
||||||
const menuBtn = uni.getMenuButtonBoundingClientRect()
|
const menuBtn = uni.getMenuButtonBoundingClientRect()
|
||||||
const now = new Date()
|
const now = new Date()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :class="themeClass" class="page-container evt-detail-page">
|
<view class="page-container evt-detail-page">
|
||||||
<!-- 顶部导航 -->
|
<!-- 顶部导航 -->
|
||||||
<view class="evt-nav" :style="{ paddingTop: navPaddingTop }">
|
<view class="evt-nav" :style="{ paddingTop: navPaddingTop }">
|
||||||
<view class="evt-nav-inner">
|
<view class="evt-nav-inner">
|
||||||
@@ -169,10 +169,8 @@
|
|||||||
<script>
|
<script>
|
||||||
import { GetEventDetail, JoinEvent, QuitEvent, CheckInEvent, DeleteEvent, ApproveEvent } from '../../common/api'
|
import { GetEventDetail, JoinEvent, QuitEvent, CheckInEvent, DeleteEvent, ApproveEvent } from '../../common/api'
|
||||||
import wsManager from '../../common/websocket'
|
import wsManager from '../../common/websocket'
|
||||||
import themeMixin from '../../common/theme-mixin'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [themeMixin],
|
|
||||||
data() {
|
data() {
|
||||||
const menuBtn = uni.getMenuButtonBoundingClientRect()
|
const menuBtn = uni.getMenuButtonBoundingClientRect()
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :class="themeClass" class="page-container friends-page">
|
<view class="page-container friends-page">
|
||||||
<!-- 顶部导航 -->
|
<!-- 顶部导航 -->
|
||||||
<view class="friends-nav" :style="{ paddingTop: navPaddingTop }">
|
<view class="friends-nav" :style="{ paddingTop: navPaddingTop }">
|
||||||
<view class="friends-nav-inner">
|
<view class="friends-nav-inner">
|
||||||
@@ -96,10 +96,8 @@ import FriendItem from '../../components/FriendItem.vue'
|
|||||||
import EmptyState from '../../components/EmptyState.vue'
|
import EmptyState from '../../components/EmptyState.vue'
|
||||||
import { GetFriends, GetFriendRequests, AcceptFriendRequest, RemoveFriend } from '../../common/api'
|
import { GetFriends, GetFriendRequests, AcceptFriendRequest, RemoveFriend } from '../../common/api'
|
||||||
import { savePendingInvite, handlePendingInvite, getMyInviteCode } from '../../common/invite'
|
import { savePendingInvite, handlePendingInvite, getMyInviteCode } from '../../common/invite'
|
||||||
import themeMixin from '../../common/theme-mixin'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [themeMixin],
|
|
||||||
components: { FriendItem, EmptyState },
|
components: { FriendItem, EmptyState },
|
||||||
data() {
|
data() {
|
||||||
const menuBtn = uni.getMenuButtonBoundingClientRect()
|
const menuBtn = uni.getMenuButtonBoundingClientRect()
|
||||||
@@ -204,13 +202,13 @@ export default {
|
|||||||
const parts = []
|
const parts = []
|
||||||
if (this.inviteCode) parts.push(`inviteCode=${encodeURIComponent(this.inviteCode)}`)
|
if (this.inviteCode) parts.push(`inviteCode=${encodeURIComponent(this.inviteCode)}`)
|
||||||
if (user.nickname) parts.push(`inviterNick=${encodeURIComponent(user.nickname)}`)
|
if (user.nickname) parts.push(`inviterNick=${encodeURIComponent(user.nickname)}`)
|
||||||
const query = parts.length ? `?${parts.join('&')}` : ''
|
const query = parts.length ? `&${parts.join('&')}` : ''
|
||||||
const nick = user.nickname ? `「${user.nickname}」` : ''
|
const nick = user.nickname ? `「${user.nickname}」` : ''
|
||||||
// 本次分享已用掉当前邀请码,异步生成新码供下次分享
|
// 本次分享已用掉当前邀请码,异步生成新码供下次分享
|
||||||
this.refreshInviteCode()
|
this.refreshInviteCode()
|
||||||
return {
|
return {
|
||||||
title: `${nick}邀请你成为酒友,一起记录饮酒生活 🍻`,
|
title: `${nick}邀请你成为酒友,一起记录饮酒生活 🍻`,
|
||||||
path: `/pages/index/index${query}`
|
path: `/pages/main/main?tab=0${query}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :class="themeClass" class="page-container games-page">
|
<view class="page-container games-page">
|
||||||
<!-- 顶部导航 -->
|
<!-- 顶部导航 -->
|
||||||
<view class="games-nav" :style="{ paddingTop: navPaddingTop }">
|
<view class="games-nav" :style="{ paddingTop: navPaddingTop }">
|
||||||
<view class="nav-back" @click="goBack">
|
<view class="nav-back" @click="goBack">
|
||||||
@@ -259,10 +259,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import themeMixin from '../../common/theme-mixin'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [themeMixin],
|
|
||||||
data() {
|
data() {
|
||||||
let navPaddingTop = '20px'
|
let navPaddingTop = '20px'
|
||||||
try {
|
try {
|
||||||
|
|||||||
+39
-40
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :class="themeClass" class="page-container home">
|
<view class="page-container home">
|
||||||
<!-- 顶部问候 -->
|
<!-- 顶部问候 -->
|
||||||
<view class="greeting-bar" :style="{ paddingTop: statusBarHeight + 'px' }">
|
<view class="greeting-bar" :style="{ paddingTop: statusBarHeight + 'px' }">
|
||||||
<view class="greeting-left">
|
<view class="greeting-left">
|
||||||
@@ -153,10 +153,8 @@ import { GetCalendarReq, DeleteRecordReq, CreateRecordReq, GetRecordDetailReq }
|
|||||||
import { getGreeting, formatDate, getWeekStart, getCatIcon, isIconPath, calcLocalStreak } from '../../common/utils'
|
import { getGreeting, formatDate, getWeekStart, getCatIcon, isIconPath, calcLocalStreak } from '../../common/utils'
|
||||||
import { FEELINGS, DRINK_CATEGORIES, DRINK_UNITS } from '../../common/constants'
|
import { FEELINGS, DRINK_CATEGORIES, DRINK_UNITS } from '../../common/constants'
|
||||||
import { savePendingInvite, handlePendingInvite } from '../../common/invite'
|
import { savePendingInvite, handlePendingInvite } from '../../common/invite'
|
||||||
import themeMixin from '../../common/theme-mixin'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [themeMixin],
|
|
||||||
components: { DrinkCalendar },
|
components: { DrinkCalendar },
|
||||||
data() {
|
data() {
|
||||||
const now = new Date()
|
const now = new Date()
|
||||||
@@ -189,44 +187,45 @@ export default {
|
|||||||
return this.selectedDate === formatDate(new Date(), 'YYYY-MM-DD')
|
return this.selectedDate === formatDate(new Date(), 'YYYY-MM-DD')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onLoad(options) {
|
|
||||||
// 分享邀请落地:携带 inviteCode 时暂存邀请,已登录则立即接受邀请
|
|
||||||
if (options && options.inviteCode) {
|
|
||||||
savePendingInvite(options.inviteCode, options.inviterNick)
|
|
||||||
if (uni.getStorageSync('is_logged_in') === 'true') {
|
|
||||||
handlePendingInvite()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onShow() {
|
|
||||||
// 首次启动跳转引导页由 App.vue onLaunch 统一处理,
|
|
||||||
// 这里不再重复 reLaunch,避免两个跳转并发导致 reLaunch:fail timeout
|
|
||||||
const isFirst = uni.getStorageSync('is_first_launch')
|
|
||||||
if (isFirst === 'true') {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// 游客可直接浏览首页:不发起鉴权请求,展示空数据;
|
|
||||||
// 仅在用户主动点击记录等功能时才引导登录(微信审核要求:先浏览后登录)
|
|
||||||
this.isGuest = !isLoggedIn()
|
|
||||||
if (this.isGuest) {
|
|
||||||
this.initGuestView()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.loadData()
|
|
||||||
},
|
|
||||||
onShareAppMessage() {
|
|
||||||
return {
|
|
||||||
title: '碰盏日记 - 让每一杯酒都有迹可循',
|
|
||||||
path: '/pages/index/index'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onShareTimeline() {
|
|
||||||
return {
|
|
||||||
title: '碰盏日记 - 让每一杯酒都有迹可循',
|
|
||||||
query: ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
|
// === 子组件生命周期(由 main.vue 容器通过 ref 调用)===
|
||||||
|
pageLoad(options) {
|
||||||
|
// 分享邀请落地:携带 inviteCode 时暂存邀请,已登录则立即接受邀请
|
||||||
|
if (options && options.inviteCode) {
|
||||||
|
savePendingInvite(options.inviteCode, options.inviterNick)
|
||||||
|
if (uni.getStorageSync('is_logged_in') === 'true') {
|
||||||
|
handlePendingInvite()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
pageShow() {
|
||||||
|
// 首次启动跳转引导页由 App.vue onLaunch 统一处理,
|
||||||
|
// 这里不再重复 reLaunch,避免两个跳转并发导致 reLaunch:fail timeout
|
||||||
|
const isFirst = uni.getStorageSync('is_first_launch')
|
||||||
|
if (isFirst === 'true') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 游客可直接浏览首页:不发起鉴权请求,展示空数据;
|
||||||
|
// 仅在用户主动点击记录等功能时才引导登录(微信审核要求:先浏览后登录)
|
||||||
|
this.isGuest = !isLoggedIn()
|
||||||
|
if (this.isGuest) {
|
||||||
|
this.initGuestView()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.loadData()
|
||||||
|
},
|
||||||
|
getShareAppMessage() {
|
||||||
|
return {
|
||||||
|
title: '碰盏日记 - 让每一杯酒都有迹可循',
|
||||||
|
path: '/pages/main/main?tab=0'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getShareTimeline() {
|
||||||
|
return {
|
||||||
|
title: '碰盏日记 - 让每一杯酒都有迹可循',
|
||||||
|
query: 'tab=0'
|
||||||
|
}
|
||||||
|
},
|
||||||
// 游客浏览视图:问候语与零数据,页面结构可完整浏览,不发起任何鉴权请求
|
// 游客浏览视图:问候语与零数据,页面结构可完整浏览,不发起任何鉴权请求
|
||||||
initGuestView() {
|
initGuestView() {
|
||||||
this.greeting = getGreeting()
|
this.greeting = getGreeting()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :class="themeClass" class="page-container login-page">
|
<view class="page-container login-page">
|
||||||
<!-- 顶部品牌区 -->
|
<!-- 顶部品牌区 -->
|
||||||
<view class="brand-area">
|
<view class="brand-area">
|
||||||
<view class="brand-glow"></view>
|
<view class="brand-glow"></view>
|
||||||
@@ -94,13 +94,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import themeMixin from '../../common/theme-mixin'
|
|
||||||
import client, { saveAuthTokens, UploadImage, UpdateUserAvatar } from '../../common/api'
|
import client, { saveAuthTokens, UploadImage, UpdateUserAvatar } from '../../common/api'
|
||||||
import { handlePendingInvite } from '../../common/invite'
|
import { handlePendingInvite } from '../../common/invite'
|
||||||
import wsManager from '../../common/websocket'
|
import wsManager from '../../common/websocket'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [themeMixin],
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
showNotice: true,
|
showNotice: true,
|
||||||
@@ -114,7 +112,7 @@ export default {
|
|||||||
onShareAppMessage() {
|
onShareAppMessage() {
|
||||||
return {
|
return {
|
||||||
title: '碰盏日记 - 让每一杯酒都有迹可循',
|
title: '碰盏日记 - 让每一杯酒都有迹可循',
|
||||||
path: '/pages/index/index'
|
path: '/pages/main/main?tab=0'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onShareTimeline() {
|
onShareTimeline() {
|
||||||
@@ -132,7 +130,7 @@ export default {
|
|||||||
enterGuest() {
|
enterGuest() {
|
||||||
uni.setStorageSync('is_first_launch', 'false')
|
uni.setStorageSync('is_first_launch', 'false')
|
||||||
uni.setStorageSync('is_guest', 'true')
|
uni.setStorageSync('is_guest', 'true')
|
||||||
uni.switchTab({ url: '/pages/index/index' })
|
uni.reLaunch({ url: '/pages/main/main?tab=0' })
|
||||||
},
|
},
|
||||||
|
|
||||||
// ===== 微信新规范:头像选择 =====
|
// ===== 微信新规范:头像选择 =====
|
||||||
@@ -282,7 +280,7 @@ export default {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn('补发邀请失败,不影响登录:', e)
|
console.warn('补发邀请失败,不影响登录:', e)
|
||||||
}
|
}
|
||||||
uni.switchTab({ url: '/pages/index/index' })
|
uni.reLaunch({ url: '/pages/main/main?tab=0' })
|
||||||
},
|
},
|
||||||
|
|
||||||
// ===== 协议查看:跳转协议页(user=用户协议 / privacy=隐私政策)=====
|
// ===== 协议查看:跳转协议页(user=用户协议 / privacy=隐私政策)=====
|
||||||
|
|||||||
@@ -0,0 +1,147 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 单页容器:三个 tab 页作为子组件常驻挂载,用 v-show 切换(只改 display),
|
||||||
|
不再走原生 tabBar 的 switchTab 页面过渡,从根源消除 iOS WKWebView 重新栅格化导致的闪白。
|
||||||
|
页面级生命周期(onLoad/onShow/onHide/onUnload/分享)由本容器统一接收,
|
||||||
|
再通过 ref 分发给当前活跃的子组件。 -->
|
||||||
|
<view class="main-page" :style="rootStyle">
|
||||||
|
<HomeTab v-show="current === 0" ref="home" @switch-tab="onTabChange" />
|
||||||
|
<CircleTab v-show="current === 1" ref="circle" @switch-tab="onTabChange" />
|
||||||
|
<ProfileTab v-show="current === 2" ref="profile" @switch-tab="onTabChange" />
|
||||||
|
|
||||||
|
<!-- 自绘底部导航:切换只改 current,不触发任何原生页面过渡 -->
|
||||||
|
<TabBar :current="current" @change="onTabChange" />
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import HomeTab from '../index/index.vue'
|
||||||
|
import CircleTab from '../circle/circle.vue'
|
||||||
|
import ProfileTab from '../profile/profile.vue'
|
||||||
|
import TabBar from '../../components/TabBar.vue'
|
||||||
|
|
||||||
|
// 三个子组件的 ref 名,与 tab 索引一一对应
|
||||||
|
const CHILD_REFS = ['home', 'circle', 'profile']
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: { HomeTab, CircleTab, ProfileTab, TabBar },
|
||||||
|
data() {
|
||||||
|
// 底部安全区(iPhone 全面屏手势条)
|
||||||
|
let safeBottom = 0
|
||||||
|
try {
|
||||||
|
const sys = uni.getSystemInfoSync()
|
||||||
|
if (sys.safeAreaInsets && typeof sys.safeAreaInsets.bottom === 'number') {
|
||||||
|
safeBottom = sys.safeAreaInsets.bottom
|
||||||
|
} else if (sys.safeArea && sys.windowHeight) {
|
||||||
|
safeBottom = Math.max(0, sys.windowHeight - sys.safeArea.bottom)
|
||||||
|
}
|
||||||
|
} catch (e) { safeBottom = 0 }
|
||||||
|
return {
|
||||||
|
current: 0,
|
||||||
|
// 自绘 tabBar 总高度(内容 100rpx + 安全区),经 CSS 变量下发给子组件计算底部留白/可视高度
|
||||||
|
tabBarHeight: `calc(100rpx + ${safeBottom}px)`,
|
||||||
|
// 首屏是否就绪(onReady 后置 true),用于区分首屏初始化与后续 onShow 刷新
|
||||||
|
inited: false,
|
||||||
|
// onLoad 参数,首屏就绪后转发给初始 tab(如 index 处理 inviteCode)
|
||||||
|
loadOptions: {},
|
||||||
|
// 各 tab 的页面级滚动位置记忆(home=0/circle=1/profile=2)。
|
||||||
|
// index/profile 共享 main 页面同一条滚动条,切换时须按 tab 记忆并恢复,否则位置互相串扰;
|
||||||
|
// circle 为内部 scroll-view 滚动,页面级滚动恒 0,其 scroll-view 位置由 v-show 常驻自动保留。
|
||||||
|
savedScroll: [0, 0, 0],
|
||||||
|
// tab 切换进行中标志:期间暂停滚动记录,避免 v-show 改变文档高度引发的 clamp 污染目标 tab 记忆
|
||||||
|
scrollSwitching: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
rootStyle() {
|
||||||
|
return { '--tabbar-h': this.tabBarHeight }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onLoad(options) {
|
||||||
|
this.loadOptions = options || {}
|
||||||
|
// 支持外部通过 ?tab=x 指定初始 tab(分享落地 / reLaunch 跳转)
|
||||||
|
const t = parseInt(this.loadOptions.tab, 10)
|
||||||
|
if (t >= 0 && t <= 2) this.current = t
|
||||||
|
},
|
||||||
|
onReady() {
|
||||||
|
// 子组件已挂载,初始化当前活跃 tab(首次加载数据 + 处理邀请码)
|
||||||
|
this.inited = true
|
||||||
|
const child = this.activeChild()
|
||||||
|
if (!child) return
|
||||||
|
if (child.pageLoad) child.pageLoad(this.loadOptions)
|
||||||
|
if (child.pageShow) child.pageShow()
|
||||||
|
},
|
||||||
|
onShow() {
|
||||||
|
// 首次 onShow 早于 onReady(子组件尚未挂载),跳过;
|
||||||
|
// 之后从其它页面返回时,刷新当前活跃 tab
|
||||||
|
if (!this.inited) return
|
||||||
|
const child = this.activeChild()
|
||||||
|
if (child && child.pageShow) child.pageShow()
|
||||||
|
},
|
||||||
|
onHide() {
|
||||||
|
const child = this.activeChild()
|
||||||
|
if (child && child.pageHide) child.pageHide()
|
||||||
|
},
|
||||||
|
onPageScroll(e) {
|
||||||
|
// 实时记录当前活跃 tab 的页面滚动位置,供切回时恢复;
|
||||||
|
// 切换进行中(scrollSwitching)忽略,避免文档高度变化引发的 clamp 污染记忆
|
||||||
|
if (this.scrollSwitching) return
|
||||||
|
this.savedScroll[this.current] = e.scrollTop
|
||||||
|
},
|
||||||
|
onUnload() {
|
||||||
|
// 页面卸载:通知所有子组件解绑(circle 需解绑 WebSocket 事件、清理定时器)
|
||||||
|
CHILD_REFS.forEach(name => {
|
||||||
|
const c = this.$refs[name]
|
||||||
|
if (c && c.pageUnload) c.pageUnload()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
onShareAppMessage() {
|
||||||
|
const child = this.activeChild()
|
||||||
|
if (child && child.getShareAppMessage) {
|
||||||
|
const res = child.getShareAppMessage()
|
||||||
|
if (res) return res
|
||||||
|
}
|
||||||
|
return { title: '碰盏日记 - 让每一杯酒都有迹可循', path: '/pages/main/main?tab=0' }
|
||||||
|
},
|
||||||
|
onShareTimeline() {
|
||||||
|
const child = this.activeChild()
|
||||||
|
if (child && child.getShareTimeline) {
|
||||||
|
const res = child.getShareTimeline()
|
||||||
|
if (res) return res
|
||||||
|
}
|
||||||
|
return { title: '碰盏日记 - 让每一杯酒都有迹可循' }
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 当前活跃 tab 对应的子组件实例
|
||||||
|
activeChild() {
|
||||||
|
return this.$refs[CHILD_REFS[this.current]]
|
||||||
|
},
|
||||||
|
// tab 切换:来自自绘 TabBar 的 @change 或子组件的 @switch-tab
|
||||||
|
onTabChange(i) {
|
||||||
|
if (i === this.current) return
|
||||||
|
const prev = this.activeChild()
|
||||||
|
// 进入切换态:暂停滚动记录,防止 v-show 改变文档高度引发的 clamp 污染记忆
|
||||||
|
this.scrollSwitching = true
|
||||||
|
this.current = i
|
||||||
|
// 旧 tab 转后台
|
||||||
|
if (prev && prev.pageHide) prev.pageHide()
|
||||||
|
// 新 tab 转前台(等 v-show 生效后再触发)
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.current !== i) return
|
||||||
|
// 恢复目标 tab 的页面滚动位置(circle 恒 0;index/profile 为各自记忆值)
|
||||||
|
uni.pageScrollTo({ scrollTop: this.savedScroll[i] || 0, duration: 0 })
|
||||||
|
const next = this.activeChild()
|
||||||
|
if (next && next.pageShow) next.pageShow()
|
||||||
|
// 待 pageScrollTo 引发的滚动事件平息后再恢复记录
|
||||||
|
setTimeout(() => { this.scrollSwitching = false }, 80)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.main-page {
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: $bg-base;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :class="themeClass" class="page-container onboarding">
|
<view class="page-container onboarding">
|
||||||
<!-- 跳过按钮 -->
|
<!-- 跳过按钮 -->
|
||||||
<view class="skip-bar">
|
<view class="skip-bar">
|
||||||
<text class="btn-text" @click="goLogin">跳过</text>
|
<text class="btn-text" @click="goLogin">跳过</text>
|
||||||
@@ -63,10 +63,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import themeMixin from '../../common/theme-mixin'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [themeMixin],
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
currentSlide: 0,
|
currentSlide: 0,
|
||||||
@@ -101,7 +98,7 @@ export default {
|
|||||||
onShareAppMessage() {
|
onShareAppMessage() {
|
||||||
return {
|
return {
|
||||||
title: '碰盏日记 - 让每一杯酒都有迹可循',
|
title: '碰盏日记 - 让每一杯酒都有迹可循',
|
||||||
path: '/pages/index/index'
|
path: '/pages/main/main?tab=0'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onShareTimeline() {
|
onShareTimeline() {
|
||||||
@@ -121,7 +118,7 @@ export default {
|
|||||||
},
|
},
|
||||||
goLogin() {
|
goLogin() {
|
||||||
uni.setStorageSync('is_first_launch', 'false')
|
uni.setStorageSync('is_first_launch', 'false')
|
||||||
uni.reLaunch({ url: '/pages/index/index' })
|
uni.reLaunch({ url: '/pages/main/main' })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-23
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :class="themeClass" class="page-container profile-page">
|
<view class="page-container profile-page">
|
||||||
<!-- 沉浸式头部 -->
|
<!-- 沉浸式头部 -->
|
||||||
<view class="hero-header" :style="{ paddingTop: headerPaddingTop }">
|
<view class="hero-header" :style="{ paddingTop: headerPaddingTop }">
|
||||||
<view class="hero-bg">
|
<view class="hero-bg">
|
||||||
@@ -176,11 +176,11 @@ import AchievementBadge from '../../components/AchievementBadge.vue'
|
|||||||
import client, { clearAuth, GetAchievements, isLoggedIn, requireLogin } from '../../common/api'
|
import client, { clearAuth, GetAchievements, isLoggedIn, requireLogin } from '../../common/api'
|
||||||
import { checkAchievements, getCatIcon, isIconPath, calcLocalStreak, isValidAvatar } from '../../common/utils'
|
import { checkAchievements, getCatIcon, isIconPath, calcLocalStreak, isValidAvatar } from '../../common/utils'
|
||||||
import { ACHIEVEMENTS, DRINK_CATEGORIES } from '../../common/constants'
|
import { ACHIEVEMENTS, DRINK_CATEGORIES } from '../../common/constants'
|
||||||
import themeMixin from '../../common/theme-mixin'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [themeMixin],
|
|
||||||
components: { AchievementBadge },
|
components: { AchievementBadge },
|
||||||
|
// Vue3 组件事件必须显式声明
|
||||||
|
emits: ['switch-tab'],
|
||||||
data() {
|
data() {
|
||||||
// 获取胶囊按钮位置,动态计算分享按钮偏移和头部内边距
|
// 获取胶囊按钮位置,动态计算分享按钮偏移和头部内边距
|
||||||
const sysInfo = uni.getSystemInfoSync()
|
const sysInfo = uni.getSystemInfoSync()
|
||||||
@@ -252,25 +252,26 @@ export default {
|
|||||||
return '百天老友,酒中见真章'
|
return '百天老友,酒中见真章'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onShow() {
|
|
||||||
this.checkLoginState()
|
|
||||||
this.loadData()
|
|
||||||
},
|
|
||||||
onShareAppMessage() {
|
|
||||||
const name = this.user.nickname || '我'
|
|
||||||
return {
|
|
||||||
title: `${name}的饮酒名片 - 碰盏日记`,
|
|
||||||
path: `/pages/share-profile/share-profile?${this.buildShareQuery()}`
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onShareTimeline() {
|
|
||||||
const name = this.user.nickname || '我'
|
|
||||||
return {
|
|
||||||
title: `${name}的饮酒名片 - 碰盏日记`,
|
|
||||||
query: this.buildShareQuery()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
|
// === 子组件生命周期(由 main.vue 容器通过 ref 调用)===
|
||||||
|
pageShow() {
|
||||||
|
this.checkLoginState()
|
||||||
|
this.loadData()
|
||||||
|
},
|
||||||
|
getShareAppMessage() {
|
||||||
|
const name = this.user.nickname || '我'
|
||||||
|
return {
|
||||||
|
title: `${name}的饮酒名片 - 碰盏日记`,
|
||||||
|
path: `/pages/share-profile/share-profile?${this.buildShareQuery()}`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getShareTimeline() {
|
||||||
|
const name = this.user.nickname || '我'
|
||||||
|
return {
|
||||||
|
title: `${name}的饮酒名片 - 碰盏日记`,
|
||||||
|
query: this.buildShareQuery()
|
||||||
|
}
|
||||||
|
},
|
||||||
isValidAvatar,
|
isValidAvatar,
|
||||||
isIconPath,
|
isIconPath,
|
||||||
// 构建分享名片的 query 参数(携带公开档案数据)
|
// 构建分享名片的 query 参数(携带公开档案数据)
|
||||||
@@ -382,13 +383,13 @@ export default {
|
|||||||
return ACHIEVEMENTS[index % ACHIEVEMENTS.length].icon
|
return ACHIEVEMENTS[index % ACHIEVEMENTS.length].icon
|
||||||
},
|
},
|
||||||
goCircle() {
|
goCircle() {
|
||||||
uni.switchTab({ url: '/pages/circle/circle' })
|
this.$emit('switch-tab', 1)
|
||||||
},
|
},
|
||||||
goGames() {
|
goGames() {
|
||||||
uni.navigateTo({ url: '/pages/games/games' })
|
uni.navigateTo({ url: '/pages/games/games' })
|
||||||
},
|
},
|
||||||
goHome() {
|
goHome() {
|
||||||
uni.switchTab({ url: '/pages/index/index' })
|
this.$emit('switch-tab', 0)
|
||||||
},
|
},
|
||||||
goRecord() {
|
goRecord() {
|
||||||
if (!requireLogin()) return
|
if (!requireLogin()) return
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :class="themeClass" class="page-container record-page safe-bottom">
|
<view class="page-container record-page safe-bottom">
|
||||||
<!-- 顶部进度 -->
|
<!-- 顶部进度 -->
|
||||||
<view class="step-header" :style="{ paddingTop: (statusBarHeight + 12) + 'px' }">
|
<view class="step-header" :style="{ paddingTop: (statusBarHeight + 12) + 'px' }">
|
||||||
<view class="step-back" @click="handleBack">
|
<view class="step-back" @click="handleBack">
|
||||||
@@ -347,10 +347,8 @@ import {
|
|||||||
} from '../../common/constants'
|
} from '../../common/constants'
|
||||||
import { calcStandardCups, unitToMl, formatDate, getCatIcon, isIconPath } from '../../common/utils'
|
import { calcStandardCups, unitToMl, formatDate, getCatIcon, isIconPath } from '../../common/utils'
|
||||||
import client, { isLoggedIn } from '../../common/api'
|
import client, { isLoggedIn } from '../../common/api'
|
||||||
import themeMixin from '../../common/theme-mixin'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [themeMixin],
|
|
||||||
data() {
|
data() {
|
||||||
const sysInfo = uni.getSystemInfoSync()
|
const sysInfo = uni.getSystemInfoSync()
|
||||||
return {
|
return {
|
||||||
@@ -458,7 +456,7 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
uni.navigateBack({
|
uni.navigateBack({
|
||||||
fail: () => {
|
fail: () => {
|
||||||
uni.switchTab({ url: '/pages/index/index' })
|
uni.reLaunch({ url: '/pages/main/main?tab=0' })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -469,7 +467,7 @@ export default {
|
|||||||
onShareAppMessage() {
|
onShareAppMessage() {
|
||||||
return {
|
return {
|
||||||
title: '碰盏日记 - 记录每一杯酒',
|
title: '碰盏日记 - 记录每一杯酒',
|
||||||
path: '/pages/index/index'
|
path: '/pages/main/main?tab=0'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onShareTimeline() {
|
onShareTimeline() {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :class="themeClass" class="page-container share-page">
|
<view class="page-container share-page">
|
||||||
<!-- 氛围背景 -->
|
<!-- 氛围背景 -->
|
||||||
<view class="ambient">
|
<view class="ambient">
|
||||||
<view class="glow glow-1"></view>
|
<view class="glow glow-1"></view>
|
||||||
@@ -80,11 +80,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import themeMixin from '../../common/theme-mixin'
|
|
||||||
import { DRINK_CATEGORIES } from '../../common/constants'
|
import { DRINK_CATEGORIES } from '../../common/constants'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [themeMixin],
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
info: {
|
info: {
|
||||||
@@ -178,15 +176,12 @@ export default {
|
|||||||
enterApp() {
|
enterApp() {
|
||||||
const isLoggedIn = uni.getStorageSync('is_logged_in')
|
const isLoggedIn = uni.getStorageSync('is_logged_in')
|
||||||
if (isLoggedIn === 'true') {
|
if (isLoggedIn === 'true') {
|
||||||
uni.switchTab({ url: '/pages/index/index' })
|
uni.reLaunch({ url: '/pages/main/main?tab=0' })
|
||||||
} else {
|
} else {
|
||||||
// 未登录以游客身份进入首页浏览,不强制跳登录页
|
// 未登录以游客身份进入首页浏览,不强制跳登录页
|
||||||
uni.setStorageSync('is_first_launch', 'false')
|
uni.setStorageSync('is_first_launch', 'false')
|
||||||
uni.setStorageSync('is_guest', 'true')
|
uni.setStorageSync('is_guest', 'true')
|
||||||
uni.switchTab({
|
uni.reLaunch({ url: '/pages/main/main?tab=0' })
|
||||||
url: '/pages/index/index',
|
|
||||||
fail: () => uni.reLaunch({ url: '/pages/index/index' })
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
/* ==========================================
|
/* ==========================================
|
||||||
* 碰盏日记 - 设计令牌 (Design Tokens)
|
* 碰盏日记 - 设计令牌 (Design Tokens)
|
||||||
* 设计概念: 琥珀夜光 Amber Night / 暖白琥珀 Warm Day
|
* 设计概念: 琥珀夜光 Amber Night
|
||||||
* 全局统一深色主题(琥珀夜光)
|
* 全局统一深色主题(已通过 page 选择器全局生效)
|
||||||
* ========================================== */
|
* ========================================== */
|
||||||
|
|
||||||
/* --- 夜间主题(默认)--- */
|
page {
|
||||||
page, .theme-dark {
|
|
||||||
--bg-base: #0B0B14;
|
--bg-base: #0B0B14;
|
||||||
--bg-card: #1A1A28;
|
--bg-card: #1A1A28;
|
||||||
--bg-card-alt: #222236;
|
--bg-card-alt: #222236;
|
||||||
|
|||||||
Reference in New Issue
Block a user