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

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
@@ -1,6 +1,6 @@
import unittest
from sqlalchemy import CHAR, BigInteger, CheckConstraint, DateTime, Integer, String, Table, Text, UniqueConstraint
from sqlalchemy import JSON, CHAR, BigInteger, CheckConstraint, Date, DateTime, Integer, String, Table, Text, UniqueConstraint
from sqlalchemy.dialects import mysql
from sqlalchemy.schema import CreateColumn, CreateTable
@@ -14,6 +14,7 @@ TEST_BATCH_OWNED_TABLES = {
'biz_customer',
'biz_customer_site',
'biz_production_line',
'biz_tunnel',
'biz_warehouse',
'biz_pallet',
'biz_inbound_order',
@@ -88,6 +89,20 @@ EXPECTED_COLUMNS = {
'update_time',
'remark',
},
'biz_tunnel': {
'tunnel_id',
'site_id',
'tunnel_code',
'tunnel_name',
'current_trace_no',
'current_trace_started_at',
'status',
'create_by',
'create_time',
'update_by',
'update_time',
'remark',
},
'biz_pallet': {
'pallet_id',
'pallet_code',
@@ -133,6 +148,8 @@ EXPECTED_COLUMNS = {
'strain_code_snapshot',
'strain_name_snapshot',
'batch_no',
'production_date',
'expiry_date',
'package_spec',
'initial_packages',
'active_slot',
@@ -178,6 +195,9 @@ EXPECTED_COLUMNS = {
'pallet_id',
'active_filling_id',
'site_id',
'tunnel_id',
'trace_no',
'batch_no_snapshot',
'line_id',
'used_packages',
'remaining_packages_after',
@@ -211,6 +231,9 @@ EXPECTED_COLUMNS = {
'return_id',
'pallet_id',
'active_filling_id_snapshot',
'tunnel_id_snapshot',
'trace_no_snapshot',
'batch_no_snapshot',
'remaining_packages_snapshot',
'create_by',
'create_time',
@@ -220,6 +243,8 @@ EXPECTED_COLUMNS = {
'active_filling_id',
'warehouse_id',
'site_id',
'tunnel_id',
'trace_no',
'current_line_id',
'flow_state',
'remaining_packages',
@@ -238,12 +263,16 @@ EXPECTED_COLUMNS = {
'after_state',
'before_warehouse_id',
'before_site_id',
'before_tunnel_id',
'before_line_id',
'after_warehouse_id',
'after_site_id',
'after_tunnel_id',
'after_line_id',
'before_remaining_packages',
'after_remaining_packages',
'trace_no',
'batch_no_snapshot',
'operator_id',
'occurred_at',
'idempotency_key',
@@ -263,6 +292,20 @@ EXPECTED_COLUMN_TYPES = {
'update_time': (DateTime, None),
'remark': (String, 500),
},
'biz_tunnel': {
'tunnel_id': (BigInteger, None),
'site_id': (BigInteger, None),
'tunnel_code': (String, 64),
'tunnel_name': (String, 100),
'current_trace_no': (String, 64),
'current_trace_started_at': (DateTime, None),
'status': (CHAR, 1),
'create_by': (String, 64),
'create_time': (DateTime, None),
'update_by': (String, 64),
'update_time': (DateTime, None),
'remark': (String, 500),
},
'biz_warehouse': {
'warehouse_id': (BigInteger, None),
'warehouse_code': (String, 64),
@@ -366,6 +409,8 @@ EXPECTED_COLUMN_TYPES = {
'strain_code_snapshot': (String, 64),
'strain_name_snapshot': (String, 100),
'batch_no': (String, 64),
'production_date': (Date, None),
'expiry_date': (Date, None),
'package_spec': (String, 64),
'initial_packages': (Integer, None),
'active_slot': (String, 16),
@@ -411,6 +456,9 @@ EXPECTED_COLUMN_TYPES = {
'pallet_id': (BigInteger, None),
'active_filling_id': (BigInteger, None),
'site_id': (BigInteger, None),
'tunnel_id': (BigInteger, None),
'trace_no': (String, 64),
'batch_no_snapshot': (String, 64),
'line_id': (BigInteger, None),
'used_packages': (Integer, None),
'remaining_packages_after': (Integer, None),
@@ -444,6 +492,9 @@ EXPECTED_COLUMN_TYPES = {
'return_id': (BigInteger, None),
'pallet_id': (BigInteger, None),
'active_filling_id_snapshot': (BigInteger, None),
'tunnel_id_snapshot': (BigInteger, None),
'trace_no_snapshot': (String, 64),
'batch_no_snapshot': (String, 64),
'remaining_packages_snapshot': (Integer, None),
'create_by': (String, 64),
'create_time': (DateTime, None),
@@ -453,6 +504,8 @@ EXPECTED_COLUMN_TYPES = {
'active_filling_id': (BigInteger, None),
'warehouse_id': (BigInteger, None),
'site_id': (BigInteger, None),
'tunnel_id': (BigInteger, None),
'trace_no': (String, 64),
'current_line_id': (BigInteger, None),
'flow_state': (String, 32),
'remaining_packages': (Integer, None),
@@ -471,12 +524,16 @@ EXPECTED_COLUMN_TYPES = {
'after_state': (String, 32),
'before_warehouse_id': (BigInteger, None),
'before_site_id': (BigInteger, None),
'before_tunnel_id': (BigInteger, None),
'before_line_id': (BigInteger, None),
'after_warehouse_id': (BigInteger, None),
'after_site_id': (BigInteger, None),
'after_tunnel_id': (BigInteger, None),
'after_line_id': (BigInteger, None),
'before_remaining_packages': (Integer, None),
'after_remaining_packages': (Integer, None),
'trace_no': (String, 64),
'batch_no_snapshot': (String, 64),
'operator_id': (BigInteger, None),
'occurred_at': (DateTime, None),
'idempotency_key': (String, 64),
@@ -496,6 +553,20 @@ EXPECTED_NULLABILITY = {
'update_time': True,
'remark': True,
},
'biz_tunnel': {
'tunnel_id': False,
'site_id': False,
'tunnel_code': False,
'tunnel_name': False,
'current_trace_no': True,
'current_trace_started_at': True,
'status': False,
'create_by': True,
'create_time': True,
'update_by': True,
'update_time': True,
'remark': True,
},
'biz_warehouse': {
'warehouse_id': False,
'warehouse_code': False,
@@ -599,6 +670,8 @@ EXPECTED_NULLABILITY = {
'strain_code_snapshot': False,
'strain_name_snapshot': False,
'batch_no': False,
'production_date': True,
'expiry_date': True,
'package_spec': False,
'initial_packages': False,
'active_slot': True,
@@ -644,7 +717,10 @@ EXPECTED_NULLABILITY = {
'pallet_id': False,
'active_filling_id': False,
'site_id': False,
'line_id': False,
'tunnel_id': True,
'trace_no': True,
'batch_no_snapshot': True,
'line_id': True,
'used_packages': False,
'remaining_packages_after': False,
'idempotency_key': False,
@@ -677,6 +753,9 @@ EXPECTED_NULLABILITY = {
'return_id': False,
'pallet_id': False,
'active_filling_id_snapshot': True,
'tunnel_id_snapshot': True,
'trace_no_snapshot': True,
'batch_no_snapshot': True,
'remaining_packages_snapshot': False,
'create_by': True,
'create_time': True,
@@ -686,6 +765,8 @@ EXPECTED_NULLABILITY = {
'active_filling_id': True,
'warehouse_id': True,
'site_id': True,
'tunnel_id': True,
'trace_no': True,
'current_line_id': True,
'flow_state': False,
'remaining_packages': False,
@@ -704,12 +785,16 @@ EXPECTED_NULLABILITY = {
'after_state': False,
'before_warehouse_id': True,
'before_site_id': True,
'before_tunnel_id': True,
'before_line_id': True,
'after_warehouse_id': True,
'after_site_id': True,
'after_tunnel_id': True,
'after_line_id': True,
'before_remaining_packages': False,
'after_remaining_packages': False,
'trace_no': True,
'batch_no_snapshot': True,
'operator_id': False,
'occurred_at': False,
'idempotency_key': False,
@@ -728,6 +813,8 @@ EXPECTED_CALLABLE_DATETIME_DEFAULTS = {
('biz_customer_site', 'update_time'),
('biz_production_line', 'create_time'),
('biz_production_line', 'update_time'),
('biz_tunnel', 'create_time'),
('biz_tunnel', 'update_time'),
('biz_pallet', 'create_time'),
('biz_pallet', 'update_time'),
('biz_user_warehouse', 'create_time'),
@@ -757,6 +844,8 @@ EXPECTED_EMPTY_AUDIT_SERVER_DEFAULTS = {
('biz_customer_site', 'update_by'),
('biz_production_line', 'create_by'),
('biz_production_line', 'update_by'),
('biz_tunnel', 'create_by'),
('biz_tunnel', 'update_by'),
('biz_pallet', 'create_by'),
('biz_pallet', 'update_by'),
('biz_user_warehouse', 'create_by'),
@@ -780,6 +869,7 @@ EXPECTED_PRIMARY_KEYS = {
'biz_customer': ('customer_id',),
'biz_customer_site': ('site_id',),
'biz_production_line': ('line_id',),
'biz_tunnel': ('tunnel_id',),
'biz_pallet': ('pallet_id',),
'biz_user_warehouse': ('user_id', 'warehouse_id'),
'biz_user_site': ('user_id', 'site_id'),
@@ -801,6 +891,9 @@ EXPECTED_FOREIGN_KEYS = {
'biz_customer': set(),
'biz_customer_site': {('customer_id', 'biz_customer.customer_id')},
'biz_production_line': {('site_id', 'biz_customer_site.site_id')},
'biz_tunnel': {
('site_id', 'biz_customer_site.site_id'),
},
'biz_pallet': set(),
'biz_user_warehouse': {
('user_id', 'sys_user.user_id'),
@@ -838,6 +931,7 @@ EXPECTED_FOREIGN_KEYS = {
('pallet_id', 'biz_pallet.pallet_id'),
('active_filling_id', 'biz_filling_record.filling_id'),
('site_id', 'biz_customer_site.site_id'),
('tunnel_id', 'biz_tunnel.tunnel_id'),
('line_id', 'biz_production_line.line_id'),
('operator_id', 'sys_user.user_id'),
},
@@ -851,12 +945,14 @@ EXPECTED_FOREIGN_KEYS = {
('return_id', 'biz_return_order.return_id'),
('pallet_id', 'biz_pallet.pallet_id'),
('active_filling_id_snapshot', 'biz_filling_record.filling_id'),
('tunnel_id_snapshot', 'biz_tunnel.tunnel_id'),
},
'biz_pallet_inventory': {
('pallet_id', 'biz_pallet.pallet_id'),
('active_filling_id', 'biz_filling_record.filling_id'),
('warehouse_id', 'biz_warehouse.warehouse_id'),
('site_id', 'biz_customer_site.site_id'),
('tunnel_id', 'biz_tunnel.tunnel_id'),
('current_line_id', 'biz_production_line.line_id'),
('last_event_id', 'biz_pallet_event.event_id'),
},
@@ -864,9 +960,11 @@ EXPECTED_FOREIGN_KEYS = {
('pallet_id', 'biz_pallet.pallet_id'),
('before_warehouse_id', 'biz_warehouse.warehouse_id'),
('before_site_id', 'biz_customer_site.site_id'),
('before_tunnel_id', 'biz_tunnel.tunnel_id'),
('before_line_id', 'biz_production_line.line_id'),
('after_warehouse_id', 'biz_warehouse.warehouse_id'),
('after_site_id', 'biz_customer_site.site_id'),
('after_tunnel_id', 'biz_tunnel.tunnel_id'),
('after_line_id', 'biz_production_line.line_id'),
('operator_id', 'sys_user.user_id'),
},
@@ -878,6 +976,7 @@ EXPECTED_UNIQUE_SETS = {
'biz_customer': {frozenset({'customer_code'})},
'biz_customer_site': {frozenset({'customer_id', 'site_code'})},
'biz_production_line': {frozenset({'site_id', 'line_code'})},
'biz_tunnel': {frozenset({'site_id', 'tunnel_code'})},
'biz_pallet': {frozenset({'pallet_code'}), frozenset({'qr_token'})},
'biz_user_warehouse': set(),
'biz_user_site': set(),
@@ -913,6 +1012,36 @@ EXPECTED_UNIQUE_SETS = {
},
}
# 收货补齐:与既有日期、隧道契约并存,不用当前时间填充历史收货记录。
EXPECTED_COLUMNS['biz_shipment_order'].update({
'receipt_state', 'received_by', 'received_at', 'receipt_idempotency_key', 'receipt_request_hash',
})
EXPECTED_COLUMN_TYPES['biz_shipment_order'].update({
'receipt_state': (String, 16),
'received_by': (BigInteger, None),
'received_at': (DateTime, None),
'receipt_idempotency_key': (String, 64),
'receipt_request_hash': (String, 64),
})
EXPECTED_NULLABILITY['biz_shipment_order'].update({
'receipt_state': False,
'received_by': True,
'received_at': True,
'receipt_idempotency_key': True,
'receipt_request_hash': True,
})
EXPECTED_FOREIGN_KEYS['biz_shipment_order'].add(('received_by', 'sys_user.user_id'))
EXPECTED_UNIQUE_SETS['biz_shipment_order'].add(frozenset({'target_site_id', 'receipt_idempotency_key'}))
EXPECTED_COLUMNS['biz_pallet_inventory'].add('site_arrived_at')
EXPECTED_COLUMN_TYPES['biz_pallet_inventory']['site_arrived_at'] = (DateTime, None)
EXPECTED_NULLABILITY['biz_pallet_inventory']['site_arrived_at'] = True
for fifo_table in ('biz_usage_record', 'biz_pallet_event'):
EXPECTED_COLUMNS[fifo_table].update({'fifo_skip_reason', 'fifo_recommendation'})
EXPECTED_NULLABILITY[fifo_table].update({'fifo_skip_reason': True, 'fifo_recommendation': True})
EXPECTED_COLUMN_TYPES[fifo_table]['fifo_skip_reason'] = (String, 500)
EXPECTED_COLUMN_TYPES[fifo_table]['fifo_recommendation'] = (JSON, None)
for table_name in TEST_BATCH_OWNED_TABLES:
EXPECTED_COLUMNS[table_name].add('test_batch_id')
EXPECTED_COLUMN_TYPES[table_name]['test_batch_id'] = (BigInteger, None)
@@ -1064,7 +1193,7 @@ class BusinessModelContractTest(unittest.TestCase):
def test_batch_related_tables_compile_for_mysql(self) -> None:
self.assertIs(Base.metadata.tables['sys_user'], user_do.SysUser.__table__)
batch_tables = EXPECTED_TEST_BATCH_TABLES | TEST_BATCH_OWNED_TABLES
self.assertEqual(18, len(batch_tables))
self.assertEqual(19, len(batch_tables))
for table_name in batch_tables:
for dialect_name, dialect in (('mysql', mysql.dialect()),):
with self.subTest(table_name=table_name, dialect=dialect_name):
@@ -1078,6 +1207,7 @@ class BusinessModelContractTest(unittest.TestCase):
'biz_customer',
'biz_customer_site',
'biz_production_line',
'biz_tunnel',
'biz_pallet',
'biz_user_warehouse',
'biz_user_site',
@@ -1102,6 +1232,7 @@ class BusinessModelContractTest(unittest.TestCase):
master_do.BizCustomer: 'biz_customer',
master_do.BizCustomerSite: 'biz_customer_site',
master_do.BizProductionLine: 'biz_production_line',
master_do.BizTunnel: 'biz_tunnel',
master_do.BizPallet: 'biz_pallet',
master_do.BizUserWarehouse: 'biz_user_warehouse',
master_do.BizUserSite: 'biz_user_site',
@@ -1258,6 +1389,7 @@ class BusinessModelContractTest(unittest.TestCase):
'biz_customer': {'ck_biz_customer_status': "statusIN('0','1')"},
'biz_customer_site': {'ck_biz_customer_site_status': "statusIN('0','1')"},
'biz_production_line': {'ck_biz_production_line_status': "statusIN('0','1')"},
'biz_tunnel': {'ck_biz_tunnel_status': "statusIN('0','1')"},
'biz_pallet': {
'ck_biz_pallet_capacity_packages': 'capacity_packages>0',
'ck_biz_pallet_asset_status': "asset_statusIN('0','1')",
@@ -1267,10 +1399,12 @@ class BusinessModelContractTest(unittest.TestCase):
},
'biz_filling_record': {
'ck_biz_filling_record_initial_packages': 'initial_packages>0',
'ck_biz_filling_record_material_dates': '(production_dateISNULLANDexpiry_dateISNULL)OR(production_dateISNOTNULLANDexpiry_dateISNOTNULLANDexpiry_date>=production_date)',
'ck_biz_filling_record_active_slot': "active_slotISNULLORactive_slot='ACTIVE'",
},
'biz_shipment_order': {
'ck_biz_shipment_order_status': "statusIN('DRAFT','CONFIRMED')",
'ck_biz_shipment_order_receipt_state': "receipt_stateIN('PENDING','RECEIVED','LEGACY')",
},
'biz_shipment_item': {
'ck_biz_shipment_item_package_qty': 'package_qtyISNULLORpackage_qty>0',
@@ -1288,7 +1422,7 @@ class BusinessModelContractTest(unittest.TestCase):
'biz_pallet_inventory': {
'ck_biz_pallet_inventory_flow_state': (
"flow_stateIN('UNSTOCKED','EMPTY_IN_WAREHOUSE','FILLED_IN_WAREHOUSE',"
"'AT_SITE_UNUSED','AT_SITE_PARTIAL','AT_SITE_EMPTY','RETURNING')"
"'IN_TRANSIT','AT_SITE_UNUSED','AT_SITE_PARTIAL','AT_SITE_EMPTY','RETURNING')"
),
'ck_biz_pallet_inventory_remaining_packages': 'remaining_packages>=0',
'ck_biz_pallet_inventory_version': 'version>=0',
@@ -1296,7 +1430,7 @@ class BusinessModelContractTest(unittest.TestCase):
},
'biz_pallet_event': {
'ck_biz_pallet_event_event_type': (
"event_typeIN('INBOUND_CONFIRMED','FILLING_CONFIRMED','SHIPMENT_CONFIRMED',"
"event_typeIN('INBOUND_CONFIRMED','FILLING_CONFIRMED','SHIPMENT_CONFIRMED','SHIPMENT_RECEIVED','TUNNEL_ENTERED',"
"'USAGE_RECORDED','RETURN_REQUESTED','RETURN_CONFIRMED')"
),
},
@@ -1312,6 +1446,7 @@ class BusinessModelContractTest(unittest.TestCase):
'biz_customer': 'status',
'biz_customer_site': 'status',
'biz_production_line': 'status',
'biz_tunnel': 'status',
'biz_pallet': 'asset_status',
}
for table_name, column_name in char_statuses.items():
@@ -1375,15 +1510,19 @@ class BusinessModelContractTest(unittest.TestCase):
'active_filling_id',
'warehouse_id',
'site_id',
'tunnel_id',
'trace_no',
'current_line_id',
'last_event_id',
},
'biz_pallet_event': {
'before_warehouse_id',
'before_site_id',
'before_tunnel_id',
'before_line_id',
'after_warehouse_id',
'after_site_id',
'after_tunnel_id',
'after_line_id',
},
}