ERPTurbo_Client/packages/app-client/src/utils/classes/templates/PdfTemplate.ts
shenyifei 24d53d6c83 feat(audit): 添加审批和审核查看功能并优化发货单据生成
- 在审批列表中添加老板查看审批按钮,仅在审批成功时显示
- 在审核列表中添加审核员查看审核按钮,仅在审核成功时显示
- 修复发货单据组件中重量计算使用净重而非毛重的问题
- 移除采购交付表单中的调试日志输出
- 将审批页面标题从"采购单审核"改为"采购单审批"
- 在审批页面中添加供应商采购单价列表展示功能,支持展开收起
- 优化审批页面成本明细显示,添加到货日期信息
- 修复审批页面中返点金额的条件判断逻辑
- 优化审批页面利润显示颜色,正利润显示为蓝色,负利润显示为红色
- 添加返回首页按钮到审批页面底部操作栏
- 重构发货单据页面数据加载逻辑,优化模板配置更新流程
- 移除发货单据页面中未使用的经销商返点客户列表状态管理
- 优化发货单据页面的预览和生成方法参数传递
2025-12-28 08:43:04 +08:00

619 lines
23 KiB
TypeScript
Raw 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.

export class PdfTemplate {
private moduleList: any[];
constructor(moduleList: any[]) {
this.moduleList = moduleList;
}
// 将预览内容转换为HTML字符串的函数
generateHtmlString = () => {
let htmlString = `
<style> @page {size: 210mm 297mm;margin: 0;padding: 0;}* {outline: none;box-sizing: border-box;margin: 0;padding: 0;border: 0 solid;}body {background-color: #fff;color: #4d4d4d;font-size: 14px;font-style: normal;box-sizing: border-box;}.page-wrap {width: 210mm;min-height: 297mm;margin: 0 auto;}.page-content {position: relative;box-sizing: border-box;width: 100%;height: 100%;padding: 20mm 10mm 0;display: flex;flex-direction: column;gap: 2mm;}@media print {.print-controls {display: none !important;}body {padding: 0;margin: 0;}}.print-module {margin-bottom: 15px;text-align: center;}.print-controls {position: fixed;top: 10px;right: 10px;z-index: 9999;}.print-button,.close-button {padding: 8px 16px;margin-left: 10px;cursor: pointer;border: 1px solid #d9d9d9;border-radius: 4px;}.print-button {background-color: #1890ff;color: white;}.close-button {background-color: #fff;color: #000;}.preview {width: 19cm;div {height: 0.7cm;}}.table-border {border: 2px solid #000;}.table-border>div {border-bottom: 1px solid #000;}.table-border>div>div {border-right: 1px solid #000;}.table-border>div>div:last-child {border-right: none;}.table-border>div:last-child {border-bottom: none;}.col-span-1 {grid-column: span 1 / span 1;}.col-span-2 {grid-column: span 2 / span 2;}.col-span-3 {grid-column: span 3 / span 3;}.col-span-6 {grid-column: span 6 / span 6;}.col-span-8 {grid-column: span 8 / span 8;}.flex {display: flex;}.items-center {align-items: center;}.grid {display: grid;}.w-full {width: 100%;}.grid-cols-1 {grid-template-columns: repeat(1, minmax(0, 1fr));}.grid-cols-2 {grid-template-columns: repeat(2, minmax(0, 1fr));}.grid-cols-3 {grid-template-columns: repeat(3, minmax(0, 1fr));}.grid-cols-4 {grid-template-columns: repeat(4, minmax(0, 1fr));}.grid-cols-5 {grid-template-columns: repeat(5, minmax(0, 1fr));}.grid-cols-6 {grid-template-columns: repeat(6, minmax(0, 1fr));}.grid-cols-7 {grid-template-columns: repeat(7, minmax(0, 1fr));}.grid-cols-8 {grid-template-columns: repeat(8, minmax(0, 1fr));}.items-end {align-items: flex-end;}.justify-center {justify-content: center;}.border-t-0 {border-top-width: 0px;}.border-b {border-bottom-width: 1px;}.border-black {border-color: #000000;}.bg-white {background-color: #ffffff;}.text-2xl {font-size: 24px;line-height: 1;}.text-base {font-size: 16px;line-height: 1;}.text-lg {font-size: 18px;line-height: 1;}.font-bold {font-weight: bold;}.preview {width: 19cm;div {height: 0.69cm;}}.table-border {border: 2px solid #000;}.table-border>div {border-bottom: 1px solid #000;}.table-border>div>div {border-right: 1px solid #000;}.table-border>div>div:last-child {border-right: none;}.table-border>div:last-child {border-bottom: none;}.p-2 {padding:8px}</style>
<div class="page-wrap">
<div class="page-content">
`;
this.moduleList.forEach((module) => {
const config = module.config;
if (module.type === "title") {
htmlString += `
<div class="preview grid w-full grid-cols-8 gap-0 text-2xl font-bold">
<div class="col-span-8 flex items-end justify-center">
${config.title || ""}
</div>
</div>
`;
}
if (module.type === "dealerInfo") {
htmlString += `
<div class="preview grid w-full grid-cols-8 gap-0 text-lg font-bold">
<div class="col-span-1"></div>
`;
if (config.showDealerName || config.showWatermelonGrade) {
htmlString += `
<div class="col-span-3 flex items-end justify-center border-b border-black">
${
config.showWatermelonGrade
? `${config.dealerName || ""}-${config.watermelonGrade || ""}`
: config.dealerName || ""
}
</div>
`;
} else {
htmlString += `<div class="col-span-3"></div>`;
}
if (config.showDestination || config.showVehicleNumber) {
htmlString += `
<div class="col-span-3 flex items-end justify-center border-b border-black">
${config.destination || ""} ${config.vehicleNumber || ""}
</div>
`;
} else {
htmlString += `<div class="col-span-3"></div>`;
}
htmlString += `
<div class="col-span-1"></div>
</div>
`;
}
if (module.type === "shippingInfo") {
htmlString += `<div class="preview grid w-full grid-cols-8 gap-0 text-base">`;
if (config.showShippingFrom) {
htmlString += `
<div class="col-span-1 flex items-end justify-center">发货地:</div>
<div class="col-span-3 flex items-end justify-center border-b border-black">
${config.shippingFrom || ""}
</div>
`;
}
if (config.showDate) {
htmlString += `
<div class="col-span-1 flex items-end justify-center">日期:</div>
<div class="col-span-3 flex items-end justify-center border-b border-black">
${config.date || ""}
</div>
`;
}
htmlString += `</div>`;
}
if (module.type === "weightInfo") {
if (config.data) {
config.data.forEach((item: any) => {
htmlString += `<div class="preview grid w-full grid-cols-2 gap-0 text-base">`;
if (config.showNetWeight) {
htmlString += `
<div class="col-span-1 grid grid-cols-4">
<div class="col-span-1 flex items-end justify-center">净重:</div>
<div class="col-span-2 flex items-end justify-center border-b border-black">
${item.netWeight || ""}
</div>
<div class="col-span-1 flex items-end justify-center border-b border-black">
${config.netWeightUnit === "1" ? "斤" : "公斤"}
</div>
</div>
`;
}
if (config.showBoxWeight) {
htmlString += `
<div class="col-span-1 grid grid-cols-4">
<div class="col-span-1 flex items-end justify-center">箱重:</div>
<div class="col-span-2 flex items-end justify-center border-b border-black">
${item.boxWeight || ""}
</div>
<div class="col-span-1 flex items-end justify-center border-b border-black">
${config.boxWeightUnit === "1" ? "斤" : "公斤"}
</div>
</div>
`;
}
if (config.showGrossWeight) {
htmlString += `
<div class="col-span-1 grid grid-cols-4">
<div class="col-span-1 flex items-end justify-center">毛重:</div>
<div class="col-span-2 flex items-end justify-center border-b border-black">
${item.grossWeight || ""}
</div>
<div class="col-span-1 flex items-end justify-center border-b border-black">
${config.grossWeightUnit === "1" ? "斤" : "公斤"}
</div>
</div>
`;
}
if (config.showUnitPrice) {
htmlString += `
<div class="col-span-1 grid grid-cols-4">
<div class="col-span-1 flex items-end justify-center">单价:</div>
<div class="col-span-2 flex items-end justify-center border-b border-black">
${item.unitPrice || ""}
</div>
<div class="col-span-1 flex items-end justify-center border-b border-black">
${config.unitPriceUnit === "1" ? "元/斤" : "元/公斤"}
</div>
</div>
`;
}
if (config.showAmount) {
htmlString += `
<div class="col-span-1 grid grid-cols-4">
<div class="col-span-1 flex items-end justify-center">金额:</div>
<div class="col-span-2 flex items-end justify-center border-b border-black">
${item.totalAmount || ""}
</div>
<div class="col-span-1 flex items-end justify-center border-b border-black">元</div>
</div>
`;
}
if (config.showGrade) {
htmlString += `
<div class="col-span-1 grid grid-cols-4">
<div class="col-span-1 flex items-end justify-center">品级:</div>
<div class="col-span-3 flex items-end justify-center border-b border-black">
${item.watermelonGrade || ""}
</div>
</div>
`;
}
htmlString += `</div>`;
});
}
htmlString += `<div class="preview grid w-full grid-cols-2 gap-0 text-base">`;
if (config.showAccountCompany) {
htmlString += `
<div class="col-span-1 grid grid-cols-4">
<div class="col-span-1 flex items-end justify-center">入账公司:</div>
<div class="col-span-3 flex items-end justify-center border-b border-black">
${config.accountCompany || ""}
</div>
</div>
`;
}
if (config.showSumAmount) {
htmlString += `
<div class="col-span-1 grid grid-cols-4">
<div class="col-span-1 flex items-end justify-center">总计:</div>
<div class="col-span-2 flex items-end justify-center border-b border-black">
${config.sumAmount || ""}
</div>
<div class="col-span-1 flex items-end justify-center border-b border-black">元</div>
</div>
`;
}
htmlString += `</div>`;
}
if (module.type === "packingSpec") {
htmlString += `<div>`;
// 计算需要显示的列数
const visibleColumnCount =
[
config.showBoxType,
config.showQuantity,
config.showUnitPrice,
config.showAmount,
config.showUnitWeight,
config.showWeight,
].filter(Boolean).length + 1; // +1 是因为"规格:"列总是显示
const gridClass = `grid w-full gap-0 text-base grid-cols-${visibleColumnCount}`;
htmlString += `
<div class="${gridClass}">
<div class="grid-span-1 flex items-end justify-center">规格:</div>
</div>
`;
htmlString += `<div class="${gridClass}">`;
if (config.columns) {
config.columns.forEach((column: any, index: number) => {
if (index === 0) {
htmlString += `<div class="">&nbsp;</div>`;
return;
}
if (
(column.dataIndex === "boxType" && config.showBoxType) ||
(column.dataIndex === "quantity" && config.showQuantity) ||
(column.dataIndex === "unitPrice" && config.showUnitPrice) ||
(column.dataIndex === "amount" && config.showAmount) ||
(column.dataIndex === "unitWeight" && config.showUnitWeight) ||
(column.dataIndex === "weight" && config.showWeight)
) {
htmlString += `
<div class="flex items-end justify-center">${column.title || ""}</div>
`;
}
});
}
htmlString += `</div>`;
htmlString += `<div class="table-border">`;
if (config.data) {
config.data.forEach((item: any, index: number) => {
htmlString += `
<div class="${gridClass} ${index > 0 ? "border-t-0" : ""}">
<div class="flex items-end justify-center">
${item.boxSpecName}
</div>
`;
htmlString += `
<div class="flex items-end justify-center">${item.boxType || ""}</div>
`;
if (config.showQuantity) {
htmlString += `
<div class="flex items-end justify-center">${item.quantity || ""}</div>
`;
}
if (config.showUnitPrice) {
htmlString += `
<div class="flex items-end justify-center">${item.unitPrice || ""}</div>
`;
}
if (config.showAmount) {
htmlString += `
<div class="flex items-end justify-center">${item.amount || ""}</div>
`;
}
if (config.showUnitWeight) {
htmlString += `
<div class="flex items-end justify-center">${item.unitWeight || ""}</div>
`;
}
if (config.showWeight) {
htmlString += `
<div class="flex items-end justify-center">${item.weight || ""}</div>
`;
}
htmlString += `</div>`;
});
}
htmlString += `
<div class="${gridClass}">
<div class="col-span-2 flex items-end justify-center">总件数</div>
`;
if (config.showQuantity) {
htmlString += `
<div class="col-span-1 flex items-end justify-center">
${
config.data?.reduce(
(acc: any, cur: any) => acc + Number(cur.quantity || 0),
0,
) || 0
}
</div>
`;
}
if (config.showUnitPrice) {
htmlString += `
<div class="col-span-1 flex items-end justify-center">
</div>
`;
}
if (config.showAmount) {
htmlString += `
<div class="col-span-1 flex items-end justify-center">
${
config.data?.reduce(
(acc: any, cur: any) => acc + Number(cur.amount || 0),
0,
) || 0
}
</div>
`;
}
if (config.showUnitWeight) {
htmlString += `
<div class="col-span-1 flex items-end justify-center">
</div>
`;
}
if (config.showWeight) {
htmlString += `
<div class="col-span-1 flex items-end justify-center">
${
config.data?.reduce(
(acc: any, cur: any) => acc + Number(cur.weight || 0),
0,
) || 0
}
</div>
`;
}
htmlString += `
</div>
</div>
`;
htmlString += `</div>`;
}
if (module.type === "vehicleInfo") {
htmlString += `<div class="preview grid w-full grid-cols-8 gap-0 text-base">`;
if (config.showDriverPhone) {
htmlString += `
<div class="col-span-2 flex items-end justify-center">司机号码:</div>
<div class="col-span-6 flex items-end justify-center border-b border-black">
${config.driverPhone || ""}
</div>
`;
}
if (config.showLicensePlate) {
htmlString += `
<div class="col-span-2 flex items-end justify-center">车牌:</div>
<div class="col-span-6 flex items-end justify-center border-b border-black">
${config.licensePlate || ""}
</div>
`;
}
if (config.showEstimatedArrivalTime) {
htmlString += `
<div class="col-span-2 flex items-end justify-center">预计到仓时间:</div>
<div class="col-span-6 flex items-end justify-center border-b border-black">
${config.estimatedArrivalTime || ""}
</div>
`;
}
if (config.showRemarks) {
htmlString += `
<div class="col-span-2 flex items-end justify-center">备注:</div>
<div class="col-span-6 flex items-end justify-center border-b border-black">
${config.remarks || ""}
</div>
`;
}
if (config.showFreightDebt) {
htmlString += `
<div class="col-span-2 flex items-end justify-center">
${config.freightDebtTitle || "运费欠"}:
</div>
<div class="col-span-2 flex items-end justify-center border-b border-black">
${config.freightDebt || ""}
</div>
`;
}
if (config.showStrawMatDebt) {
htmlString += `
<div class="col-span-2 flex items-end justify-center">草帘欠:</div>
<div class="col-span-2 flex items-end justify-center border-b border-black">
${config.strawMatDebt || ""}
</div>
`;
}
htmlString += `</div>`;
}
if (module.type === "otherFees") {
htmlString += `<div class="preview grid w-full grid-cols-8 gap-0 text-base">`;
if (config.feeItems) {
config.feeItems.forEach((feeType: any) => {
htmlString += `
<div class="col-span-1 flex items-end justify-center">
${(config.feeLabels && config.feeLabels[feeType]) || ""}
</div>
<div class="col-span-1 flex items-end justify-center border-b border-black">
${config[feeType] || ""}
</div>
`;
});
}
htmlString += `</div>`;
}
if (module.type === "totalAmount") {
htmlString += `<div class="preview grid w-full grid-cols-8 gap-0 text-base">`;
if (config.showTotalAmount) {
htmlString += `
<div class="col-span-1 flex items-end justify-center">
${config.sumTitle || "合计金额"}:
</div>
<div class="col-span-2 flex items-end justify-center border-b border-black">
${config.amount || ""}
</div>
<div class="col-span-1 flex items-end justify-center border-b border-black">元</div>
`;
}
if (config.showFarmer) {
htmlString += `
<div class="col-span-1 flex items-end justify-center">瓜农:</div>
<div class="col-span-3 flex items-end justify-center border-b border-black">
${config.farmer || ""}
</div>
`;
}
htmlString += `</div>`;
}
if (module.type === "otherInfo") {
htmlString += `
<div class="table-border">
<div class="grid w-full grid-cols-3 gap-0 text-base">
<div class="p-2 text-left font-bold">车次:</div>
<div class="col-span-2 p-2 text-left">
${config.vehicleNumber}
</div>
</div>
<div class="grid w-full grid-cols-3 gap-0 text-base">
<div class="p-2 text-left font-bold">
收货地:
</div>
<div class="col-span-2 p-2 text-left">
${config.destination}
</div>
</div>
`;
if (config.showShippingFrom) {
htmlString += `
<div class="grid w-full grid-cols-3 gap-0 text-base">
<div class="p-2 text-left font-bold">
产地:
</div>
<div class="col-span-2 p-2 text-left">
${config.shippingFrom}
</div>
</div>
`;
}
htmlString += `<div class="grid w-full grid-cols-3 gap-0 text-base">
<div class="p-2 text-left font-bold">
供应商:
</div>
<div class="col-span-2 p-2 text-left">
${config.accountCompany}
</div>
</div>
<div class="grid w-full grid-cols-3 gap-0 text-base">
<div class="p-2 text-left font-bold">
发车时间:
</div>
<div class="col-span-2 p-2 text-left">
${config.date}
</div>
</div>
`;
if (config.showEstimatedArrivalTime) {
htmlString += `<div class="grid w-full grid-cols-3 gap-0 text-base">
<div class="p-2 text-left font-bold">
到达时间:
</div>
<div class="col-span-2 p-2 text-left">
${config.estimatedArrivalTime}
</div>
</div>
`;
}
if (config.data) {
config.data?.forEach((item: any) => {
if (config.showGrade) {
htmlString += `
<div class="grid w-full grid-cols-3 gap-0 text-base">
<div class="p-2 text-left font-bold">
品名:
</div>
<div class="col-span-2 p-2 text-left">
${item.watermelonGrade}
</div>
</div>
`;
}
htmlString += `
<div class="grid w-full grid-cols-3 gap-0 text-base">
<div class="p-2 text-left font-bold">
发货重量:
</div>
<div class="col-span-2 p-2 text-left">
以公司入库重量为准。
</div>
</div>
<div class="grid w-full grid-cols-3 gap-0 text-base">
<div class="p-2 text-left font-bold">
净瓜单价:
</div>
<div class="col-span-2 p-2 text-left">
${item.unitPrice}
${config.unitPriceUnit === "1" ? "元/斤" : "元/公斤"}
</div>
</div>
`;
});
}
htmlString += `
<div class="grid w-full grid-cols-3 gap-0 text-base">
<div class="p-2 text-left font-bold">
大约重量:
</div>
<div class="p-2 text-left">
${config.data?.reduce(
(acc: any, cur: any) => acc + cur.netWeight,
0,
)}
</div>
<div class="p-2 text-left">斤</div>
</div>
<div class="grid w-full grid-cols-3 gap-0 text-base">
<div class="p-2 text-left font-bold">箱数</div>
<div class="p-2 text-left">
${config.data?.reduce(
(acc: any, cur: any) => acc + cur.boxCount,
0,
)}
</div>
<div class="p-2 text-left">件</div>
</div>
<div class="grid w-full grid-cols-3 gap-0 text-base">
<div class="p-2 text-left font-bold">车号:</div>
<div class="col-span-2 p-2 text-left">
${config.licensePlate}
</div>
</div>
<div class="grid w-full grid-cols-3 gap-0 text-base">
<div class="p-2 text-left font-bold">
手机号:
</div>
<div class="col-span-2 p-2 text-left">
${config.driverPhone}
</div>
</div>
</div>
`;
}
});
htmlString += `</div></div>`;
console.log("generateHtmlString", htmlString);
return htmlString;
};
}