Files
dealerhub/backend/PROGRESS_PRINTING.md

53 lines
3.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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/标签打印(蓝牙热敏)