t14:前端模块行退役——左导航三支路自解析、AppContext 重构为通用壳两视图

- App.vue:引导只剩 GetUserInfo,之后并行取 fillable/managed/capabilities 三支构造导航
  (取不到按空集/false 走,fail-closed,不造兜底菜单树);摘 GetUserMod 调用与 setModules
- store:modules/IModule 状态与 setModules 删除,改存三支路数据 + managesForm() 判"这张表我管不管得动"
- AppContext.vue:重写为通用壳两视图(§5.1)——管理员视图=数据列表+复制填报路径
  (添加/导入 T18 接进这一档),填报者视图=仅填报 tab;判定只看 managed 是否非空,
  壳零自有权限逻辑;GetUserMod?appCode= 拉目标应用树那一路与 :modules prop 链整条拆除
- Data.vue:导出按钮改"该表单 ALL 档(managed 成员)",中心与快应用两种上下文从此同一条判据;
  AnswerDetail.vue 的管理动作区同判据;utils/modulePerms.ts(canExport/hasPage)删除
- utils/menuNav.ts:buildNavTree 与"从树渲染菜单"三条规则删除,只留导航数据结构与
  高亮/面包屑/默认跳转;menuRoute 的 /f/{code} 形态识别按任务书保留(分享直链/历史链接)
- mock:baseapi 去 GetUserMod 与两棵模块树;dataapi 补 /my/managed 与 /my/capabilities 桩
This commit is contained in:
chenxing
2026-10-20 13:21:23 +08:00
parent 4a7db3d22c
commit 6401a69c18
12 changed files with 324 additions and 472 deletions
+8 -19
View File
@@ -1,14 +1,16 @@
import { alovaInstance } from "@/utils/alova/alova-iview";
import type { IModule } from "@/types/Basics";
import type { SchoolTreeNode } from "@/types/admin";
/**
* 基础平台接口(notice/front 的 api/module 形态 + flow-center base.ts 同构):
* 用户信息与已授权模块列表(左导航数据源)。
* 基础平台接口(notice/front 的 api/module 形态 + flow-center base.ts 同构)。
*
* 模块行在 UserBase 按本应用(app_code=form-center)配置,path 须逐字对上
* router/routes.ts(手册 §2.2 表 v1.5 五行版)。数据范围升级位不再挂在模块行上:
* T10 起由后端管理员两表(school_admin / form_admin)承载,前端只在 /admin/app 的角色设置 tab 维护它。
* 契约 v2 §2.4 之后只剩两把:
* - `getUserInfo`:会话用户本体,App.vue 引导的唯一请求;
* - `getSchoolAll`:本校组织树(教师版),管理员两表选人弹窗的数据源。
*
* **`getUserMod` 已随 UserBase 模块行整条退役而删除**(§19 作废-10):左导航改由三支路自解析
* (`/api/form/my/fillable`、`/api/form/my/managed`、`/api/form/my/capabilities`),
* B14 缺口与跨项目触点 H4 一并消失。
*
* 写法与 Notice 的一处差异:Notice 用 `new Method<T>(...)`,而 alova 3.5 的 Method 第一个
* 泛型位是 AlovaGenerics(不是响应类型),strict vue-tsc 下报 TS2344;本端改用实例方法
@@ -22,19 +24,6 @@ class BaseApi {
return alovaInstance.Get(`${BASE}/GetUserInfo`);
}
/**
* 当前用户已授权的模块树(左侧菜单数据源)。
*
* @param appCode 可选目标应用(快应用上下文 /app/{appCode}/ 要的是<b>那个应用</b>的树,
* 参数名按执行手册 §5 P2 定稿 appCode)。UserBase 侧 H4 未上线时后端
* 返回空树并打 warn——前端据此显示空导航,<b>不得回落本应用树</b>(P3 裁决)。
*/
getUserMod(appCode?: string) {
return alovaInstance.Get<IModule[]>(`${BASE}/GetUserMod`, {
params: appCode ? { appCode } : undefined
});
}
/**
* 本校组织树(教师版)——选人弹窗 UserCheckModal 的 loader,形态同 notice。
* 没有 schId 入参:域只从会话推导,因此候选天然限在本校树里(跨校的人在接口层就给不出来)。
+16 -1
View File
@@ -6,7 +6,7 @@
*/
import { alovaInstance } from "@/utils/alova/alova-iview";
import type { ResolvedForm, SubmitRequest, SubmitView, MyAnswerItem } from "@/types/answer";
import type { AnswerDetail, FillableForm, MyAnswerViewItem } from "@/types/data";
import type { AnswerDetail, Capabilities, FillableForm, ManagedForm, MyAnswerViewItem } from "@/types/data";
/** 解析当前发布版本(契约 §1:入口寻址) */
export function resolveForm(code: string, appCode?: string) {
@@ -67,3 +67,18 @@ export function listFillableForms(appCode?: string) {
if (appCode) params.appCode = appCode;
return alovaInstance.Get<FillableForm[]>("/api/form/my/fillable", { params }).send();
}
// ==================== 菜单自解析另两支路(契约 v2 §2.4/D5,T14) ====================
// 三支路的后两支:我管理的表单(C3)与能力位(校管理员)。前端不自行判权,只消费这三把接口。
/** 我管理的表单(创建人 ∪ 表单管理员;role 标出来源) */
export function listManagedForms(appCode?: string) {
const params: Record<string, string> = {};
if (appCode) params.appCode = appCode;
return alovaInstance.Get<ManagedForm[]>("/api/form/my/managed", { params }).send();
}
/** 能力位:只回答"要不要给这个人画系统设置入口",不是权限 */
export function getMyCapabilities() {
return alovaInstance.Get<Capabilities>("/api/form/my/capabilities").send();
}