431 lines
20 KiB
Transact-SQL
431 lines
20 KiB
Transact-SQL
/* ============================================================================
|
||
FMS 模块注册脚本 — 流程(wf_* 的配置与监控部分)
|
||
|
||
依据文档:FMS新系统核心表结构设计.md「16. 工作流与审批」、
|
||
FMS工作流与审批设计.md(§14 前端页面)
|
||
|
||
前置条件:
|
||
wf_* 表已由 fms_workflow.sql 建好。
|
||
|
||
使用说明:
|
||
1. 执行前先切换到目标数据库(USE FMS)。
|
||
2. 本脚本写查询视图 + 模块元数据(s_module / s_field / s_module_schema)
|
||
+ 菜单绑定(s_menu_module),不含业务数据。
|
||
3. 脚本可重复执行:先按模块路径清理,再重建。
|
||
4. 四个模块都是只读数据源(b_save_table 为空):流程的写入必须走流程服务
|
||
(校验、版本快照、发布后不可改、幂等都在服务端保证),通用保存接口不参与。
|
||
|
||
不注册的模块(有意为之):
|
||
- wf_task / wf_cc:审批中心的「我的待办 / 抄送我的」是动作页,需要按当前用户
|
||
过滤、按状态给不同按钮,走专用 API;登记成数据模块会给通用保存接口开后门。
|
||
- wf_node / wf_edge / wf_actor_rule:设计器内部结构,只在画布与属性面板里读写。
|
||
- wf_action:审批历史是单据详情页的时间线,不做独立列表。
|
||
- wf_outbox:内部消息队列,只给运维看。
|
||
============================================================================ */
|
||
|
||
SET NOCOUNT ON;
|
||
GO
|
||
|
||
/* ----------------------------------------------------------------------------
|
||
1. 查询视图
|
||
|
||
两个目的:
|
||
a) 裁剪列:wf_version.b_canvas_json、wf_node.b_config_json、wf_instance.b_context_json
|
||
/ b_snapshot_json 都是大 JSON,不进程列表字段;
|
||
b) 派生展示列:状态枚举拼中文、关联出名称、聚合出计数,避免前端写转换逻辑。
|
||
约定:v_ 前缀列是派生列(只读),其余列名与基表保持一致。
|
||
---------------------------------------------------------------------------- */
|
||
|
||
/* 流程定义:带出已发布版本、版本数、绑定模块数 */
|
||
create or alter view dbo.v_wf_definition as
|
||
select d.b_id,
|
||
d.b_name,
|
||
d.b_canuse,
|
||
case when d.b_canuse = 1 then N'启用' else N'停用' end as v_canuse_name,
|
||
p.b_version_no as v_published_version_no,
|
||
p.b_published_at as v_published_at,
|
||
p.b_published_by as v_published_by,
|
||
(select count(*) from dbo.wf_version x where x.b_definition_id = d.b_id) as v_version_count,
|
||
(select count(*) from dbo.wf_binding g
|
||
where g.b_canuse = 1
|
||
and exists (select 1 from dbo.wf_version v where v.b_id = g.b_version_id and v.b_definition_id = d.b_id)) as v_binding_count,
|
||
d.b_bz,
|
||
d.b_created_at,
|
||
d.b_updated_at
|
||
from dbo.wf_definition d
|
||
outer apply (select top 1 v.b_version_no, v.b_published_at, v.b_published_by
|
||
from dbo.wf_version v
|
||
where v.b_definition_id = d.b_id
|
||
and v.b_status = 'published'
|
||
order by v.b_version_no desc) p;
|
||
GO
|
||
|
||
/* 流程版本:状态拼中文,带出定义名称与节点数;b_canvas_json 不进视图 */
|
||
create or alter view dbo.v_wf_version as
|
||
select v.b_id,
|
||
v.b_definition_id,
|
||
d.b_name as v_definition_name,
|
||
v.b_version_no,
|
||
v.b_status,
|
||
case v.b_status
|
||
when 'draft' then N'草稿'
|
||
when 'published' then N'已发布'
|
||
when 'retired' then N'已停用'
|
||
else v.b_status end as v_status_name,
|
||
(select count(*) from dbo.wf_node n where n.b_version_id = v.b_id) as v_node_count,
|
||
v.b_bz,
|
||
v.b_published_by,
|
||
v.b_published_at,
|
||
v.b_updated_at
|
||
from dbo.wf_version v
|
||
left join dbo.wf_definition d on d.b_id = v.b_definition_id;
|
||
GO
|
||
|
||
/* 流程绑定:模块名、事件中文、版本显示名 */
|
||
create or alter view dbo.v_wf_binding as
|
||
select g.b_id,
|
||
g.b_module_id,
|
||
m.b_name as v_module_name,
|
||
g.b_event,
|
||
case g.b_event
|
||
when 'submit' then N'送审'
|
||
when 'resubmit' then N'重新提交'
|
||
when 'change' then N'变更'
|
||
else g.b_event end as v_event_name,
|
||
g.b_version_id,
|
||
isnull(d.b_name + N' V' + cast(v.b_version_no as nvarchar(10)), g.b_version_id) as v_version_name,
|
||
g.b_priority,
|
||
g.b_effective_from,
|
||
g.b_effective_to,
|
||
g.b_canuse,
|
||
case when g.b_canuse = 1 then N'启用' else N'停用' end as v_canuse_name,
|
||
g.b_bz
|
||
from dbo.wf_binding g
|
||
left join dbo.s_module m on m.b_id = g.b_module_id
|
||
left join dbo.wf_version v on v.b_id = g.b_version_id
|
||
left join dbo.wf_definition d on d.b_id = v.b_definition_id;
|
||
GO
|
||
|
||
/* 流程实例(流程监控):状态中文、发起人姓名、当前待办数、耗时;两个大 JSON 不进视图 */
|
||
create or alter view dbo.v_wf_instance as
|
||
select i.b_id,
|
||
i.b_business_no,
|
||
i.b_module_id,
|
||
i.b_definition_id,
|
||
i.b_version_id,
|
||
i.b_initiator_id,
|
||
u.b_name as v_initiator_name,
|
||
i.b_status,
|
||
case i.b_status
|
||
when 'running' then N'运行中'
|
||
when 'approved' then N'已通过'
|
||
when 'rejected' then N'已驳回'
|
||
when 'returned' then N'已退回'
|
||
when 'withdrawn' then N'已撤回'
|
||
when 'cancelled' then N'已取消'
|
||
when 'expired' then N'已过期'
|
||
when 'error' then N'异常待处理'
|
||
else i.b_status end as v_status_name,
|
||
(select count(*) from dbo.wf_task t
|
||
where t.b_instance_id = i.b_id and t.b_status in ('pending', 'claimed')) as v_pending_task_count,
|
||
i.b_started_at,
|
||
i.b_completed_at,
|
||
datediff(minute, i.b_started_at, isnull(i.b_completed_at, sysdatetime())) as v_duration_minutes
|
||
from dbo.wf_instance i
|
||
left join dbo.b_user u on u.b_id = i.b_initiator_id;
|
||
GO
|
||
|
||
/* ----------------------------------------------------------------------------
|
||
2. 清理(脚本可重复执行):本分组下的界面配置、字段、模块行与菜单绑定
|
||
---------------------------------------------------------------------------- */
|
||
|
||
delete from dbo.s_module_schema
|
||
where b_module_id in (select b_id from dbo.s_module where b_path like '/workflow/%');
|
||
GO
|
||
|
||
delete from dbo.s_field
|
||
where b_module_id in (select b_id from dbo.s_module where b_path like '/workflow/%');
|
||
GO
|
||
|
||
delete from dbo.s_module
|
||
where b_path like '/workflow/%' or b_id = 'workflow';
|
||
GO
|
||
|
||
delete from dbo.s_menu_module where b_menu_id = 'workflow';
|
||
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 ('workflow', null, 0, '/workflow/', N'流程', 'module.workflow', 'module', 1, 20,
|
||
N'流程定义、版本、绑定与运行实例;只读,写入一律走流程服务');
|
||
GO
|
||
|
||
/* ----------------------------------------------------------------------------
|
||
4. 数据模块(data 类型,只读)
|
||
|
||
b_view_table 指向上面的视图,b_save_table 留空 = 列表页不提供新增 / 编辑 / 删除。
|
||
---------------------------------------------------------------------------- */
|
||
|
||
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_wf_definition', 'workflow', 1, '/workflow/v_wf_definition/', N'流程定义', 'module.v_wf_definition', 'data',
|
||
'v_wf_definition', null, 'b_id', 'b_id ASC', 1, 10,
|
||
N'流程的稳定身份;发布内容在版本表,绑定关系在流程绑定表');
|
||
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_wf_version', 'workflow', 1, '/workflow/v_wf_version/', N'流程版本', 'module.v_wf_version', 'data',
|
||
'v_wf_version', null, 'b_id', 'b_version_no DESC', 1, 20,
|
||
N'draft 可编辑,published 可被新实例使用,retired 不再接受新实例;已发布版本不可原地修改');
|
||
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_wf_binding', 'workflow', 1, '/workflow/v_wf_binding/', N'流程绑定', 'module.v_wf_binding', 'data',
|
||
'v_wf_binding', null, 'b_id', 'b_module_id ASC, b_priority ASC', 1, 30,
|
||
N'模块 + 业务事件 + 条件 → 流程版本;同一业务上下文只能匹配一个最终流程');
|
||
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_wf_instance', 'workflow', 1, '/workflow/v_wf_instance/', N'流程实例', 'module.v_wf_instance', 'data',
|
||
'v_wf_instance', null, 'b_id', 'b_started_at DESC', 1, 40,
|
||
N'流程监控:某张业务单据某次提交的运行情况,含当前待办数与耗时');
|
||
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_wf_definition', 'b_id', N'流程编码', null, 'input', 1, 10),
|
||
('v_wf_definition', 'b_name', N'流程名称', null, 'input', 1, 20),
|
||
('v_wf_definition', 'v_published_version_no', N'已发布版本', null, 'number', 1, 30),
|
||
('v_wf_definition', 'v_version_count', N'版本数', null, 'number', 1, 40),
|
||
('v_wf_definition', 'v_binding_count', N'绑定模块数', null, 'number', 1, 50),
|
||
('v_wf_definition', 'v_published_at', N'发布时间', null, 'datetime', 1, 60),
|
||
('v_wf_definition', 'v_published_by', N'发布人', null, 'input', 1, 70),
|
||
('v_wf_definition', 'v_canuse_name', N'是否启用', null, 'input', 1, 80),
|
||
('v_wf_definition', 'b_bz', N'备注', null, 'input', 1, 90),
|
||
('v_wf_definition', 'b_updated_at', N'最后修改时间', null, 'datetime', 1, 100);
|
||
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_wf_version', 'b_definition_id', N'流程编码', null, 'input', 1, 10),
|
||
('v_wf_version', 'v_definition_name', N'流程名称', null, 'input', 1, 20),
|
||
('v_wf_version', 'b_version_no', N'版本号', null, 'number', 1, 30),
|
||
('v_wf_version', 'v_status_name', N'版本状态', null, 'input', 1, 40),
|
||
('v_wf_version', 'v_node_count', N'节点数', null, 'number', 1, 50),
|
||
('v_wf_version', 'b_published_by', N'发布人', null, 'input', 1, 60),
|
||
('v_wf_version', 'b_published_at', N'发布时间', null, 'datetime', 1, 70),
|
||
('v_wf_version', 'b_bz', N'备注', null, 'input', 1, 80),
|
||
('v_wf_version', 'b_updated_at', N'最后修改时间', null, 'datetime', 1, 90),
|
||
('v_wf_version', 'b_id', N'版本 ID', null, 'input', 1, 100);
|
||
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_wf_binding', 'b_module_id', N'模块编码', null, 'input', 1, 10),
|
||
('v_wf_binding', 'v_module_name', N'模块名称', null, 'input', 1, 20),
|
||
('v_wf_binding', 'v_event_name', N'业务事件', null, 'input', 1, 30),
|
||
('v_wf_binding', 'v_version_name', N'流程版本', null, 'input', 1, 40),
|
||
('v_wf_binding', 'b_priority', N'优先级', null, 'number', 1, 50),
|
||
('v_wf_binding', 'b_effective_from', N'生效开始', null, 'datetime', 1, 60),
|
||
('v_wf_binding', 'b_effective_to', N'生效结束', null, 'datetime', 1, 70),
|
||
('v_wf_binding', 'v_canuse_name', N'是否启用', null, 'input', 1, 80),
|
||
('v_wf_binding', 'b_bz', N'备注', null, 'input', 1, 90),
|
||
('v_wf_binding', 'b_id', N'绑定 ID', null, 'input', 1, 100);
|
||
GO
|
||
|
||
/* 5.4 流程实例 */
|
||
insert into dbo.s_field (b_module_id, b_field, b_name, b_i18n, b_type, b_canuse, b_xh)
|
||
values ('v_wf_instance', 'b_business_no', N'业务单号', null, 'input', 1, 10),
|
||
('v_wf_instance', 'b_module_id', N'模块编码', null, 'input', 1, 20),
|
||
('v_wf_instance', 'b_definition_id', N'流程编码', null, 'input', 1, 30),
|
||
('v_wf_instance', 'v_initiator_name', N'发起人', null, 'input', 1, 40),
|
||
('v_wf_instance', 'v_status_name', N'实例状态', null, 'input', 1, 50),
|
||
('v_wf_instance', 'v_pending_task_count', N'当前待办数', null, 'number', 1, 60),
|
||
('v_wf_instance', 'b_started_at', N'开始时间', null, 'datetime', 1, 70),
|
||
('v_wf_instance', 'b_completed_at', N'结束时间', null, 'datetime', 1, 80),
|
||
('v_wf_instance', 'v_duration_minutes', N'耗时(分钟)', null, 'number', 1, 90),
|
||
('v_wf_instance', 'b_id', N'实例 ID', null, 'input', 1, 100);
|
||
GO
|
||
|
||
/* ----------------------------------------------------------------------------
|
||
6. 界面配置(s_module_schema):view / query
|
||
|
||
只读模块不生成 edit 配置。列宽按内容给:编码类窄、名称类宽、时间类 170。
|
||
---------------------------------------------------------------------------- */
|
||
|
||
insert into dbo.s_module_schema (b_module_id, b_schema_type, b_schema_json, b_canuse)
|
||
values ('v_wf_definition', 'view', N'{
|
||
"schemaVersion": 1,
|
||
"columns": [
|
||
{ "field": "b_id", "width": 160 },
|
||
{ "field": "b_name", "width": 200 },
|
||
{ "field": "v_published_version_no", "width": 100 },
|
||
{ "field": "v_version_count", "width": 90 },
|
||
{ "field": "v_binding_count", "width": 100 },
|
||
{ "field": "v_canuse_name", "width": 90 },
|
||
{ "field": "v_published_at", "width": 170 },
|
||
{ "field": "v_published_by", "width": 110 },
|
||
{ "field": "b_bz", "width": 200 }
|
||
]
|
||
}', 1),
|
||
('v_wf_definition', 'query', N'{
|
||
"schemaVersion": 1,
|
||
"groups": [
|
||
{ "conditions": [
|
||
{ "field": "b_name", "operator": "like" },
|
||
{ "field": "b_id", "operator": "like" },
|
||
{ "field": "v_canuse_name", "operator": "eq" },
|
||
{ "field": "v_published_at", "operator": "between" }
|
||
] }
|
||
],
|
||
"quick": ["b_name", "b_id"]
|
||
}', 1);
|
||
GO
|
||
|
||
insert into dbo.s_module_schema (b_module_id, b_schema_type, b_schema_json, b_canuse)
|
||
values ('v_wf_version', 'view', N'{
|
||
"schemaVersion": 1,
|
||
"columns": [
|
||
{ "field": "b_definition_id", "width": 160 },
|
||
{ "field": "v_definition_name","width": 200 },
|
||
{ "field": "b_version_no", "width": 90 },
|
||
{ "field": "v_status_name", "width": 90 },
|
||
{ "field": "v_node_count", "width": 90 },
|
||
{ "field": "b_published_at", "width": 170 },
|
||
{ "field": "b_published_by", "width": 110 },
|
||
{ "field": "b_bz", "width": 200 }
|
||
]
|
||
}', 1),
|
||
('v_wf_version', 'query', N'{
|
||
"schemaVersion": 1,
|
||
"groups": [
|
||
{ "conditions": [
|
||
{ "field": "b_definition_id", "operator": "eq" },
|
||
{ "field": "v_definition_name","operator": "like" },
|
||
{ "field": "v_status_name", "operator": "eq" },
|
||
{ "field": "b_published_at", "operator": "between" }
|
||
] }
|
||
],
|
||
"quick": ["v_definition_name"]
|
||
}', 1);
|
||
GO
|
||
|
||
insert into dbo.s_module_schema (b_module_id, b_schema_type, b_schema_json, b_canuse)
|
||
values ('v_wf_binding', 'view', N'{
|
||
"schemaVersion": 1,
|
||
"columns": [
|
||
{ "field": "b_module_id", "width": 160 },
|
||
{ "field": "v_module_name", "width": 180 },
|
||
{ "field": "v_event_name", "width": 100 },
|
||
{ "field": "v_version_name", "width": 220 },
|
||
{ "field": "b_priority", "width": 80 },
|
||
{ "field": "v_canuse_name", "width": 90 },
|
||
{ "field": "b_effective_from","width": 170 },
|
||
{ "field": "b_effective_to", "width": 170 },
|
||
{ "field": "b_bz", "width": 200 }
|
||
]
|
||
}', 1),
|
||
('v_wf_binding', 'query', N'{
|
||
"schemaVersion": 1,
|
||
"groups": [
|
||
{ "conditions": [
|
||
{ "field": "b_module_id", "operator": "eq" },
|
||
{ "field": "v_event_name", "operator": "eq" },
|
||
{ "field": "v_version_name","operator": "like" },
|
||
{ "field": "v_canuse_name","operator": "eq" }
|
||
] }
|
||
],
|
||
"quick": ["b_module_id"]
|
||
}', 1);
|
||
GO
|
||
|
||
insert into dbo.s_module_schema (b_module_id, b_schema_type, b_schema_json, b_canuse)
|
||
values ('v_wf_instance', 'view', N'{
|
||
"schemaVersion": 1,
|
||
"columns": [
|
||
{ "field": "b_business_no", "width": 180 },
|
||
{ "field": "b_module_id", "width": 150 },
|
||
{ "field": "b_definition_id", "width": 160 },
|
||
{ "field": "v_initiator_name", "width": 110 },
|
||
{ "field": "v_status_name", "width": 100 },
|
||
{ "field": "v_pending_task_count", "width": 110 },
|
||
{ "field": "b_started_at", "width": 170 },
|
||
{ "field": "b_completed_at", "width": 170 },
|
||
{ "field": "v_duration_minutes", "width": 110 }
|
||
]
|
||
}', 1),
|
||
('v_wf_instance', 'query', N'{
|
||
"schemaVersion": 1,
|
||
"groups": [
|
||
{ "conditions": [
|
||
{ "field": "b_business_no", "operator": "like" },
|
||
{ "field": "v_initiator_name","operator": "like" },
|
||
{ "field": "v_status_name", "operator": "eq" },
|
||
{ "field": "b_started_at", "operator": "between" }
|
||
] }
|
||
],
|
||
"quick": ["b_business_no"]
|
||
}', 1);
|
||
GO
|
||
|
||
/* ----------------------------------------------------------------------------
|
||
7. 菜单绑定(s_menu_module):流程管理页挂上三个配置模块
|
||
审批中心各页是专用页面(待办 / 抄送 / 我发起的 / 我已处理),不绑数据模块。
|
||
---------------------------------------------------------------------------- */
|
||
|
||
insert into dbo.s_menu_module (b_menu_id, b_module_id, b_xh, b_canuse)
|
||
values ('workflow', 'v_wf_definition', 10, 1),
|
||
('workflow', 'v_wf_version', 20, 1),
|
||
('workflow', 'v_wf_binding', 30, 1),
|
||
('workflow', 'v_wf_instance', 40, 1);
|
||
GO
|
||
|
||
/* ----------------------------------------------------------------------------
|
||
8. 多语言(s_i18n):模块名,默认语言为中文时写入中文值
|
||
---------------------------------------------------------------------------- */
|
||
|
||
declare @i18n table (k varchar(150) primary key, v nvarchar(1000) not null);
|
||
insert into @i18n (k, v) values
|
||
('module.workflow', N'流程'),
|
||
('module.v_wf_definition', N'流程定义'),
|
||
('module.v_wf_version', N'流程版本'),
|
||
('module.v_wf_binding', N'流程绑定'),
|
||
('module.v_wf_instance', 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 '/workflow/%' or b_id = 'workflow'
|
||
union all
|
||
select '字段', count(*) from dbo.s_field where b_module_id in
|
||
('v_wf_definition', 'v_wf_version', 'v_wf_binding', 'v_wf_instance')
|
||
union all
|
||
select '界面配置', count(*) from dbo.s_module_schema where b_module_id in
|
||
('v_wf_definition', 'v_wf_version', 'v_wf_binding', 'v_wf_instance')
|
||
union all
|
||
select '菜单绑定', count(*) from dbo.s_menu_module where b_menu_id = 'workflow'
|
||
union all
|
||
select '视图', count(*) from sys.views where name in
|
||
('v_wf_definition', 'v_wf_version', 'v_wf_binding', 'v_wf_instance');
|
||
GO |