Files
dealerhub/backend/PROGRESS_PRINTING.md
T

3.5 KiB
Raw Blame History

dealerhub · 打印功能实施报告(P3 #17 打印模板引擎,提前落地)

需求来源:用户提出"需要打印的功能"。对应《差距分析与改造清单》P3 第 17 项(打印模板引擎), 竞品对标:智慧记"多种单据都能打"(小票/A4/三联/标签)、管家婆打印模板。 结果:后端打印中心 + 前端打印按钮全部落地,新增 16 个测试,全量回归 157 passed; 顺带修复一个全项目潜在 bug(detail 路由 404,见下文)。

✅ 功能清单

  1. 打印模板引擎(注入安全)
    • 自研占位符语法:{{path.to.value}} 点路径取值 + {{#each lines}}…{{/each}} 行循环
    • 所有取值经 html.escape——商品名含 <script>/<img onerror> 均被转义(有专项测试)
    • Django/Jinja 模板标签原样输出不执行——租户编辑模板无法注入逻辑(防模板注入)
  2. 两种单据默认模板(A4 版式、含抬头/明细表/抹零/签收栏/页脚)
    • 销售单 sales_bill(XS 单号、客户、仓库、合计行数数量、应收合计)
    • 进货单 purchase_bill(供应商视角)
    • 首次渲染自动落库为租户模板(is_default=True),可在管理界面改
  3. 打印抬头设置(租户单例):公司名/电话/地址/开户行/页脚备注,渲染时自动注入 {{company.*}}
  4. API
    • GET /api/v1/printing/render/<doc_type>/<id>/?template=code&autoprint=0|1 → 整页 HTML(带自动打印脚本,可关)
    • GET|POST|PATCH /api/v1/printing/templates/(模板 CRUD)
    • GET|PUT|PATCH /api/v1/printing/settings/default/(抬头单例)
  5. 前端:销售单/采购单列表加"打印"按钮(仅已过账单可用)——axios 取回 HTML → 新窗口写入 → 浏览器打印对话框自动弹出;npm run build 通过
  6. 样张:docs/print_sample.html(含中文抬头、明细、抹零 0.5 元、签收栏的完整样例,浏览器打开即可打印预览)

🐛 顺带修复:全项目 detail 路由 404(潜在 bug)

打印模板的 PUT/PATCH 测试暴露:BaseTenantViewSet.get_queryset 是 async def, 而 adrf 的 aget_object() 同步调用它拿到 coroutine,在 aget_object_or_404 里抛 ValueError 被吞成 Http404——全项目所有 detail 路由(retrieve/PUT/PATCH/DELETE)一直都会 404。 此前未暴露是因为旧测试只覆盖 list 接口。 修复:apps/core/viewset.py 增加覆盖版 aget_object(先 await get_queryset 再过滤/查对象/校验权限), 对全部业务 ViewSet 生效。

📁 变更文件

backend/apps/printing/           [新] models / renderer / services / views / serializers / urls / migrations
backend/config/settings/base.py  注册 apps.printing
backend/apps/core/urls.py        挂载 printing 路由
backend/apps/core/viewset.py     [修] aget_object 支持 async get_queryset(全局 detail 路由修复)
backend/tests/test_printing.py   [新] 16 例(渲染器安全/语法、上下文、API、租户隔离、转义)
frontend/src/pages/SalesBills.vue · PurchaseBills.vue  [新] 打印按钮
frontend/dist/                   [重建]
docs/print_sample.html           [新] 打印样张

🔜 打印后续可扩展(未做)

  • 三联送货单/小票(58mm)版式模板、{{#if}} 条件块、批次号列(批次商品)
  • 二维码(对账单分享链接直接印在单据上,客户扫码对账)
  • PDA/标签打印(蓝牙热敏)