| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859 |
- 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<boolean> {
- try {
- const m = await api.fetchOrgMembership();
- return m.hasOrg;
- } catch {
- return true;
- }
- }
|