Compare commits
12 Commits
76497eece7
...
0.8.X
| Author | SHA1 | Date | |
|---|---|---|---|
| c4eab467ee | |||
| fd50118161 | |||
| cc63aa80b2 | |||
| c95ea7db61 | |||
| f50c240bbe | |||
| 66278e635b | |||
| 74d0ba57e2 | |||
| e00d1357b0 | |||
| b9f87c6cc4 | |||
| 7c9c99bf45 | |||
| fdb13b7261 | |||
| 74a3803290 |
@@ -26,6 +26,9 @@ public class MesRollInfo extends BaseEntity {
|
||||
/** 产线ID */
|
||||
private Long lineId;
|
||||
|
||||
/** 机架 */
|
||||
private String frame;
|
||||
|
||||
/** 轧辊编号 */
|
||||
private String rollNo;
|
||||
|
||||
|
||||
@@ -25,6 +25,9 @@ public class MesRollInfoBo extends BaseEntity {
|
||||
/** 产线ID(查询过滤 / 新增归属) */
|
||||
private Long lineId;
|
||||
|
||||
/** 机架 */
|
||||
private String frame;
|
||||
|
||||
@NotBlank(message = "轧辊编号不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private String rollNo;
|
||||
|
||||
|
||||
@@ -25,6 +25,9 @@ public class MesRollInfoVo {
|
||||
@ExcelProperty("产线名称")
|
||||
private String lineName;
|
||||
|
||||
@ExcelProperty("机架")
|
||||
private String frame;
|
||||
|
||||
@ExcelProperty("轧辊编号")
|
||||
private String rollNo;
|
||||
|
||||
|
||||
@@ -77,6 +77,7 @@ public class MesRollInfoServiceImpl implements IMesRollInfoService {
|
||||
lqw.like(StringUtils.isNotBlank(bo.getRollNo()), MesRollInfo::getRollNo, bo.getRollNo());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getRollType()), MesRollInfo::getRollType, bo.getRollType());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getStatus()), MesRollInfo::getStatus, bo.getStatus());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getFrame()), MesRollInfo::getFrame, bo.getFrame());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getManufacturer()), MesRollInfo::getManufacturer, bo.getManufacturer());
|
||||
lqw.orderByAsc(MesRollInfo::getRollType, MesRollInfo::getRollId);
|
||||
return lqw;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<el-icon class="el-icon-document-checked" />
|
||||
</div>
|
||||
<div class="right-menu-item hover-effect" @click="gotoWarning" title="告警信息">
|
||||
<el-badge :is-dot="hasWarning" class="nav-badge">
|
||||
<el-badge :value="hasWarning || ''" class="nav-badge">
|
||||
<el-icon class="el-icon-bell" />
|
||||
</el-badge>
|
||||
</div>
|
||||
@@ -116,9 +116,9 @@ export default {
|
||||
},
|
||||
checkWarning() {
|
||||
listMaterialWarning({ pageNum: 1, pageSize: 1, warningStatus: '0' }).then(response => {
|
||||
this.hasWarning = response.total > 0
|
||||
this.hasWarning = response.total
|
||||
}).catch(() => {
|
||||
this.hasWarning = false
|
||||
this.hasWarning = 0
|
||||
})
|
||||
},
|
||||
async logout() {
|
||||
|
||||
@@ -143,32 +143,32 @@ export default {
|
||||
const hasCol = (key) => activeCols.some(c => c.key === key);
|
||||
const hasRow = (key) => activeRows.some(r => r.key === key);
|
||||
|
||||
let headerCells = '<th style="border:2px solid #000;padding:4px 4px;font-weight:bold;width:30px;">序号</th>';
|
||||
if (hasCol('spec')) headerCells += '<th style="border:2px solid #000;padding:4px 4px;font-weight:bold;width:80px;">规格(mm)</th>';
|
||||
if (hasCol('material')) headerCells += '<th style="border:2px solid #000;padding:4px 4px;font-weight:bold;width:60px;">材质</th>';
|
||||
if (hasCol('quantity')) headerCells += '<th style="border:2px solid #000;padding:4px 4px;font-weight:bold;width:55px;">数量(吨)</th>';
|
||||
if (hasCol('taxPrice')) headerCells += '<th style="border:2px solid #000;padding:4px 4px;font-weight:bold;width:70px;">含税单价(元/吨)</th>';
|
||||
if (hasCol('taxDivisor')) headerCells += '<th style="border:2px solid #000;padding:4px 4px;font-weight:bold;width:45px;">税率除数</th>';
|
||||
if (hasCol('noTaxPrice')) headerCells += '<th style="border:2px solid #000;padding:4px 4px;font-weight:bold;width:70px;">无税单价(元/吨)</th>';
|
||||
if (hasCol('taxTotal')) headerCells += '<th style="border:2px solid #000;padding:4px 4px;font-weight:bold;width:70px;">含税总额(元)</th>';
|
||||
if (hasCol('noTaxTotal')) headerCells += '<th style="border:2px solid #000;padding:4px 4px;font-weight:bold;width:70px;">无税总额(元)</th>';
|
||||
if (hasCol('taxAmount')) headerCells += '<th style="border:2px solid #000;padding:4px 4px;font-weight:bold;width:55px;">税额(元)</th>';
|
||||
if (hasCol('remark')) headerCells += '<th style="border:2px solid #000;padding:4px 4px;font-weight:bold;width:80px;">备注</th>';
|
||||
let headerCells = '<th style="border:1px solid #000;padding:5px 6px;font-weight:bold;width:30px;">序号</th>';
|
||||
if (hasCol('spec')) headerCells += '<th style="border:1px solid #000;padding:5px 6px;font-weight:bold;width:80px;">规格(mm)</th>';
|
||||
if (hasCol('material')) headerCells += '<th style="border:1px solid #000;padding:5px 6px;font-weight:bold;width:60px;">材质</th>';
|
||||
if (hasCol('quantity')) headerCells += '<th style="border:1px solid #000;padding:5px 6px;font-weight:bold;width:55px;">数量(吨)</th>';
|
||||
if (hasCol('taxPrice')) headerCells += '<th style="border:1px solid #000;padding:5px 6px;font-weight:bold;width:70px;">含税单价(元/吨)</th>';
|
||||
if (hasCol('taxDivisor')) headerCells += '<th style="border:1px solid #000;padding:5px 6px;font-weight:bold;width:45px;">税率除数</th>';
|
||||
if (hasCol('noTaxPrice')) headerCells += '<th style="border:1px solid #000;padding:5px 6px;font-weight:bold;width:70px;">无税单价(元/吨)</th>';
|
||||
if (hasCol('taxTotal')) headerCells += '<th style="border:1px solid #000;padding:5px 6px;font-weight:bold;width:70px;">含税总额(元)</th>';
|
||||
if (hasCol('noTaxTotal')) headerCells += '<th style="border:1px solid #000;padding:5px 6px;font-weight:bold;width:70px;">无税总额(元)</th>';
|
||||
if (hasCol('taxAmount')) headerCells += '<th style="border:1px solid #000;padding:5px 6px;font-weight:bold;width:55px;">税额(元)</th>';
|
||||
if (hasCol('remark')) headerCells += '<th style="border:1px solid #000;padding:5px 6px;font-weight:bold;width:80px;">备注</th>';
|
||||
const colCount = activeCols.length + 1;
|
||||
|
||||
let bodyRows = '';
|
||||
products.forEach((product, index) => {
|
||||
let cells = `<td style="border:2px solid #000;padding:3px 4px;text-align:center;">${index + 1}</td>`;
|
||||
if (hasCol('spec')) cells += `<td style="border:2px solid #000;padding:3px 4px;text-align:center;">${product.spec || ''}</td>`;
|
||||
if (hasCol('material')) cells += `<td style="border:2px solid #000;padding:3px 4px;text-align:center;">${product.material || ''}</td>`;
|
||||
if (hasCol('quantity')) cells += `<td style="border:2px solid #000;padding:3px 4px;text-align:center;">${product.quantity || ''}</td>`;
|
||||
if (hasCol('taxPrice')) cells += `<td style="border:2px solid #000;padding:3px 4px;text-align:center;">${product.taxPrice || ''}</td>`;
|
||||
if (hasCol('taxDivisor')) cells += `<td style="border:2px solid #000;padding:3px 4px;text-align:center;">${product.taxDivisor || '1.13'}</td>`;
|
||||
if (hasCol('noTaxPrice')) cells += `<td style="border:2px solid #000;padding:3px 4px;text-align:center;">${(product.noTaxPrice || 0).toFixed(3)}</td>`;
|
||||
if (hasCol('taxTotal')) cells += `<td style="border:2px solid #000;padding:3px 4px;text-align:center;">${(product.taxTotal || 0).toFixed(3)}</td>`;
|
||||
if (hasCol('noTaxTotal')) cells += `<td style="border:2px solid #000;padding:3px 4px;text-align:center;">${(product.noTaxTotal || 0).toFixed(3)}</td>`;
|
||||
if (hasCol('taxAmount')) cells += `<td style="border:2px solid #000;padding:3px 4px;text-align:center;">${(product.taxAmount || 0).toFixed(3)}</td>`;
|
||||
if (hasCol('remark')) cells += `<td style="border:2px solid #000;padding:3px 4px;text-align:center;max-width:100px;word-wrap:break-word;">${product.remark || ''}</td>`;
|
||||
let cells = `<td style="border:1px solid #000;padding:4px 6px;text-align:center;">${index + 1}</td>`;
|
||||
if (hasCol('spec')) cells += `<td style="border:1px solid #000;padding:4px 6px;text-align:center;">${product.spec || ''}</td>`;
|
||||
if (hasCol('material')) cells += `<td style="border:1px solid #000;padding:4px 6px;text-align:center;">${product.material || ''}</td>`;
|
||||
if (hasCol('quantity')) cells += `<td style="border:1px solid #000;padding:4px 6px;text-align:center;">${product.quantity || ''}</td>`;
|
||||
if (hasCol('taxPrice')) cells += `<td style="border:1px solid #000;padding:4px 6px;text-align:center;">${product.taxPrice || ''}</td>`;
|
||||
if (hasCol('taxDivisor')) cells += `<td style="border:1px solid #000;padding:4px 6px;text-align:center;">${product.taxDivisor || '1.13'}</td>`;
|
||||
if (hasCol('noTaxPrice')) cells += `<td style="border:1px solid #000;padding:4px 6px;text-align:center;">${(product.noTaxPrice || 0).toFixed(3)}</td>`;
|
||||
if (hasCol('taxTotal')) cells += `<td style="border:1px solid #000;padding:4px 6px;text-align:center;">${(product.taxTotal || 0).toFixed(3)}</td>`;
|
||||
if (hasCol('noTaxTotal')) cells += `<td style="border:1px solid #000;padding:4px 6px;text-align:center;">${(product.noTaxTotal || 0).toFixed(3)}</td>`;
|
||||
if (hasCol('taxAmount')) cells += `<td style="border:1px solid #000;padding:4px 6px;text-align:center;">${(product.taxAmount || 0).toFixed(3)}</td>`;
|
||||
if (hasCol('remark')) cells += `<td style="border:1px solid #000;padding:4px 6px;text-align:center;max-width:100px;word-wrap:break-word;">${product.remark || ''}</td>`;
|
||||
bodyRows += `<tr>${cells}</tr>`;
|
||||
});
|
||||
|
||||
@@ -181,9 +181,9 @@ export default {
|
||||
let totalCells = '';
|
||||
let cellIdx = 0;
|
||||
activeCols.forEach((col) => {
|
||||
if (cellIdx < 2) {
|
||||
if (cellIdx < 2) {
|
||||
if (cellIdx === 0) {
|
||||
totalCells += `<td colspan="3" style="border:2px solid #000;padding:4px 4px;font-weight:bold;text-align:center;">合 计</td>`;
|
||||
totalCells += `<td colspan="3" style="border:1px solid #000;padding:5px 6px;font-weight:bold;text-align:center;">合 计</td>`;
|
||||
}
|
||||
} else {
|
||||
let val = '';
|
||||
@@ -191,22 +191,22 @@ export default {
|
||||
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:2px solid #000;padding:3px 4px;text-align:center;">${val}</td>`;
|
||||
totalCells += `<td style="border:1px solid #000;padding:4px 6px;text-align:center;">${val}</td>`;
|
||||
}
|
||||
cellIdx++;
|
||||
});
|
||||
|
||||
const html = `
|
||||
<table style="width:100%;border-collapse:collapse;font-size:11px;margin-bottom:6px;">
|
||||
<table style="width:100%;border-collapse:collapse;font-size:13px;margin-bottom:6px;border:2px solid #000;">
|
||||
<tr>
|
||||
<td colspan="4" style="border:2px solid #000;padding:3px 6px;font-weight:bold;text-align:left;">产品名称:${productData.productName || ''}</td>
|
||||
<td colspan="${colCount - 4 > 0 ? colCount - 4 : 1}" style="border:2px solid #000;padding:3px 6px;font-weight:bold;text-align:left;">生产厂家:嘉祥科伦普重工有限公司</td>
|
||||
<td colspan="4" style="border:1px solid #000;padding:4px 6px;font-weight:bold;text-align:left;">产品名称:${productData.productName || ''}</td>
|
||||
<td colspan="${colCount - 4 > 0 ? colCount - 4 : 1}" style="border:1px solid #000;padding:4px 6px;font-weight:bold;text-align:left;">生产厂家:嘉祥科伦普重工有限公司</td>
|
||||
</tr>
|
||||
<tr>${headerCells}</tr>
|
||||
${bodyRows}
|
||||
${hasRow('totalRow') ? `<tr>${totalCells}</tr>` : ''}
|
||||
${hasRow('amountWordsRow') ? `<tr><td colspan="${colCount}" style="border:2px solid #000;padding:4px 6px;font-weight:bold;text-align:left;">合计人民币(大写):${totalAmountInWords}</td></tr>` : ''}
|
||||
${hasRow('remarkRow') && productData.remark ? `<tr><td colspan="${colCount}" style="border:2px solid #000;padding:4px 6px;text-align:left;">备注:${productData.remark}</td></tr>` : ''}
|
||||
${hasRow('amountWordsRow') ? `<tr><td colspan="${colCount}" style="border:1px solid #000;padding:5px 6px;font-weight:bold;text-align:left;">合计人民币(大写):${totalAmountInWords}</td></tr>` : ''}
|
||||
${hasRow('remarkRow') && productData.remark ? `<tr><td colspan="${colCount}" style="border:1px solid #000;padding:4px 6px;text-align:left;">备注:${productData.remark}</td></tr>` : ''}
|
||||
</table>`;
|
||||
return html;
|
||||
},
|
||||
@@ -299,8 +299,8 @@ export default {
|
||||
.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: separate; border-spacing: 0; border-top: 2px solid #000; border-left: 2px solid #000; }
|
||||
th, td { border-right: 2px solid #000; border-bottom: 2px solid #000; padding: 3px 4px; text-align: center; font-size: 11px; }
|
||||
table { width: 100%; border-collapse: collapse; }
|
||||
th, td { border: 1px solid #000; padding: 4px 6px; text-align: center; font-size: 13px; }
|
||||
th { font-weight: 700; }
|
||||
.sign-section { margin-top: 24px; font-size: 12px; line-height: 2.2; }
|
||||
.sign-section .col { width: 48%; }
|
||||
@@ -404,7 +404,9 @@ export default {
|
||||
const printW = pW - mg * 2;
|
||||
const printH = pH - mg * 2;
|
||||
const ratio = canvas.width / printW;
|
||||
const pageCanvasHeight = printH * ratio;
|
||||
const footerMargin = 8;
|
||||
const imagePrintH = printH - footerMargin;
|
||||
const pageCanvasHeight = imagePrintH * ratio;
|
||||
|
||||
let currentY = 0;
|
||||
const pages = [];
|
||||
@@ -435,17 +437,31 @@ export default {
|
||||
currentY = pageBottom;
|
||||
}
|
||||
|
||||
const checkedAttachmentCount = this.attachmentConfigs.filter(a => a.checked).length;
|
||||
const totalPages = pages.length + checkedAttachmentCount;
|
||||
let pageNum = 0;
|
||||
|
||||
const fullPageCanvasHeight = Math.round(printH * ratio);
|
||||
|
||||
for (let i = 0; i < pages.length; i++) {
|
||||
pageNum++;
|
||||
const { top, bottom } = pages[i];
|
||||
const sliceH = bottom - top;
|
||||
const sliceMm = sliceH / ratio;
|
||||
|
||||
const sc = document.createElement('canvas');
|
||||
sc.width = canvas.width;
|
||||
sc.height = Math.ceil(sliceH);
|
||||
sc.getContext('2d').drawImage(canvas, 0, top, canvas.width, sliceH, 0, 0, canvas.width, sliceH);
|
||||
sc.height = fullPageCanvasHeight;
|
||||
const sctx = sc.getContext('2d');
|
||||
sctx.fillStyle = '#ffffff';
|
||||
sctx.fillRect(0, 0, sc.width, sc.height);
|
||||
sctx.drawImage(canvas, 0, top, canvas.width, sliceH, 0, 0, canvas.width, sliceH);
|
||||
sctx.fillStyle = '#000000';
|
||||
sctx.font = 'bold 24px "SimHei","黑体",sans-serif';
|
||||
sctx.textAlign = 'center';
|
||||
sctx.textBaseline = 'bottom';
|
||||
sctx.fillText(`第 ${pageNum} 页,共 ${totalPages} 页`, sc.width / 2, sc.height - 4);
|
||||
|
||||
pdf.addImage(sc.toDataURL('image/jpeg', 0.95), 'JPEG', mg, mg, printW, sliceMm);
|
||||
pdf.addImage(sc.toDataURL('image/jpeg', 0.95), 'JPEG', mg, mg, printW, printH);
|
||||
|
||||
if (i < pages.length - 1) {
|
||||
pdf.addPage();
|
||||
@@ -459,22 +475,34 @@ export default {
|
||||
try {
|
||||
const img = await this.loadImage(att.url);
|
||||
pdf.addPage();
|
||||
pageNum++;
|
||||
|
||||
let drawW = img.width;
|
||||
let drawH = img.height;
|
||||
const scale = Math.min(printW / drawW, printH / drawH, 1);
|
||||
drawW *= scale;
|
||||
drawH *= scale;
|
||||
const canvasPageW = Math.round(printW * ratio);
|
||||
const canvasImageH = Math.round(imagePrintH * ratio);
|
||||
const canvasFooterH = Math.round(footerMargin * ratio);
|
||||
const canvasTotalH = canvasImageH + canvasFooterH;
|
||||
|
||||
const x = mg + (printW - drawW) / 2;
|
||||
const y = mg + (printH - drawH) / 2;
|
||||
const attCanvas = document.createElement('canvas');
|
||||
attCanvas.width = canvasPageW;
|
||||
attCanvas.height = canvasTotalH;
|
||||
const actx = attCanvas.getContext('2d');
|
||||
actx.fillStyle = '#ffffff';
|
||||
actx.fillRect(0, 0, canvasPageW, canvasTotalH);
|
||||
|
||||
const tmpCanvas = document.createElement('canvas');
|
||||
tmpCanvas.width = img.width;
|
||||
tmpCanvas.height = img.height;
|
||||
tmpCanvas.getContext('2d').drawImage(img, 0, 0);
|
||||
const imgScale = Math.min(canvasPageW / img.width, canvasImageH / img.height, 1);
|
||||
const imgDrawW = img.width * imgScale;
|
||||
const imgDrawH = img.height * imgScale;
|
||||
const imgX = (canvasPageW - imgDrawW) / 2;
|
||||
const imgY = (canvasImageH - imgDrawH) / 2;
|
||||
actx.drawImage(img, imgX, imgY, imgDrawW, imgDrawH);
|
||||
|
||||
pdf.addImage(tmpCanvas.toDataURL('image/jpeg', 0.95), 'JPEG', x, y, drawW, drawH);
|
||||
actx.fillStyle = '#000000';
|
||||
actx.font = 'bold 24px "SimHei","黑体",sans-serif';
|
||||
actx.textAlign = 'center';
|
||||
actx.textBaseline = 'bottom';
|
||||
actx.fillText(`第 ${pageNum} 页,共 ${totalPages} 页`, canvasPageW / 2, canvasTotalH - 4);
|
||||
|
||||
pdf.addImage(attCanvas.toDataURL('image/jpeg', 0.95), 'JPEG', mg, mg, printW, printH);
|
||||
} catch (e) {
|
||||
console.error('加载附件图片失败: ' + att.originalName, e);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
<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-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" />
|
||||
@@ -65,8 +64,6 @@
|
||||
<script>
|
||||
import ProductContent from './ProductContent.vue';
|
||||
import OrderDetail from './OrderDetail.vue';
|
||||
import { parseProductContent, convertToChinese } from '@/utils/productContent';
|
||||
import contractLogo from '@/assets/images/contractLogo.png';
|
||||
|
||||
export default {
|
||||
name: "ContractPreview",
|
||||
@@ -109,176 +106,6 @@ export default {
|
||||
.replace('{i}', minutes)
|
||||
.replace('{s}', seconds);
|
||||
},
|
||||
/** 打印预览(A4尺寸,多页支持) */
|
||||
printContract() {
|
||||
const row = this.contract;
|
||||
if (!row) return;
|
||||
|
||||
let productData = parseProductContent(row.productContent);
|
||||
if (!productData.productName && row.productName) {
|
||||
productData.productName = row.productName;
|
||||
}
|
||||
const products = productData.products && productData.products.length > 0 ? productData.products : [];
|
||||
const totalQty = products.reduce((a, p) => a + (parseFloat(p.quantity) || 0), 0);
|
||||
const totalTax = products.reduce((a, p) => a + (parseFloat(p.taxTotal) || 0), 0);
|
||||
const totalNoTax = products.reduce((a, p) => a + (parseFloat(p.noTaxTotal) || 0), 0);
|
||||
const totalTaxAmt = products.reduce((a, p) => a + (parseFloat(p.taxAmount) || 0), 0);
|
||||
const amountWords = productData.totalAmountInWords || convertToChinese(totalTax) || '零元整';
|
||||
|
||||
let productRowsHtml = '';
|
||||
products.forEach((product, index) => {
|
||||
productRowsHtml += `<tr>
|
||||
<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${index + 1}</td>
|
||||
<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${product.spec || ''}</td>
|
||||
<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${product.material || ''}</td>
|
||||
<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${product.quantity || ''}</td>
|
||||
<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${product.taxPrice || ''}</td>
|
||||
<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${product.taxDivisor || '1.13'}</td>
|
||||
<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${(product.noTaxPrice || 0).toFixed(2)}</td>
|
||||
<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${(product.taxTotal || 0).toFixed(2)}</td>
|
||||
<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${(product.noTaxTotal || 0).toFixed(2)}</td>
|
||||
<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${(product.taxAmount || 0).toFixed(2)}</td>
|
||||
<td style="border:1px solid #000;padding:3px 4px;text-align:center;max-width:100px;word-wrap:break-word;">${product.remark || ''}</td>
|
||||
</tr>`;
|
||||
});
|
||||
|
||||
let contractContentHtml = '';
|
||||
if (row.contractContent) {
|
||||
let htmlContent = row.contractContent;
|
||||
const pTagRegex = /<p[^>]*>([\s\S]*?)<\/p>/g;
|
||||
let match;
|
||||
const pContents = [];
|
||||
while ((match = pTagRegex.exec(htmlContent)) !== null) {
|
||||
let content = match[1].replace(/<[^>]*>/g, '').replace(/ /g, ' ').replace(/</g, '<').replace(/>/g, '>').replace(/&/g, '&').replace(/"/g, '"').replace(/'/g, "'").trim();
|
||||
if (content) {
|
||||
const chineseNumberRegex = /^[一二三四五六七八九十]+、/;
|
||||
pContents.push(chineseNumberRegex.test(content) ? content : ' ' + content);
|
||||
}
|
||||
}
|
||||
if (pContents.length === 0) {
|
||||
const textContent = htmlContent.replace(/<[^>]*>/g, '').replace(/ /g, ' ').trim();
|
||||
if (textContent) pContents.push(textContent);
|
||||
}
|
||||
if (pContents.length > 0) {
|
||||
contractContentHtml = '<div style="margin-top:10px;font-size:12px;line-height:1.8;">' + pContents.join('<br/>') + '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
const printHtml = `<!DOCTYPE html>
|
||||
<html>
|
||||
<head><meta charset="utf-8"><title>合同打印预览</title>
|
||||
<style>
|
||||
@page { size: A4; margin: 15mm; }
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body { font-family: 'SimHei','黑体',sans-serif; font-weight: 600; 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: 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: separate; border-spacing: 0; border-top: 2px solid #000; border-left: 2px solid #000; }
|
||||
th, td { border-right: 2px solid #000; border-bottom: 2px solid #000; padding: 3px 4px; text-align: center; font-size: 11px; }
|
||||
th { font-weight: 700; }
|
||||
.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; }
|
||||
.print-toolbar button { padding: 8px 20px; border: none; border-radius: 4px; cursor: pointer; font-size: 14px; }
|
||||
.print-toolbar .btn-print { background: #409eff; color: #fff; }
|
||||
.print-toolbar .btn-print:hover { background: #66b1ff; }
|
||||
@media print {
|
||||
body { background: #fff; padding: 0; }
|
||||
.a4-page { width: auto; min-height: auto; padding: 0; margin: 0; box-shadow: none; page-break-after: always; }
|
||||
.print-toolbar { display: none !important; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<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: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="position:relative;margin:12px 0 8px 0;text-align:center;">
|
||||
<div style="font-size:22px;font-weight:bold;letter-spacing:6px;">产 品 销 售 合 同</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%;">
|
||||
<div>供方(甲方):${row.supplier || ''}</div>
|
||||
<div>需方(乙方):${row.customer || ''}</div>
|
||||
</div>
|
||||
<div style="width:40%;">
|
||||
<div>签订时间:${row.signTime ? this.parseTime(row.signTime, '{y}年{m}月{d}日') : ''}</div>
|
||||
<div>签订地点:${row.signLocation || ''}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section-title">一、产品内容</div>
|
||||
<table>
|
||||
<tr>
|
||||
<td colspan="4" style="font-weight:bold;text-align:left;">产品名称:${productData.productName || ''}</td>
|
||||
<td colspan="7" style="font-weight:bold;text-align:left;">生产厂家:${row.manufacturer || '嘉祥科伦普重工有限公司'}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th style="width:30px;">序号</th>
|
||||
<th style="width:80px;">规格(mm)</th>
|
||||
<th style="width:55px;">材质</th>
|
||||
<th style="width:50px;">数量(吨)</th>
|
||||
<th style="width:70px;">含税单价(元/吨)</th>
|
||||
<th style="width:45px;">税率除数</th>
|
||||
<th style="width:70px;">无税单价(元/吨)</th>
|
||||
<th style="width:70px;">含税总额(元)</th>
|
||||
<th style="width:70px;">无税总额(元)</th>
|
||||
<th style="width:50px;">税额(元)</th>
|
||||
<th style="width:80px;">备注</th>
|
||||
</tr>
|
||||
${productRowsHtml}
|
||||
<tr class="total-row">
|
||||
<td colspan="4" style="text-align:center;">合 计</td>
|
||||
<td>${totalQty.toFixed(2)}</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td>${totalTax.toFixed(2)}</td>
|
||||
<td>${totalNoTax.toFixed(2)}</td>
|
||||
<td>${totalTaxAmt.toFixed(2)}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr><td colspan="11" style="font-weight:bold;text-align:left;">合计人民币(大写):${amountWords}</td></tr>
|
||||
</table>
|
||||
${contractContentHtml}
|
||||
<div class="sign-section">
|
||||
<div class="sign-row">
|
||||
<div class="col">
|
||||
<div>供方(甲方):${row.supplier || ''}</div>
|
||||
<div>地址:${row.supplierAddress || ''}</div>
|
||||
<div>电话:${row.supplierPhone || ''}</div>
|
||||
<div>开户行:${row.supplierBank || ''}</div>
|
||||
<div>账号:${row.supplierAccount || ''}</div>
|
||||
<div>税号:${row.supplierTaxNo || ''}</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div>需方(乙方):${row.customer || ''}</div>
|
||||
<div>地址:${row.customerAddress || ''}</div>
|
||||
<div>电话:${row.customerPhone || ''}</div>
|
||||
<div>开户行:${row.customerBank || ''}</div>
|
||||
<div>账号:${row.customerAccount || ''}</div>
|
||||
<div>税号:${row.customerTaxNo || ''}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>`;
|
||||
|
||||
const printWindow = window.open('', '_blank');
|
||||
if (printWindow) {
|
||||
printWindow.document.write(printHtml);
|
||||
printWindow.document.close();
|
||||
} else {
|
||||
this.$message.warning('请允许浏览器弹出新窗口,或手动使用 Ctrl+P 打印');
|
||||
}
|
||||
},
|
||||
handleStatusChange(value) {
|
||||
this.$emit('updateStatus', value);
|
||||
}
|
||||
|
||||
@@ -50,7 +50,9 @@
|
||||
<el-input v-model="item.spec" placeholder="请输入规格" :readonly="readonly" size="small" />
|
||||
</div>
|
||||
<div class="table-cell">
|
||||
<el-input v-model="item.material" placeholder="请输入材质" :readonly="readonly" size="small" />
|
||||
<el-select v-model="item.material" placeholder="请选择材质" :readonly="readonly" size="small" filterable allow-create clearable style="width:100%;">
|
||||
<el-option v-for="opt in materialOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="table-cell">
|
||||
<el-input v-model="item.quantity" placeholder="请输入数量" :readonly="readonly" size="small"
|
||||
@@ -149,7 +151,13 @@ export default {
|
||||
{ label: '冷硬钢卷', value: '冷硬钢卷' },
|
||||
{ label: '镀锌钢卷', value: '镀锌钢卷' },
|
||||
{ label: '冷轧钢卷', value: '冷轧钢卷' },
|
||||
{ label: '冷轧卷(花纹)', value: '冷轧卷(花纹)' },
|
||||
{ label: '镀铬钢卷', value: '镀铬钢卷' },
|
||||
],
|
||||
materialOptions: [
|
||||
{ label: 'SPCC', value: 'SPCC' },
|
||||
{ label: 'DX51D+Z', value: 'DX51D+Z' },
|
||||
{ label: 'DC01', value: 'DC01' },
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -39,6 +39,10 @@
|
||||
<el-radio-button label="">全部厂家</el-radio-button>
|
||||
<el-radio-button v-for="mfr in manufacturerOptions" :key="mfr" :label="mfr">{{ mfr }}</el-radio-button>
|
||||
</el-radio-group>
|
||||
<el-radio-group v-model="filterFrame" size="small" @change="filterRolls">
|
||||
<el-radio-button label="">全部机架</el-radio-button>
|
||||
<el-radio-button v-for="f in frameOptions" :key="f" :label="f">{{ f }}</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
|
||||
<!-- 下方:左右布局 -->
|
||||
@@ -65,6 +69,7 @@
|
||||
<span class="ri-dia">φ{{ r.currentDia != null ? r.currentDia : r.initialDia }}</span>
|
||||
</div>
|
||||
<div v-if="r.manufacturer" class="ri-manufacturer">{{ r.manufacturer }}</div>
|
||||
<div v-if="r.frame" class="ri-manufacturer">{{ r.frame }}</div>
|
||||
<div v-if="filterLineId === null && r.lineName" class="ri-line">{{ r.lineName }}</div>
|
||||
</div>
|
||||
<div v-if="!rollLoading && filteredRolls.length === 0" class="roll-empty">暂无数据</div>
|
||||
@@ -89,6 +94,8 @@
|
||||
<div class="roll-header-grid">
|
||||
<div class="rh-item"><span class="rh-k">轧辊编号</span><span class="rh-v bold">{{ selectedRoll.rollNo }}</span></div>
|
||||
<div class="rh-item"><span class="rh-k">辊型</span><span class="rh-v">{{ { WR: '工作辊', BR: '支撑辊', CR: '中间辊' }[selectedRoll.rollType] || '—' }}</span></div>
|
||||
<div class="rh-item"><span class="rh-k">机架</span><span class="rh-v">{{ selectedRoll.frame || '—' }}</span></div>
|
||||
<div class="rh-item"><span class="rh-k">厂家</span><span class="rh-v">{{ selectedRoll.manufacturer || '—' }}</span></div>
|
||||
<div class="rh-item"><span class="rh-k">材质</span><span class="rh-v">{{ selectedRoll.material || '—' }}</span></div>
|
||||
<div class="rh-item"><span class="rh-k">初始辊径</span><span class="rh-v">{{ selectedRoll.initialDia != null ? selectedRoll.initialDia + ' mm' : '—' }}</span></div>
|
||||
<div class="rh-item"><span class="rh-k">当前辊径</span><span class="rh-v bold accent">{{ effectiveCurrentDia != null ? effectiveCurrentDia + ' mm' : '—' }}</span></div>
|
||||
@@ -464,6 +471,13 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="机架" prop="frame">
|
||||
<el-select v-model="rollForm.frame" placeholder="请输入机架" style="width:100%" clearable filterable allow-create>
|
||||
<el-option v-for="f in frameOptions" :key="f" :label="f" :value="f" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="rollForm.remark" type="textarea" :rows="2" placeholder="请输入备注" />
|
||||
@@ -500,6 +514,7 @@ export default {
|
||||
filterNo: '',
|
||||
filterType: '',
|
||||
filterManufacturer: '',
|
||||
filterFrame: '',
|
||||
|
||||
selectedRollId: null,
|
||||
selectedRoll: null,
|
||||
@@ -558,6 +573,14 @@ export default {
|
||||
return [...set].sort()
|
||||
},
|
||||
|
||||
frameOptions() {
|
||||
const set = new Set()
|
||||
this.allRolls.forEach(r => {
|
||||
if (r.frame) set.add(r.frame)
|
||||
})
|
||||
return [...set].sort()
|
||||
},
|
||||
|
||||
effectiveCurrentDia() {
|
||||
if (this.grindList.length > 0) {
|
||||
const latest = [...this.grindList].sort((a, b) => {
|
||||
@@ -615,7 +638,8 @@ export default {
|
||||
const matchNo = !this.filterNo || r.rollNo.includes(this.filterNo)
|
||||
const matchType = !this.filterType || r.rollType === this.filterType
|
||||
const matchMfr = !this.filterManufacturer || r.manufacturer === this.filterManufacturer
|
||||
return matchNo && matchType && matchMfr
|
||||
const matchFrame = !this.filterFrame || r.frame === this.filterFrame
|
||||
return matchNo && matchType && matchMfr && matchFrame
|
||||
})
|
||||
},
|
||||
selectRoll(r) {
|
||||
@@ -742,6 +766,7 @@ export default {
|
||||
rollNo: undefined,
|
||||
rollType: this.filterType || undefined,
|
||||
manufacturer: this.filterManufacturer || '',
|
||||
frame: '',
|
||||
initialDia: undefined,
|
||||
currentDia: undefined,
|
||||
minDia: undefined,
|
||||
@@ -764,6 +789,7 @@ export default {
|
||||
rollNo: data.rollNo,
|
||||
rollType: data.rollType,
|
||||
manufacturer: data.manufacturer || '',
|
||||
frame: data.frame || '',
|
||||
initialDia: data.initialDia,
|
||||
currentDia: data.currentDia,
|
||||
minDia: data.minDia,
|
||||
|
||||
@@ -33,12 +33,8 @@
|
||||
<template slot-scope="scope">
|
||||
<template v-if="scope.row.attachmentFiles">
|
||||
<div v-for="(url, idx) in scope.row.attachmentFiles.split(',')" :key="idx" style="margin-right: 4px;">
|
||||
<el-image
|
||||
style="width: 30px; height: 30px; vertical-align: middle; border-radius: 2px;"
|
||||
:src="url"
|
||||
:preview-src-list="scope.row.attachmentFiles.split(',')"
|
||||
fit="cover"
|
||||
/>
|
||||
<el-image style="width: 30px; height: 30px; vertical-align: middle; border-radius: 2px;" :src="url"
|
||||
:preview-src-list="scope.row.attachmentFiles.split(',')" fit="cover" />
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
@@ -50,6 +46,13 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="创建人" align="center" prop="createBy" />
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" />
|
||||
<el-table-column label="继承来源" prop="processSource" width="110">
|
||||
<template slot-scope="scope">
|
||||
<el-tag v-if="scope.row.processSource" type="warning" size="mini">
|
||||
{{ scope.row.processSource }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="挂载时机" align="center" prop="abnormalTime" v-if="coilInfo.coilId">
|
||||
<template slot-scope="scope">
|
||||
{{ getAbnormalTime(scope.row) }}
|
||||
|
||||
@@ -142,6 +142,7 @@ export default {
|
||||
return val
|
||||
},
|
||||
normalizeExcoilRow(row) {
|
||||
console.log(row, '标准化')
|
||||
const g = k => row[k] != null ? row[k] : (row[k.toUpperCase()] != null ? row[k.toUpperCase()] : null)
|
||||
return {
|
||||
hot_coilid: g('hot_coilid'),
|
||||
@@ -150,6 +151,8 @@ export default {
|
||||
exit_thick: g('exit_thick'),
|
||||
exit_width: g('exit_width'),
|
||||
exit_length: g('exit_length'),
|
||||
start_date: g('start_date'),
|
||||
end_date: g('end_date'),
|
||||
entry_weight: g('used_entry_weight') != null ? g('used_entry_weight')
|
||||
: (g('meas_exit_weight') != null ? g('meas_exit_weight') : g('entry_weight')),
|
||||
}
|
||||
|
||||
@@ -676,8 +676,15 @@ export default {
|
||||
if (data.exit_thick != null) this.$set(this.updateForm, 'actualThickness', parseFloat(data.exit_thick))
|
||||
if (data.exit_width != null) this.$set(this.updateForm, 'actualWidth', parseFloat(data.exit_width))
|
||||
|
||||
if (data.start_date) this.$set(this.updateForm, 'productionStartTime', this.formatDateTime(data.start_date))
|
||||
if (data.end_date) this.$set(this.updateForm, 'productionEndTime', this.formatDateTime(data.end_date))
|
||||
console.log(data)
|
||||
|
||||
if (data.start_date) {
|
||||
this.$set(this.updateForm, 'productionStartTime', this.formatDateTime(data.start_date))
|
||||
}
|
||||
|
||||
if (data.end_date) {
|
||||
this.$set(this.updateForm, 'productionEndTime', this.formatDateTime(data.end_date))
|
||||
}
|
||||
if (data.start_date || data.end_date) this.calculateProductionDuration()
|
||||
|
||||
const query = {
|
||||
|
||||
@@ -299,9 +299,9 @@ export default {
|
||||
getRowClassName({ row, rowIndex }) {
|
||||
const { rows } = this.highlightConfig
|
||||
|
||||
if (this.isLengthAbnormal(row) || this.isThicknessAbnormal(row)) {
|
||||
return 'warning-row'
|
||||
}
|
||||
// if (this.isLengthAbnormal(row) || this.isThicknessAbnormal(row)) {
|
||||
// return 'warning-row'
|
||||
// }
|
||||
|
||||
if (!rows || (Array.isArray(rows) && rows.length === 0)) {
|
||||
return ''
|
||||
|
||||
@@ -2,7 +2,11 @@ package com.klp.controller;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.klp.domain.bo.WmsMaterialCoilBo;
|
||||
import com.klp.domain.vo.WmsMaterialCoilVo;
|
||||
import com.klp.service.IWmsMaterialCoilService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.constraints.*;
|
||||
@@ -35,13 +39,42 @@ import com.klp.common.core.page.TableDataInfo;
|
||||
public class WmsMaterialWarningController extends BaseController {
|
||||
|
||||
private final IWmsMaterialWarningService iWmsMaterialWarningService;
|
||||
private final IWmsMaterialCoilService wmsMaterialCoilService;
|
||||
|
||||
/**
|
||||
* 查询钢卷通用维度告警(长度/厚度/宽度)列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<WmsMaterialWarningVo> list(WmsMaterialWarningBo bo, PageQuery pageQuery) {
|
||||
return iWmsMaterialWarningService.queryPageList(bo, pageQuery);
|
||||
TableDataInfo<WmsMaterialWarningVo> result = iWmsMaterialWarningService.queryPageList(bo, pageQuery);
|
||||
// 收集所有钢卷ID,批量查询钢卷信息并填充
|
||||
List<WmsMaterialWarningVo> list = result.getRows();
|
||||
if (list != null && !list.isEmpty()) {
|
||||
String coilIds = list.stream()
|
||||
.map(WmsMaterialWarningVo::getCoilId)
|
||||
.filter(java.util.Objects::nonNull)
|
||||
.distinct()
|
||||
.map(String::valueOf)
|
||||
.collect(Collectors.joining(","));
|
||||
if (!coilIds.isEmpty()) {
|
||||
WmsMaterialCoilBo wmsMaterialCoilBo = new WmsMaterialCoilBo();
|
||||
wmsMaterialCoilBo.setCoilIds(coilIds);
|
||||
List<WmsMaterialCoilVo> coilVos = wmsMaterialCoilService.queryList(wmsMaterialCoilBo);
|
||||
java.util.Map<Long, WmsMaterialCoilVo> coilMap = coilVos.stream()
|
||||
.filter(v -> v.getCoilId() != null)
|
||||
.collect(java.util.stream.Collectors.toMap(
|
||||
WmsMaterialCoilVo::getCoilId,
|
||||
v -> v,
|
||||
(a, b) -> a));
|
||||
for (WmsMaterialWarningVo warning : list) {
|
||||
WmsMaterialCoilVo coilVo = coilMap.get(warning.getCoilId());
|
||||
if (coilVo != null) {
|
||||
warning.setCoilVo(coilVo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -90,6 +90,11 @@ public class WmsMaterialWarningBo extends BaseEntity {
|
||||
*/
|
||||
private String handleRemark;
|
||||
|
||||
/**
|
||||
* 钢卷ID集合(逗号分隔),用于列表查询批量过滤
|
||||
*/
|
||||
private String coilIds;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
|
||||
@@ -7,6 +7,7 @@ import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.klp.common.annotation.ExcelDictFormat;
|
||||
import com.klp.common.convert.ExcelDictConvert;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
@@ -112,5 +113,11 @@ public class WmsMaterialWarningVo {
|
||||
@ExcelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 钢卷信息(关联查询,不导出)
|
||||
*/
|
||||
@JsonIgnore
|
||||
private WmsMaterialCoilVo coilVo;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1119,17 +1119,15 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
|
||||
bo.setSpecThickness(thickness);
|
||||
// 计算理论厚度(需要实测长度)
|
||||
if (bo.getTheoreticalThickness() == null && bo.getActualLength() != null) {
|
||||
if (bo.getActualLength() != null) {
|
||||
BigDecimal length = new BigDecimal(bo.getActualLength());
|
||||
BigDecimal theoreticalThickness = volume.divide(length, 10, RoundingMode.HALF_UP).divide(width, 10, RoundingMode.HALF_UP).multiply(new BigDecimal("1000"));
|
||||
bo.setTheoreticalThickness(theoreticalThickness);
|
||||
}
|
||||
|
||||
// 计算理论长度
|
||||
if (bo.getTheoreticalLength() == null) {
|
||||
BigDecimal theoreticalLength = volume.divide(thickness, 10, RoundingMode.HALF_UP).divide(width, 10, RoundingMode.HALF_UP).multiply(new BigDecimal("1000"));
|
||||
bo.setTheoreticalLength(theoreticalLength);
|
||||
}
|
||||
BigDecimal theoreticalLength = volume.divide(thickness, 10, RoundingMode.HALF_UP).divide(width, 10, RoundingMode.HALF_UP).multiply(new BigDecimal("1000"));
|
||||
bo.setTheoreticalLength(theoreticalLength);
|
||||
} catch (Exception e) {
|
||||
log.warn("计算理论厚度/长度失败", e);
|
||||
}
|
||||
@@ -1492,6 +1490,12 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public WmsMaterialCoilVo insertByBo(WmsMaterialCoilBo bo) {
|
||||
// 检查当前钢卷号是否重复(新增)
|
||||
Map<String, Object> duplicateCheck = checkCoilNoDuplicate(null, null, bo.getCurrentCoilNo(), null);
|
||||
if ("current".equals(duplicateCheck.get("duplicateType")) || "both".equals(duplicateCheck.get("duplicateType"))) {
|
||||
throw new RuntimeException("新增失败:当前钢卷号[" + bo.getCurrentCoilNo() + "]已存在");
|
||||
}
|
||||
|
||||
// 1. 生成二维码
|
||||
Long qrcodeRecordId = generateQrcodeForInsert(bo);
|
||||
bo.setQrcodeRecordId(qrcodeRecordId);
|
||||
@@ -1671,6 +1675,12 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
throw new RuntimeException("钢卷ID不能为空");
|
||||
}
|
||||
|
||||
// 检查当前钢卷号是否重复(简单更新,传入coilId排除自身)
|
||||
Map<String, Object> duplicateCheck = checkCoilNoDuplicate(bo.getCoilId(), null, bo.getCurrentCoilNo(), null);
|
||||
if ("current".equals(duplicateCheck.get("duplicateType")) || "both".equals(duplicateCheck.get("duplicateType"))) {
|
||||
throw new RuntimeException("更新失败:当前钢卷号[" + bo.getCurrentCoilNo() + "]已存在");
|
||||
}
|
||||
|
||||
// 检查独占状态
|
||||
validateCoilOperationPermission(bo.getCoilId(), "简单更新");
|
||||
|
||||
@@ -1803,6 +1813,12 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
throw new RuntimeException("原钢卷已被更新");
|
||||
}
|
||||
|
||||
// 检查当前钢卷号是否重复(单个更新,传入coilId排除自身)
|
||||
Map<String, Object> duplicateCheck = checkCoilNoDuplicate(bo.getCoilId(), null, bo.getCurrentCoilNo(), null);
|
||||
if ("current".equals(duplicateCheck.get("duplicateType")) || "both".equals(duplicateCheck.get("duplicateType"))) {
|
||||
throw new RuntimeException("更新失败:当前钢卷号[" + bo.getCurrentCoilNo() + "]已存在");
|
||||
}
|
||||
|
||||
// 若修改实际库位,先进行校验
|
||||
if (bo.getActualWarehouseId() != null) {
|
||||
Long ignoreOccupiedId = Objects.equals(bo.getActualWarehouseId(), oldCoil.getActualWarehouseId())
|
||||
@@ -2048,6 +2064,14 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
throw new RuntimeException("分卷操作需要原钢卷信息");
|
||||
}
|
||||
|
||||
// 检查每个子钢卷的当前钢卷号是否重复
|
||||
for (WmsMaterialCoilBo newCoilBo : bo.getNewCoils()) {
|
||||
Map<String, Object> duplicateCheck = checkCoilNoDuplicate(null, null, newCoilBo.getCurrentCoilNo(), null);
|
||||
if ("current".equals(duplicateCheck.get("duplicateType")) || "both".equals(duplicateCheck.get("duplicateType"))) {
|
||||
throw new RuntimeException("分卷失败:子钢卷号[" + newCoilBo.getCurrentCoilNo() + "]已存在");
|
||||
}
|
||||
}
|
||||
|
||||
// 1. 将原始钢卷的二维码标记为失效(status=0)
|
||||
if (oldCoil.getQrcodeRecordId() != null) {
|
||||
WmsGenerateRecordBo oldQrBo = new WmsGenerateRecordBo();
|
||||
@@ -2168,6 +2192,14 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
// 1. 将参与合卷的原始钢卷的二维码标记为失效,并将钢卷标记为历史数据
|
||||
//在合卷之前需要判断前端传来的bo.getNewCoils()中的所有原始钢卷的coilId是否已经是历史卷
|
||||
validateOriginalCoilsForMerge(bo.getNewCoils());
|
||||
|
||||
// 检查合卷后新钢卷的当前钢卷号是否重复
|
||||
if (StringUtils.isNotBlank(bo.getCurrentCoilNo())) {
|
||||
Map<String, Object> duplicateCheck = checkCoilNoDuplicate(null, null, bo.getCurrentCoilNo(), null);
|
||||
if ("current".equals(duplicateCheck.get("duplicateType")) || "both".equals(duplicateCheck.get("duplicateType"))) {
|
||||
throw new RuntimeException("合卷失败:当前钢卷号[" + bo.getCurrentCoilNo() + "]已存在");
|
||||
}
|
||||
}
|
||||
for (WmsMaterialCoilBo originalCoilBo : bo.getNewCoils()) {
|
||||
if (originalCoilBo.getCoilId() != null) {
|
||||
WmsMaterialCoil originalCoil = baseMapper.selectById(originalCoilBo.getCoilId());
|
||||
@@ -4292,7 +4324,7 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
|
||||
// // 检查恢复的钢卷的当前钢卷号是否重复
|
||||
// for (WmsMaterialCoil originalCoil : originalCoils) {
|
||||
// Map<String, Object> duplicateCheck = checkCoilNoDuplicate(originalCoil.getCoilId(), originalCoil.getEnterCoilNo(), originalCoil.getCurrentCoilNo());
|
||||
// Map<String, Object> duplicateCheck = checkCoilNoDuplicate(originalCoil.getCoilId(), null, originalCoil.getCurrentCoilNo(), null);
|
||||
// boolean currentCoilNoDuplicate = (boolean) duplicateCheck.get("currentCoilNoDuplicate");
|
||||
// if (currentCoilNoDuplicate) {
|
||||
// String errorMsg = "无法恢复原始钢卷,存在重复的钢卷号:原始钢卷的当前钢卷号[" + originalCoil.getCurrentCoilNo() + "]重复。";
|
||||
@@ -5038,11 +5070,11 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
throw new RuntimeException("待操作记录不存在或不匹配");
|
||||
}
|
||||
|
||||
// // 4. 检查子钢卷号是否重复
|
||||
// Map<String, Object> duplicateCheck = checkCoilNoDuplicate(null, parentCoil.getEnterCoilNo(), childCoilBo.getCurrentCoilNo());
|
||||
// if ("current".equals(duplicateCheck.get("duplicateType")) || "both".equals(duplicateCheck.get("duplicateType"))) {
|
||||
// throw new RuntimeException("子钢卷号[" + childCoilBo.getCurrentCoilNo() + "]已存在");
|
||||
// }
|
||||
// 4. 检查子钢卷号是否重复
|
||||
Map<String, Object> duplicateCheck = checkCoilNoDuplicate(null, null, childCoilBo.getCurrentCoilNo(), null);
|
||||
if ("current".equals(duplicateCheck.get("duplicateType")) || "both".equals(duplicateCheck.get("duplicateType"))) {
|
||||
throw new RuntimeException("子钢卷号[" + childCoilBo.getCurrentCoilNo() + "]已存在");
|
||||
}
|
||||
|
||||
// 校验每个子卷的实际库位
|
||||
if (childCoilBo.getActualWarehouseId() != null) {
|
||||
@@ -5353,6 +5385,12 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
throw new RuntimeException("该钢卷是历史钢卷");
|
||||
}
|
||||
|
||||
// 检查当前钢卷号是否重复(退货时用原钢卷号创建新钢卷,传入coilId排除自身)
|
||||
Map<String, Object> duplicateCheck = checkCoilNoDuplicate(coilId, null, oldCoil.getCurrentCoilNo(), null);
|
||||
if ("current".equals(duplicateCheck.get("duplicateType")) || "both".equals(duplicateCheck.get("duplicateType"))) {
|
||||
throw new RuntimeException("退货失败:当前钢卷号[" + oldCoil.getCurrentCoilNo() + "]已存在");
|
||||
}
|
||||
|
||||
WmsWarehouseBo warehouseBo = new WmsWarehouseBo();
|
||||
warehouseBo.setWarehouseName("退货仓");
|
||||
warehouseBo.setWarehouseCode("return");
|
||||
|
||||
@@ -8,6 +8,9 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.klp.common.core.service.ConfigService;
|
||||
import com.klp.common.utils.StringUtils;
|
||||
import com.klp.domain.vo.WmsMaterialCoilVo;
|
||||
import com.klp.mapper.WmsMaterialCoilMapper;
|
||||
import com.klp.service.IWmsMaterialCoilService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -25,6 +28,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 钢卷通用维度告警(长度/厚度/宽度)Service业务层处理
|
||||
@@ -40,6 +44,7 @@ public class WmsMaterialWarningServiceImpl implements IWmsMaterialWarningService
|
||||
private final WmsMaterialWarningMapper baseMapper;
|
||||
private final ConfigService configService;
|
||||
|
||||
|
||||
/**
|
||||
* 查询钢卷通用维度告警(长度/厚度/宽度)
|
||||
*/
|
||||
@@ -71,6 +76,20 @@ public class WmsMaterialWarningServiceImpl implements IWmsMaterialWarningService
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<WmsMaterialWarning> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(bo.getCoilId() != null, WmsMaterialWarning::getCoilId, bo.getCoilId());
|
||||
// 批量钢卷ID过滤(逗号分隔)
|
||||
if (StringUtils.isNotBlank(bo.getCoilIds())) {
|
||||
String[] ids = bo.getCoilIds().split(",");
|
||||
List<Long> idList = new ArrayList<>();
|
||||
for (String id : ids) {
|
||||
try {
|
||||
idList.add(Long.parseLong(id.trim()));
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
}
|
||||
if (!idList.isEmpty()) {
|
||||
lqw.in(WmsMaterialWarning::getCoilId, idList);
|
||||
}
|
||||
}
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getWarningType()), WmsMaterialWarning::getWarningType, bo.getWarningType());
|
||||
lqw.eq(bo.getTheoreticalVal() != null, WmsMaterialWarning::getTheoreticalVal, bo.getTheoreticalVal());
|
||||
lqw.eq(bo.getActualVal() != null, WmsMaterialWarning::getActualVal, bo.getActualVal());
|
||||
@@ -83,6 +102,8 @@ public class WmsMaterialWarningServiceImpl implements IWmsMaterialWarningService
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getHandleBy()), WmsMaterialWarning::getHandleBy, bo.getHandleBy());
|
||||
lqw.eq(bo.getHandleTime() != null, WmsMaterialWarning::getHandleTime, bo.getHandleTime());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getHandleRemark()), WmsMaterialWarning::getHandleRemark, bo.getHandleRemark());
|
||||
// 根据创建时间倒叙
|
||||
lqw.orderByDesc(WmsMaterialWarning::getCreateTime);
|
||||
return lqw;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user