更新登录页及优化相关功能

This commit is contained in:
焦龙言
2026-10-08 14:13:05 +08:00
parent 9a14b692e3
commit 56e646bcc1
139 changed files with 77587 additions and 811 deletions
@@ -184,13 +184,15 @@ OPERATION_MODEL_FIELDS = {
'warehouse_id',
'strain_id',
'batch_no',
'production_date',
'expiry_date',
'package_spec',
'initial_packages',
'idempotency_key',
},
ShipmentCreateModel: {'source_warehouse_id', 'target_site_id', 'pallet_ids'},
ShipmentUpdateModel: {'shipment_id', 'source_warehouse_id', 'target_site_id', 'pallet_ids'},
UsageCreateModel: {'qr_token', 'line_id', 'used_packages', 'idempotency_key'},
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'},
@@ -219,6 +221,8 @@ OPERATION_MODEL_FIELDS = {
'strain_code_snapshot',
'strain_name_snapshot',
'batch_no',
'production_date',
'expiry_date',
'package_spec',
'initial_packages',
'active_slot',
@@ -253,6 +257,9 @@ OPERATION_MODEL_FIELDS = {
'confirm_request_hash',
'confirmed_by',
'confirmed_at',
'receipt_state',
'received_by',
'received_at',
'create_by',
'create_time',
'update_by',
@@ -262,10 +269,14 @@ OPERATION_MODEL_FIELDS = {
},
UsageModel: {
'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',
@@ -279,6 +290,9 @@ OPERATION_MODEL_FIELDS = {
'return_id',
'pallet_id',
'active_filling_id_snapshot',
'tunnel_id_snapshot',
'trace_no_snapshot',
'batch_no_snapshot',
'remaining_packages_snapshot',
'create_by',
'create_time',
@@ -339,6 +353,8 @@ OPERATION_MODEL_FIELDS = {
'page_size',
'usage_no',
'site_id',
'tunnel_id',
'trace_no',
'line_id',
'pallet_code',
'begin_time',
@@ -361,15 +377,20 @@ OPERATION_MODEL_FIELDS = {
PalletScanResponseModel: {
'pallet_id',
'pallet_code',
'qr_token',
'flow_state',
'warehouse_id',
'site_id',
'tunnel_id',
'trace_no',
'current_line_id',
'active_filling_id',
'strain_id',
'strain_code',
'strain_name',
'batch_no',
'production_date',
'expiry_date',
'package_spec',
'capacity_packages',
'remaining_packages',
@@ -379,6 +400,10 @@ OPERATION_MODEL_FIELDS = {
REPORT_MODEL_FIELDS = {
PalletInventoryReportQueryModel: {
'tunnel_id',
'tunnel_code',
'tunnel_name',
'trace_no',
'page_num',
'page_size',
'begin_time',
@@ -392,6 +417,12 @@ REPORT_MODEL_FIELDS = {
'batch_no',
},
PalletInventoryReportModel: {
'production_date',
'expiry_date',
'tunnel_id',
'tunnel_code',
'tunnel_name',
'trace_no',
'pallet_id',
'pallet_code',
'flow_state',
@@ -463,6 +494,10 @@ REPORT_MODEL_FIELDS = {
'package_qty',
},
ConsumptionReportQueryModel: {
'tunnel_id',
'tunnel_code',
'tunnel_name',
'trace_no',
'page_num',
'page_size',
'begin_time',
@@ -475,6 +510,13 @@ REPORT_MODEL_FIELDS = {
'batch_no',
},
ConsumptionReportModel: {
'production_date',
'expiry_date',
'tunnel_id',
'tunnel_code',
'tunnel_name',
'trace_no',
'batch_no_snapshot',
'usage_id',
'usage_no',
'occurred_at',
@@ -496,6 +538,11 @@ REPORT_MODEL_FIELDS = {
'operator_name',
},
ReturnReportQueryModel: {
'tunnel_id',
'tunnel_code',
'tunnel_name',
'trace_no',
'batch_no',
'page_num',
'page_size',
'begin_time',
@@ -507,6 +554,14 @@ REPORT_MODEL_FIELDS = {
'status',
},
ReturnReportModel: {
'production_date',
'expiry_date',
'tunnel_id',
'tunnel_code',
'tunnel_name',
'trace_no',
'batch_no_snapshot',
'batch_no',
'return_id',
'return_no',
'status',
@@ -522,6 +577,11 @@ REPORT_MODEL_FIELDS = {
'remaining_packages_snapshot',
},
PalletTraceReportQueryModel: {
'tunnel_id',
'tunnel_code',
'tunnel_name',
'trace_no',
'batch_no',
'page_num',
'page_size',
'begin_time',
@@ -530,6 +590,19 @@ REPORT_MODEL_FIELDS = {
'event_type',
},
PalletTraceReportModel: {
'production_date',
'expiry_date',
'tunnel_id',
'tunnel_code',
'tunnel_name',
'trace_no',
'batch_no_snapshot',
'before_tunnel_id',
'before_tunnel_code',
'before_tunnel_name',
'after_tunnel_id',
'after_tunnel_code',
'after_tunnel_name',
'event_id',
'event_seq',
'event_type',
@@ -702,7 +775,7 @@ PACKAGE_MODEL_PAYLOADS = {
'pallet_id': 1,
'pallet_code': 'PLT-001',
'qr_token': 'qr-12345678',
'capacity_packages': 20,
'capacity_packages': 100,
'asset_status': '0',
},
FillingModel: {
@@ -715,7 +788,7 @@ PACKAGE_MODEL_PAYLOADS = {
'strain_name_snapshot': '菌种一号',
'batch_no': 'B20260724',
'package_spec': '20kg/包',
'initial_packages': 20,
'initial_packages': 100,
'idempotency_key': 'fill-key-1',
'request_hash': 'fill-hash-1',
'operator_id': 1,
@@ -734,6 +807,9 @@ PACKAGE_MODEL_PAYLOADS = {
'pallet_id': 1,
'active_filling_id': 1,
'site_id': 1,
'tunnel_id': 9,
'trace_no': 'TRACE-9',
'batch_no_snapshot': 'B20260724',
'line_id': 1,
'used_packages': 1,
'remaining_packages_after': 19,
@@ -746,13 +822,16 @@ PACKAGE_MODEL_PAYLOADS = {
'return_item_id': 1,
'return_id': 1,
'pallet_id': 1,
'tunnel_id_snapshot': 9,
'trace_no_snapshot': 'TRACE-9',
'batch_no_snapshot': 'B20260724',
'remaining_packages_snapshot': 0,
},
PalletScanResponseModel: {
'pallet_id': 1,
'pallet_code': 'PLT-001',
'flow_state': 'AT_SITE_PARTIAL',
'capacity_packages': 20,
'capacity_packages': 100,
'remaining_packages': 10,
'allowed_actions': [],
},
@@ -760,7 +839,7 @@ PACKAGE_MODEL_PAYLOADS = {
'pallet_id': 1,
'pallet_code': 'PLT-001',
'flow_state': 'FILLED_IN_WAREHOUSE',
'initial_packages': 20,
'initial_packages': 100,
'remaining_packages': 20,
'updated_at': '2026-07-24T10:00:00',
},
@@ -776,7 +855,7 @@ PACKAGE_MODEL_PAYLOADS = {
'strain_name_snapshot': '菌种一号',
'batch_no': 'B20260724',
'package_spec': '20kg/包',
'initial_packages': 20,
'initial_packages': 100,
'operator_id': 1,
},
ShipmentReportModel: {
@@ -862,10 +941,10 @@ class BusinessVoContractTest(unittest.TestCase):
),
(LineModel, {'siteId': 1, 'lineCode': 'L-1', 'lineName': '产线'}),
(WarehouseModel, {'warehouseCode': 'W-1', 'warehouseName': '仓库'}),
(PalletCreateModel, {'palletCode': 'P-1', 'capacityPackages': 20}),
(PalletCreateModel, {'palletCode': 'P-1', 'capacityPackages': 100}),
(
PalletEditModel,
{'palletId': 1, 'capacityPackages': 20, 'assetStatus': '0'},
{'palletId': 1, 'capacityPackages': 100, 'assetStatus': '0'},
),
)
for model_class, payload in payloads:
@@ -979,20 +1058,23 @@ class BusinessVoContractTest(unittest.TestCase):
'warehouseId': 1,
'strainId': 2,
'batchNo': 'B20260724',
'productionDate': '2026-07-20',
'expiryDate': '2027-01-20',
'packageSpec': '20kg/包',
'initialPackages': 10,
'initialPackages': 100,
'idempotencyKey': 'fill-key-1',
}
)
self.assertEqual(10, model.initial_packages)
self.assertEqual(10, model.model_dump(by_alias=True)['initialPackages'])
self.assertEqual(100, model.initial_packages)
self.assertEqual(100, model.model_dump(by_alias=True)['initialPackages'])
def test_usage_rejects_zero_packages(self) -> None:
with self.assertRaises(ValidationError):
UsageCreateModel.model_validate(
{
'qrToken': 'qr-12345678',
'tunnelId': 9,
'lineId': 3,
'usedPackages': 0,
'idempotencyKey': 'usage-key-1',
@@ -1003,9 +1085,10 @@ class BusinessVoContractTest(unittest.TestCase):
for used_packages in (1.5, '1', True):
with self.subTest(used_packages=used_packages), self.assertRaises(ValidationError):
UsageCreateModel.model_validate(
{
'qrToken': 'qr-12345678',
'lineId': 3,
{
'qrToken': 'qr-12345678',
'tunnelId': 9,
'lineId': 3,
'usedPackages': used_packages,
'idempotencyKey': 'usage-key-1',
}
@@ -1133,7 +1216,7 @@ class BusinessVoContractTest(unittest.TestCase):
def test_pallet_edit_forbids_identity_fields(self) -> None:
valid_payload = {
'palletId': 1,
'capacityPackages': 20,
'capacityPackages': 100,
'assetStatus': '0',
'remark': None,
}
@@ -1169,7 +1252,7 @@ class BusinessVoContractTest(unittest.TestCase):
'strainId': 2,
'batchNo': ' ',
'packageSpec': '20kg/包',
'initialPackages': 10,
'initialPackages': 100,
'idempotencyKey': 'fill-key-1',
}
)
@@ -1190,7 +1273,7 @@ class BusinessVoContractTest(unittest.TestCase):
'palletId': 1,
'palletCode': 'PLT-001',
'flowState': 'AT_SITE_PARTIAL',
'capacityPackages': 20,
'capacityPackages': 100,
'remainingPackages': -1,
'allowedActions': [],
}