"""签收单 20260803001 压力测试数据。 目的:观察当前「单页绝对定位」模板在【内容 > 1 页】时的表现: * 明细行 > MAX_ROWS(20) 时,超出部分被静默截断(合计仍按全量计)。 * 即便在 20 行内,若累计高度超过内容区,行会越过页脚、与签收栏重叠。 * 发货/收货地址为固定高度(12mm)文本,加长后会换行并压到下一行(电话)上。 可重复运行:STRESS_BOXES 为显式列表,运行前先 DELETE 这些箱,再 INSERT; 地址直接 UPDATE(幂等)。 运行: .venv/Scripts/python.exe reports/sign_receipt/add_stress_rows.py 注意:本脚本只动 20260803001;重新跑 setup_db.py 会清空 202608030% 测试 数据(含本脚本追加内容),恢复干净状态。 """ from __future__ import annotations import sys from pathlib import Path # 让脚本能 import core.* PROJECT_ROOT = Path(__file__).resolve().parents[2] if str(PROJECT_ROOT) not in sys.path: sys.path.insert(0, str(PROJECT_ROOT)) from core.db import get_engine from sqlalchemy import text RECEIPT_NO = "20260803001" # 显式选取一批真实箱(来自 finished_goods_box,单箱明细行数较多,确保 > 20 行)。 # 格式:(paichan_no, box_no) STRESS_BOXES = [ ("R07200", 1), ("R06994", 1), ("R06994", 2), ("R06626", 1), ("R06687", 1), ("R06884", 1), ("R05541", 1), ("R06006", 87), ] LONG_SHIPPER_ADDR = ( "北京市朝阳区南三环成寿寺路甲135号院1号楼 北京布莱迪仪器仪表有限公司 " "仓储物流中心收发室(近地铁成寿寺站B口,工作日8:30-17:30可收货," "节假日及夜间到货请提前与仓管预约,货车限高3.2米,卸货区在厂区西北角)" ) LONG_RECEIVER_ADDR = ( "上海市浦东新区张江高科技园区博云路2号三期厂房B栋5层收货平台 " "(收货联系人:王女士,电话:15230028484;请走北门货运通道," "货车需登记后入厂,卸货位B1-07,到货前1小时请短信通知)" ) # 静态 VALUES 列表(STRESS_BOXES 为硬编码常量,无注入风险) VALUES_SQL = ", ".join(f"(:p{i}, :b{i})" for i in range(len(STRESS_BOXES))) PAIR_VALS = {f"p{i}": p for i, (p, _) in enumerate(STRESS_BOXES)} | \ {f"b{i}": b for i, (_, b) in enumerate(STRESS_BOXES)} def main() -> None: eng = get_engine() with eng.begin() as conn: # 1) 清掉上一轮追加的箱(VALUES + EXISTS,兼容 SQL Server) conn.execute( text( f"DELETE FROM warehouseOutbound.delivery_receipt_item " f"WHERE receipt_no = :r AND EXISTS (" f" SELECT 1 FROM (VALUES {VALUES_SQL}) v(pa, bo) " f" WHERE v.pa = paichan_no AND v.bo = box_no)" ), {**PAIR_VALS, "r": RECEIPT_NO}, ) # 2) 仅当箱真实存在才插入 exist = { (p, b) for (p, b) in conn.execute( text( f"SELECT v.pa, v.bo FROM (VALUES {VALUES_SQL}) v(pa, bo) " f"WHERE EXISTS (SELECT 1 FROM CargoTrace.finished_goods_box b " f" WHERE b.paichan_no = v.pa AND b.box_no = v.bo)" ), PAIR_VALS, ).fetchall() } missing = [pb for pb in STRESS_BOXES if pb not in exist] if missing: print(" 警告:以下箱在 finished_goods_box 不存在,已跳过:", missing) for (p, b) in STRESS_BOXES: if (p, b) in exist: conn.execute( text( "INSERT INTO warehouseOutbound.delivery_receipt_item " "(receipt_no, paichan_no, box_no) VALUES (:r, :p, :b)" ), {"r": RECEIPT_NO, "p": p, "b": b}, ) # 3) 拉长地址(幂等 UPDATE) conn.execute( text( "UPDATE warehouseOutbound.delivery_receipt " "SET shipper_address = :sa, receiver_address = :ra " "WHERE receipt_no = :r" ), {"sa": LONG_SHIPPER_ADDR, "ra": LONG_RECEIVER_ADDR, "r": RECEIPT_NO}, ) # 校验 with eng.connect() as conn: n = conn.execute( text("SELECT COUNT(*) FROM warehouseOutbound.delivery_receipt_item " "WHERE receipt_no = :r"), {"r": RECEIPT_NO}).scalar() rows = conn.execute( text( "SELECT COUNT(*) FROM (" "SELECT bi.id FROM warehouseOutbound.delivery_receipt_item di " "JOIN CargoTrace.finished_goods_box b ON b.paichan_no=di.paichan_no AND b.box_no=di.box_no " "JOIN CargoTrace.finished_goods_box_item bi ON bi.box_id=b.id " "WHERE di.receipt_no = :r) t" ), {"r": RECEIPT_NO}).scalar() sa = conn.execute( text("SELECT LEN(shipper_address) FROM warehouseOutbound.delivery_receipt " "WHERE receipt_no=:r"), {"r": RECEIPT_NO}).scalar() ra = conn.execute( text("SELECT LEN(receiver_address) FROM warehouseOutbound.delivery_receipt " "WHERE receipt_no=:r"), {"r": RECEIPT_NO}).scalar() print(f" {RECEIPT_NO} 明细箱数={n},预计明细行数(产品粒度)={rows}") print(f" 发货地址长度={sa}字符,收货地址长度={ra}字符") print(f" MAX_ROWS=20 → 超出 {max(0, rows - 20)} 行将被截断(合计仍按 {rows} 行计)。") if __name__ == "__main__": main()