12 KiB
付款详情打印页:数据与渲染流程梳理
页面 URL: http://czemc.localhost/budget/#/payment/payment-detail-print/161(示例 id=161)
组件: czemc-budget-execution-frontend/src/views/payment/PaymentDetailPrint.vue
路由: /payment/payment-detail-print/:id(src/router/index.js)
一、入口与路由
| 项目 | 说明 |
|---|---|
| 路由定义 | path: '/payment/payment-detail-print/:id',name: 'PaymentDetailPrint' |
| 组件 | () => import('@/views/payment/PaymentDetailPrint.vue'),懒加载 |
| meta | title: '付款详情打印',hidden: true(不显示在菜单) |
| 访问方式 | 直接访问 URL,或从预算执行等页面通过 router.push({ path: \/payment/payment-detail-print/${row.payment_id}` })` 跳转 |
URL 中的 161 为付款 id(Payment.id),从 route.params.id 读取。
二、整体数据与渲染流程概览
onMounted
└─ loadPaymentDetail()
├─ 1) paymentAPI.getDetail(id) → GET /budget/payments/{id}
├─ 2) payment 赋值,collectFlowId(payment.flow_info.id) // 付款主流程
├─ 3) loadPaymentTemplateElements() // 付款分类模板元素
├─ 4) loadApprovalFlowDetails() // 审批流程类型字段的流程详情
├─ 5) loadRelatedPlannedExpenditure() // 若 related_type=planned_expenditure
├─ 6) nextTick + setTimeout(300) → renderPrintTemplates()
└─ 7) renderedPrintTemplates 更新后 → 触发 renderPdfAsImages(会议纪要 PDF 等)
子组件挂载(ContractInfoCard / PlannedExpenditureInfoCard):
└─ PlannedExpenditureTemplateReadonly
└─ 从 flow_bindings / element_values 解析流程 ID → emit('collect-flow-id', id)
└─ 父层 collectFlowId(id) → collectedFlowIds
watch(collectedFlowIds.size) → renderPrintTemplates()
└─ oaFlowAPI.renderPrintTemplates(flowIds) → POST /oa/flow/render-print-templates
└─ renderedPrintTemplates = res.data → 渲染「相关流程详情」区块
三、主数据源:付款详情接口
3.1 请求
- 调用:
paymentAPI.getDetail(paymentId),其中paymentId = route.params.id(如 161) - 接口:
GET /budget/payments/{id} - 后端:
backend/Modules/Budget/app/Http/Controllers/Api/PaymentController.php→show($id)
3.2 后端加载与格式化
Payment::with(['paymentCategory.parent', 'oaFlow', 'elementValues.element'])->findOrFail($id)- 使用
formatPayment($payment, true)输出,其中会:- 按
oa_flow_id查 OA 流程,得到flow_info(id、no、title、status_text、custom_model_id、created_at 等) - 按
payment_category_id算支付类型与面包屑,得到payment_type_info - 把
fields_data作为fields返回(与 element_values 双写一致) includeDetails === true时附加details: [ formatPaymentLineItemFromPayment($payment) ],用于兼容前端对「明细」的引用
- 按
3.3 返回数据结构(与页面用法对应)
| 字段 | 说明 | 页面中的主要用途 |
|---|---|---|
| id, serial_number, status, status_text | 付款标识与状态 | 标题区、状态展示、表格 |
| total_amount, updated_at | 金额与更新时间 | 本次支付、付款确认日期 |
| payment_type_info | { payment_type_text, breadcrumb } | 支付类型一行 |
| flow_info | { id, no, title, status_text, custom_model_id, … } | 流程信息展示、collectFlowId、抽屉跳转 OA |
| description, remarks | 说明、备注 | 表格两行 |
| fields | 模板字段键值(element_id → value) | 支付模板区所有「元素」的取值来源 |
| related_type, related_id | 关联类型与 id | 决定关联内容分支(见下) |
| contract_id | 合同 id(可与 related 并存) | 合同信息卡片、关联合同事前流程 |
| details | 长度 1 的数组,兼容用 | currentDetail 等(打印页用到不多) |
payment 写入 ref(null),请求成功后再赋值为接口返回的 response.data,此后整页以 payment 为单一数据根进行渲染。
四、页面渲染结构(从上到下)
4.1 打印工具栏
- 固定于页面右上,内含「打印」「关闭」。
- 打印前会执行
renderPdfAsImages(),把本页所有会议纪要等 PDF 占位渲染成图片,再window.print()。 - 仅在屏幕显示,
@media print下隐藏。
4.2 页眉
- 标题:「付款详情」
- 打印/归档时间:
printTime(new Date().toLocaleString('zh-CN'))
4.3 付款基本信息(.section.payment-basic-info)
数据一律来自 payment:
- 固定行
- 编号、状态、本次支付、付款确认日期(仅当
status === 'completed')、支付类型、流程信息、说明、备注。
- 编号、状态、本次支付、付款确认日期(仅当
- 支付模板区(visiblePaymentTemplateElements)
- 数据:
paymentTemplateElements来自loadPaymentTemplateElements(),过滤后得到visiblePaymentTemplateElements。 - 取值:
payment.fields[el.id](及勾选清单备注键el.id_remark_${optionValue})。 - 按元素类型分别渲染:
- checklist:只读勾选列表 + 备注
- meeting_minutes:
MeetingMinutesField只读;若唯一附件为 PDF,下方通栏用 PDF 占位,由renderPdfAsImages转成图片 - detail_table:表格列来自
detailTableFieldsMap(detailTableFieldAPI.getList(elementId)),行数据来自payment.fields[elementId],部门/用户通过departmentMap、userMap转名称 - approval_flow:用
flowDetailsCache展示流程简述,flowDetailsCache由loadApprovalFlowDetails()调用plannedExpenditureAPI.getOaFlowDetails(flowIds)填充 - 附件:从
payment.fields[elementId]解析为{ name, url }列表展示 - 其余:
formatTemplateFieldValue(el, payment.fields[el.id])文本或默认展示
- 数据:
loadPaymentTemplateElements 使用 payment.payment_category_id 调 paymentCategoryAPI.getTemplateElements(categoryId),得到该分类下模板元素列表,并预加载所有 detail_table 的字段配置与部门/用户列表(若需要)。
4.4 关联内容区(按 related_type 三分支)
分支仅由 relatedTypeCase 决定,relatedTypeCase 来自 payment.related_type('planned_expenditure' | 'contract' | null/undefined/'' 等视为 'null')。
-
relatedTypeCase === 'null'
- 仅再判断
payment.contract_id。 - 若有合同 id,渲染 ContractInfoCard,
contract-id=payment.contract_id,embed-planned-expenditures="true",用于展示合同信息与「关联合同的事前流程」。
- 仅再判断
-
relatedTypeCase === 'contract'
- 渲染 ContractInfoCard,
contract-id=payment.related_id,当前付款 id 传入,同样嵌入合同事前流程。
- 渲染 ContractInfoCard,
-
relatedTypeCase === 'planned_expenditure'
- 先渲染 PlannedExpenditureInfoCard:
expenditure、template来自loadRelatedPlannedExpenditure()(按payment.related_id调plannedExpenditureAPI.getDetail(relatedId),再按category_id拉模板并写入relatedPlannedExpenditure、relatedPlannedExpenditureTemplate)。- 内部用
PlannedExpenditureTemplateReadonly,会 emitcollect-flow-id。
- 再若存在
payment.contract_id,渲染 ContractInfoCard,embed-planned-expenditures="false",只展示合同信息与合同相关支付列表,不再嵌入事前流程。
- 先渲染 PlannedExpenditureInfoCard:
三个分支里,凡是出现 ContractInfoCard 且 embedPlannedExpenditures === true,或出现 PlannedExpenditureInfoCard,其内的 PlannedExpenditureTemplateReadonly 都会从模板配置、flow_bindings、element_values 中解析出流程 id,并向父级 emit collect-flow-id,由页面 collectFlowId 汇总到 collectedFlowIds。
4.5 相关流程详情(renderedPrintTemplates)
- 显示条件:
renderedPrintTemplates.length > 0 - 数据来源:
- 流程 id 来自
collectedFlowIds(付款主流程 + 合同/事前流程子组件上报的流程 id)。 - 请求:
oaFlowAPI.renderPrintTemplates(Array.from(collectedFlowIds))→POST /oa/flow/render-print-templates,body 为{ flow_ids: number[] }。 - 后端对每个 flow_id 用 OA 的打印模版(CustomModel.print_format)渲染 HTML,返回
{ flow_id, flow_title, flow_info: { no, title, creator_name, created_at }, html }等。
- 流程 id 来自
- 渲染方式:
- 标题:「相关流程详情」
- 列表:
v-for="(template, idx) in renderedPrintTemplates",每条显示「序号、流程编号 - 流程标题(创建人 创建时间)」,正文v-html="template.html"。 - 分页:整块前
page-break-before: always;从第二条起每条前也page-break-before: always。
流程 id 收集与「相关流程详情」的详细说明见:付款详情打印页-相关流程详情渲染说明.md。
五、关键辅助请求一览
| 用途 | 调用链 | 接口 |
|---|---|---|
| 付款主数据 | paymentAPI.getDetail(id) | GET /budget/payments/{id} |
| 付款分类模板元素 | paymentCategoryAPI.getTemplateElements(categoryId) | 见 api 中 paymentCategory 相关 |
| 明细表列配置 | detailTableFieldAPI.getList(elementId) | 见 api 中 detailTableField |
| 部门/用户 | departmentAPI.getTree()、userAPI.getSimpleList() | 部门树、用户简单列表 |
| 审批流程简述 | plannedExpenditureAPI.getOaFlowDetails(flowIds) | 批量取 OA 流程展示信息 |
| 事前流程实体+模板 | plannedExpenditureAPI.getDetail(relatedId)、plannedExpenditureTemplateAPI.getByCategory(categoryId) | 事前流程详情、按分类取模板 |
| 合同相关 | ContractInfoCard 内 contractAPI、paymentAPI、plannedExpenditureAPI 等 | 合同详情、合同下支付列表、关联事前流程等 |
| 相关流程 HTML | oaFlowAPI.renderPrintTemplates(flowIds) | POST /oa/flow/render-print-templates |
六、状态与缓存(前端)
payment:当前付款详情,整页主数据源。paymentTemplateElements/visiblePaymentTemplateElements:模板元素列表与「有值才展示」的过滤结果。templatesCache:按事前分类 id 缓存的打印用模板,避免重复请求。flowDetailsCache:按流程 id 缓存的流程简述,供审批流程元素展示。detailTableFieldsMap:按明细表元素 id 缓存的列配置。departmentMap/userMap:部门、用户 id→名称。collectedFlowIds:当前页及子组件上报的流程 id 集合,用于拉取「相关流程详情」。renderedPrintTemplates:接口返回的流程打印 HTML 列表,驱动「相关流程详情」区块。relatedPlannedExpenditure/relatedPlannedExpenditureTemplate:仅当related_type === 'planned_expenditure'时有效,用于 PlannedExpenditureInfoCard。
七、与 URL 中 id 的对应关系
对 http://czemc.localhost/budget/#/payment/payment-detail-print/161:
161即route.params.id,作为paymentId传入paymentAPI.getDetail(161)。- 若存在,返回的
Payment即 id=161 的付款记录,整页展示、关联内容、流程收集与「相关流程详情」都基于这一条付款数据派生而来。
八、相关文件索引
| 角色 | 路径 |
|---|---|
| 页面组件 | czemc-budget-execution-frontend/src/views/payment/PaymentDetailPrint.vue |
| 路由 | czemc-budget-execution-frontend/src/router/index.js |
| 付款接口 | paymentAPI.getDetail → GET /budget/payments/{id} |
| 付款详情后端 | backend/Modules/Budget/app/Http/Controllers/Api/PaymentController.php(show、formatPayment) |
| 合同信息卡片 | czemc-budget-execution-frontend/src/components/payment-print/ContractInfoCard.vue |
| 事前流程信息卡片 | czemc-budget-execution-frontend/src/components/payment-print/PlannedExpenditureInfoCard.vue |
| 事前模板只读(含 collect-flow-id) | czemc-budget-execution-frontend/src/components/PlannedExpenditureTemplateReadonly.vue |
| 相关流程详情渲染说明 | czemc-budget-execution-frontend/docs/付款详情打印页-相关流程详情渲染说明.md |
| 流程打印模版 API / 后端 | oaFlowAPI.renderPrintTemplates、backend/Modules/Oa/.../FlowController.php :: renderPrintTemplates |
以上为付款详情打印页(含 /payment/payment-detail-print/161)的数据与渲染流程梳理,便于从 URL → 接口 → 状态 → 区块逐层对照。