feat: add guest mode and optimize login experience

针对微信审核要求新增游客浏览模式,用户可无需登录直接浏览应用内容,仅在使用发布、点赞、记录等需要身份的功能时才弹窗引导登录。具体修改包括:
1. 新增游客态判断工具函数与登录守卫逻辑
2. 为登录页添加游客直接进入入口
3. 为首页、酒友圈、个人页、动态页、记录页添加游客适配逻辑
4. 优化登录态失效处理逻辑,不再强制跳转登录页
5. 调整部分页面的返回逻辑适配分享直接进入场景
6. 为各页面添加游客引导UI与交互
This commit is contained in:
cg
2026-09-10 21:43:46 +08:00
parent 26b7111af0
commit dd3c670021
9 changed files with 307 additions and 46 deletions
+83 -1
View File
@@ -8,6 +8,15 @@
</view>
</view>
<!-- 游客登录引导条(非阻断,可继续浏览;登录由用户自行选择) -->
<view v-if="isGuest" class="guest-banner" @click="goLogin">
<view class="guest-banner-info">
<text class="guest-banner-title">登录后开启完整记录</text>
<text class="guest-banner-desc">云端同步 · 成就徽章 · 酒友互动</text>
</view>
<text class="guest-banner-btn">去登录</text>
</view>
<!-- 核心CTA - 首页最醒目位置 -->
<view class="hero-cta" @click="goRecord">
<view class="hero-cta-bg"></view>
@@ -139,7 +148,7 @@
<script>
import DrinkCalendar from '../../components/DrinkCalendar.vue'
import client from '../../common/api'
import client, { isLoggedIn, requireLogin } from '../../common/api'
import { GetCalendarReq, DeleteRecordReq, CreateRecordReq, GetRecordDetailReq } from 'HaveADrink'
import { getGreeting, formatDate, getWeekStart, getCatIcon, isIconPath, calcLocalStreak } from '../../common/utils'
import { FEELINGS, DRINK_CATEGORIES, DRINK_UNITS } from '../../common/constants'
@@ -196,6 +205,13 @@ export default {
if (isFirst === 'true') {
return
}
// 游客可直接浏览首页:不发起鉴权请求,展示空数据;
// 仅在用户主动点击记录等功能时才引导登录(微信审核要求:先浏览后登录)
this.isGuest = !isLoggedIn()
if (this.isGuest) {
this.initGuestView()
return
}
this.loadData()
},
onShareAppMessage() {
@@ -211,6 +227,26 @@ export default {
}
},
methods: {
// 游客浏览视图:问候语与零数据,页面结构可完整浏览,不发起任何鉴权请求
initGuestView() {
this.greeting = getGreeting()
this.userName = '酒友'
this.records = []
this.stats = {
weekDrinkCount: 0,
weekCups: 0,
monthDrinkCount: 0,
monthCups: 0,
streak: 0,
streakType: 'drank',
drankStreak: 0,
abstainStreak: 0
}
},
// 游客主动点击"去登录"
goLogin() {
uni.navigateTo({ url: '/pages/login/login' })
},
async loadData() {
this.greeting = getGreeting()
// 并行加载用户信息、统计概览、记录列表
@@ -436,14 +472,17 @@ export default {
})
},
goRecord() {
if (!requireLogin()) return
uni.navigateTo({ url: '/pages/record/record' })
},
goRecordToday() {
if (!requireLogin()) return
this.showDayDetail = false
uni.navigateTo({ url: '/pages/record/record' })
},
// 标记为未饮酒(直接创建 abstain 记录)
async markAbstain() {
if (!requireLogin()) return
const recordData = {
date: this.selectedDate,
mode: 'abstain',
@@ -497,6 +536,49 @@ export default {
margin-top: 4rpx;
}
/* 游客登录引导条(非阻断) */
.guest-banner {
display: flex;
align-items: center;
justify-content: space-between;
padding: $sp-md $sp-lg;
margin-bottom: $sp-md;
border-radius: $radius-lg;
background: rgba(232, 168, 56, 0.08);
border: 2rpx solid rgba(232, 168, 56, 0.25);
&:active {
background: rgba(232, 168, 56, 0.14);
}
}
.guest-banner-info {
display: flex;
flex-direction: column;
gap: 4rpx;
}
.guest-banner-title {
font-size: $fs-sm;
font-weight: $fw-bold;
color: $amber;
}
.guest-banner-desc {
font-size: $fs-xs;
color: $text-tertiary;
}
.guest-banner-btn {
font-size: $fs-sm;
font-weight: $fw-bold;
color: $text-on-amber;
background: linear-gradient(135deg, $amber-light, $amber-deep);
padding: $sp-xs $sp-lg;
border-radius: $radius-full;
flex-shrink: 0;
}
.calendar-section {
margin-bottom: $sp-md;
padding: $sp-md;