"""OA 归属人 / 归属部门:只读强制回填与校验辅助""" from __future__ import annotations from typing import Any, Dict, List, Optional def _walk_rules(rules: Any, out: List[dict]) -> None: if not isinstance(rules, list): return for r in rules: if not isinstance(r, dict): continue out.append(r) children = r.get("children") or (r.get("props") or {}).get("rule") or [] if isinstance(children, list): _walk_rules(children, out) def _schema_rules(schema: Any) -> List[dict]: if isinstance(schema, list): out: List[dict] = [] _walk_rules(schema, out) return out if not isinstance(schema, dict): return [] out: List[dict] = [] _walk_rules(schema.get("rule") or schema.get("rules") or [], out) return out def _rule_props(rule: dict) -> dict: props = rule.get("props") return props if isinstance(props, dict) else {} def _allow_modify(rule: dict) -> bool: return _rule_props(rule).get("allowModify") is True def apply_owner_field_defaults( schema: Any, form_data: Optional[Dict[str, Any]], *, user_id: str, user_name: str, dept_id: Optional[str], dept_name: Optional[str], ) -> Dict[str, Any]: """ 归属字段处理: - allowModify 为假:强制写入当前发起人 / 主部门(防篡改) - allowModify 为真且字段为空:补默认值 """ data = dict(form_data or {}) uid = (user_id or "").strip() uname = (user_name or "").strip() or uid did = (dept_id or "").strip() dname = (dept_name or "").strip() or did person_val = {"id": uid, "name": uname} if uid else None dept_val = {"id": did, "name": dname} if did else None for rule in _schema_rules(schema): typ = str(rule.get("type") or "") field = str(rule.get("field") or "").strip() if not field: continue allow = _allow_modify(rule) cur = data.get(field) empty = cur is None or cur == "" or cur == [] or ( isinstance(cur, dict) and not str(cur.get("id") or "").strip() ) if typ == "ownerPerson" and person_val: if not allow or empty: data[field] = dict(person_val) elif typ == "ownerDept" and dept_val: if not allow or empty: data[field] = dict(dept_val) return data