Quellcode durchsuchen

feat(oa): add dept_contains_match for condition id intersection

Co-authored-by: Cursor <cursoragent@cursor.com>
zlwu vor 2 Monaten
Ursprung
Commit
f1fad2d27d
2 geänderte Dateien mit 57 neuen und 2 gelöschten Zeilen
  1. 24 1
      backend/app/services/oa_dept_select.py
  2. 33 1
      backend/tests/test_oa_dept_select.py

+ 24 - 1
backend/app/services/oa_dept_select.py

@@ -1,7 +1,7 @@
 """OA 表单设计器:部门选择控件 form_data 校验"""
 from __future__ import annotations
 
-from typing import Any, Dict, List, Optional
+from typing import Any, Dict, List, Optional, Set
 
 
 def _walk_rules(rules: Any, out: List[dict]) -> None:
@@ -139,3 +139,26 @@ def validate_dept_form_values(schema: Any, form_data: Optional[Dict[str, Any]])
             forced["props"] = props
             errors.extend(_validate_dept_rule(forced, data))
     return errors
+
+
+def extract_dept_ids(raw: Any) -> Set[str]:
+    ids: Set[str] = set()
+    items = raw if isinstance(raw, list) else ([raw] if isinstance(raw, dict) else [])
+    for item in items:
+        if not isinstance(item, dict):
+            continue
+        did = str(item.get("id") or "").strip()
+        if did:
+            ids.add(did)
+    return ids
+
+
+def dept_contains_match(form_value: Any, cond_ids: Any) -> bool:
+    form_ids = extract_dept_ids(form_value)
+    if isinstance(cond_ids, str):
+        want = {cond_ids.strip()} if cond_ids.strip() else set()
+    elif isinstance(cond_ids, list):
+        want = {str(x).strip() for x in cond_ids if str(x).strip()}
+    else:
+        want = set()
+    return bool(form_ids & want)

+ 33 - 1
backend/tests/test_oa_dept_select.py

@@ -1,6 +1,10 @@
 import unittest
 
-from app.services.oa_dept_select import validate_dept_form_values
+from app.services.oa_dept_select import (
+    dept_contains_match,
+    extract_dept_ids,
+    validate_dept_form_values,
+)
 
 
 class TestValidateDeptFormValues(unittest.TestCase):
@@ -113,5 +117,33 @@ class TestValidateDeptFormValues(unittest.TestCase):
         self.assertEqual(validate_dept_form_values(schema, {"t": "x"}), [])
 
 
+class TestOaDeptSelect(unittest.TestCase):
+    def test_extract_and_contains(self):
+        self.assertEqual(extract_dept_ids({"id": "d1", "name": "研发"}), {"d1"})
+        self.assertEqual(
+            extract_dept_ids([{"id": "d1", "name": "A"}, {"id": "d2", "name": "B"}]),
+            {"d1", "d2"},
+        )
+        self.assertTrue(
+            dept_contains_match(
+                [{"id": "d1", "name": "A"}],
+                ["d1", "d9"],
+            )
+        )
+        self.assertFalse(
+            dept_contains_match(
+                [{"id": "d3", "name": "C"}],
+                ["d1", "d2"],
+            )
+        )
+        # 精确匹配:下级 id 不等于上级 id
+        self.assertFalse(
+            dept_contains_match(
+                {"id": "d1-child", "name": "前端组"},
+                ["d1"],
+            )
+        )
+
+
 if __name__ == "__main__":
     unittest.main()