ERPTurbo_Client/packages/app-client/src/utils/Template.ts
shenyifei 74623e6c1b feat(delivery): 新增发货单据预览组件及模板生成功能
- 添加 DealerInfo、WeightInfo 等多个发货单据信息展示组件
- 实现 Template 类用于将模块配置转换为 HTML 字符串
- 更新 OrderVehicle 组件以简化经销商数据设置逻辑
- 移除冗余的单据类型判断逻辑,统一处理发货单据生成流程
- 导出新增的 DeliveryStep 和 PurchaseStep 相关组件
- 在发货列表页集成新的发货单据生成功能并优化界面交互
2025-11-19 08:01:54 +08:00

618 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.

class Template {
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.grossWeight,
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>`;
return htmlString;
};
}