feat(home): 实现游客模式与登录流程优化
- 添加游客模式,展示公共内容无需强制登录 - 实现游客模块展示打卡、计划、关于我们等功能介绍 - 添加产品介绍页面显示学习成长工具详情 - 优化登录流程,添加用户协议和隐私政策同意选项 - 更新角色标签将老师改为管理员,学员改为成员 - 添加注销账号功能替代退出登录 - 实现webview页面域名白名单安全验证 - 添加隐私政策和用户协议页面 - 优化页面跳转逻辑和错误提示信息 - 统一项目名称从明缘进阶场改为明缘云道场
This commit is contained in:
@@ -16,6 +16,7 @@ Page({
|
||||
displayName: '',
|
||||
encouragement: '',
|
||||
modules: [],
|
||||
introData: null,
|
||||
loading: true,
|
||||
error: '',
|
||||
skeletonItems: [0, 1, 2, 3, 4, 5, 6, 7, 8]
|
||||
@@ -27,12 +28,32 @@ Page({
|
||||
if (!silent) {
|
||||
this.setData({ loading: true, error: '' });
|
||||
}
|
||||
const token = auth.getToken();
|
||||
if (!token) {
|
||||
// 游客模式:展示公开内容,不强制登录
|
||||
this.setData({
|
||||
loading: false,
|
||||
error: '',
|
||||
greeting: '欢迎来到明缘云道场',
|
||||
displayName: '游客',
|
||||
encouragement: '登录后即可打卡、提交计划',
|
||||
modules: this.getGuestModules(),
|
||||
introData: this.getIntroData()
|
||||
});
|
||||
return Promise.resolve();
|
||||
}
|
||||
return auth.ensureLogin()
|
||||
.then((token) => {
|
||||
if (!token) {
|
||||
// 新用户未绑定手机号,引导去「我的」完成绑定,避免无 token 请求受保护接口导致 401
|
||||
this.setData({ loading: false, error: '请先完成微信绑定后再进入' });
|
||||
setTimeout(() => wx.switchTab({ url: '/pages/profile/profile' }), 500);
|
||||
this.setData({
|
||||
loading: false,
|
||||
error: '',
|
||||
greeting: '欢迎来到明缘云道场',
|
||||
displayName: '游客',
|
||||
encouragement: '登录后即可打卡、提交计划',
|
||||
modules: this.getGuestModules(),
|
||||
introData: this.getIntroData()
|
||||
});
|
||||
return;
|
||||
}
|
||||
return api.request({ url: '/api/v1/pages/home' });
|
||||
@@ -45,7 +66,8 @@ Page({
|
||||
greeting: res.greeting || '',
|
||||
displayName: res.display_name || '',
|
||||
encouragement: res.encouragement || '',
|
||||
modules: (res.modules || []).filter((m) => m.visible)
|
||||
modules: (res.modules || []).filter((m) => m.visible),
|
||||
introData: null
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
@@ -53,6 +75,42 @@ Page({
|
||||
});
|
||||
},
|
||||
|
||||
getGuestModules() {
|
||||
return [
|
||||
{ id: 'checkin', icon: '📋', label: '打卡介绍', desc: '每日打卡记录', visible: true, url: '', guest: true },
|
||||
{ id: 'plan', icon: '📝', label: '计划介绍', desc: '周/月/年计划', visible: true, url: '', guest: true },
|
||||
{ id: 'about', icon: 'ℹ️', label: '关于我们', desc: '了解明缘云道场', visible: true, url: '', guest: true }
|
||||
];
|
||||
},
|
||||
|
||||
getIntroData() {
|
||||
return {
|
||||
title: '产品介绍',
|
||||
sections: [
|
||||
{
|
||||
icon: '📚',
|
||||
heading: '学习成长工具',
|
||||
text: '明缘云道场是一款专注于个人成长的效率工具,通过每周打卡与计划管理,帮助你养成良好的学习习惯,实现持续进步。好好学习,天天向上。'
|
||||
},
|
||||
{
|
||||
icon: '✅',
|
||||
heading: '周打卡',
|
||||
text: '每周打卡,支持多种状态记录(正常、迟到、请假、早退、不参加讨论等)。查看小组打卡情况,与同学们互相监督、共同进步。'
|
||||
},
|
||||
{
|
||||
icon: '📝',
|
||||
heading: '计划管理',
|
||||
text: '提供周计划、月计划、年计划三级管理,支持文字与图片上传。清晰追踪每个周期的目标完成情况,让成长有迹可循。'
|
||||
},
|
||||
{
|
||||
icon: '👥',
|
||||
heading: '小组共学',
|
||||
text: '加入学习小组,查看组员的打卡与计划完成情况。在集体的氛围中保持学习动力,与志同道合的伙伴一起成长。'
|
||||
}
|
||||
]
|
||||
};
|
||||
},
|
||||
|
||||
onPullDownRefresh() {
|
||||
this.loadHome(true).then(() => {
|
||||
wx.stopPullDownRefresh();
|
||||
@@ -63,12 +121,37 @@ Page({
|
||||
this.loadHome();
|
||||
},
|
||||
|
||||
goLogin() {
|
||||
wx.switchTab({ url: '/pages/profile/profile' });
|
||||
},
|
||||
|
||||
onModuleTap(e) {
|
||||
const url = e.currentTarget.dataset.url;
|
||||
if (!url) return;
|
||||
const token = auth.getToken();
|
||||
const sep = url.indexOf('?') >= 0 ? '&' : '?';
|
||||
const target = url + sep + 'token=' + encodeURIComponent(token);
|
||||
wx.navigateTo({ url: '/pages/webview/webview?url=' + encodeURIComponent(target) });
|
||||
// 游客模式:引导登录
|
||||
if (!token) {
|
||||
wx.showModal({
|
||||
title: '登录提示',
|
||||
content: '登录后使用此功能,是否前往登录?',
|
||||
confirmText: '去登录',
|
||||
confirmColor: '#C67B30',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
wx.switchTab({ url: '/pages/profile/profile' });
|
||||
}
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (!url) return;
|
||||
|
||||
// 通过 webview redirect 接口:后端验证 token 后设置 HttpOnly cookie,再 302 到目标页
|
||||
// H5 页面内的同域请求会自动携带 cookie,H5 端零改动
|
||||
const redirectUrl = api.BASE_URL + '/api/v1/webview/redirect'
|
||||
+ '?token=' + encodeURIComponent(token)
|
||||
+ '&target=' + encodeURIComponent(url);
|
||||
wx.navigateTo({ url: '/pages/webview/webview?url=' + encodeURIComponent(redirectUrl) });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
<view class="hero-chip" wx:if="{{greeting}}">{{greeting}}</view>
|
||||
<view class="hero-name">{{displayName || '欢迎回来'}}</view>
|
||||
<view class="hero-enc" wx:if="{{encouragement}}">{{encouragement}}</view>
|
||||
<view class="hero-login-tip" wx:if="{{!displayName || displayName === '游客'}}" hover-class="btn-hover" bindtap="goLogin">
|
||||
登录账号解锁完整功能 ›
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="error-bar" wx:if="{{error}}">
|
||||
@@ -37,6 +40,18 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 游客模式:明缘介绍 -->
|
||||
<view class="intro-section" wx:if="{{introData && introData.sections}}">
|
||||
<view class="intro-title">{{introData.title}}</view>
|
||||
<view class="intro-card" wx:for="{{introData.sections}}" wx:key="heading">
|
||||
<view class="intro-icon">{{item.icon}}</view>
|
||||
<view class="intro-body">
|
||||
<view class="intro-heading">{{item.heading}}</view>
|
||||
<view class="intro-text">{{item.text}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="empty" wx:if="{{modules.length === 0 && !error}}">暂无功能入口</view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -153,4 +153,56 @@
|
||||
@keyframes shimmer {
|
||||
0% { background-position: 200% 0; }
|
||||
100% { background-position: -200% 0; }
|
||||
}
|
||||
.hero-login-tip {
|
||||
margin-top: 24rpx;
|
||||
display: inline-block;
|
||||
padding: 12rpx 28rpx;
|
||||
background: rgba(198, 123, 48, 0.25);
|
||||
border: 1rpx solid rgba(227, 179, 124, 0.4);
|
||||
border-radius: 999rpx;
|
||||
color: #E3B37C;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
/* ---- intro section ---- */
|
||||
.intro-section {
|
||||
margin-top: 40rpx;
|
||||
}
|
||||
.intro-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
color: #2C1810;
|
||||
margin-bottom: 20rpx;
|
||||
padding-left: 4rpx;
|
||||
}
|
||||
.intro-card {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
background: #fff;
|
||||
border-radius: 16rpx;
|
||||
padding: 28rpx 24rpx;
|
||||
margin-bottom: 16rpx;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.03);
|
||||
}
|
||||
.intro-icon {
|
||||
font-size: 40rpx;
|
||||
margin-right: 20rpx;
|
||||
flex-shrink: 0;
|
||||
line-height: 1;
|
||||
padding-top: 2rpx;
|
||||
}
|
||||
.intro-body {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
.intro-heading {
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
color: #C67B30;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
.intro-text {
|
||||
font-size: 25rpx;
|
||||
color: #5A4A3A;
|
||||
line-height: 1.8;
|
||||
}
|
||||
Reference in New Issue
Block a user