This commit is contained in:
oneao committed 2026-10-13 22:32:50 +08:00
1 parent f3936cec61
commit 15e0ae5b67
115 files changed
+11399 -2741

No files matched your search

@@ -0,0 +1,86 @@
/* ============================================================================
表格测试菜单(s_menu)—— 根菜单项
用途:把原「海运 → 订舱单」(/ocean/booking)整页搬迁为独立测试页后,
在 s_menu 里挂一个**一级(根)菜单**指向它,与前端路由
/table-test(见 web/src/router/index.ts 的 protectedRoutes)一一对应。
背景:本仓库的侧栏菜单已改为**动态**(读 s_menu,对照 fms-vue)——
前端静态路由只声明「有哪些页面组件」,是否出现在侧栏、叫什么名字由 s_menu 决定。
因此新增页面必须同时做两件事:
1. 加一条静态路由(前端代码)
2. 在 s_menu 里录一条菜单(本脚本)
说明:
1. 幂等:菜单按 b_id 判断存在性,重复运行无副作用。
2. 权限:本脚本默认**不建权限点**。侧栏可见性与路由进入由 menu.{菜单编码} 授权控制,
而权限 store 对 g3soft 账号提权(一切放行),故用 g3soft 登录即可看到本菜单。
若要让普通账号也能看到,请另行执行本文件末尾「可选:给普通账号授权」那段
(建 s_power(menu.table_test) + s_user_power 授权),否则非管理员账号的侧栏
会因白名单语义**不显示**该菜单(这是预期行为,不是 bug)。
3. 排序:b_xh = 1,让它排在「审批中心(5)」「基础资料(10)」「系统管理(10)」等之前,
作为根菜单下的第一项。
4. b_parent_id 为 null 即根节点;b_depth = 0。
5. b_path 约定:节点编码前后均带 /,根级为 /table_test/(与 FMS 树结构规范一致)。
============================================================================ */
if not exists (select 1 from dbo.s_menu where b_id = 'table_test')
begin
insert into dbo.s_menu (b_id, b_parent_id, b_depth, b_path, b_name, b_i18n, b_menu_type, b_route, b_icon, b_xh, b_canuse)
values ('table_test', null, 0, '/table_test/', N'表格测试', 'menu.table_test', 'page', '/table-test', 'table', 1, 1);
end
GO
/* ----------------------------------------------------------------------------
多语言(s_i18n):菜单名,默认语言为中文时写入中文值。
已存在同键同语言的行不覆盖(人工翻译优先)。
---------------------------------------------------------------------------- */
declare @i18n table (k varchar(150) primary key, v nvarchar(1000) not null);
insert into @i18n (k, v) values
('menu.table_test', N'表格测试');
insert into dbo.s_i18n (b_key, b_locale, b_value, b_canuse)
select i.k, t.b_id, i.v, 1
from @i18n i
cross join (select b_id from dbo.s_i18n_type where b_default = 1) t
where not exists (select 1 from dbo.s_i18n x where x.b_key = i.k and x.b_locale = t.b_id);
GO
/* ----------------------------------------------------------------------------
自检
---------------------------------------------------------------------------- */
select '菜单' as 项, count(*) as 行数 from dbo.s_menu where b_id = 'table_test'
union all
select '多语言', count(*) from dbo.s_i18n where b_key = 'menu.table_test';
GO
/* ============================================================================
可选:给普通账号授权(默认注释掉,按需启用)
权限点是白名单语义:s_power 里没有 menu.table_test、或用户没被授权,
侧栏就不显示该菜单、路由守卫也会拦到 /403。
g3soft 超管不受此限(前后端都对其提权),所以调试时可先用 g3soft 登录。
启用前请把 'demo_zhangwei' 换成目标账号;若该机构库尚未建 s_power /
s_user_power 表,请先建表再执行。
============================================================================ */
/*
-- 1) 权限点:menu.table_test
if not exists (select 1 from dbo.s_power where b_id = 'menu.table_test')
begin
insert into dbo.s_power (b_id, b_name, b_type, b_canuse, b_xh, b_object_type, b_object_id, b_action, b_i18n)
values ('menu.table_test', N'表格测试', 'menu', 1, 10, 'menu', 'table_test', 'access', 'menu.table_test');
end
GO
-- 2) 授权:把权限点授给指定账号
if not exists (select 1 from dbo.s_user_power where b_user_id = 'demo_zhangwei' and b_power_id = 'menu.table_test')
begin
insert into dbo.s_user_power (b_user_id, b_power_id, b_canuse, b_created_by, b_created_at)
values ('demo_zhangwei', 'menu.table_test', 1, 'g3soft', sysutcdatetime());
end
GO
*/
@@ -0,0 +1,39 @@
/* ============================================================================
首页菜单(s_menu)—— 根菜单项
用途:登录后的默认落地页(前端 router 的 HOME_PATH = /dashboard)。
本次与原「表格测试」菜单一起补上:页面路由必须先存在,菜单才点得通。
说明:
1. 幂等:菜单按 b_id 判断存在性,重复运行无副作用。
2. 排序:b_xh = 0,排在「表格测试(1)」之前,作为根菜单第一项。
3. b_parent_id 为 null 即根节点;b_depth = 0;
b_path 约定节点编码前后均带 /,根级为 /dashboard/。
4. 权限:不建权限点。g3soft 超管提权可见;普通账号需另配
s_power(menu.dashboard) + s_user_power,做法见 13_table_test_menu.sql 末尾注释。
============================================================================ */
if not exists (select 1 from dbo.s_menu where b_id = 'dashboard')
begin
insert into dbo.s_menu (b_id, b_parent_id, b_depth, b_path, b_name, b_i18n, b_menu_type, b_route, b_icon, b_xh, b_canuse)
values ('dashboard', null, 0, '/dashboard/', N'首页', 'menu.dashboard', 'page', '/dashboard', 'layout-dashboard', 0, 1);
end
GO
/* ----------------------------------------------------------------------------
多语言(s_i18n):菜单名。已存在同键同语言的行不覆盖(人工翻译优先)。
---------------------------------------------------------------------------- */
declare @i18n table (k varchar(150) primary key, v nvarchar(1000) not null);
insert into @i18n (k, v) values
('menu.dashboard', N'首页');
insert into dbo.s_i18n (b_key, b_locale, b_value, b_canuse)
select i.k, t.b_id, i.v, 1
from @i18n i
cross join (select b_id from dbo.s_i18n_type where b_default = 1) t
where not exists (select 1 from dbo.s_i18n x where x.b_key = i.k and x.b_locale = t.b_id);
GO
select '菜单' as 项, count(*) as 行数 from dbo.s_menu where b_id = 'dashboard';
GO
+38
View File
@@ -20,6 +20,8 @@
| 4 | `20_registration/10_fms_workflow_module.sql` | 4 个只读视图 + `s_module` / `s_field` / `s_module_schema` / `s_menu_module` 注册 | 是(先删后建) |
| 5 | `20_registration/11_fms_workflow_menu.sql` | 流程管理 / 审批中心菜单 + `s_i18n` | 是 |
| 6 | `20_registration/12_fms_workflow_power.sql` | 菜单权限点 + 动作权限点 + 授予 `g3soft` | 是 |
| 6.5 | `20_registration/13_table_test_menu.sql` | 表格测试根菜单(`/table-test`)+ `s_i18n` | 是 |
| 6.6 | `20_registration/14_dashboard_menu.sql` | 首页根菜单(`/dashboard`)+ `s_i18n` | 是 |
| 7 | `30_patches/01_fms_workflow_index_patch.sql` | 补充索引(见下) | 是 |
| 8 | `90_mock/01_fms_workflow_mock.sql` | **示例**流程定义 `expense_approval`(14 节点 / 17 连线 / 13 审批人规则) | 否 |
| 9 | `90_mock/02_fms_workflow_runtime_mock.sql` | **示例**运行数据:演示机构/用户 + 6 个实例 | 否 |
@@ -71,6 +73,42 @@ select distinct b_module_id from dbo.wf_binding where b_canuse = 1
- **审计探写**:`WorkflowAuditWriter` 每事务探测 `s_log_audit` 是否存在;不存在时写一条
`wf_outbox(audit.skipped)` 并继续。**库里没有审计表不算故障**,不会阻断审批。
## 菜单现在是动态的(第 6.5 步的背景)
前端侧栏菜单已改为**动态**:读 `s_menu` 表构建菜单树(对照 fms-vue 的 `stores/menus.js`
+ `AppSidebar`),不再使用前端常量菜单。因此**新增页面必须两步都做**:
1. 在前端加一条静态路由(`web/src/router/index.ts`,数据库存不了 Vue 组件);
2. 在 `s_menu` 里录一条菜单(决定是否出现在侧栏、叫什么、排第几)。
`13_table_test_menu.sql` 就是第 2 步的示例:把「表格测试」页挂成**根菜单**,路由 `/table-test`。
**权限是白名单语义**:`s_power` 里没有 `menu.{菜单编码}`、或用户未被授权,侧栏就**不显示**该菜单、
路由守卫也会拦到 `/403`。`g3soft` 超管前后端都提权、不受此限,调试时先用它登录最省事;
要给普通账号开放,用该脚本末尾注释掉的「可选:给普通账号授权」那段。
### ⚠️ 菜单与路由必须成对,否则点进去是 404
**`s_menu` 里有 `b_route` 的每一条页面菜单,前端都必须有一条 path 完全相同的静态路由。**
少一条,点击该菜单就会落到 router 末尾的 `/:pathMatch(.*)*` 通配路由 → 显示 404 缺省页。
实测过的坑:只给已实现的页面建路由、其余菜单不建,会表现为「**菜单点进去全是 404**」——
而 Vite dev server 对任意路径都返回 HTTP 200(SPA fallback),所以浏览器网络面板里
**看不到 404 状态码**,容易误判成后端或代理问题。真正的判据是**路由是否匹配**,不是 HTTP 状态。
当前 `s_menu` 的 13 条页面菜单与前端路由已逐条对齐:
| s_menu `b_route` | 页面 | 状态 |
|---|---|---|
| `/dashboard` | 首页 | 占位(`views/dashboard/index.vue`) |
| `/table-test` | 表格测试 | **已实现**(G3Table 完整范例) |
| `/approval/todo`、`/initiated`、`/done`、`/cc` | 审批中心 | 占位 |
| `/base/othercompany`、`/contact`、`/otherdata` | 基础资料 | 占位 |
| `/system/user`、`/system/workflow`、`/system/log/login`、`/system/log/audit` | 系统管理 | 占位 |
占位页统一复用 `web/src/components/PlaceholderPage.vue`:把真实页面写进对应视图文件即可,
**路由与菜单都不用再改**。
## 补充索引说明(第 7 步)
| 索引 | 解决什么 |