以下从 业务逻辑梳理、字段适配性分析、接口设计落地 三个维度,结合你的表结构和接口需求,完整拆解 SOP 管理模块的实现方案:
SOP 管理的核心是 “版本化管理 + 流程控制”,业务闭环如下:
创建SOP主记录
创建草稿版本
更新草稿内容
发布正式版本
版本对比/回滚
关联工单执行
对应你的接口需求,可映射为:
接口功能 | 业务阶段 | 核心逻辑 |
---|---|---|
POST 创建SOP | 主记录创建 | 初始化 sops 表,生成基础元数据 |
POST 创建新SOP版本 | 草稿版本创建 | 初始化 sop_versions 表(状态 Draft) |
PAT 更新SOP草稿 | 草稿内容迭代 | 更新 sop_versions.definition 字段 |
POST 发布SOP版本 | 正式版本发布 | 修改 sop_versions.status 为 Published,并更新 sops.latest_published_version_id |
POST 回滚SOP版本 | 版本回退 | 重置 sops.latest_published_version_id 到历史版本 |
GET 获取SOP版本历史 | 版本追溯 | 按 sop_id 筛选 sop_versions 记录 |
GET 版本对比 | 版本差异分析 | 对比两个 sop_versions.definition 的 JSON 差异 |
GET 获取SOP列表 | 主记录查询 | 检索 sops 表,支持筛选 / 分页 |
你的表结构已覆盖核心字段,但需注意以下细节:
sop_versions.status
(区分 Draft/Published/Archived
)sops.latest_published_version_id
(关联最新有效版本)sop_versions.definition
(存储流程定义的 JSON 内容)created_by/created_at/updated_by/updated_at
(记录操作人、操作时间)sop_versions
表中 (sop_id, version_string)
唯一(已有 UNIQUE
约束,可满足)。sops.latest_published_version_id
,并确保同一 SOP 仅有一个 Published
版本(需业务逻辑控制)。sop_versions.definition
需约定 JSON Schema(如:节点 node_id
、类型 node_type
、顺序 sort_order
),否则版本对比 / 执行会混乱。以下以 RESTful 接口设计 为例,结合表结构给出完整实现方案(以 PostgreSQL 为例,伪代码示意):
POST 创建SOP
功能:创建 SOP 主记录(无版本内容,需后续创建版本) 请求体:
json
{
"name": "车间设备每日巡检流程",
"description": "详细描述...",
"created_by": 123 // 当前登录用户 ID(需鉴权)
}
SQL 执行:
sql
INSERT INTO sops (id, name, description, created_by, created_at, updated_by, updated_at)
VALUES (
1001, -- 假设 ID 由雪花算法或自增生成
'车间设备每日巡检流程',
'详细描述...',
123,
NOW(),
123,
NOW()
);
响应:返回 sops.id
(如 1001
),用于关联后续版本。
POST 创建新SOP版本
功能:为 SOP 主记录创建草稿版本(状态 Draft
)
请求体:
json
{
"sop_id": 1001, // 关联主记录
"version_string": "V1.0-Draft",
"definition": {"nodes": [...], "edges": [...]}, // SOP 流程定义(JSON)
"created_by": 123
}
SQL 执行:
sql
INSERT INTO sop_versions (id, sop_id, version_string, status, definition, created_by, created_at)
VALUES (
2001, -- 版本记录 ID
1001,
"V1.0-Draft",
"Draft",
'{"nodes": [...]}', -- JSONB 类型
123,
NOW()
);
响应:返回 sop_versions.id
(如 2001
),用于后续更新。
PAT 更新SOP草稿
功能:迭代草稿版本的内容(仅允许 status=Draft
的版本)
请求体:
json
{
"id": 2001, // sop_versions.id
"definition": {"nodes": [...], "edges": [...]}, // 新的流程定义
"updated_by": 123
}
SQL 执行:
sql
UPDATE sop_versions
SET definition = '{"nodes": [...]}',
updated_by = 123,
updated_at = NOW()
WHERE id = 2001
AND status = 'Draft'; -- 仅允许草稿更新
响应:返回更新后的 definition
摘要(或 HTTP 204 成功)。
POST 发布SOP版本
功能:将草稿版本转为正式版本,并更新主表的 latest_published_version_id
请求体:
json
{
"sop_version_id": 2001, // 要发布的版本 ID
"operator_id": 123 // 发布人 ID
}
SQL 执行:
sql
BEGIN; -- 事务保证原子性
-- 1. 标记版本为已发布
UPDATE sop_versions
SET status = 'Published',
published_at = NOW(),
updated_by = 123,
updated_at = NOW()
WHERE id = 2001
AND status = 'Draft'; -- 防止重复发布
-- 2. 更新主表最新版本
UPDATE sops
SET latest_published_version_id = 2001,
updated_by = 123,
updated_at = NOW()
WHERE id = 1001;
COMMIT;
响应:返回 sops.latest_published_version_id
(如 2001
),标记发布成功。
POST 回滚SOP版本
功能:将主表的 latest_published_version_id
回退到历史版本
请求体:
json
{
"sop_id": 1001, // 要回滚的 SOP 主记录
"target_version_id": 1002 // 回退到的历史版本 ID(需已发布)
}
SQL 执行:
sql
UPDATE sops
SET latest_published_version_id = 1002,
updated_by = 123,
updated_at = NOW()
WHERE id = 1001
AND EXISTS ( -- 校验目标版本是否合法
SELECT 1 FROM sop_versions
WHERE id = 1002
AND status IN ('Published', 'Archived')
);
响应:返回回退后的 latest_published_version_id
(如 1002
)。
GET 获取SOP版本历史
功能:按 SOP 主记录查询所有版本(含草稿、已发布、归档) 请求参数:
plaintext
sop_id=1001 // 要查询的 SOP 主记录 ID
SQL 执行:
sql
SELECT id, version_string, status, definition, created_at
FROM sop_versions
WHERE sop_id = 1001
ORDER BY created_at DESC; -- 按创建时间倒序(新的在前)
响应体:
json
[
{"id":2001, "version_string":"V1.0", "status":"Published", ...},
{"id":2002, "version_string":"V0.9", "status":"Archived", ...}
]
GET 版本对比
功能:对比两个版本的 definition
差异(需 JSON diff 工具)
请求参数:
plaintext
sop_id=1001&version_id_1=2001&version_id_2=2002
实现逻辑:
sop_versions
表中取出两个版本的 definition
(JSONB 类型)。json-diff
、Python 的 jsondiff
)生成差异报告。
响应体:json
{
"diff": [
{"path": "/nodes/0/name", "old": "Check1", "new": "Check2"},
{"path": "/edges/1", "status": "removed"}
]
}
GET 获取SOP列表
功能:查询 sops
表,支持筛选、分页
请求参数:
plaintext
page=1&size=10&name_like=设备巡检 // 分页+名称模糊搜索
SQL 执行:
sql
SELECT id, name, latest_published_version_id, created_at
FROM sops
WHERE name ILIKE '%设备巡检%' -- 模糊搜索
ORDER BY created_at DESC
LIMIT 10 OFFSET 0; -- 分页
响应体:
json
{
"total": 25,
"page": 1,
"size": 10,
"items": [
{"id":1001, "name":"车间设备每日巡检流程", ...},
{"id":1002, "name":"产线安全检查SOP", ...}
]
}
事务一致性:
涉及 sops
和 sop_versions
联动更新的操作(如发布版本),必须用事务保证数据一致性(参考 POST 发布SOP版本
的 BEGIN/COMMIT
)。
JSON Schema 规范:
sop_versions.definition
的结构必须提前约定 Schema(如:节点必须包含 node_id
、type
、description
字段),否则版本对比和工单执行会混乱。
权限控制:
所有接口需增加身份校验(如 created_by
必须等于登录用户 ID,或符合角色权限),防止越权操作。
索引优化:
高频查询字段(如 sop_versions.sop_id
、sop_versions.status
)需创建复合索引:
sql
CREATE INDEX idx_sop_versions_sop_status ON sop_versions(sop_id, status);
通过以上设计,你的表结构完全可以支撑接口需求,核心是通过 sops
(主记录) + sop_versions
(版本明细)的联动,实现 SOP 从创建、迭代到发布、回退的完整生命周期管理。