feat: 合同富文本改为表头调列宽、首列调行高,避免拖拽把邻列挤窄。
产品表按像素列宽重排,水印改到页面右下角,打开编辑时不再铺满整表绿线。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
bde19c0644
commit
3aa0f0ff2e
12 files changed
+734
-161
No files matched your search
@@ -913,7 +913,7 @@
|
||||
<div class="generate-print-dialog-header">
|
||||
<span class="generate-print-dialog-title">{{ isPreviewMode ? '预览合同' : '编辑合同' }}</span>
|
||||
<p v-if="!isPreviewMode" class="generate-print-dialog-edit-hint">
|
||||
编辑模式:鼠标移入表格后,列/行边界会出现绿色调整条,按住拖动即可调列宽或行高;工具栏可合并拆分、插删行列、对齐与换行。调整后请点「保存模板」。
|
||||
编辑模式:鼠标移到表头格子的右边界可调列宽,移到每行最左边格子的下边界可调行高。工具栏可合并拆分、插删行列、对齐与换行。调整后请点「保存模板」。
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1056,6 +1056,8 @@ import TinyMceEditor from '@/components/TinyMceEditor/index.vue';
|
||||
import html2canvas from 'html2canvas';
|
||||
import jsPDF from 'jspdf';
|
||||
import { fitRichTextTablesToMaxWidth } from '@/utils/tinymce-table-excel-resize';
|
||||
import { normalizeContractProductTableWidths } from '@/utils/crm/contract-product-table-widths';
|
||||
import { appendContractPageWatermarks, contractWatermarkPrintCss } from '@/utils/crm/contract-watermark';
|
||||
import {
|
||||
downloadCrmAttachment,
|
||||
getCrmAttachmentCategoryLabel,
|
||||
@@ -2136,6 +2138,30 @@ const replacePlaceholders = (htmlContent: string, contractData: ContractVO | und
|
||||
/(<th\b[^>]*style="[^"]*?\bwidth:\s*)\d+(%;[^"]*"[^>]*>\s*包装规格\s*<\/th>)/gi,
|
||||
(_m, prefix, suffix) => `${prefix}11${suffix}`
|
||||
)
|
||||
result = result.replace(
|
||||
/(<th\b[^>]*style="[^"]*?\bwidth:\s*)\d+(%;[^"]*"[^>]*>\s*产品名称\s*<\/th>)/gi,
|
||||
(_m, prefix, suffix) => `${prefix}13${suffix}`
|
||||
)
|
||||
result = result.replace(
|
||||
/(<th\b[^>]*style="[^"]*?\bwidth:\s*)\d+(%;[^"]*"[^>]*>\s*备注\s*<\/th>)/gi,
|
||||
(_m, prefix, suffix) => `${prefix}5${suffix}`
|
||||
)
|
||||
result = result.replace(
|
||||
/(<th\b[^>]*style="[^"]*?\bwidth:\s*)\d+(%;[^"]*"[^>]*>\s*单位\s*<\/th>)/gi,
|
||||
(_m, prefix, suffix) => `${prefix}7${suffix}`
|
||||
)
|
||||
result = result.replace(
|
||||
/(<th\b[^>]*style="[^"]*?\bwidth:\s*)\d+(%;[^"]*"[^>]*>\s*用量(?:(吨))?\s*<\/th>)/gi,
|
||||
(_m, prefix, suffix) => `${prefix}9${suffix}`
|
||||
)
|
||||
result = result.replace(
|
||||
/(<th\b[^>]*style="[^"]*?\bwidth:\s*)\d+(%;[^"]*"[^>]*>\s*含税单价(元(?:\/吨)?)\s*<\/th>)/gi,
|
||||
(_m, prefix, suffix) => `${prefix}10${suffix}`
|
||||
)
|
||||
result = result.replace(
|
||||
/(<th\b[^>]*style="[^"]*?\bwidth:\s*)\d+(%;[^"]*"[^>]*>\s*未含税金额(元)\s*<\/th>)/gi,
|
||||
(_m, prefix, suffix) => `${prefix}10${suffix}`
|
||||
)
|
||||
|
||||
|
||||
// 合计区(12 列):运费/桶押金 → 不含税/税额 → 含税金额合计 → 提示
|
||||
@@ -2147,7 +2173,7 @@ const replacePlaceholders = (htmlContent: string, contractData: ContractVO | und
|
||||
const freightText = freightAmount > 0 ? `¥${formatNumber(freightAmount)}` : '-';
|
||||
const barrelDepositText = barrelDepositAmount > 0 ? `¥${formatNumber(barrelDepositAmount)}` : '-';
|
||||
const formatRmbAmountText = (amount: number) =>
|
||||
isFrameworkContract ? '随行就市' : `${numberToChinese(amount)}(¥${formatNumber(amount)})`;
|
||||
isFrameworkContract ? '随行就市' : `${numberToChinese(amount)}<br/>(¥${formatNumber(amount)})`;
|
||||
const beforeTaxTotalText = formatRmbAmountText(productTotalBeforeTax);
|
||||
const taxTotalText = formatRmbAmountText(totalTax);
|
||||
const totalWithExtrasText = formatRmbAmountText(totalWithExtras);
|
||||
@@ -2162,14 +2188,14 @@ const replacePlaceholders = (htmlContent: string, contractData: ContractVO | und
|
||||
<td colspan="4" style="padding: 5px 6px; border: 0.3px solid #000; text-align: center; font-size: 12px;">${barrelDepositText}</td>
|
||||
</tr>
|
||||
<tr style="background-color: #fff; font-weight: bold;">
|
||||
<td colspan="2" style="padding: 5px 6px; border: 0.3px solid #000; text-align: center; font-size: 12px;">不含税金额合计(人民币)</td>
|
||||
<td colspan="4" style="padding: 5px 6px; border: 0.3px solid #000; text-align: center; font-size: 12px;">${beforeTaxTotalText}</td>
|
||||
<td colspan="2" style="padding: 5px 6px; border: 0.3px solid #000; text-align: center; font-size: 12px;">税额合计(人民币)</td>
|
||||
<td colspan="4" style="padding: 5px 6px; border: 0.3px solid #000; text-align: center; font-size: 12px;">${taxTotalText}</td>
|
||||
<td colspan="2" style="padding: 5px 6px; border: 0.3px solid #000; text-align: center; font-size: 12px; line-height: 1.35;">不含税金额合计<br/>(人民币)</td>
|
||||
<td colspan="4" style="padding: 5px 6px; border: 0.3px solid #000; text-align: center; font-size: 12px; line-height: 1.35;">${beforeTaxTotalText}</td>
|
||||
<td colspan="2" style="padding: 5px 6px; border: 0.3px solid #000; text-align: center; font-size: 12px; line-height: 1.35;">税额合计<br/>(人民币)</td>
|
||||
<td colspan="4" style="padding: 5px 6px; border: 0.3px solid #000; text-align: center; font-size: 12px; line-height: 1.35;">${taxTotalText}</td>
|
||||
</tr>
|
||||
<tr style="background-color: #fff; font-weight: bold;">
|
||||
<td colspan="2" style="padding: 5px 6px; border: 0.3px solid #000; text-align: center; font-size: 12px;">含税金额合计(人民币)</td>
|
||||
<td colspan="10" style="padding: 5px 6px; border: 0.3px solid #000; text-align: center; font-size: 12px;">${totalWithExtrasText}</td>
|
||||
<td colspan="2" style="padding: 5px 6px; border: 0.3px solid #000; text-align: center; font-size: 12px; line-height: 1.35;">含税金额合计<br/>(人民币)</td>
|
||||
<td colspan="10" style="padding: 5px 6px; border: 0.3px solid #000; text-align: center; font-size: 12px; line-height: 1.35;">${totalWithExtrasText}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="12" style="padding: 5px 6px; border: 0.3px solid #000; text-align: center; font-size: 11px; background-color: #fff;">
|
||||
@@ -2221,7 +2247,7 @@ const replacePlaceholders = (htmlContent: string, contractData: ContractVO | und
|
||||
result = result.replace(/\{\{partyASeal\}\}/gi, getSealHtml(contractData.partyA));
|
||||
result = result.replace(/\{\{partyBSeal\}\}/gi, getSealHtml(contractData.partyB));
|
||||
|
||||
return result;
|
||||
return normalizeContractProductTableWidths(result);
|
||||
};
|
||||
|
||||
/** 替换模板第五条内容 */
|
||||
@@ -2511,18 +2537,18 @@ const generateContractTemplate = (contractData: ContractVO | undefined): string
|
||||
<table style="width: 100%; border-collapse: collapse; margin-bottom: 0; border: 0.3px solid #000; table-layout: fixed;">
|
||||
<thead>
|
||||
<tr style="background-color: #fff;">
|
||||
<th style="padding: 5px 3px; border: 0.3px solid #000; text-align: center; font-size: 12px; width: 10%;">产品名称</th>
|
||||
<th style="padding: 5px 3px; border: 0.3px solid #000; text-align: center; font-size: 12px; width: 13%;">产品名称</th>
|
||||
<th style="padding: 5px 3px; border: 0.3px solid #000; text-align: center; font-size: 12px; width: 6%;">规格</th>
|
||||
<th style="padding: 5px 3px; border: 0.3px solid #000; text-align: center; font-size: 12px; width: 6%;">品牌</th>
|
||||
<th style="padding: 5px 3px; border: 0.3px solid #000; text-align: center; font-size: 12px; width: 5%;">单位</th>
|
||||
<th style="padding: 5px 3px; border: 0.3px solid #000; text-align: center; font-size: 12px; width: 7%;">用量</th>
|
||||
<th style="padding: 5px 3px; border: 0.3px solid #000; text-align: center; font-size: 12px; width: 7%;">单位</th>
|
||||
<th style="padding: 5px 3px; border: 0.3px solid #000; text-align: center; font-size: 12px; width: 9%;">用量</th>
|
||||
<th style="padding: 5px 3px; border: 0.3px solid #000; text-align: center; font-size: 12px; width: 5%;">税率</th>
|
||||
<th style="padding: 5px 3px; border: 0.3px solid #000; text-align: center; font-size: 12px; width: 12%;">含税单价(元)</th>
|
||||
<th style="padding: 5px 3px; border: 0.3px solid #000; text-align: center; font-size: 12px; width: 12%;">未含税金额(元)</th>
|
||||
<th style="padding: 5px 3px; border: 0.3px solid #000; text-align: center; font-size: 12px; width: 10%;">含税单价(元)</th>
|
||||
<th style="padding: 5px 3px; border: 0.3px solid #000; text-align: center; font-size: 12px; width: 10%;">未含税金额(元)</th>
|
||||
<th style="padding: 5px 3px; border: 0.3px solid #000; text-align: center; font-size: 12px; width: 10%;">税费(元)</th>
|
||||
<th style="padding: 5px 3px; border: 0.3px solid #000; text-align: center; font-size: 12px; width: 8%;">含税金额(元)</th>
|
||||
<th style="padding: 5px 3px; border: 0.3px solid #000; text-align: center; font-size: 12px; width: 11%;">包装规格</th>
|
||||
<th style="padding: 5px 3px; border: 0.3px solid #000; text-align: center; font-size: 12px; width: 8%;">备注</th>
|
||||
<th style="padding: 5px 3px; border: 0.3px solid #000; text-align: center; font-size: 12px; width: 5%;">备注</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -2949,34 +2975,7 @@ const handlePrintContract = () => {
|
||||
const printWindow = window.open('', '_blank');
|
||||
if (printWindow) {
|
||||
// 根据供方编码决定是否显示背景图片
|
||||
const backgroundStyle = isSXSupplier
|
||||
? `
|
||||
/* 水印层 - 使用完整URL */
|
||||
body::before {
|
||||
content: '';
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: url('${watermarkUrl}');
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
background-size: 50%;
|
||||
opacity: 0.15;
|
||||
z-index: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
@media print {
|
||||
/* 打印时也显示水印 */
|
||||
body::before {
|
||||
position: absolute;
|
||||
print-color-adjust: exact;
|
||||
-webkit-print-color-adjust: exact;
|
||||
}
|
||||
}
|
||||
`
|
||||
: '';
|
||||
const backgroundStyle = isSXSupplier ? contractWatermarkPrintCss(watermarkUrl) : '';
|
||||
|
||||
printWindow.document.write(`
|
||||
<!DOCTYPE html>
|
||||
@@ -2991,11 +2990,6 @@ const handlePrintContract = () => {
|
||||
position: relative;
|
||||
}
|
||||
${backgroundStyle}
|
||||
/* 确保内容在水印上方 */
|
||||
body > * {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
@media print {
|
||||
body {
|
||||
margin: 0;
|
||||
@@ -3132,26 +3126,6 @@ const handleGeneratePdfFromDialog = async () => {
|
||||
watermarkDiv.style.maxWidth = '100%';
|
||||
watermarkDiv.style.boxSizing = 'border-box';
|
||||
|
||||
// 根据供方编码决定是否添加水印背景层
|
||||
if (isSXSupplier) {
|
||||
const watermarkBg = document.createElement('div');
|
||||
watermarkBg.style.cssText = `
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: url('/watermask.jpg');
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
background-size: 50%;
|
||||
opacity: 0.15;
|
||||
z-index: 0;
|
||||
pointer-events: none;
|
||||
`;
|
||||
watermarkDiv.appendChild(watermarkBg);
|
||||
}
|
||||
|
||||
// 添加内容层
|
||||
const contentDiv = document.createElement('div');
|
||||
contentDiv.style.cssText = 'position: relative; z-index: 1; width: 100%; max-width: 100%; box-sizing: border-box; overflow: hidden;';
|
||||
@@ -3176,7 +3150,7 @@ const handleGeneratePdfFromDialog = async () => {
|
||||
const fitStyle = document.createElement('style');
|
||||
fitStyle.textContent = `
|
||||
table { max-width: 100% !important; width: 100% !important; table-layout: fixed !important; box-sizing: border-box !important; }
|
||||
table td, table th { box-sizing: border-box !important; min-width: 0 !important; word-break: break-word; overflow-wrap: anywhere; }
|
||||
table td, table th { box-sizing: border-box !important; min-width: 0 !important; word-break: break-word; overflow-wrap: break-word; }
|
||||
`;
|
||||
contentDiv.prepend(fitStyle);
|
||||
|
||||
@@ -3202,6 +3176,10 @@ const handleGeneratePdfFromDialog = async () => {
|
||||
const pdfContentMaxWidth = Math.max(1, tempDiv.clientWidth - 40);
|
||||
fitRichTextTablesToMaxWidth(contentDiv, pdfContentMaxWidth);
|
||||
|
||||
if (isSXSupplier) {
|
||||
appendContractPageWatermarks(watermarkDiv, tempDiv.clientWidth || 794);
|
||||
}
|
||||
|
||||
// 如果不是SX供方编码,再次检查并隐藏可能遗漏的logo
|
||||
if (!isSXSupplier) {
|
||||
const logoImages = contentDiv.querySelectorAll('img');
|
||||
|
||||
@@ -1156,7 +1156,7 @@
|
||||
<div class="generate-print-dialog-header">
|
||||
<span class="generate-print-dialog-title">{{ isPreviewMode ? '预览合同' : '编辑合同' }}</span>
|
||||
<p v-if="!isPreviewMode" class="generate-print-dialog-edit-hint">
|
||||
编辑模式:鼠标移入表格后,列/行边界会出现绿色调整条,按住拖动即可调列宽或行高;工具栏可合并拆分、插删行列、对齐与换行。调整后请点「保存模板」。
|
||||
编辑模式:鼠标移到表头格子的右边界可调列宽,移到每行最左边格子的下边界可调行高。工具栏可合并拆分、插删行列、对齐与换行。调整后请点「保存模板」。
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1242,6 +1242,8 @@ import { canDeleteByCreator } from '@/utils/creator-delete';
|
||||
import html2canvas from 'html2canvas';
|
||||
import { jsPDF } from 'jspdf';
|
||||
import { fitRichTextTablesToMaxWidth } from '@/utils/tinymce-table-excel-resize';
|
||||
import { normalizeContractProductTableWidths } from '@/utils/crm/contract-product-table-widths';
|
||||
import { appendContractPageWatermarks, contractWatermarkPrintCss } from '@/utils/crm/contract-watermark';
|
||||
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
@@ -1850,7 +1852,7 @@ const replacePlaceholders = (htmlContent: string, contractData: ContractVO | und
|
||||
const freightText = freightAmount > 0 ? `¥${formatNumber(freightAmount)}` : '-';
|
||||
const barrelDepositText = barrelDepositAmount > 0 ? `¥${formatNumber(barrelDepositAmount)}` : '-';
|
||||
const formatRmbAmountText = (amount: number) =>
|
||||
isFrameworkContract ? '随行就市' : `${numberToChinese(amount)}(¥${formatNumber(amount)})`;
|
||||
isFrameworkContract ? '随行就市' : `${numberToChinese(amount)}<br/>(¥${formatNumber(amount)})`;
|
||||
const beforeTaxTotalText = formatRmbAmountText(productTotalBeforeTax);
|
||||
const taxTotalText = formatRmbAmountText(totalTax);
|
||||
const totalWithExtrasText = formatRmbAmountText(totalWithExtras);
|
||||
@@ -1865,13 +1867,13 @@ const replacePlaceholders = (htmlContent: string, contractData: ContractVO | und
|
||||
<td colspan="4" style="padding: 5px 6px; border: 1px solid #000; text-align: center; font-size: 12px;">${barrelDepositText}</td>
|
||||
</tr>
|
||||
<tr style="background-color: #fff; font-weight: bold;">
|
||||
<td colspan="2" style="padding: 5px 6px; border: 1px solid #000; text-align: center; font-size: 12px;">不含税金额合计(人民币)</td>
|
||||
<td colspan="2" style="padding: 5px 6px; border: 1px solid #000; text-align: center; font-size: 12px;">不含税金额合计<br/>(人民币)</td>
|
||||
<td colspan="4" style="padding: 5px 6px; border: 1px solid #000; text-align: center; font-size: 12px;">${beforeTaxTotalText}</td>
|
||||
<td colspan="2" style="padding: 5px 6px; border: 1px solid #000; text-align: center; font-size: 12px;">税额合计(人民币)</td>
|
||||
<td colspan="2" style="padding: 5px 6px; border: 1px solid #000; text-align: center; font-size: 12px;">税额合计<br/>(人民币)</td>
|
||||
<td colspan="4" style="padding: 5px 6px; border: 1px solid #000; text-align: center; font-size: 12px;">${taxTotalText}</td>
|
||||
</tr>
|
||||
<tr style="background-color: #fff; font-weight: bold;">
|
||||
<td colspan="2" style="padding: 5px 6px; border: 1px solid #000; text-align: center; font-size: 12px;">含税金额合计(人民币)</td>
|
||||
<td colspan="2" style="padding: 5px 6px; border: 1px solid #000; text-align: center; font-size: 12px;">含税金额合计<br/>(人民币)</td>
|
||||
<td colspan="10" style="padding: 5px 6px; border: 1px solid #000; text-align: center; font-size: 12px;">${totalWithExtrasText}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -1891,7 +1893,7 @@ const replacePlaceholders = (htmlContent: string, contractData: ContractVO | und
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return normalizeContractProductTableWidths(result);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -2108,7 +2110,7 @@ const generateContractTemplate = (contractData: ContractVO | undefined): string
|
||||
const barrelDepositText = barrelDepositAmount > 0 ? `¥${formatNumber(barrelDepositAmount)}` : '-';
|
||||
const isFrameworkContract = isFrameworkContractType(contractData.contractType);
|
||||
const formatRmbAmountText = (amount: number) =>
|
||||
isFrameworkContract ? '随行就市' : `${numberToChinese(amount)}(¥${formatNumber(amount)})`;
|
||||
isFrameworkContract ? '随行就市' : `${numberToChinese(amount)}<br/>(¥${formatNumber(amount)})`;
|
||||
const beforeTaxTotalText = formatRmbAmountText(productTotalBeforeTax);
|
||||
const taxTotalText = formatRmbAmountText(totalTax);
|
||||
const totalWithExtrasText = formatRmbAmountText(totalWithExtras);
|
||||
@@ -2203,13 +2205,13 @@ const generateContractTemplate = (contractData: ContractVO | undefined): string
|
||||
<td colspan="3" style="padding: 5px 6px; border: 1px solid #000; text-align: center; font-size: 12px;">${barrelDepositText}</td>
|
||||
</tr>
|
||||
<tr style="background-color: #fff; font-weight: bold;">
|
||||
<td colspan="2" style="padding: 5px 6px; border: 1px solid #000; text-align: center; font-size: 12px;">不含税金额合计(人民币)</td>
|
||||
<td colspan="2" style="padding: 5px 6px; border: 1px solid #000; text-align: center; font-size: 12px;">不含税金额合计<br/>(人民币)</td>
|
||||
<td colspan="4" style="padding: 5px 6px; border: 1px solid #000; text-align: center; font-size: 12px;">${beforeTaxTotalText}</td>
|
||||
<td colspan="2" style="padding: 5px 6px; border: 1px solid #000; text-align: center; font-size: 12px;">税额合计(人民币)</td>
|
||||
<td colspan="2" style="padding: 5px 6px; border: 1px solid #000; text-align: center; font-size: 12px;">税额合计<br/>(人民币)</td>
|
||||
<td colspan="3" style="padding: 5px 6px; border: 1px solid #000; text-align: center; font-size: 12px;">${taxTotalText}</td>
|
||||
</tr>
|
||||
<tr style="background-color: #fff; font-weight: bold;">
|
||||
<td colspan="2" style="padding: 5px 6px; border: 1px solid #000; text-align: center; font-size: 12px;">含税金额合计(人民币)</td>
|
||||
<td colspan="2" style="padding: 5px 6px; border: 1px solid #000; text-align: center; font-size: 12px;">含税金额合计<br/>(人民币)</td>
|
||||
<td colspan="9" style="padding: 5px 6px; border: 1px solid #000; text-align: center; font-size: 12px;">${totalWithExtrasText}</td>
|
||||
</tr>
|
||||
<!-- 提示行 -->
|
||||
@@ -2727,34 +2729,7 @@ const handlePrintContract = () => {
|
||||
const printWindow = window.open('', '_blank');
|
||||
if (printWindow) {
|
||||
// 根据供方编码决定是否显示背景图片
|
||||
const backgroundStyle = isSXSupplier
|
||||
? `
|
||||
/* 水印层 - 使用完整URL */
|
||||
body::before {
|
||||
content: '';
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: url('${watermarkUrl}');
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
background-size: 50%;
|
||||
opacity: 0.15;
|
||||
z-index: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
@media print {
|
||||
/* 打印时也显示水印 */
|
||||
body::before {
|
||||
position: absolute;
|
||||
print-color-adjust: exact;
|
||||
-webkit-print-color-adjust: exact;
|
||||
}
|
||||
}
|
||||
`
|
||||
: '';
|
||||
const backgroundStyle = isSXSupplier ? contractWatermarkPrintCss(watermarkUrl) : '';
|
||||
|
||||
printWindow.document.write(`
|
||||
<!DOCTYPE html>
|
||||
@@ -2769,11 +2744,6 @@ const handlePrintContract = () => {
|
||||
position: relative;
|
||||
}
|
||||
${backgroundStyle}
|
||||
/* 确保内容在水印上方 */
|
||||
body > * {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
@media print {
|
||||
body {
|
||||
margin: 0;
|
||||
@@ -3003,35 +2973,16 @@ const handleGeneratePdfFile = async () => {
|
||||
watermarkDiv.style.maxWidth = '100%';
|
||||
watermarkDiv.style.boxSizing = 'border-box';
|
||||
|
||||
// 添加水印背景层
|
||||
const watermarkBg = document.createElement('div');
|
||||
watermarkBg.style.cssText = `
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: url('/watermask.jpg');
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
background-size: 50%;
|
||||
opacity: 0.15;
|
||||
z-index: 0;
|
||||
pointer-events: none;
|
||||
`;
|
||||
|
||||
// 添加内容层
|
||||
const contentDiv = document.createElement('div');
|
||||
contentDiv.style.cssText = 'position: relative; z-index: 1; width: 100%; max-width: 100%; box-sizing: border-box; overflow: hidden;';
|
||||
contentDiv.innerHTML = contractContent.value;
|
||||
const fitStyle = document.createElement('style');
|
||||
fitStyle.textContent = `
|
||||
table { max-width: 100% !important; width: 100% !important; table-layout: fixed !important; box-sizing: border-box !important; }
|
||||
table td, table th { box-sizing: border-box !important; min-width: 0 !important; word-break: break-word; overflow-wrap: anywhere; }
|
||||
table td, table th { box-sizing: border-box !important; min-width: 0 !important; word-break: break-word; overflow-wrap: break-word; }
|
||||
`;
|
||||
contentDiv.prepend(fitStyle);
|
||||
|
||||
watermarkDiv.appendChild(watermarkBg);
|
||||
watermarkDiv.appendChild(contentDiv);
|
||||
tempDiv.appendChild(watermarkDiv);
|
||||
document.body.appendChild(tempDiv);
|
||||
@@ -3053,6 +3004,7 @@ const handleGeneratePdfFile = async () => {
|
||||
// 编辑器拖拽后表宽常大于 A4 内容区;截图前等比缩进,避免 PDF 右侧裁切
|
||||
const pdfContentMaxWidth = Math.max(1, tempDiv.clientWidth - 40);
|
||||
fitRichTextTablesToMaxWidth(contentDiv, pdfContentMaxWidth);
|
||||
appendContractPageWatermarks(watermarkDiv, tempDiv.clientWidth || 794);
|
||||
|
||||
// 使用html2canvas将HTML转换为canvas
|
||||
const canvas = await html2canvas(tempDiv, {
|
||||
|
||||
@@ -628,7 +628,7 @@
|
||||
<div class="generate-print-dialog-header">
|
||||
<span class="generate-print-dialog-title">{{ isPreviewMode ? '预览报价单' : '编辑报价单' }}</span>
|
||||
<p v-if="!isPreviewMode" class="generate-print-dialog-edit-hint">
|
||||
编辑模式:鼠标移入表格后,列/行边界会出现绿色调整条,按住拖动即可调列宽或行高;工具栏可合并拆分、插删行列、对齐与换行。调整后请点「保存模板」。
|
||||
编辑模式:鼠标移到表头格子的右边界可调列宽,移到每行最左边格子的下边界可调行高。工具栏可合并拆分、插删行列、对齐与换行。调整后请点「保存模板」。
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in new issue
Block a user