Feat: 后端新增基础资料与业务管理只读汇总接口

为 Web 端改版提供名称、统计和看板数据。只新增只读查询、扩展列表与详情
返回字段;写接口、托盘状态机和幂等键规则均未改动,未新增权限标识。

- 基础资料:列表补充名称与汇总,客户详情返回现场树,托盘详情返回最近流转,
  托盘列表支持按流转阶段筛选和二维码精确匹配;新增现场、产线、隧道的上级
  资料选项接口;Excel 导入支持 preview 只校验不写入
- 发货出库:列表支持 keyword、receiptState 筛选并补充名称、托盘数、包数和
  菌种构成;详情明细补充托盘号、菌种、批次
- 首次入库:列表与详情补充名称、托盘数、托盘当前状态;新增 /summary
- 托盘退回:列表支持 keyword 并补充名称与托盘汇总,详情补充托盘号和隧道;
  新增 /summary、/site-options
- 工厂装填:列表支持 keyword 并补充托盘号、仓库、操作人;新增 /summary、
  /batches、/batches/detail
- 客户现场使用:列表支持 keyword、fifoSkipped 并补充名称和被跳过的先到托盘号;
  新增 /site-options、/site-board 以及 usage-fifo 的 /queue
- 先到先用 DAO 抽出公共候选条件与排序,建议查询生成的 SQL 与改动前一致
- 新增各汇总 DAO 的单元测试,同步更新路由权限与模型字段契约测试

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-18 05:03:10 -07:00
co-authored by Claude Opus 5.5
parent 80a71b48ce
commit 3050ccdc4e
51 changed files with 6545 additions and 103 deletions
@@ -30,31 +30,52 @@ from module_business.entity.vo.master_vo import (
from module_business.entity.vo.operation_vo import (
BusinessOptionModel,
ConfirmCommandModel,
FillingBatchDetailModel,
FillingBatchDetailQueryModel,
FillingBatchModel,
FillingBatchPageQueryModel,
FillingBatchRecordModel,
FillingBatchStateCountModel,
FillingCreateModel,
FillingListItemModel,
FillingModel,
FillingOverviewModel,
FillingPageQueryModel,
InboundCreateModel,
InboundItemModel,
InboundListItemModel,
InboundModel,
InboundOverviewModel,
InboundPageQueryModel,
InboundScanQueryModel,
InboundUpdateModel,
InboundWarehouseCountModel,
PalletScanResponseModel,
ReturnConfirmModel,
ReturnItemModel,
ReturnListItemModel,
ReturnModel,
ReturnOverviewModel,
ReturnPageQueryModel,
ReturnRequestModel,
ReturnScanQueryModel,
ReturnSiteOptionModel,
ShipmentCreateModel,
ShipmentItemModel,
ShipmentListItemModel,
ShipmentModel,
ShipmentPageQueryModel,
ShipmentScanQueryModel,
ShipmentStrainSummaryModel,
ShipmentUpdateModel,
UsageBoardTunnelModel,
UsageCreateModel,
UsageLinePackagesModel,
UsageListItemModel,
UsageModel,
UsagePageQueryModel,
UsageSiteBoardModel,
UsageSiteOptionModel,
)
from module_business.entity.vo.report_vo import (
ConsumptionReportModel,
@@ -170,7 +191,7 @@ MASTER_MODEL_FIELDS = {
},
PalletCreateModel: {'pallet_code', 'capacity_packages', 'remark'},
PalletEditModel: {'pallet_id', 'capacity_packages', 'asset_status', 'remark'},
PalletPageQueryModel: {'page_num', 'page_size', 'pallet_code', 'asset_status', 'ids'},
PalletPageQueryModel: {'page_num', 'page_size', 'pallet_code', 'asset_status', 'flow_group', 'ids'},
DeletePalletModel: {'pallet_ids'},
UserAssignModel: {'user_ids'},
}
@@ -195,7 +216,15 @@ OPERATION_MODEL_FIELDS = {
UsageCreateModel: {'qr_token', 'tunnel_id', 'line_id', 'used_packages', 'idempotency_key', 'fifo_skip_reason'},
ReturnRequestModel: {'source_site_id', 'target_warehouse_id', 'pallet_ids', 'idempotency_key'},
ReturnConfirmModel: {'scanned_pallet_ids', 'idempotency_key'},
InboundItemModel: {'inbound_item_id', 'inbound_id', 'pallet_id', 'create_by', 'create_time'},
InboundItemModel: {
'inbound_item_id',
'inbound_id',
'pallet_id',
'pallet_code',
'flow_state',
'create_by',
'create_time',
},
InboundModel: {
'inbound_id',
'inbound_no',
@@ -212,6 +241,38 @@ OPERATION_MODEL_FIELDS = {
'remark',
'items',
},
InboundListItemModel: {
'inbound_id',
'inbound_no',
'warehouse_id',
'status',
'confirm_idempotency_key',
'confirm_request_hash',
'confirmed_by',
'confirmed_at',
'create_by',
'create_time',
'update_by',
'update_time',
'remark',
'items',
'warehouse_name',
'creator_name',
'confirmer_name',
'pallet_count',
},
InboundWarehouseCountModel: {'warehouse_id', 'warehouse_name', 'pallet_count'},
InboundOverviewModel: {
'draft_count',
'draft_pallet_count',
'oldest_draft_at',
'month_start',
'month_confirmed_count',
'month_confirmed_pallet_count',
'unstocked_pallet_count',
'empty_pallet_count',
'empty_by_warehouse',
},
FillingModel: {
'filling_id',
'filling_no',
@@ -237,6 +298,88 @@ OPERATION_MODEL_FIELDS = {
'update_time',
'remark',
},
FillingListItemModel: {
'filling_id',
'filling_no',
'pallet_id',
'warehouse_id',
'strain_id',
'strain_code_snapshot',
'strain_name_snapshot',
'batch_no',
'production_date',
'expiry_date',
'package_spec',
'initial_packages',
'active_slot',
'closed_at',
'idempotency_key',
'request_hash',
'operator_id',
'operated_at',
'create_by',
'create_time',
'update_by',
'update_time',
'remark',
'pallet_code',
'warehouse_name',
'operator_name',
},
FillingBatchModel: {
'strain_id',
'strain_code',
'strain_name',
'batch_no',
'production_date',
'expiry_date',
'package_spec',
'pallet_count',
'package_sum',
'last_operated_at',
'last_operator_name',
},
FillingBatchStateCountModel: {'state', 'pallet_count'},
FillingBatchRecordModel: {
'filling_id',
'filling_no',
'pallet_id',
'pallet_code',
'warehouse_name',
'operator_name',
'operated_at',
},
FillingBatchDetailModel: {
'strain_id',
'strain_code',
'strain_name',
'batch_no',
'production_date',
'expiry_date',
'package_spec',
'pallet_count',
'package_sum',
'last_operated_at',
'last_operator_name',
'distribution',
'recent',
},
FillingOverviewModel: {
'today_pallet_count',
'today_package_sum',
'today_batch_count',
'month_start',
'month_pallet_count',
'month_batch_count',
'month_top_strains',
'empty_pallet_count',
'empty_by_warehouse',
'near_expiry_days',
'near_expiry_pallet_count',
'near_expiry_batch_count',
'nearest_expiry_batch_no',
'nearest_expiry_date',
},
ShipmentItemModel: {
'shipment_item_id',
'shipment_id',
@@ -244,6 +387,10 @@ OPERATION_MODEL_FIELDS = {
'active_filling_id',
'package_qty',
'remaining_packages',
'pallet_code',
'strain_code',
'strain_name',
'batch_no',
'create_by',
'create_time',
},
@@ -267,6 +414,37 @@ OPERATION_MODEL_FIELDS = {
'remark',
'items',
},
ShipmentStrainSummaryModel: {
'strain_name',
'pallet_count',
},
ShipmentListItemModel: {
'shipment_id',
'shipment_no',
'source_warehouse_id',
'target_site_id',
'status',
'confirm_idempotency_key',
'confirm_request_hash',
'confirmed_by',
'confirmed_at',
'receipt_state',
'received_by',
'received_at',
'create_by',
'create_time',
'update_by',
'update_time',
'remark',
'items',
'source_warehouse_name',
'target_site_name',
'customer_name',
'creator_name',
'pallet_count',
'package_qty',
'strains',
},
UsageModel: {
'usage_id',
'fifo_skip_reason',
@@ -285,6 +463,63 @@ OPERATION_MODEL_FIELDS = {
'operator_id',
'occurred_at',
},
UsageListItemModel: {
'usage_id',
'fifo_skip_reason',
'usage_no',
'pallet_id',
'active_filling_id',
'site_id',
'tunnel_id',
'trace_no',
'batch_no_snapshot',
'line_id',
'used_packages',
'remaining_packages_after',
'idempotency_key',
'request_hash',
'operator_id',
'occurred_at',
'pallet_code',
'site_name',
'tunnel_code',
'tunnel_name',
'line_name',
'operator_name',
'skipped_pallet_code',
},
UsageBoardTunnelModel: {
'tunnel_id',
'tunnel_code',
'tunnel_name',
'in_use',
'pallet_count',
'remaining_packages',
'started_at',
'last_used_at',
'last_line_name',
},
UsageLinePackagesModel: {'line_id', 'line_name', 'used_packages'},
UsageSiteBoardModel: {
'site_id',
'site_code',
'site_name',
'customer_name',
'pallet_count',
'package_sum',
'unused_pallet_count',
'partial_pallet_count',
'empty_pallet_count',
'today_usage_count',
'today_used_packages',
'today_by_line',
'tunnel_count',
'active_tunnel_count',
'today_fifo_skip_count',
'week_fifo_skip_count',
'tunnels',
'lines',
},
ReturnItemModel: {
'return_item_id',
'return_id',
@@ -294,6 +529,8 @@ OPERATION_MODEL_FIELDS = {
'trace_no_snapshot',
'batch_no_snapshot',
'remaining_packages_snapshot',
'pallet_code',
'tunnel_name',
'create_by',
'create_time',
},
@@ -318,6 +555,48 @@ OPERATION_MODEL_FIELDS = {
'remark',
'items',
},
ReturnListItemModel: {
'return_id',
'return_no',
'source_site_id',
'target_warehouse_id',
'status',
'request_idempotency_key',
'request_hash',
'confirm_idempotency_key',
'confirm_request_hash',
'requested_by',
'requested_at',
'confirmed_by',
'confirmed_at',
'create_by',
'create_time',
'update_by',
'update_time',
'remark',
'items',
'source_site_name',
'customer_name',
'target_warehouse_name',
'requester_name',
'confirmer_name',
'pallet_count',
'package_sum',
'filled_count',
},
ReturnOverviewModel: {
'pending_count',
'pending_pallet_count',
'pending_filled_count',
'pending_package_sum',
'oldest_pending_at',
'month_start',
'month_confirmed_count',
'month_confirmed_pallet_count',
'month_filled_pallet_count',
'month_package_sum',
'month_avg_confirm_hours',
},
InboundPageQueryModel: {
'page_num',
'page_size',
@@ -331,6 +610,7 @@ OPERATION_MODEL_FIELDS = {
'page_num',
'page_size',
'filling_no',
'keyword',
'warehouse_id',
'strain_id',
'batch_no',
@@ -338,13 +618,24 @@ OPERATION_MODEL_FIELDS = {
'begin_time',
'end_time',
},
FillingBatchPageQueryModel: {
'page_num',
'page_size',
'keyword',
'strain_id',
'begin_time',
'end_time',
},
FillingBatchDetailQueryModel: {'strain_id', 'batch_no'},
ShipmentPageQueryModel: {
'page_num',
'page_size',
'shipment_no',
'keyword',
'source_warehouse_id',
'target_site_id',
'status',
'receipt_state',
'begin_time',
'end_time',
},
@@ -352,6 +643,8 @@ OPERATION_MODEL_FIELDS = {
'page_num',
'page_size',
'usage_no',
'keyword',
'fifo_skipped',
'site_id',
'tunnel_id',
'trace_no',
@@ -364,6 +657,7 @@ OPERATION_MODEL_FIELDS = {
'page_num',
'page_size',
'return_no',
'keyword',
'source_site_id',
'target_warehouse_id',
'status',
@@ -374,6 +668,8 @@ OPERATION_MODEL_FIELDS = {
ShipmentScanQueryModel: {'source_warehouse_id', 'target_site_id'},
ReturnScanQueryModel: {'mode', 'return_id'},
BusinessOptionModel: {'id', 'code', 'name'},
ReturnSiteOptionModel: {'id', 'code', 'name', 'customer_name'},
UsageSiteOptionModel: {'id', 'code', 'name', 'customer_name', 'tunnel_count', 'line_count'},
PalletScanResponseModel: {
'pallet_id',
'pallet_code',
@@ -726,6 +1022,7 @@ WRITE_MODELS = (
OPERATION_PAGE_QUERY_MODELS = (
InboundPageQueryModel,
FillingPageQueryModel,
FillingBatchPageQueryModel,
ShipmentPageQueryModel,
UsagePageQueryModel,
ReturnPageQueryModel,