|
|
@@ -7,6 +7,7 @@ from sqlalchemy.orm import Session
|
|
|
|
|
|
from app.crud import oa_approval as oa_crud
|
|
|
from app.models.models import OaRole
|
|
|
+from app.services.oa_assignee import VALID_ASSIGNEE_TYPES, normalize_cc_assignee_types
|
|
|
|
|
|
# 可填控件(FormCreate / 自建控件字典交集;布局类不计)
|
|
|
FILLABLE_TYPES = frozenset(
|
|
|
@@ -57,16 +58,6 @@ LAYOUT_TYPES = frozenset(
|
|
|
}
|
|
|
)
|
|
|
|
|
|
-VALID_ASSIGNEE_TYPES = frozenset(
|
|
|
- {
|
|
|
- "users",
|
|
|
- "oa_roles",
|
|
|
- "dept_leader",
|
|
|
- "direct_supervisor",
|
|
|
- "initiator_select",
|
|
|
- }
|
|
|
-)
|
|
|
-
|
|
|
VALID_NODE_TYPES = frozenset({"start", "approval", "cc", "condition", "end"})
|
|
|
|
|
|
# 系统条件伪字段(非表单控件)
|
|
|
@@ -212,11 +203,11 @@ def validate_flow_tree(flow_tree: Any) -> List[str]:
|
|
|
errors.append(f"{path}:结束节点后不应再有子节点")
|
|
|
return
|
|
|
|
|
|
- if ntype in ("approval", "cc"):
|
|
|
+ if ntype == "approval":
|
|
|
cfg = node.get("approverConfig") or node.get("approver_config") or {}
|
|
|
if not isinstance(cfg, dict):
|
|
|
cfg = {}
|
|
|
- # 抄送也需要明确接收人策略
|
|
|
+ # 审批只认单字段 assigneeType(忽略 assigneeTypes)
|
|
|
at = (cfg.get("assigneeType") or cfg.get("assignee_type") or "").strip()
|
|
|
if not at:
|
|
|
errors.append(f"{path}:未配置审批人/抄送人策略")
|
|
|
@@ -231,7 +222,27 @@ def validate_flow_tree(flow_tree: Any) -> List[str]:
|
|
|
codes = cfg.get("oaRoleCodes") or cfg.get("oa_role_codes") or []
|
|
|
if not rids and not codes:
|
|
|
errors.append(f"{path}:工作流角色不能为空")
|
|
|
- # dept_leader / direct_supervisor / initiator_select:类型本身即完备
|
|
|
+
|
|
|
+ if ntype == "cc":
|
|
|
+ cfg = node.get("approverConfig") or node.get("approver_config") or {}
|
|
|
+ if not isinstance(cfg, dict):
|
|
|
+ cfg = {}
|
|
|
+ types = normalize_cc_assignee_types(cfg)
|
|
|
+ if not types:
|
|
|
+ errors.append(f"{path}:未配置审批人/抄送人策略")
|
|
|
+ else:
|
|
|
+ for at in types:
|
|
|
+ if at not in VALID_ASSIGNEE_TYPES:
|
|
|
+ errors.append(f"{path}:不支持的审批人类型「{at}」")
|
|
|
+ elif at == "users":
|
|
|
+ ids = cfg.get("userIds") or cfg.get("user_ids") or []
|
|
|
+ if not ids:
|
|
|
+ errors.append(f"{path}:指定成员不能为空")
|
|
|
+ elif at == "oa_roles":
|
|
|
+ rids = cfg.get("oaRoleIds") or cfg.get("oa_role_ids") or []
|
|
|
+ codes = cfg.get("oaRoleCodes") or cfg.get("oa_role_codes") or []
|
|
|
+ if not rids and not codes:
|
|
|
+ errors.append(f"{path}:工作流角色不能为空")
|
|
|
|
|
|
if ntype == "condition":
|
|
|
groups = node.get("conditionGroups") or node.get("condition_groups") or []
|