fix: 封禁强制登录页并清会话,修复解封后无请求
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
1c6c9a7ac0
commit
b9de9ea34e
6 files changed
+223
-38
No files matched your search
@@ -12,7 +12,7 @@ import { fetchGonggaoLunbo, isGonggaoCacheValid, getCachedGonggaoLunbo } from '.
|
||||
import { checkPenaltyForGrab } from '../../utils/grab-order-gate.js';
|
||||
import { ensureRoleAgreement } from '../../utils/role-agreement-gate.js';
|
||||
import { fetchMyZhidingOrders, submitZhidingResponse, processZhidingList, filterZhidingBannerList, ZHIDING_HF_MAP } from '../../utils/zhiding-order.js';
|
||||
import { isFighterOnly, FIGHTER_MINE, isDashouCertified, canEnterAcceptOrder } from '../../utils/fighter-only.js';
|
||||
import { isFighterOnly, FIGHTER_MINE, isDashouCertified, canEnterAcceptOrder, kickToLoginPage } from '../../utils/fighter-only.js';
|
||||
|
||||
/** 抢单池轮播 page_key(勿与点单页 order_pool 混用) */
|
||||
const ACCEPT_ORDER_PAGE_KEY = 'accept_order';
|
||||
@@ -325,6 +325,20 @@ Page({
|
||||
/** 拉取最新打手信息(会员/押金/积分),并刷新订单卡片上的会员展示 */
|
||||
async syncDashouProfileFromServer() {
|
||||
if (!wx.getStorageSync('token')) return;
|
||||
try {
|
||||
const res = await request({ url: '/yonghu/dashouxinxi', method: 'POST' });
|
||||
if (res && res.data && res.data.code == 200 && res.data.data) {
|
||||
const data = res.data.data;
|
||||
if (Number(data.zhanghaostatus) !== 1) {
|
||||
kickToLoginPage(
|
||||
data.fengjin_yuanyin
|
||||
? `账号状态异常,您的账号已被封禁。原因:${data.fengjin_yuanyin}`
|
||||
: '账号状态异常,您的账号已被封禁,请联系客服'
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (e) {}
|
||||
await refreshDashouMembership(app);
|
||||
this.loadGlobalStatus();
|
||||
if (this.data.dingdanList && this.data.dingdanList.length) {
|
||||
|
||||
+93
-13
@@ -18,8 +18,7 @@ import {
|
||||
} from '../../utils/miniapp-icons.js'
|
||||
import { getDefaultAvatarUrl } from '../../utils/avatar.js'
|
||||
import { ensureRoleAgreement } from '../../utils/role-agreement-gate.js'
|
||||
import { isFighterOnly, FIGHTER_ONLY_DEFAULT_INVITE, FIGHTER_HOME, shouldSkipAutoAuth, clearSkipAutoAuth, isShangjiaCertified } from '../../utils/fighter-only.js'
|
||||
import { LOGIN_HINT_KEY } from '../../utils/request.js'
|
||||
import { isFighterOnly, FIGHTER_ONLY_DEFAULT_INVITE, FIGHTER_HOME, shouldSkipAutoAuth, clearSkipAutoAuth, isShangjiaCertified, LOGIN_HINT_KEY, clearAuthSession, kickToLoginPage } from '../../utils/fighter-only.js'
|
||||
|
||||
const PLATFORM_INVITE_CODE = FIGHTER_ONLY_DEFAULT_INVITE || '0000008VfJKPu4Spmcjt'
|
||||
const app = getApp()
|
||||
@@ -39,6 +38,7 @@ Page(createPage({
|
||||
accountBanReason: '',
|
||||
roleBanTips: [],
|
||||
loginPageHint: '',
|
||||
forceLoginView: false,
|
||||
totalAssets: '0.00',
|
||||
totalDongjie: '0.00',
|
||||
showDongjieHint: false,
|
||||
@@ -246,14 +246,19 @@ Page(createPage({
|
||||
},
|
||||
|
||||
async onShow() {
|
||||
this.loadLoginPageHint();
|
||||
this.checkRoleStatuses();
|
||||
const needLogin = isFighterOnly() && !isDashouCertified()
|
||||
const hasToken = !!wx.getStorageSync('token');
|
||||
const needLogin = isFighterOnly() && (!hasToken || !isDashouCertified())
|
||||
&& !isRoleStatusActive(wx.getStorageSync('guanshistatus'))
|
||||
&& !isRoleStatusActive(wx.getStorageSync('zuzhangstatus'))
|
||||
&& !isRoleStatusActive(wx.getStorageSync('kaoheguanstatus'));
|
||||
if (needLogin) {
|
||||
if (needLogin || this.data.forceLoginView || !hasToken) {
|
||||
// 登录页:强制隐藏底部导航,杜绝 Tab 露出来
|
||||
try { wx.hideTabBar({ animation: false }); } catch (e) {}
|
||||
this.setData({ forceLoginView: true });
|
||||
// 无 token 时不要走手机号认证等业务,避免卡死/乱跳
|
||||
if (!hasToken) return;
|
||||
} else {
|
||||
try { wx.showTabBar({ animation: false }); } catch (e) {}
|
||||
}
|
||||
@@ -308,6 +313,23 @@ Page(createPage({
|
||||
},
|
||||
|
||||
checkRoleStatuses() {
|
||||
const token = wx.getStorageSync('token');
|
||||
// 无 token:必须显示登录页,不能靠残留 dashoustatus=1 伪登录
|
||||
if (!token) {
|
||||
this.setData({
|
||||
isDashou: false,
|
||||
isGuanshi: false,
|
||||
isZuzhang: false,
|
||||
isKaoheguan: false,
|
||||
isShangjia: false,
|
||||
shangjiaCertified: false,
|
||||
forceLoginView: true,
|
||||
showPindaoEntry: false,
|
||||
layoutSparse: true,
|
||||
moreFuncList: [],
|
||||
});
|
||||
return;
|
||||
}
|
||||
const isDashou = isRoleStatusActive(wx.getStorageSync('dashoustatus'));
|
||||
const isGuanshi = isRoleStatusActive(wx.getStorageSync('guanshistatus'));
|
||||
const isZuzhang = isRoleStatusActive(wx.getStorageSync('zuzhangstatus'));
|
||||
@@ -320,6 +342,7 @@ Page(createPage({
|
||||
shangjiaCertified: isShangjia,
|
||||
layoutSparse: subRoleCount === 0,
|
||||
showPindaoEntry: !!(isDashou || isGuanshi || isZuzhang),
|
||||
forceLoginView: false,
|
||||
}, () => {
|
||||
this._updateTotalAssets();
|
||||
this._buildMoreFuncList();
|
||||
@@ -336,12 +359,31 @@ Page(createPage({
|
||||
try {
|
||||
const hint = wx.getStorageSync(LOGIN_HINT_KEY) || '';
|
||||
if (hint) {
|
||||
this.setData({ loginPageHint: hint });
|
||||
wx.removeStorageSync(LOGIN_HINT_KEY);
|
||||
this.setData({ loginPageHint: hint, forceLoginView: true });
|
||||
// 保留到用户点登录成功后再清,避免闪一下消失
|
||||
}
|
||||
} catch (e) {}
|
||||
},
|
||||
|
||||
/** 封禁:清会话进登录页并提示账号状态异常 */
|
||||
forceAccountBannedLogout(reason) {
|
||||
const msg = reason
|
||||
? `账号状态异常,您的账号已被封禁。原因:${reason}`
|
||||
: '账号状态异常,您的账号已被封禁,请联系客服';
|
||||
kickToLoginPage(msg);
|
||||
this.setData({
|
||||
forceLoginView: true,
|
||||
isDashou: false,
|
||||
isGuanshi: false,
|
||||
isZuzhang: false,
|
||||
isKaoheguan: false,
|
||||
accountBanned: true,
|
||||
accountBanReason: reason || '',
|
||||
loginPageHint: msg,
|
||||
isAutoRegistering: false,
|
||||
});
|
||||
},
|
||||
|
||||
_parseMoney(val) {
|
||||
return parseFloat(String(val || '0').replace(/,/g, '')) || 0;
|
||||
},
|
||||
@@ -578,6 +620,13 @@ Page(createPage({
|
||||
};
|
||||
Object.assign(app.globalData, updateData);
|
||||
|
||||
// 账号封禁:立刻踢回登录页,禁止继续停留在「已登录我的」
|
||||
if (Number(data.zhanghaostatus) !== 1) {
|
||||
try { wx.setStorageSync('zhanghaostatus', data.zhanghaostatus); } catch (e) {}
|
||||
this.forceAccountBannedLogout(data.fengjin_yuanyin || '');
|
||||
return;
|
||||
}
|
||||
|
||||
// 身份:以后端实时字段为准(后台刚加/封禁角色,下拉即可更新)
|
||||
if (data.dashoustatus !== undefined) {
|
||||
this._applyRoleStatusFromApi('dashoustatus', isRoleStatusActive(data.dashoustatus));
|
||||
@@ -594,7 +643,6 @@ Page(createPage({
|
||||
this._applyRoleStatusFromApi('shangjiastatus', isRoleStatusActive(data.shangjiastatus));
|
||||
}
|
||||
|
||||
const accountBanned = Number(data.zhanghaostatus) !== 1;
|
||||
const roleBanTips = [];
|
||||
if (data.guanshistatus === 0 && data.guanshi_fengjin_yuanyin) {
|
||||
roleBanTips.push({ role: '管事', reason: data.guanshi_fengjin_yuanyin });
|
||||
@@ -608,9 +656,10 @@ Page(createPage({
|
||||
|
||||
this.setData({
|
||||
...updateData,
|
||||
accountBanned,
|
||||
accountBanReason: data.fengjin_yuanyin || '',
|
||||
accountBanned: false,
|
||||
accountBanReason: '',
|
||||
roleBanTips,
|
||||
forceLoginView: false,
|
||||
isLoading: false,
|
||||
});
|
||||
this._updateTotalAssets();
|
||||
@@ -1134,6 +1183,14 @@ Page(createPage({
|
||||
success: (res) => {
|
||||
if (res.statusCode === 200 && res.data && res.data.code === 0 && res.data.data) {
|
||||
const userData = res.data.data;
|
||||
// 封禁账号:后端应已拦截;双保险再拦一次
|
||||
if (userData.zhanghaostatus !== undefined && Number(userData.zhanghaostatus) !== 1) {
|
||||
wx.hideLoading();
|
||||
that.setData({ isAutoRegistering: false });
|
||||
const reason = userData.fengjin_yuanyin || '';
|
||||
that.forceAccountBannedLogout(reason);
|
||||
return;
|
||||
}
|
||||
syncProfileFields(userData);
|
||||
syncRoleStatuses(userData);
|
||||
syncGroupFields(userData);
|
||||
@@ -1150,6 +1207,7 @@ Page(createPage({
|
||||
app.globalData[field] = val;
|
||||
}
|
||||
});
|
||||
try { wx.removeStorageSync(LOGIN_HINT_KEY); } catch (e) {}
|
||||
// 登录后立刻按真实值刷新「更多功能」列表
|
||||
that.checkRoleStatuses();
|
||||
that._buildMoreFuncList && that._buildMoreFuncList();
|
||||
@@ -1178,6 +1236,9 @@ Page(createPage({
|
||||
}
|
||||
that.setData({
|
||||
isDashou: true,
|
||||
forceLoginView: false,
|
||||
loginPageHint: '',
|
||||
accountBanned: false,
|
||||
uid: userData.uid || '',
|
||||
touxiang: userData.touxiang || '',
|
||||
isAutoRegistering: false
|
||||
@@ -1192,7 +1253,14 @@ Page(createPage({
|
||||
that._goFighterHomeAfterRegister();
|
||||
} else {
|
||||
wx.hideLoading();
|
||||
wx.showToast({ title: (res.data && res.data.msg) || '登录注册失败', icon: 'none' });
|
||||
that.setData({ isAutoRegistering: false, forceLoginView: true });
|
||||
const failMsg = (res.data && res.data.msg) || '登录注册失败';
|
||||
// 封禁等业务错误:固定展示在登录页
|
||||
if (String(failMsg).includes('封禁') || String(failMsg).includes('状态异常') || (res.data && res.data.code === 4031)) {
|
||||
try { wx.setStorageSync(LOGIN_HINT_KEY, failMsg); } catch (e) {}
|
||||
that.setData({ loginPageHint: failMsg });
|
||||
}
|
||||
wx.showToast({ title: failMsg, icon: 'none', duration: 3000 });
|
||||
}
|
||||
},
|
||||
fail: () => {
|
||||
@@ -1204,20 +1272,32 @@ Page(createPage({
|
||||
|
||||
checkDashouStatus() {
|
||||
try {
|
||||
const token = wx.getStorageSync('token');
|
||||
if (!token) {
|
||||
// 残留身份缓存一律忽略,强制登录视图
|
||||
this.setData({
|
||||
isDashou: false,
|
||||
isGuanshi: false,
|
||||
isZuzhang: false,
|
||||
isKaoheguan: false,
|
||||
forceLoginView: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
const dashoustatus = wx.getStorageSync('dashoustatus');
|
||||
const uid = wx.getStorageSync('uid');
|
||||
const touxiang = wx.getStorageSync('touxiang');
|
||||
if (isRoleStatusActive(dashoustatus)) {
|
||||
this.setData({ isDashou: true, uid: uid || '', touxiang: touxiang || '' });
|
||||
this.setData({ isDashou: true, forceLoginView: false, uid: uid || '', touxiang: touxiang || '' });
|
||||
this.loadAvatar();
|
||||
this.checkGlobalData();
|
||||
ensureRoleOnCenterPage(this, 'dashou');
|
||||
} else {
|
||||
this.setData({ isDashou: false });
|
||||
this.setData({ isDashou: false, forceLoginView: true });
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('读取缓存失败:', error);
|
||||
this.setData({ isDashou: false });
|
||||
this.setData({ isDashou: false, forceLoginView: true });
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!-- 打手端个人中心 - 逍遥梦布局,逻辑/事件不变 -->
|
||||
|
||||
<!-- 未注册 / 未登录:只保留邀请码输入(可选)+ 一键登录,不再有「注册」按钮 -->
|
||||
<block wx:if="{{!isDashou && !isGuanshi && !isZuzhang && !isKaoheguan}}">
|
||||
<!-- 未注册 / 未登录 / 封禁踢出:只保留邀请码输入(可选)+ 一键登录 -->
|
||||
<block wx:if="{{forceLoginView || (!isDashou && !isGuanshi && !isZuzhang && !isKaoheguan)}}">
|
||||
<view class="user-page unreg-page">
|
||||
<view class="page-header">
|
||||
<view class="status-bar" style="height:{{statusBar}}px"></view>
|
||||
|
||||
@@ -9,6 +9,17 @@ export async function refreshDashouMembership(app) {
|
||||
const res = await request({ url: '/yonghu/dashouxinxi', method: 'POST' });
|
||||
if (res && res.data && res.data.code == 200) {
|
||||
const data = res.data.data || {};
|
||||
if (data.zhanghaostatus !== undefined && Number(data.zhanghaostatus) !== 1) {
|
||||
try {
|
||||
const { kickToLoginPage } = require('./fighter-only.js');
|
||||
kickToLoginPage(
|
||||
data.fengjin_yuanyin
|
||||
? `账号状态异常,您的账号已被封禁。原因:${data.fengjin_yuanyin}`
|
||||
: '账号状态异常,您的账号已被封禁,请联系客服'
|
||||
);
|
||||
} catch (e) {}
|
||||
return app.globalData.clumber || [];
|
||||
}
|
||||
const clumber = Array.isArray(data.clumber) ? data.clumber : [];
|
||||
app.globalData.clumber = clumber;
|
||||
if (data.yajin !== undefined) app.globalData.yajin = data.yajin;
|
||||
|
||||
@@ -17,14 +17,49 @@ export const FIGHTER_MINE = '/pages/fighter/fighter'
|
||||
/** 清除缓存后禁止自动登录/自动注册(用户手动点登录后再清) */
|
||||
export const SKIP_AUTO_AUTH_KEY = 'fighter_skip_auto_auth'
|
||||
|
||||
/** 登录页提示文案 */
|
||||
export const LOGIN_HINT_KEY = 'login_page_hint'
|
||||
|
||||
const ROLE_STATUS_KEYS = [
|
||||
'dashoustatus',
|
||||
'guanshistatus',
|
||||
'shangjiastatus',
|
||||
'zuzhangstatus',
|
||||
'kaoheguanstatus',
|
||||
]
|
||||
|
||||
const AUTH_CACHE_KEYS = [
|
||||
'token',
|
||||
'userInfo',
|
||||
'uid',
|
||||
'nicheng',
|
||||
'touxiang',
|
||||
'phone',
|
||||
'dsnc',
|
||||
'dsjieshao',
|
||||
'dsdianhua',
|
||||
'dsweixin',
|
||||
...ROLE_STATUS_KEYS,
|
||||
]
|
||||
|
||||
export function isFighterOnly() {
|
||||
return FIGHTER_ONLY === true
|
||||
}
|
||||
|
||||
export function isDashouCertified() {
|
||||
if (!wx.getStorageSync('token')) return false
|
||||
return Number(wx.getStorageSync('dashoustatus')) === 1
|
||||
}
|
||||
|
||||
/** 本地是否标记为账号封禁(会话清理后仍可提示) */
|
||||
export function isAccountBannedLocal() {
|
||||
try {
|
||||
const st = wx.getStorageSync('zhanghaostatus')
|
||||
if (st !== '' && st !== undefined && st !== null && Number(st) !== 1) return true
|
||||
} catch (e) {}
|
||||
return false
|
||||
}
|
||||
|
||||
export function markSkipAutoAuth() {
|
||||
try {
|
||||
wx.setStorageSync(SKIP_AUTO_AUTH_KEY, '1')
|
||||
@@ -45,6 +80,52 @@ export function shouldSkipAutoAuth() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清登录态但保留动态配置(OSS 等)。
|
||||
* 解决:只删 token、留下 dashoustatus=1 → 卡在「已登录我的」且请求全部假 401。
|
||||
*/
|
||||
export function clearAuthSession(opts = {}) {
|
||||
const app = typeof getApp === 'function' ? getApp() : null
|
||||
const hint = opts.hint || ''
|
||||
try {
|
||||
AUTH_CACHE_KEYS.forEach((k) => {
|
||||
try { wx.removeStorageSync(k) } catch (e) {}
|
||||
})
|
||||
try { wx.removeStorageSync('zhanghaostatus') } catch (e) {}
|
||||
if (hint) wx.setStorageSync(LOGIN_HINT_KEY, hint)
|
||||
markSkipAutoAuth()
|
||||
} catch (e) {}
|
||||
|
||||
if (app && app.globalData) {
|
||||
app.globalData.token = ''
|
||||
app.globalData.uid = ''
|
||||
app.globalData.nicheng = ''
|
||||
app.globalData.dashouNicheng = ''
|
||||
app.globalData.loginPromise = null
|
||||
app.globalData.currentUser = null
|
||||
app.globalData._acceptOrderSessionReady = false
|
||||
app.globalData._acceptOrderPageCache = null
|
||||
app.globalData._acceptOrderPopupDone = false
|
||||
app.globalData._dashouPhoneChecked = false
|
||||
ROLE_STATUS_KEYS.forEach((k) => { app.globalData[k] = 0 })
|
||||
}
|
||||
}
|
||||
|
||||
/** 封禁 / 登录失效:清会话并回登录页 */
|
||||
export function kickToLoginPage(hint) {
|
||||
const msg =
|
||||
hint ||
|
||||
'账号状态异常,您的账号可能已被封禁。请点击一键登录重试;若仍无法进入,请联系客服。'
|
||||
clearAuthSession({ hint: msg })
|
||||
const url = getLoginPageUrl()
|
||||
wx.reLaunch({
|
||||
url,
|
||||
fail: () => {
|
||||
try { wx.redirectTo({ url }) } catch (e) {}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/** 冷启动应去的页面:未登录 / 未认证 → 登录页;已认证 → 抢单池 */
|
||||
export function resolveFighterOnlyLaunchUrl() {
|
||||
const token = wx.getStorageSync('token')
|
||||
|
||||
+21
-22
@@ -1,8 +1,6 @@
|
||||
// utils/request.js
|
||||
import { buildClubHeaders } from './club-context';
|
||||
|
||||
const LOGIN_HINT_KEY = 'login_page_hint';
|
||||
|
||||
function getLoginFallbackUrl() {
|
||||
try {
|
||||
const { getLoginPageUrl } = require('./fighter-only.js');
|
||||
@@ -14,8 +12,19 @@ function getLoginFallbackUrl() {
|
||||
|
||||
function goLoginPage(hint) {
|
||||
try {
|
||||
if (hint) wx.setStorageSync(LOGIN_HINT_KEY, hint);
|
||||
} catch (e) {}
|
||||
const { kickToLoginPage, LOGIN_HINT_KEY, clearAuthSession } = require('./fighter-only.js');
|
||||
if (typeof kickToLoginPage === 'function') {
|
||||
kickToLoginPage(hint);
|
||||
return;
|
||||
}
|
||||
if (hint) wx.setStorageSync(LOGIN_HINT_KEY || 'login_page_hint', hint);
|
||||
clearAuthSession && clearAuthSession({ hint });
|
||||
} catch (e) {
|
||||
try {
|
||||
if (hint) wx.setStorageSync('login_page_hint', hint);
|
||||
wx.removeStorageSync('token');
|
||||
} catch (e2) {}
|
||||
}
|
||||
const url = getLoginFallbackUrl();
|
||||
wx.reLaunch({
|
||||
url,
|
||||
@@ -26,31 +35,18 @@ function goLoginPage(hint) {
|
||||
}
|
||||
|
||||
function clearAuthAndGoLogin(hint) {
|
||||
try {
|
||||
wx.removeStorageSync('token');
|
||||
wx.removeStorageSync('userInfo');
|
||||
} catch (e) {}
|
||||
goLoginPage(
|
||||
hint ||
|
||||
'您的账号可能已被封禁,或尚未注册。请点击一键登录重试;若仍无法进入,请联系客服。'
|
||||
'账号状态异常,您的账号可能已被封禁或登录已失效。请点击一键登录重试;若仍无法进入,请联系客服。'
|
||||
);
|
||||
}
|
||||
|
||||
function showAuthFailModal(serverMsg) {
|
||||
const hint =
|
||||
(serverMsg && String(serverMsg).trim()) ||
|
||||
'您的账号可能已被封禁,或尚未注册。请点击一键登录重试;若仍无法进入,请联系客服。';
|
||||
wx.showModal({
|
||||
title: '无法继续访问',
|
||||
content: hint,
|
||||
confirmText: '去登录',
|
||||
cancelText: '取消',
|
||||
success: (modalRes) => {
|
||||
if (modalRes.confirm) {
|
||||
clearAuthAndGoLogin(hint);
|
||||
}
|
||||
},
|
||||
});
|
||||
'账号状态异常,您的账号可能已被封禁或登录已失效。请点击一键登录重试;若仍无法进入,请联系客服。';
|
||||
// 直接清会话进登录页,避免卡在「伪已登录」我的页且不再发请求
|
||||
clearAuthAndGoLogin(hint);
|
||||
}
|
||||
|
||||
function request(options) {
|
||||
@@ -84,6 +80,7 @@ function request(options) {
|
||||
if (res.statusCode === 401 || res.statusCode === 403) {
|
||||
const serverMsg =
|
||||
(res.data && (res.data.msg || res.data.message)) || '';
|
||||
// 业务封禁文案优先;登录页会展示
|
||||
if (app.globalData.loginPromise) {
|
||||
try {
|
||||
await app.globalData.loginPromise;
|
||||
@@ -118,4 +115,6 @@ function request(options) {
|
||||
}
|
||||
|
||||
export default request;
|
||||
export { LOGIN_HINT_KEY, goLoginPage, clearAuthAndGoLogin };
|
||||
export { goLoginPage, clearAuthAndGoLogin };
|
||||
// 兼容旧引用
|
||||
export { LOGIN_HINT_KEY } from './fighter-only.js';
|
||||
Reference in new issue
Block a user