增加了项目侧关于steps的处理。允许保存和提取steps信息。

This commit is contained in:
strepsiades
2026-03-11 10:34:49 +08:00
parent 291aa0b4b7
commit 1f68bd5ca8
22 changed files with 759 additions and 142 deletions
+52 -3
View File
@@ -15,6 +15,7 @@ BaseApiHandler - API Handler 基类
import uuid
import asyncio
from abc import abstractmethod
from copy import deepcopy
from typing import ClassVar, Dict, List, Any, Optional, TYPE_CHECKING, TypeVar
from pydantic import BaseModel
@@ -139,6 +140,48 @@ class BaseApiHandler(NodeHandler[T]):
"""默认节点创建(子类可覆盖并补充 context)"""
return self._create_basic_node(data)
def _get_committed_approval_snapshot(self, node: 'SyncNode') -> Dict[str, Any]:
snapshot = node.context.get("approval_snapshot")
return snapshot if isinstance(snapshot, dict) else {}
def _get_pending_approval_snapshot(self, node: 'SyncNode') -> Dict[str, Any]:
snapshot = node.context.get("pending_approval_snapshot")
return snapshot if isinstance(snapshot, dict) else {}
def _get_active_approval_snapshot(self, node: 'SyncNode') -> Dict[str, Any]:
pending_snapshot = self._get_pending_approval_snapshot(node)
if pending_snapshot:
return pending_snapshot
return self._get_committed_approval_snapshot(node)
def _get_request_steps(self, node: 'SyncNode') -> List[Dict[str, Any]]:
snapshot = self._get_active_approval_snapshot(node)
steps = snapshot.get("steps")
if isinstance(steps, list):
return deepcopy(steps)
return []
def _steps_changed(self, node: 'SyncNode') -> bool:
snapshot = self._get_active_approval_snapshot(node)
return bool(snapshot.get("steps_changed"))
def _attach_request_steps(self, request_data: Dict[str, Any], node: Optional['SyncNode']) -> Dict[str, Any]:
payload = dict(request_data)
payload["steps"] = self._get_request_steps(node) if node is not None else []
return payload
def _build_full_update_data(self, new_data: Dict[str, Any], schema: Any) -> Dict[str, Any]:
validated = schema.model_validate(new_data)
return validated.model_dump(exclude_none=True)
def _mark_approval_snapshot_synced(self, node: 'SyncNode') -> None:
snapshot = self._get_active_approval_snapshot(node)
if snapshot:
committed_snapshot = deepcopy(snapshot)
committed_snapshot.pop("steps_changed", None)
node.context["approval_snapshot"] = committed_snapshot
node.context.pop("pending_approval_snapshot", None)
def extract_id(self, data: Dict[str, Any]) -> str:
"""从原始数据提取 ID(默认优先 id,其次 _id)"""
return str(data.get("id") or data.get("_id") or "")
@@ -221,7 +264,8 @@ class BaseApiHandler(NodeHandler[T]):
schema,
data: Dict[str, Any],
origin_data: Dict[str, Any],
node_id: Optional[str] = None
node_id: Optional[str] = None,
force_full_schema: bool = False,
) -> Dict[str, Any] | None:
"""
获取数据在指定 schema 下的差异字段
@@ -245,6 +289,8 @@ class BaseApiHandler(NodeHandler[T]):
origin_dict = origin_model.model_dump(exclude_unset=True)
if new_dict == origin_dict:
if force_full_schema:
return new_dict
return None
# 返回有差异的字段
@@ -268,7 +314,8 @@ class BaseApiHandler(NodeHandler[T]):
self,
new_data: Dict[str, Any],
original_data: Dict[str, Any],
schema: Optional[Any] = None
schema: Optional[Any] = None,
force_full_schema: bool = False,
) -> Dict[str, Any]:
"""
过滤出需要更新的字段
@@ -320,7 +367,9 @@ class BaseApiHandler(NodeHandler[T]):
has_change = True
# 2. 只有存在变化时才返回数据
return schema_data if has_change else {}
if has_change or force_full_schema:
return schema_data
return {}
def _schema_changed_fields(
self,