name: packing_list title: 装箱单 description: 按排产号 + 箱号 生成单箱装箱单 PDF(一箱一份) renderer: reportbro-lib params: paichan_no: description: 排产号(如 R04398、R07425) required: true box_no: description: 箱号(整数,在排产号下从 1 开始,如 1) required: true files: query.sql: 参数化查询(:paichan_no / :box_no),双表 LEFT JOIN 取产品信息 transform.py: build_context(rows) → 预展开的标量参数 + 行高估算(纯逻辑) _build_template.py: 样式定义 + 运行时按数据动态布局的文档元素生成(无边框列表式) fields: seq: 序号(行号,1 起) product_name: 产品名称(取自合同表 [客户名称] 字段——历史遗留命名,实际存的是产品名称,不改字段名) model: 产品型号(双表 LEFT JOIN 取 COALESCE;超长编码会换行) range_: 量程 qty: 装入该箱的数量 weihao: 位号(合同表字段,多数订单为空;有则显示、无则留白) remark: 备注(合同表 [备注] 字段) notes: - 单位:一个箱子一份 PDF - 纸张:A5 横向(210×148mm)。后期内容多时可切 A4 纵向,本期统一 A5 横向 - 信息条:2×2 网格,行1 排产号/箱号,行2 订单号/装箱日期(订单号在排产号正下方) - 排版:无边框、单色、字体驱动的列表式(弃用 ReportBro 表格元素,因其行高不自适应、行不自动堆叠) - 文档元素按数据动态生成:明细行高度由 transform 按字段长度估算,模板据此计算 y 坐标 - 明细行预展开为标量参数 r0_*..r7_*(ReportBro 表达式不支持 array 索引引用,故在 Python 端展平) - 产品信息按总排号双表 LEFT JOIN(压力表/温度计合同表)取 COALESCE,避免前缀误匹配(26BW 不会被 26B% 命中) - 合计件数 = 该箱所有 qty 之和 - 查询空结果 → build_context 抛 EmptyBoxError,CLI 给出清晰提示 - 中文通过 additional_fonts 注册 simhei.ttf 渲染(见 core/fonts.py) - 预留最多 8 行明细;超过可在 _build_template.MAX_ROWS 与 transform.MAX_ROWS 同步调大