feat(分卷): 实现镀锌工序特殊分卷功能
新增特殊分卷功能,包括分步分条界面、API接口及状态管理。主要修改: 1. 添加分步分条组件,支持新增、编辑、删除分条 2. 扩展分卷API接口,包括开始/完成/取消特殊分卷 3. 优化操作按钮加载状态和错误处理 4. 调整界面布局和样式
This commit is contained in:
@@ -238,4 +238,68 @@ export function restoreMaterialCoil(coilId) {
|
||||
url: '/wms/materialCoil/rollback/' + coilId,
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始分条,锁定钢卷
|
||||
*/
|
||||
export function startSpecialSplit(coilId) {
|
||||
if (!coilId) {
|
||||
return Promise.reject(new Error('coilId is required'))
|
||||
}
|
||||
return request({
|
||||
url: '/wms/materialCoil/specialSplit/start',
|
||||
method: 'post',
|
||||
params: {
|
||||
coilId
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个分条
|
||||
*/
|
||||
export function createSpecialChild(parentCoilId, pendingActionId, data) {
|
||||
return request({
|
||||
url: '/wms/materialCoil/specialSplit/createChild',
|
||||
method: 'post',
|
||||
data: data,
|
||||
params: {
|
||||
parentCoilId,
|
||||
pendingActionId
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 完成分卷操作
|
||||
*/
|
||||
export function completeSpecialSplit(pendingActionId) {
|
||||
if (!pendingActionId) {
|
||||
return Promise.reject(new Error('pendingActionId is required'))
|
||||
}
|
||||
return request({
|
||||
url: '/wms/materialCoil/specialSplit/complete',
|
||||
method: 'post',
|
||||
params: {
|
||||
pendingActionId
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消镀锌分卷
|
||||
*/
|
||||
export function cancelSpecialSplit(pendingActionId) {
|
||||
if (!pendingActionId) {
|
||||
return Promise.reject(new Error('pendingActionId is required'))
|
||||
}
|
||||
return request({
|
||||
url: '/wms/materialCoil/specialSplit/cancel',
|
||||
method: 'post',
|
||||
params: {
|
||||
pendingActionId
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -1359,6 +1359,7 @@ body {
|
||||
border-bottom: 1px solid $--border-color-lighter;
|
||||
// background: $--metal-gradient-dark;
|
||||
color: $--color-text-primary; // 白色标题
|
||||
margin-bottom: 0px;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ export default {
|
||||
components: { iframeToggle },
|
||||
computed: {
|
||||
cachedViews() {
|
||||
console.log(this.$store.state.tagsView.cachedViews)
|
||||
// console.log(this.$store.state.tagsView.cachedViews)
|
||||
return this.$store.state.tagsView.cachedViews
|
||||
},
|
||||
key() {
|
||||
|
||||
@@ -415,6 +415,7 @@ export default {
|
||||
// 特殊处理:发货和移库操作不需要跳转
|
||||
if (actionType === 4 || actionType === 5 || actionType === 401 || actionType === 402) {
|
||||
this.$message.info(actionType === 4 ? '发货操作已在移动端完成' : '移库操作已在移动端完成');
|
||||
this.buttonLoading = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -429,13 +430,19 @@ export default {
|
||||
else if (actionType == 200) {
|
||||
path = '/wms/merge';
|
||||
}
|
||||
else if (actionType < 100) {
|
||||
path = '/wms/typing';
|
||||
}
|
||||
// 其他操作类型
|
||||
else {
|
||||
path = '/wms/typing';
|
||||
this.$message.error('特殊操作请到专门的页面进行处理');
|
||||
this.buttonLoading = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!path) {
|
||||
this.$message.error('未知的操作类型: ' + row.actionType);
|
||||
this.buttonLoading = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -462,7 +469,9 @@ export default {
|
||||
}).catch(error => {
|
||||
console.error('更新状态失败:', error);
|
||||
this.$message.error('更新状态失败: ' + (error.message || error));
|
||||
})
|
||||
}).finally(() => {
|
||||
this.buttonLoading = false;
|
||||
});
|
||||
},
|
||||
/** 取消操作 */
|
||||
handleCancel(row) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<DoPage :label="actionType" :tabs="tabs" />
|
||||
<DoPage :label="actionType" :tabs="tabs" :useSpecialSplit="useSpecialSplit" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -14,6 +14,7 @@
|
||||
return {
|
||||
actionType: '分卷',
|
||||
tabs: [],
|
||||
useSpecialSplit: false,
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -53,6 +54,10 @@
|
||||
{value: '1988151132361519105', label: '镀铬成品库'},
|
||||
],
|
||||
}
|
||||
|
||||
if (this.actionType === '镀锌工序') {
|
||||
this.useSpecialSplit = true
|
||||
}
|
||||
// 从map中获取默认的查询参数
|
||||
const defaultWarehouseIds = map[this.actionType] || []
|
||||
console.log(defaultWarehouseIds, 'defaultWarehouseIds')
|
||||
|
||||
@@ -167,7 +167,8 @@
|
||||
|
||||
<i class="el-icon-view param-icon" @click="handlePreviewLabel(item)" title="查看标签"></i>
|
||||
<!-- <el-button style="margin-left: 0px; padding: 4px !important;" type="text" size="mini" @click="handlePreviewLabel(item)" title="查看标签">预览</el-button> -->
|
||||
<el-button style="margin-left: 0px; padding: 4px !important;" type="text" size="mini" @click="handlePrintLabel(item)" title="打印标签">打印</el-button>
|
||||
<el-button v-loading="buttonLoading" style="margin-left: 0px; padding: 4px !important;" type="text"
|
||||
size="mini" @click="handlePrintLabel(item)" title="打印标签">打印</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -196,15 +197,15 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-button style="position: absolute; bottom: 10px; right: 10px;" type="success" icon="el-icon-scissors" size="mini" @click="handleStartSplit(item)"
|
||||
:loading="item.picking" class="action-btn">分条</el-button>
|
||||
<el-button style="position: absolute; bottom: 10px; right: 10px;" type="success" icon="el-icon-scissors"
|
||||
size="mini" @click="handleStartSplit(item)" :loading="buttonLoading" class="action-btn">分条</el-button>
|
||||
</div>
|
||||
|
||||
<div class="card-footer">
|
||||
<el-button type="primary" icon="el-icon-check" size="mini" @click="handlePickMaterial(item)"
|
||||
:loading="item.picking" class="action-btn">领料</el-button>
|
||||
:loading="buttonLoading" class="action-btn">领料</el-button>
|
||||
<el-button type="danger" icon="el-icon-alarm-clock" :plain="item.abnormalCount == 0" size="mini"
|
||||
@click="handleAddAbnormal(item)" :loading="item.cancelling" class="action-btn">
|
||||
@click="handleAddAbnormal(item)" :loading="buttonLoading" class="action-btn">
|
||||
异常
|
||||
<span v-if="item.abnormalCount > 0">({{ item.abnormalCount }})</span>
|
||||
</el-button>
|
||||
@@ -220,9 +221,25 @@
|
||||
|
||||
<!-- 右侧:待操作列表 -->
|
||||
<el-col :span="12">
|
||||
<div v-if="useSpecialSplit" style="margin-bottom: 20px;" v-loading="stepSpilt.loading">
|
||||
<div class="section-header">
|
||||
<h3 class="section-title">进行中的镀锌工序</h3>
|
||||
<el-button size="mini" icon="el-icon-refresh" @click="getStepSplitList">刷新</el-button>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; gap: 10px;">
|
||||
<div v-for="item in stepSpilt.list" :key="item.coilId || index" style="text-align: center; padding: 10px; border: 2px solid #e4e7ed; border-radius: 4px;">
|
||||
<div class="step-item" style="font-size: 24px; font-weight: bold; ">
|
||||
<span class="step-value">{{ item.currentCoilNo }}</span>
|
||||
</div>
|
||||
<el-button type="primary" size="mini" @click="handleContinueSplit(item)">查看</el-button>
|
||||
<el-button size="mini" @click="handleCancelSplit(item)">取消操作</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section-card action-section">
|
||||
<div class="section-header">
|
||||
<h3 class="section-title">{{ label }}待操作</h3>
|
||||
<h3 class="section-title">{{ label }}操作记录</h3>
|
||||
<el-button size="mini" icon="el-icon-refresh" @click="getPendingAction">刷新</el-button>
|
||||
</div>
|
||||
|
||||
@@ -301,27 +318,32 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-footer">
|
||||
<div class="card-footer" v-if="!useSpecialSplit">
|
||||
<!-- 待处理状态显示操作按钮 -->
|
||||
<template v-if="item.actionStatus === 0">
|
||||
<el-button type="primary" icon="el-icon-edit" size="mini" @click="handleProcess(item)"
|
||||
class="action-btn">操作</el-button>
|
||||
<el-button type="danger" icon="el-icon-delete" size="mini" @click="handleDeleteAction(item)"
|
||||
class="action-btn">删除</el-button>
|
||||
<el-button :loading="buttonLoading" type="primary" icon="el-icon-edit" size="mini"
|
||||
@click="handleProcess(item)" class="action-btn">操作</el-button>
|
||||
<el-button :loading="buttonLoading" type="danger" icon="el-icon-delete" size="mini"
|
||||
@click="handleDeleteAction(item)" class="action-btn">删除</el-button>
|
||||
</template>
|
||||
<!-- 处理中状态显示继续按钮 -->
|
||||
<template v-else-if="item.actionStatus === 1">
|
||||
<el-button type="warning" icon="el-icon-edit" size="mini" @click="handleProcess(item)"
|
||||
class="action-btn">继续</el-button>
|
||||
<el-button type="info" icon="el-icon-close" size="mini" @click="handleCancel(item)"
|
||||
class="action-btn">取消</el-button>
|
||||
<el-button :loading="buttonLoading" type="warning" icon="el-icon-edit" size="mini"
|
||||
@click="handleProcess(item)" class="action-btn">继续</el-button>
|
||||
<el-button :loading="buttonLoading" type="info" icon="el-icon-close" size="mini"
|
||||
@click="handleCancel(item)" class="action-btn">取消</el-button>
|
||||
</template>
|
||||
<!-- 已完成或已取消状态显示删除按钮 -->
|
||||
<template v-else>
|
||||
<el-button type="danger" icon="el-icon-delete" size="mini" @click="handleDeleteAction(item)"
|
||||
class="action-btn">删除</el-button>
|
||||
<el-button :loading="buttonLoading" type="danger" icon="el-icon-delete" size="mini"
|
||||
@click="handleDeleteAction(item)" class="action-btn">删除</el-button>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div class="card-footer" v-else="!useSpecialSplit">
|
||||
<el-button :loading="buttonLoading" type="primary" icon="el-icon-edit" size="mini"
|
||||
@click="handleProcess(item)" class="action-btn">查看</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -371,18 +393,24 @@
|
||||
<label-render :content="labelRender.data" :labelType="labelRender.type" />
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog title="分步分条" :visible.sync="stepSpilt.visible" width="1400px" append-to-body>
|
||||
<step-split @print="handlePrintLabel" @complete="stepSpilt.visible = false" :actionId="stepSpilt.actionId"
|
||||
:coilId="stepSpilt.coilId" :actionStatus="stepSpilt.actionStatus" />
|
||||
</el-dialog>
|
||||
|
||||
<label-render ref="labelRender" v-show="false" :content="labelRender.data" :labelType="labelRender.type" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listMaterialCoil } from '@/api/wms/coil'
|
||||
import { listMaterialCoil, startSpecialSplit, cancelSpecialSplit } from '@/api/wms/coil'
|
||||
import { listPendingAction, startProcess, cancelAction, delPendingAction, addPendingAction } from '@/api/wms/pendingAction'
|
||||
import { parseTime } from '@/utils/klp'
|
||||
import ProductInfo from '@/components/KLPService/Renderer/ProductInfo'
|
||||
import RawMaterialInfo from '@/components/KLPService/Renderer/RawMaterialInfo'
|
||||
import { addCoilAbnormal } from '@/api/wms/coilAbnormal'
|
||||
import LabelRender from './LabelRender/index.vue'
|
||||
import StepSplit from './stepSplit.vue'
|
||||
|
||||
export default {
|
||||
name: 'DoPage',
|
||||
@@ -395,12 +423,17 @@ export default {
|
||||
tabs: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
useSpecialSplit: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
components: {
|
||||
ProductInfo,
|
||||
RawMaterialInfo,
|
||||
LabelRender
|
||||
LabelRender,
|
||||
StepSplit
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -434,7 +467,7 @@ export default {
|
||||
actionType: null, // 将在created中设置为酸连轧工序的actionType
|
||||
actionStatus: null
|
||||
},
|
||||
|
||||
buttonLoading: false,
|
||||
exceptionDialogVisible: false,
|
||||
exceptionForm: {
|
||||
coilId: null,
|
||||
@@ -443,6 +476,14 @@ export default {
|
||||
defectCode: null,
|
||||
degree: null,
|
||||
remark: null
|
||||
},
|
||||
stepSpilt: {
|
||||
list: [],
|
||||
loading: false,
|
||||
visible: false,
|
||||
coilId: null,
|
||||
actionId: null,
|
||||
actionStatus: null
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -492,7 +533,6 @@ export default {
|
||||
created() {
|
||||
// 立即加载物料列表(不依赖字典)
|
||||
// this.getMaterialCoil()
|
||||
|
||||
// 尝试加载待操作列表(如果字典已加载)
|
||||
this.$nextTick(() => {
|
||||
if (this.acidRollingActionType) {
|
||||
@@ -500,6 +540,7 @@ export default {
|
||||
this.getPendingAction()
|
||||
}
|
||||
})
|
||||
this.getStepSplitList()
|
||||
},
|
||||
mounted() {
|
||||
// 确保在mounted时也尝试加载(字典数据可能此时才加载完成)
|
||||
@@ -528,7 +569,21 @@ export default {
|
||||
})
|
||||
},
|
||||
|
||||
/** 预览标签 */
|
||||
getStepSplitList() {
|
||||
this.stepSpilt.loading = true
|
||||
listPendingAction({ actionType: 501, actionStatus: 0 }).then(response => {
|
||||
this.stepSpilt.list = response.rows || []
|
||||
this.stepSpilt.loading = false
|
||||
})
|
||||
},
|
||||
|
||||
handleComposeSplit() {
|
||||
this.stepSpilt.visible = false;
|
||||
this.getStepSplitList()
|
||||
this.getPendingAction()
|
||||
},
|
||||
|
||||
/** 预览标签 */
|
||||
handlePreviewLabel(row) {
|
||||
this.labelRender.visible = true;
|
||||
const item = row.itemType === 'product' ? row.product : row.rawMaterial;
|
||||
@@ -631,6 +686,19 @@ export default {
|
||||
}
|
||||
this.getPendingAction()
|
||||
},
|
||||
async handleCancelSplit(row) {
|
||||
this.$modal.confirm('是否取消分卷操作?').then(_ => {
|
||||
this.stepSpilt.loading = true
|
||||
this.buttonLoading = true
|
||||
cancelSpecialSplit(row.actionId).then(response => {
|
||||
this.$message.success('取消分卷成功')
|
||||
this.stepSpilt.loading = false
|
||||
this.buttonLoading = false
|
||||
this.getPendingAction() // 刷新待操作列表
|
||||
this.getStepSplitList()
|
||||
})
|
||||
})
|
||||
},
|
||||
/** 重置待操作搜索 */
|
||||
resetActionQuery() {
|
||||
this.resetForm('actionQueryForm')
|
||||
@@ -652,6 +720,12 @@ export default {
|
||||
return
|
||||
}
|
||||
|
||||
if (actionType === 501) {
|
||||
// 特殊分条,打开弹窗操作
|
||||
this.handleContinueSplit(row)
|
||||
return;
|
||||
}
|
||||
|
||||
// 根据操作类型跳转到不同页面
|
||||
let path = ''
|
||||
|
||||
@@ -753,6 +827,44 @@ export default {
|
||||
}
|
||||
})
|
||||
},
|
||||
handleStartSplit(row) {
|
||||
this.buttonLoading = true
|
||||
this.$modal.confirm('是否确认领料开始分条操作?')
|
||||
.then(_ => {
|
||||
this.stepSpilt.loading = true
|
||||
addPendingAction({
|
||||
coilId: row.coilId,
|
||||
currentCoilNo: row.currentCoilNo,
|
||||
actionType: 501,
|
||||
actionStatus: 0,
|
||||
sourceType: 'manual',
|
||||
priority: 0,
|
||||
}).then(_ => {
|
||||
startSpecialSplit(row.coilId).then(_ => {
|
||||
this.$message.success('分条操作已创建')
|
||||
this.stepSpilt.loading = false
|
||||
this.getPendingAction()
|
||||
// this.getMaterialCoil()
|
||||
this.getStepSplitList()
|
||||
}).finally(() => {
|
||||
this.buttonLoading = false
|
||||
})
|
||||
})
|
||||
})
|
||||
.finally(() => {
|
||||
this.buttonLoading = false
|
||||
})
|
||||
},
|
||||
handleContinueSplit(row) {
|
||||
this.stepSpilt.coilId = row.coilId
|
||||
this.stepSpilt.actionId = row.actionId
|
||||
this.stepSpilt.actionStatus = row.actionStatus
|
||||
this.stepSpilt.visible = true
|
||||
// this.buttonLoading = true
|
||||
// this.getPendingAction()
|
||||
// this.getMaterialCoil()
|
||||
// this.buttonLoading = false
|
||||
},
|
||||
cancelException() {
|
||||
// 重置表单
|
||||
this.exceptionForm = {
|
||||
@@ -855,7 +967,7 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1600px) {
|
||||
@media (min-width: 2000px) {
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,54 +1,557 @@
|
||||
<template>
|
||||
<div>
|
||||
分步分条
|
||||
<div class="split-coil-container" v-loading="loading">
|
||||
<!-- 左右分栏布局 -->
|
||||
<el-row :gutter="20">
|
||||
<!-- 左侧:钢卷信息 + 新增按钮 + 已分条列表 -->
|
||||
<el-col :span="12">
|
||||
<div class="coil-info-card">
|
||||
<el-row :gutter="20" flex justify="end">
|
||||
<!-- 新增分条按钮 -->
|
||||
<el-button type="primary" icon="el-icon-plus" @click="addSplitForm" :loading="buttonLoading"
|
||||
v-if="actionStatus != 2">
|
||||
新增分条
|
||||
</el-button>
|
||||
|
||||
<!-- 完成分条按钮 -->
|
||||
<el-button type="success" icon="el-icon-check" @click="completeSplit" :disabled="splitList.length === 0"
|
||||
:loading="buttonLoading" v-if="actionStatus != 2">
|
||||
完成整体分条
|
||||
</el-button>
|
||||
|
||||
<el-button type="primary" icon="el-icon-refresh" @click="refresh" :loading="buttonLoading">
|
||||
刷新
|
||||
</el-button>
|
||||
</el-row>
|
||||
|
||||
<el-descriptions :column="2" border title="待分条钢卷信息">
|
||||
<el-descriptions-item label="入场钢卷号">{{ coilInfo.enterCoilNo || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="当前钢卷号">{{ coilInfo.currentCoilNo || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="厂家原料卷号">{{ coilInfo.supplierCoilNo || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="所在库位">{{ coilInfo.warehouseName || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="材料类型">{{ coilInfo.materialType || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="净重">{{ coilInfo.netWeight || '-' }} kg</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<!-- 已分条钢卷列表 -->
|
||||
|
||||
<el-descriptions :column="1" border title="已分出的钢卷列表"></el-descriptions>
|
||||
<el-table v-loading="splitListLoading" :data="splitList" @row-click="handleSplitItemClick"
|
||||
highlight-current-row border stripe>
|
||||
<el-table-column prop="currentCoilNo" label="当前钢卷号" />
|
||||
<el-table-column prop="materialType" label="材料类型" />
|
||||
<el-table-column prop="dataType" label="钢卷状态">
|
||||
<template #default="scope">
|
||||
<div v-if="scope.row.status == 1">
|
||||
<el-tag type="info">已发货</el-tag>
|
||||
</div>
|
||||
<div v-else-if="scope.row.dataType == 1">
|
||||
<el-tag type="success">当前在库</el-tag>
|
||||
</div>
|
||||
<div v-else-if="scope.row.dataType == 0">
|
||||
<el-tag type="warning">历史卷</el-tag>
|
||||
</div>
|
||||
<div v-else>
|
||||
<el-tag type="danger">未知状态</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="操作" width="220">
|
||||
<template #default="scope">
|
||||
<div v-if="scope.row.dataType == 1 && scope.row.status == 0">
|
||||
<el-button @click.stop="handlePrint(scope.row)">打印</el-button>
|
||||
<el-button @click.stop="handleEditSplit(scope.row)">编辑</el-button>
|
||||
<el-button @click.stop="handleDeleteSplit(scope.row)">删除</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
<!-- 右侧:分条表单 / 分条详情 -->
|
||||
<el-col :span="12">
|
||||
<div class="split-form-card" v-if="showSplitForm">
|
||||
<el-card title="分条钢卷信息录入" shadow="hover">
|
||||
<el-form ref="splitFormRef" :model="splitForm" :rules="rules" label-width="100px" style="max-width: 800px;">
|
||||
<el-form-item label="入场钢卷号" prop="enterCoilNo">
|
||||
<el-input v-model="splitForm.enterCoilNo" placeholder="请输入入场钢卷号" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="当前钢卷号" prop="currentCoilNo">
|
||||
<el-input v-model="splitForm.currentCoilNo" placeholder="请输入当前钢卷号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="厂家原料卷号" prop="supplierCoilNo">
|
||||
<el-input v-model="splitForm.supplierCoilNo" placeholder="请输入厂家原料卷号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="所在库位" prop="warehouseId">
|
||||
<warehouse-select v-model="splitForm.warehouseId" placeholder="请选择仓库/库区/库位" style="width: 100%;"
|
||||
clearable />
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="实际库区" prop="actualWarehouseId">
|
||||
<actual-warehouse-select
|
||||
v-model="splitForm.actualWarehouseId"
|
||||
:clearInput="splitForm.coilId != null"
|
||||
placeholder="请选择实际库区"
|
||||
style="width: 100%;"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item> -->
|
||||
<el-form-item label="班组" prop="team">
|
||||
<el-select v-model="splitForm.team" placeholder="请选择班组" style="width: 100%">
|
||||
<el-option key="甲" label="甲" value="甲" />
|
||||
<el-option key="乙" label="乙" value="乙" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="材料类型" prop="materialType">
|
||||
<el-select v-model="splitForm.materialType" placeholder="请选择材料类型" @change="handleMaterialTypeChange">
|
||||
<el-option label="成品" value="成品" />
|
||||
<el-option label="原料" value="原料" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="getItemLabel" prop="itemId">
|
||||
<product-select v-if="splitForm.itemType === 'product'" v-model="splitForm.itemId" placeholder="请选择成品"
|
||||
style="width: 100%;" clearable />
|
||||
<raw-material-select v-else-if="splitForm.itemType === 'raw_material'" v-model="splitForm.itemId"
|
||||
placeholder="请选择原料" style="width: 100%;" clearable />
|
||||
<div v-else>请先选择材料类型</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="质量状态" prop="qualityStatus">
|
||||
<el-select v-model="splitForm.qualityStatus" placeholder="请选择质量状态" style="width: 100%">
|
||||
<el-option v-for="item in dict.type.coil_quality_status" :key="item.value" :label="item.label"
|
||||
:value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="切边要求" prop="trimmingRequirement">
|
||||
<el-select v-model="splitForm.trimmingRequirement" placeholder="请选择切边要求" style="width: 100%">
|
||||
<el-option label="净边料" value="净边料" />
|
||||
<el-option label="毛边料" value="毛边料" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="打包状态" prop="packingStatus">
|
||||
<el-input v-model="splitForm.packingStatus" placeholder="请输入打包状态" />
|
||||
</el-form-item>
|
||||
<el-form-item label="包装要求" prop="packagingRequirement">
|
||||
<el-select v-model="splitForm.packagingRequirement" placeholder="请选择包装要求" style="width: 100%">
|
||||
<el-option label="裸包" value="裸包" />
|
||||
<el-option label="普包" value="普包" />
|
||||
<el-option label="简包" value="简包" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="毛重" prop="grossWeight">
|
||||
<el-input v-model="splitForm.grossWeight" placeholder="请输入毛重" type="number" />
|
||||
</el-form-item>
|
||||
<el-form-item label="净重" prop="netWeight">
|
||||
<el-input v-model="splitForm.netWeight" placeholder="请输入净重" type="number" />
|
||||
</el-form-item>
|
||||
<el-form-item label="长度" prop="length">
|
||||
<el-input v-model="splitForm.length" placeholder="请输入长度" type="number" />
|
||||
</el-form-item>
|
||||
<el-form-item label="调制度" prop="temperGrade">
|
||||
<el-input v-model="splitForm.temperGrade" placeholder="请输入调制度" />
|
||||
</el-form-item>
|
||||
<el-form-item label="镀层种类" prop="coatingType">
|
||||
<el-input v-model="splitForm.coatingType" placeholder="请输入镀层种类" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="splitForm.remark" placeholder="请输入备注" type="textarea" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button :loading="buttonLoading" type="primary" @click="addSplit">提交分条</el-button>
|
||||
<el-button :loading="buttonLoading" @click="resetSplitForm">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
<!-- 分条钢卷详情(选中列表项时显示) -->
|
||||
<div class="split-detail-card" v-else-if="selectedSplitItem">
|
||||
<el-card title="分条钢卷详情" shadow="hover">
|
||||
<!-- <el-button type="primary" @click="handlePrint(selectedSplitItem)">打印</el-button> -->
|
||||
<el-descriptions :column="2" border size="large">
|
||||
<el-descriptions-item label="入场钢卷号">{{ selectedSplitItem.enterCoilNo || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="当前钢卷号">{{ selectedSplitItem.currentCoilNo || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="厂家原料卷号">{{ selectedSplitItem.supplierCoilNo || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="逻辑库位">{{ selectedSplitItem.warehouseName || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="实际库区">{{ selectedSplitItem.actualWarehouseName || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="班组">{{ selectedSplitItem.team || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="材料类型">{{ selectedSplitItem.materialType || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="产品/原料">{{ selectedSplitItem.itemName || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="质量状态">{{ selectedSplitItem.qualityStatus || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="切边要求">{{ selectedSplitItem.trimmingRequirement || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="打包状态">{{ selectedSplitItem.packingStatus || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="包装要求">{{ selectedSplitItem.packagingRequirement || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="毛重">{{ selectedSplitItem.grossWeight || '-' }} kg</el-descriptions-item>
|
||||
<el-descriptions-item label="净重">{{ selectedSplitItem.netWeight || '-' }} kg</el-descriptions-item>
|
||||
<el-descriptions-item label="长度" v-if="selectedSplitItem.length">{{ selectedSplitItem.length }}
|
||||
m</el-descriptions-item>
|
||||
<el-descriptions-item label="调制度">{{ selectedSplitItem.temperGrade || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="镀层种类">{{ selectedSplitItem.coatingType || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="备注" :span="2">{{ selectedSplitItem.remark || '-' }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
<!-- 初始提示 -->
|
||||
<div class="empty-tip" v-else>
|
||||
<el-empty description="请选择左侧已分条钢卷查看详情,或点击「新增分条」创建新分条"></el-empty>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getMaterialCoil, listMaterialCoil } from '@/api/wms/coil'
|
||||
import { completeAction } from '@/api/wms/pendingAction'
|
||||
import { getMaterialCoil, listMaterialCoil, createSpecialChild, completeSpecialSplit, updateMaterialCoilSimple, checkCoilNo, delMaterialCoil } from '@/api/wms/coil'
|
||||
import { completeAction, getPendingAction, updatePendingAction } from '@/api/wms/pendingAction'
|
||||
import ProductSelect from "@/components/KLPService/ProductSelect";
|
||||
import RawMaterialSelect from "@/components/KLPService/RawMaterialSelect";
|
||||
import WarehouseSelect from "@/components/KLPService/WarehouseSelect";
|
||||
import ActualWarehouseSelect from "@/components/KLPService/ActualWarehouseSelect";
|
||||
|
||||
export default {
|
||||
name: 'StepSplit',
|
||||
props: {
|
||||
actionId: {
|
||||
type: String,
|
||||
required: true,
|
||||
export default {
|
||||
name: 'StepSplit',
|
||||
props: {
|
||||
actionId: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
coilId: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
actionStatus: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
ProductSelect,
|
||||
RawMaterialSelect,
|
||||
WarehouseSelect,
|
||||
ActualWarehouseSelect,
|
||||
},
|
||||
dicts: ['coil_quality_status'],
|
||||
data() {
|
||||
return {
|
||||
// 待分条钢卷基础信息
|
||||
coilInfo: {},
|
||||
loading: false,
|
||||
// 分条表单数据
|
||||
splitForm: {
|
||||
coilId: '', // 分条钢卷ID(编辑时赋值)
|
||||
enterCoilNo: '',
|
||||
currentCoilNo: '',
|
||||
supplierCoilNo: '',
|
||||
warehouseId: '',
|
||||
actualWarehouseId: '',
|
||||
team: '',
|
||||
materialType: '',
|
||||
itemType: '', // product/raw_material
|
||||
itemId: '',
|
||||
qualityStatus: '',
|
||||
trimmingRequirement: '',
|
||||
packingStatus: '',
|
||||
packagingRequirement: '',
|
||||
grossWeight: '',
|
||||
netWeight: '',
|
||||
length: '',
|
||||
temperGrade: '',
|
||||
coatingType: '',
|
||||
remark: '',
|
||||
},
|
||||
coilId: {
|
||||
type: String,
|
||||
required: true,
|
||||
// 已分条钢卷列表
|
||||
splitList: [],
|
||||
// 列表加载状态
|
||||
splitListLoading: false,
|
||||
// 选中的分条项(用于显示详情)
|
||||
selectedSplitItem: null,
|
||||
// 是否显示分条表单
|
||||
showSplitForm: false,
|
||||
// 表单验证规则
|
||||
rules: {
|
||||
currentCoilNo: [
|
||||
{ required: true, message: "当前钢卷号不能为空", trigger: "blur" },
|
||||
// 仅在新增的时候校验
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
// 没有coilId则为新增 触发校验
|
||||
checkCoilNo({ currentCoilNo: value, coilId: this.splitForm.coilId }).then(res => {
|
||||
const { duplicateType } = res.data;
|
||||
if (duplicateType === 'current' || duplicateType === 'both') {
|
||||
// alert('当前钢卷号重复,请重新输入');
|
||||
callback(new Error('当前钢卷号重复,请重新输入'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
})
|
||||
}, trigger: 'blur'
|
||||
}
|
||||
],
|
||||
materialType: [{ required: true, message: '请选择材料类型', trigger: 'change' }],
|
||||
itemId: [{ required: true, message: '请选择成品/原料', trigger: 'change' }],
|
||||
netWeight: [{ required: true, message: '请输入净重', trigger: 'blur' }],
|
||||
warehouseId: [{ required: true, message: '请选择所在库位', trigger: 'change' }],
|
||||
},
|
||||
buttonLoading: false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 动态获取成品/原料标签
|
||||
getItemLabel() {
|
||||
return this.splitForm.itemType === 'product' ? '成品' : this.splitForm.itemType === 'raw_material' ? '原料' : '材料项'
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
coilId: {
|
||||
immediate: true, // 初始化时立即执行
|
||||
async handler(val) {
|
||||
if (val) {
|
||||
this.loading = true
|
||||
await this.getCoilInfo()
|
||||
await this.getSplitList()
|
||||
this.loading = false
|
||||
// 更新父钢卷ID
|
||||
this.splitForm.parentCoilId = val
|
||||
}
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
actionId: {
|
||||
immediate: true,
|
||||
handler(val) {
|
||||
// 若actionId变化需要重新加载数据,可在此补充逻辑
|
||||
},
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
// 查询待分条的钢卷信息
|
||||
async getCoilInfo() {
|
||||
try {
|
||||
const res = await getMaterialCoil(this.coilId)
|
||||
if (res.code === 200) {
|
||||
this.coilInfo = res.data || {}
|
||||
} else {
|
||||
this.$message.error('查询钢卷信息失败:' + res.msg)
|
||||
}
|
||||
} catch (error) {
|
||||
this.$message.error('查询钢卷信息异常:' + error.message)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 查询待分条的钢卷信息
|
||||
async getCoilInfo() {
|
||||
|
||||
},
|
||||
|
||||
// 查询钢卷的已分条列表
|
||||
async getSplitList() {
|
||||
|
||||
},
|
||||
async handlePrint(row) {
|
||||
this.$emit('print', row)
|
||||
},
|
||||
|
||||
// 新增一个分条表单
|
||||
async addSplitForm() {
|
||||
|
||||
},
|
||||
async handleDeleteSplit(row) {
|
||||
this.$modal.confirm('确认删除该分卷吗?').then(async () => {
|
||||
try {
|
||||
await delMaterialCoil(row.coilId)
|
||||
this.$message.success('删除成功')
|
||||
// 刷新钢卷信息
|
||||
this.refresh()
|
||||
} catch (error) {
|
||||
this.$message.error('删除失败:' + error.message)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 新增一个分条
|
||||
async addSplit() {
|
||||
|
||||
},
|
||||
// 刷新分条列表
|
||||
async refresh() {
|
||||
this.loading = true
|
||||
await this.getSplitList()
|
||||
await this.getCoilInfo()
|
||||
this.loading = false
|
||||
},
|
||||
|
||||
// 完成整体分条
|
||||
async completeSplit() {
|
||||
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
// 查询钢卷的已分条列表
|
||||
async getSplitList() {
|
||||
this.splitListLoading = true
|
||||
try {
|
||||
if (!this.actionId) {
|
||||
return
|
||||
}
|
||||
const action = await getPendingAction(this.actionId)
|
||||
const coilIds = action.data.remark;
|
||||
console.log('coilIds', coilIds)
|
||||
if (!coilIds) {
|
||||
this.splitList = []
|
||||
return
|
||||
}
|
||||
const res = await listMaterialCoil({
|
||||
coilIds
|
||||
})
|
||||
this.splitList = res.rows || []
|
||||
updatePendingAction({
|
||||
actionId: action.data.actionId,
|
||||
actionStatus: action.data.actionStatus,
|
||||
actionType: action.data.actionType,
|
||||
coilId: action.data.coilId,
|
||||
currentCoilNo: action.data.currentCoilNo,
|
||||
remark: res.rows.map(item => item.coilId).join(','),
|
||||
})
|
||||
} catch (error) {
|
||||
this.$message.error('查询分条列表异常:' + error.message)
|
||||
} finally {
|
||||
this.splitListLoading = false
|
||||
}
|
||||
},
|
||||
|
||||
// 新增一个分条表单(重置表单并显示)
|
||||
async addSplitForm() {
|
||||
this.showSplitForm = true
|
||||
this.selectedSplitItem = null
|
||||
this.resetSplitForm()
|
||||
this.splitForm.enterCoilNo = this.coilInfo.enterCoilNo || ''
|
||||
},
|
||||
|
||||
// 重置分条表单
|
||||
resetSplitForm() {
|
||||
this.$refs.splitFormRef?.resetFields()
|
||||
this.splitForm = {
|
||||
coilId: undefined,
|
||||
enterCoilNo: '',
|
||||
currentCoilNo: '',
|
||||
supplierCoilNo: '',
|
||||
warehouseId: '',
|
||||
actualWarehouseId: '',
|
||||
team: '',
|
||||
materialType: '',
|
||||
itemType: '',
|
||||
itemId: '',
|
||||
qualityStatus: '',
|
||||
trimmingRequirement: '',
|
||||
packingStatus: '',
|
||||
packagingRequirement: '',
|
||||
grossWeight: '',
|
||||
netWeight: '',
|
||||
length: '',
|
||||
temperGrade: '',
|
||||
coatingType: '',
|
||||
remark: '',
|
||||
parentCoilId: this.coilId,
|
||||
}
|
||||
},
|
||||
|
||||
// 材料类型变更处理
|
||||
handleMaterialTypeChange(val) {
|
||||
// 根据材料类型设置itemType
|
||||
this.splitForm.itemType = val === '成品' ? 'product' : val === '原料' ? 'raw_material' : ''
|
||||
},
|
||||
|
||||
// 选中分条列表项(显示详情)
|
||||
handleSplitItemClick(row) {
|
||||
this.selectedSplitItem = row
|
||||
this.showSplitForm = false
|
||||
},
|
||||
|
||||
// 编辑分条项
|
||||
async handleEditSplit(row) {
|
||||
this.showSplitForm = true
|
||||
this.selectedSplitItem = null
|
||||
// 赋值表单数据
|
||||
this.splitForm = { ...row }
|
||||
// 同步材料类型和长度显示状态
|
||||
this.handleMaterialTypeChange(row.materialType)
|
||||
},
|
||||
|
||||
// 新增/编辑分条
|
||||
async addSplit() {
|
||||
try {
|
||||
// 表单验证
|
||||
const valid = await this.$refs.splitFormRef.validate()
|
||||
if (!valid) {
|
||||
return
|
||||
}
|
||||
// 区分新增/编辑:有coilId则为编辑,否则为新增
|
||||
let res
|
||||
this.buttonLoading = true
|
||||
if (this.splitForm.coilId) {
|
||||
// 编辑分条:调用更新接口
|
||||
res = await updateMaterialCoilSimple(this.splitForm)
|
||||
} else {
|
||||
// 新增分条:调用创建接口
|
||||
res = await createSpecialChild(this.coilId, this.actionId, this.splitForm)
|
||||
}
|
||||
|
||||
this.$message.success(this.splitForm.coilId ? '编辑分条成功' : '新增分条成功')
|
||||
// 重置表单
|
||||
this.resetSplitForm()
|
||||
this.showSplitForm = false
|
||||
// 刷新分条列表
|
||||
this.getSplitList()
|
||||
} catch (error) {
|
||||
// 表单验证失败时的提示
|
||||
if (error.name !== 'ValidationError') {
|
||||
this.$message.error((this.splitForm.coilId ? '编辑' : '新增') + '分条异常:' + error.message)
|
||||
}
|
||||
} finally {
|
||||
this.buttonLoading = false
|
||||
}
|
||||
},
|
||||
|
||||
// 完成整体分条
|
||||
async completeSplit() {
|
||||
this.$confirm('确认完成整体分条操作?完成后将无法修改分条信息', '提示', {
|
||||
confirmButtonText: '确认',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}).then(async () => {
|
||||
try {
|
||||
this.buttonLoading = true
|
||||
|
||||
// 1. 完成分条主流程
|
||||
const splitRes = await completeSpecialSplit(this.actionId)
|
||||
if (splitRes.code !== 200) {
|
||||
this.$message.error('完成分条失败:' + splitRes.msg)
|
||||
return
|
||||
}
|
||||
|
||||
// 2. 完成待办动作(根据业务逻辑调整)
|
||||
const actionRes = await completeAction(this.actionId)
|
||||
if (actionRes.code !== 200) {
|
||||
this.$message.error('完成待办动作失败:' + actionRes.msg)
|
||||
return
|
||||
}
|
||||
this.buttonLoading = false
|
||||
|
||||
this.$message.success('分条操作已完成')
|
||||
// 通知父组件(如需要)
|
||||
this.$emit('complete')
|
||||
} catch (error) {
|
||||
if (error.message !== 'cancel') { // 排除取消确认的情况
|
||||
this.$message.error('完成分条异常:' + error.message)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.split-coil-container {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.coil-info-card {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.split-form-card,
|
||||
.split-detail-card {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.empty-tip {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
min-height: 400px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user