add formulation action

This commit is contained in:
Junhan Chang
2026-03-21 09:32:16 +08:00
committed by Andy6M
parent 03e3719b18
commit dff70bd72b
4 changed files with 307 additions and 18 deletions

View File

@@ -188,6 +188,108 @@ bioyond_cell:
title: create_orders参数
type: object
type: UniLabJsonCommand
auto-create_orders_formulation:
always_free: true
feedback: {}
goal: {}
goal_default:
batch_id: ''
bottle_type: 配液小瓶
conductivity_bottle_count: 0
conductivity_info: 0.0
formulation: null
load_shedding_info: 0.0
mix_time: 0
pouch_cell_info: 0.0
handles:
output:
- data_key: total_orders
data_source: executor
data_type: integer
handler_key: bottle_count
label: 配液瓶数
- data_key: vial_plates
data_source: executor
data_type: array
handler_key: vial_plates_output
label: 分液瓶板列表
- data_key: mass_ratios
data_source: executor
data_type: array
handler_key: mass_ratios_output
label: 配方信息列表
placeholder_keys:
formulation: unilabos_formulation
result: {}
schema:
description: 配方批量输入版本的创建实验——通过前端配方组件输入物料配比替代Excel导入
properties:
feedback: {}
goal:
properties:
batch_id:
default: ''
description: 批次ID为空则自动生成时间戳
type: string
bottle_type:
default: 配液小瓶
description: 配液瓶类型
type: string
conductivity_bottle_count:
default: 0
description: 电导测试分液瓶数
type: integer
conductivity_info:
default: 0.0
description: 电导测试分液体积
type: number
formulation:
description: 配方列表,每个元素代表一个订单(一瓶)
items:
properties:
materials:
description: 物料列表
items:
properties:
mass:
description: 质量(g)
type: number
name:
description: 物料名称
type: string
required:
- name
- mass
type: object
type: array
order_name:
description: 配方名称(可选)
type: string
required:
- materials
type: object
type: array
load_shedding_info:
default: 0.0
description: 扣电组装分液体积
type: number
mix_time:
default: 0
description: 混匀时间(秒)
type: integer
pouch_cell_info:
default: 0.0
description: 软包组装分液体积
type: number
required:
- formulation
type: object
result: {}
required:
- goal
title: create_orders_formulation参数
type: object
type: UniLabJsonCommand
auto-create_sample:
feedback: {}
goal: {}

View File

@@ -632,6 +632,11 @@ class Registry:
# 保留字段的 title用户自定义的中文名
if "title" in prev_field and prev_field["title"]:
field_schema["title"] = prev_field["title"]
# 保留旧 schema 中手动定义的复杂嵌套结构(如 items、properties、required
# 当旧 schema 比自动生成的更丰富时,使用旧 schema 的结构
for rich_key in ("items", "properties", "required"):
if rich_key in prev_field and rich_key not in field_schema:
field_schema[rich_key] = prev_field[rich_key]
def _is_typed_dict(self, annotation: Any) -> bool:
"""
@@ -818,20 +823,26 @@ class Registry:
"goal_default": {i["name"]: i["default"] for i in v["args"]},
"handles": old_action_configs.get(f"auto-{k}", {}).get("handles", []),
"placeholder_keys": {
i["name"]: (
"unilabos_resources"
if i["type"] == "unilabos.registry.placeholder_type:ResourceSlot"
or i["type"] == ("list", "unilabos.registry.placeholder_type:ResourceSlot")
else "unilabos_devices"
)
for i in v["args"]
if i.get("type", "")
in [
"unilabos.registry.placeholder_type:ResourceSlot",
"unilabos.registry.placeholder_type:DeviceSlot",
("list", "unilabos.registry.placeholder_type:ResourceSlot"),
("list", "unilabos.registry.placeholder_type:DeviceSlot"),
]
# 先用旧配置中手动定义的 placeholder_keys 作为基础
**old_action_configs.get(f"auto-{k}", {}).get("placeholder_keys", {}),
# 再用自动推断的覆盖ResourceSlot/DeviceSlot 类型)
**{
i["name"]: (
"unilabos_resources"
if i["type"] == "unilabos.registry.placeholder_type:ResourceSlot"
or i["type"]
== ("list", "unilabos.registry.placeholder_type:ResourceSlot")
else "unilabos_devices"
)
for i in v["args"]
if i.get("type", "")
in [
"unilabos.registry.placeholder_type:ResourceSlot",
"unilabos.registry.placeholder_type:DeviceSlot",
("list", "unilabos.registry.placeholder_type:ResourceSlot"),
("list", "unilabos.registry.placeholder_type:DeviceSlot"),
]
},
},
**({"always_free": True} if v.get("always_free") else {}),
}