Compare commits

...

2 Commits

Author SHA1 Message Date
砂糖
d3da84f65e fix: 修复产线能力查询参数错误及调整分页默认值
修复产线能力查询时lineId参数传递错误的问题,增加参数校验
调整分页组件默认的pageSizes选项,增加10的选项
修改物料线圈查询状态参数为0
优化线圈吞吐记录展示方式,改为行点击触发
移除用餐记录中不必要的部门字典依赖
2026-03-09 10:34:05 +08:00
砂糖
c532d7f753 feat(标签打印): 添加镀锌原料标签组件及显示逻辑
新增 ZincRawTag 组件用于显示镀锌原料标签,并在特定仓库条件下自动选择该标签类型。标签包含冷卷号、热卷号、规格等字段,并支持二维码显示和打印适配。
2026-03-09 10:33:17 +08:00
7 changed files with 351 additions and 23 deletions

View File

@@ -100,7 +100,7 @@ export default {
// 顺序请求:前一个请求完成后,再执行下一个
const productRes = await listProduct({ pageSize: 10, pageNum: 1 });
const rawMaterialRes = await listRawMaterial({ pageSize: 10, pageNum: 1 });
const materialCoilRes = await listMaterialCoil({ pageSize: 10, pageNum: 1, dataType: 1, status: 1 });
const materialCoilRes = await listMaterialCoil({ pageSize: 10, pageNum: 1, dataType: 1, status: 0 });
const equipmentRes = await listEquipmentManagement({ pageSize: 1, pageNum: 1, status: 'in_service' });
const orderRes = await listOrder({ pageSize: 1, pageNum: 1 });
const customerRes = await listCustomer({ pageSize: 1, pageNum: 1 });

View File

@@ -37,7 +37,7 @@ export default {
pageSizes: {
type: Array,
default() {
return [15, 20, 30, 50]
return [10, 15, 20, 30, 50]
}
},
// 移动端页码按钮的数量端默认值5

View File

@@ -236,7 +236,8 @@ export default {
},
onLineRowClick(row) {
this.queryParams.lineId = row.lineId
this.handleQuery()
console.log(row);
// this.handleQuery()
},
getList() {
this.loading = true
@@ -264,8 +265,14 @@ export default {
this.open = true
return
}
console.log(row);
const lineId = row.lineId ?? this.queryParams.lineId
if (!lineId) {
this.$modal.msgError('请选择产线')
return
}
this.loading = true
getLineCapability(row.capabilityId).then(res => {
getLineCapability(lineId).then(res => {
const d = res.data || {}
this.form = {
...this.form,

View File

@@ -0,0 +1,290 @@
<template>
<div class="label-container" :style="{ '--print-scale': printScale }">
<div class="material-label-grid">
<!-- 公司名称行 -->
<div class="grid-cell company-cell">嘉祥科伦普重工有限公司</div>
<!-- 第一行冷卷号热卷号 -->
<div class="grid-cell label-cell">冷卷号</div>
<div class="grid-cell value-cell">
<div class="nob" contenteditable>{{ content.currentCoilNo || '' }}</div>
</div>
<div class="grid-cell label-cell">热卷号</div>
<div class="grid-cell value-cell">
<div class="nob" contenteditable>{{ content.enterCoilNo || '' }}</div>
</div>
<!-- 第二行规格钢种 -->
<div class="grid-cell label-cell">规格</div>
<div class="grid-cell value-cell">
<div class="nob" contenteditable>{{ content.specification || '' }}</div>
</div>
<div class="grid-cell label-cell">钢种</div>
<div class="grid-cell value-cell">
<div class="nob" contenteditable>{{ content.material || '' }}</div>
</div>
<!-- 第三行净重下工序 -->
<div class="grid-cell label-cell">净重</div>
<div class="grid-cell value-cell">
<div class="nob" contenteditable>{{ content.netWeight || '' }}</div>
</div>
<div class="grid-cell label-cell">下工序</div>
<div class="grid-cell value-cell">
<div class="nob" contenteditable>{{ content.nextProcess || '冷硬卷' }}</div>
</div>
<!-- 第四行包装要求切边要求 -->
<div class="grid-cell label-cell">包装要求</div>
<div class="grid-cell value-cell">
<div class="nob" contenteditable>{{ content.packagingRequirements || '' }}</div>
</div>
<div class="grid-cell label-cell">切边要求</div>
<div class="grid-cell value-cell">
<div class="nob" contenteditable>{{ content.trimmingRequirements || '' }}</div>
</div>
<!-- 第五行班组代码二维码 -->
<div class="grid-cell label-cell">班组</div>
<div class="grid-cell value-cell">
<div class="nob" contenteditable>{{ content.team || '' }}</div>
</div>
<div class="grid-cell label-cell">代码</div>
<div class="grid-cell qrcode-cell">
<!-- 二维码容器 -->
<QRCode :content="content.qrcodeRecordId" />
</div>
<!-- 第六行生产日期 -->
<div class="grid-cell label-cell">生产日期</div>
<div class="grid-cell value-cell date-cell">
<div class="nob" contenteditable>{{ content.createTime || '' }}</div>
</div>
</div>
</div>
</template>
<script>
import QRCode from '@/components/QRCode/index.vue';
export default {
name: 'ZincRawTag',
components: {
QRCode
},
props: {
content: {
type: Object,
default: () => ({
currentCoilNo: '',
entryCoilNo: '',
specification: '',
material: '',
netWeight: '',
nextProcess: '',
packagingRequirements: '',
trimmingRequirements: '',
team: '',
createTime: '',
qrcodeRecordId: '',
})
},
paperWidthMm: {
type: Number,
default: 100
},
paperHeightMm: {
type: Number,
default: 80
}
},
data() {
return {
printScale: 1,
printMediaQuery: null
}
},
mounted() {
this.printMediaQuery = window.matchMedia('print');
this.printMediaQuery.addListener(this.handlePrintMediaChange);
window.addEventListener('beforeprint', this.handleBeforePrint);
window.addEventListener('afterprint', this.handleAfterPrint);
this.$nextTick(() => {
this.calculatePrintScale();
});
},
beforeDestroy() {
if (this.printMediaQuery) {
this.printMediaQuery.removeListener(this.handlePrintMediaChange);
}
window.removeEventListener('beforeprint', this.handleBeforePrint);
window.removeEventListener('afterprint', this.handleAfterPrint);
},
methods: {
handlePrintMediaChange(mq) {
mq.matches ? this.calculatePrintScale() : this.resetPrintScale();
},
handleBeforePrint() {
setTimeout(() => this.calculatePrintScale(), 100);
},
handleAfterPrint() {
this.resetPrintScale();
},
calculatePrintScale() {
this.$nextTick(() => {
const container = this.$el;
if (!container) return;
const dpi = 96;
const mmToPx = dpi / 25.4;
const paperWidthPx = this.paperWidthMm * mmToPx;
const paperHeightPx = this.paperHeightMm * mmToPx;
const marginPx = 2 * mmToPx;
const rect = container.getBoundingClientRect();
const contentWidth = rect.width || container.scrollWidth;
const contentHeight = rect.height || container.scrollHeight;
const availableWidth = paperWidthPx - marginPx * 2;
const availableHeight = paperHeightPx - marginPx * 2;
const scaleX = contentWidth > 0 ? availableWidth / contentWidth : 1;
const scaleY = contentHeight > 0 ? availableHeight / contentHeight : 1;
this.printScale = Math.min(scaleX, scaleY, 1);
container.style.setProperty('--print-scale', this.printScale);
container.style.setProperty('--paper-width', `${this.paperWidthMm}mm`);
container.style.setProperty('--paper-height', `${this.paperHeightMm}mm`);
});
},
resetPrintScale() {
this.printScale = 1;
if (this.$el) {
this.$el.style.setProperty('--print-scale', 1);
this.$el.style.removeProperty('--paper-width');
this.$el.style.removeProperty('--paper-height');
}
}
}
}
</script>
<style scoped>
.label-container {
width: 45em;
height: 25em;
padding: 0;
font-family: "SimSun", serif;
box-sizing: border-box;
}
/* 核心Grid布局 */
.material-label-grid {
display: grid;
grid-template-columns: repeat(4, 1fr); /* 4列等宽 */
grid-auto-rows: 1fr; /* 行高自适应 */
width: 100%;
height: 100%;
border: 1px solid #333;
box-sizing: border-box;
}
.grid-cell {
border: 1px solid #333;
padding: 4px;
font-size: 14px;
box-sizing: border-box;
text-align: center;
word-break: break-all;
overflow-wrap: break-word;
display: flex;
align-items: center;
justify-content: center;
}
/* 公司名称单元格 */
.company-cell {
grid-column: span 4; /* 跨4列 */
font-size: 18px;
font-weight: bold;
background-color: #f5f5f5;
}
/* 标签单元格(左) */
.label-cell {
background-color: #f5f5f5;
font-weight: bold;
}
/* 值单元格 */
.value-cell {
text-align: center;
}
.date-cell {
grid-column: span 2;
}
/* 二维码单元格跨2列+2行 */
.qrcode-cell {
grid-row: span 2; /* 跨2行 */
display: flex;
align-items: center;
justify-content: center;
}
.qrcode-container {
width: 80%;
height: 80%;
border: 1px dashed #999; /* 占位虚线 */
}
/* 内容可编辑区域 */
.nob {
width: 100%;
height: 100%;
border: none;
outline: none;
background: transparent;
text-align: center;
font-size: inherit;
word-break: break-all;
display: flex;
align-items: center;
justify-content: center;
}
/* 打印样式 */
@media print {
@page {
size: 100mm 80mm;
margin: 0 !important;
}
* {
-webkit-print-color-adjust: exact !important;
print-color-adjust: exact !important;
}
html,
body {
margin: 0 !important;
padding: 0 !important;
overflow: hidden !important;
}
body>*:not(.label-container) {
display: none !important;
}
.label-container {
page-break-inside: avoid !important;
break-inside: avoid !important;
transform: scale(var(--print-scale, 1)) !important;
transform-origin: top left !important;
max-width: var(--paper-width, 100mm) !important;
max-height: var(--paper-height, 80mm) !important;
overflow: hidden !important;
}
}
</style>

View File

@@ -26,6 +26,12 @@
:paperWidthMm="100"
:paperHeightMm="80"
/>
<ZincRawTag
v-if="tagType === '5'"
:content="content"
:paperWidthMm="180"
:paperHeightMm="100"
/>
<!-- <SampleTagPreview v-if="labelType === '4'" :content="content" />
<ForgeTagPreview v-if="labelType === '5'" :content="content" />
<SaltSprayTagPreview v-if="labelType === '6'" :content="content" /> -->
@@ -47,6 +53,8 @@ import MaterialTag from './MaterialTag.vue';
import OuterTagPreview from './OuterTagPreview.vue';
import GalvanizedTag from './GalvanizedTag.vue';
import WhereTag from './WhereTag.vue';
import ZincRawTag from './ZincRawTag.vue';
// import SampleTagPreview from './SampleTagPreview.vue';
// import ForgeTagPreview from './ForgeTagPreview.vue';
// import SaltSprayTagPreview from './SaltSprayTagPreview.vue';
@@ -58,6 +66,7 @@ export default {
OuterTagPreview,
GalvanizedTag,
WhereTag,
ZincRawTag,
// SampleTagPreview,
// ForgeTagPreview,
// SaltSprayTagPreview,
@@ -114,8 +123,11 @@ export default {
watch: {
content: {
handler(newVal) {
const { itemName, itemType } = newVal;
if (itemType == 'raw_material') {
const { itemName, itemType, warehouseId } = newVal;
// 在镀锌颜料库的卷使用镀锌原料标签
if (itemType == 'raw_material' && warehouseId == '1988150263284953089') {
this.labelType = '5';
} else if (itemType == 'raw_material') {
this.labelType = '2';
} else if (itemType == 'product' && itemName == '冷硬卷') {
this.labelType = '3';

View File

@@ -77,7 +77,7 @@
</el-row>
<KLPTable v-loading="loading" :data="materialCoilList" @selection-change="handleSelectionChange" :floatLayer="true"
:floatLayerConfig="floatLayerConfig">
:floatLayerConfig="floatLayerConfig" @row-click="handleRowClick">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="入场钢卷号" align="center" prop="enterCoilNo">
<template slot-scope="scope">
@@ -249,8 +249,8 @@
@click="handleAbnormal(scope.row)">查看异常</el-button>
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleCheck(scope.row)"
v-if="showControl">修正</el-button>
<el-button size="mini" type="text" icon="el-icon-time" @click="handleLog(scope.row)"
v-if="showWareLog">吞吐记录</el-button>
<!-- <el-button size="mini" type="text" icon="el-icon-time" @click="handleLog(scope.row)"
v-if="showWareLog">吞吐记录</el-button> -->
<!-- <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
v-if="showControl">删除</el-button> -->
<el-button size="mini" type="text" icon="el-icon-search" @click="handleTrace(scope.row)">追溯</el-button>
@@ -387,9 +387,9 @@
</el-dialog>
<!-- 吞吐记录 -->
<el-dialog v-if="showWareLog" title="吞吐记录" :visible.sync="logOpen" width="90%" append-to-body>
<log-table :coil-id="currentCoilId"></log-table>
</el-dialog>
<!-- <el-dialog v-if="showWareLog" title="吞吐记录" :visible.sync="logOpen" width="90%" append-to-body> -->
<log-table v-if="showWareLog && currentCoilId" :coil-id="currentCoilId"></log-table>
<!-- </el-dialog> -->
</div>
</template>
@@ -721,6 +721,12 @@ export default {
this.getUserList();
},
methods: {
// 处理行点击事件
handleRowClick(row) {
this.currentCoilId = row.coilId;
this.logOpen = true;
},
// 获取用户列表
getUserList() {
listUser({ pageNum: 1, pageSize: 1000 }).then(res => {
this.userList = res.rows || [];

View File

@@ -31,7 +31,6 @@
/>
</el-form-item>
<el-form-item label="部门名称" prop="deptName">
<!-- <DictSelect dictType="hrm_department" v-model="queryParams.deptName" placeholder="请选择部门名称"></DictSelect> -->
<el-select v-model="queryParams.deptName" placeholder="请选择部门名称">
<el-option
v-for="dict in deptOptions"
@@ -98,11 +97,7 @@
<dict-tag :options="dict.type.hrm_meal_type" :value="scope.row.mealType"/>
</template>
</el-table-column>
<el-table-column label="部门名称" align="center" prop="deptName">
<template slot-scope="scope">
<dict-tag :options="dict.type.hrm_department" :value="scope.row.deptName"/>
</template>
</el-table-column>
<el-table-column label="部门名称" align="center" prop="deptName"></el-table-column>
<el-table-column label="用餐总人数" align="center" prop="totalPeople" />
<el-table-column label="堂食人数" align="center" prop="dineInPeople">
<template slot-scope="scope">
@@ -172,7 +167,6 @@
:value="dict.deptName"
></el-option>
</el-select>
<!-- <DictSelect dictType="hrm_department" v-model="form.deptName" placeholder="请选择部门名称"></DictSelect> -->
</el-form-item>
<el-form-item label="堂食成员" prop="dineInPeopleList">
<employee-selector v-model="form.dineInPeopleList" :key-field="'name'" :multiple="true" placeholder="请选择堂食成员" @change="handleDineInPeopleChange" :disabled-names="form.takeoutPeopleList || ''" />
@@ -208,7 +202,7 @@ import { listDept } from "@/api/wms/dept"
export default {
name: "MealReport",
dicts: ['hrm_meal_type', 'hrm_department'],
dicts: ['hrm_meal_type'],
components: { DictSelect, EmployeeSelector },
data() {
// 用餐日期默认选中今天
@@ -241,7 +235,24 @@ export default {
status: undefined,
deadlineTime: '12:00:00' // 新增截至时间默认12点
},
form: {},
form: {
reportId: undefined,
reportDate: nowTime,
mealType: undefined,
deptName: undefined,
totalPeople: undefined,
dineInPeopleList: '',
dineInPeople: 0,
takeoutPeopleList: '',
takeoutPeople: 0,
reportUserName: undefined,
status: undefined,
createBy: undefined,
createTime: undefined,
updateBy: undefined,
updateTime: undefined,
remark: undefined
},
// 替换原有统计变量新增6个有效/无效统计项
validDineIn: 0, // 有效堂食人数
validTakeout: 0, // 有效打包人数
@@ -372,8 +383,10 @@ export default {
mealType: undefined,
deptName: undefined,
totalPeople: undefined,
dineInPeople: undefined,
takeoutPeople: undefined,
dineInPeopleList: '',
dineInPeople: 0,
takeoutPeopleList: '',
takeoutPeople: 0,
reportUserName: undefined,
status: undefined,
createBy: undefined,