20260915221013

This commit is contained in:
oneao committed 2026-09-15 22:10:13 +08:00
1 parent 1f56cc3efb
commit dce29f250e
54 files changed
+3732 -574

No files matched your search

+3 -3
View File
@@ -320,7 +320,7 @@ create table dbo.s_log_technical (
b_error_message nvarchar(4000) null, -- 错误信息
b_exception_text nvarchar(max) null, -- 异常文本
b_context_text nvarchar(max) null, -- 上下文文本
b_occurdatetime datetime2 default sysutcdatetime() -- 发生时间
b_occurdatetime datetime2 default getdate() -- 发生时间(本地墙钟值:全链路统一,不用 sysutcdatetime 的 UTC)
);
GO
@@ -342,7 +342,7 @@ create table dbo.s_log_login (
b_session_id varchar(50) null, -- 会话 ID
b_request_id varchar(64) null, -- 请求 ID
b_trace_id varchar(64) null, -- 链路 ID
b_occurdatetime datetime2 default sysutcdatetime() -- 发生时间
b_occurdatetime datetime2 default getdate() -- 发生时间(本地墙钟值:全链路统一,不用 sysutcdatetime 的 UTC)
);
GO
@@ -361,7 +361,7 @@ create table dbo.s_log_audit (
b_request_id varchar(64) null, -- 请求 ID
b_trace_id varchar(64) null, -- 链路 ID
b_payload_text nvarchar(max) null, -- 载荷文本
b_occurdatetime datetime2 default sysutcdatetime() -- 发生时间
b_occurdatetime datetime2 default getdate() -- 发生时间(本地墙钟值:全链路统一,不用 sysutcdatetime 的 UTC)
);
GO
+403
View File
@@ -0,0 +1,403 @@
/* ============================================================================
FMS 模块注册脚本 — 日志(系统管理 → 日志 → 登录日志 / 操作日志 / 技术日志)
依据文档:FMS新系统核心表结构设计.md「12. 日志」
前置条件:
s_log_technical / s_log_login / s_log_audit / s_log_audit_field 已由 fms_core.sql 建表。
使用说明:
1. 执行前先切换到目标数据库(USE FMS)。
2. 本脚本只写模块元数据(s_module / s_field / s_module_schema)、查询视图与菜单,不含日志数据。
3. 脚本可重复执行:先清空本分组下的 s_field / s_module / s_module_schema 行再重建。
4. 三张日志表都是只读数据源:b_save_table 为 NULL,列表页不提供新增 / 编辑 / 删除。
写入侧现状:
- 登录日志:后端 LoginLogService 已在登录成功 / 失败时落库;
- 操作日志(审计)/ 技术日志:写入逻辑待实现,页面先建好,有数据即可看到。
============================================================================ */
SET NOCOUNT ON;
GO
/* ----------------------------------------------------------------------------
1. 查询视图
用途:作为 s_module.b_view_table 的数据源;s_field.b_field 必须是视图里真实存在的列。
v_ 前缀是派生列(只读,不参与保存):日志表存的是编码 / 枚举值,展示用的可读文本
在视图里拼好,列表列设置与查询条件都直接用这些派生列,避免前端再写转换逻辑。
---------------------------------------------------------------------------- */
/* 登录日志:b_login_result 是 0/1,派生一列中文结果;浏览器 / 系统拼成「名称 版本」 */
create or alter view dbo.v_s_log_login as
select l.b_id,
l.b_user_id,
-- 登录账号(派生):直接取登录时输入的账号,不联 b_user 取姓名 ——
-- 账号是登录事件的稳定标识(成功 / 密码错误 / 账号不存在都有值),
-- 而姓名只对已存在账号有意义,失败记录会缺一半;少一次 join 也不吃亏
l.b_user_id as v_user_name,
l.b_login_type,
case when l.b_login_result = 1 then N'成功' else N'失败' end as v_login_result, -- 登录结果(派生)
l.b_fail_reason,
l.b_ip,
l.b_ip_location,
l.b_browser,
l.b_browser_version,
l.b_os,
l.b_os_version,
l.b_device_type,
l.b_session_id,
l.b_request_id,
l.b_trace_id,
l.b_occurdatetime
from dbo.s_log_login l;
GO
/* 操作日志(审计):操作人名称在写入时已冗余落库,这里不联表 */
create or alter view dbo.v_s_log_audit as
select a.b_id,
a.b_event_code,
a.b_module_id,
a.b_data_id,
a.b_business_no,
a.b_operation,
a.b_operator_id,
a.b_operator_name,
a.b_source_type,
a.b_visibility,
a.b_payload_text,
a.b_trace_id,
a.b_occurdatetime
from dbo.s_log_audit a;
GO
/* 技术日志:b_exception_text / b_context_text 是大文本,不进程列表字段,仅按需查库 */
create or alter view dbo.v_s_log_technical as
select t.b_id,
t.b_user_id,
u.b_name as v_user_name, -- 用户名(派生)
t.b_sourcetype,
t.b_loglevel,
t.b_logcategory,
t.b_operation,
t.b_module_id,
t.b_duration_ms,
t.b_result_code,
t.b_error_code,
t.b_error_message,
t.b_server_node,
t.b_trace_id,
t.b_occurdatetime
from dbo.s_log_technical t
left join dbo.b_user u on u.b_id = t.b_user_id;
GO
/* ----------------------------------------------------------------------------
2. 父节点路径修正 + 清理(脚本可重复执行)
b_path 是派生字段(权威关系是 b_parent_id),格式形如 /system/log/。
已存在的 system 节点 b_path 是历史遗留的 /-1/,与派生规则不一致:
不先修正,本脚本新增的 log 节点就无法与之拼成连贯路径。
---------------------------------------------------------------------------- */
update dbo.s_module
set b_path = '/system/'
where b_id = 'system'
and b_path <> '/system/';
GO
delete from dbo.s_module_schema
where b_module_id in (select b_id from dbo.s_module where b_path like '/system/log/%');
GO
delete from dbo.s_field
where b_module_id in (select b_id from dbo.s_module where b_path like '/system/log/%');
GO
delete from dbo.s_module
where b_path like '/system/log/%' or b_id = 'log';
GO
/* ----------------------------------------------------------------------------
3. 分组节点(module 类型):系统管理 → 日志
---------------------------------------------------------------------------- */
insert into dbo.s_module (b_id, b_parent_id, b_depth, b_path, b_name, b_i18n, b_module_type, b_canuse, b_xh, b_bz)
values ('log', 'system', 1, '/system/log/', N'日志', 'module.log', 'module', 1, 20,
N'系统运行痕迹:登录 / 操作(审计)/ 技术日志,均为只读数据源');
GO
/* ----------------------------------------------------------------------------
4. 数据模块(data 类型,只读)
b_view_table 指向本脚本的视图;b_save_table 留空表示不可写 —— 列表页因此不提供
新增 / 编辑 / 删除,符合日志「只增不改」的语义(写入只发生在后端)。
b_order_sql 统一按发生时间倒序:看日志永远是「最近的先出现」。
---------------------------------------------------------------------------- */
insert into dbo.s_module (b_id, b_parent_id, b_depth, b_path, b_name, b_i18n, b_module_type,
b_view_table, b_save_table, b_key_field, b_order_sql, b_canuse, b_xh, b_bz)
values ('v_s_log_login', 'log', 2, '/system/log/v_s_log_login/', N'登录日志', 'module.v_s_log_login', 'data',
'v_s_log_login', null, 'b_id', 'b_occurdatetime DESC', 1, 10,
N'登录成功 / 失败记录(含 IP、设备、失败原因),由后端 LoginLogService 写入');
GO
insert into dbo.s_module (b_id, b_parent_id, b_depth, b_path, b_name, b_i18n, b_module_type,
b_view_table, b_save_table, b_key_field, b_order_sql, b_canuse, b_xh, b_bz)
values ('v_s_log_audit', 'log', 2, '/system/log/v_s_log_audit/', N'操作日志', 'module.v_s_log_audit', 'data',
'v_s_log_audit', null, 'b_id', 'b_occurdatetime DESC', 1, 20,
N'业务操作审计:谁在何时对哪条数据做了什么(字段级前后值见 s_log_audit_field)');
GO
insert into dbo.s_module (b_id, b_parent_id, b_depth, b_path, b_name, b_i18n, b_module_type,
b_view_table, b_save_table, b_key_field, b_order_sql, b_canuse, b_xh, b_bz)
values ('v_s_log_technical', 'log', 2, '/system/log/v_s_log_technical/', N'技术日志', 'module.v_s_log_technical', 'data',
'v_s_log_technical', null, 'b_id', 'b_occurdatetime DESC', 1, 30,
N'后端异常 / 性能记录,供开发排查;与登录、操作日志通过 b_trace_id 关联');
GO
/* ----------------------------------------------------------------------------
5. 字段定义
b_field 必须存在于对应视图;b_type 决定单元格渲染与查询操作符分组:
input(文本)/ number / datetime。
---------------------------------------------------------------------------- */
/* 5.1 登录日志 */
insert into dbo.s_field (b_module_id, b_field, b_name, b_i18n, b_type, b_canuse, b_xh)
values ('v_s_log_login', 'b_occurdatetime', N'登录时间', null, 'datetime', 1, 10),
('v_s_log_login', 'v_user_name', N'登录账号', null, 'input', 1, 20),
('v_s_log_login', 'b_user_id', N'用户编码', null, 'input', 1, 30),
('v_s_log_login', 'v_login_result', N'登录结果', null, 'input', 1, 40),
('v_s_log_login', 'b_login_type', N'登录类型', null, 'input', 1, 50),
('v_s_log_login', 'b_fail_reason', N'失败原因', null, 'input', 1, 60),
('v_s_log_login', 'b_ip', N'IP', null, 'input', 1, 70),
('v_s_log_login', 'b_ip_location', N'IP 归属地', null, 'input', 1, 80),
('v_s_log_login', 'b_browser', N'浏览器', null, 'input', 1, 90),
('v_s_log_login', 'b_browser_version', N'浏览器版本', null, 'input', 1, 100),
('v_s_log_login', 'b_os', N'操作系统', null, 'input', 1, 110),
('v_s_log_login', 'b_os_version', N'系统版本', null, 'input', 1, 120),
('v_s_log_login', 'b_device_type', N'设备类型', null, 'input', 1, 130),
('v_s_log_login', 'b_session_id', N'会话 ID', null, 'input', 1, 140),
('v_s_log_login', 'b_trace_id', N'链路 ID', null, 'input', 1, 150),
('v_s_log_login', 'b_id', N'日志 ID', null, 'input', 1, 160);
GO
/* 5.2 操作日志 */
insert into dbo.s_field (b_module_id, b_field, b_name, b_i18n, b_type, b_canuse, b_xh)
values ('v_s_log_audit', 'b_occurdatetime', N'操作时间', null, 'datetime', 1, 10),
('v_s_log_audit', 'b_operator_name', N'操作人', null, 'input', 1, 20),
('v_s_log_audit', 'b_module_id', N'模块', null, 'input', 1, 30),
('v_s_log_audit', 'b_operation', N'操作', null, 'input', 1, 40),
('v_s_log_audit', 'b_business_no', N'业务单号', null, 'input', 1, 50),
('v_s_log_audit', 'b_event_code', N'事件编码', null, 'input', 1, 60),
('v_s_log_audit', 'b_data_id', N'数据 ID', null, 'input', 1, 70),
('v_s_log_audit', 'b_source_type', N'来源类型', null, 'input', 1, 80),
('v_s_log_audit', 'b_visibility', N'可见性', null, 'input', 1, 90),
('v_s_log_audit', 'b_operator_id', N'操作人编码', null, 'input', 1, 100),
('v_s_log_audit', 'b_trace_id', N'链路 ID', null, 'input', 1, 110),
('v_s_log_audit', 'b_payload_text', N'载荷文本', null, 'input', 1, 120),
('v_s_log_audit', 'b_id', N'日志 ID', null, 'input', 1, 130);
GO
/* 5.3 技术日志 */
insert into dbo.s_field (b_module_id, b_field, b_name, b_i18n, b_type, b_canuse, b_xh)
values ('v_s_log_technical', 'b_occurdatetime', N'发生时间', null, 'datetime', 1, 10),
('v_s_log_technical', 'b_loglevel', N'级别', null, 'input', 1, 20),
('v_s_log_technical', 'b_logcategory', N'分类', null, 'input', 1, 30),
('v_s_log_technical', 'b_operation', N'操作', null, 'input', 1, 40),
('v_s_log_technical', 'b_module_id', N'模块', null, 'input', 1, 50),
('v_s_log_technical', 'v_user_name', N'用户', null, 'input', 1, 60),
('v_s_log_technical', 'b_duration_ms', N'耗时(ms)', null, 'number', 1, 70),
('v_s_log_technical', 'b_error_code', N'错误码', null, 'input', 1, 80),
('v_s_log_technical', 'b_error_message', N'错误信息', null, 'input', 1, 90),
('v_s_log_technical', 'b_result_code', N'结果码', null, 'input', 1, 100),
('v_s_log_technical', 'b_sourcetype', N'来源类型', null, 'input', 1, 110),
('v_s_log_technical', 'b_server_node', N'服务节点', null, 'input', 1, 120),
('v_s_log_technical', 'b_trace_id', N'链路 ID', null, 'input', 1, 130),
('v_s_log_technical', 'b_user_id', N'用户编码', null, 'input', 1, 140),
('v_s_log_technical', 'b_id', N'日志 ID', null, 'input', 1, 150);
GO
/* ----------------------------------------------------------------------------
6. 界面配置(s_module_schema):view / query
日志只读,不生成 edit 配置(列表页不进入可编辑模式)。
查询条件的时间字段用 between:日志排查的第一步永远是「圈一个时间段」。
---------------------------------------------------------------------------- */
/* 6.1 登录日志 */
insert into dbo.s_module_schema (b_module_id, b_schema_type, b_schema_json, b_canuse)
values ('v_s_log_login', 'view', N'{
"schemaVersion": 1,
"columns": [
{ "field": "b_occurdatetime", "width": 170 },
{ "field": "v_user_name", "width": 140 },
{ "field": "v_login_result", "width": 90 },
{ "field": "b_fail_reason", "width": 180 },
{ "field": "b_ip", "width": 130 },
{ "field": "b_ip_location", "width": 150 },
{ "field": "b_browser", "width": 110 },
{ "field": "b_os", "width": 110 },
{ "field": "b_device_type", "width": 100 }
]
}', 1),
('v_s_log_login', 'query', N'{
"schemaVersion": 1,
"groups": [
{ "conditions": [
{ "field": "b_occurdatetime", "operator": "between" },
{ "field": "v_user_name", "operator": "like" },
{ "field": "v_login_result", "operator": "eq" },
{ "field": "b_ip", "operator": "like" }
] }
],
"quick": ["b_occurdatetime", "v_user_name"]
}', 1);
GO
/* 6.2 操作日志 */
insert into dbo.s_module_schema (b_module_id, b_schema_type, b_schema_json, b_canuse)
values ('v_s_log_audit', 'view', N'{
"schemaVersion": 1,
"columns": [
{ "field": "b_occurdatetime", "width": 170 },
{ "field": "b_operator_name", "width": 120 },
{ "field": "b_module_id", "width": 150 },
{ "field": "b_operation", "width": 110 },
{ "field": "b_business_no", "width": 150 },
{ "field": "b_event_code", "width": 150 },
{ "field": "b_visibility", "width": 100 },
{ "field": "b_data_id", "width": 140 }
]
}', 1),
('v_s_log_audit', 'query', N'{
"schemaVersion": 1,
"groups": [
{ "conditions": [
{ "field": "b_occurdatetime", "operator": "between" },
{ "field": "b_operator_name", "operator": "like" },
{ "field": "b_module_id", "operator": "like" },
{ "field": "b_operation", "operator": "like" },
{ "field": "b_business_no", "operator": "like" },
{ "field": "b_trace_id", "operator": "like" }
] }
],
"quick": ["b_occurdatetime", "b_operator_name", "b_business_no"]
}', 1);
GO
/* 6.3 技术日志 */
insert into dbo.s_module_schema (b_module_id, b_schema_type, b_schema_json, b_canuse)
values ('v_s_log_technical', 'view', N'{
"schemaVersion": 1,
"columns": [
{ "field": "b_occurdatetime", "width": 170 },
{ "field": "b_loglevel", "width": 90 },
{ "field": "b_logcategory", "width": 130 },
{ "field": "b_operation", "width": 140 },
{ "field": "b_module_id", "width": 150 },
{ "field": "v_user_name", "width": 120 },
{ "field": "b_duration_ms", "width": 100 },
{ "field": "b_error_code", "width": 120 },
{ "field": "b_error_message", "width": 260 }
]
}', 1),
('v_s_log_technical', 'query', N'{
"schemaVersion": 1,
"groups": [
{ "conditions": [
{ "field": "b_occurdatetime", "operator": "between" },
{ "field": "b_loglevel", "operator": "eq" },
{ "field": "b_logcategory", "operator": "like" },
{ "field": "b_operation", "operator": "like" },
{ "field": "b_error_code", "operator": "like" },
{ "field": "b_trace_id", "operator": "like" }
] }
],
"quick": ["b_occurdatetime", "b_logcategory"]
}', 1);
GO
/* ----------------------------------------------------------------------------
7. 菜单(s_menu)
业务菜单通常由「菜单管理」维护,这里随脚本一并初始化(幂等):
系统管理 → 日志(目录)→ 登录日志 / 操作日志。
路由地址与前端 routes.js 的 /system/log/ 下各页面一一对应。
技术日志默认不进菜单:它的受众是开发 / 运维,字段(trace_id、服务节点、
错误堆栈)对业务用户没有意义;需要时按下面第 3 行同样的写法补一条即可。
---------------------------------------------------------------------------- */
if not exists (select 1 from dbo.s_menu where b_id = 'log')
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 ('log', 'system', 1, '/system/log/', N'日志', 'menu.log', 'directory', null, null, 20, 1);
end
GO
if not exists (select 1 from dbo.s_menu where b_id = 'log_login')
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 ('log_login', 'log', 2, '/system/log/log_login/', N'登录日志', 'menu.log_login', 'page', '/system/log/login', null, 10, 1);
end
GO
if not exists (select 1 from dbo.s_menu where b_id = 'log_audit')
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 ('log_audit', 'log', 2, '/system/log/log_audit/', N'操作日志', 'menu.log_audit', 'page', '/system/log/audit', null, 20, 1);
end
GO
-- 技术日志(默认不启用;需要时取消注释)
-- if not exists (select 1 from dbo.s_menu where b_id = 'log_technical')
-- 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 ('log_technical', 'log', 2, '/system/log/log_technical/', N'技术日志', 'menu.log_technical', 'page', '/system/log/technical', null, 30, 1);
-- end
-- GO
/* ----------------------------------------------------------------------------
8. 多语言(s_i18n):模块名与菜单名,默认语言为中文时写入中文值
资源键命名见设计文档第 11 节:模块名 module.*、菜单名 menu.*。
已存在同键同语言的行不覆盖(人工翻译优先)。
---------------------------------------------------------------------------- */
declare @i18n table (k varchar(150) primary key, v nvarchar(1000) not null);
insert into @i18n (k, v) values
('module.log', N'日志'),
('module.v_s_log_login', N'登录日志'),
('module.v_s_log_audit', N'操作日志'),
('module.v_s_log_technical', N'技术日志'),
('menu.log', N'日志'),
('menu.log_login', N'登录日志'),
('menu.log_audit', 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
/* ----------------------------------------------------------------------------
9. 自检
---------------------------------------------------------------------------- */
select '模块' as 项, count(*) as 行数 from dbo.s_module where b_path like '/system/log/%' or b_id = 'log'
union all
select '字段', count(*) from dbo.s_field where b_module_id in ('v_s_log_login', 'v_s_log_audit', 'v_s_log_technical')
union all
select '界面配置', count(*) from dbo.s_module_schema where b_module_id in ('v_s_log_login', 'v_s_log_audit', 'v_s_log_technical')
union all
select '菜单', count(*) from dbo.s_menu where b_path like '/system/log/%' or b_id = 'log'
union all
select '登录日志行数', count(*) from dbo.s_log_login
union all
select '操作日志行数', count(*) from dbo.s_log_audit
union all
select '技术日志行数', count(*) from dbo.s_log_technical;
GO
+199
View File
@@ -0,0 +1,199 @@
/* ============================================================================
FMS 模块注册脚本 — 用户管理(v_b_user)
目标库:FMS
前置条件:
b_user / b_dept 已由 sql/fms_core.sql 建表(核心表,本脚本不重复建表)。
本脚本写入:
1. 查询视图 dbo.v_b_user(含派生列 v_dept_name)
2. s_module 模块行(b_id = v_b_user,挂在 system 目录下)
3. s_field 字段行(12 个)
4. s_module_schema 界面配置(view / edit / query)
5. s_menu_module 绑定(user 菜单 → v_b_user 模块),使侧栏入口具备权限范围
可重复执行:先清理本模块的元数据行,再重建。
============================================================================ */
SET NOCOUNT ON;
GO
/* ----------------------------------------------------------------------------
1. 查询视图
b_view_table 指向本视图;s_field.b_field 必须是视图中真实存在的列。
v_dept_name 为派生列(v_ 前缀约定 => 只读,不参与保存),
写库仍走 s_module.b_save_table = b_user。
---------------------------------------------------------------------------- */
create or alter view dbo.v_b_user as
-- 注意:视图刻意不含 b_password。列表接口按视图 SELECT 返回行,带上密码等于把
-- 全员口令(现为明文存储)随分页数据一起下发,抓包/DevTools 即可见。
-- 密码只在编辑表单里录入,来源于 s_field 定义,不需要出现在查询视图里。
select u.b_id,
u.b_name,
u.b_dept_id,
d.b_name as v_dept_name, -- 所属部门名称(派生,只读)
u.b_bz,
u.b_canuse,
u.b_logincount,
u.b_created_by,
u.b_created_at,
u.b_updated_by,
u.b_updated_at
from dbo.b_user u
left join dbo.b_dept d on d.b_id = u.b_dept_id;
GO
/* ----------------------------------------------------------------------------
2. 模块定义(先清理,保证可重复执行)
---------------------------------------------------------------------------- */
delete from dbo.s_menu_module where b_module_id = 'v_b_user';
GO
delete from dbo.s_module_schema where b_module_id = 'v_b_user';
GO
delete from dbo.s_field where b_module_id = 'v_b_user';
GO
delete from dbo.s_module where b_id = 'v_b_user';
GO
/* b_id 即模块编码,前端 usePermissionStore 用 b_id 做权限范围:
canPower('v_b_user', 'create') => powerSet.has('v_b_user.create')
因此 b_id 必须与 src/views/system/user/index.vue 里的 MODULE_CODE 一致。
s_module 本身是树:system 为 depth 0,本模块挂其下 depth 1。
b_order_sql 留空表示按主键默认排序。 */
insert into dbo.s_module (b_id, b_parent_id, b_depth, b_path, b_name, b_i18n, b_module_type,
b_view_table, b_save_table, b_key_field, b_order_sql, b_canuse, b_xh, b_bz)
values ('v_b_user', 'system', 1, '/system/v_b_user/', N'用户管理', 'module.v_b_user',
'data', 'v_b_user', 'b_user', 'b_id', null, 1, 10,
N'系统管理 —— 用户列表(部门树过滤由页面负责)');
GO
/* ----------------------------------------------------------------------------
3. 字段定义
b_field 必须存在于 v_b_user;b_type 决定单元格渲染与编辑器:
input / number / checkbox / datetime / date(与已有模块保持一致)
b_xh 决定默认列顺序,b_name 为中文标题。
---------------------------------------------------------------------------- */
insert into dbo.s_field (b_module_id, b_field, b_name, b_i18n, b_type, b_canuse, b_xh)
values ('v_b_user', 'b_id', N'用户编码', null, 'input', 1, 10),
('v_b_user', 'b_name', N'用户名', null, 'input', 1, 20),
('v_b_user', 'b_dept_id', N'部门编码', null, 'input', 1, 30),
('v_b_user', 'v_dept_name', N'所属部门', null, 'input', 1, 40),
-- b_type = password:编辑弹窗渲染为掩码输入框(FmsField 的 typeDefaults 提供 type=password)
('v_b_user', 'b_password', N'密码', null, 'password', 1, 50),
('v_b_user', 'b_canuse', N'是否启用', null, 'checkbox', 1, 60),
('v_b_user', 'b_logincount', N'登录次数', null, 'number', 1, 70),
('v_b_user', 'b_bz', N'备注', null, 'input', 1, 80),
('v_b_user', 'b_created_by', N'创建人', null, 'input', 1, 90),
('v_b_user', 'b_created_at', N'创建时间', null, 'datetime', 1, 100),
('v_b_user', 'b_updated_by', N'最后修改人', null, 'input', 1, 110),
('v_b_user', 'b_updated_at', N'最后修改时间', null, 'datetime', 1, 120);
GO
/* ----------------------------------------------------------------------------
4. 界面配置(s_module_schema):view / edit / query
主键为 (b_module_id, b_schema_type)。JSON 结构需与 schemaRender.js 解析一致:
view :{ schemaVersion, columns: [ { field, width } | { type:'group', title, children } ] }
edit :{ schemaVersion, children: [ { field, span, required, readonly, defaultValue }
| { type:'group', ... } ] }
query :{ schemaVersion, groups: [ { conditions: [ { field, operator } ] } ], quick: [field] }
这些是「系统默认值」;模块管理页面调整会覆盖它们,
用户个人调整另存于 s_user_module_pref。
---------------------------------------------------------------------------- */
insert into dbo.s_module_schema (b_module_id, b_schema_type, b_schema_json, b_canuse)
values ('v_b_user', 'view', N'{
"schemaVersion": 1,
"columns": [
{ "field": "b_id", "width": 140 },
{ "field": "b_name", "width": 140 },
{ "field": "v_dept_name", "width": 160 },
{ "field": "b_canuse", "width": 90 },
{ "field": "b_logincount", "width": 100 },
{ "field": "b_bz", "width": 200 },
{ "field": "b_updated_at", "width": 170 }
]
}', 1),
('v_b_user', 'edit', N'{
"schemaVersion": 1,
"children": [
{ "type": "group", "title": "基本信息", "span": 48, "children": [
{ "field": "b_id", "span": 24, "required": true },
{ "field": "b_name", "span": 24, "required": true },
{ "field": "b_dept_id", "span": 24 },
{ "field": "b_password", "span": 24, "placeholder": "新增必填;编辑时留空表示不修改" },
{ "field": "b_canuse", "span": 24, "defaultValue": 1 },
{ "field": "b_bz", "span": 48 }
] }
]
}', 1),
('v_b_user', 'query', N'{
"schemaVersion": 1,
"groups": [
{ "conditions": [
{ "field": "b_id", "operator": "like" },
{ "field": "b_name", "operator": "like" }
] }
],
"quick": ["b_id", "b_name"]
}', 1);
GO
/* ----------------------------------------------------------------------------
5. 菜单绑定(s_menu_module)
s_menu 中已存在 b_id = 'user' 的 page 菜单(b_route = /system/user)。
这里把该菜单与 v_b_user 模块关联,
使其出现在角色的「菜单权限」树中,可被授权。
若菜单不存在则跳过(不擅自新建菜单行;菜单请用「菜单管理」维护)。
---------------------------------------------------------------------------- */
if exists (select 1 from dbo.s_menu where b_id = 'user')
begin
insert into dbo.s_menu_module (b_menu_id, b_module_id, b_xh, b_canuse)
values ('user', 'v_b_user', 10, 1);
update dbo.s_menu
set b_route = '/system/user',
b_path = '/system/user/',
b_canuse = 1
where b_id = 'user';
print 's_menu_module:已绑定 user 菜单 -> v_b_user 模块';
end
else
begin
print '未发现 b_id = user 的菜单:如需侧栏入口,请在「菜单管理」新建 page 菜单,路由填 /system/user';
end
GO
/* ----------------------------------------------------------------------------
6. 自检
---------------------------------------------------------------------------- */
select N'模块 s_module' as 项, count(*) as 行数 from dbo.s_module where b_id = 'v_b_user'
union all
select N'字段 s_field', count(*) from dbo.s_field where b_module_id = 'v_b_user'
union all
select N'界面配置 s_module_schema', count(*) from dbo.s_module_schema where b_module_id = 'v_b_user'
union all
select N'菜单绑定 s_menu_module', count(*) from dbo.s_menu_module where b_module_id = 'v_b_user'
union all
select N'视图列 v_b_user', count(*) from sys.columns where object_id = object_id('dbo.v_b_user')
union all
select N'视图数据行', count(*) from dbo.v_b_user;
GO
-- 视图内容抽样(确认 v_dept_name 关联可用)
select b_id, b_name, b_dept_id, v_dept_name, b_canuse, b_logincount from dbo.v_b_user;
GO