fix(release): close fixed-code mobile auth gaps

This commit is contained in:
key
2026-07-29 11:59:30 +08:00
parent 3c92edd23d
commit 70e5516ff3
21 changed files with 546 additions and 65 deletions
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "aihr-mobile-uni",
"version": "0.1.12",
"version": "0.1.13",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "aihr-mobile-uni",
"version": "0.1.12",
"version": "0.1.13",
"dependencies": {
"@dcloudio/uni-app": "3.0.0-alpha-5020220260725001",
"@dcloudio/uni-app-plus": "3.0.0-alpha-5020220260725001",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package",
"name": "aihr-mobile-uni",
"version": "0.1.12",
"version": "0.1.13",
"private": true,
"type": "module",
"scripts": {
+2 -2
View File
@@ -3,8 +3,8 @@
"appid" : "__UNI__B36D8BE",
"description" : "帮道员工端",
"vueVersion" : "3",
"versionName" : "0.1.12",
"versionCode" : "112",
"versionName" : "0.1.13",
"versionCode" : "113",
"uniStatistics" : {
"enable" : false
},
+9 -1
View File
@@ -240,6 +240,14 @@ const goAfterLogin = async () => {
goToMobileTarget(await nextUserRouteAfterLogin(redirect));
};
const resumeAfterLogin = async () => {
try {
await goAfterLogin();
} catch (error) {
message.value = error instanceof Error ? error.message : '组织身份加载失败,请重试';
}
};
const sendCode = async () => {
if (sending.value || countdown.value > 0) return;
if (!ensureLegalConsent()) return;
@@ -302,7 +310,7 @@ const login = async () => {
onShow(() => {
resetPageScroll();
if (isLoggedIn()) {
void goAfterLogin();
void resumeAfterLogin();
}
});
+12 -6
View File
@@ -2,7 +2,6 @@ import type { MobileIdentity, RoleKey } from '@/types/api';
import { apiRequest, isAuthApiError } from './api';
import {
clearOrgPosition,
getSelectedPosition,
hasOrgPosition,
isSupervisorLearnerMode,
leaveSupervisorLearnerMode,
@@ -43,14 +42,17 @@ export const routeForMobileRole = (role: RoleKey, requested: string) => {
export const hydrateMobileRole = async (): Promise<RoleKey> => {
try {
const identity = await fetchMobileIdentity();
const role = identity.role === 'supervisor' ? 'supervisor' : 'user';
if (identity.role !== 'user' && identity.role !== 'supervisor') {
throw new Error('组织角色无效,请联系管理员');
}
const role = identity.role;
uni.setStorageSync(roleKey, role);
if (role !== 'supervisor') leaveSupervisorLearnerMode();
return role;
} catch {
// ponytail: role lookup failure fails closed; never reuse a stale supervisor cache.
} catch (error) {
uni.removeStorageSync(roleKey);
return 'user';
clearOrgPosition();
throw error instanceof Error ? error : new Error('组织角色加载失败,请重试');
}
};
@@ -89,7 +91,11 @@ export const hydratePositionFromOrg = async (): Promise<UserPosition | ''> => {
const result = await fetchOrgPositionResult();
if (result.status === 'matched') return result.position;
if (result.status === 'unmatched') return '';
return hasOrgPosition() ? getSelectedPosition() : '';
clearOrgPosition();
if (result.status === 'unauthorized') {
throw new Error('登录已失效,请重新登录');
}
throw new Error('组织岗位加载失败,请检查网络后重试');
};
export const nextUserRouteAfterLogin = async (redirect: string) => {
+11 -1
View File
@@ -229,12 +229,22 @@ test('工作助手与查全网使用一致的来源切换头部', async () => {
});
test('登录后按组织身份切换主管首页', async () => {
const source = await pageSource('../src/services/position.ts');
const [source, loginSource] = await Promise.all([
pageSource('../src/services/position.ts'),
pageSource('../src/pages/auth/login/index.vue')
]);
assert.match(source, /\/api\/aihr\/mobile\/me/);
assert.match(source, /role === 'supervisor'/);
assert.match(source, /pages\/supervisor\/index\/index/);
assert.match(source, /removeStorageSync\(roleKey\)/);
assert.match(source, /identity\.role !== 'user' && identity\.role !== 'supervisor'/);
assert.match(source, /clearOrgPosition\(\);\s*throw error/);
assert.doesNotMatch(source, /catch\s*\{[\s\S]*return 'user'/);
assert.doesNotMatch(source, /return hasOrgPosition\(\) \? getSelectedPosition\(\) : ''/);
assert.match(loginSource, /const resumeAfterLogin = async \(\) => \{/);
assert.match(loginSource, /message\.value = error instanceof Error \? error\.message : '组织身份加载失败,请重试'/);
assert.doesNotMatch(loginSource, /void goAfterLogin\(\)/);
});
test('普通员工请求主管深链时回到员工首页', async () => {