Files
huike-front/src/main.ts
T
weli adbf73891a router guard: wrap in try/catch, add single-department auto-selection
- Wrap entire beforeEach guard in try/catch to prevent crashes from
  breaking navigation and leaving a blank page
- Add missing next() at end of try block so all code paths resolve
- Integrate switchDepartment() after loadMyDepartments() when exactly
  1 department is available, enabling transparent single-dept flow

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-02 18:29:54 +08:00

212 lines
8.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import {createApp} from 'vue'
import {createRouter, createWebHistory} from "vue-router";
import routes from "~/routes";
// @ts-ignore
import wx from 'weixin-js-sdk';
import App from './App.vue'
import 'vant/lib/index.css'
import 'leaflet/dist/leaflet.css'
import '~/fontawesome/all.css';
import './index.less'
// @ts-ignore
import useUser from '~/store/user'
import useOrg from "~/store/org";
import cookie from "~/utils/cookie";
import {CurrentOrgId, CurrentUserRole, HtyAuthToken, HtySudoToken, HtyUnionIDToken, pad} from "~/utils";
import {HtyRoles, HtyStates, UserStates} from "~/types";
import useTimer from "~/store/timer";
const router = createRouter({
history: createWebHistory(),
routes
})
const weixin = {
// @ts-ignore
install: app => {
// @ts-ignore
app.config.globalProperties.$weixin = wx;
}
}
// @ts-ignore
Date.prototype.toJSON = function () {
let year = this.getFullYear(),
month = this.getMonth() + 1,
date = this.getDate(),
hour = this.getHours(),
minute = this.getMinutes(),
second = this.getSeconds();
return [year, pad(month), pad(date)].join('-') + 'T' + [pad(hour), pad(minute), pad(second)].join(':')
}
const parseCurrentOrgIdFromToken = (token: string | null): string | undefined => {
if (!token) return undefined;
try {
const tokenParts = token.split('.');
if (tokenParts.length < 2) return undefined;
const payloadRaw = tokenParts[1].replace(/-/g, '+').replace(/_/g, '/');
const payloadRawWithPadding = payloadRaw.padEnd(Math.ceil(payloadRaw.length / 4) * 4, '=');
const payloadJson = decodeURIComponent(
atob(payloadRawWithPadding)
.split('')
.map((char) => `%${(`00${char.charCodeAt(0).toString(16)}`).slice(-2)}`)
.join('')
);
const payload = JSON.parse(payloadJson) as Record<string, unknown>;
if (typeof payload.current_org_id === 'string' && payload.current_org_id) {
return payload.current_org_id;
}
if (typeof payload.sub === 'string' && payload.sub.length > 0) {
const subjectPayload = JSON.parse(payload.sub) as Record<string, unknown>;
if (typeof subjectPayload.current_org_id === 'string' && subjectPayload.current_org_id) {
return subjectPayload.current_org_id;
}
}
return undefined;
} catch (_error) {
return undefined;
}
};
router.beforeEach(async (to, from , next) => {
try {
document.title = to.meta.title as string;
let { store, read, login, logout, chooseRole, getUnreadTongzhis, set_editing } = useUser();
let { store: orgStore, loadMyOrgs, switchOrg, loadMyDepartments, switchDepartment } = useOrg();
set_editing(false)
store.unionid = (store.unionid || cookie.get(HtyUnionIDToken) || '').toString();
if (!store.current.hty_id) {
if (window.localStorage.getItem(HtyAuthToken) && window.localStorage.getItem(HtySudoToken)) {
await read();
} else {
window.localStorage.removeItem(HtyAuthToken);
window.localStorage.removeItem(HtySudoToken);
let userStatus = Number(to.query.status || UserStates.Anonymous);
if (userStatus === UserStates.Registered) {
// 已注册,登录获取用户信息
let new_unionid = to.query.unionid;
if(!store.unionid || (new_unionid && new_unionid !== store.unionid)) {
if(new_unionid) {
cookie.set(HtyUnionIDToken, new_unionid);
await login(new_unionid.toString())
}
} else {
await login(store.unionid)
}
} else {
if (to.path !== '/' && !to.path.startsWith('/guest')) {
await router.replace('/')
}
next()
return
}
}
}
// switched unionidURL 与当前会话不一致时)
if (to.query.unionid && store.unionid !== to.query.unionid) {
const rawQ = to.query.unionid;
const qUnionStr = String(Array.isArray(rawQ) ? rawQ[0] : rawQ || '');
// 已登录且 URL 中的 unionid 与当前用户不同:多为带毒分享链接,剥离身份参数而非 logout
if (store.current.hty_id && qUnionStr) {
const cur = store.current as { union_id?: string };
const currentUnion = String(
cur.union_id != null && cur.union_id !== '' ? cur.union_id : store.unionid || ''
);
if (currentUnion && qUnionStr !== currentUnion) {
const nextQuery = { ...to.query } as Record<string, string | string[] | undefined | null>;
delete nextQuery.unionid;
delete nextQuery.openid;
delete nextQuery.status;
await router.replace({ path: to.path, query: nextQuery });
next();
return;
}
}
cookie.set(HtyUnionIDToken, qUnionStr);
logout();
await login(qUnionStr);
next();
return;
}
let {enabled, is_registered, roles, union_id} = store.current;
console.log(enabled, is_registered, to.path);
// 未启用、未注册 用户进入首页操作
if ((!enabled || !is_registered) && to.path !== '/' && !to.path.startsWith('/guest')) {
if (store.currentRole){
delete store.currentRole
}
window.localStorage.removeItem(CurrentUserRole)
await router.replace('/')
} else {
if (!store.currentRole) {
let prev_role = window.localStorage.getItem(CurrentUserRole)
// check if prev role is still valid
if (prev_role && roles && roles.some(r => r.role_key === prev_role && r.role_status === HtyStates.ACTIVE)) {
chooseRole(prev_role as HtyRoles)
} else {
window.localStorage.removeItem(CurrentUserRole);
let activeRoles = roles?.filter(r => r.role_status === HtyStates.ACTIVE)
if(activeRoles?.length === 1) {
chooseRole(activeRoles[0].role_key)
} else if (to.path !== '/') {
await router.replace('/')
}
}
} else if (enabled && is_registered) {
getUnreadTongzhis();
}
}
if (enabled && is_registered && to.path !== '/' && to.path !== '/org/select') {
const authToken = window.localStorage.getItem(HtyAuthToken);
const tokenOrgId = parseCurrentOrgIdFromToken(authToken);
if (!tokenOrgId) {
const organizations = await loadMyOrgs();
if (organizations.length === 1) {
const switched = await switchOrg(organizations[0].id);
if (!switched) {
next(false);
return;
}
const currentAuthToken = window.localStorage.getItem(HtyAuthToken);
if (currentAuthToken) {
window.localStorage.setItem(HtySudoToken, currentAuthToken);
}
await loadMyDepartments();
if (orgStore.departments.length === 1 && orgStore.currentDepartmentId) {
await switchDepartment(orgStore.currentDepartmentId);
}
} else if (organizations.length > 1) {
await router.replace('/org/select');
next();
return;
}
} else if (!orgStore.currentOrgId) {
window.localStorage.setItem(CurrentOrgId, tokenOrgId);
orgStore.currentOrgId = tokenOrgId;
}
if (orgStore.currentOrgId && orgStore.departments.length === 0) {
await loadMyDepartments();
if (orgStore.departments.length === 1 && orgStore.currentDepartmentId) {
await switchDepartment(orgStore.currentDepartmentId);
}
}
}
let {stopTimer} = useTimer()
stopTimer();
if (to.path.endsWith("/profile") && store.currentRole && !to.path.includes(store.currentRole.toLowerCase())) {
await router.replace("/" + store.currentRole.toLowerCase() + "/profile")
}
next();
} catch (e: any) {
window.localStorage.setItem('__guardError', e?.message || String(e));
next();
}
})
createApp(App).use(router).use(weixin).mount('#app')