Files
workspace/code/fms/sql/fms_workflow_module.sql
T
2026-09-23 16:54:54 +08:00

505 lines
24 KiB
Transact-SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ============================================================================
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, "visible": false }
]
}', 1),
('v_wf_definition', 'query', N'{
"schemaVersion": 2,
"defaultViewCode": "all",
"views": [
{ "code": "all", "label": "全部", "order": 10 },
{ "code": "recent_published", "label": "近三个月发布", "order": 20,
"conditions": [ { "field": "v_published_at", "operator": "between", "value": { "preset": "recent_3_months" } } ] },
{ "code": "unpublished", "label": "未发布", "order": 30,
"conditions": [ { "field": "v_published_at", "operator": "is_null" } ] }
],
"keywordSearch": {
"placeholder": "搜索流程名称、编码",
"trigger": "enter_or_debounce",
"fields": ["b_name", "b_id"]
},
"quickFilters": [
{ "field": "v_published_at", "order": 10 },
{ "field": "v_canuse_name", "order": 20 }
],
"filterGroups": [
{ "code": "basic", "label": "基础信息", "order": 10, "fields": ["b_name", "b_id", "v_canuse_name"] },
{ "code": "time", "label": "发布时间", "order": 20, "fields": ["v_published_at", "v_published_by"] }
],
"queryFields": {
"b_name": { "component": "input", "operator": "like" },
"b_id": { "component": "input", "operator": "like" },
"v_canuse_name": { "component": "select", "operator": "eq" },
"v_published_at": { "component": "datetime", "operator": "between" },
"v_published_by": { "component": "input", "operator": "like" }
}
}', 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, "visible": false },
{ "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, "visible": false }
]
}', 1),
('v_wf_version', 'query', N'{
"schemaVersion": 2,
"defaultViewCode": "all",
"views": [
{ "code": "all", "label": "全部", "order": 10 },
{ "code": "unpublished", "label": "未发布", "order": 20,
"conditions": [ { "field": "b_published_at", "operator": "is_null" } ] }
],
"keywordSearch": {
"placeholder": "搜索流程名称、定义编码",
"trigger": "enter_or_debounce",
"fields": ["v_definition_name", "b_definition_id"]
},
"quickFilters": [
{ "field": "b_published_at", "order": 10 },
{ "field": "v_status_name", "order": 20 }
],
"filterGroups": [
{ "code": "basic", "label": "基础信息", "order": 10, "fields": ["v_definition_name", "b_definition_id", "v_status_name", "v_node_count"] },
{ "code": "time", "label": "发布时间", "order": 20, "fields": ["b_published_at", "b_published_by"] }
],
"queryFields": {
"b_definition_id": { "component": "input", "operator": "eq" },
"v_definition_name": { "component": "input", "operator": "like" },
"v_status_name": { "component": "select", "operator": "eq" },
"b_published_at": { "component": "datetime", "operator": "between" },
"b_published_by": { "component": "input", "operator": "like" }
}
}', 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, "visible": false },
{ "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, "visible": false },
{ "field": "b_bz", "width": 200, "visible": false }
]
}', 1),
('v_wf_binding', 'query', N'{
"schemaVersion": 2,
"defaultViewCode": "all",
"views": [
{ "code": "all", "label": "全部", "order": 10 }
],
"keywordSearch": {
"placeholder": "搜索模块、流程版本",
"trigger": "enter_or_debounce",
"fields": ["v_module_name", "v_version_name", "b_module_id"]
},
"quickFilters": [
{ "field": "v_event_name", "order": 10 },
{ "field": "v_canuse_name", "order": 20 }
],
"filterGroups": [
{ "code": "basic", "label": "基础信息", "order": 10, "fields": ["b_module_id", "v_module_name", "v_event_name", "v_version_name"] },
{ "code": "state", "label": "状态", "order": 20, "fields": ["v_canuse_name", "b_priority", "b_effective_from", "b_effective_to"] }
],
"queryFields": {
"b_module_id": { "component": "input", "operator": "eq" },
"v_module_name": { "component": "input", "operator": "like" },
"v_event_name": { "component": "select", "operator": "eq" },
"v_version_name": { "component": "input", "operator": "like" },
"v_canuse_name": { "component": "select", "operator": "eq" },
"b_priority": { "component": "number", "operator": "eq" },
"b_effective_from": { "component": "datetime", "operator": "between" },
"b_effective_to": { "component": "datetime", "operator": "between" }
}
}', 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, "visible": false },
{ "field": "b_definition_id", "width": 160, "visible": false },
{ "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": 2,
"defaultViewCode": "all",
"views": [
{ "code": "all", "label": "全部", "order": 10 },
{ "code": "running", "label": "进行中", "order": 20, "showCount": true,
"conditions": [ { "field": "b_completed_at", "operator": "is_null" } ] },
{ "code": "today", "label": "今天发起", "order": 30,
"conditions": [ { "field": "b_started_at", "operator": "between", "value": { "preset": "today" } } ] }
],
"keywordSearch": {
"placeholder": "搜索业务单号、发起人",
"trigger": "enter_or_debounce",
"fields": ["b_business_no", "v_initiator_name", "b_module_id"]
},
"quickFilters": [
{ "field": "b_started_at", "order": 10 },
{ "field": "v_status_name", "order": 20 }
],
"filterGroups": [
{ "code": "basic", "label": "基础信息", "order": 10, "fields": ["b_business_no", "b_module_id", "b_definition_id", "v_initiator_name"] },
{ "code": "state", "label": "状态与耗时", "order": 20, "fields": ["v_status_name", "v_pending_task_count", "v_duration_minutes"] },
{ "code": "time", "label": "时间", "order": 30, "fields": ["b_started_at", "b_completed_at"] }
],
"queryFields": {
"b_business_no": { "component": "input", "operator": "like" },
"v_initiator_name": { "component": "input", "operator": "like" },
"v_status_name": { "component": "select", "operator": "eq" },
"b_started_at": { "component": "datetime", "operator": "between" },
"b_completed_at": { "component": "datetime", "operator": "between" }
}
}', 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