import { inject } from '@angular/core'; import { CanActivateFn, Router } from '@angular/router'; import { FmodeApi } from './api/fmode-api'; import { SessionService } from './session.service'; /** 无组织用户停留的等待页路径 */ export const PENDING_PATH = '/pending'; /** * 组织归属守卫(2026-11-10) * * ## 为什么要它 * * App 原本只判「登录了没」,不判「有没有组织」—— 没有组织的账号 * 照常进入,看到的是一堆空列表,用户分不清是没权限还是真没数据。 * * ## 🔴 为什么不能只看 `me.companyId` * * 实测(2026-11-10):新用户注册时,系统会**自动创建一个以他命名的组织** * (如 liujun 的组织就叫「liujun」),并写入 `enterpriseTrialClaimedAt`。 * 所以「有 companyId」≠「被组织接纳」。 * * 真正的判定在服务端(`fmodeagent-users.js` 的 `opMe`): * ① 组织带 `enterpriseTrialClaimedAt`(个人试用组织) * ② 且该组织里只有他一个人 * → 两项都满足,视为**无组织**。 * * ## 与 `authGuard` 的关系 * * 必须排在 `authGuard` 之后(`canActivate: [authGuard, orgGuard]`)。 * `/login` 与 `/pending` 自身**不得**挂本守卫,否则自我重定向死循环。 */ export const orgGuard: CanActivateFn = async (_route, state) => { const session = inject(SessionService); const api = inject(FmodeApi); const router = inject(Router); // 未登录交给 authGuard,这里不重复判 if (!session.isLoggedIn()) return true; const hasOrg = await queryHasOrg(api); if (hasOrg) return true; return router.createUrlTree([PENDING_PATH], { queryParams: { redirect: state.url } }); }; /** * 询问服务端「我有没有真正的组织」。 * * 🔴 查询失败按**放行**处理:判成无组织会让所有人卡在等待页,风险更大; * 放行后页面自身的错误态会如实提示。 */ export async function queryHasOrg(api: FmodeApi): Promise { try { const m = await api.fetchOrgMembership(); return m.hasOrg; } catch { return true; } }