From 87cb6a63743ee81e8058d258b09da7fe0ec6118a Mon Sep 17 00:00:00 2001 From: xcbyy <2578898740@qq.com> Date: Wed, 21 Oct 2026 11:38:26 +0800 Subject: [PATCH] =?UTF-8?q?fix(miniapp):=20=E6=8F=90=E7=8E=B0/=E8=B4=A2?= =?UTF-8?q?=E5=8A=A1=E6=8E=A5=E5=8F=A3=E4=B8=8D=E5=86=8D=E7=94=A8=201001?= =?UTF-8?q?=20=E6=BC=94=E7=A4=BA=E8=BA=AB=E4=BB=BD=EF=BC=8C=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=20403?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - getUserProfile/getUserWithdrawals/getUserFinanceRecords 去掉 userId=1001 默认值,改由 normalizeUserId 解析登录身份 - withdraw.vue / withdraw-records.vue / workspace.vue 调用改为 normalizeUserId(),不再硬编码 1001 - normalizeUserId 将 1001 视为演示占位符:登录态下传 0 由 token 识别,未登录才兜底 1001 - request.js 遇 403 身份校验失败时清理错配登录态并提示重新登录(其它 403 权限拒绝不受影响) - 登录态闸门补齐用例(108 套件/714 用例全绿) --- pwuniapp/common/api.js | 13 ++++++---- pwuniapp/common/request.js | 2 ++ pwuniapp/pages/expert/workspace.vue | 5 ++-- pwuniapp/pages/user/withdraw-records.vue | 4 +-- pwuniapp/pages/user/withdraw.vue | 7 ++--- .../tests/login-identity-consistency.spec.ts | 26 +++++++++++++++++++ 6 files changed, 45 insertions(+), 12 deletions(-) diff --git a/pwuniapp/common/api.js b/pwuniapp/common/api.js index 1e01b17..d8bb32a 100644 --- a/pwuniapp/common/api.js +++ b/pwuniapp/common/api.js @@ -558,13 +558,16 @@ export async function viewPost(id) { */ export function normalizeUserId(uid) { let target = uid; - if (!target && target !== 0) { + // 1001 是历史演示账号默认值,不代表真实登录用户:一律回到本地存储解析 + const isPlaceholder = target === undefined || target === null || target === '' || Number(target) === 1001; + if (isPlaceholder) { try { target = uni.getStorageSync('userId'); } catch (_) {} } const n = Number(target); - const valid = !isNaN(n) && n > 0; + // 1001 仅作为"未登录演示"的兜底,登录态下不作为真实身份 + const valid = !isNaN(n) && n > 0 && n !== 1001; // 已登录(存在会话 token)时身份以服务端 token 为准:若本地 userId 缺失则传 0, // 避免"旧 token 属主 + 声明的 userId"不一致被服务端判定为以他人身份操作(403)。 try { @@ -577,7 +580,7 @@ export function normalizeUserId(uid) { /** * 获取用户个人资料与钱包资产 (真实读取 MySQL users 表) */ -export async function getUserProfile(userId = 1001) { +export async function getUserProfile(userId) { const safeId = normalizeUserId(userId); try { const res = await http.get(`/users/${safeId}`); @@ -653,7 +656,7 @@ export async function withdrawCommission(arg1, arg2, arg3 = {}) { /** * 查询用户提现记录与审批状态 (待审核/处理中/已打款/已驳回) */ -export async function getUserWithdrawals(userId = 1001) { +export async function getUserWithdrawals(userId) { const safeId = normalizeUserId(userId); try { const res = await http.get(`/users/${safeId}/withdrawals`); @@ -667,7 +670,7 @@ export async function getUserWithdrawals(userId = 1001) { /** * 查询用户财务收支流水 */ -export async function getUserFinanceRecords(userId = 1001) { +export async function getUserFinanceRecords(userId) { const safeId = normalizeUserId(userId); try { const res = await http.get(`/users/${safeId}/finance-records`); diff --git a/pwuniapp/common/request.js b/pwuniapp/common/request.js index b2f1641..4635975 100644 --- a/pwuniapp/common/request.js +++ b/pwuniapp/common/request.js @@ -75,6 +75,7 @@ export function request(options = {}) { bizErr.code = res.data.code; bizErr.statusCode = res.statusCode; if (res.data.code === 40100) handleAuthExpired(); + else if (res.data.code === 40300 && /身份校验失败|无权以他人身份/.test(res.data.message || '')) handleAuthExpired(); reject(bizErr); } } else { @@ -86,6 +87,7 @@ export function request(options = {}) { httpErr.statusCode = res.statusCode; httpErr.code = (res.data && res.data.code) || res.statusCode; if (res.statusCode === 401) handleAuthExpired(); + else if (res.statusCode === 403 && /身份校验失败|无权以他人身份/.test(errMsg)) handleAuthExpired(); reject(httpErr); } }, diff --git a/pwuniapp/pages/expert/workspace.vue b/pwuniapp/pages/expert/workspace.vue index f6869af..518e989 100644 --- a/pwuniapp/pages/expert/workspace.vue +++ b/pwuniapp/pages/expert/workspace.vue @@ -490,7 +490,8 @@ import { updateExpertService, deleteExpertService, uploadVoiceIntro, - getUserWithdrawals + getUserWithdrawals, + normalizeUserId } from '@/common/api.js'; const currentThemeKey = ref(getCurrentThemeKey()); @@ -801,7 +802,7 @@ const goToWithdrawPage = () => { const openWithdrawRecords = async () => { try { - const list = await getUserWithdrawals(1001); + const list = await getUserWithdrawals(normalizeUserId()); withdrawRecords.value = list || []; } catch (_) {} showWithdrawRecordsModal.value = true; diff --git a/pwuniapp/pages/user/withdraw-records.vue b/pwuniapp/pages/user/withdraw-records.vue index 8f5d5fe..dbd6c88 100644 --- a/pwuniapp/pages/user/withdraw-records.vue +++ b/pwuniapp/pages/user/withdraw-records.vue @@ -180,7 +180,7 @@ import { onShow } from '@dcloudio/uni-app'; import { ICONS } from '@/common/icons.js'; import { getCurrentThemeKey, applyThemeToNativeUI } from '@/common/theme.js'; import { getNavBarInfo } from '@/common/nav.js'; -import { getUserWithdrawals } from '@/common/api.js'; +import { getUserWithdrawals, normalizeUserId } from '@/common/api.js'; const currentThemeKey = ref(getCurrentThemeKey()); const navInfo = ref(getNavBarInfo()); @@ -272,7 +272,7 @@ const handleCopyOrderNo = (orderNo) => { const loadWithdrawals = async () => { try { - const list = await getUserWithdrawals(1001); + const list = await getUserWithdrawals(normalizeUserId()); if (Array.isArray(list)) { allRecords.value = list; let successSum = 0; diff --git a/pwuniapp/pages/user/withdraw.vue b/pwuniapp/pages/user/withdraw.vue index 8f8830a..4e3c3a8 100644 --- a/pwuniapp/pages/user/withdraw.vue +++ b/pwuniapp/pages/user/withdraw.vue @@ -189,7 +189,8 @@ import { getUserProfile, withdrawCommission, getUserWithdrawals, - getPlatformConfigs + getPlatformConfigs, + normalizeUserId } from '@/common/api.js'; const currentThemeKey = ref(getCurrentThemeKey()); @@ -281,7 +282,7 @@ const handleFillAllCommission = () => { const loadPageData = async () => { try { - const profile = await getUserProfile(1001); + const profile = await getUserProfile(normalizeUserId()); if (profile && profile.commission !== undefined) { userCommission.value = String(profile.commission); if (profile.nickname) { @@ -298,7 +299,7 @@ const loadPageData = async () => { } catch (_) {} try { - const records = await getUserWithdrawals(1001); + const records = await getUserWithdrawals(normalizeUserId()); if (Array.isArray(records)) { withdrawalsList.value = records; let successSum = 0; diff --git a/server/tests/login-identity-consistency.spec.ts b/server/tests/login-identity-consistency.spec.ts index 2e5f175..5eefe34 100644 --- a/server/tests/login-identity-consistency.spec.ts +++ b/server/tests/login-identity-consistency.spec.ts @@ -26,4 +26,30 @@ describe('第九十批登录态一致性闸门', () => { expect(api).not.toContain('if (n === 101) return 2006;'); expect(api).toContain('if (token) return valid ? n : 0;'); }); + + it('1001 演示默认值不作为真实身份(登录态下回退 token 识别)', () => { + expect(api).toContain('Number(target) === 1001'); + expect(api).toContain('n !== 1001'); + expect(api).not.toContain('getUserWithdrawals(userId = 1001)'); + expect(api).not.toContain('getUserFinanceRecords(userId = 1001)'); + expect(api).not.toContain('getUserProfile(userId = 1001)'); + }); + + it('提现/财务页面不再硬编码 1001 查询本人数据', () => { + for (const rel of [ + 'pwuniapp/pages/user/withdraw.vue', + 'pwuniapp/pages/user/withdraw-records.vue', + 'pwuniapp/pages/expert/workspace.vue', + ]) { + const src = fs.readFileSync(path.join(root, rel), 'utf-8'); + expect(src).not.toContain('getUserWithdrawals(1001)'); + expect(src).not.toContain('getUserProfile(1001)'); + } + }); + + it('请求层遇身份校验失败 403 时清理错配登录态并提示重新登录', () => { + const request = fs.readFileSync(path.join(root, 'pwuniapp/common/request.js'), 'utf-8'); + expect(request).toContain('40300 && /身份校验失败|无权以他人身份/'); + expect(request).toContain('res.statusCode === 403 && /身份校验失败|无权以他人身份/'); + }); });