Compare commits

...

4 Commits

Author SHA1 Message Date
37a69b563b Merge branch '0.8.X' of http://49.232.154.205:10100/DeXun/klp-oa into 0.8.X 2026-06-05 10:45:01 +08:00
66f0b3fdd7 fix(wms): 修复三处业务显示与逻辑不一致问题
1. 修复异常报表接口数据字段使用错误,将rows改为data
2. 调整标签渲染PDF的图片缩放和位置,避免内容超出页面
3. 修改考勤审核页面的请假天数列标题为请假小时,匹配实际展示数据
2026-06-05 10:44:56 +08:00
5e0dc848bb fix(wms-warehouse): 修复仓库页面容器高度溢出和导出二维码逻辑 2026-06-05 10:41:49 +08:00
a5323aea76 fix(crm/contract): 优化合同预览与导出功能
1.  隐藏打印预览按钮
2.  调整合同预览页面样式间距与logo位置
3.  修改合同金额字段保留小数位数为3位
4.  优化PDF导出分页逻辑,按空白行自动分页
2026-06-05 10:41:33 +08:00
8 changed files with 93 additions and 49 deletions

View File

@@ -232,9 +232,9 @@
<el-dialog :title="rpTitle" :visible.sync="rpOpen" width="500px" append-to-body>
<el-form ref="rpf" :model="rpForm" :rules="{reportTitle:[{required:true,message:'请输入',trigger:'blur'}]}" label-width="100px">
<el-form-item label="报表标题" prop="reportTitle"><el-input v-model="rpForm.reportTitle" /></el-form-item>
<el-form-item label="报表日期" prop="reportDate"><el-date-picker v-model="rpForm.reportDate" type="date" value-format="yyyy-MM-dd" style="width:100%" /></el-form-item>
<el-form-item label="备注" prop="remark"><el-input v-model="rpForm.remark" type="textarea" /></el-form-item>
<el-form-item label="报表标题" prop="reportTitle"><el-input v-model="rpForm.reportTitle" placeholder="请输入报表标题" /></el-form-item>
<el-form-item label="报表日期" prop="reportDate"><el-date-picker v-model="rpForm.reportDate" type="date" placeholder="选择日期" clearable value-format="yyyy-MM-dd" style="width:100%" /></el-form-item>
<el-form-item label="备注" prop="remark"><el-input v-model="rpForm.remark" type="textarea" placeholder="请输入备注" /></el-form-item>
</el-form>
<div slot="footer"><el-button :loading="rpBtnLoading" type="primary" @click="submitRp"> </el-button><el-button @click="rpOpen=false"> </el-button></div>
</el-dialog>
@@ -242,8 +242,8 @@
<!-- 复制报表弹窗 -->
<el-dialog title="复制报表" :visible.sync="copyRpOpen" width="500px" append-to-body>
<el-form :model="copyRpForm" label-width="100px" size="small">
<el-form-item label="报表标题"><el-input v-model="copyRpForm.reportTitle" /></el-form-item>
<el-form-item label="报表日期"><el-date-picker v-model="copyRpForm.reportDate" type="date" value-format="yyyy-MM-dd" style="width:100%" /></el-form-item>
<el-form-item label="报表标题"><el-input v-model="copyRpForm.reportTitle" placeholder="请输入报表标题" /></el-form-item>
<el-form-item label="报表日期"><el-date-picker v-model="copyRpForm.reportDate" type="date" placeholder="选择日期" clearable value-format="yyyy-MM-dd" style="width:100%" /></el-form-item>
</el-form>
<div slot="footer">
<el-button type="primary" @click="doCopyRp"> </el-button>

View File

@@ -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`);

View File

@@ -4,7 +4,7 @@
<h3 style="margin-bottom: 20px; color: #303133; display: flex; justify-content: space-between; align-items: center;">
{{ contract.contractName }}
<span>
<el-button type="primary" icon="el-icon-printer" @click="printContract">打印预览</el-button>
<!-- <el-button type="primary" icon="el-icon-printer" @click="printContract">打印预览</el-button> -->
<el-select v-hasPermi="['crm:contract:status']" v-model="contract.status" placeholder="请选择合同状态" style="width: 150px; margin-left: 10px;" @change="handleStatusChange">
<el-option label="草稿" :value="0" />
<el-option label="已生效" :value="1" />
@@ -172,15 +172,14 @@ export default {
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: 'SimSun','宋体',serif; color: #000; background: #e8e8e8; font-size: 12px; line-height: 1.6; display: flex; flex-direction: column; align-items: center; padding: 20px 0; }
.a4-page { width: 794px; min-height: 1123px; padding: 30px 40px; background: #fff; margin-bottom: 20px; box-shadow: 0 2px 12px rgba(0,0,0,0.15); }
.company-header { display: flex; align-items: flex-start; justify-content: space-between; margin-bottom: 8px; }
.contract-title { text-align: center; font-size: 22px; font-weight: bold; letter-spacing: 6px; margin-bottom: 18px; }
.info-row { display: flex; justify-content: space-between; margin-bottom: 6px; font-size: 13px; line-height: 2; }
.section-title { font-size: 13px; font-weight: bold; margin-bottom: 4px; margin-top: 10px; }
table { width: 100%; border-collapse: collapse; font-size: 11px; }
th, td { border: 1px solid #000; padding: 3px 4px; text-align: center; }
th { background-color: #f5f5f5; font-weight: bold; }
.total-row td { font-weight: bold; }
.sign-section { margin-top: 30px; font-size: 12px; line-height: 2.2; }
.company-header { display: flex; align-items: flex-start; justify-content: space-between; margin-bottom: 6px; }
.contract-title { text-align: center; font-size: 20px; font-weight: bold; letter-spacing: 6px; margin-bottom: 14px; }
.info-row { display: flex; justify-content: space-between; margin-bottom: 4px; font-size: 13px; line-height: 2; }
.section-title { font-size: 13px; font-weight: bold; margin-bottom: 4px; margin-top: 8px; }
table { width: 100%; border-collapse: collapse; }
th, td { border: 1px solid #000; padding: 3px 4px; text-align: center; font-size: 11px; }
th { font-weight: bold; }
.sign-section { margin-top: 24px; font-size: 12px; line-height: 2.2; }
.sign-section .col { width: 48%; }
.sign-row { display: flex; justify-content: space-between; }
.print-toolbar { position: fixed; top: 0; right: 20px; z-index: 100; display: flex; gap: 8px; padding: 10px; }
@@ -197,13 +196,13 @@ export default {
<body>
<div class="print-toolbar"><button class="btn-print" onclick="window.print()">打 印</button></div>
<div class="a4-page" style="position:relative;">
<img src="${contractLogo}" style="position:absolute;left:20px;top:20px;height:80px;" crossorigin="anonymous" />
<img src="${contractLogo}" style="position:absolute;left:40px;top:40px;height:80px;" crossorigin="anonymous" />
<div style="text-align:center;padding-top:10px;">
<div style="font-size:20px;font-weight:bold;letter-spacing:2px;">嘉祥科伦普重工有限公司</div>
</div>
<div style="display:flex;justify-content:center;align-items:baseline;margin:12px 0 8px 0;">
<div style="position:relative;margin:12px 0 8px 0;text-align:center;">
<div style="font-size:22px;font-weight:bold;letter-spacing:6px;">产 品 销 售 合 同</div>
<div style="font-size:11px;margin-left:40px;">合同编号:${row.contractCode || ''}</div>
<div style="position:absolute;right:0;top:50%;transform:translateY(-50%);font-size:11px;">合同编号:${row.contractCode || ''}</div>
</div>
<div class="info-row">
<div style="width:55%;">

View File

@@ -318,13 +318,15 @@ export default {
// 确保页面尺寸正确宽100mm高80mm横向
const page = pdfDoc.addPage([pageWidthPt, pageHeightPt]);
// 直接拉伸填充整个PDF页面不留边距确保占满整张纸
// 从(0,0)开始,直接填充整个页面尺寸
// 缩放到原尺寸的95%,原点为左上
const scaleFactor = 0.95;
const imgWidth = pageWidthPt * scaleFactor;
const imgHeight = pageHeightPt * scaleFactor;
page.drawImage(imgPng, {
x: 0,
y: 0,
width: pageWidthPt,
height: pageHeightPt
y: pageHeightPt - imgHeight,
width: imgWidth,
height: imgHeight
});
const pdfBytes = await pdfDoc.save();

View File

@@ -73,7 +73,7 @@
<el-table-column prop="applicantDeptName" label="部门" />
<el-table-column prop="startTime" label="开始时间" />
<el-table-column prop="endTime" label="结束时间" />
<el-table-column prop="leaveDays" label="请假天数" />
<el-table-column prop="leaveDays" label="请假小时" />
<el-table-column prop="leaveReason" label="请假原因" />
<el-table-column prop="approvalStatus" label="审批状态">
<template slot-scope="scope">
@@ -342,7 +342,7 @@
<el-table-column prop="leaveType" label="请假类型" width="100" />
<el-table-column prop="startTime" label="开始时间" width="150" />
<el-table-column prop="endTime" label="结束时间" width="150" />
<el-table-column prop="leaveDays" label="天数" width="80" />
<el-table-column prop="leaveDays" label="小时" width="80" />
<el-table-column prop="leaveReason" label="原因" />
<el-table-column prop="approvalStatus" label="状态" width="100">
<template slot-scope="scope">

View File

@@ -273,7 +273,7 @@ export default {
this.loading = true;
const actions = await listLightPendingAction({ ...this.queryParams, actionTypes: this.actionTypes, actionStatus: 2 });
const outIds = actions.rows.map(item => item.processedCoilIds).join(',');
const outIds = actions.data.map(item => item.processedCoilIds).join(',');
if (!outIds) {
this.outList = []

View File

@@ -351,7 +351,8 @@ export default {
<style scoped lang="scss">
.bird-container {
width: 100%;
height: 100%;
height: calc(100vh - 168px);
overflow-y: scroll;
}
// 统计卡片样式

View File

@@ -15,6 +15,7 @@
element-loading-spinner="el-icon-loading">
<el-tabs v-model="activeTab" class="overview-tabs">
<el-tab-pane label="平面视图" name="bird">
<!-- <button buttonLoading type="primary" @click="exportAllQrcodes">导出二维码</button> -->
<WarehouseBird
:id="selectedNodeId"
:warehouse-list="warehouseList"
@@ -221,7 +222,8 @@ export default {
let currentX = margin; // 当前X坐标
let currentY = margin; // 当前Y坐标
let currentIndex = 0; // 当前处理的库位索引
const list = this.warehouseList.filter(item => item.actualWarehouseCode.includes('X'));
// const list = this.warehouseList.filter(item => item.actualWarehouseCode.includes('X'));
const list = this.warehouseList;
const totalCount = list.length;
// 遍历所有库位生成二维码并添加到PDF