From 8734b43a2a0ca3cbb933363b978571ae9dadb324 Mon Sep 17 00:00:00 2001 From: ZhangAo Date: Tue, 8 Sep 2026 17:03:59 +0800 Subject: [PATCH] 20260908170359 --- code/fms/.tmp-doc.js | 10 + code/fms/.tmp-dom.html | 30 + code/fms/.tmp-panel.html | 109 ++ code/fms/.tmp-replace.js | 14 + code/fms/.tmp-shot.png | Bin 0 -> 107839 bytes code/fms/.tmp-smoke.js | 23 + code/fms/FMS新系统核心表结构设计.md | 20 +- code/fms/FMS权限设计.md | 337 ++++++ code/fms/demo.html | 876 +++++++++++++- .../src/components/ui/button/index.scss | 11 +- .../fms/fms-vue/src/views/dashboard/index.vue | 548 ++++++--- code/fms/fms-vue/src/views/login/index.vue | 9 +- code/fms/字段权限与用户个性化设计.md | 1020 +++-------------- code/fms/开发规范.md | 12 + 14 files changed, 1956 insertions(+), 1063 deletions(-) create mode 100644 code/fms/.tmp-doc.js create mode 100644 code/fms/.tmp-dom.html create mode 100644 code/fms/.tmp-panel.html create mode 100644 code/fms/.tmp-replace.js create mode 100644 code/fms/.tmp-shot.png create mode 100644 code/fms/.tmp-smoke.js create mode 100644 code/fms/FMS权限设计.md diff --git a/code/fms/.tmp-doc.js b/code/fms/.tmp-doc.js new file mode 100644 index 00000000..49d21b0d --- /dev/null +++ b/code/fms/.tmp-doc.js @@ -0,0 +1,10 @@ +const fs = require('fs'); +const file = 'd:/workspace/code/fms/FMS权限设计.md'; +const content = fs.readFileSync(file, 'utf8'); + +const oldPoints = '- 第一列是**模块树**,缩进 + 展开 + 父子半选\n- `page` 节点只配入口,权限列置灰(不直接对应数据表)\n- 动作全在一列,全部默认拒绝,勾选即授权;业务动作与基础操作 chip 同样式\n- **字段是模块行的展开子行**,且只显示**敏感字段 + 字段组**,默认折叠\n- 数据范围是一列,跟着模块走("仅本人"与"禁止删除"是同频操作,不该分开放)'; +const newPoints = '- **顶部用户条**横排选人 + 角色模板 + 批量多选\n- **左:模块树**只负责导航选择,节点带配置数 badge;树顶有「全部模块」概览入口\n- **右:权限面板** 4 个分区(入口 / 动作 / 数据范围 / 敏感字段),只配置当前选中模块\n- 面板内的字段**只显示 IT 标记的敏感字段**\n- 数据范围是面板内一段,不是独立分区(与「增删改」同频)'; + +if (content.indexOf(oldPoints) < 0) { console.log('STILL NOT FOUND'); process.exit(1) } +fs.writeFileSync(file, content.replace(oldPoints, newPoints), 'utf8'); +console.log('OK'); \ No newline at end of file diff --git a/code/fms/.tmp-dom.html b/code/fms/.tmp-dom.html new file mode 100644 index 00000000..5cc2a10a --- /dev/null +++ b/code/fms/.tmp-dom.html @@ -0,0 +1,30 @@ + + + + +FMS 权限中心 · 一屏授权 + + + + + +
F
FMS 权限中心
一客户一库 · 权限点自动生成
IT
系统管理员
客户库:DEMO-FWD
授权对象

费用管理

cw_fee

张三 · 全部默认拒绝,勾选即授权
入口
已开通menu.cw_fee.access
动作
数据范围
未配置视为全部数据
敏感字段
金额amount已收紧
内部成本internal_cost已收紧
毛利gross_profit已收紧
+ + +
+ + + diff --git a/code/fms/.tmp-panel.html b/code/fms/.tmp-panel.html new file mode 100644 index 00000000..82977c89 --- /dev/null +++ b/code/fms/.tmp-panel.html @@ -0,0 +1,109 @@ + +
+ + +
+
+

全部模块概览

+

{{ curUser.name }} · 点模块名进入详细配置

+
+ + + + + + + + + + + + + + + + + +
模块入口已授权动作数据范围
+
{{ m.name }}
+
{{ m.id }}
+
+ + + 未授权(默认拒绝) + + {{ a }} + + + {{ scopeName(scopeOf(m.id)) }} +
+
+ + +
+
+
+

{{ selName }}

+

{{ state.selected }}

+
+ page 节点 + {{ curUser.name }} · 全部默认拒绝,勾选即授权 +
+ + +
+
入口
+ + {{ hasEntry(state.selected) ? '已开通' : '未开通' }} + {{ entryCode }} +
+ + +
+
动作
+
+ +
+
+
页面节点只配入口,具体操作在下属模块上配置
+ + +
+
数据范围
+ + 未配置视为全部数据 +
+ + +
+
敏感字段
+
+
该模块没有标记敏感字段,无需配置字段权限
+
+
+ {{ f.l }}{{ f.n }} + + + + 已收紧 + 默认 +
+
+
+
+
diff --git a/code/fms/.tmp-replace.js b/code/fms/.tmp-replace.js new file mode 100644 index 00000000..141c692e --- /dev/null +++ b/code/fms/.tmp-replace.js @@ -0,0 +1,14 @@ +const fs = require('fs'); +const file = 'd:/workspace/code/fms/demo.html'; +const panelFile = 'd:/workspace/code/fms/.tmp-panel.html'; +const lines = fs.readFileSync(file, 'utf8').split('\n'); +const panel = fs.readFileSync(panelFile, 'utf8').replace(/\n$/, '').split('\n'); + +// 替换第 108..211 行(1-based)为新的权限面板;保留第 212 行的
+const before = lines.slice(0, 107); +const after = lines.slice(211); +console.log('第108行原内容:', JSON.stringify(lines[107])); +console.log('第211行原内容:', JSON.stringify(lines[210])); +console.log('第212行原内容:', JSON.stringify(lines[211])); +fs.writeFileSync(file, before.concat(panel).concat(after).join('\n'), 'utf8'); +console.log('done, total lines:', before.length + panel.length + after.length); diff --git a/code/fms/.tmp-shot.png b/code/fms/.tmp-shot.png new file mode 100644 index 0000000000000000000000000000000000000000..67f9185302004c2261ea8d6c5739dd02ddd19c00 GIT binary patch literal 107839 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 literal 0 HcmV?d00001 diff --git a/code/fms/.tmp-smoke.js b/code/fms/.tmp-smoke.js new file mode 100644 index 00000000..262f04cc --- /dev/null +++ b/code/fms/.tmp-smoke.js @@ -0,0 +1,23 @@ +const { execFileSync } = require('child_process'); +const fs = require('fs'); +const exe = 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe'; +const shot = process.argv[2] === 'shot'; +let out = ''; +try { + out = execFileSync(exe, ['--headless=new', '--disable-gpu', '--no-sandbox', '--hide-scrollbars', + '--window-size=1680,1400', '--virtual-time-budget=12000', + shot ? '--screenshot=d:/workspace/code/fms/.tmp-shot.png' : '--dump-dom', + 'file:///d:/workspace/code/fms/demo.html'], { maxBuffer: 64 * 1024 * 1024 }).toString(); +} catch (e) { out = String(e.stdout || ''); console.log('ERR', String(e.stderr || '').slice(0, 400)) } +if (shot) { console.log('shot ok'); process.exit(0) } +fs.writeFileSync('d:/workspace/code/fms/.tmp-dom.html', out, 'utf8'); +console.log(JSON.stringify({ + len: out.length, + vueWarn: out.indexOf('[Vue warn]') > -1, + hasTreeAside: out.indexOf('模块树') > -1, + hasPanel: out.indexOf('敏感字段') > -1, + hasUserBar: out.indexOf('授权对象') > -1, + hasOverview: out.indexOf('全部模块(概览)') > -1, + hasOldTable: out.indexOf('min-w-[1000px]') > -1, + hasError: out.indexOf('Uncaught') > -1 +}, null, 2)); diff --git a/code/fms/FMS新系统核心表结构设计.md b/code/fms/FMS新系统核心表结构设计.md index beb96e6a..6d5d41fa 100644 --- a/code/fms/FMS新系统核心表结构设计.md +++ b/code/fms/FMS新系统核心表结构设计.md @@ -3,6 +3,16 @@ > 目标结构基于 2026-09-04 只读拉取的 `FMS-NEW` 数据库整理。 > 平台配置使用字符串业务键;未来业务数据表使用 `bigint` 雪花 ID。 +## 0. SQL 驱动与动态配置 + +本系统是 SQL 驱动的内部 ERP。能通过 SQL 完成的查询、关联、过滤、排序、分页、聚合、权限过滤和数据范围过滤,优先在 SQL 层完成,不在业务代码中加载大量数据后再处理。 + +- 模块、字段、查询条件、排序、字段权限和数据范围等规则,优先从本文件定义的配置表读取,由通用查询逻辑动态生成 SQL; +- 动态 SQL 的表名、字段名和操作符只能来自受控的模块元数据、字段定义和白名单,业务值使用参数传递; +- 配置驱动的动态 SQL 不等于保存任意 SQL 字符串。不得把未审查的前端字符串或整段 SQL 直接保存后执行; +- 固定 SQL 仅用于稳定且明确的特殊业务逻辑,且应保持通用,不为单个页面或单个用户复制一套查询接口; +- 前端权限控制只负责界面展示,模块操作、字段访问和数据范围必须在后端查询或写入 SQL 中落实;用户个性化只能调整布局,不能放宽权限。 + ## 1. 用户表 ```sql @@ -345,11 +355,13 @@ create index ix_s_user_data_scope_module 权限计算约定: -- 默认拒绝:用户没有有效授权记录时不具备该权限; -- 用户存在有效 `s_user_power` 记录时获得该权限;停用的权限点或授权记录不生效; -- 字段没有有效策略记录时为 `hidden`;`view` 表示可见只读,`edit` 表示可见可编辑;`s_field_view` / `s_field_edit` 等元数据只能收紧权限; +- 入口权限默认拒绝:`menu/access`、`page/access`、`report/access` 和 `action/execute` 必须存在有效的 `s_user_power` 授权记录;停用的权限点或授权记录不生效; +- 模块操作权限默认放行:`module/read|create|update|delete|export` 没有用户授权记录时视为允许;`s_power` 权限点或用户授权记录存在 `b_canuse = 0` 时视为明确禁用; +- 字段没有有效用户策略记录时不增加限制,按 `s_field`、`s_field_view`、`s_field_edit`、`s_field_query` 等模块默认配置执行;有效的 `s_user_field_permission` 只能收紧权限;`hidden` 表示不可见,`view` 表示可见只读,`edit` 表示可见可编辑; - `hidden` 字段不可查询、不可导出;`b_allow_query` / `b_allow_export` 不能突破字段访问级别; -- 模块数据操作权限与数据范围同时生效:先判断操作权限,再按 `s_user_data_scope` 限制数据行; +- 模块数据操作权限与数据范围同时生效:先判断操作权限,再按 `s_user_data_scope` 限制数据行;数据范围没有配置时视为 `all`; +- 数据范围优先使用当前操作的 `override`,没有 `override` 时使用 `operation = '*'` 的 `default`;同一层级的多条范围按 OR 合并; +- `read`、`export`、`update`、`delete` 在 SQL 行条件中应用数据范围;`create` 在写入前校验新增数据是否符合数据范围; - 菜单/页面/报表访问权限只控制入口和访问,不能替代模块、字段或数据范围权限。 ## 9. 多语言 diff --git a/code/fms/FMS权限设计.md b/code/fms/FMS权限设计.md new file mode 100644 index 00000000..8ad205f2 --- /dev/null +++ b/code/fms/FMS权限设计.md @@ -0,0 +1,337 @@ +# FMS 权限设计 + +> 本文是权限部分的**定稿设计**,以《FMS新系统核心表结构设计.md》的表结构为基础,替代《字段权限与用户个性化设计.md》中与本文冲突的表述(差异见第 8 节)。 +> 用户个性化(`s_user_field_pref`、`s_user_query_field_pref`)不在本文范围内,后续单独处理。 + +## 0. 设计定位 + +### 0.1 系统特征(决定设计取向的前提) + +| 特征 | 现状 | 对权限设计的影响 | +| --- | --- | --- | +| 部署方式 | **一客户一数据库** | 权限点只需在本库内唯一,编码不带租户前缀;不存在跨租户数据串户风险 | +| 架构 | 元数据驱动(`s_module` / `s_field` / `s_field_view` …) | 权限点必须**自动生成**,不能手工维护清单 | +| 客户可定制 | 可加模块、加字段 | 权限点需要**增量同步**机制 | +| 客户规模 | 中小货代,多数无专职 IT | 模型必须简单到客户管理员能自行配置 | +| 用户规模 | 几十 ~ 几百 | 不需要 SAP 级别的授权对象模型 | + +### 0.2 结论:对应用友 / 金蝶的三层模型 + +**认知模型对标用友 / 金蝶**(功能权限 / 数据权限 / 字段权限 + 角色),理由不是技术最优,而是**客户和实施顾问无需学习成本**,且规模匹配。 + +**不采用**: + +- SAP 授权对象模型(为跨国集团设计,规模不匹配,交付成本高) +- Salesforce 四层共享模型(Profile + Permission Set + OWD + Sharing,计算复杂) +- 通用权限框架 / ABAC / 运行时策略引擎(明确不做) + +**借鉴两点**: + +- 权限点自动生成(Salesforce 思路,利用本系统元数据驱动的优势) +- 数据范围支持选择多个组织节点(CargoWise 的 Branch 思路,覆盖"只看上海 + 深圳分公司") + +--- + +## 1. 权限模型 + +### 1.1 四类权限 + +| 类别 | 回答的问题 | 载体 | 默认策略 | +| --- | --- | --- | --- | +| **入口** | 能不能进 | `menu` / `page` / `report` | 默认拒绝 | +| **动作** | 能不能做 | `module..` | 全部默认拒绝(权限就是权限) | +| **字段** | 能看/改哪些列 | `s_user_field_permission` | 跟随模块默认,只收紧 | +| **数据范围** | 能看哪些行 | `s_user_data_scope` | 未配置视为 `all` | + +### 1.2 入口 ≠ 动作 + +- **入口**是一维的:能不能打开(菜单可见、页面可访问)。勾了"能进费用管理"**不代表**能改数据。 +- **动作**是多维的:对某个模块能做什么。 + +两者互不继承,符合《核心表结构》"菜单权限不自动授予模块权限"的约定。 + +### 1.3 权限就是权限 + +不区分「内置动作」与「业务动作」。查看 / 新增 / 修改 / 删除 / 导出、审核 / 核销 / 关闭 / 作废等都是同一种**动作权限**,只有「勾选」与「未勾选」两种状态。 + +| 状态 | 含义 | +| --- | --- | +| 勾选 | 有 `s_user_power` 授权记录(`b_canuse = 1`) | +| 未勾选 | 无授权记录 = 拒绝 | + +**全部动作统一默认拒绝**。简化点: + +- 一种存储:只存「授权记录」,没有「禁止记录」 +- 一种默认策略:未勾选 = 拒绝 +- 一种行为:勾选即授权 + +> 客户不能新建动作权限点——业务动作需要对应的后端代码,客户建了也无效。客户界面只提供勾选。 + +### 1.4 角色(可选层) + +采用**主角色 + 个人例外**两层,不做角色继承角色: + +``` +用户 → 主角色(继承,只有一个)+ 个人例外(覆盖角色中的少数项) +``` + +- 新员工入职 = 选一个角色 +- 个别人特殊 = 加几条例外 +- 改角色 = 该角色所有人跟着变(与 SAP / 用友行为一致) +- 查询只有两层,不是无限递归 + +角色不是强制项:不引入角色也能用(直接给用户配),但引入后配置量大幅下降。产品内置「货代标准权限包」(操作员 / 客服 / 费用会计 / 财务经理 / 只读查询),实施时导入客户库后微调。 + +--- + +## 2. 权限点编码规范 + +| 类型 | 编码 | 示例 | +| --- | --- | --- | +| 菜单入口 | `menu..access` | `menu.cw_fee.access` | +| 页面入口 | `page..access` | `page.sea_detail.access` | +| 报表入口 | `report..access` | `report.cw_fee_summary.access` | +| 内置动作 | `module..` | `module.cw_fee.delete` | +| 业务动作 | `module..` | `module.cw_fee.audit` | + +规则: + +- 全部小写,点分分隔;`` 用 `s_module.b_id` +- **一客户一库,编码在本库内唯一即可**,不加租户前缀 +- 权限点由系统生成,**不允许手工新增业务动作** +- `s_power.b_code` 是稳定业务键;`s_power.b_id` 是内部主键,业务代码只依赖 `b_code` + +### 与旧模型的差异 + +| 项 | 旧(`b_user_power` / `s_module_power`) | 本文 | +| --- | --- | --- | +| 权限点标识 | `${module_id}.${雪花ID}`,跨环境 ID 不同,配置无法迁移 | 语义化 `b_code`,可跨环境迁移 | +| 动作编码 | `action.module.xx.yy.execute` | `module.xx.yy` | + +> 现有 `stores/permissions.js` 依赖旧表(`b_user_power` / `s_module_power`),迁移到新模型后需同步改造(见第 6 节)。 + +--- + +## 3. 权限点的自动生成与升级同步 + +### 3.1 生成规则 + +| 来源 | 生成内容 | +| --- | --- | +| `s_module` 模块 | `menu..access` + 5 个内置动作 | +| `s_module` 中 `b_module_type = 'page'` 的节点 | `page..access`(仅"需要独立入口控制"的页面) | +| 报表定义 | `report..access` | +| 开发注册的业务动作 | `module..` | + +### 3.2 增量同步三原则 + +产品升级或客户新增模块后需要补权限点,同步逻辑必须幂等: + +1. **只增不删** —— 不删除已有权限点(删了会丢客户配置) +2. **不覆盖已有配置** —— 客户主动停用的 `b_canuse = 0` 不被重置 +3. **废弃置 `b_canuse = 0`** —— 不物理删除,保留历史可追溯 + +### 3.3 客户自定义字段的权限 + +客户新增字段(如"拖车费")默认跟随模块默认配置,即**全员可见可编辑**。 + +防泄漏建议(低优先级,可后置): + +- 新增字段时,字段名命中 `cost / price / amount / profit / 成本 / 价` 等关键词 → 提示是否标记为敏感字段 +- 提供「敏感字段体检」:列出金额类型但未标记敏感的字段供确认 + +--- + +## 4. 权限计算顺序 + +一次页面访问或接口调用按顺序计算: + +1. 用户账号与对应资源是否启用 +2. **入口**:菜单 / 页面 / 报表是否有有效授权(默认拒绝) +3. **动作**:当前动作是否被允许 + - 内置动作:无记录即放行;`b_canuse = 0` 明确禁止 + - 业务动作:必须有有效授权记录 +4. **字段**:按模块字段元数据 + 用户字段策略裁剪(只收紧) +5. **数据范围**:`override` → `default` → `all`,同层多条 OR 合并,生成 SQL 行条件 +6. 角色层:用户例外覆盖角色配置 + +> 页面显示与接口执行必须用同一套规则。前端可提前隐藏,但**最终以后端 SQL 为准**(《开发规范》第 10、23 条)。 + +--- + +## 5. 后端落实 + +### 5.1 统一拦截点 + +通用数据接口是唯一的 SQL 出入口,权限在此单点落实: + +| 接口 | 对应动作 | 需落实 | +| --- | --- | --- | +| `/data/loaddata` | read | 动作校验 + 数据范围 WHERE + 字段裁剪 | +| `/data/page` | read | 同上 | +| `/data/saveobjt` | create / update / delete | 动作校验 + 字段 edit 校验 + **目标行必须落在数据范围内** | +| `/data/loaddatabysql` | — | ⚠️ 见 5.2 | +| `/data/nextid` `/nextcode` `/describe` | — | 无需 | + +流程: + +``` +解析 table → 用 s_module.b_viewtable / b_savetable 反查 module_id + → 确定 action(loaddata/page → read;saveobjt 按 inserts/updates/deletes 分别定) + → ① 动作校验 + → ② 数据范围拼入 WHERE + → ③ SELECT 列剔除 hidden 字段 + → 执行 +``` + +权限结果按 `(user_id, module_id, action)` 缓存,避免每次查询都查权限表。 + +### 5.2 ⚠️ `/data/loaddatabysql` 必须收紧 + +该接口接受任意 SQL,**会完全绕过字段裁剪和数据范围**。不处理则第 4 节所有规则形同虚设。 + +处理方案(择一,建议第一种): + +1. **仅限管理员 / 内部账号可用**(推荐) +2. 改为只接受白名单视图名,不接受 SQL 片段 +3. 解析 SQL 后注入条件(复杂且易出漏洞,不推荐) + +> 这与《开发规范》第 8 条「动态配置不等于任意 SQL」一致。 + +### 5.3 表名 → 模块 反查 + +`loaddata` / `page` 的参数只带表名,需经 `s_module.b_viewtable` / `b_savetable` 反查 `module_id`。 + +**待确认**:是否存在多个模块共用同一视图?若存在,表名 → 模块的映射不唯一,需要前端额外传 `moduleId` 参数。 + +--- + +## 6. 前端落实 + +### 6.1 `stores/permissions.js` 改造 + +现有骨架(并发加载 + 主体去重 + 管理员提权)保留,替换数据源与判断逻辑: + +| 现状 | 改造后 | +| --- | --- | +| 拉 `s_module` / `b_user_module` / `b_user_power` / `s_module_power` | 拉 `s_module` / `s_power` / `s_user_power` / `s_user_field_permission` / `s_user_data_scope` | +| `powerSet` 存 `${module_id}.${雪花ID}` | 存语义化 `b_code` | +| `canPower(scopeCode, powerCode)`(零调用) | `can(code)` 直接传 `b_code` | + +对外暴露: + +```js +can('module.cw_fee.delete') // 动作判断 +fieldPerm(moduleId, field) // → { mode, query, export } +scope(moduleId, action) // 数据范围 +``` + +### 6.2 三个接线点 + +1. **按钮级**:提供 `v-permission` 指令 + `usePermission()`,替换掉零调用的 `canPower` +2. **字段裁剪**:`FmsModuleTable.buildColumns()` 之后过滤 —— `hidden` 移除列、`view` 置只读、`export = 0` 剔除导出列 +3. **菜单过滤**:`stores/menus.js` 目前只按 `g3soft` 管理员裁剪,**未使用授权数据**,需改为按入口权限过滤 + +> 前端裁剪只是展示层,**不可信**。真正的过滤在后端 SQL。 + +--- + +## 7. 配置界面设计 + +### 7.1 核心原则 + +- **IT 定义"能分配什么",客户决定"分给谁"**。IT 不碰人,客户不碰元数据。 +- **一个页面配完**,不分区切换、不重复选模块。 +- 默认展示**已配置项**,而非全量清单(规则是"没配 = 放行",全量铺开只会增加噪音)。 + +### 7.2 树的主体是模块树,不是菜单树 + +`s_module` 本身是树(`b_parent_id` + `b_module_type`),`page` 类型节点天然承载"页面包含哪些模块": + +``` +海运详细页(page 节点,只配入口) +├── 海运主表(module) +├── 装箱主表(module) +└── 费用管理(module) +``` + +菜单 `s_menu` 只是指向模块的指针(`s_menu.b_module_id`)。**不用菜单树做权限骨架**: + +- 菜单不拥有字段 / 动作 / 数据范围,挂上去语义错误 +- 一个模块可能被多个菜单引用 → 同一模块重复出现、配置冲突 +- 与《核心表结构》"权限以业务模块为核心"矛盾 + +菜单入口权限 = 模块树上的「入口」列。只有"一个模块被多个菜单引用且需分别控制"时,才启用 `page..access` 独立入口。 + +### 7.3 主界面形态(一屏配完一个人) + +``` +模块树 入口 │ 动作(默认拒绝,勾选即授权) │ 数据范围 +────────────────────────────────────────────────────────────────────────────── +▾ 海运详细页[page] ☑ │ - - - - - │ - │ - + ▾ 海运主表 ☑ │ ☑ ☑ ☐ ☐ ☐ │ ☑审核 ☐关闭 │ 仅本人▾ + └ 字段(敏感) 金额=只读 · 内部成本=隐藏 + ▾ 装箱主表 ☑ │ ☑ ☐ ☐ ☐ ☐ │ - │ 本部门▾ + ▾ 费用管理 ☑ │ ☑ ☑ ☑ ☐ ☑ │ ☑审核 ☐反审核 │ 本部门▾ + └ 字段(敏感) 金额=只读 · 内部成本=隐藏 · 毛利=隐藏 +▾ 发票管理 ☑ │ ☑ ☑ ☑ ☐ ☑ │ ☑作废 │ 本部门▾ + 客户档案 ☐ │ ☑ ☐ ☐ ☐ ☐ │ - │ 本部门▾ +``` + +要点: + +- 第一列是**模块树**,缩进 + 展开 + 父子半选 +- `page` 节点只配入口,权限列置灰(不直接对应数据表) +- 动作全在一列,全部默认拒绝,勾选即授权;业务动作与基础操作 chip 同样式 +- **字段是模块行的展开子行**,且只显示**敏感字段 + 字段组**,默认折叠 +- 数据范围是一列,跟着模块走("仅本人"与"禁止删除"是同频操作,不该分开放) + +### 7.4 批量 + +- 左侧用户列表支持多选 → 底部出现「应用角色模板」「批量设置数据范围」「清空」 +- 表格支持整列操作(如"所有模块禁止删除") + +### 7.5 IT 专属入口(客户不可见) + +| 内容 | 频率 | +| --- | --- | +| 模块 / 字段元数据 + 敏感标记 | 低 | +| 字段分组(`s_field_group`) | 低 | +| 业务动作注册(需写代码) | 低 | +| 权限点清单 + 重新生成 | 低 | +| 标准权限包维护 | 低 | + +### 7.6 权限诊断(必做) + +- **以某用户身份预览** +- **反查**:选中一个权限点 / 字段 → 列出谁有 → 批量调整 +- **查看生效 SQL**:排查"为什么这个人看不到这条数据" + +--- + +## 8. 与既有文档的差异(决策变更) + +| # | 原表述 | 本文 | 原因 | +| --- | --- | --- | --- | +| 1 | 动作编码 `action.module...execute` | `module..` | CRUD 与业务动作本质是同一概念,统一编码 | +| 2 | 权限直接授予用户,**不引入角色继承** | 可选「主角色 + 个人例外」两层 | 无角色时配置量是 `人 × 模块 × 字段` 的笛卡尔积 | +| 3 | 权限点类型含 `page` / `report`,与 `module` 并列 | 入口与动作分离;动作统一挂模块 | 入口是"能不能进",动作是"能不能做" | +| 4 | 数据范围 `custom` 填单个值 | 支持选择多个组织节点 | "只看上海 + 深圳分公司" | +| 5 | 未说明树的主语 | **模块树**是主体,菜单只是指针 | 权限以模块为核心 | +| 6 | 未涉及 | 权限点自动生成 + 增量同步三原则 | 一客户一库 + 客户可定制 | +| 7 | 动作分内置 / 业务两种,默认策略不同 | 不区分,统一为「动作」,**全部默认拒绝** | 简化模型:只存授权记录,没有禁止记录 | + +> 建议:将第 1、2 条同步修订到《FMS新系统核心表结构设计.md》第 276 行及权限章节,避免两份文档冲突。 + +--- + +## 9. 实施顺序 + +| 阶段 | 内容 | 产出 | +| --- | --- | --- | +| P1 | 建 `s_power` / `s_user_power`(统一编码)+ 权限点自动生成 + `/data/*` 拦截只做动作校验 | 能控制"谁能进哪个模块、能做什么" | +| P2 | 字段裁剪 + 数据范围 WHERE;**收紧 `/data/loaddatabysql`** | 后端强制完整 | +| P3 | 前端 `permissions.js` 改造 + `v-permission` + 菜单过滤 + 表格字段裁剪 | 界面生效 | +| P4 | 配置界面(模块树 + 一屏配置)+ 标准权限包 + 权限诊断 | 好用 | + +P1 与 P2 是同一个拦截层的两批规则,不会返工。**不建议先做 P4**——模型未定,界面做了会返工。 diff --git a/code/fms/demo.html b/code/fms/demo.html index d5d85d87..bdb0151c 100644 --- a/code/fms/demo.html +++ b/code/fms/demo.html @@ -2,38 +2,856 @@ - -ERP 查询构建器 Demo + +FMS 权限中心 · 一屏授权 + + - -
-
费用列表
费用单与账单、发票、收付款状态统一查询
-
当前查询
-
费用数据
已应用 4 个条件 · 共 18 条
☐费用单号 客户 费用类型 金额 状态 创建时间 操作
□FY20260906001上海东方物流有限公司海运费¥12,800.00待审核2026-09-06审核详情
□FY20260906002深圳华南供应链港杂费¥8,620.00待审核2026-09-05审核详情
□FY20260906003宁波海联国际拖车费¥4,200.00已审核2026-09-05详情
□FY20260906004上海东方物流有限公司报关费¥16,300.00待审核2026-09-04审核详情
+ +
+ + +
+
+
+ F +
+
FMS 权限中心
+
一客户一库 · 权限点自动生成
+
+
+
+ +
+
+ IT +
+
系统管理员
+
客户库:DEMO-FWD
+
+
+
+
+ + +
+ + +
+
+ 授权对象 + +
+ + +
+
+
+ +
+ + + + + +
+ + +
+
+

全部模块概览

+

{{ curUser.name }} · 点模块名进入详细配置

+
+ + + + + + + + + + + + + + + + + +
模块入口已授权动作数据范围
+
{{ m.name }}
+
{{ m.id }}
+
+ + + 未授权(默认拒绝) + + {{ a }} + + + {{ scopeName(scopeOf(m.id)) }} +
+
+ + +
+
+
+

{{ selName }}

+

{{ state.selected }}

+
+ page 节点 + {{ curUser.name }} · 全部默认拒绝,勾选即授权 +
+ + +
+
入口
+ + {{ hasEntry(state.selected) ? '已开通' : '未开通' }} + {{ entryCode }} +
+ + +
+
动作
+
+ +
+
+
页面节点只配入口,具体操作在下属模块上配置
+ + +
+
数据范围
+ + 未配置视为全部数据 +
+ + +
+
敏感字段
+
+
该模块没有标记敏感字段,无需配置字段权限
+
+
+ {{ f.l }}{{ f.n }} + + + + 已收紧 + 默认 +
+
+
+
+
+
+ + + +
+
+ + +
+
+
IT ADMINISTRATION
+

资源配置(客户不可见)

+

IT 定义「能分配什么」。客户只做分配,不碰元数据,也不能新建业务动作(动作需要后端代码)。

+
+
模块 / 页面
{{ nodeCount }}
+
业务动作
{{ actionDefCount }}
+
敏感字段
{{ sensitiveCount }}
+
权限点(自动生成)
{{ powerCodes.length }}
+
+
+ +
+ +
+
+

模块与敏感字段标记

+

只有标为敏感的字段才进入客户授权界面,其余字段不占配置量

+
+
+ + + + + + + + + + + +
模块字段敏感
+
+
+ + +
+
+
+

权限点清单

+

随元数据自动生成,只增不删、不覆盖已有配置

+
+
+ +
+
+
+ + + + + + + + + + + + + + + +
权限点编码名称默认
{{ p.code }}{{ p.name }}拒绝
+
+
+ 业务动作(如 module.cw_fee.audit)由开发注册代码后生成,客户界面只能勾选、不能新建。 +
+
+
+
+ + + +
+
+ 已选 {{ state.picked.length }} 人 + + + +
+
+ 有 {{ diffList.length }} 项未保存变更 + + + +
+
+ + +
+
+
+
+
保存前确认
+
共 {{ diffList.length }} 项变更,保存后立即生效
+
+ +
+
+ + + + + + + + + + + + + + + + + + + +
用户类别对象变更前变更后
{{ d.user }}{{ d.type }}{{ d.target }}{{ d.from }}{{ d.to }}
+
+
+ + +
+
+
+ +
{{ toastMsg }}
+ + + + +
-
高级查询当前列表列是快捷字段,也可以查询未展示的关联业务字段
普通列条件与关联单据条件会组合成同一个查询
快捷字段 · 点击即可添加
-
- diff --git a/code/fms/fms-vue/src/components/ui/button/index.scss b/code/fms/fms-vue/src/components/ui/button/index.scss index 3639b3e8..3a5dd48a 100644 --- a/code/fms/fms-vue/src/components/ui/button/index.scss +++ b/code/fms/fms-vue/src/components/ui/button/index.scss @@ -110,14 +110,17 @@ } /* 加载态 —— spinner 在前,隐藏自带图标 */ -.button-loading { - cursor: default; -} - .button-loading :deep(svg):not(.button-spinner) { display: none; } +/* 加载态虽因防重复提交而原生 disabled,但视觉是“进行中”而非“禁用”: + 保持原配色(不降透明度、悬停不变色),光标用纯加载样式 */ +.button-loading:disabled { + opacity: 1; + cursor: wait; +} + :deep(.button-spinner) { width: 1em; height: 1em; diff --git a/code/fms/fms-vue/src/views/dashboard/index.vue b/code/fms/fms-vue/src/views/dashboard/index.vue index 9f8f6f50..55fdd496 100644 --- a/code/fms/fms-vue/src/views/dashboard/index.vue +++ b/code/fms/fms-vue/src/views/dashboard/index.vue @@ -243,15 +243,12 @@ const searchForm = reactive(makeEmptyForm()) const queryPrefs = reactive(Object.fromEntries(SEARCH_FIELD_DEFS.map((field) => [field.key, { area: field.area || 'advanced', order: field.order || 999 }]))) const QUICK_VISIBLE_LIMIT = 4 const quickSearchExpanded = ref(false) -const drawerOpen = ref(false) -const drawerTab = ref('conditions') const queryApplied = ref(false) -const activeQueryMode = ref('quick') -const queryMode = ref('quick') +const activeQueryMode = ref('quick') // 'quick' 搜索卡 / 'advanced' 左侧常驻高级面板 +const settingsOpen = ref(false) // 查询设置右侧抽屉 const advancedLogic = ref('and') const advancedNodes = reactive([]) const advancedGroups = reactive([]) -const advancedSnapshot = ref(null) const draggingFieldKey = ref('') const dragOverFieldKey = ref('') const allAdvancedNodes = computed(() => advancedNodes.concat(advancedGroups.flatMap((group) => group.nodes))) @@ -282,13 +279,8 @@ const extraQuickConditionCount = computed(() => extraQuickSearchFields.value.fil if (field.type === 'numrange') return searchForm[`${field.key}Min`] || searchForm[`${field.key}Max`] return searchForm[field.key] !== '' && searchForm[field.key] !== null && searchForm[field.key] !== undefined }).length) -// 常用区已填条件总数:高级模式的说明条要用 —— 告诉用户这些值还在,只是不参与 -const quickConditionCount = computed(() => quickSearchFields.value.filter((field) => { - if (field.type === 'numrange') return searchForm[`${field.key}Min`] || searchForm[`${field.key}Max`] - return searchForm[field.key] !== '' && searchForm[field.key] !== null && searchForm[field.key] !== undefined -}).length) -// 高级模式下常用区强制收起:保留上下文(知道有哪几个常用条件),但不占版面 -const showAllQuickFields = computed(() => quickSearchExpanded.value && activeQueryMode.value === 'quick') +// 高级模式下面板即状态呈现,不再需要「常用条件暂不参与」的说明 +const showAllQuickFields = computed(() => quickSearchExpanded.value) const advancedSearchFields = computed(() => searchFields.value.filter((field) => field.queryable !== false && queryPrefs[field.key]?.area !== 'hidden'), ) @@ -379,30 +371,11 @@ function removeSummaryItem(item) { } if (!querySummary.value.length) queryApplied.value = false } -function openQueryDrawer(tab = 'conditions') { - if (tab === 'conditions' && !drawerOpen.value) { - advancedSnapshot.value = { - logic: advancedLogic.value, - nodes: JSON.parse(JSON.stringify(advancedNodes)), - groups: JSON.parse(JSON.stringify(advancedGroups)), - } - } - drawerTab.value = tab - drawerOpen.value = true +function openSettings() { + settingsOpen.value = true } -function closeQueryDrawer() { - if (advancedSnapshot.value) { - advancedLogic.value = advancedSnapshot.value.logic - advancedNodes.splice(0, advancedNodes.length, ...advancedSnapshot.value.nodes) - advancedGroups.splice(0, advancedGroups.length, ...advancedSnapshot.value.groups) - advancedSnapshot.value = null - queryMode.value = activeQueryMode.value - } - drawerOpen.value = false -} -function selectQueryMode(mode) { - queryMode.value = mode - if (mode === 'advanced') openQueryDrawer('conditions') +function closeSettings() { + settingsOpen.value = false } function setFieldArea(field, area) { if (field.queryable === false) return @@ -443,6 +416,11 @@ function resetQuickQuery() { Object.assign(searchForm, makeEmptyForm()) if (activeQueryMode.value === 'quick') queryApplied.value = false } +function resetAllQueries() { + resetQuickQuery() + resetAdvancedQuery() + queryApplied.value = false +} function startFieldDrag(field, event) { draggingFieldKey.value = field.key // Firefox 下不写 dataTransfer 不会触发 drop,同时声明「移动」语义拿到正确的光标 @@ -476,28 +454,52 @@ function dropField(field, area) { } function onSearch() { activeQueryMode.value = 'quick' - queryMode.value = 'quick' queryApplied.value = true } -function applyAdvancedQuery() { +// 进入高级模式:滑出左侧常驻面板(无遮罩),搜索卡隐藏、表格占满剩余宽高 +function enterAdvancedMode() { activeQueryMode.value = 'advanced' - queryMode.value = 'advanced' - queryApplied.value = true - advancedSnapshot.value = null - drawerOpen.value = false -} -function resetAllQueries() { - resetQuickQuery() - resetAdvancedQuery() - queryApplied.value = false - advancedSnapshot.value = null } +// 回到简单模式:收起面板、恢复搜索卡 function returnToQuickQuery() { - if (drawerOpen.value && drawerTab.value === 'conditions') closeQueryDrawer() activeQueryMode.value = 'quick' - queryMode.value = 'quick' - queryApplied.value = false } +// 面板内应用:编辑即暂存,应用只固化生效态 +function applyAdvancedQuery() { + queryApplied.value = true +} + +/* ============================================================ + * 布局原型扩展(模拟验证用,正式页面删除): + * pageLayout = 'flat' 纯列表 | 'tree' 树+表格。 + * 验证「左栏槽位」约定:树(快速模式)与高级面板(高级模式)轮班占同一列, + * 表格宽度开销恒等于一列;树选中条件以 chip 呈现,两种模式都可见可清除。 + * ============================================================ */ +const pageLayout = ref('flat') +const TREE_NODES = [ + { id: 'all', label: '全部分类', children: [ + { id: 'c1', label: '华东区', children: [ + { id: 'c11', label: '上海' }, + { id: 'c12', label: '杭州' }, + ] }, + { id: 'c2', label: '华南区', children: [ + { id: 'c21', label: '广州' }, + { id: 'c22', label: '深圳' }, + ] }, + { id: 'c3', label: '华北区' }, + ] }, +] +function findTreeLabel(nodes, id) { + for (const node of nodes) { + if (node.id === id) return node.label + const childLabel = findTreeLabel(node.children || [], id) + if (childLabel) return childLabel + } + return '' +} +// 树选中条件(页面固定条件):chips 条数据源之一,两种模式都渲染 +const selectedTreeNodeId = ref('') +const selectedTreeNodeLabel = computed(() => findTreeLabel(TREE_NODES, selectedTreeNodeId.value) || '') /* ---------- fms-table 大数据量 + 单行编辑 demo ---------- */ const TYPE_OPTIONS = [ @@ -614,7 +616,7 @@ const selectedText = computed(() => ? t('demo.statusbar.selected').replace('{n}', selectedRowKeys.value.length) : '', ) -const totalText = computed(() => t('demo.footer.total').replace('{n}', allRows.value.length)) +const totalText = computed(() => t('demo.footer.total').replace('{n}', filteredRows.value.length)) function onRefresh() { allRows.value = makeRows(DEFAULT_ROW_COUNT) @@ -625,25 +627,138 @@ function onMoreAction({ key }) { // 打印 / 密度 / 全屏:占位,后续接入 void key } +/* 树选中过滤表格行(模拟;正式页面由 SQL 条件承担) */ +const filteredRows = computed(() => { + if (!selectedTreeNodeLabel.value || selectedTreeNodeLabel.value === '全部分类') return allRows.value + return allRows.value.filter((row) => String(row.name).length % 2 === Number(selectedTreeNodeId.value.slice(-1)) % 2) +}) +/* 左栏是否有内容占位:树(快速模式)或高级面板(高级模式) */ +const leftColumnOccupied = computed(() => pageLayout.value === 'tree' || activeQueryMode.value === 'advanced') +/* 树扁平化渲染(模拟;正式页面用 ui/tree 组件) */ +function flattenTree(nodes, depth = 0) { + const result = [] + for (const node of nodes) { + result.push({ id: node.id, label: node.label, depth }) + if (node.children?.length) result.push(...flattenTree(node.children, depth + 1)) + } + return result +}