Files
my-mom-system/.cursor/plans/workorder_print_template_6cc2bcf4.plan.md
panchengyong c28ada5050 commit content
2026-03-06 02:02:59 +08:00

22 KiB
Raw Blame History

name, overview, todos, isProject
name overview todos isProject
Universal Document Print 设计并实现跨项目的通用单据打印框架,覆盖 erp-frontend-vue (Vue 3) 和 mom-backend-ui (Vue 2) 两个前端项目中所有单据类型的打印需求,采用配置驱动方式,一套设计思路适配全部单据。
id content status
install-deps-vue3 erp-frontend-vue: 安装 qrcode + @types/qrcode completed
id content status
install-deps-vue2 mom-backend-ui: 安装 qrcode已有 vue-plugin-hiprint 用于标签,文档打印需另行处理) pending
id content status
print-types 创建 PrintConfig 类型/接口定义(两项目各一份,结构一致) completed
id content status
qrcode-vue3 erp-frontend-vue: 创建 src/components/print/QrCode.vue completed
id content status
print-dialog-vue3 erp-frontend-vue: 创建 src/components/print/PrintDialog.vue含 @media print 样式) completed
id content status
qrcode-vue2 mom-backend-ui: 创建 src/components/PrintDoc/QrCode.vueVue 2 版) pending
id content status
print-dialog-vue2 mom-backend-ui: 创建 src/components/PrintDoc/PrintDialog.vueVue 2 版,含 @media print 样式) pending
id content status
task-api erp-frontend-vue: 在 workOrder.ts 中添加 ProTask 类型和 getTaskListByWorkorder API completed
id content status
integrate-workorder-vue3 erp-frontend-vue: 生产工单 form.vue 集成打印 completed
id content status
integrate-sales-vue3 erp-frontend-vue: 销售订单 form.vue 集成打印 completed
id content status
integrate-purchase-vue3 erp-frontend-vue: 采购订单 form.vue 集成打印 completed
id content status
integrate-issue-vue3 erp-frontend-vue: 生产领料单 form.vue 集成打印 completed
id content status
integrate-arrival-vue2 mom-backend-ui: 到货通知单 index.vue 集成打印 pending
id content status
integrate-itemrecpt-vue2 mom-backend-ui: 物料入库单 index.vue 集成打印 pending
id content status
integrate-productsales-vue2 mom-backend-ui: 销售出库单 index.vue 集成打印 pending
id content status
integrate-remaining-vue2 mom-backend-ui: 其余仓库单据(退货/转移/杂项等)逐步集成打印 pending
false

通用单据打印框架(跨项目)

现状分析

erp-frontend-vueVue 3 + Element Plus

  • handlePrint() 要么仅调 window.print()(生产工单、采购订单),要么是占位符(销售订单等)
  • @media print 样式、无 QR 码库、无打印组件
  • 包含单据:销售订单、采购订单、生产工单、生产领料单、采购到货单(表单未完成)

mom-backend-uiVue 2 + Element UI

  • 已有 vue-plugin-hiprint 用于条码标签打印(物料/仓库/工位标签),但无单据格式打印
  • handleHiPrint 仅在 detail 页做标签打印,不是单据表单打印
  • 包含大量仓库单据模块:到货通知、入库单(4种)、领料单(3种)、出库单(2种)、退货单(3种)、转移单、装箱单、备料通知等

两项目共同点

所有单据结构高度一致:表头字段 + 明细行列表,适合用统一的配置驱动方案。

架构设计

核心思路:配置驱动 + 双项目适配

graph TB
    subgraph config ["PrintConfig 配置接口(结构一致)"]
        fields["headerFields: 表头字段数组"]
        cols["columns: 明细列定义"]
        data["data: 明细行数据"]
        meta["title / qrCode / footer"]
    end

    subgraph vue3 ["erp-frontend-vue (Vue 3)"]
        pd3["PrintDialog.vue"]
        qr3["QrCode.vue"]
        pages3["各单据 form.vue"]
    end

    subgraph vue2 ["mom-backend-ui (Vue 2)"]
        pd2["PrintDialog.vue"]
        qr2["QrCode.vue"]
        pages2["各单据 index.vue"]
    end

    pages3 -->|"构建 config"| pd3
    pages2 -->|"构建 config"| pd2
    pd3 --> qr3
    pd2 --> qr2
    config -.->|"同一结构"| pd3
    config -.->|"同一结构"| pd2

PrintConfig 接口定义

两个项目各自维护一份Vue 3 用 TypeScriptVue 2 用 JSDoc结构完全一致

/** 表头字段 */
interface PrintHeaderField {
  label: string          // "单据编码"
  value: string | number // "SCDD000001"
  span?: number          // 占列数,默认 1共 4 列一行)
}

/** 明细表列 */
interface PrintColumn {
  prop: string           // 数据字段名
  label: string          // 列标题
  width?: string         // 列宽
  align?: 'left' | 'center' | 'right'
  type?: 'text' | 'index' | 'qrcode' | 'amount'
  qrCodeProp?: string    // type=qrcode 时的编码内容字段
  formatter?: (row: any, index: number) => string
}

/** 合计行 */
interface PrintSummary {
  label: string
  value: string | number
}

/** 完整打印配置 */
interface PrintConfig {
  systemName?: string              // 默认 "升阳云ERP"
  title: string                    // "销售订单" | "到货通知单" | ...
  subtitle?: string                // "加工车间" 等
  qrCodeValue?: string             // 右上角二维码内容
  headerFields: PrintHeaderField[] // 4 列网格,自动换行
  columns: PrintColumn[]           // 明细表列
  data: any[]                      // 明细表数据
  summaries?: PrintSummary[]       // 合计行(可选)
  footer: {
    creator?: string               // 制单人
    approver?: string              // 审核人
  }
}

打印页面统一布局

+------------------------------------------------------------------+
| 升阳云ERP                                              [QR 码]    |
| {title} - {subtitle}                                             |
|                                                                  |
| {label}: {value}   {label}: {value}   {label}: {value}   {label}:|
| {label}: {value}   {label}: {value}   {label}: {value}   {label}:|
|                                                                  |
| +----+----------+----------+------+------+----------+------+     |
| | 序号| 列1      | 列2      | 列3  | 列4  | 列5      | 列6  |     |
| +----+----------+----------+------+------+----------+------+     |
| |  1 | ...      | ...      | ...  | ...  | [QR码]   | ...  |     |
| +----+----------+----------+------+------+----------+------+     |
|                                                                  |
| 制单人: xxx          审核人: xxx         打印日期: 2025-xx-xx     |
+------------------------------------------------------------------+

实现步骤

第一步:依赖安装

erp-frontend-vue:

cd erp-frontend-vue && npm install qrcode && npm install -D @types/qrcode

mom-backend-ui:

cd mom-backend-ui && npm install qrcode

第二步:公共组件开发

Vue 3 版erp-frontend-vue

新建目录 src/components/print/,包含 3 个文件:

文件 说明
src/components/print/types.ts PrintConfig 等类型定义
src/components/print/QrCode.vue QR 码组件Props: value, size
src/components/print/PrintDialog.vue 通用打印对话框

QrCode.vue — 使用 qrcode.toDataURL() 生成 base64 图片,渲染 <img> 标签。

PrintDialog.vue — 核心组件:

  • Props: v-model:visibleconfig: PrintConfig
  • el-dialogfullscreen包裹打印预览
  • 对话框 header 有「打印」「关闭」按钮
  • 打印内容区使用纯 HTML table + CSS Grid不依赖 Element Plus确保打印输出干净
  • 组件内嵌 @media print 样式,隐藏对话框 header/footer仅保留 .print-content

Vue 2 版mom-backend-ui

新建目录 src/components/PrintDoc/,包含 2 个文件:

文件 说明
src/components/PrintDoc/QrCode.vue QR 码组件Vue 2 语法)
src/components/PrintDoc/PrintDialog.vue 通用打印对话框Vue 2 + Element UI el-dialog

两个版本的布局 HTML 和 CSS 完全一致,仅框架语法不同:

  • Vue 3: <script setup> + defineProps + v-model:visible
  • Vue 2: export default + props + .sync 修饰符

第三步:打印专用 CSS两项目通用

嵌入在 PrintDialog 组件内(或独立 CSS 文件),核心规则:

@media print {
  body > *:not(.el-overlay):not(.v-modal) { display: none !important; }
  .el-overlay, .v-modal { position: static !important; overflow: visible !important; }
  .el-dialog__wrapper { position: static !important; overflow: visible !important; }
  .el-dialog { box-shadow: none !important; border: none !important;
               margin: 0 !important; width: 100% !important; }
  .el-dialog__header, .el-dialog__footer,
  .print-dialog-actions { display: none !important; }
  .print-content { padding: 8mm 10mm; margin: 0; }
  .print-content table { page-break-inside: auto; }
  .print-content tr { page-break-inside: avoid; }
}

第四步:各单据集成

每个单据页面的 handlePrint() 只需:

  1. 构建 PrintConfig 对象(映射该单据的字段)
  2. 设置 showPrintDialog = true

全部单据配置清单

A. erp-frontend-vue 项目Vue 3

A1. 生产工单

页面: src/views/Production/WorkOrder/form.vue 需新增 API: getTaskListByWorkorder(workorderId) -> GET /mes/pro/protask/list (添加到 src/api/workOrder.ts

表头字段headerFields

  • 单据编码 workorderCode / 跟单号 salesOrderCode / 物料编码 productCode / 工艺路线 routeName
  • 单据日期 orderDate / 操作员 operatorName / 物料名称 productName + productSpc / 生产线 productionLine
  • 单据状态 status / 订单交期 deliveryDate / 计量单位 unitName / 生产日期 productionDate
  • 业务状态 businessStatus / 需求日期 requestDate / 生产数量 quantity / 备注 remark

明细列(工序,来自 ProTask

  • 序号(index) / 工序编码 processCode / 工序名称 processName / 应报数量 quantity / 计件方式(固定"个人") / 扫码报工(qrcode) / 备注

页脚: 制单人 createBy / 审核人 approverName


A2. 销售订单

页面: src/views/Sales/Order/form.vue

表头字段:

  • 单据编码 orderCode / 单据日期 orderDate / 单据状态 orderStatus / 业务类型 bizType
  • 客户名称 clientName / 销售人员 salesmanName / 销售部门 deptName / 合同号 contractNo
  • 交付日期 deliveryDate / 付款条件 paymentTerms / 收货人 receiver / 收货电话 receiverPhone
  • 收货地址 receiverAddress(span:2) / 备注 remark(span:2)

明细列(物料行,来自 lines

  • 序号 / 物料编码 itemCode / 物料名称 itemName / 型号规格 specification / 主计量 unitOfMeasure / 数量 quantity / 单价 unitPrice / 金额 amount / 质量要求 qualityReq / 备注 remark

合计: 总金额 totalAmount 页脚: 制单人 createBy / 审核人 auditorName


A3. 采购订单

页面: src/views/Purchasing/Order/form.vue

表头字段:

  • 单据编码 orderCode / 单据日期 orderDate / 单据状态 status / 业务类型 businessType
  • 业务状态 businessStatus / 供方 supplierName / 采购部门 deptName / 采购人员 userName
  • 到货日期 deliveryDate / 合同号 contractNo / 用料需求 materialNeed / 备注 remark

明细列(采购行,来自 lines

  • 序号 / 跟单编号 trackCode / 计划单号 planCode / 物料编码 itemCode / 物料名称 itemName / 型号规格 specification / 主计量 unitName / 数量 quantity / 单价 unitPrice / 金额 amount / 采购说明 remark

合计: 总数量 totalQuantity / 总金额 totalAmount 页脚: 制单人 operatorName / 审核人 approverName


A4. 生产领料单

页面: src/views/Warehouse/Issue/form.vue(需新增打印按钮)

表头字段:

  • 单据编码 issueCode / 领料日期 issueDate / 单据状态 status / 工单编码 workorderCode
  • 工作站 workstationName / 客户名称 clientName / 需求时间 requiredTime / 备注 remark

明细列(领料行):

  • 序号 / 物料编码 itemCode / 物料名称 itemName / 规格型号 specification / 计量单位 unitName / 领料数量 quantityIssued / 批次号 batchCode / 备注 remark

页脚: 制单人 createBy


B. mom-backend-ui 项目Vue 2

以下单据在老项目中,均无单据打印功能(仅部分有标签打印)。统一使用 PrintDialog 组件集成。

B1. 到货通知单

页面: src/views/mes/wm/arrivalnotice/index.vue + line.vue

表头字段:

  • 通知单编号 noticeCode / 通知单名称 noticeName / 采购订单号 poCode / 到货日期 arrivalDate
  • 供应商 vendorName / 联系人 contact / 联系方式 tel / 单据状态 status
  • 备注 remark(span:3)

明细列(到货行):

  • 序号 / 物料编码 itemCode / 物料名称 itemName / 规格型号 specification / 单位 unitName / 到货数量 quantityArrival / 是否检验 iqcCheck / 合格数量 quantityQuanlified / 检验单号 iqcCode / 备注 remark

页脚: 制单人 createBy


B2. 物料入库单(采购入库)

页面: src/views/mes/wm/itemrecpt/index.vue + line.vue

表头字段:

  • 入库单编号 recptCode / 入库单名称 recptName / 入库日期 recptDate / 单据状态 status
  • 到货通知单 noticeCode / 采购订单号 poCode / 供应商 vendorName / 备注 remark

明细列(入库行):

  • 序号 / 物料编码 itemCode / 物料名称 itemName / 规格型号 specification / 单位 unitName / 入库数量 quantityRecived / 批次号 batchCode

页脚: 制单人 createBy


B3. 产品入库单

页面: src/views/mes/wm/productrecpt/

表头字段: 入库单编号、名称、工单编码、入库日期、状态、备注 明细列: 产品编码、产品名称、规格、单位、入库数量、批次号


B4. 外协入库单

页面: src/views/mes/wm/outsourcerecpt/

表头: 入库单编号、名称、外协工单号、入库日期、状态、备注 明细: 物料编码、物料名称、规格、单位、入库数量、批次号


B5. 销售出库单

页面: src/views/mes/wm/productsales/index.vue + line.vue

表头字段:

  • 出库单编号 salesCode / 出库单名称 salesName / 发货通知单 noticeCode / 销售订单 soCode
  • 客户编码 clientCode / 客户名称 clientName / 出库日期 salesDate / 单据状态 status
  • 收货人 recipient / 联系方式 tel / 承运商 carrier / 运输单号 shippingNumber
  • 收货地址 address(span:2) / 备注 remark(span:2)

明细列(出库行):

  • 序号 / 产品编码 itemCode / 产品名称 itemName / 规格型号 specification / 单位 unitName / 出库数量 quantitySales / 批次号 batchCode / 是否检验 oqcCheck / 备注 remark

页脚: 制单人 createBy


B6. 发货通知单

页面: src/views/mes/wm/salesnotice/

表头: 通知单编号、销售订单号、客户名称、发货日期、收货人、联系方式、地址、承运商、状态 明细: 产品编码、产品名称、规格、单位、发货数量、批次号


B7. 供应商退货单

页面: src/views/mes/wm/rtvendor/index.vue + line.vue

表头字段:

  • 退货单编号 rtCode / 退货单名称 rtName / 采购订单 poCode / 退货日期 rtDate
  • 供应商 vendorName / 退货原因 rtReason / 运单号 transportCode / 单据状态 status
  • 备注 remark(span:3)

明细列:

  • 序号 / 物料编码 itemCode / 物料名称 itemName / 规格型号 specification / 单位 unitName / 退货数量 quantityRted / 批次号 batchCode / 备注 remark

B8. 销售退货单

页面: src/views/mes/wm/rtsales/

表头: 退货单编号、销售订单号、客户名称、退货日期、状态 明细: 产品编码、产品名称、规格、单位、退货数量、批次号


B9. 生产退料单

页面: src/views/mes/wm/rtissue/

表头: 退料单编号、工单编码、退料日期、状态 明细: 物料编码、物料名称、规格、单位、退料数量、批次号


B10. 生产领料单

页面: src/views/mes/wm/issue/index.vue + line.vue

表头: 领料单编号、领料单名称、工单编码、工作站、领料日期、状态 明细: 物料编码、物料名称、规格、单位、领料数量、备注


B11. 外协领料单

页面: src/views/mes/wm/outsourceissue/

表头: 领料单编号、外协工单号、领料日期、状态 明细: 物料编码、物料名称、规格、单位、领料数量


B12. 转移单

页面: src/views/mes/wm/transfer/index.vue

表头字段:

  • 转移单编号 transferCode / 转移单名称 transferName / 转移类型 transferType / 转移日期 transferDate
  • 是否配送 deliveryFlag / 收货人 recipient / 联系方式 tel / 单据状态 status
  • 承运商 carrier / 运输单号 shippingNumber / 目的地 destination / 备注 remark

明细: 物料编码、物料名称、规格、单位、转移数量、批次号


B13. 杂项入库单 / 杂项出库单 / 备料通知单 / 装箱单

页面: 分别位于 mes/wm/miscrecpt/mes/wm/miscissue/mes/wm/mrnotice/mes/wm/package/

结构与上述单据一致,表头字段略有不同,明细均为物料行。集成方式相同:构建 PrintConfig 即可。


实施优先级

Phase 1 — 公共组件 + 核心单据(优先)

  1. 安装依赖(两个项目)
  2. 创建公共打印组件Vue 3 版 + Vue 2 版)
  3. erp-frontend-vue: 生产工单、销售订单、采购订单集成打印
  4. mom-backend-ui: 到货通知单、物料入库单集成打印

Phase 2 — 仓库出入库单据

  1. erp-frontend-vue: 生产领料单集成打印
  2. mom-backend-ui: 销售出库单、发货通知单、生产领料单集成打印

Phase 3 — 退货/转移/其余单据

  1. mom-backend-ui: 供应商退货单、销售退货单、生产退料单
  2. mom-backend-ui: 转移单、外协入库/领料、杂项入库/出库、备料通知、装箱单

文件变更总览

erp-frontend-vue新增 3 文件 + 修改 5 文件)

新增:

  • src/components/print/types.ts — PrintConfig 类型定义
  • src/components/print/QrCode.vue — QR 码组件
  • src/components/print/PrintDialog.vue — 通用打印对话框

修改:

  • src/api/workOrder.ts — 添加 ProTask 类型和 API
  • src/views/Production/WorkOrder/form.vue — 集成打印
  • src/views/Sales/Order/form.vue — 集成打印
  • src/views/Purchasing/Order/form.vue — 集成打印
  • src/views/Warehouse/Issue/form.vue — 添加打印按钮 + 集成打印

mom-backend-ui新增 2 文件 + 修改 N 个单据页面)

新增:

  • src/components/PrintDoc/QrCode.vue — QR 码组件Vue 2
  • src/components/PrintDoc/PrintDialog.vue — 通用打印对话框Vue 2

修改Phase 1-3 逐步):

  • src/views/mes/wm/arrivalnotice/index.vue — 到货通知单
  • src/views/mes/wm/itemrecpt/index.vue — 物料入库单
  • src/views/mes/wm/productsales/index.vue — 销售出库单
  • src/views/mes/wm/salesnotice/index.vue — 发货通知单
  • src/views/mes/wm/issue/index.vue — 生产领料单
  • src/views/mes/wm/rtvendor/index.vue — 供应商退货单
  • src/views/mes/wm/rtsales/index.vue — 销售退货单
  • src/views/mes/wm/rtissue/index.vue — 生产退料单
  • src/views/mes/wm/transfer/index.vue — 转移单
  • 其余仓库单据页面...

安装依赖:

  • erp-frontend-vue: qrcode + @types/qrcode
  • mom-backend-ui: qrcode

扩展性说明

新增任何单据的打印,不论在哪个项目中,只需:

  1. 在该单据页面中引入 PrintDialog 组件
  2. 构建 PrintConfig 对象(映射表头字段 + 配置明细列 + 提供行数据)
  3. 设置 showPrintDialog = true

无需修改任何公共打印组件。