Merge remote-tracking branch 'origin/0.8.X' into 0.8.X
This commit is contained in:
@@ -56,6 +56,7 @@
|
|||||||
"js-cookie": "3.0.1",
|
"js-cookie": "3.0.1",
|
||||||
"jsbarcode": "^3.12.1",
|
"jsbarcode": "^3.12.1",
|
||||||
"jsencrypt": "3.0.0-rc.1",
|
"jsencrypt": "3.0.0-rc.1",
|
||||||
|
"jspdf": "^2.5.1",
|
||||||
"konva": "^10.0.2",
|
"konva": "^10.0.2",
|
||||||
"mqtt": "^5.13.3",
|
"mqtt": "^5.13.3",
|
||||||
"nprogress": "0.2.0",
|
"nprogress": "0.2.0",
|
||||||
|
|||||||
@@ -24,9 +24,18 @@
|
|||||||
@keyup.enter.native="handleQuery" />
|
@keyup.enter.native="handleQuery" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="钢种">
|
<el-form-item label="钢种">
|
||||||
<el-input v-model="queryParams.grade" placeholder="请输入钢种" clearable size="small"
|
<el-input v-model="queryParams.itemName" placeholder="请输入钢种" clearable size="small"
|
||||||
@keyup.enter.native="handleQuery" />
|
@keyup.enter.native="handleQuery" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="材质">
|
||||||
|
<el-input v-model="queryParams.itemMaterial" placeholder="请输入材质" clearable size="small"
|
||||||
|
@keyup.enter.native="handleQuery" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="厂家">
|
||||||
|
<el-input v-model="queryParams.itemManufacturer" placeholder="请输入厂家" clearable size="small"
|
||||||
|
@keyup.enter.native="handleQuery" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" icon="el-icon-search" size="small" @click="handleQuery">搜索</el-button>
|
<el-button type="primary" icon="el-icon-search" size="small" @click="handleQuery">搜索</el-button>
|
||||||
<el-button icon="el-icon-refresh" size="small" @click="resetQuery">重置</el-button>
|
<el-button icon="el-icon-refresh" size="small" @click="resetQuery">重置</el-button>
|
||||||
@@ -115,6 +124,7 @@ export default {
|
|||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
currentCoilNo: null,
|
currentCoilNo: null,
|
||||||
grade: null,
|
grade: null,
|
||||||
|
itemType: 'raw_material',
|
||||||
dataType: 1 // 只查询当前数据,不查询历史数据
|
dataType: 1 // 只查询当前数据,不查询历史数据
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -241,7 +251,8 @@ export default {
|
|||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
currentCoilNo: null,
|
currentCoilNo: null,
|
||||||
grade: null,
|
grade: null,
|
||||||
dataType: 1
|
dataType: 1,
|
||||||
|
itemType: 'raw_material',
|
||||||
};
|
};
|
||||||
this.getList();
|
this.getList();
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -20,23 +20,18 @@
|
|||||||
style="width: 100%; display: inline-block;" clearable />
|
style="width: 100%; display: inline-block;" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="产品名称" prop="productName">
|
<el-form-item label="产品名称" prop="itemName">
|
||||||
<el-input v-model="queryParams.productName" placeholder="请输入产品名称" clearable
|
<el-input v-model="queryParams.itemName" placeholder="请输入产品名称" clearable
|
||||||
@keyup.enter.native="handleQuery" />
|
@keyup.enter.native="handleQuery" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="规格" prop="spec">
|
<el-form-item label="材质" prop="itemMaterial">
|
||||||
<el-input v-model="queryParams.spec" placeholder="请输入规格" clearable
|
<el-input v-model="queryParams.itemMaterial" placeholder="请输入材质" clearable
|
||||||
@keyup.enter.native="handleQuery" />
|
@keyup.enter.native="handleQuery" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="材质" prop="material">
|
<el-form-item label="厂家" prop="itemManufacturer">
|
||||||
<el-input v-model="queryParams.material" placeholder="请输入材质" clearable
|
<el-input v-model="queryParams.itemManufacturer" placeholder="请输入厂家" clearable
|
||||||
@keyup.enter.native="handleQuery" />
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item label="厂家" prop="factory">
|
|
||||||
<el-input v-model="queryParams.factory" placeholder="请输入厂家" clearable
|
|
||||||
@keyup.enter.native="handleQuery" />
|
@keyup.enter.native="handleQuery" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
@@ -445,6 +440,10 @@ export default {
|
|||||||
startTime: this.queryParams.updateTime?.[0],
|
startTime: this.queryParams.updateTime?.[0],
|
||||||
endTime: this.queryParams.updateTime?.[1],
|
endTime: this.queryParams.updateTime?.[1],
|
||||||
}
|
}
|
||||||
|
// 如果没有设置itemType,则设置为raw_material
|
||||||
|
if (!query.itemType) {
|
||||||
|
query.itemType = 'raw_material';
|
||||||
|
}
|
||||||
listMaterialCoil(query).then(response => {
|
listMaterialCoil(query).then(response => {
|
||||||
if (this.querys.warehouseId != 111) {
|
if (this.querys.warehouseId != 111) {
|
||||||
// 排除掉111仓库的
|
// 排除掉111仓库的
|
||||||
|
|||||||
@@ -59,9 +59,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleApprove(row)" v-if="row.auditStatus != 1">审批</el-button>
|
<el-button size="mini" type="text" icon="el-icon-edit" @click.stop="handleApprove(row)" v-if="row.auditStatus != 1">审批</el-button>
|
||||||
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(row)">修改</el-button>
|
<el-button size="mini" type="text" icon="el-icon-edit" @click.stop="handleUpdate(row)">修改</el-button>
|
||||||
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(row)">删除</el-button>
|
<el-button size="mini" type="text" icon="el-icon-delete" @click.stop="handleDelete(row)">删除</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-col>
|
</el-col>
|
||||||
@@ -92,7 +92,7 @@
|
|||||||
<el-table-column label="厂家" align="center" prop="manufacturer" />
|
<el-table-column label="厂家" align="center" prop="manufacturer" />
|
||||||
<el-table-column label="重量(t)" align="center" prop="netWeight" width="100" />
|
<el-table-column label="重量(t)" align="center" prop="netWeight" width="100" />
|
||||||
<el-table-column label="库区" align="center" prop="warehouseName" :show-overflow-tooltip="true" />
|
<el-table-column label="库区" align="center" prop="warehouseName" :show-overflow-tooltip="true" />
|
||||||
<el-table-column label="操作" align="center" width="100" fixed="right" v-if="currentPlan.auditStatus != 1">
|
<el-table-column label="操作" align="center" width="100" v-if="currentPlan.auditStatus != 1">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button type="danger" size="small" @click.stop="handleDeleteCoil(scope.row)">删除</el-button>
|
<el-button type="danger" size="small" @click.stop="handleDeleteCoil(scope.row)">删除</el-button>
|
||||||
</template>
|
</template>
|
||||||
@@ -228,6 +228,11 @@ export default {
|
|||||||
}).then(res => {
|
}).then(res => {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
this.buttonLoading = false;
|
this.buttonLoading = false;
|
||||||
|
|
||||||
|
// 如何当前选中的计划是被审批的计划,需要同步修改数据
|
||||||
|
if (row.planId == this.currentPlan.planId) {
|
||||||
|
this.currentPlan.auditStatus = 1;
|
||||||
|
}
|
||||||
this.$message({
|
this.$message({
|
||||||
message: '审批成功',
|
message: '审批成功',
|
||||||
type: 'success'
|
type: 'success'
|
||||||
|
|||||||
@@ -13,6 +13,8 @@
|
|||||||
<!-- 右侧仓库信息区域 - 替换为 Bird 组件 -->
|
<!-- 右侧仓库信息区域 - 替换为 Bird 组件 -->
|
||||||
<div class="warehouse-container" v-if="selectedNodeId" v-loading="rightLoading" element-loading-text="加载中..."
|
<div class="warehouse-container" v-if="selectedNodeId" v-loading="rightLoading" element-loading-text="加载中..."
|
||||||
element-loading-spinner="el-icon-loading">
|
element-loading-spinner="el-icon-loading">
|
||||||
|
<!-- 导出所有二维码 -->
|
||||||
|
<button buttonLoading type="primary" @click="exportAllQrcodes">导出二维码</button>
|
||||||
<WarehouseBird :warehouse-list="warehouseList" @open-init-dialog="openInitDialog" />
|
<WarehouseBird :warehouse-list="warehouseList" @open-init-dialog="openInitDialog" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -35,9 +37,9 @@
|
|||||||
@mouseleave="resetGridHover">
|
@mouseleave="resetGridHover">
|
||||||
<div v-for="row in 40" :key="`grid-row-${row}`" class="grid-selector-row">
|
<div v-for="row in 40" :key="`grid-row-${row}`" class="grid-selector-row">
|
||||||
<div v-for="col in 10" :key="`grid-col-${col}`" class="grid-selector-cell" :class="{
|
<div v-for="col in 10" :key="`grid-col-${col}`" class="grid-selector-cell" :class="{
|
||||||
hovered: row <= hoverRow && col <= hoverCol,
|
hovered: row <= hoverRow && col <= hoverCol,
|
||||||
selected: row <= initForm.rowCount && col <= initForm.columnCount
|
selected: row <= initForm.rowCount && col <= initForm.columnCount
|
||||||
}">
|
}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -58,6 +60,8 @@
|
|||||||
<script>
|
<script>
|
||||||
import { listActualWarehouse, treeActualWarehouseTwoLevel, getActualWarehouse, generateLocations } from "@/api/wms/actualWarehouse";
|
import { listActualWarehouse, treeActualWarehouseTwoLevel, getActualWarehouse, generateLocations } from "@/api/wms/actualWarehouse";
|
||||||
import WarehouseBird from './components/WarehouseBird.vue';
|
import WarehouseBird from './components/WarehouseBird.vue';
|
||||||
|
import jsPDF from 'jspdf';
|
||||||
|
import QRCode from 'qrcode';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Overview",
|
name: "Overview",
|
||||||
@@ -125,6 +129,111 @@ export default {
|
|||||||
.finally(() => { this.treeLoading = false; });
|
.finally(() => { this.treeLoading = false; });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async exportAllQrcodes() {
|
||||||
|
this.buttonLoading = true;
|
||||||
|
if (!this.warehouseList || this.warehouseList.length === 0) {
|
||||||
|
this.$message.warning('暂无库位数据可导出');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadingInstance = this.$loading({
|
||||||
|
lock: true,
|
||||||
|
text: '正在生成二维码PDF,请稍候...',
|
||||||
|
spinner: 'el-icon-loading',
|
||||||
|
background: 'rgba(0, 0, 0, 0.7)'
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 初始化PDF (A4纸尺寸: 210mm × 297mm,换算成px约595 × 842)
|
||||||
|
const pdf = new jsPDF({
|
||||||
|
orientation: 'portrait', // 纵向
|
||||||
|
unit: 'mm', // 单位:毫米
|
||||||
|
format: 'a4' // A4格式
|
||||||
|
});
|
||||||
|
|
||||||
|
// 配置项
|
||||||
|
const qrCodeSize = 30; // 二维码尺寸(mm)
|
||||||
|
const margin = 10; // 页面边距(mm)
|
||||||
|
const gap = 10; // 二维码间距(mm)
|
||||||
|
const textOffset = 5; // 文字与二维码间距(mm)
|
||||||
|
const maxPerRow = Math.floor((210 - 2 * margin) / (qrCodeSize + gap)); // 每行最多二维码数
|
||||||
|
const maxPerPage = Math.floor((297 - 2 * margin) / (qrCodeSize + gap + textOffset + 5)) * maxPerRow; // 每页最多二维码数
|
||||||
|
|
||||||
|
let currentX = margin; // 当前X坐标
|
||||||
|
let currentY = margin; // 当前Y坐标
|
||||||
|
let currentIndex = 0; // 当前处理的库位索引
|
||||||
|
const totalCount = this.warehouseList.length;
|
||||||
|
|
||||||
|
// 遍历所有库位生成二维码并添加到PDF
|
||||||
|
for (const [index, item] of this.warehouseList.entries()) {
|
||||||
|
currentIndex = index;
|
||||||
|
|
||||||
|
// 跳过无ID的项
|
||||||
|
if (!item.actualWarehouseId) continue;
|
||||||
|
|
||||||
|
// 生成二维码 (返回base64格式)
|
||||||
|
const qrCodeDataUrl = await QRCode.toDataURL(item.actualWarehouseId, {
|
||||||
|
width: qrCodeSize * 3.78, // 转换mm到px (1mm ≈ 3.78px)
|
||||||
|
margin: 1,
|
||||||
|
errorCorrectionLevel: 'H' // 高容错率
|
||||||
|
});
|
||||||
|
|
||||||
|
// 检查是否需要换行
|
||||||
|
if (currentX + qrCodeSize > 210 - margin) {
|
||||||
|
currentX = margin;
|
||||||
|
currentY += qrCodeSize + gap + textOffset + 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否需要分页
|
||||||
|
if (currentY + qrCodeSize > 297 - margin || (index > 0 && index % maxPerPage === 0)) {
|
||||||
|
pdf.addPage();
|
||||||
|
currentX = margin;
|
||||||
|
currentY = margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加二维码到PDF
|
||||||
|
pdf.addImage(qrCodeDataUrl, 'PNG', currentX, currentY, qrCodeSize, qrCodeSize);
|
||||||
|
|
||||||
|
// 添加库位名称(自动换行处理)
|
||||||
|
const name = item.actualWarehouseName || '未知库位';
|
||||||
|
const fontSize = 8; // 字体大小
|
||||||
|
pdf.setFontSize(fontSize);
|
||||||
|
// 计算文字宽度,超出则截断
|
||||||
|
const textWidth = pdf.getTextWidth(name);
|
||||||
|
let displayName = name;
|
||||||
|
if (textWidth > qrCodeSize) {
|
||||||
|
const maxTextWidth = qrCodeSize;
|
||||||
|
let tempText = '';
|
||||||
|
for (let i = 0; i < name.length; i++) {
|
||||||
|
if (pdf.getTextWidth(tempText + name[i]) > maxTextWidth) {
|
||||||
|
displayName = tempText + '...';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tempText += name[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 文字居中显示在二维码下方
|
||||||
|
const textX = currentX + (qrCodeSize - pdf.getTextWidth(displayName)) / 2;
|
||||||
|
pdf.text(displayName, textX, currentY + qrCodeSize + textOffset);
|
||||||
|
|
||||||
|
// 更新X坐标
|
||||||
|
currentX += qrCodeSize + gap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存PDF
|
||||||
|
const fileName = `库位二维码_${this.selectedNode.actualWarehouseName}.pdf`;
|
||||||
|
pdf.save(fileName);
|
||||||
|
|
||||||
|
this.$message.success(`成功导出 ${totalCount} 个库位二维码`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('二维码导出失败:', error);
|
||||||
|
this.$message.error(`二维码导出失败:${error.message}`);
|
||||||
|
} finally {
|
||||||
|
this.buttonLoading = false;
|
||||||
|
loadingInstance.close();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// 树节点点击
|
// 树节点点击
|
||||||
handleNodeClick(node) {
|
handleNodeClick(node) {
|
||||||
if (this.isSwitching) return;
|
if (this.isSwitching) return;
|
||||||
|
|||||||
Reference in New Issue
Block a user