feat(home): 实现游客模式与登录流程优化
- 添加游客模式,展示公共内容无需强制登录 - 实现游客模块展示打卡、计划、关于我们等功能介绍 - 添加产品介绍页面显示学习成长工具详情 - 优化登录流程,添加用户协议和隐私政策同意选项 - 更新角色标签将老师改为管理员,学员改为成员 - 添加注销账号功能替代退出登录 - 实现webview页面域名白名单安全验证 - 添加隐私政策和用户协议页面 - 优化页面跳转逻辑和错误提示信息 - 统一项目名称从明缘进阶场改为明缘云道场
This commit is contained in:
@@ -2,15 +2,15 @@ const api = require('../../utils/api');
|
||||
const auth = require('../../utils/auth');
|
||||
|
||||
const ROLE_LABELS = {
|
||||
student: '学员',
|
||||
student: '成员',
|
||||
member: '成员',
|
||||
teacher: '老师',
|
||||
teacher: '管理员',
|
||||
leader: '组长',
|
||||
'group_leader': '组长',
|
||||
admin: '管理员'
|
||||
};
|
||||
const LOGIN_TYPE_LABELS = {
|
||||
wechat: '微信',
|
||||
wechat: '微信授权',
|
||||
phone: '手机号',
|
||||
admin: '管理员'
|
||||
};
|
||||
@@ -27,11 +27,15 @@ Page({
|
||||
roleLabel: '',
|
||||
loginTypeLabel: '',
|
||||
classGroups: [],
|
||||
avatarUploading: false
|
||||
avatarUploading: false,
|
||||
privacyAgreed: false
|
||||
},
|
||||
|
||||
onShow() {
|
||||
this.setData({ phoneError: '' });
|
||||
this.setData({
|
||||
phoneError: '',
|
||||
privacyAgreed: !!wx.getStorageSync('privacy_agreed')
|
||||
});
|
||||
this.loadPage();
|
||||
},
|
||||
|
||||
@@ -114,16 +118,17 @@ Page({
|
||||
showPhoneLogin() {
|
||||
this.setData({
|
||||
view: 'phoneLogin',
|
||||
phoneLoading: false
|
||||
phoneLoading: false,
|
||||
privacyAgreed: !!wx.getStorageSync('privacy_agreed')
|
||||
});
|
||||
},
|
||||
|
||||
roleLabel(role) {
|
||||
return ROLE_LABELS[role] || role || '学员';
|
||||
return ROLE_LABELS[role] || role || '成员';
|
||||
},
|
||||
|
||||
loginTypeLabel(type) {
|
||||
return LOGIN_TYPE_LABELS[type] || type || '微信';
|
||||
return LOGIN_TYPE_LABELS[type] || type || '手机号';
|
||||
},
|
||||
|
||||
fullUrl(rel) {
|
||||
@@ -138,7 +143,6 @@ Page({
|
||||
|
||||
onChooseAvatar(e) {
|
||||
const path = e.detail && e.detail.avatarUrl;
|
||||
console.log('[avatar] chooseAvatar ->', path);
|
||||
if (!path) {
|
||||
wx.showToast({ title: '未选择头像', icon: 'none' });
|
||||
return;
|
||||
@@ -150,7 +154,6 @@ Page({
|
||||
name: 'file',
|
||||
header: { Authorization: 'Bearer ' + auth.getToken() },
|
||||
success: (res) => {
|
||||
console.log('[avatar] upload success', res.statusCode, res.data);
|
||||
let data = {};
|
||||
try {
|
||||
data = JSON.parse(res.data);
|
||||
@@ -170,8 +173,6 @@ Page({
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('[avatar] upload fail', err);
|
||||
console.error('[avatar] filePath', path);
|
||||
wx.showToast({ title: '上传失败', icon: 'none' });
|
||||
},
|
||||
complete: () => {
|
||||
@@ -184,6 +185,10 @@ Page({
|
||||
if (this.data.phoneLoading) {
|
||||
return;
|
||||
}
|
||||
if (!this.data.privacyAgreed) {
|
||||
wx.showToast({ title: '请先阅读并同意用户协议和隐私政策', icon: 'none', duration: 2000 });
|
||||
return;
|
||||
}
|
||||
const phoneCode = e.detail && e.detail.code;
|
||||
if (!phoneCode) {
|
||||
const message = '未授权手机号,请点击上方按钮重试';
|
||||
@@ -205,19 +210,48 @@ Page({
|
||||
this.loadPage();
|
||||
},
|
||||
|
||||
logout() {
|
||||
togglePrivacy() {
|
||||
const agreed = !this.data.privacyAgreed;
|
||||
this.setData({ privacyAgreed: agreed });
|
||||
if (agreed) {
|
||||
wx.setStorageSync('privacy_agreed', true);
|
||||
} else {
|
||||
wx.removeStorageSync('privacy_agreed');
|
||||
}
|
||||
},
|
||||
|
||||
openPrivacy(e) {
|
||||
const type = e.currentTarget.dataset.type || 'privacy';
|
||||
wx.navigateTo({ url: '/pages/privacy/privacy?type=' + type });
|
||||
},
|
||||
|
||||
deleteAccount() {
|
||||
wx.showModal({
|
||||
title: '退出登录',
|
||||
content: '确定要退出当前账号吗?',
|
||||
confirmText: '退出',
|
||||
title: '注销账号',
|
||||
content: '确定要注销账号吗?注销后将清除本机登录信息,需要重新登录。',
|
||||
confirmText: '注销',
|
||||
confirmColor: '#c0392b',
|
||||
success: (res) => {
|
||||
if (!res.confirm) {
|
||||
return;
|
||||
}
|
||||
api.request({ url: '/api/v1/auth/logout', method: 'POST' }).catch(() => {});
|
||||
auth.clearToken();
|
||||
wx.reLaunch({ url: '/pages/home/home' });
|
||||
if (!res.confirm) return;
|
||||
wx.showModal({
|
||||
title: '再次确认',
|
||||
content: '注销后本机登录状态将被清除,你可以使用手机号重新登录。确定继续吗?',
|
||||
confirmText: '确认注销',
|
||||
confirmColor: '#c0392b',
|
||||
success: (res2) => {
|
||||
if (!res2.confirm) return;
|
||||
// 仅清除前端登录信息
|
||||
try {
|
||||
api.request({ url: '/api/v1/auth/logout', method: 'POST' }).catch(() => {});
|
||||
} catch (e) {}
|
||||
auth.clearToken();
|
||||
wx.removeStorageSync('privacy_agreed');
|
||||
wx.showToast({ title: '已注销', icon: 'success' });
|
||||
setTimeout(() => {
|
||||
wx.reLaunch({ url: '/pages/home/home' });
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
<view class="login-wrap">
|
||||
<view class="login-card">
|
||||
<view class="login-icon">👤</view>
|
||||
<view class="login-title">微信手机号一键登录</view>
|
||||
<view class="login-desc">未找到你的账号,请使用微信手机号登录。手机号仅用于账号绑定,不会公开展示。</view>
|
||||
<view class="login-title">手机号快捷登录</view>
|
||||
<view class="login-desc">未找到你的账号,请使用手机号登录。手机号仅用于账号绑定,不会公开展示。</view>
|
||||
<button
|
||||
class="btn-phone btn-primary"
|
||||
open-type="getPhoneNumber"
|
||||
@@ -29,7 +29,18 @@
|
||||
loading="{{phoneLoading}}"
|
||||
disabled="{{phoneLoading}}"
|
||||
hover-class="btn-hover"
|
||||
>{{phoneLoading ? '登录中...' : '微信手机号一键登录'}}</button>
|
||||
>{{phoneLoading ? '登录中...' : '手机号快捷登录'}}</button>
|
||||
<view class="privacy-row">
|
||||
<view class="checkbox {{privacyAgreed ? 'checked' : ''}}" bindtap="togglePrivacy">
|
||||
<text wx:if="{{privacyAgreed}}" class="check-icon">✓</text>
|
||||
</view>
|
||||
<view class="privacy-text">
|
||||
我已阅读并同意
|
||||
<text class="link" data-type="agreement" catchtap="openPrivacy">《用户协议》</text>
|
||||
和
|
||||
<text class="link" data-type="privacy" catchtap="openPrivacy">《隐私政策》</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="error" wx:if="{{phoneError}}">{{phoneError}}</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -91,7 +102,7 @@
|
||||
</view>
|
||||
|
||||
<view class="card classlist-card" wx:if="{{classGroups.length}}">
|
||||
<view class="info-title">班级分组</view>
|
||||
<view class="info-title">小组分组</view>
|
||||
<view class="class-row" wx:for="{{classGroups}}" wx:key="class_id">
|
||||
<text class="info-label">{{item.period || item.class_code}}</text>
|
||||
<text class="info-value">{{item.group}} · {{item.role}}</text>
|
||||
@@ -99,7 +110,8 @@
|
||||
</view>
|
||||
|
||||
<view class="bottom-actions">
|
||||
<button class="btn-logout" hover-class="btn-hover" bindtap="logout">退出登录</button>
|
||||
<button class="btn-delete" hover-class="btn-hover" bindtap="deleteAccount">注销账号</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</block>
|
||||
@@ -186,9 +186,52 @@ button::after { border: none; }
|
||||
margin-top: 48rpx;
|
||||
padding-top: 24rpx;
|
||||
}
|
||||
.btn-logout {
|
||||
/* ---- privacy row ---- */
|
||||
.privacy-row {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-top: 28rpx;
|
||||
text-align: left;
|
||||
}
|
||||
.checkbox {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
border: 2rpx solid #D8C7B4;
|
||||
border-radius: 6rpx;
|
||||
margin-right: 14rpx;
|
||||
margin-top: 2rpx;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #fff;
|
||||
}
|
||||
.checkbox.checked {
|
||||
background: #C67B30;
|
||||
border-color: #C67B30;
|
||||
}
|
||||
.check-icon {
|
||||
color: #fff;
|
||||
font-size: 22rpx;
|
||||
line-height: 1;
|
||||
font-weight: 700;
|
||||
}
|
||||
.privacy-text {
|
||||
flex: 1;
|
||||
font-size: 24rpx;
|
||||
color: #8B7A6A;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.privacy-text .link {
|
||||
color: #C67B30;
|
||||
}
|
||||
|
||||
/* ---- delete account ---- */
|
||||
.btn-delete {
|
||||
background: #fff;
|
||||
color: #c0392b;
|
||||
border: 1rpx solid #f0b4ae;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
/* ---- profile name edit ---- */
|
||||
|
||||
Reference in New Issue
Block a user