20260914223013

This commit is contained in:
oneao committed 2026-09-14 22:30:13 +08:00
1 parent 549c8bd2eb
commit 63514476d7
60 files changed
+6478 -2004

No files matched your search

@@ -576,6 +576,13 @@ create index ix_s_menu_module_module
菜单树同样使用 `b_parent_id` 作为权威关系,并冗余维护 `b_depth`、`b_path`。菜单节点新增、移动和删除时,由业务层同步处理后代节点路径和层级;菜单编码创建后原则上不可修改。
绑定规则:
- `directory`(目录)和 `external`(外链)不绑定模块;`page` 可绑定一个或多个模块;
- 关系表只登记 `data` / `virtual` 模块:权限按 `data` 模块判定,`module` 类型只是模块树上的分类节点,不参与权限,也不进入关系表;
- 菜单管理界面按模块树勾选,勾中分类节点时自动展开为其下全部 `data` 模块逐条登记(界面级快捷操作,落库的始终是明确的模块清单,之后可单独增删);
- 菜单编码创建后原则上不可修改,绑定关系随菜单保存一并提交。
业务模块上下文可以根据所绑定数据模块的父级模块获得;暂不增加独立的菜单上下文字段。
菜单权限(`menu.*`)只控制页面入口;页面内各 `data`、`virtual` 模块的操作权限按模块编码独立判定,一个菜单绑定多个模块时不做权限合并。
@@ -968,3 +975,84 @@ b_condition_sql = 'b_salesman_id = {userId}'
- `s_user_field_power.b_module_id`、`s_user_data_power.b_module_id` 指向 `s_module.b_id`,字段还需在 `s_field` 中存在;
- 数据范围只作用于本表的 `b_user_id + b_module_id + b_operation`;是否向关联模块延伸(例如子表、明细模块)由权限引擎根据业务语义决定,不依赖 `s_relation` 自动传播;
- 权限缓存、批量校验和 SQL 条件注入点由权限引擎实现,业务 SQL 生成时统一追加范围条件。
## 15. 文件
文件统一由文件服务托管:业务表不保存文件二进制,只通过 `bf_files.father` 关联宿主业务主键,
按 `father + mx_moduleid + mx_cate_id` 聚合出某个业务对象、某模块、某分类下的附件列表。
存储方式由配置决定(本地磁盘 / 阿里云 OSS),两种模式共用同一张表:本地模式由后端写盘后落库,
OSS 模式由前端取号直传后回调落库。
```sql
-- 文件表
create table dbo.bf_files (
subid bigint not null primary key, -- 文件主键(雪花,应用层取号:本地由后端、OSS 直传由前端先取号)
father bigint null, -- 宿主业务主键(业务表 b_id),列表按它聚合
mx_filename nvarchar(500) null, -- 原始文件名(含扩展名,展示与下载用)
mx_filesize varchar(50) null, -- 文件大小(字节,字符串存储)
mx_fileext varchar(50) null, -- 扩展名(小写、不含点)
mx_mapfilename nvarchar(500) null, -- 访问地址:本地为 {url-prefix}/{org}/{yyyy}/{MM}/{dd}/{uuid}.{ext},OSS 为完整 URL
mx_moduleid varchar(50) null, -- 业务模块编码(s_module.b_id)
mx_cate_id varchar(50) null, -- 文件分类(bf_files_cateid.b_id)
mx_xh int not null default 0, -- 排序号(保留;当前实现固定 0,列表按 subid 倒序)
mx_sh tinyint not null default 0, -- 审核标识(保留;当前实现固定 0)
mx_shuser_id varchar(50) null, -- 审核人(保留)
mx_shdatetime datetime2 null, -- 审核时间(保留)
mx_cutfilename nvarchar(500) null, -- 缩略图地址(保留)
mx_cutfilesize varchar(50) null, -- 缩略图大小(保留)
mx_orderid varchar(50) null, -- 排序组(保留)
mx_bz nvarchar(500) null, -- 备注(保留)
mx_inputuser_id varchar(50) null, -- 上传人(用户账号)
mx_inputdatetime datetime2 null, -- 上传时间
mx_updateuser_id varchar(50) null, -- 最后修改人
mx_updatedatetime datetime2 null -- 最后修改时间
);
create index ix_bf_files_host
on dbo.bf_files (father, mx_moduleid, mx_cate_id, mx_xh, subid);
-- 文件分类表
create table dbo.bf_files_cateid (
b_id varchar(50) not null primary key, -- 分类编码
b_name nvarchar(50) null, -- 分类名称
b_files_type varchar(50) null, -- 允许的扩展名(逗号分隔,空 = 不限;保留)
b_xh int not null default 0, -- 显示顺序
b_canuse tinyint not null default 1, -- 是否启用(0/1)
b_bz nvarchar(200) null, -- 备注
b_inputuser_id varchar(50) null, -- 创建人
b_inputdatetime datetime2 null, -- 创建时间
b_updateuser_id varchar(50) null, -- 最后修改人
b_updatedatetime datetime2 null -- 最后修改时间
);
```
要点:
- **主键**:`subid` 为应用层雪花 ID,不使用 `identity`。本地模式由后端在写盘前取号;OSS 模式由前端在上传前取号(`nextIdApi`),直传完成后回调 `/file/save-record` 落库 —— 两条链路都不能依赖数据库自增。
- **宿主关联**:`father` 存宿主业务主键(业务表 `b_id`,bigint 雪花),不建外键;删除业务数据时由业务层级联清理附件(先删存储、后删行)。
- **存储地址**:`mx_mapfilename` 即访问地址,前端预览 / 下载直接使用。本地模式写入 `{fms.file.local.url-prefix}/{orgId}/{yyyy}/{MM}/{dd}/{uuid}.{ext}`,物理文件落在 `{fms.file.local.storage-dir}` 下的同路径;OSS 模式写入 g3oss 返回的完整 URL。
- **保留字段**:`mx_sh*`(审核)、`mx_cut*`(缩略图)、`mx_orderid`、`mx_bz`、`mx_xh` 沿用旧库结构,当前实现未使用(写 0 / 空值),保留以兼容历史数据迁移。
- **旧库遗留**:`bf_files_type`(模块文件类型 / 数量配置)在旧库存在,但新旧系统均未使用,不迁移。
存储配置(`application.yaml`):
```yaml
fms:
file:
storage-type: local # local / aliyun-oss
local:
storage-dir: ./data/files # 物理根目录
url-prefix: /api/file/static # 访问前缀
oss:
g3oss-url: http://g3oss.g3soft.cn:8082
```
业务接入(前端 `FmsFile` 组件):
```text
<FmsFile :father="业务主键" :module-id="模块编码" :cate-id="分类编码(可空)" />
├── 列表:bf_files 按 father + mx_moduleid + mx_cate_id 过滤,mx_xh ASC, subid DESC 排序
├── 上传:local → POST /file/upload(后端写盘 + 落库)
│ aliyun-oss → 取号 → 凭证直传 → POST /file/save-record 落库
└── 删除:POST /file/delete(删存储 → 删 DB 行)
```