|
|
@@ -32,6 +32,8 @@ class OaEngineError(ValueError):
|
|
|
|
|
|
_AUTO_PASS_COMMENT = "系统自动通过"
|
|
|
|
|
|
+INITIATOR_CONDITION_FIELD = "__initiator__"
|
|
|
+
|
|
|
|
|
|
def _loads(text: Optional[str], default: Any = None) -> Any:
|
|
|
if text is None or text == "":
|
|
|
@@ -351,7 +353,10 @@ def _pending_people_for_node(
|
|
|
|
|
|
|
|
|
def _iter_resolved_path_nodes(
|
|
|
- root: Optional[Dict[str, Any]], form_data: Optional[Dict[str, Any]]
|
|
|
+ root: Optional[Dict[str, Any]],
|
|
|
+ form_data: Optional[Dict[str, Any]],
|
|
|
+ *,
|
|
|
+ initiator_user_id: Optional[str] = None,
|
|
|
) -> Optional[List[Dict[str, Any]]]:
|
|
|
"""沿条件命中路径收集节点;无法匹配时返回 None。"""
|
|
|
if not isinstance(root, dict):
|
|
|
@@ -365,12 +370,16 @@ def _iter_resolved_path_nodes(
|
|
|
out.append(cur)
|
|
|
break
|
|
|
if ntype == "condition":
|
|
|
- g = _match_condition_group(cur.get("conditionGroups") or [], data)
|
|
|
+ g = _match_condition_group(
|
|
|
+ cur.get("conditionGroups") or [], data, initiator_user_id=initiator_user_id
|
|
|
+ )
|
|
|
if not g:
|
|
|
return None
|
|
|
child = g.get("child")
|
|
|
if isinstance(child, dict):
|
|
|
- sub = _iter_resolved_path_nodes(child, data)
|
|
|
+ sub = _iter_resolved_path_nodes(
|
|
|
+ child, data, initiator_user_id=initiator_user_id
|
|
|
+ )
|
|
|
if sub is None:
|
|
|
return None
|
|
|
out.extend(sub)
|
|
|
@@ -396,7 +405,9 @@ def _append_pending_nodes_on_path(
|
|
|
initiator_select_by_node: Optional[Dict[str, List[str]]],
|
|
|
) -> None:
|
|
|
"""按命中路径列出全部后续审批/抄送/结束节点(含人员),对齐发起预览。"""
|
|
|
- path = _iter_resolved_path_nodes(flow_root, form_data)
|
|
|
+ path = _iter_resolved_path_nodes(
|
|
|
+ flow_root, form_data, initiator_user_id=initiator_user_id
|
|
|
+ )
|
|
|
if path is None:
|
|
|
already = {
|
|
|
(x.get("nodeKey") or "").strip()
|
|
|
@@ -1180,7 +1191,9 @@ def _walk_preview_nodes(
|
|
|
|
|
|
if ntype == "condition":
|
|
|
groups = cur.get("conditionGroups") or []
|
|
|
- g = _match_condition_group(groups, data)
|
|
|
+ g = _match_condition_group(
|
|
|
+ groups, data, initiator_user_id=initiator_user_id
|
|
|
+ )
|
|
|
if not g:
|
|
|
return False
|
|
|
child = g.get("child")
|
|
|
@@ -1398,7 +1411,12 @@ def _create_tasks_for_node(
|
|
|
return created
|
|
|
|
|
|
|
|
|
-def _eval_condition_rules(rules: List[Any], form_data: Dict[str, Any]) -> bool:
|
|
|
+def _eval_condition_rules(
|
|
|
+ rules: List[Any],
|
|
|
+ form_data: Dict[str, Any],
|
|
|
+ *,
|
|
|
+ initiator_user_id: Optional[str] = None,
|
|
|
+) -> bool:
|
|
|
"""AND 多条 {field, op, value};contains 走人员集合交集,其余走公式。"""
|
|
|
from app.services.oa_person_select import person_contains_match
|
|
|
|
|
|
@@ -1411,6 +1429,12 @@ def _eval_condition_rules(rules: List[Any], form_data: Dict[str, Any]) -> bool:
|
|
|
if field is None:
|
|
|
return False
|
|
|
if op == "contains":
|
|
|
+ if field == INITIATOR_CONDITION_FIELD:
|
|
|
+ uid = (initiator_user_id or "").strip()
|
|
|
+ allowed = {str(x or "").strip() for x in (val or [])}
|
|
|
+ if not uid or uid not in allowed:
|
|
|
+ return False
|
|
|
+ continue
|
|
|
if not person_contains_match(form_data.get(field), val):
|
|
|
return False
|
|
|
continue
|
|
|
@@ -1426,7 +1450,12 @@ def _eval_condition_rules(rules: List[Any], form_data: Dict[str, Any]) -> bool:
|
|
|
return True
|
|
|
|
|
|
|
|
|
-def _match_condition_group(groups: List[Any], form_data: Dict[str, Any]) -> Optional[Dict[str, Any]]:
|
|
|
+def _match_condition_group(
|
|
|
+ groups: List[Any],
|
|
|
+ form_data: Dict[str, Any],
|
|
|
+ *,
|
|
|
+ initiator_user_id: Optional[str] = None,
|
|
|
+) -> Optional[Dict[str, Any]]:
|
|
|
default_g = None
|
|
|
for g in groups:
|
|
|
if not isinstance(g, dict):
|
|
|
@@ -1453,7 +1482,9 @@ def _match_condition_group(groups: List[Any], form_data: Dict[str, Any]) -> Opti
|
|
|
continue
|
|
|
if isinstance(rules, list) and rules:
|
|
|
try:
|
|
|
- if _eval_condition_rules(rules, form_data):
|
|
|
+ if _eval_condition_rules(
|
|
|
+ rules, form_data, initiator_user_id=initiator_user_id
|
|
|
+ ):
|
|
|
return g
|
|
|
except FormulaError:
|
|
|
continue
|
|
|
@@ -1479,7 +1510,9 @@ def advance_from(
|
|
|
ntype = _node_type(node)
|
|
|
if ntype == "condition":
|
|
|
groups = node.get("conditionGroups") or []
|
|
|
- g = _match_condition_group(groups, form_data)
|
|
|
+ g = _match_condition_group(
|
|
|
+ groups, form_data, initiator_user_id=inst.initiator_user_id
|
|
|
+ )
|
|
|
if not g or not isinstance(g.get("child"), dict):
|
|
|
raise OaEngineError("条件分支无法匹配出线")
|
|
|
return g["child"]
|