fix: sync Bioyond materials over stale slot placeholders

This commit is contained in:
yxz321
2026-05-12 11:37:52 +08:00
parent 765342c4ff
commit e6ee6fc964
3 changed files with 38 additions and 9 deletions

View File

@@ -431,13 +431,14 @@ class BioyondSirnaStation(BioyondWorkstation):
)
def resync_external_materials(
self,
refresh_material_cache: bool = True,
refresh_material_cache: bool = False,
**kwargs: Any,
) -> Dict[str, Any]:
"""手动触发共享 Bioyond 外部物料同步。
Args:
refresh_material_cache: 同步前是否调用 Bioyond 物料缓存刷新(若 RPC 支持)。
refresh_material_cache: 是否在同步前额外刷新 Bioyond 物料缓存。通常保持 False
共享同步路径会用同一次库存查询结果更新缓存。
"""
with self._debug_call_session("resync_external_materials"):
api_host = self._kwarg_text(kwargs, "api_host")
@@ -1813,7 +1814,7 @@ class BioyondSirnaStation(BioyondWorkstation):
def _run_shared_external_material_sync(
self,
rpc: Optional[Any] = None,
refresh_material_cache: bool = True,
refresh_material_cache: bool = False,
) -> Dict[str, Any]:
"""为 reset / 手动 resync 运行共享 Bioyond 外部物料同步路径。"""
if rpc is None:
@@ -3865,6 +3866,8 @@ class BioyondSirnaStation(BioyondWorkstation):
return False
# TODO: Refactor this into a small BioyondResourceSynchronizer classification hook
# before re-enabling long-term; keep only the Sirna reagent-as-liquid rule here.
class SirnaResourceSynchronizer(BioyondResourceSynchronizer):
"""Sirna-specific resource synchronizer.

View File

@@ -176,6 +176,8 @@ class BioyondResourceSynchronizer(ResourceSynchronizer):
logger.warning("从Bioyond获取的物料数据为空")
return False
self._update_material_cache_from_stock(all_bioyond_data)
# 转换为UniLab格式
unilab_resources = resource_bioyond_to_plr(
all_bioyond_data,
@@ -189,6 +191,29 @@ class BioyondResourceSynchronizer(ResourceSynchronizer):
logger.error(f"从Bioyond同步物料数据失败: {e}")
return False
def _update_material_cache_from_stock(self, materials: List[Dict[str, Any]]) -> None:
"""用本次库存查询结果同步 RPC 的 name -> material id 缓存。"""
material_cache = getattr(self.bioyond_api_client, "material_cache", None)
if not isinstance(material_cache, dict):
return
before_count = len(material_cache)
for material in materials:
material_name = material.get("name")
material_id = material.get("id")
if material_name and material_id:
material_cache[material_name] = material_id
for detail_material in material.get("detail", []) or []:
detail_name = detail_material.get("name")
detail_id = detail_material.get("detailMaterialId") or detail_material.get("id")
if detail_name and detail_id:
material_cache[detail_name] = detail_id
logger.debug(
f"已用Bioyond库存同步物料缓存: {before_count} -> {len(material_cache)}"
)
def sync_to_external(self, resource: Any) -> bool:
"""将本地物料数据变更同步到Bioyond系统"""
try:
@@ -1404,11 +1429,7 @@ class BioyondWorkstation(WorkstationBase):
if self.hardware_interface:
self.hardware_interface.scheduler_reset()
# 新物料缓存
if self.hardware_interface:
self.hardware_interface.refresh_material_cache()
# 重新同步资源
# 重新同步资源,并用同一次库存查询结果更新物料缓存
if self.resource_synchronizer:
self.resource_synchronizer.sync_from_external()

View File

@@ -934,7 +934,12 @@ def resource_bioyond_to_plr(bioyond_materials: list[dict], type_mapping: Dict[st
)
current_resource = warehouse[idx]
if current_resource is None or isinstance(current_resource, ResourceHolder):
if current_resource is None or isinstance(current_resource, (ResourceHolder, str)):
if isinstance(current_resource, str):
logger.warning(
f"⚠️ 物料 {unique_name} 覆盖 {wh_name}[{idx}]"
f"{f'({slot_key})' if slot_key else ''} 的旧占位 occupied_by={current_resource!r}"
)
# 物料尺寸已在放入warehouse前根据需要进行了交换
warehouse[idx] = plr_material
logger.debug(