增加了项目侧关于steps的处理。允许保存和提取steps信息。
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user