fix(crm/contract): 优化合同预览与导出功能
1. 隐藏打印预览按钮 2. 调整合同预览页面样式间距与logo位置 3. 修改合同金额字段保留小数位数为3位 4. 优化PDF导出分页逻辑,按空白行自动分页
This commit is contained in:
@@ -326,10 +326,10 @@ export default {
|
||||
if (hasCol('quantity')) cells += `<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${product.quantity || ''}</td>`;
|
||||
if (hasCol('taxPrice')) cells += `<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${product.taxPrice || ''}</td>`;
|
||||
if (hasCol('taxDivisor')) cells += `<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${product.taxDivisor || '1.13'}</td>`;
|
||||
if (hasCol('noTaxPrice')) cells += `<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${(product.noTaxPrice || 0).toFixed(2)}</td>`;
|
||||
if (hasCol('taxTotal')) cells += `<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${(product.taxTotal || 0).toFixed(2)}</td>`;
|
||||
if (hasCol('noTaxTotal')) cells += `<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${(product.noTaxTotal || 0).toFixed(2)}</td>`;
|
||||
if (hasCol('taxAmount')) cells += `<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${(product.taxAmount || 0).toFixed(2)}</td>`;
|
||||
if (hasCol('noTaxPrice')) cells += `<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${(product.noTaxPrice || 0).toFixed(3)}</td>`;
|
||||
if (hasCol('taxTotal')) cells += `<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${(product.taxTotal || 0).toFixed(3)}</td>`;
|
||||
if (hasCol('noTaxTotal')) cells += `<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${(product.noTaxTotal || 0).toFixed(3)}</td>`;
|
||||
if (hasCol('taxAmount')) cells += `<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${(product.taxAmount || 0).toFixed(3)}</td>`;
|
||||
if (hasCol('remark')) cells += `<td style="border:1px solid #000;padding:3px 4px;text-align:center;max-width:100px;word-wrap:break-word;">${product.remark || ''}</td>`;
|
||||
bodyRows += `<tr>${cells}</tr>`;
|
||||
});
|
||||
@@ -352,10 +352,10 @@ export default {
|
||||
}
|
||||
} else {
|
||||
let val = '';
|
||||
if (col.key === 'quantity') val = totalQty.toFixed(2);
|
||||
else if (col.key === 'taxTotal') val = totalTax.toFixed(2);
|
||||
else if (col.key === 'noTaxTotal') val = totalNoTax.toFixed(2);
|
||||
else if (col.key === 'taxAmount') val = totalTaxAmt.toFixed(2);
|
||||
if (col.key === 'quantity') val = totalQty.toFixed(3);
|
||||
else if (col.key === 'taxTotal') val = totalTax.toFixed(3);
|
||||
else if (col.key === 'noTaxTotal') val = totalNoTax.toFixed(3);
|
||||
else if (col.key === 'taxAmount') val = totalTaxAmt.toFixed(3);
|
||||
totalCells += `<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${val}</td>`;
|
||||
}
|
||||
cellIdx++;
|
||||
@@ -605,23 +605,63 @@ export default {
|
||||
|
||||
document.body.removeChild(container);
|
||||
|
||||
const pdf = new jsPDF('p', 'mm', 'a4');
|
||||
const pdfWidth = 210;
|
||||
const pdfHeight = 297;
|
||||
const imgWidth = pdfWidth;
|
||||
const imgHeight = (canvas.height * pdfWidth) / canvas.width;
|
||||
const pdf = new jsPDF('p', 'mm', 'a4');
|
||||
const imgData = canvas.toDataURL('image/jpeg', 0.95);
|
||||
let heightLeft = imgHeight;
|
||||
let position = 0;
|
||||
const margin = 5;
|
||||
const contentWidth = pdfWidth - margin * 2;
|
||||
const contentHeight = pdfHeight - margin * 2;
|
||||
const scale = contentWidth / canvas.width;
|
||||
|
||||
pdf.addImage(imgData, 'JPEG', 0, position, imgWidth, imgHeight);
|
||||
heightLeft -= pdfHeight;
|
||||
function isBlankRow(canvas, y) {
|
||||
const ctx = canvas.getContext('2d');
|
||||
const row = ctx.getImageData(0, y, canvas.width, 1).data;
|
||||
let whiteCount = 0;
|
||||
const total = row.length / 4;
|
||||
for (let i = 0; i < row.length; i += 4) {
|
||||
if (row[i] > 250 && row[i + 1] > 250 && row[i + 2] > 250) whiteCount++;
|
||||
}
|
||||
return whiteCount / total >= 0.95;
|
||||
}
|
||||
|
||||
while (heightLeft > 0) {
|
||||
position = heightLeft - imgHeight;
|
||||
pdf.addPage();
|
||||
pdf.addImage(imgData, 'JPEG', 0, position, imgWidth, imgHeight);
|
||||
heightLeft -= pdfHeight;
|
||||
function findBreakY(canvas, targetY, range) {
|
||||
range = range || 40;
|
||||
for (let offset = 0; offset < range; offset++) {
|
||||
if (targetY + offset < canvas.height && isBlankRow(canvas, targetY + offset)) return targetY + offset;
|
||||
if (targetY - offset > 0 && isBlankRow(canvas, targetY - offset)) return targetY - offset;
|
||||
}
|
||||
return targetY;
|
||||
}
|
||||
|
||||
let currentY = 0;
|
||||
let firstPage = true;
|
||||
|
||||
while (currentY < canvas.height) {
|
||||
const pageHeightPx = Math.round(contentHeight / scale);
|
||||
let endY = Math.min(currentY + pageHeightPx, canvas.height);
|
||||
|
||||
if (endY < canvas.height) {
|
||||
endY = findBreakY(canvas, endY);
|
||||
}
|
||||
|
||||
const sliceHeight = endY - currentY;
|
||||
const pageCanvas = document.createElement('canvas');
|
||||
pageCanvas.width = canvas.width;
|
||||
pageCanvas.height = sliceHeight;
|
||||
pageCanvas.getContext('2d').drawImage(canvas, 0, currentY, canvas.width, sliceHeight, 0, 0, canvas.width, sliceHeight);
|
||||
|
||||
const imgData = pageCanvas.toDataURL('image/jpeg', 0.95);
|
||||
const pageImgHeight = sliceHeight * scale;
|
||||
|
||||
if (firstPage) {
|
||||
pdf.addImage(imgData, 'JPEG', margin, margin, contentWidth, pageImgHeight);
|
||||
firstPage = false;
|
||||
} else {
|
||||
pdf.addPage();
|
||||
pdf.addImage(imgData, 'JPEG', margin, margin, contentWidth, pageImgHeight);
|
||||
}
|
||||
|
||||
currentY = endY;
|
||||
}
|
||||
|
||||
pdf.save(`合同_${row.contractCode || row.contractName || '未命名'}.pdf`);
|
||||
|
||||
Reference in New Issue
Block a user