添加web的合卷分卷合并操作
This commit is contained in:
@@ -14,7 +14,7 @@ export function exportMaterialCoil(query) {
|
||||
url: '/wms/materialCoil/export',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export function getMaterialCoil(CoilMaterialId) {
|
||||
@@ -83,3 +83,21 @@ export function getMaterialCoilDistributionByType(query) {
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 钢卷分卷
|
||||
export function splitMaterialCoil(data) {
|
||||
return request({
|
||||
url: '/wms/materialCoil',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 钢卷合卷
|
||||
export function mergeMaterialCoil(data) {
|
||||
return request({
|
||||
url: '/wms/materialCoil',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
86
klp-ui/src/api/wms/pendingAction.js
Normal file
86
klp-ui/src/api/wms/pendingAction.js
Normal file
@@ -0,0 +1,86 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询钢卷待操作列表
|
||||
export function listPendingAction(query) {
|
||||
return request({
|
||||
url: '/wms/coilPendingAction/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询钢卷待操作详细
|
||||
export function getPendingAction(actionId) {
|
||||
return request({
|
||||
url: '/wms/coilPendingAction/' + actionId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增钢卷待操作
|
||||
export function addPendingAction(data) {
|
||||
return request({
|
||||
url: '/wms/coilPendingAction',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改钢卷待操作
|
||||
export function updatePendingAction(data) {
|
||||
return request({
|
||||
url: '/wms/coilPendingAction',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除钢卷待操作
|
||||
export function delPendingAction(actionId) {
|
||||
return request({
|
||||
url: '/wms/coilPendingAction/' + actionId,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 更新操作状态
|
||||
export function updateStatus(actionId, status) {
|
||||
return request({
|
||||
url: `/wms/coilPendingAction/status/${actionId}/${status}`,
|
||||
method: 'put'
|
||||
})
|
||||
}
|
||||
|
||||
// 开始处理操作
|
||||
export function startProcess(actionId) {
|
||||
return request({
|
||||
url: `/wms/coilPendingAction/start/${actionId}`,
|
||||
method: 'put'
|
||||
})
|
||||
}
|
||||
|
||||
// 完成操作
|
||||
export function completeAction(actionId) {
|
||||
return request({
|
||||
url: `/wms/coilPendingAction/complete/${actionId}`,
|
||||
method: 'put'
|
||||
})
|
||||
}
|
||||
|
||||
// 取消操作
|
||||
export function cancelAction(actionId) {
|
||||
return request({
|
||||
url: `/wms/coilPendingAction/cancel/${actionId}`,
|
||||
method: 'put'
|
||||
})
|
||||
}
|
||||
|
||||
// 导出钢卷待操作
|
||||
export function exportPendingAction(query) {
|
||||
return request({
|
||||
url: '/wms/coilPendingAction/export',
|
||||
method: 'post',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,538 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 搜索栏 -->
|
||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="80px">
|
||||
<el-form-item label="钢卷号" prop="currentCoilNo">
|
||||
<el-input
|
||||
v-model="queryParams.currentCoilNo"
|
||||
placeholder="请输入钢卷号"
|
||||
clearable
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="操作类型" prop="actionType">
|
||||
<el-select v-model="queryParams.actionType" placeholder="请选择操作类型">
|
||||
<el-option v-for="item in dict.type.action_type" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<!-- 工具栏 -->
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
icon="el-icon-plus"
|
||||
size="mini"
|
||||
@click="handleAdd"
|
||||
>新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
icon="el-icon-delete"
|
||||
size="mini"
|
||||
:disabled="multiple"
|
||||
@click="handleDelete"
|
||||
>删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="warning"
|
||||
plain
|
||||
icon="el-icon-refresh"
|
||||
size="mini"
|
||||
@click="handleRefresh"
|
||||
>刷新</el-button>
|
||||
</el-col>
|
||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="actionList"
|
||||
@selection-change="handleSelectionChange"
|
||||
:row-class-name="tableRowClassName"
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="序号" type="index" width="60" align="center" />
|
||||
|
||||
<el-table-column label="钢卷号" align="center" prop="currentCoilNo" width="140" :show-overflow-tooltip="true">
|
||||
<template slot-scope="scope">
|
||||
<el-tag type="info" size="small">{{ scope.row.currentCoilNo }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="操作类型" align="center" prop="actionType" width="100">
|
||||
<template slot-scope="scope">
|
||||
<dict-tag :options="dict.type.action_type" :value="scope.row.actionType"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="操作状态" align="center" prop="actionStatus" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-tag v-if="scope.row.actionStatus === 0" type="info" size="small">待处理</el-tag>
|
||||
<el-tag v-else-if="scope.row.actionStatus === 1" type="warning" size="small">处理中</el-tag>
|
||||
<el-tag v-else-if="scope.row.actionStatus === 2" type="success" size="small">已完成</el-tag>
|
||||
<el-tag v-else-if="scope.row.actionStatus === 3" type="danger" size="small">已取消</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="优先级" align="center" prop="priority" width="90">
|
||||
<template slot-scope="scope">
|
||||
<el-tag v-if="scope.row.priority === 0" type="info" size="mini">普通</el-tag>
|
||||
<el-tag v-else-if="scope.row.priority === 1" type="warning" size="mini">重要</el-tag>
|
||||
<el-tag v-else-if="scope.row.priority === 2" type="danger" size="mini">紧急</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="来源" align="center" prop="sourceType" width="80">
|
||||
<template slot-scope="scope">
|
||||
<el-tag v-if="scope.row.sourceType === 'scan'" type="success" size="mini">
|
||||
<i class="el-icon-mobile"></i> 扫码
|
||||
</el-tag>
|
||||
<el-tag v-else type="info" size="mini">
|
||||
<i class="el-icon-edit-outline"></i> 手动
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="扫码时间" align="center" prop="scanTime" width="155" :show-overflow-tooltip="true">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.scanTime, '{y}-{m}-{d} {h}:{i}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="操作人" align="center" prop="operatorName" width="100" />
|
||||
|
||||
<el-table-column label="处理时间" align="center" prop="processTime" width="155" :show-overflow-tooltip="true">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.processTime, '{y}-{m}-{d} {h}:{i}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" />
|
||||
|
||||
<el-table-column label="操作" align="center" width="200" class-name="small-padding fixed-width" fixed="right">
|
||||
<template slot-scope="scope">
|
||||
<!-- 待处理状态显示操作按钮 -->
|
||||
<template v-if="scope.row.actionStatus === 0">
|
||||
<el-button
|
||||
size="mini"
|
||||
type="primary"
|
||||
icon="el-icon-edit"
|
||||
@click="handleProcess(scope.row)"
|
||||
>操作</el-button>
|
||||
<el-button
|
||||
size="mini"
|
||||
type="danger"
|
||||
icon="el-icon-delete"
|
||||
@click="handleDelete(scope.row)"
|
||||
>删除</el-button>
|
||||
</template>
|
||||
<!-- 处理中状态显示继续按钮 -->
|
||||
<template v-else-if="scope.row.actionStatus === 1">
|
||||
<el-button
|
||||
size="mini"
|
||||
type="warning"
|
||||
icon="el-icon-edit"
|
||||
@click="handleProcess(scope.row)"
|
||||
>继续</el-button>
|
||||
<el-button
|
||||
size="mini"
|
||||
type="info"
|
||||
icon="el-icon-close"
|
||||
@click="handleCancel(scope.row)"
|
||||
>取消</el-button>
|
||||
</template>
|
||||
<!-- 已完成或已取消状态显示删除按钮 -->
|
||||
<template v-else>
|
||||
<el-button
|
||||
size="mini"
|
||||
type="danger"
|
||||
icon="el-icon-delete"
|
||||
@click="handleDelete(scope.row)"
|
||||
>删除</el-button>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-show="total>0"
|
||||
:total="total"
|
||||
:page.sync="queryParams.pageNum"
|
||||
:limit.sync="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
|
||||
<!-- 添加或修改对话框 -->
|
||||
<el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
|
||||
<el-form-item label="钢卷" prop="coilId">
|
||||
<el-button size="small" @click="showCoilSelector">
|
||||
<i class="el-icon-search"></i> 选择钢卷
|
||||
</el-button>
|
||||
<span v-if="form.currentCoilNo" style="margin-left: 10px;">
|
||||
<el-tag type="info">{{ form.currentCoilNo }}</el-tag>
|
||||
</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="操作类型" prop="actionType">
|
||||
<el-select v-model="form.actionType" placeholder="请选择操作类型">
|
||||
<el-option label="合卷" :value="1" />
|
||||
<el-option label="分卷" :value="2" />
|
||||
<el-option label="更新" :value="3" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="优先级" prop="priority">
|
||||
<el-select v-model="form.priority" placeholder="请选择优先级">
|
||||
<el-option label="普通" :value="0" />
|
||||
<el-option label="重要" :value="1" />
|
||||
<el-option label="紧急" :value="2" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" placeholder="请输入备注" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 钢卷选择器 -->
|
||||
<coil-selector
|
||||
:visible.sync="coilSelectorVisible"
|
||||
@select="handleCoilSelect"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
listPendingAction,
|
||||
getPendingAction,
|
||||
delPendingAction,
|
||||
addPendingAction,
|
||||
updatePendingAction,
|
||||
startProcess,
|
||||
completeAction,
|
||||
cancelAction
|
||||
} from '@/api/wms/pendingAction';
|
||||
import CoilSelector from '@/components/CoilSelector';
|
||||
|
||||
export default {
|
||||
name: 'CoilActflow',
|
||||
dicts: ['action_type'],
|
||||
components: {
|
||||
CoilSelector
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
// 选中数组
|
||||
ids: [],
|
||||
// 非单个禁用
|
||||
single: true,
|
||||
// 非多个禁用
|
||||
multiple: true,
|
||||
// 显示搜索条件
|
||||
showSearch: true,
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 待操作列表数据
|
||||
actionList: [],
|
||||
// 弹出层标题
|
||||
title: '',
|
||||
// 是否显示弹出层
|
||||
open: false,
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
currentCoilNo: null,
|
||||
actionType: null,
|
||||
actionStatus: null, // 默认查询待处理
|
||||
priority: null
|
||||
},
|
||||
// 表单参数
|
||||
form: {},
|
||||
// 表单校验
|
||||
rules: {
|
||||
coilId: [
|
||||
{ required: true, message: '请选择钢卷', trigger: 'blur' }
|
||||
],
|
||||
actionType: [
|
||||
{ required: true, message: '请选择操作类型', trigger: 'change' }
|
||||
]
|
||||
},
|
||||
// 钢卷选择器可见性
|
||||
coilSelectorVisible: false
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
// 设置定时刷新(可选,用于移动端扫码后自动刷新)
|
||||
this.startAutoRefresh();
|
||||
},
|
||||
beforeDestroy() {
|
||||
// 清除定时器
|
||||
if (this.refreshTimer) {
|
||||
clearInterval(this.refreshTimer);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/** 查询待操作列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listPendingAction(this.queryParams).then(response => {
|
||||
console.log('response.rows', response.rows);
|
||||
|
||||
this.actionList = response.rows;
|
||||
this.total = response.total;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
// 取消按钮
|
||||
cancel() {
|
||||
this.open = false;
|
||||
this.reset();
|
||||
},
|
||||
// 表单重置
|
||||
reset() {
|
||||
this.form = {
|
||||
actionId: null,
|
||||
coilId: null,
|
||||
currentCoilNo: null,
|
||||
actionType: null,
|
||||
actionStatus: null,
|
||||
priority: 0,
|
||||
sourceType: 'manual',
|
||||
remark: null
|
||||
};
|
||||
this.resetForm('form');
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.resetForm('queryForm');
|
||||
this.handleQuery();
|
||||
},
|
||||
// 多选框选中数据
|
||||
handleSelectionChange(selection) {
|
||||
this.ids = selection.map(item => item.actionId);
|
||||
this.single = selection.length !== 1;
|
||||
this.multiple = !selection.length;
|
||||
},
|
||||
/** 新增按钮操作 */
|
||||
handleAdd() {
|
||||
this.reset();
|
||||
this.open = true;
|
||||
this.title = '添加待操作';
|
||||
},
|
||||
/** 修改按钮操作 */
|
||||
handleUpdate(row) {
|
||||
this.reset();
|
||||
const actionId = row.actionId || this.ids;
|
||||
getPendingAction(actionId).then(response => {
|
||||
this.form = response.data;
|
||||
this.open = true;
|
||||
this.title = '修改待操作';
|
||||
});
|
||||
},
|
||||
/** 提交按钮 */
|
||||
submitForm() {
|
||||
this.$refs['form'].validate(valid => {
|
||||
if (valid) {
|
||||
if (this.form.actionId != null) {
|
||||
updatePendingAction(this.form).then(response => {
|
||||
this.$message.success('修改成功');
|
||||
this.open = false;
|
||||
this.getList();
|
||||
});
|
||||
} else {
|
||||
addPendingAction(this.form).then(response => {
|
||||
this.$message.success('新增成功');
|
||||
this.open = false;
|
||||
this.getList();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/** 删除按钮操作 */
|
||||
handleDelete(row) {
|
||||
const actionIds = row.actionId || this.ids;
|
||||
this.$confirm('是否确认删除该待操作记录?', '警告', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
return delPendingAction(actionIds);
|
||||
}).then(() => {
|
||||
this.getList();
|
||||
this.$message.success('删除成功');
|
||||
}).catch(() => {});
|
||||
},
|
||||
/** 处理操作 - 跳转到对应页面 */
|
||||
handleProcess(row) {
|
||||
console.log('=== 开始处理操作 ===');
|
||||
console.log('待操作记录:', row);
|
||||
console.log('操作类型:', row.actionType);
|
||||
console.log('钢卷ID:', row.coilId);
|
||||
|
||||
// 根据操作类型跳转到不同页面
|
||||
let path = '';
|
||||
// 注意:action_type字典中 1=合卷, 2=分卷, 3=更新
|
||||
if (row.actionType === 1 || row.actionType === '1') {
|
||||
// 合卷
|
||||
path = '/wms/merge';
|
||||
} else if (row.actionType === 2 || row.actionType === '2') {
|
||||
// 分卷
|
||||
path = '/wms/split';
|
||||
} else {
|
||||
// 更新
|
||||
path = '/wms/typing';
|
||||
}
|
||||
|
||||
console.log('跳转路径:', path);
|
||||
|
||||
if (!path) {
|
||||
this.$message.error('未知的操作类型: ' + row.actionType);
|
||||
return;
|
||||
}
|
||||
|
||||
// 更新状态为处理中
|
||||
console.log('调用startProcess,actionId:', row.actionId);
|
||||
startProcess(row.actionId).then(response => {
|
||||
console.log('开始处理响应:', response);
|
||||
|
||||
if (response.code !== 200) {
|
||||
this.$message.error(response.msg || '更新状态失败');
|
||||
return;
|
||||
}
|
||||
|
||||
// 跳转并传递参数
|
||||
console.log('准备跳转到:', path, '参数:', { coilId: row.coilId, actionId: row.actionId });
|
||||
this.$router.push({
|
||||
path: path,
|
||||
query: {
|
||||
coilId: row.coilId,
|
||||
actionId: row.actionId
|
||||
}
|
||||
});
|
||||
}).catch(error => {
|
||||
console.error('更新状态失败:', error);
|
||||
this.$message.error('更新状态失败: ' + (error.message || error));
|
||||
});
|
||||
},
|
||||
/** 取消操作 */
|
||||
handleCancel(row) {
|
||||
this.$confirm('是否确认取消该操作?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
return cancelAction(row.actionId);
|
||||
}).then(() => {
|
||||
this.$message.success('操作已取消');
|
||||
this.getList();
|
||||
}).catch(() => {});
|
||||
},
|
||||
/** 刷新列表 */
|
||||
handleRefresh() {
|
||||
this.getList();
|
||||
this.$message.success('刷新成功');
|
||||
},
|
||||
/** 自动刷新 */
|
||||
startAutoRefresh() {
|
||||
// 每30秒自动刷新一次(用于移动端扫码后自动更新列表)
|
||||
this.refreshTimer = setInterval(() => {
|
||||
|
||||
// 只在查看待处理状态时自动刷新
|
||||
this.getList();
|
||||
}, 30000);
|
||||
},
|
||||
/** 表格行样式 */
|
||||
tableRowClassName({ row }) {
|
||||
if (row.priority === 2) {
|
||||
return 'urgent-row';
|
||||
} else if (row.priority === 1) {
|
||||
return 'important-row';
|
||||
}
|
||||
return '';
|
||||
},
|
||||
/** 显示钢卷选择器 */
|
||||
showCoilSelector() {
|
||||
this.coilSelectorVisible = true;
|
||||
},
|
||||
/** 钢卷选择回调 */
|
||||
handleCoilSelect(coil) {
|
||||
this.form.coilId = coil.coilId;
|
||||
this.form.currentCoilNo = coil.currentCoilNo;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.app-container {
|
||||
::v-deep .urgent-row {
|
||||
background: #fef0f0 !important;
|
||||
}
|
||||
|
||||
::v-deep .important-row {
|
||||
background: #fdf6ec !important;
|
||||
}
|
||||
|
||||
// 优化按钮文字颜色
|
||||
// 实心按钮:白色文字(在深色背景上清晰可见)
|
||||
::v-deep .el-button--primary.el-button--mini:not(.is-plain) {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
::v-deep .el-button--danger.el-button--mini:not(.is-plain) {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
::v-deep .el-button--warning.el-button--mini:not(.is-plain) {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
::v-deep .el-button--info.el-button--mini:not(.is-plain) {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
::v-deep .el-button--success.el-button--mini:not(.is-plain) {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
// plain按钮:同色系深色文字(在浅色背景上)
|
||||
::v-deep .el-button--primary.el-button--mini.is-plain {
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
::v-deep .el-button--danger.el-button--mini.is-plain {
|
||||
color: #f56c6c;
|
||||
}
|
||||
|
||||
::v-deep .el-button--warning.el-button--mini.is-plain {
|
||||
color: #e6a23c;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
<span>钢卷合卷</span>
|
||||
</div>
|
||||
<div class="header-actions">
|
||||
<el-button type="primary" size="small" @click="handleSave" :loading="loading">保存合卷</el-button>
|
||||
<el-button size="small" @click="handleCancel" :disabled="loading">取消</el-button>
|
||||
<el-button v-if="!readonly" type="primary" size="small" @click="handleSave" :loading="loading">保存合卷</el-button>
|
||||
<el-button size="small" @click="handleCancel" :disabled="loading">{{ readonly ? '返回' : '取消' }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -18,29 +18,69 @@
|
||||
<div class="flow-left">
|
||||
<div class="flow-section-title">
|
||||
<span>源卷列表</span>
|
||||
<el-button type="text" size="mini" @click="addSourceCoil" icon="el-icon-plus">添加钢卷</el-button>
|
||||
<el-button v-if="!readonly" type="text" size="mini" @click="addSourceCoil" icon="el-icon-plus">添加钢卷</el-button>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="source-list">
|
||||
<div class="source-coil-card" v-for="(item, index) in sourceCoils" :key="index">
|
||||
<div class="source-coil-header">
|
||||
<div class="source-number">{{ index + 1 }}</div>
|
||||
<div class="source-info">
|
||||
<div class="source-id">{{ item.currentCoilNo || '待选择' }}</div>
|
||||
<div class="source-weight">{{ item.weight || '—' }} t</div>
|
||||
</div>
|
||||
<el-button
|
||||
type="text"
|
||||
size="mini"
|
||||
icon="el-icon-delete"
|
||||
<el-button
|
||||
v-if="!readonly"
|
||||
type="text"
|
||||
size="mini"
|
||||
icon="el-icon-delete"
|
||||
@click="removeSourceCoil(index)"
|
||||
class="btn-remove"
|
||||
></el-button>
|
||||
</div>
|
||||
<div class="source-coil-body">
|
||||
<el-button type="text" size="small" @click="selectCoil(index)">
|
||||
<template v-if="item.coilId">
|
||||
<div class="source-detail-row">
|
||||
<span class="detail-label">入场钢卷号:</span>
|
||||
<span class="detail-value">{{ item.enterCoilNo || '—' }}</span>
|
||||
</div>
|
||||
<div class="source-detail-row">
|
||||
<span class="detail-label">当前库区:</span>
|
||||
<span class="detail-value">{{ item.warehouseName || '未分配' }}</span>
|
||||
</div>
|
||||
<div class="source-detail-row" v-if="item.materialName || item.productName">
|
||||
<span class="detail-label">物料名称:</span>
|
||||
<span class="detail-value">{{ item.materialName || item.productName || '—' }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 第二个位置:显示待合卷列表 -->
|
||||
<template v-else-if="index === 1 && !readonly">
|
||||
<div class="pending-list-title">待合卷钢卷列表</div>
|
||||
<div class="pending-coil-list" v-if="pendingMergeList.length > 0">
|
||||
<div
|
||||
class="pending-coil-item"
|
||||
v-for="pending in pendingMergeList"
|
||||
:key="pending.actionId"
|
||||
@click="selectPendingCoil(pending, index)"
|
||||
>
|
||||
<div class="pending-coil-no">{{ pending.currentCoilNo }}</div>
|
||||
<div class="pending-coil-info">
|
||||
<span class="pending-label">扫码时间:</span>
|
||||
<span class="pending-value">{{ formatTime(pending.scanTime) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="empty-tip">
|
||||
<i class="el-icon-info"></i>
|
||||
暂无其他待合卷钢卷
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 其他位置:显示选择按钮 -->
|
||||
<el-button v-else-if="!readonly" type="text" size="small" @click="selectCoil(index)">
|
||||
<i class="el-icon-search"></i> 选择钢卷
|
||||
</el-button>
|
||||
<div v-else class="empty-tip">未选择钢卷</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -51,14 +91,14 @@
|
||||
<div class="merge-arrow-container">
|
||||
<svg width="120" height="100%" viewBox="0 0 120 400" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- 多条线汇聚到一点 -->
|
||||
<line
|
||||
v-for="(item, index) in sourceCoils"
|
||||
<line
|
||||
v-for="(item, index) in sourceCoils"
|
||||
:key="index"
|
||||
:x1="0"
|
||||
:y1="50 + index * 80"
|
||||
:x2="100"
|
||||
:y2="200"
|
||||
stroke="#0066cc"
|
||||
:x1="0"
|
||||
:y1="50 + index * 80"
|
||||
:x2="100"
|
||||
:y2="200"
|
||||
stroke="#0066cc"
|
||||
stroke-width="2"
|
||||
stroke-dasharray="5,5"
|
||||
/>
|
||||
@@ -83,31 +123,68 @@
|
||||
<div class="target-coil-body">
|
||||
<el-form size="small" label-width="90px">
|
||||
<el-form-item label="卷号">
|
||||
<el-input v-model="targetCoil.currentCoilNo" placeholder="输入目标卷号"></el-input>
|
||||
<el-input v-model="targetCoil.currentCoilNo" placeholder="输入目标卷号" :disabled="readonly"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="钢种">
|
||||
<el-input v-model="targetCoil.grade" placeholder="继承源卷"></el-input>
|
||||
<el-form-item label="班组">
|
||||
<el-input v-model="targetCoil.team" placeholder="请输入班组名称" :disabled="readonly"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="厚度(mm)">
|
||||
<el-input-number
|
||||
v-model="targetCoil.thickness"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
controls-position="right"
|
||||
<el-form-item label="物品类型">
|
||||
<el-select v-model="targetCoil.itemType" placeholder="请选择" style="width: 100%" :disabled="readonly">
|
||||
<el-option label="原材料" value="raw_material" />
|
||||
<el-option label="产品" value="product" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="物品">
|
||||
<el-select
|
||||
v-model="targetCoil.itemId"
|
||||
placeholder="请选择物品"
|
||||
filterable
|
||||
remote
|
||||
:remote-method="searchItems"
|
||||
:loading="itemSearchLoading"
|
||||
style="width: 100%"
|
||||
></el-input-number>
|
||||
clearable
|
||||
:disabled="readonly"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in currentItemList"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="宽度(mm)">
|
||||
<el-input-number
|
||||
v-model="targetCoil.width"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
controls-position="right"
|
||||
style="width: 100%"
|
||||
></el-input-number>
|
||||
<el-form-item label="毛重(t)">
|
||||
<el-input
|
||||
v-model.number="targetCoil.grossWeight"
|
||||
placeholder="请输入毛重"
|
||||
type="number"
|
||||
step="0.01"
|
||||
:disabled="readonly"
|
||||
>
|
||||
<template slot="append">吨</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="重量(t)">
|
||||
<el-input v-model="totalWeight" disabled></el-input>
|
||||
<el-form-item label="净重(t)">
|
||||
<el-input
|
||||
v-model.number="targetCoil.netWeight"
|
||||
placeholder="请输入净重"
|
||||
type="number"
|
||||
step="0.01"
|
||||
:disabled="readonly"
|
||||
>
|
||||
<template slot="append">吨</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="目标库区">
|
||||
<el-select v-model="targetCoil.nextWarehouseId" placeholder="请选择" style="width: 100%" clearable :disabled="readonly">
|
||||
<el-option
|
||||
v-for="warehouse in warehouseList"
|
||||
:key="warehouse.warehouseId"
|
||||
:label="warehouse.warehouseName"
|
||||
:value="warehouse.warehouseId"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
@@ -120,10 +197,9 @@
|
||||
合卷规则
|
||||
</div>
|
||||
<ul class="rule-list">
|
||||
<li>同一钢种才可合卷</li>
|
||||
<li>厚度差异不超过±0.05mm</li>
|
||||
<li>宽度必须完全一致</li>
|
||||
<li>目标卷重量为源卷总和</li>
|
||||
<li>至少需要2个源卷</li>
|
||||
<li>所有源卷的物品类型和物品ID应保持一致</li>
|
||||
<li>请确保录入正确的新钢卷号和班组信息</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -139,6 +215,10 @@
|
||||
|
||||
<script>
|
||||
import { getMaterialCoil, mergeMaterialCoil } from '@/api/wms/coil';
|
||||
import { listWarehouse } from '@/api/wms/warehouse';
|
||||
import { listRawMaterial } from '@/api/wms/rawMaterial';
|
||||
import { listProduct } from '@/api/wms/product';
|
||||
import { listPendingAction, completeAction } from '@/api/wms/pendingAction';
|
||||
import CoilSelector from '@/components/CoilSelector';
|
||||
|
||||
export default {
|
||||
@@ -153,51 +233,306 @@ export default {
|
||||
// 目标卷信息
|
||||
targetCoil: {
|
||||
currentCoilNo: '',
|
||||
grade: '',
|
||||
thickness: null,
|
||||
width: null,
|
||||
warehouseId: null,
|
||||
team: null,
|
||||
team: '',
|
||||
itemType: null,
|
||||
itemId: null
|
||||
itemId: null,
|
||||
grossWeight: null,
|
||||
netWeight: null,
|
||||
nextWarehouseId: null
|
||||
},
|
||||
loading: false,
|
||||
// 钢卷选择器可见性
|
||||
coilSelectorVisible: false,
|
||||
// 当前选择的源卷索引
|
||||
currentSelectIndex: -1
|
||||
currentSelectIndex: -1,
|
||||
// 库区列表
|
||||
warehouseList: [],
|
||||
// 原材料和产品列表
|
||||
rawMaterialList: [],
|
||||
productList: [],
|
||||
itemSearchLoading: false,
|
||||
// 只读模式
|
||||
readonly: false,
|
||||
// 待合卷列表(其他待操作的合卷任务)
|
||||
pendingMergeList: [],
|
||||
pendingLoading: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 源卷总重量
|
||||
totalWeight() {
|
||||
return this.sourceCoils.reduce((sum, item) => sum + (Number(item.weight) || 0), 0).toFixed(2);
|
||||
// 当前物品列表(根据物品类型动态切换)
|
||||
currentItemList() {
|
||||
if (this.targetCoil.itemType === 'raw_material') {
|
||||
return this.rawMaterialList.map(item => ({
|
||||
id: item.rawMaterialId,
|
||||
name: item.rawMaterialName
|
||||
}));
|
||||
} else if (this.targetCoil.itemType === 'product') {
|
||||
return this.productList.map(item => ({
|
||||
id: item.productId,
|
||||
name: item.productName
|
||||
}));
|
||||
}
|
||||
return [];
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 初始化至少2个源卷
|
||||
this.sourceCoils = [
|
||||
{ coilId: null, currentCoilNo: '', grade: '', weight: 0, thickness: null, width: null },
|
||||
{ coilId: null, currentCoilNo: '', grade: '', weight: 0, thickness: null, width: null }
|
||||
];
|
||||
watch: {
|
||||
// 监听物品类型变化,加载对应的列表
|
||||
'targetCoil.itemType'(newVal, oldVal) {
|
||||
if (newVal !== oldVal) {
|
||||
this.targetCoil.itemId = null; // 清空物品ID
|
||||
this.loadItemList(newVal);
|
||||
}
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
// 加载库区列表
|
||||
await this.loadWarehouses();
|
||||
|
||||
// 从路由参数获取coilId、actionId和readonly
|
||||
const coilId = this.$route.query.coilId;
|
||||
const actionId = this.$route.query.actionId;
|
||||
const readonly = this.$route.query.readonly;
|
||||
|
||||
// 保存当前页面的待操作ID
|
||||
if (actionId) {
|
||||
this.actionId = actionId;
|
||||
}
|
||||
|
||||
// 设置只读模式
|
||||
if (readonly === 'true' || readonly === true) {
|
||||
this.readonly = true;
|
||||
}
|
||||
|
||||
// 如果有coilId,加载该钢卷作为第一个源卷
|
||||
if (coilId) {
|
||||
await this.loadFirstCoil(coilId);
|
||||
// 加载其他待合卷的钢卷列表
|
||||
await this.loadPendingMergeList();
|
||||
} else {
|
||||
// 没有coilId,初始化空的源卷
|
||||
this.sourceCoils = [
|
||||
{
|
||||
coilId: null,
|
||||
enterCoilNo: '',
|
||||
currentCoilNo: '',
|
||||
itemType: null,
|
||||
itemId: null,
|
||||
warehouseName: '',
|
||||
materialName: '',
|
||||
productName: ''
|
||||
},
|
||||
{
|
||||
coilId: null,
|
||||
enterCoilNo: '',
|
||||
currentCoilNo: '',
|
||||
itemType: null,
|
||||
itemId: null,
|
||||
warehouseName: '',
|
||||
materialName: '',
|
||||
productName: ''
|
||||
}
|
||||
];
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 加载第一个钢卷(从待操作进入时)
|
||||
async loadFirstCoil(coilId) {
|
||||
try {
|
||||
this.loading = true;
|
||||
const response = await getMaterialCoil(coilId);
|
||||
if (response.code === 200 && response.data) {
|
||||
const data = response.data;
|
||||
|
||||
// 初始化源卷列表,第一个是当前钢卷
|
||||
this.sourceCoils = [
|
||||
{
|
||||
coilId: data.coilId,
|
||||
enterCoilNo: data.enterCoilNo || '',
|
||||
currentCoilNo: data.currentCoilNo || '',
|
||||
itemType: data.itemType,
|
||||
itemId: data.itemId,
|
||||
warehouseName: data.warehouseName || (data.warehouse ? data.warehouse.warehouseName : ''),
|
||||
materialName: data.materialName || (data.rawMaterial ? data.rawMaterial.rawMaterialName : ''),
|
||||
productName: data.productName || (data.product ? data.product.productName : '')
|
||||
},
|
||||
{
|
||||
coilId: null,
|
||||
enterCoilNo: '',
|
||||
currentCoilNo: '',
|
||||
itemType: null,
|
||||
itemId: null,
|
||||
warehouseName: '',
|
||||
materialName: '',
|
||||
productName: ''
|
||||
}
|
||||
];
|
||||
|
||||
// 自动填充目标卷信息
|
||||
this.targetCoil.itemType = data.itemType;
|
||||
this.targetCoil.itemId = data.itemId;
|
||||
this.targetCoil.nextWarehouseId = data.warehouseId;
|
||||
|
||||
// 加载对应的物品列表
|
||||
if (data.itemType) {
|
||||
await this.loadItemList(data.itemType);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
this.$message.error('加载钢卷信息失败');
|
||||
console.error(error);
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
// 加载待合卷列表
|
||||
async loadPendingMergeList() {
|
||||
try {
|
||||
this.pendingLoading = true;
|
||||
const response = await listPendingAction({
|
||||
actionType: 1, // 1=合卷
|
||||
actionStatus: 0, // 0=待处理
|
||||
pageNum: 1,
|
||||
pageSize: 50
|
||||
});
|
||||
|
||||
if (response.code === 200) {
|
||||
// 排除当前钢卷
|
||||
const currentCoilId = this.sourceCoils[0].coilId;
|
||||
this.pendingMergeList = (response.rows || []).filter(item => item.coilId !== currentCoilId);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载待合卷列表失败', error);
|
||||
} finally {
|
||||
this.pendingLoading = false;
|
||||
}
|
||||
},
|
||||
|
||||
// 选择待操作中的钢卷
|
||||
async selectPendingCoil(pending, index) {
|
||||
try {
|
||||
this.loading = true;
|
||||
const response = await getMaterialCoil(pending.coilId);
|
||||
if (response.code === 200 && response.data) {
|
||||
const data = response.data;
|
||||
this.$set(this.sourceCoils, index, {
|
||||
coilId: data.coilId,
|
||||
enterCoilNo: data.enterCoilNo || '',
|
||||
currentCoilNo: data.currentCoilNo || '',
|
||||
itemType: data.itemType,
|
||||
itemId: data.itemId,
|
||||
warehouseName: data.warehouseName || (data.warehouse ? data.warehouse.warehouseName : ''),
|
||||
materialName: data.materialName || (data.rawMaterial ? data.rawMaterial.rawMaterialName : ''),
|
||||
productName: data.productName || (data.product ? data.product.productName : ''),
|
||||
actionId: pending.actionId // 保存待操作ID,用于后续完成操作
|
||||
});
|
||||
|
||||
this.$message.success('已添加到合卷列表');
|
||||
}
|
||||
} catch (error) {
|
||||
this.$message.error('加载钢卷信息失败');
|
||||
console.error(error);
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
// 格式化时间
|
||||
formatTime(time) {
|
||||
if (!time) return '';
|
||||
const date = new Date(time);
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
const hour = String(date.getHours()).padStart(2, '0');
|
||||
const minute = String(date.getMinutes()).padStart(2, '0');
|
||||
return `${month}-${day} ${hour}:${minute}`;
|
||||
},
|
||||
|
||||
// 加载库区列表
|
||||
async loadWarehouses() {
|
||||
try {
|
||||
const response = await listWarehouse({ pageNum: 1, pageSize: 1000 });
|
||||
if (response.code === 200) {
|
||||
this.warehouseList = response.rows || response.data || [];
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载库区列表失败', error);
|
||||
}
|
||||
},
|
||||
|
||||
// 加载物品列表(根据类型)
|
||||
async loadItemList(itemType) {
|
||||
if (!itemType) return;
|
||||
|
||||
try {
|
||||
this.itemSearchLoading = true;
|
||||
if (itemType === 'raw_material') {
|
||||
const response = await listRawMaterial({ pageNum: 1, pageSize: 100 });
|
||||
if (response.code === 200) {
|
||||
this.rawMaterialList = response.rows || [];
|
||||
}
|
||||
} else if (itemType === 'product') {
|
||||
const response = await listProduct({ pageNum: 1, pageSize: 100 });
|
||||
if (response.code === 200) {
|
||||
this.productList = response.rows || [];
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载物品列表失败', error);
|
||||
} finally {
|
||||
this.itemSearchLoading = false;
|
||||
}
|
||||
},
|
||||
|
||||
// 搜索物品
|
||||
async searchItems(query) {
|
||||
if (!this.targetCoil.itemType) {
|
||||
this.$message.warning('请先选择物品类型');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
this.itemSearchLoading = true;
|
||||
if (this.targetCoil.itemType === 'raw_material') {
|
||||
const response = await listRawMaterial({
|
||||
rawMaterialName: query,
|
||||
pageNum: 1,
|
||||
pageSize: 50
|
||||
});
|
||||
if (response.code === 200) {
|
||||
this.rawMaterialList = response.rows || [];
|
||||
}
|
||||
} else if (this.targetCoil.itemType === 'product') {
|
||||
const response = await listProduct({
|
||||
productName: query,
|
||||
pageNum: 1,
|
||||
pageSize: 50
|
||||
});
|
||||
if (response.code === 200) {
|
||||
this.productList = response.rows || [];
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('搜索物品失败', error);
|
||||
} finally {
|
||||
this.itemSearchLoading = false;
|
||||
}
|
||||
},
|
||||
|
||||
// 添加源卷
|
||||
addSourceCoil() {
|
||||
this.sourceCoils.push({
|
||||
coilId: null,
|
||||
enterCoilNo: '',
|
||||
currentCoilNo: '',
|
||||
grade: '',
|
||||
weight: 0,
|
||||
thickness: null,
|
||||
width: null,
|
||||
warehouseId: null,
|
||||
team: null,
|
||||
itemType: null,
|
||||
itemId: null
|
||||
itemId: null,
|
||||
warehouseName: '',
|
||||
materialName: '',
|
||||
productName: ''
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
// 删除源卷
|
||||
removeSourceCoil(index) {
|
||||
if (this.sourceCoils.length > 2) {
|
||||
@@ -206,7 +541,7 @@ export default {
|
||||
this.$message.warning('至少需要2个源卷才能合卷');
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// 选择钢卷
|
||||
selectCoil(index) {
|
||||
this.currentSelectIndex = index;
|
||||
@@ -218,31 +553,25 @@ export default {
|
||||
const index = this.currentSelectIndex;
|
||||
this.$set(this.sourceCoils, index, {
|
||||
coilId: coil.coilId,
|
||||
enterCoilNo: coil.enterCoilNo || '',
|
||||
currentCoilNo: coil.currentCoilNo || '',
|
||||
grade: coil.grade || '',
|
||||
weight: coil.weight || 0,
|
||||
thickness: coil.thickness,
|
||||
width: coil.width,
|
||||
warehouseId: coil.warehouseId,
|
||||
team: coil.team,
|
||||
itemType: coil.itemType,
|
||||
itemId: coil.itemId
|
||||
itemId: coil.itemId,
|
||||
warehouseName: coil.warehouseName || '',
|
||||
materialName: coil.materialName || '',
|
||||
productName: coil.productName || ''
|
||||
});
|
||||
|
||||
// 如果是第一个源卷,自动填充目标卷信息
|
||||
if (index === 0) {
|
||||
this.targetCoil.grade = coil.grade;
|
||||
this.targetCoil.thickness = coil.thickness;
|
||||
this.targetCoil.width = coil.width;
|
||||
this.targetCoil.warehouseId = coil.warehouseId;
|
||||
this.targetCoil.team = coil.team;
|
||||
this.targetCoil.itemType = coil.itemType;
|
||||
this.targetCoil.itemId = coil.itemId;
|
||||
this.targetCoil.nextWarehouseId = coil.warehouseId;
|
||||
}
|
||||
|
||||
this.$message.success('钢卷选择成功');
|
||||
},
|
||||
|
||||
|
||||
// 保存合卷
|
||||
async handleSave() {
|
||||
// 验证源卷数量
|
||||
@@ -266,52 +595,48 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
// 验证源卷规格一致性
|
||||
const firstCoil = this.sourceCoils[0];
|
||||
for (let i = 1; i < this.sourceCoils.length; i++) {
|
||||
const coil = this.sourceCoils[i];
|
||||
if (coil.grade !== firstCoil.grade) {
|
||||
this.$message.error('源卷钢种不一致,无法合卷');
|
||||
return;
|
||||
}
|
||||
if (Math.abs(coil.thickness - firstCoil.thickness) > 0.05) {
|
||||
this.$message.error('源卷厚度差异超过±0.05mm,无法合卷');
|
||||
return;
|
||||
}
|
||||
if (coil.width !== firstCoil.width) {
|
||||
this.$message.error('源卷宽度不一致,无法合卷');
|
||||
return;
|
||||
}
|
||||
// 验证班组
|
||||
if (!this.targetCoil.team || this.targetCoil.team.trim() === '') {
|
||||
this.$message.error('请输入班组名称');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
this.loading = true;
|
||||
|
||||
// 构造合卷数据
|
||||
// 入场钢卷号:所有源卷的入场钢卷号拼接(逗号分隔)
|
||||
const enterCoilNos = this.sourceCoils
|
||||
.map(item => item.enterCoilNo)
|
||||
.filter(no => no) // 过滤空值
|
||||
.join(',');
|
||||
|
||||
const mergeData = {
|
||||
enterCoilNo: enterCoilNos, // 拼接的入场钢卷号
|
||||
currentCoilNo: this.targetCoil.currentCoilNo,
|
||||
grade: this.targetCoil.grade,
|
||||
thickness: this.targetCoil.thickness,
|
||||
width: this.targetCoil.width,
|
||||
weight: Number(this.totalWeight),
|
||||
warehouseId: this.targetCoil.warehouseId,
|
||||
team: this.targetCoil.team,
|
||||
itemType: this.targetCoil.itemType,
|
||||
itemId: this.targetCoil.itemId,
|
||||
grossWeight: this.targetCoil.grossWeight,
|
||||
netWeight: this.targetCoil.netWeight,
|
||||
nextWarehouseId: this.targetCoil.nextWarehouseId,
|
||||
hasMergeSplit: 2, // 2表示合卷
|
||||
newCoils: this.sourceCoils.map(item => ({
|
||||
coilId: item.coilId,
|
||||
currentCoilNo: item.currentCoilNo,
|
||||
grade: item.grade,
|
||||
thickness: item.thickness,
|
||||
width: item.width,
|
||||
weight: item.weight
|
||||
enterCoilNo: item.enterCoilNo,
|
||||
currentCoilNo: item.currentCoilNo
|
||||
}))
|
||||
};
|
||||
|
||||
console.log('提交的合卷数据:', mergeData);
|
||||
|
||||
const response = await mergeMaterialCoil(mergeData);
|
||||
if (response.code === 200) {
|
||||
this.$message.success('合卷保存成功');
|
||||
|
||||
// 完成所有相关的待操作记录
|
||||
await this.completeAllRelatedActions();
|
||||
|
||||
// 延迟返回,让用户看到成功提示
|
||||
setTimeout(() => {
|
||||
this.$router.back();
|
||||
@@ -326,7 +651,38 @@ export default {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// 完成所有相关的待操作记录
|
||||
async completeAllRelatedActions() {
|
||||
try {
|
||||
// 收集所有待操作ID
|
||||
const actionIds = [];
|
||||
|
||||
// 当前页面的actionId(从路由参数获取)
|
||||
if (this.actionId) {
|
||||
actionIds.push(this.actionId);
|
||||
}
|
||||
|
||||
// 从待合卷列表中选择的钢卷的actionId
|
||||
this.sourceCoils.forEach(item => {
|
||||
if (item.actionId) {
|
||||
actionIds.push(item.actionId);
|
||||
}
|
||||
});
|
||||
|
||||
// 批量完成所有待操作
|
||||
console.log('需要完成的待操作ID列表:', actionIds);
|
||||
|
||||
const promises = actionIds.map(id => completeAction(id));
|
||||
await Promise.all(promises);
|
||||
|
||||
console.log('所有待操作已完成');
|
||||
} catch (error) {
|
||||
console.error('完成待操作失败:', error);
|
||||
// 不影响主流程,只记录错误
|
||||
}
|
||||
},
|
||||
|
||||
// 取消操作
|
||||
handleCancel() {
|
||||
this.$router.back();
|
||||
@@ -361,7 +717,7 @@ export default {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
|
||||
|
||||
i {
|
||||
color: #0066cc;
|
||||
font-size: 20px;
|
||||
@@ -416,11 +772,11 @@ export default {
|
||||
overflow-y: auto;
|
||||
padding-right: 10px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: #dcdfe6;
|
||||
border-radius: 3px;
|
||||
@@ -433,7 +789,7 @@ export default {
|
||||
border-radius: 8px;
|
||||
margin-bottom: 12px;
|
||||
transition: all 0.3s;
|
||||
|
||||
|
||||
&:hover {
|
||||
border-color: #0066cc;
|
||||
box-shadow: 0 2px 8px rgba(0, 102, 204, 0.15);
|
||||
@@ -481,13 +837,107 @@ export default {
|
||||
|
||||
.source-coil-body {
|
||||
padding: 12px 16px;
|
||||
text-align: center;
|
||||
|
||||
&:empty {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.empty-tip {
|
||||
text-align: center;
|
||||
color: #909399;
|
||||
font-size: 13px;
|
||||
padding: 10px 0;
|
||||
|
||||
i {
|
||||
display: block;
|
||||
font-size: 24px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 待合卷列表 */
|
||||
.pending-list-title {
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: #606266;
|
||||
margin-bottom: 10px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #e4e7ed;
|
||||
}
|
||||
|
||||
.pending-coil-list {
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 4px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: #dcdfe6;
|
||||
border-radius: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.pending-coil-item {
|
||||
padding: 10px;
|
||||
margin-bottom: 8px;
|
||||
background: #f5f7fa;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
background: #ecf5ff;
|
||||
border-color: #0066cc;
|
||||
}
|
||||
|
||||
.pending-coil-no {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #303133;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.pending-coil-info {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
|
||||
.pending-label {
|
||||
margin-right: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.source-detail-row {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 8px;
|
||||
font-size: 13px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.detail-label {
|
||||
color: #909399;
|
||||
min-width: 90px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.detail-value {
|
||||
color: #303133;
|
||||
flex: 1;
|
||||
word-break: break-all;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-remove {
|
||||
color: #f56c6c;
|
||||
padding: 0;
|
||||
|
||||
|
||||
&:hover {
|
||||
color: #f56c6c;
|
||||
}
|
||||
@@ -562,12 +1012,43 @@ export default {
|
||||
.rule-list {
|
||||
padding-left: 20px;
|
||||
margin: 0;
|
||||
|
||||
|
||||
li {
|
||||
color: #606266;
|
||||
font-size: 13px;
|
||||
line-height: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
// 优化按钮文字颜色
|
||||
// 实心primary按钮:白色文字
|
||||
::v-deep .el-button--primary.el-button--small:not(.is-plain) {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
// plain按钮和text按钮:蓝色文字
|
||||
::v-deep .el-button--primary.el-button--small.is-plain,
|
||||
::v-deep .el-button--text {
|
||||
color: #409eff;
|
||||
|
||||
&:hover {
|
||||
color: #66b1ff;
|
||||
}
|
||||
}
|
||||
|
||||
// 修复数字输入框的上下箭头溢出
|
||||
.target-coil-body {
|
||||
::v-deep input[type="number"] {
|
||||
appearance: textfield;
|
||||
-moz-appearance: textfield;
|
||||
|
||||
&::-webkit-outer-spin-button,
|
||||
&::-webkit-inner-spin-button {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
<span>钢卷分卷</span>
|
||||
</div>
|
||||
<div class="header-actions">
|
||||
<el-button type="primary" size="small" @click="handleSave" :loading="loading">保存分卷</el-button>
|
||||
<el-button size="small" @click="handleCancel" :disabled="loading">取消</el-button>
|
||||
<el-button v-if="!readonly" type="primary" size="small" @click="handleSave" :loading="loading">保存分卷</el-button>
|
||||
<el-button size="small" @click="handleCancel" :disabled="loading">{{ readonly ? '返回' : '取消' }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -18,30 +18,52 @@
|
||||
<div class="flow-left">
|
||||
<div class="flow-section-title">
|
||||
<span>母卷信息</span>
|
||||
<el-button type="text" size="mini" @click="showCoilSelector" icon="el-icon-search">选择母卷</el-button>
|
||||
</div>
|
||||
<div class="coil-card mother-coil">
|
||||
<div class="coil-header">
|
||||
<i class="el-icon-s-grid"></i>
|
||||
<span class="coil-id">{{ motherCoil.currentCoilNo || '—' }}</span>
|
||||
<span class="coil-title">钢卷信息</span>
|
||||
</div>
|
||||
<div class="coil-body">
|
||||
<div class="coil-info-row">
|
||||
<span class="label">钢种:</span>
|
||||
<span class="value">{{ motherCoil.grade || '—' }}</span>
|
||||
<span class="label">入场钢卷号:</span>
|
||||
<span class="value">{{ motherCoil.enterCoilNo || '—' }}</span>
|
||||
</div>
|
||||
<div class="coil-info-row">
|
||||
<span class="label">厚度:</span>
|
||||
<span class="value">{{ motherCoil.thickness || '—' }} mm</span>
|
||||
<span class="label">当前钢卷号:</span>
|
||||
<span class="value">{{ motherCoil.currentCoilNo || '—' }}</span>
|
||||
</div>
|
||||
<div class="coil-info-row">
|
||||
<span class="label">宽度:</span>
|
||||
<span class="value">{{ motherCoil.width || '—' }} mm</span>
|
||||
<span class="label">当前库区:</span>
|
||||
<span class="value">{{ motherCoil.warehouseName || '未分配' }}</span>
|
||||
</div>
|
||||
<div class="coil-info-row">
|
||||
<span class="label">重量:</span>
|
||||
<span class="value highlight">{{ motherCoil.weight || '—' }} t</span>
|
||||
<span class="label">班组:</span>
|
||||
<span class="value">{{ motherCoil.team || '—' }}</span>
|
||||
</div>
|
||||
<div class="coil-info-row" v-if="motherCoil.materialName || motherCoil.productName">
|
||||
<span class="label">物料名称:</span>
|
||||
<span class="value">{{ motherCoil.materialName || motherCoil.productName || '—' }}</span>
|
||||
</div>
|
||||
<div class="coil-info-row">
|
||||
<span class="label">毛重:</span>
|
||||
<span class="value">{{ motherCoil.grossWeight ? motherCoil.grossWeight + ' t' : '—' }}</span>
|
||||
</div>
|
||||
<div class="coil-info-row">
|
||||
<span class="label">净重:</span>
|
||||
<span class="value">{{ motherCoil.netWeight ? motherCoil.netWeight + ' t' : '—' }}</span>
|
||||
</div>
|
||||
|
||||
<!-- BOM参数展示 -->
|
||||
<template v-if="motherCoil.bomItems && motherCoil.bomItems.length > 0">
|
||||
<el-divider content-position="left" style="margin: 15px 0 10px;">参数信息</el-divider>
|
||||
<div class="bom-params">
|
||||
<div class="param-item" v-for="(param, index) in motherCoil.bomItems" :key="index">
|
||||
<span class="param-name">{{ param.attrKey }}:</span>
|
||||
<span class="param-value">{{ param.attrValue }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -65,43 +87,101 @@
|
||||
<div class="flow-right">
|
||||
<div class="flow-section-title">
|
||||
<span>子卷列表</span>
|
||||
<el-button type="text" size="mini" @click="addSplitItem" icon="el-icon-plus">添加子卷</el-button>
|
||||
<div>
|
||||
<el-button v-if="!readonly" type="text" size="mini" @click="copyToAllSubCoils" icon="el-icon-document-copy">复制到全部</el-button>
|
||||
<el-button v-if="!readonly" type="text" size="mini" @click="addSplitItem" icon="el-icon-plus">添加子卷</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="split-list">
|
||||
<div class="sub-coil-card" v-for="(item, index) in splitList" :key="index">
|
||||
<div class="sub-coil-header">
|
||||
<span class="sub-coil-number">{{ index + 1 }}</span>
|
||||
<el-button
|
||||
type="text"
|
||||
size="mini"
|
||||
icon="el-icon-delete"
|
||||
<el-button
|
||||
v-if="!readonly"
|
||||
type="text"
|
||||
size="mini"
|
||||
icon="el-icon-delete"
|
||||
@click="removeSplitItem(index)"
|
||||
class="btn-remove"
|
||||
></el-button>
|
||||
</div>
|
||||
<div class="sub-coil-body">
|
||||
<el-form size="small" label-width="70px">
|
||||
<el-form-item label="卷号">
|
||||
<el-input v-model="item.currentCoilNo" placeholder="输入子卷卷号"></el-input>
|
||||
<el-form size="small" label-width="90px">
|
||||
<el-form-item label="卷号" required>
|
||||
<el-input v-model="item.currentCoilNo" placeholder="输入子卷卷号" :disabled="readonly"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="重量(t)">
|
||||
<el-input-number
|
||||
v-model="item.weight"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
controls-position="right"
|
||||
style="width: 100%"
|
||||
></el-input-number>
|
||||
<el-form-item label="班组" required>
|
||||
<el-input v-model="item.team" placeholder="输入班组名称" :disabled="readonly"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="长度(m)">
|
||||
<el-input-number
|
||||
v-model="item.length"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
controls-position="right"
|
||||
<el-form-item label="物品类型" required>
|
||||
<el-select
|
||||
v-model="item.itemType"
|
||||
placeholder="请选择"
|
||||
style="width: 100%"
|
||||
></el-input-number>
|
||||
@change="handleItemTypeChange(index)"
|
||||
:disabled="readonly"
|
||||
>
|
||||
<el-option label="原材料" value="raw_material" />
|
||||
<el-option label="产品" value="product" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="物品" required>
|
||||
<el-select
|
||||
v-model="item.itemId"
|
||||
placeholder="请选择物品"
|
||||
filterable
|
||||
remote
|
||||
:remote-method="(query) => searchItemsForSplit(query, index)"
|
||||
:loading="itemSearchLoading"
|
||||
style="width: 100%"
|
||||
:disabled="readonly"
|
||||
>
|
||||
<el-option
|
||||
v-for="option in getItemListForSplit(item.itemType)"
|
||||
:key="option.id"
|
||||
:label="option.name"
|
||||
:value="option.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="毛重(t)" required>
|
||||
<el-input
|
||||
v-model.number="item.grossWeight"
|
||||
placeholder="请输入毛重"
|
||||
type="number"
|
||||
step="0.01"
|
||||
:disabled="readonly"
|
||||
>
|
||||
<template slot="append">吨</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="净重(t)" required>
|
||||
<el-input
|
||||
v-model.number="item.netWeight"
|
||||
placeholder="请输入净重"
|
||||
type="number"
|
||||
step="0.01"
|
||||
:disabled="readonly"
|
||||
>
|
||||
<template slot="append">吨</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="目标库区" required>
|
||||
<el-select
|
||||
v-model="item.nextWarehouseId"
|
||||
placeholder="请选择目标库区"
|
||||
style="width: 100%"
|
||||
filterable
|
||||
:disabled="readonly"
|
||||
>
|
||||
<el-option
|
||||
v-for="warehouse in warehouseList"
|
||||
:key="warehouse.warehouseId"
|
||||
:label="warehouse.warehouseName"
|
||||
:value="warehouse.warehouseId"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
@@ -114,18 +194,6 @@
|
||||
<span class="summary-label">子卷数量:</span>
|
||||
<span class="summary-value">{{ splitList.length }}</span>
|
||||
</div>
|
||||
<div class="summary-item">
|
||||
<span class="summary-label">总重量:</span>
|
||||
<span class="summary-value" :class="{ 'error': totalWeight > motherCoil.weight }">
|
||||
{{ totalWeight.toFixed(2) }} t
|
||||
</span>
|
||||
</div>
|
||||
<div class="summary-item">
|
||||
<span class="summary-label">剩余重量:</span>
|
||||
<span class="summary-value" :class="{ 'error': remainWeight < 0 }">
|
||||
{{ remainWeight.toFixed(2) }} t
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -140,6 +208,9 @@
|
||||
|
||||
<script>
|
||||
import { getMaterialCoil, splitMaterialCoil } from '@/api/wms/coil';
|
||||
import { listWarehouse } from '@/api/wms/warehouse';
|
||||
import { listRawMaterial } from '@/api/wms/rawMaterial';
|
||||
import { listProduct } from '@/api/wms/product';
|
||||
import CoilSelector from '@/components/CoilSelector';
|
||||
|
||||
export default {
|
||||
@@ -152,45 +223,146 @@ export default {
|
||||
// 母卷信息
|
||||
motherCoil: {
|
||||
coilId: null,
|
||||
enterCoilNo: '',
|
||||
currentCoilNo: '',
|
||||
grade: '',
|
||||
thickness: null,
|
||||
width: null,
|
||||
weight: null,
|
||||
team: '',
|
||||
warehouseId: null,
|
||||
team: null,
|
||||
warehouseName: '',
|
||||
itemType: null,
|
||||
itemId: null,
|
||||
enterCoilNo: '',
|
||||
supplierCoilNo: ''
|
||||
materialName: '',
|
||||
productName: '',
|
||||
grossWeight: null,
|
||||
netWeight: null,
|
||||
bomItems: []
|
||||
},
|
||||
// 子卷列表
|
||||
splitList: [
|
||||
{ currentCoilNo: '', weight: 0, length: 0 }
|
||||
{
|
||||
currentCoilNo: '',
|
||||
team: '',
|
||||
itemType: null,
|
||||
itemId: null,
|
||||
grossWeight: null,
|
||||
netWeight: null,
|
||||
nextWarehouseId: null
|
||||
}
|
||||
],
|
||||
loading: false,
|
||||
// 钢卷选择器可见性
|
||||
coilSelectorVisible: false
|
||||
coilSelectorVisible: false,
|
||||
// 库区列表
|
||||
warehouseList: [],
|
||||
// 原材料和产品列表
|
||||
rawMaterialList: [],
|
||||
productList: [],
|
||||
itemSearchLoading: false,
|
||||
// 只读模式
|
||||
readonly: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 子卷总重量
|
||||
totalWeight() {
|
||||
return this.splitList.reduce((sum, item) => sum + (Number(item.weight) || 0), 0);
|
||||
},
|
||||
// 剩余重量
|
||||
remainWeight() {
|
||||
return (Number(this.motherCoil.weight) || 0) - this.totalWeight;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 如果URL中有coilId参数,则加载母卷信息
|
||||
async created() {
|
||||
// 先加载库区列表
|
||||
await this.loadWarehouses();
|
||||
|
||||
// 从路由参数获取coilId和readonly
|
||||
const coilId = this.$route.query.coilId;
|
||||
const readonly = this.$route.query.readonly;
|
||||
|
||||
if (coilId) {
|
||||
this.loadMotherCoil(coilId);
|
||||
await this.loadMotherCoil(coilId);
|
||||
}
|
||||
|
||||
// 设置只读模式
|
||||
if (readonly === 'true' || readonly === true) {
|
||||
this.readonly = true;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 获取子卷的物品列表
|
||||
getItemListForSplit(itemType) {
|
||||
if (itemType === 'raw_material') {
|
||||
return this.rawMaterialList.map(item => ({
|
||||
id: item.rawMaterialId,
|
||||
name: item.rawMaterialName
|
||||
}));
|
||||
} else if (itemType === 'product') {
|
||||
return this.productList.map(item => ({
|
||||
id: item.productId,
|
||||
name: item.productName
|
||||
}));
|
||||
}
|
||||
return [];
|
||||
},
|
||||
|
||||
// 物品类型变化
|
||||
handleItemTypeChange(index) {
|
||||
this.splitList[index].itemId = null;
|
||||
this.loadItemListForSplit(this.splitList[index].itemType);
|
||||
},
|
||||
|
||||
// 搜索子卷物品
|
||||
async searchItemsForSplit(query, index) {
|
||||
const itemType = this.splitList[index].itemType;
|
||||
if (!itemType) {
|
||||
this.$message.warning('请先选择物品类型');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
this.itemSearchLoading = true;
|
||||
if (itemType === 'raw_material') {
|
||||
const response = await listRawMaterial({
|
||||
rawMaterialName: query,
|
||||
pageNum: 1,
|
||||
pageSize: 50
|
||||
});
|
||||
if (response.code === 200) {
|
||||
this.rawMaterialList = response.rows || [];
|
||||
}
|
||||
} else if (itemType === 'product') {
|
||||
const response = await listProduct({
|
||||
productName: query,
|
||||
pageNum: 1,
|
||||
pageSize: 50
|
||||
});
|
||||
if (response.code === 200) {
|
||||
this.productList = response.rows || [];
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('搜索物品失败', error);
|
||||
} finally {
|
||||
this.itemSearchLoading = false;
|
||||
}
|
||||
},
|
||||
|
||||
// 加载子卷物品列表
|
||||
async loadItemListForSplit(itemType) {
|
||||
if (!itemType) return;
|
||||
|
||||
try {
|
||||
this.itemSearchLoading = true;
|
||||
if (itemType === 'raw_material') {
|
||||
const response = await listRawMaterial({ pageNum: 1, pageSize: 100 });
|
||||
if (response.code === 200) {
|
||||
this.rawMaterialList = response.rows || [];
|
||||
}
|
||||
} else if (itemType === 'product') {
|
||||
const response = await listProduct({ pageNum: 1, pageSize: 100 });
|
||||
if (response.code === 200) {
|
||||
this.productList = response.rows || [];
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载物品列表失败', error);
|
||||
} finally {
|
||||
this.itemSearchLoading = false;
|
||||
}
|
||||
},
|
||||
|
||||
// 显示钢卷选择器
|
||||
showCoilSelector() {
|
||||
this.coilSelectorVisible = true;
|
||||
@@ -200,17 +372,18 @@ export default {
|
||||
handleCoilSelect(coil) {
|
||||
this.motherCoil = {
|
||||
coilId: coil.coilId,
|
||||
enterCoilNo: coil.enterCoilNo || '',
|
||||
currentCoilNo: coil.currentCoilNo || '',
|
||||
grade: coil.grade || '',
|
||||
thickness: coil.thickness,
|
||||
width: coil.width,
|
||||
weight: coil.weight,
|
||||
team: coil.team || '',
|
||||
warehouseId: coil.warehouseId,
|
||||
team: coil.team,
|
||||
warehouseName: coil.warehouseName || '',
|
||||
itemType: coil.itemType,
|
||||
itemId: coil.itemId,
|
||||
enterCoilNo: coil.enterCoilNo || '',
|
||||
supplierCoilNo: coil.supplierCoilNo || ''
|
||||
materialName: coil.materialName || '',
|
||||
productName: coil.productName || '',
|
||||
grossWeight: coil.grossWeight,
|
||||
netWeight: coil.netWeight,
|
||||
bomItems: coil.bomItemList || coil.bomItems || []
|
||||
};
|
||||
this.$message.success('母卷选择成功');
|
||||
},
|
||||
@@ -224,17 +397,18 @@ export default {
|
||||
const data = response.data;
|
||||
this.motherCoil = {
|
||||
coilId: data.coilId,
|
||||
enterCoilNo: data.enterCoilNo || '',
|
||||
currentCoilNo: data.currentCoilNo || '',
|
||||
grade: data.grade || '',
|
||||
thickness: data.thickness,
|
||||
width: data.width,
|
||||
weight: data.weight,
|
||||
team: data.team || '',
|
||||
warehouseId: data.warehouseId,
|
||||
team: data.team,
|
||||
warehouseName: data.warehouseName || (data.warehouse ? data.warehouse.warehouseName : ''),
|
||||
itemType: data.itemType,
|
||||
itemId: data.itemId,
|
||||
enterCoilNo: data.enterCoilNo || '',
|
||||
supplierCoilNo: data.supplierCoilNo || ''
|
||||
materialName: data.materialName || (data.rawMaterial ? data.rawMaterial.rawMaterialName : ''),
|
||||
productName: data.productName || (data.product ? data.product.productName : ''),
|
||||
grossWeight: data.grossWeight,
|
||||
netWeight: data.netWeight,
|
||||
bomItems: data.bomItemList || data.bomItems || []
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -245,15 +419,32 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
// 加载库区列表
|
||||
async loadWarehouses() {
|
||||
try {
|
||||
const response = await listWarehouse({ pageNum: 1, pageSize: 1000 });
|
||||
if (response.code === 200) {
|
||||
this.warehouseList = response.rows || response.data || [];
|
||||
console.log('库区列表加载成功,数量:', this.warehouseList.length);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载库区列表失败', error);
|
||||
}
|
||||
},
|
||||
|
||||
// 添加子卷
|
||||
addSplitItem() {
|
||||
this.splitList.push({
|
||||
currentCoilNo: '',
|
||||
weight: 0,
|
||||
length: 0
|
||||
team: '',
|
||||
itemType: null,
|
||||
itemId: null,
|
||||
grossWeight: null,
|
||||
netWeight: null,
|
||||
nextWarehouseId: null
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
// 删除子卷
|
||||
removeSplitItem(index) {
|
||||
if (this.splitList.length > 1) {
|
||||
@@ -262,7 +453,7 @@ export default {
|
||||
this.$message.warning('至少保留一个子卷');
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// 保存分卷
|
||||
async handleSave() {
|
||||
// 验证母卷信息
|
||||
@@ -277,12 +468,6 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
// 验证重量
|
||||
if (this.remainWeight < 0) {
|
||||
this.$message.error('子卷总重量不能超过母卷重量');
|
||||
return;
|
||||
}
|
||||
|
||||
// 验证子卷信息
|
||||
for (let i = 0; i < this.splitList.length; i++) {
|
||||
const item = this.splitList[i];
|
||||
@@ -290,8 +475,28 @@ export default {
|
||||
this.$message.error(`第${i + 1}个子卷的卷号不能为空`);
|
||||
return;
|
||||
}
|
||||
if (!item.weight || item.weight <= 0) {
|
||||
this.$message.error(`第${i + 1}个子卷的重量必须大于0`);
|
||||
if (!item.team || item.team.trim() === '') {
|
||||
this.$message.error(`第${i + 1}个子卷的班组不能为空`);
|
||||
return;
|
||||
}
|
||||
if (!item.itemType) {
|
||||
this.$message.error(`第${i + 1}个子卷的物品类型不能为空`);
|
||||
return;
|
||||
}
|
||||
if (!item.itemId) {
|
||||
this.$message.error(`第${i + 1}个子卷的物品不能为空`);
|
||||
return;
|
||||
}
|
||||
if (item.grossWeight === null || item.grossWeight === undefined || item.grossWeight === '') {
|
||||
this.$message.error(`第${i + 1}个子卷的毛重不能为空`);
|
||||
return;
|
||||
}
|
||||
if (item.netWeight === null || item.netWeight === undefined || item.netWeight === '') {
|
||||
this.$message.error(`第${i + 1}个子卷的净重不能为空`);
|
||||
return;
|
||||
}
|
||||
if (!item.nextWarehouseId) {
|
||||
this.$message.error(`第${i + 1}个子卷的目标库区不能为空`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -302,24 +507,24 @@ export default {
|
||||
// 构造分卷数据
|
||||
const splitData = {
|
||||
coilId: this.motherCoil.coilId,
|
||||
enterCoilNo: this.motherCoil.enterCoilNo, // 入场钢卷号(必填)
|
||||
currentCoilNo: this.motherCoil.currentCoilNo,
|
||||
hasMergeSplit: 1, // 1表示分卷
|
||||
newCoils: this.splitList.map(item => ({
|
||||
enterCoilNo: this.motherCoil.enterCoilNo, // 子卷继承母卷的入场钢卷号
|
||||
currentCoilNo: item.currentCoilNo,
|
||||
weight: item.weight,
|
||||
length: item.length,
|
||||
hasMergeSplit: 1,
|
||||
// 继承母卷的基本信息
|
||||
grade: this.motherCoil.grade,
|
||||
thickness: this.motherCoil.thickness,
|
||||
width: this.motherCoil.width,
|
||||
warehouseId: this.motherCoil.warehouseId,
|
||||
team: this.motherCoil.team,
|
||||
itemType: this.motherCoil.itemType,
|
||||
itemId: this.motherCoil.itemId
|
||||
team: item.team,
|
||||
itemType: item.itemType || this.motherCoil.itemType,
|
||||
itemId: item.itemId || this.motherCoil.itemId,
|
||||
grossWeight: item.grossWeight,
|
||||
netWeight: item.netWeight,
|
||||
nextWarehouseId: item.nextWarehouseId,
|
||||
hasMergeSplit: 1
|
||||
}))
|
||||
};
|
||||
|
||||
console.log('提交的分卷数据:', splitData);
|
||||
|
||||
const response = await splitMaterialCoil(splitData);
|
||||
if (response.code === 200) {
|
||||
this.$message.success('分卷保存成功');
|
||||
@@ -337,10 +542,46 @@ export default {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// 取消操作
|
||||
handleCancel() {
|
||||
this.$router.back();
|
||||
},
|
||||
|
||||
// 复制到全部子卷
|
||||
copyToAllSubCoils() {
|
||||
if (!this.motherCoil.coilId) {
|
||||
this.$message.warning('请先加载母卷信息');
|
||||
return;
|
||||
}
|
||||
|
||||
// 复制到所有子卷
|
||||
this.splitList.forEach((item, index) => {
|
||||
// 自动生成卷号:母卷号-1, 母卷号-2, 母卷号-3...
|
||||
if (!item.currentCoilNo) {
|
||||
item.currentCoilNo = `${this.motherCoil.currentCoilNo}-${index + 1}`;
|
||||
}
|
||||
|
||||
// 复制班组
|
||||
if (!item.team) {
|
||||
item.team = this.motherCoil.team;
|
||||
}
|
||||
|
||||
// 复制物品类型和物品ID
|
||||
if (!item.itemType) {
|
||||
item.itemType = this.motherCoil.itemType;
|
||||
}
|
||||
if (!item.itemId) {
|
||||
item.itemId = this.motherCoil.itemId;
|
||||
}
|
||||
});
|
||||
|
||||
// 加载物品列表
|
||||
if (this.motherCoil.itemType) {
|
||||
this.loadItemListForSplit(this.motherCoil.itemType);
|
||||
}
|
||||
|
||||
this.$message.success('已复制到所有子卷');
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -372,7 +613,7 @@ export default {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
|
||||
|
||||
i {
|
||||
color: #0066cc;
|
||||
font-size: 20px;
|
||||
@@ -418,7 +659,7 @@ export default {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
|
||||
.el-button--text {
|
||||
font-size: 12px;
|
||||
}
|
||||
@@ -444,15 +685,15 @@ export default {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
|
||||
|
||||
i {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.coil-id {
|
||||
|
||||
.coil-title {
|
||||
flex: 1;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -462,24 +703,27 @@ export default {
|
||||
|
||||
.coil-info-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 12px;
|
||||
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
|
||||
.label {
|
||||
color: #909399;
|
||||
font-size: 14px;
|
||||
min-width: 70px;
|
||||
min-width: 100px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
|
||||
.value {
|
||||
color: #303133;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
|
||||
flex: 1;
|
||||
word-break: break-all;
|
||||
|
||||
&.highlight {
|
||||
color: #0066cc;
|
||||
font-size: 16px;
|
||||
@@ -488,6 +732,30 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
/* BOM参数展示 */
|
||||
.bom-params {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.param-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 13px;
|
||||
|
||||
.param-name {
|
||||
color: #909399;
|
||||
min-width: 80px;
|
||||
}
|
||||
|
||||
.param-value {
|
||||
color: #303133;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
/* 流程箭头 */
|
||||
.flow-arrow-container {
|
||||
position: absolute;
|
||||
@@ -549,11 +817,11 @@ export default {
|
||||
overflow-y: auto;
|
||||
margin-bottom: 20px;
|
||||
padding-right: 10px;
|
||||
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: #dcdfe6;
|
||||
border-radius: 3px;
|
||||
@@ -566,7 +834,7 @@ export default {
|
||||
border-radius: 8px;
|
||||
margin-bottom: 16px;
|
||||
transition: all 0.3s;
|
||||
|
||||
|
||||
&:hover {
|
||||
border-color: #0066cc;
|
||||
box-shadow: 0 2px 8px rgba(0, 102, 204, 0.15);
|
||||
@@ -598,7 +866,7 @@ export default {
|
||||
.btn-remove {
|
||||
color: #f56c6c;
|
||||
padding: 0;
|
||||
|
||||
|
||||
&:hover {
|
||||
color: #f56c6c;
|
||||
}
|
||||
@@ -634,10 +902,41 @@ export default {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #0066cc;
|
||||
|
||||
|
||||
&.error {
|
||||
color: #f56c6c;
|
||||
}
|
||||
}
|
||||
|
||||
// 优化按钮文字颜色
|
||||
// 实心primary按钮:白色文字
|
||||
::v-deep .el-button--primary.el-button--small:not(.is-plain) {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
// plain按钮和text按钮:蓝色文字
|
||||
::v-deep .el-button--primary.el-button--small.is-plain,
|
||||
::v-deep .el-button--text {
|
||||
color: #409eff;
|
||||
|
||||
&:hover {
|
||||
color: #66b1ff;
|
||||
}
|
||||
}
|
||||
|
||||
// 修复数字输入框的上下箭头溢出
|
||||
.sub-coil-body {
|
||||
::v-deep input[type="number"] {
|
||||
appearance: textfield;
|
||||
-moz-appearance: textfield;
|
||||
|
||||
&::-webkit-outer-spin-button,
|
||||
&::-webkit-inner-spin-button {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
843
klp-ui/src/views/wms/coil/typing.vue
Normal file
843
klp-ui/src/views/wms/coil/typing.vue
Normal file
@@ -0,0 +1,843 @@
|
||||
<template>
|
||||
<div class="typing-coil-container">
|
||||
<!-- 顶部操作栏 -->
|
||||
<div class="header-bar">
|
||||
<div class="header-title">
|
||||
<i class="el-icon-edit"></i>
|
||||
<span>钢卷信息更新</span>
|
||||
</div>
|
||||
<div class="header-actions">
|
||||
<el-button v-if="!readonly" type="primary" size="small" @click="handleSave" :loading="loading">保存更新</el-button>
|
||||
<el-button size="small" @click="handleCancel" :disabled="loading">{{ readonly ? '返回' : '取消' }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 主内容区 - 左右布局 -->
|
||||
<div class="content-wrapper">
|
||||
<!-- 左侧:当前信息 -->
|
||||
<div class="left-panel">
|
||||
<el-card class="info-card">
|
||||
<div slot="header" class="card-header">
|
||||
<span><i class="el-icon-info"></i> 当前信息</span>
|
||||
</div>
|
||||
|
||||
<div class="info-section">
|
||||
<div class="info-row">
|
||||
<span class="info-label">入场钢卷号:</span>
|
||||
<span class="info-value">{{ currentInfo.enterCoilNo || '—' }}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">当前钢卷号:</span>
|
||||
<span class="info-value">{{ currentInfo.currentCoilNo || '—' }}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">厂家原料卷号:</span>
|
||||
<span class="info-value">{{ currentInfo.supplierCoilNo || '—' }}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">班组:</span>
|
||||
<span class="info-value">{{ currentInfo.team || '—' }}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">物品类型:</span>
|
||||
<span class="info-value">{{ getItemTypeText(currentInfo.itemType) }}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">物料名称:</span>
|
||||
<span class="info-value">{{ currentInfo.itemName || '—' }}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">毛重:</span>
|
||||
<span class="info-value">{{ currentInfo.grossWeight ? currentInfo.grossWeight + ' t' : '—' }}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">净重:</span>
|
||||
<span class="info-value">{{ currentInfo.netWeight ? currentInfo.netWeight + ' t' : '—' }}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">目标库区:</span>
|
||||
<span class="info-value">{{ currentInfo.nextWarehouseName || '—' }}</span>
|
||||
</div>
|
||||
<div class="info-row" v-if="currentInfo.remark">
|
||||
<span class="info-label">备注:</span>
|
||||
<span class="info-value">{{ currentInfo.remark }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
<!-- 右侧:更新表单 -->
|
||||
<div class="right-panel">
|
||||
<el-card class="form-card">
|
||||
<div slot="header" class="card-header">
|
||||
<span><i class="el-icon-edit-outline"></i> {{ readonly ? '查看信息' : '更新信息' }}</span>
|
||||
<el-button v-if="!readonly" type="text" size="mini" @click="copyFromCurrent" icon="el-icon-document-copy">
|
||||
复制当前信息
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<el-form
|
||||
ref="updateForm"
|
||||
:model="updateForm"
|
||||
:rules="rules"
|
||||
label-width="120px"
|
||||
size="small"
|
||||
>
|
||||
<el-form-item label="当前钢卷号" prop="currentCoilNo">
|
||||
<el-input
|
||||
v-model="updateForm.currentCoilNo"
|
||||
placeholder="请输入当前钢卷号"
|
||||
:disabled="readonly"
|
||||
>
|
||||
<template slot="prepend">
|
||||
<i class="el-icon-document"></i>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="班组" prop="team">
|
||||
<el-input
|
||||
v-model="updateForm.team"
|
||||
placeholder="请输入班组名称"
|
||||
:disabled="readonly"
|
||||
>
|
||||
<template slot="prepend">
|
||||
<i class="el-icon-user-solid"></i>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="物品类型" prop="itemType">
|
||||
<el-select
|
||||
v-model="updateForm.itemType"
|
||||
placeholder="请选择物品类型"
|
||||
style="width: 100%"
|
||||
:disabled="readonly"
|
||||
>
|
||||
<el-option label="原材料" value="raw_material" />
|
||||
<el-option label="产品" value="product" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="物品" prop="itemId">
|
||||
<el-select
|
||||
v-model="updateForm.itemId"
|
||||
placeholder="请选择物品"
|
||||
filterable
|
||||
remote
|
||||
:remote-method="searchItems"
|
||||
:loading="itemSearchLoading"
|
||||
style="width: 100%"
|
||||
:disabled="readonly"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in currentItemList"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="毛重(t)" prop="grossWeight">
|
||||
<el-input
|
||||
v-model.number="updateForm.grossWeight"
|
||||
placeholder="请输入毛重"
|
||||
type="number"
|
||||
step="0.01"
|
||||
:disabled="readonly"
|
||||
>
|
||||
<template slot="append">吨</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="净重(t)" prop="netWeight">
|
||||
<el-input
|
||||
v-model.number="updateForm.netWeight"
|
||||
placeholder="请输入净重"
|
||||
type="number"
|
||||
step="0.01"
|
||||
:disabled="readonly"
|
||||
>
|
||||
<template slot="append">吨</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="目标库区" prop="nextWarehouseId">
|
||||
<el-select
|
||||
v-model="updateForm.nextWarehouseId"
|
||||
placeholder="请选择目标库区"
|
||||
style="width: 100%"
|
||||
filterable
|
||||
:disabled="readonly"
|
||||
>
|
||||
<el-option
|
||||
v-for="warehouse in warehouseList"
|
||||
:key="warehouse.warehouseId"
|
||||
:label="warehouse.warehouseName"
|
||||
:value="warehouse.warehouseId"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input
|
||||
v-model="updateForm.remark"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder="请输入备注信息(非必填)"
|
||||
maxlength="500"
|
||||
show-word-limit
|
||||
:disabled="readonly"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 变更历史(占满整行) -->
|
||||
<div class="history-section">
|
||||
<el-card class="history-card">
|
||||
<div slot="header" class="card-header">
|
||||
<span><i class="el-icon-time"></i> 变更历史</span>
|
||||
<el-button type="text" size="mini" @click="loadHistory" :loading="historyLoading">
|
||||
<i class="el-icon-refresh"></i> 刷新
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<el-timeline v-if="historySteps.length > 0">
|
||||
<el-timeline-item
|
||||
v-for="(step, index) in historySteps"
|
||||
:key="index"
|
||||
:timestamp="`步骤 ${step.display_step || step.step}`"
|
||||
placement="top"
|
||||
:type="step.operation === '新增' ? 'success' : 'primary'"
|
||||
>
|
||||
<div class="history-item">
|
||||
<div class="history-title">{{ step.operation || step.action }}</div>
|
||||
<div class="history-detail" v-if="step.operator">
|
||||
<span class="detail-label">操作人:</span>
|
||||
<span>{{ step.operator }}</span>
|
||||
</div>
|
||||
<div class="history-detail" v-if="step.old_current_coil_no">
|
||||
<span class="detail-label">原钢卷号:</span>
|
||||
<span>{{ step.old_current_coil_no }}</span>
|
||||
</div>
|
||||
<div class="history-detail" v-if="step.new_current_coil_no">
|
||||
<span class="detail-label">新钢卷号:</span>
|
||||
<span>{{ step.new_current_coil_no }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
|
||||
<div v-else class="empty-history">
|
||||
<i class="el-icon-document"></i>
|
||||
<p>暂无变更历史</p>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getMaterialCoil, updateMaterialCoil, getMaterialCoilTrace } from '@/api/wms/coil';
|
||||
import { completeAction } from '@/api/wms/pendingAction';
|
||||
import { listWarehouse } from '@/api/wms/warehouse';
|
||||
import { listRawMaterial } from '@/api/wms/rawMaterial';
|
||||
import { listProduct } from '@/api/wms/product';
|
||||
|
||||
export default {
|
||||
name: 'TypingCoil',
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
historyLoading: false,
|
||||
// 当前信息(只读)
|
||||
currentInfo: {
|
||||
coilId: null,
|
||||
enterCoilNo: '',
|
||||
currentCoilNo: '',
|
||||
supplierCoilNo: '',
|
||||
team: '',
|
||||
itemType: null,
|
||||
itemId: null,
|
||||
itemName: '',
|
||||
grossWeight: null,
|
||||
netWeight: null,
|
||||
warehouseId: null,
|
||||
nextWarehouseId: null,
|
||||
nextWarehouseName: '',
|
||||
status: 0,
|
||||
remark: ''
|
||||
},
|
||||
// 更新表单
|
||||
updateForm: {
|
||||
currentCoilNo: '',
|
||||
team: '',
|
||||
itemType: null,
|
||||
itemId: null,
|
||||
grossWeight: null,
|
||||
netWeight: null,
|
||||
nextWarehouseId: null,
|
||||
remark: ''
|
||||
},
|
||||
rules: {
|
||||
currentCoilNo: [
|
||||
{ required: true, message: '请输入当前钢卷号', trigger: 'blur' }
|
||||
],
|
||||
team: [
|
||||
{ required: true, message: '请输入班组', trigger: 'blur' }
|
||||
],
|
||||
itemType: [
|
||||
{ required: true, message: '请选择物品类型', trigger: 'change' }
|
||||
],
|
||||
itemId: [
|
||||
{ required: true, message: '请选择物品', trigger: 'change' }
|
||||
],
|
||||
grossWeight: [
|
||||
{ required: true, message: '请输入毛重', trigger: 'blur' },
|
||||
{ type: 'number', message: '毛重必须为数字', trigger: 'blur' }
|
||||
],
|
||||
netWeight: [
|
||||
{ required: true, message: '请输入净重', trigger: 'blur' },
|
||||
{ type: 'number', message: '净重必须为数字', trigger: 'blur' }
|
||||
],
|
||||
nextWarehouseId: [
|
||||
{ required: true, message: '请选择目标库区', trigger: 'change' }
|
||||
]
|
||||
},
|
||||
warehouseList: [],
|
||||
historySteps: [],
|
||||
actionId: null,
|
||||
// 原材料和产品列表
|
||||
rawMaterialList: [],
|
||||
productList: [],
|
||||
itemSearchLoading: false,
|
||||
// 只读模式
|
||||
readonly: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 当前物品列表(根据物品类型动态切换)
|
||||
currentItemList() {
|
||||
if (this.updateForm.itemType === 'raw_material') {
|
||||
return this.rawMaterialList.map(item => ({
|
||||
id: item.rawMaterialId,
|
||||
name: item.rawMaterialName
|
||||
}));
|
||||
} else if (this.updateForm.itemType === 'product') {
|
||||
return this.productList.map(item => ({
|
||||
id: item.productId,
|
||||
name: item.productName
|
||||
}));
|
||||
}
|
||||
return [];
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
// 监听物品类型变化,加载对应的列表
|
||||
'updateForm.itemType'(newVal, oldVal) {
|
||||
if (newVal !== oldVal) {
|
||||
this.updateForm.itemId = null;
|
||||
this.loadItemList(newVal);
|
||||
}
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
// 先加载库区列表
|
||||
await this.loadWarehouses();
|
||||
|
||||
// 从路由参数获取coilId和actionId
|
||||
const coilId = this.$route.query.coilId;
|
||||
const actionId = this.$route.query.actionId;
|
||||
const readonly = this.$route.query.readonly;
|
||||
|
||||
if (coilId) {
|
||||
await this.loadCoilInfo(coilId);
|
||||
}
|
||||
|
||||
if (actionId) {
|
||||
this.actionId = actionId;
|
||||
}
|
||||
|
||||
// 设置只读模式
|
||||
if (readonly === 'true' || readonly === true) {
|
||||
this.readonly = true;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 加载钢卷信息
|
||||
async loadCoilInfo(coilId) {
|
||||
try {
|
||||
this.loading = true;
|
||||
const response = await getMaterialCoil(coilId);
|
||||
if (response.code === 200 && response.data) {
|
||||
const data = response.data;
|
||||
|
||||
// 填充当前信息(左侧)
|
||||
this.currentInfo = {
|
||||
coilId: data.coilId,
|
||||
enterCoilNo: data.enterCoilNo || '',
|
||||
currentCoilNo: data.currentCoilNo || '',
|
||||
supplierCoilNo: data.supplierCoilNo || '',
|
||||
team: data.team || '',
|
||||
itemType: data.itemType || null,
|
||||
itemId: data.itemId || null,
|
||||
itemName: this.getItemName(data),
|
||||
grossWeight: data.grossWeight,
|
||||
netWeight: data.netWeight,
|
||||
warehouseId: data.warehouseId,
|
||||
nextWarehouseId: data.nextWarehouseId,
|
||||
nextWarehouseName: this.getWarehouseName(data.nextWarehouseId),
|
||||
remark: data.remark || ''
|
||||
};
|
||||
|
||||
console.log('当前信息加载完成:', this.currentInfo);
|
||||
|
||||
// 重新获取库区名称(确保warehouseList已加载)
|
||||
if (data.nextWarehouseId) {
|
||||
this.currentInfo.nextWarehouseName = this.getWarehouseName(data.nextWarehouseId);
|
||||
}
|
||||
|
||||
// 加载对应类型的物品列表
|
||||
if (data.itemType) {
|
||||
await this.loadItemList(data.itemType);
|
||||
}
|
||||
|
||||
// 加载变更历史
|
||||
this.loadHistory();
|
||||
}
|
||||
} catch (error) {
|
||||
this.$message.error('加载钢卷信息失败');
|
||||
console.error(error);
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
// 获取物料名称
|
||||
getItemName(data) {
|
||||
if (data.rawMaterial) {
|
||||
return data.rawMaterial.rawMaterialName;
|
||||
} else if (data.product) {
|
||||
return data.product.productName;
|
||||
}
|
||||
return '';
|
||||
},
|
||||
|
||||
// 获取物品类型文本
|
||||
getItemTypeText(itemType) {
|
||||
if (itemType === 'raw_material') return '原材料';
|
||||
if (itemType === 'product') return '产品';
|
||||
return '—';
|
||||
},
|
||||
|
||||
// 获取库区名称
|
||||
getWarehouseName(warehouseId) {
|
||||
if (!warehouseId) return '';
|
||||
const warehouse = this.warehouseList.find(w => w.warehouseId === warehouseId);
|
||||
return warehouse ? warehouse.warehouseName : '';
|
||||
},
|
||||
|
||||
// 加载库区列表
|
||||
async loadWarehouses() {
|
||||
try {
|
||||
const response = await listWarehouse({ pageNum: 1, pageSize: 1000 });
|
||||
if (response.code === 200) {
|
||||
this.warehouseList = response.rows || response.data || [];
|
||||
console.log('库区列表加载成功,数量:', this.warehouseList.length);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载库区列表失败', error);
|
||||
}
|
||||
},
|
||||
|
||||
// 加载物品列表(根据类型)
|
||||
async loadItemList(itemType) {
|
||||
if (!itemType) return;
|
||||
|
||||
try {
|
||||
this.itemSearchLoading = true;
|
||||
if (itemType === 'raw_material') {
|
||||
const response = await listRawMaterial({ pageNum: 1, pageSize: 100 });
|
||||
if (response.code === 200) {
|
||||
this.rawMaterialList = response.rows || [];
|
||||
}
|
||||
} else if (itemType === 'product') {
|
||||
const response = await listProduct({ pageNum: 1, pageSize: 100 });
|
||||
if (response.code === 200) {
|
||||
this.productList = response.rows || [];
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载物品列表失败', error);
|
||||
} finally {
|
||||
this.itemSearchLoading = false;
|
||||
}
|
||||
},
|
||||
|
||||
// 搜索物品
|
||||
async searchItems(query) {
|
||||
if (!this.updateForm.itemType) {
|
||||
this.$message.warning('请先选择物品类型');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
this.itemSearchLoading = true;
|
||||
if (this.updateForm.itemType === 'raw_material') {
|
||||
const response = await listRawMaterial({
|
||||
rawMaterialName: query,
|
||||
pageNum: 1,
|
||||
pageSize: 50
|
||||
});
|
||||
if (response.code === 200) {
|
||||
this.rawMaterialList = response.rows || [];
|
||||
}
|
||||
} else if (this.updateForm.itemType === 'product') {
|
||||
const response = await listProduct({
|
||||
productName: query,
|
||||
pageNum: 1,
|
||||
pageSize: 50
|
||||
});
|
||||
if (response.code === 200) {
|
||||
this.productList = response.rows || [];
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('搜索物品失败', error);
|
||||
} finally {
|
||||
this.itemSearchLoading = false;
|
||||
}
|
||||
},
|
||||
|
||||
// 物品选择变化
|
||||
handleItemChange(itemId) {
|
||||
console.log('选择的物品ID:', itemId);
|
||||
},
|
||||
|
||||
// 加载变更历史
|
||||
async loadHistory() {
|
||||
if (!this.currentInfo.enterCoilNo) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
this.historyLoading = true;
|
||||
const response = await getMaterialCoilTrace({
|
||||
enterCoilNo: this.currentInfo.enterCoilNo,
|
||||
currentCoilNo: this.currentInfo.currentCoilNo || undefined
|
||||
});
|
||||
|
||||
if (response.code === 200 && response.data) {
|
||||
this.historySteps = response.data.steps || [];
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载变更历史失败', error);
|
||||
} finally {
|
||||
this.historyLoading = false;
|
||||
}
|
||||
},
|
||||
|
||||
// 复制当前信息到更新表单
|
||||
copyFromCurrent() {
|
||||
this.updateForm = {
|
||||
currentCoilNo: this.currentInfo.currentCoilNo,
|
||||
team: this.currentInfo.team,
|
||||
itemType: this.currentInfo.itemType,
|
||||
itemId: this.currentInfo.itemId,
|
||||
grossWeight: parseFloat(this.currentInfo.grossWeight) || null,
|
||||
netWeight: parseFloat(this.currentInfo.netWeight) || null,
|
||||
nextWarehouseId: this.currentInfo.nextWarehouseId,
|
||||
remark: this.currentInfo.remark
|
||||
};
|
||||
|
||||
console.log('复制的表单数据:', this.updateForm);
|
||||
|
||||
// 加载对应的物品列表
|
||||
if (this.updateForm.itemType) {
|
||||
this.loadItemList(this.updateForm.itemType);
|
||||
}
|
||||
|
||||
this.$message.success('已复制当前信息');
|
||||
},
|
||||
|
||||
// 保存更新
|
||||
async handleSave() {
|
||||
this.$refs.updateForm.validate(async (valid) => {
|
||||
if (!valid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
this.loading = true;
|
||||
|
||||
// 构造更新数据(使用标准update接口,会创建历史版本)
|
||||
const updateData = {
|
||||
coilId: this.currentInfo.coilId,
|
||||
enterCoilNo: this.currentInfo.enterCoilNo, // 入场钢卷号,从当前信息获取(必填)
|
||||
supplierCoilNo: this.currentInfo.supplierCoilNo, // 厂家原料卷号(保持不变)
|
||||
currentCoilNo: this.updateForm.currentCoilNo,
|
||||
team: this.updateForm.team,
|
||||
itemType: this.updateForm.itemType,
|
||||
itemId: this.updateForm.itemId,
|
||||
grossWeight: this.updateForm.grossWeight,
|
||||
netWeight: this.updateForm.netWeight,
|
||||
warehouseId: this.currentInfo.warehouseId, // 当前库区ID(保持不变)
|
||||
nextWarehouseId: this.updateForm.nextWarehouseId, // 目标库区ID
|
||||
remark: this.updateForm.remark
|
||||
};
|
||||
|
||||
console.log('提交的更新数据:', updateData);
|
||||
|
||||
const response = await updateMaterialCoil(updateData);
|
||||
|
||||
if (response.code === 200) {
|
||||
this.$message.success('钢卷信息更新成功');
|
||||
|
||||
// 如果是从待操作列表进来的,标记操作为完成
|
||||
if (this.actionId) {
|
||||
await completeAction(this.actionId);
|
||||
}
|
||||
|
||||
// 延迟返回
|
||||
setTimeout(() => {
|
||||
this.$router.back();
|
||||
}, 1000);
|
||||
} else {
|
||||
this.$message.error(response.msg || '更新失败');
|
||||
}
|
||||
} catch (error) {
|
||||
this.$message.error('更新失败');
|
||||
console.error(error);
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 取消操作
|
||||
handleCancel() {
|
||||
this.$router.back();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.typing-coil-container {
|
||||
padding: 20px;
|
||||
background: #f5f7fa;
|
||||
min-height: calc(100vh - 84px);
|
||||
}
|
||||
|
||||
/* 顶部操作栏 */
|
||||
.header-bar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background: #fff;
|
||||
padding: 16px 20px;
|
||||
margin-bottom: 20px;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
color: #303133;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
|
||||
i {
|
||||
color: #0066cc;
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 主内容区 */
|
||||
.content-wrapper {
|
||||
display: grid;
|
||||
grid-template-columns: 400px 1fr;
|
||||
gap: 20px;
|
||||
align-items: stretch; // 改为stretch,让子元素高度一致
|
||||
}
|
||||
|
||||
/* 左侧面板 */
|
||||
.left-panel {
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 右侧面板 */
|
||||
.right-panel {
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 确保两侧卡片高度一致 */
|
||||
.info-card,
|
||||
.form-card {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
::v-deep .el-card__body {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
/* 变更历史区域(占满整行) */
|
||||
.history-section {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
/* 卡片头部 */
|
||||
.card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-weight: 500;
|
||||
|
||||
i {
|
||||
color: #0066cc;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 当前信息展示 */
|
||||
.info-section {
|
||||
.info-row {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 12px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
color: #909399;
|
||||
font-size: 14px;
|
||||
min-width: 110px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
color: #303133;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
flex: 1;
|
||||
word-break: break-all;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 变更历史 */
|
||||
.history-card {
|
||||
::v-deep .el-card__body {
|
||||
max-height: 400px;
|
||||
overflow-y: auto;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: #dcdfe6;
|
||||
border-radius: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .el-timeline {
|
||||
padding-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.history-item {
|
||||
.history-title {
|
||||
font-weight: 500;
|
||||
color: #303133;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.history-detail {
|
||||
font-size: 13px;
|
||||
color: #606266;
|
||||
margin-bottom: 4px;
|
||||
|
||||
.detail-label {
|
||||
color: #909399;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.empty-history {
|
||||
text-align: center;
|
||||
padding: 40px 0;
|
||||
color: #909399;
|
||||
|
||||
i {
|
||||
font-size: 48px;
|
||||
margin-bottom: 10px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* 表单样式优化 */
|
||||
.form-card {
|
||||
::v-deep .el-input-number {
|
||||
width: 100%;
|
||||
|
||||
.el-input__inner {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .el-form-item {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
// 修复数字输入框的样式
|
||||
::v-deep input[type="number"] {
|
||||
appearance: textfield;
|
||||
-moz-appearance: textfield;
|
||||
|
||||
&::-webkit-outer-spin-button,
|
||||
&::-webkit-inner-spin-button {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 优化按钮文字颜色
|
||||
// 实心primary按钮:白色文字
|
||||
::v-deep .el-button--primary.el-button--small:not(.is-plain) {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
// plain按钮和text按钮:蓝色文字
|
||||
::v-deep .el-button--primary.el-button--small.is-plain,
|
||||
::v-deep .el-button--text {
|
||||
color: #409eff;
|
||||
|
||||
&:hover {
|
||||
color: #66b1ff;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,137 @@
|
||||
package com.klp.controller;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Arrays;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.constraints.*;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import com.klp.common.annotation.RepeatSubmit;
|
||||
import com.klp.common.annotation.Log;
|
||||
import com.klp.common.core.controller.BaseController;
|
||||
import com.klp.common.core.domain.PageQuery;
|
||||
import com.klp.common.core.domain.R;
|
||||
import com.klp.common.core.validate.AddGroup;
|
||||
import com.klp.common.core.validate.EditGroup;
|
||||
import com.klp.common.enums.BusinessType;
|
||||
import com.klp.common.utils.poi.ExcelUtil;
|
||||
import com.klp.domain.vo.WmsCoilPendingActionVo;
|
||||
import com.klp.domain.bo.WmsCoilPendingActionBo;
|
||||
import com.klp.service.IWmsCoilPendingActionService;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
|
||||
/**
|
||||
* 钢卷待操作
|
||||
*
|
||||
* @author Joshi
|
||||
* @date 2025-11-03
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/wms/coilPendingAction")
|
||||
public class WmsCoilPendingActionController extends BaseController {
|
||||
|
||||
private final IWmsCoilPendingActionService iWmsCoilPendingActionService;
|
||||
|
||||
/**
|
||||
* 查询钢卷待操作列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<WmsCoilPendingActionVo> list(WmsCoilPendingActionBo bo, PageQuery pageQuery) {
|
||||
return iWmsCoilPendingActionService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出钢卷待操作列表
|
||||
*/
|
||||
@Log(title = "钢卷待操作", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(WmsCoilPendingActionBo bo, HttpServletResponse response) {
|
||||
List<WmsCoilPendingActionVo> list = iWmsCoilPendingActionService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "钢卷待操作", WmsCoilPendingActionVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取钢卷待操作详细信息
|
||||
*
|
||||
* @param actionId 主键
|
||||
*/
|
||||
@GetMapping("/{actionId}")
|
||||
public R<WmsCoilPendingActionVo> getInfo(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long actionId) {
|
||||
return R.ok(iWmsCoilPendingActionService.queryById(actionId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增钢卷待操作
|
||||
*/
|
||||
@Log(title = "钢卷待操作", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping()
|
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody WmsCoilPendingActionBo bo) {
|
||||
return toAjax(iWmsCoilPendingActionService.insertByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改钢卷待操作
|
||||
*/
|
||||
@Log(title = "钢卷待操作", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping()
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody WmsCoilPendingActionBo bo) {
|
||||
return toAjax(iWmsCoilPendingActionService.updateByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除钢卷待操作
|
||||
*
|
||||
* @param actionIds 主键串
|
||||
*/
|
||||
@Log(title = "钢卷待操作", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{actionIds}")
|
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||
@PathVariable("actionIds") Long[] actionIds) {
|
||||
return toAjax(iWmsCoilPendingActionService.deleteWithValidByIds(Arrays.asList(actionIds), true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新操作状态
|
||||
*/
|
||||
@Log(title = "钢卷待操作", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/status/{actionId}/{status}")
|
||||
public R<Void> updateStatus(@PathVariable("actionId") Long actionId,
|
||||
@PathVariable("status") Integer status) {
|
||||
return toAjax(iWmsCoilPendingActionService.updateStatus(actionId, status));
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始处理操作
|
||||
*/
|
||||
@Log(title = "钢卷待操作", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/start/{actionId}")
|
||||
public R<Void> startProcess(@PathVariable("actionId") Long actionId) {
|
||||
return toAjax(iWmsCoilPendingActionService.startProcess(actionId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 完成操作
|
||||
*/
|
||||
@Log(title = "钢卷待操作", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/complete/{actionId}")
|
||||
public R<Void> completeAction(@PathVariable("actionId") Long actionId) {
|
||||
return toAjax(iWmsCoilPendingActionService.completeAction(actionId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消操作
|
||||
*/
|
||||
@Log(title = "钢卷待操作", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/cancel/{actionId}")
|
||||
public R<Void> cancelAction(@PathVariable("actionId") Long actionId) {
|
||||
return toAjax(iWmsCoilPendingActionService.cancelAction(actionId));
|
||||
}
|
||||
}
|
||||
|
||||
100
klp-wms/src/main/java/com/klp/domain/WmsCoilPendingAction.java
Normal file
100
klp-wms/src/main/java/com/klp/domain/WmsCoilPendingAction.java
Normal file
@@ -0,0 +1,100 @@
|
||||
package com.klp.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.klp.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 钢卷待操作对象 wms_coil_pending_action
|
||||
*
|
||||
* @author Joshi
|
||||
* @date 2025-11-03
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("wms_coil_pending_action")
|
||||
public class WmsCoilPendingAction extends BaseEntity {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
@TableId(value = "action_id", type = IdType.AUTO)
|
||||
private Long actionId;
|
||||
|
||||
/**
|
||||
* 关联的钢卷ID
|
||||
*/
|
||||
private Long coilId;
|
||||
|
||||
/**
|
||||
* 当前钢卷号
|
||||
*/
|
||||
private String currentCoilNo;
|
||||
|
||||
/**
|
||||
* 操作类型(1=分卷,2=合卷,3=更新)
|
||||
*/
|
||||
private Integer actionType;
|
||||
|
||||
/**
|
||||
* 操作状态(0=待处理,1=处理中,2=已完成,3=已取消)
|
||||
*/
|
||||
private Integer actionStatus;
|
||||
|
||||
/**
|
||||
* 扫码时间
|
||||
*/
|
||||
private Date scanTime;
|
||||
|
||||
/**
|
||||
* 扫码设备(移动端设备信息)
|
||||
*/
|
||||
private String scanDevice;
|
||||
|
||||
/**
|
||||
* 优先级(0=普通,1=重要,2=紧急)
|
||||
*/
|
||||
private Integer priority;
|
||||
|
||||
/**
|
||||
* 来源类型(scan=扫码,manual=手动创建)
|
||||
*/
|
||||
private String sourceType;
|
||||
|
||||
/**
|
||||
* 所在库区ID
|
||||
*/
|
||||
private Long warehouseId;
|
||||
|
||||
/**
|
||||
* 操作人ID
|
||||
*/
|
||||
private Long operatorId;
|
||||
|
||||
/**
|
||||
* 操作人姓名
|
||||
*/
|
||||
private String operatorName;
|
||||
|
||||
/**
|
||||
* 处理时间
|
||||
*/
|
||||
private Date processTime;
|
||||
|
||||
/**
|
||||
* 完成时间
|
||||
*/
|
||||
private Date completeTime;
|
||||
|
||||
/**
|
||||
* 删除标志(0=正常,1=已删除)
|
||||
*/
|
||||
@TableLogic
|
||||
private Integer delFlag;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
package com.klp.domain.bo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.klp.common.core.validate.AddGroup;
|
||||
import com.klp.common.core.validate.EditGroup;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import javax.validation.constraints.*;
|
||||
import java.util.Date;
|
||||
import com.klp.common.core.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 钢卷待操作业务对象 wms_coil_pending_action
|
||||
*
|
||||
* @author Joshi
|
||||
* @date 2025-11-03
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class WmsCoilPendingActionBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
@NotNull(message = "主键ID不能为空", groups = { EditGroup.class })
|
||||
private Long actionId;
|
||||
|
||||
/**
|
||||
* 关联的钢卷ID
|
||||
*/
|
||||
@NotNull(message = "关联的钢卷ID不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private Long coilId;
|
||||
|
||||
/**
|
||||
* 当前钢卷号
|
||||
*/
|
||||
@NotBlank(message = "当前钢卷号不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private String currentCoilNo;
|
||||
|
||||
/**
|
||||
* 操作类型(1=分卷,2=合卷,3=更新)
|
||||
*/
|
||||
@NotNull(message = "操作类型不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private Integer actionType;
|
||||
|
||||
/**
|
||||
* 操作状态(0=待处理,1=处理中,2=已完成,3=已取消)
|
||||
*/
|
||||
private Integer actionStatus;
|
||||
|
||||
/**
|
||||
* 扫码时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSX", timezone = "GMT+8")
|
||||
private Date scanTime;
|
||||
|
||||
/**
|
||||
* 扫码设备(移动端设备信息)
|
||||
*/
|
||||
private String scanDevice;
|
||||
|
||||
/**
|
||||
* 优先级(0=普通,1=重要,2=紧急)
|
||||
*/
|
||||
private Integer priority;
|
||||
|
||||
/**
|
||||
* 来源类型(scan=扫码,manual=手动创建)
|
||||
*/
|
||||
private String sourceType;
|
||||
|
||||
/**
|
||||
* 所在库区ID
|
||||
*/
|
||||
private Long warehouseId;
|
||||
|
||||
/**
|
||||
* 操作人ID
|
||||
*/
|
||||
private Long operatorId;
|
||||
|
||||
/**
|
||||
* 操作人姓名
|
||||
*/
|
||||
private String operatorName;
|
||||
|
||||
/**
|
||||
* 处理时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSX", timezone = "GMT+8")
|
||||
private Date processTime;
|
||||
|
||||
/**
|
||||
* 完成时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSX", timezone = "GMT+8")
|
||||
private Date completeTime;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
package com.klp.domain.vo;
|
||||
|
||||
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 lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 钢卷待操作视图对象 wms_coil_pending_action
|
||||
*
|
||||
* @author Joshi
|
||||
* @date 2025-11-03
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class WmsCoilPendingActionVo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
@ExcelProperty(value = "主键ID")
|
||||
private Long actionId;
|
||||
|
||||
/**
|
||||
* 关联的钢卷ID
|
||||
*/
|
||||
@ExcelProperty(value = "钢卷ID")
|
||||
private Long coilId;
|
||||
|
||||
/**
|
||||
* 当前钢卷号
|
||||
*/
|
||||
@ExcelProperty(value = "钢卷号")
|
||||
private String currentCoilNo;
|
||||
|
||||
/**
|
||||
* 操作类型(1=分卷,2=合卷,3=更新)
|
||||
*/
|
||||
@ExcelProperty(value = "操作类型", converter = ExcelDictConvert.class)
|
||||
@ExcelDictFormat(dictType = "wms_coil_action_type")
|
||||
private Integer actionType;
|
||||
|
||||
/**
|
||||
* 操作状态(0=待处理,1=处理中,2=已完成,3=已取消)
|
||||
*/
|
||||
@ExcelProperty(value = "操作状态", converter = ExcelDictConvert.class)
|
||||
@ExcelDictFormat(dictType = "wms_action_status")
|
||||
private Integer actionStatus;
|
||||
|
||||
/**
|
||||
* 扫码时间
|
||||
*/
|
||||
@ExcelProperty(value = "扫码时间")
|
||||
private Date scanTime;
|
||||
|
||||
/**
|
||||
* 扫码设备
|
||||
*/
|
||||
@ExcelProperty(value = "扫码设备")
|
||||
private String scanDevice;
|
||||
|
||||
/**
|
||||
* 优先级(0=普通,1=重要,2=紧急)
|
||||
*/
|
||||
@ExcelProperty(value = "优先级", converter = ExcelDictConvert.class)
|
||||
@ExcelDictFormat(dictType = "wms_action_priority")
|
||||
private Integer priority;
|
||||
|
||||
/**
|
||||
* 来源类型
|
||||
*/
|
||||
@ExcelProperty(value = "来源类型")
|
||||
private String sourceType;
|
||||
|
||||
/**
|
||||
* 所在库区ID
|
||||
*/
|
||||
private Long warehouseId;
|
||||
|
||||
/**
|
||||
* 库区名称
|
||||
*/
|
||||
@ExcelProperty(value = "库区")
|
||||
private String warehouseName;
|
||||
|
||||
/**
|
||||
* 操作人ID
|
||||
*/
|
||||
private Long operatorId;
|
||||
|
||||
/**
|
||||
* 操作人姓名
|
||||
*/
|
||||
@ExcelProperty(value = "操作人")
|
||||
private String operatorName;
|
||||
|
||||
/**
|
||||
* 处理时间
|
||||
*/
|
||||
@ExcelProperty(value = "处理时间")
|
||||
private Date processTime;
|
||||
|
||||
/**
|
||||
* 完成时间
|
||||
*/
|
||||
@ExcelProperty(value = "完成时间")
|
||||
private Date completeTime;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@ExcelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@ExcelProperty(value = "创建时间")
|
||||
private Date createTime;
|
||||
|
||||
// 钢卷相关信息(关联查询)
|
||||
/**
|
||||
* 钢种
|
||||
*/
|
||||
private String grade;
|
||||
|
||||
/**
|
||||
* 厚度
|
||||
*/
|
||||
private Double thickness;
|
||||
|
||||
/**
|
||||
* 宽度
|
||||
*/
|
||||
private Double width;
|
||||
|
||||
/**
|
||||
* 重量
|
||||
*/
|
||||
private Double weight;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.klp.mapper;
|
||||
|
||||
import com.klp.common.core.mapper.BaseMapperPlus;
|
||||
import com.klp.domain.WmsCoilPendingAction;
|
||||
import com.klp.domain.vo.WmsCoilPendingActionVo;
|
||||
|
||||
/**
|
||||
* 钢卷待操作Mapper接口
|
||||
*
|
||||
* @author Joshi
|
||||
* @date 2025-11-03
|
||||
*/
|
||||
public interface WmsCoilPendingActionMapper extends BaseMapperPlus<WmsCoilPendingActionMapper, WmsCoilPendingAction, WmsCoilPendingActionVo> {
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.klp.service;
|
||||
|
||||
import com.klp.domain.vo.WmsCoilPendingActionVo;
|
||||
import com.klp.domain.bo.WmsCoilPendingActionBo;
|
||||
import com.klp.common.core.domain.PageQuery;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 钢卷待操作Service接口
|
||||
*
|
||||
* @author Joshi
|
||||
* @date 2025-11-03
|
||||
*/
|
||||
public interface IWmsCoilPendingActionService {
|
||||
|
||||
/**
|
||||
* 查询钢卷待操作
|
||||
*/
|
||||
WmsCoilPendingActionVo queryById(Long actionId);
|
||||
|
||||
/**
|
||||
* 查询钢卷待操作列表
|
||||
*/
|
||||
TableDataInfo<WmsCoilPendingActionVo> queryPageList(WmsCoilPendingActionBo bo, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询钢卷待操作列表
|
||||
*/
|
||||
List<WmsCoilPendingActionVo> queryList(WmsCoilPendingActionBo bo);
|
||||
|
||||
/**
|
||||
* 新增钢卷待操作
|
||||
*/
|
||||
Boolean insertByBo(WmsCoilPendingActionBo bo);
|
||||
|
||||
/**
|
||||
* 修改钢卷待操作
|
||||
*/
|
||||
Boolean updateByBo(WmsCoilPendingActionBo bo);
|
||||
|
||||
/**
|
||||
* 校验并批量删除钢卷待操作信息
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
/**
|
||||
* 更新操作状态
|
||||
*/
|
||||
Boolean updateStatus(Long actionId, Integer status);
|
||||
|
||||
/**
|
||||
* 开始处理操作
|
||||
*/
|
||||
Boolean startProcess(Long actionId);
|
||||
|
||||
/**
|
||||
* 完成操作
|
||||
*/
|
||||
Boolean completeAction(Long actionId);
|
||||
|
||||
/**
|
||||
* 取消操作
|
||||
*/
|
||||
Boolean cancelAction(Long actionId);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
package com.klp.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.klp.common.core.domain.PageQuery;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
import com.klp.common.utils.StringUtils;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.klp.common.helper.LoginHelper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.klp.domain.bo.WmsCoilPendingActionBo;
|
||||
import com.klp.domain.vo.WmsCoilPendingActionVo;
|
||||
import com.klp.domain.WmsCoilPendingAction;
|
||||
import com.klp.mapper.WmsCoilPendingActionMapper;
|
||||
import com.klp.service.IWmsCoilPendingActionService;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 钢卷待操作Service业务层处理
|
||||
*
|
||||
* @author Joshi
|
||||
* @date 2025-11-03
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class WmsCoilPendingActionServiceImpl implements IWmsCoilPendingActionService {
|
||||
|
||||
private final WmsCoilPendingActionMapper baseMapper;
|
||||
|
||||
/**
|
||||
* 查询钢卷待操作
|
||||
*/
|
||||
@Override
|
||||
public WmsCoilPendingActionVo queryById(Long actionId){
|
||||
return baseMapper.selectVoById(actionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询钢卷待操作列表
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<WmsCoilPendingActionVo> queryPageList(WmsCoilPendingActionBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<WmsCoilPendingAction> lqw = buildQueryWrapper(bo);
|
||||
Page<WmsCoilPendingActionVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询钢卷待操作列表
|
||||
*/
|
||||
@Override
|
||||
public List<WmsCoilPendingActionVo> queryList(WmsCoilPendingActionBo bo) {
|
||||
LambdaQueryWrapper<WmsCoilPendingAction> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<WmsCoilPendingAction> buildQueryWrapper(WmsCoilPendingActionBo bo) {
|
||||
LambdaQueryWrapper<WmsCoilPendingAction> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(bo.getCoilId() != null, WmsCoilPendingAction::getCoilId, bo.getCoilId());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getCurrentCoilNo()), WmsCoilPendingAction::getCurrentCoilNo, bo.getCurrentCoilNo());
|
||||
lqw.eq(bo.getActionType() != null, WmsCoilPendingAction::getActionType, bo.getActionType());
|
||||
lqw.eq(bo.getActionStatus() != null, WmsCoilPendingAction::getActionStatus, bo.getActionStatus());
|
||||
lqw.eq(bo.getWarehouseId() != null, WmsCoilPendingAction::getWarehouseId, bo.getWarehouseId());
|
||||
lqw.eq(bo.getPriority() != null, WmsCoilPendingAction::getPriority, bo.getPriority());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getSourceType()), WmsCoilPendingAction::getSourceType, bo.getSourceType());
|
||||
lqw.orderByDesc(WmsCoilPendingAction::getPriority);
|
||||
lqw.orderByDesc(WmsCoilPendingAction::getScanTime);
|
||||
return lqw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增钢卷待操作
|
||||
*/
|
||||
@Override
|
||||
public Boolean insertByBo(WmsCoilPendingActionBo bo) {
|
||||
WmsCoilPendingAction add = BeanUtil.toBean(bo, WmsCoilPendingAction.class);
|
||||
validEntityBeforeSave(add);
|
||||
// 设置默认值
|
||||
if (add.getActionStatus() == null) {
|
||||
add.setActionStatus(0); // 默认待处理
|
||||
}
|
||||
if (StringUtils.isBlank(add.getSourceType())) {
|
||||
add.setSourceType("manual"); // 默认手动创建
|
||||
}
|
||||
if (add.getScanTime() == null && "scan".equals(add.getSourceType())) {
|
||||
add.setScanTime(new Date());
|
||||
}
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setActionId(add.getActionId());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改钢卷待操作
|
||||
*/
|
||||
@Override
|
||||
public Boolean updateByBo(WmsCoilPendingActionBo bo) {
|
||||
WmsCoilPendingAction update = BeanUtil.toBean(bo, WmsCoilPendingAction.class);
|
||||
validEntityBeforeSave(update);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(WmsCoilPendingAction entity){
|
||||
// TODO 做一些数据校验,如唯一约束
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除钢卷待操作
|
||||
*/
|
||||
@Override
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if(isValid){
|
||||
// TODO 做一些业务上的校验,判断是否需要校验
|
||||
}
|
||||
return baseMapper.deleteBatchIds(ids) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新操作状态
|
||||
*/
|
||||
@Override
|
||||
public Boolean updateStatus(Long actionId, Integer status) {
|
||||
WmsCoilPendingAction action = new WmsCoilPendingAction();
|
||||
action.setActionId(actionId);
|
||||
action.setActionStatus(status);
|
||||
return baseMapper.updateById(action) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始处理操作
|
||||
*/
|
||||
@Override
|
||||
public Boolean startProcess(Long actionId) {
|
||||
WmsCoilPendingAction action = new WmsCoilPendingAction();
|
||||
action.setActionId(actionId);
|
||||
action.setActionStatus(1); // 处理中
|
||||
action.setProcessTime(new Date());
|
||||
try {
|
||||
action.setOperatorId(LoginHelper.getUserId());
|
||||
action.setOperatorName(LoginHelper.getUsername());
|
||||
} catch (Exception e) {
|
||||
// 如果获取登录用户失败,不影响主流程
|
||||
}
|
||||
return baseMapper.updateById(action) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 完成操作
|
||||
*/
|
||||
@Override
|
||||
public Boolean completeAction(Long actionId) {
|
||||
WmsCoilPendingAction action = new WmsCoilPendingAction();
|
||||
action.setActionId(actionId);
|
||||
action.setActionStatus(2); // 已完成
|
||||
action.setCompleteTime(new Date());
|
||||
return baseMapper.updateById(action) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消操作
|
||||
*/
|
||||
@Override
|
||||
public Boolean cancelAction(Long actionId) {
|
||||
WmsCoilPendingAction action = new WmsCoilPendingAction();
|
||||
action.setActionId(actionId);
|
||||
action.setActionStatus(3); // 已取消
|
||||
return baseMapper.updateById(action) > 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,7 +230,8 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
|
||||
contentMap.put("enter_coil_no", bo.getEnterCoilNo()); // 入场钢卷号(唯一不变)
|
||||
contentMap.put("current_coil_no", currentCoilNo); // 当前钢卷号(可变)
|
||||
contentMap.put("coil_id", "null"); // 钢卷ID(新增时暂时为null,插入后更新)
|
||||
contentMap.put("coil_id", "null"); // 初始钢卷ID(新增时暂时为null,插入后更新)
|
||||
contentMap.put("current_coil_id", "null"); // 当前有效的钢卷ID(新增时暂时为null,插入后更新)
|
||||
|
||||
// 创建steps数组
|
||||
List<Map<String, Object>> steps = new ArrayList<>();
|
||||
@@ -399,15 +400,17 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
if (newCoil.getItemId() == null) {
|
||||
newCoil.setItemId(oldCoil.getItemId());
|
||||
}
|
||||
// 确保warehouseId有值(如果前端没传,使用原值)
|
||||
if (newCoil.getWarehouseId() == null) {
|
||||
newCoil.setWarehouseId(oldCoil.getWarehouseId());
|
||||
}
|
||||
|
||||
validEntityBeforeSave(newCoil);
|
||||
boolean flag = baseMapper.insert(newCoil) > 0;
|
||||
if (flag) {
|
||||
bo.setCoilId(newCoil.getCoilId());
|
||||
// 如果生成了新二维码,更新二维码中的coilId
|
||||
if (warehouseChanged) {
|
||||
updateQrcodeCoilId(qrcodeRecordId, newCoil.getCoilId());
|
||||
}
|
||||
// 无论库区是否变化,都需要更新二维码中的current_coil_id
|
||||
updateQrcodeCoilId(qrcodeRecordId, newCoil.getCoilId());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
@@ -430,7 +433,8 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
|
||||
contentMap.put("enter_coil_no", oldCoil.getEnterCoilNo()); // 入场钢卷号(始终不变)
|
||||
contentMap.put("current_coil_no", currentCoilNo); // 当前钢卷号
|
||||
contentMap.put("coil_id", "null"); // 钢卷ID(更新时暂时为null,插入后更新)
|
||||
contentMap.put("coil_id", String.valueOf(oldCoil.getCoilId())); // 初始钢卷ID(记录最初的ID)
|
||||
contentMap.put("current_coil_id", "null"); // 当前钢卷ID(更新时暂时为null,插入后更新)
|
||||
|
||||
// 复制原钢卷的历史steps
|
||||
List<Map<String, Object>> steps = new ArrayList<>();
|
||||
@@ -630,7 +634,8 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
Map<String, Object> contentMap = new HashMap<>();
|
||||
contentMap.put("enter_coil_no", oldCoil.getEnterCoilNo());
|
||||
contentMap.put("current_coil_no", newCoilBo.getCurrentCoilNo());
|
||||
contentMap.put("coil_id", "null"); // 钢卷ID(分卷时暂时为null,插入后更新)
|
||||
contentMap.put("coil_id", String.valueOf(oldCoil.getCoilId())); // 初始钢卷ID(记录原钢卷的ID)
|
||||
contentMap.put("current_coil_id", "null"); // 当前钢卷ID(分卷时暂时为null,插入后更新)
|
||||
|
||||
// 复制原钢卷的历史steps
|
||||
List<Map<String, Object>> steps = new ArrayList<>();
|
||||
@@ -700,7 +705,8 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
}
|
||||
contentMap.put("enter_coil_no", enterCoilNo);
|
||||
contentMap.put("current_coil_no", mergedCoilBo.getCurrentCoilNo());
|
||||
contentMap.put("coil_id", "null"); // 钢卷ID(合卷时暂时为null,插入后更新)
|
||||
contentMap.put("coil_id", "null"); // 初始钢卷ID(合卷时为null)
|
||||
contentMap.put("current_coil_id", "null"); // 当前钢卷ID(合卷时暂时为null,插入后更新)
|
||||
|
||||
// 合并所有参与合卷的原始钢卷的历史steps
|
||||
List<Map<String, Object>> steps = new ArrayList<>();
|
||||
@@ -790,8 +796,13 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
Map<String, Object> contentMap = objectMapper.readValue(record.getContent(), Map.class);
|
||||
|
||||
// 更新coilId
|
||||
contentMap.put("coil_id", String.valueOf(coilId));
|
||||
// 如果是第一次设置coilId(从"null"变为实际ID),则同时设置coil_id和current_coil_id
|
||||
if ("null".equals(contentMap.get("coil_id"))) {
|
||||
contentMap.put("coil_id", String.valueOf(coilId)); // 初始ID,不再改变
|
||||
}
|
||||
|
||||
// 始终更新current_coil_id为最新的钢卷ID
|
||||
contentMap.put("current_coil_id", String.valueOf(coilId));
|
||||
|
||||
// 更新二维码记录
|
||||
String newContentJson = objectMapper.writeValueAsString(contentMap);
|
||||
@@ -854,6 +865,10 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
// 更新当前钢卷号到最外层(方便快速查看)
|
||||
contentMap.put("current_coil_no", bo.getCurrentCoilNo());
|
||||
|
||||
// 更新当前钢卷ID(注意:这里需要获取新插入的钢卷ID,但在这个方法中还没有新ID)
|
||||
// 所以这个方法只在库区不变化时调用,此时钢卷ID不变
|
||||
// contentMap.put("current_coil_id", String.valueOf(bo.getCoilId())); // 保持当前ID不变
|
||||
|
||||
// 更新二维码记录
|
||||
String newContentJson = objectMapper.writeValueAsString(contentMap);
|
||||
WmsGenerateRecordBo updateBo = new WmsGenerateRecordBo();
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.klp.mapper.WmsCoilPendingActionMapper">
|
||||
|
||||
<resultMap type="com.klp.domain.WmsCoilPendingAction" id="WmsCoilPendingActionResult">
|
||||
<result property="actionId" column="action_id" />
|
||||
<result property="coilId" column="coil_id" />
|
||||
<result property="currentCoilNo" column="current_coil_no" />
|
||||
<result property="actionType" column="action_type" />
|
||||
<result property="actionStatus" column="action_status" />
|
||||
<result property="scanTime" column="scan_time" />
|
||||
<result property="scanDevice" column="scan_device" />
|
||||
<result property="priority" column="priority" />
|
||||
<result property="sourceType" column="source_type" />
|
||||
<result property="warehouseId" column="warehouse_id" />
|
||||
<result property="operatorId" column="operator_id" />
|
||||
<result property="operatorName" column="operator_name" />
|
||||
<result property="processTime" column="process_time" />
|
||||
<result property="completeTime" column="complete_time" />
|
||||
<result property="remark" column="remark" />
|
||||
<result property="delFlag" column="del_flag" />
|
||||
<result property="createTime" column="create_time" />
|
||||
<result property="createBy" column="create_by" />
|
||||
<result property="updateTime" column="update_time" />
|
||||
<result property="updateBy" column="update_by" />
|
||||
</resultMap>
|
||||
|
||||
</mapper>
|
||||
|
||||
Reference in New Issue
Block a user