feat(钢卷管理): 添加钢卷号组件并优化相关功能

新增CoilNo组件用于统一显示钢卷号,支持G开头钢卷号特殊样式
在actflow、detail、panels等页面中使用新组件替换原有el-tag显示
添加showExportTime属性控制发货时间列的显示
优化ImportGuide组件,钢卷号自动添加G前缀
This commit is contained in:
砂糖
2025-12-02 15:52:35 +08:00
parent e2ebea0549
commit 99cd07939f
6 changed files with 95 additions and 85 deletions

View File

@@ -0,0 +1,31 @@
<template>
<div :class="{'g-coil-no': isGCoilNo}">
<el-tag type="info" size="small">{{ coilNo }}</el-tag>
</div>
</template>
<script>
export default {
props: {
coilNo: {
type: String,
default: ''
}
},
computed: {
isGCoilNo() {
return this.coilNo.startsWith('G');
}
},
}
</script>
<style scoped>
/* 调整容器布局,让边框完整包裹标签 */
.g-coil-no {
display: inline-block; /* 让容器尺寸贴合内部el-tag */
border: 2px solid #67c23a !important;
padding: 2px; /* 增加内边距,避免边框紧贴标签 */
border-radius: 4px; /* 可选和el-tag圆角保持一致更美观 */
}
</style>

View File

@@ -69,9 +69,9 @@
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column label="序号" type="index" width="60" align="center" /> <el-table-column label="序号" type="index" width="60" align="center" />
<el-table-column label="钢卷号" align="center" prop="currentCoilNo" :show-overflow-tooltip="true"> <el-table-column label="钢卷号" align="center" prop="currentCoilNo">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag type="info" size="small">{{ scope.row.currentCoilNo }}</el-tag> <coil-no :coil-no="scope.row.currentCoilNo"></coil-no>
</template> </template>
</el-table-column> </el-table-column>
@@ -268,17 +268,18 @@ import {
addPendingAction, addPendingAction,
updatePendingAction, updatePendingAction,
startProcess, startProcess,
completeAction,
cancelAction cancelAction
} from '@/api/wms/pendingAction'; } from '@/api/wms/pendingAction';
import CoilSelector from '@/components/CoilSelector'; import CoilSelector from '@/components/CoilSelector';
import CoilNo from '@/components/KLPService/Renderer/CoilNo.vue';
export default { export default {
name: 'CoilActflow', name: 'CoilActflow',
dicts: ['action_type'], dicts: ['action_type'],
components: { components: {
CoilSelector CoilSelector,
CoilNo
}, },
data() { data() {
return { return {

View File

@@ -71,8 +71,16 @@
<KLPTable v-loading="loading" :data="materialCoilList" @selection-change="handleSelectionChange" :floatLayer="true" :floatLayerConfig="floatLayerConfig"> <KLPTable v-loading="loading" :data="materialCoilList" @selection-change="handleSelectionChange" :floatLayer="true" :floatLayerConfig="floatLayerConfig">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column label="入场钢卷号" align="center" prop="enterCoilNo" /> <el-table-column label="入场钢卷号" align="center" prop="enterCoilNo">
<el-table-column label="当前钢卷号" align="center" prop="currentCoilNo" /> <template slot-scope="scope">
<coil-no :coil-no="scope.row.enterCoilNo"></coil-no>
</template>
</el-table-column>
<el-table-column label="当前钢卷号" align="center" prop="currentCoilNo">
<template slot-scope="scope">
<coil-no :coil-no="scope.row.currentCoilNo"></coil-no>
</template>
</el-table-column>
<!-- <el-table-column label="厂家卷号" align="center" prop="supplierCoilNo" /> --> <!-- <el-table-column label="厂家卷号" align="center" prop="supplierCoilNo" /> -->
<el-table-column label="逻辑库位" align="center" prop="warehouseName" v-if="!hideWarehouseQuery" /> <el-table-column label="逻辑库位" align="center" prop="warehouseName" v-if="!hideWarehouseQuery" />
<el-table-column label="实际库区" align="center" prop="actualWarehouseName" v-if="!hideWarehouseQuery" /> <el-table-column label="实际库区" align="center" prop="actualWarehouseName" v-if="!hideWarehouseQuery" />
@@ -92,6 +100,7 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="更新时间" align="center" prop="updateTime" /> <el-table-column label="更新时间" align="center" prop="updateTime" />
<el-table-column label="发货时间" align="center" v-if="showExportTime" prop="exportTime" />
<el-table-column label="更新人" align="center" prop="updateBy" /> <el-table-column label="更新人" align="center" prop="updateBy" />
<el-table-column label="二维码" v-if="qrcode"> <el-table-column label="二维码" v-if="qrcode">
@@ -99,6 +108,7 @@
<QRCode :content="scope.row.qrcodeRecordId" :size="50" /> <QRCode :content="scope.row.qrcodeRecordId" :size="50" />
</template> </template>
</el-table-column> </el-table-column>
<!-- <el-table-column label="状态" v-if="showStatus" align="center" prop="status"> <!-- <el-table-column label="状态" v-if="showStatus" align="center" prop="status">
<template slot-scope="scope"> <template slot-scope="scope">
<el-select v-model="scope.row.status" placeholder="请选择状态" @change="handleStatusChange(scope.row)"> <el-select v-model="scope.row.status" placeholder="请选择状态" @change="handleStatusChange(scope.row)">
@@ -134,7 +144,7 @@
<el-button size="mini" type="text" icon="el-icon-view" @click="handlePreviewLabel(scope.row)"> <el-button size="mini" type="text" icon="el-icon-view" @click="handlePreviewLabel(scope.row)">
导出标签 导出标签
</el-button> </el-button>
<el-button size="mini" v-if="showStatus" type="text" icon="el-icon-upload" @click="handleExportCoil(scope.row.coilId)"> <el-button size="mini" v-if="showStatus" type="text" icon="el-icon-upload" @click="handleExportCoil(scope.row)">
发货 发货
</el-button> </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-edit" @click="handleCheck(scope.row)" v-if="showControl">修正</el-button>
@@ -248,6 +258,8 @@ import LabelRender from './LabelRender/index.vue'
import MaterialSelect from "@/components/KLPService/MaterialSelect"; import MaterialSelect from "@/components/KLPService/MaterialSelect";
import ActualWarehouseSelect from "@/components/KLPService/ActualWarehouseSelect"; import ActualWarehouseSelect from "@/components/KLPService/ActualWarehouseSelect";
import { findItemWithBom } from "@/store/modules/category"; import { findItemWithBom } from "@/store/modules/category";
import CoilNo from "@/components/KLPService/Renderer/CoilNo.vue";
export default { export default {
name: "MaterialCoil", name: "MaterialCoil",
@@ -262,7 +274,8 @@ export default {
BomInfoMini, BomInfoMini,
CoilTraceResult, CoilTraceResult,
LabelRender, LabelRender,
ActualWarehouseSelect ActualWarehouseSelect,
CoilNo
}, },
dicts: ['product_coil_status'], dicts: ['product_coil_status'],
props: { props: {
@@ -293,7 +306,11 @@ export default {
showControl: { showControl: {
type: Boolean, type: Boolean,
default: true, default: true,
} },
showExportTime: {
type: Boolean,
default: false,
},
}, },
data() { data() {
return { return {

View File

@@ -1,5 +1,5 @@
<template> <template>
<BasePage :qrcode="qrcode" :querys="querys" :labelType="labelType" :showStatus="showStatus" :hideType="hideType" /> <BasePage :qrcode="qrcode" :querys="querys" :labelType="labelType" :showStatus="showStatus" :hideType="hideType" :showControl="showControl" :showExportTime="showExportTime" />
</template> </template>
<script> <script>
@@ -21,6 +21,7 @@ export default {
labelType: '3', labelType: '3',
showStatus: false, showStatus: false,
hideType: false, hideType: false,
showExportTime: true,
} }
} }
} }

View File

@@ -2,46 +2,25 @@
<div class="import-wizard-container"> <div class="import-wizard-container">
<!-- 文件上传区域 --> <!-- 文件上传区域 -->
<div class="file-upload-area" :class="{ disabled: importStatus === ImportStatus.PROCESSING }"> <div class="file-upload-area" :class="{ disabled: importStatus === ImportStatus.PROCESSING }">
<el-upload <el-upload ref="upload" class="upload-excel" action="" :auto-upload="false" :show-file-list="false"
ref="upload" :on-change="handleFileChange" accept=".xlsx,.xls"
class="upload-excel" :disabled="importStatus === ImportStatus.PROCESSING || validateLoading || importLoading">
action=""
:auto-upload="false"
:show-file-list="false"
:on-change="handleFileChange"
accept=".xlsx,.xls"
:disabled="importStatus === ImportStatus.PROCESSING || validateLoading || importLoading"
>
<el-button type="primary" icon="el-icon-upload2">选择Excel文件</el-button> <el-button type="primary" icon="el-icon-upload2">选择Excel文件</el-button>
</el-upload> </el-upload>
<!-- 操作按钮新增loading和防呆 --> <!-- 操作按钮新增loading和防呆 -->
<el-button <el-button type="success" icon="el-icon-check" @click="handleValidate"
type="success" v-if="file && importStatus === ImportStatus.IDLE" :disabled="!file || validateLoading"
icon="el-icon-check" :loading="validateLoading">
@click="handleValidate"
v-if="file && importStatus === ImportStatus.IDLE"
:disabled="!file || validateLoading"
:loading="validateLoading"
>
校验数据 校验数据
</el-button> </el-button>
<el-button <el-button type="warning" icon="el-icon-circle-check" @click="startImport"
type="warning"
icon="el-icon-circle-check"
@click="startImport"
v-if="file && importStatus === ImportStatus.IDLE" v-if="file && importStatus === ImportStatus.IDLE"
:disabled="!file || !isValidated || errorList.length > 0 || importLoading" :disabled="!file || !isValidated || errorList.length > 0 || importLoading" :loading="importLoading">
:loading="importLoading"
>
开始导入 开始导入
</el-button> </el-button>
<el-button <el-button type="default" icon="el-icon-refresh" @click="reset"
type="default" :disabled="importStatus === ImportStatus.PROCESSING || validateLoading || importLoading">
icon="el-icon-refresh"
@click="reset"
:disabled="importStatus === ImportStatus.PROCESSING || validateLoading || importLoading"
>
重置 重置
</el-button> </el-button>
</div> </div>
@@ -57,46 +36,23 @@
<!-- 数据预览 --> <!-- 数据预览 -->
<div v-if="tableData.length > 0 && importStatus === ImportStatus.IDLE" class="data-preview"> <div v-if="tableData.length > 0 && importStatus === ImportStatus.IDLE" class="data-preview">
<el-alert <el-alert title="数据预览" type="info" :description="`共解析出 ${tableData.length} 条有效数据`" show-icon :closable="false" />
title="数据预览"
type="info"
:description="`共解析出 ${tableData.length} 条有效数据`"
show-icon
:closable="false"
/>
<el-table :data="tableData" border size="small" max-height="300" stripe> <el-table :data="tableData" border size="small" max-height="300" stripe>
<el-table-column <el-table-column v-for="column in TableColumnEnum" :key="column.prop" :prop="column.prop" :label="column.label"
v-for="column in TableColumnEnum" :width="column.width" :min-width="column.minWidth" />
:key="column.prop"
:prop="column.prop"
:label="column.label"
:width="column.width"
:min-width="column.minWidth"
/>
</el-table> </el-table>
</div> </div>
<!-- 导入进度展示 --> <!-- 导入进度展示 -->
<div v-if="importStatus === ImportStatus.PROCESSING" class="import-progress"> <div v-if="importStatus === ImportStatus.PROCESSING" class="import-progress">
<el-alert <el-alert title="正在导入数据" type="warning" :description="`当前进度:${progress}%`" show-icon :closable="false" />
title="正在导入数据"
type="warning"
:description="`当前进度:${progress}%`"
show-icon
:closable="false"
/>
<el-progress :percentage="progress" status="success" /> <el-progress :percentage="progress" status="success" />
<p class="progress-tip">已导入 {{ importedCount }} / {{ totalCount }} 条数据</p> <p class="progress-tip">已导入 {{ importedCount }} / {{ totalCount }} 条数据</p>
</div> </div>
<!-- 导入完成提示 --> <!-- 导入完成提示 -->
<div v-if="importStatus === ImportStatus.FINISHED" class="import-finished"> <div v-if="importStatus === ImportStatus.FINISHED" class="import-finished">
<el-alert <el-alert title="导入完成" type="success" :description="`共成功导入 ${importedCount} 条数据,总计 ${totalCount} 条`" show-icon />
title="导入完成"
type="success"
:description="`共成功导入 ${importedCount} 条数据,总计 ${totalCount} 条`"
show-icon
/>
</div> </div>
<!-- 导入失败提示 --> <!-- 导入失败提示 -->
@@ -264,7 +220,7 @@ export default {
// 枚举挂载到实例,方便模板使用 // 枚举挂载到实例,方便模板使用
ImportStatus, ImportStatus,
TableColumnEnum, TableColumnEnum,
// 文件对象 // 文件对象
file: null, file: null,
// 解析后的原始数据 // 解析后的原始数据
@@ -314,7 +270,7 @@ export default {
try { try {
const response = await listWarehouse({ pageNum: 1, pageSize: 1000 }); const response = await listWarehouse({ pageNum: 1, pageSize: 1000 });
const map = {}; const map = {};
for (let item of response.data) { for (let item of response.data) {
map[item.warehouseName] = item.warehouseId; map[item.warehouseName] = item.warehouseId;
} }
@@ -503,8 +459,8 @@ export default {
// 二次确认,防止误操作 // 二次确认,防止误操作
const confirm = await this.$confirm( const confirm = await this.$confirm(
'确认导入已校验通过的数据?导入过程中请勿刷新页面或关闭浏览器!', '确认导入已校验通过的数据?导入过程中请勿刷新页面或关闭浏览器!',
'导入确认', '导入确认',
{ {
confirmButtonText: '确认导入', confirmButtonText: '确认导入',
cancelButtonText: '取消', cancelButtonText: '取消',
@@ -555,6 +511,7 @@ export default {
throw new Error(`${row.rowNum}行导入失败:${error.message}`); throw new Error(`${row.rowNum}行导入失败:${error.message}`);
} }
} }
this.$emit('finish', this.importedCount);
}, },
/** /**
@@ -576,8 +533,8 @@ export default {
itemType, itemType,
materialType: row.type, materialType: row.type,
warehouseId: this.warehouseMap[row.logicWarehouse], warehouseId: this.warehouseMap[row.logicWarehouse],
enterCoilNo: row.inboundCoilNo, enterCoilNo: 'G' + row.inboundCoilNo,
currentCoilNo: row.inboundCoilNo, currentCoilNo: 'G' + row.inboundCoilNo,
supplierCoilNo: row.factoryCoilNo, supplierCoilNo: row.factoryCoilNo,
grossWeight: row.weight, grossWeight: row.weight,
netWeight: row.weight, netWeight: row.weight,
@@ -593,7 +550,7 @@ export default {
// 3. 插入待处理操作 // 3. 插入待处理操作
const actionParams = { const actionParams = {
coilId, coilId,
currentCoilNo: row.inboundCoilNo, currentCoilNo: 'G' + row.inboundCoilNo,
actionStatus: SystemConstant.PENDING_ACTION_STATUS, actionStatus: SystemConstant.PENDING_ACTION_STATUS,
itemType, itemType,
itemId, itemId,
@@ -606,7 +563,6 @@ export default {
if (actionRes.code !== 200) { if (actionRes.code !== 200) {
throw new Error(`待处理操作插入失败:${actionRes.message || '接口返回异常'}`); throw new Error(`待处理操作插入失败:${actionRes.message || '接口返回异常'}`);
} }
} catch (error) { } catch (error) {
throw new Error(error.message); throw new Error(error.message);
} }
@@ -632,8 +588,8 @@ export default {
}; };
// 执行查询 // 执行查询
const res = itemType === 'raw_material' const res = itemType === 'raw_material'
? await listRawMaterial(queryParams) ? await listRawMaterial(queryParams)
: await listProduct(queryParams); : await listProduct(queryParams);
// 空值判断函数 // 空值判断函数
@@ -672,8 +628,8 @@ export default {
// 有数据时二次确认,防止误清空 // 有数据时二次确认,防止误清空
if (this.file || this.tableData.length > 0 || this.errorList.length > 0) { if (this.file || this.tableData.length > 0 || this.errorList.length > 0) {
const confirm = await this.$confirm( const confirm = await this.$confirm(
'确认重置所有状态?已选择的文件、解析的数据和校验结果将被清空!', '确认重置所有状态?已选择的文件、解析的数据和校验结果将被清空!',
'重置确认', '重置确认',
{ {
confirmButtonText: '确认重置', confirmButtonText: '确认重置',
cancelButtonText: '取消', cancelButtonText: '取消',
@@ -729,7 +685,8 @@ export default {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 10px; gap: 10px;
flex-wrap: wrap; /* 适配小屏幕 */ flex-wrap: wrap;
/* 适配小屏幕 */
} }
.file-upload-area.disabled { .file-upload-area.disabled {

View File

@@ -45,7 +45,8 @@
<el-table v-loading="loading" border :data="deliveryWaybillList" highlight-current-row> <el-table v-loading="loading" border :data="deliveryWaybillList" highlight-current-row>
<el-table-column label="钢卷号" align="center" prop="currentCoilNo" :show-overflow-tooltip="true"> <el-table-column label="钢卷号" align="center" prop="currentCoilNo" :show-overflow-tooltip="true">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag type="info" size="small">{{ scope.row.currentCoilNo }}</el-tag> <CoilNo :coil-no="scope.row.currentCoilNo" />
<!-- <el-tag type="info" size="small">{{ scope.row.currentCoilNo }}</el-tag> -->
</template> </template>
</el-table-column> </el-table-column>
@@ -142,13 +143,15 @@ import { listDeliveryPlan } from '@/api/wms/deliveryPlan'
import MemoInput from "@/components/MemoInput"; import MemoInput from "@/components/MemoInput";
import ImportGuide from "@/views/wms/receive/components/ImportGuide.vue"; import ImportGuide from "@/views/wms/receive/components/ImportGuide.vue";
import ActualWarehouseSelect from "@/components/KLPService/ActualWarehouseSelect"; import ActualWarehouseSelect from "@/components/KLPService/ActualWarehouseSelect";
import CoilNo from "@/components/KLPService/Renderer/CoilNo.vue";
export default { export default {
name: "DeliveryWaybill", name: "DeliveryWaybill",
components: { components: {
MemoInput, MemoInput,
ImportGuide, ImportGuide,
ActualWarehouseSelect ActualWarehouseSelect,
CoilNo
}, },
data() { data() {
return { return {