fix: 封禁强制登录页并清会话,修复解封后无请求

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
XingQueandCursor committed 2026-07-27 05:56:30 +08:00
1 parent 1c6c9a7ac0
commit b9de9ea34e
6 files changed
+223 -38

No files matched your search

+15 -1
View File
@@ -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
View File
@@ -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 });
}
},
+2 -2
View File
@@ -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>
+11
View File
@@ -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;
+81
View File
@@ -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
View File
@@ -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';