feat(wms): 退火计划选择合同提前

- 在退火计划表格中添加合同号选择功能,支持远程搜索和下拉选择
- 更新数据库表结构,在wms_furnace_plan_coil表中新增contract_id字段
- 修改后端实体类将contractNo改为contractId,并更新相关映射配置
- 调整前端页面布局,将左右两列比例从12:12调整为10:14
- 优化退火完成验证逻辑,要求所有钢卷必须绑定合同后才能完成操作
- 修复材料网格布局样式,改为固定2列显示
- 添加订单列表加载和搜索功能,支持按关键词过滤
- 更新完成退火对话框提示文案,明确合同绑定要求
This commit is contained in:
2026-06-25 15:04:41 +08:00
parent 7e9caf9bb7
commit 1c0b0da99e
9 changed files with 97 additions and 42 deletions

View File

@@ -36,6 +36,9 @@ CREATE TABLE IF NOT EXISTS wms_furnace_plan_coil (
plan_coil_id BIGINT AUTO_INCREMENT PRIMARY KEY,
plan_id BIGINT NOT NULL COMMENT '计划ID',
coil_id BIGINT NOT NULL COMMENT '钢卷ID',
logic_warehouse_id BIGINT NULL COMMENT '逻辑库区去向(钢卷退火后目标逻辑库区)',
furnace_level TINYINT(1) NULL COMMENT '炉火层级1=一层2=二层3=三层)',
contract_id BIGINT NULL COMMENT '合同ID',
del_flag TINYINT DEFAULT 0 COMMENT '删除标记(0正常 1删除)',
create_by VARCHAR(64) NULL,
update_by VARCHAR(64) NULL,

View File

@@ -52,7 +52,7 @@
@pagination="getList" />
<el-row :gutter="20" class="mt16">
<el-col :span="12">
<el-col :span="10">
<div class="custom-panel">
<div class="panel-header">
<span class="panel-title">领料列表</span>
@@ -102,7 +102,7 @@
</div>
</div>
</el-col>
<el-col :span="12">
<el-col :span="14">
<div class="custom-panel">
<div class="panel-header">
<span class="panel-title">退火计划</span>
@@ -136,8 +136,33 @@
</el-table-column>
<el-table-column label="入场卷号" align="center" prop="enterCoilNo" />
<el-table-column label="当前卷号" align="center" prop="coil.currentCoilNo" />
<el-table-column label="创建时间" align="center" prop="action" width="200">
<el-table-column label="合同号" align="center" prop="contractId" width="200">
<template slot-scope="scope">
<el-select
v-model="scope.row.contractId"
placeholder="搜索"
filterable
remote
:remote-method="(q) => remoteSearchOrders(q)"
:loading="orderLoading"
clearable
size="small"
@change="handleContractIdChange(scope.row)"
>
<el-option
v-for="item in orderList"
:key="item.orderId"
:label="`${item.contractCode} - ${item.companyName}`"
:value="item.orderId"
>
<span style="font-weight:bold">{{ item.contractCode }}</span>
<span style="color:#8492a6;font-size:13px;margin-left:8px">{{ item.companyName }}</span>
<span style="color:#c0c4cc;font-size:12px;float:right">{{ item.salesman }}</span>
</el-option>
</el-select>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="action">
<template slot-scope="scope">
<el-date-picker style="width: 185px" v-model="scope.row.createTime" type="datetime"
value-format="yyyy-MM-dd HH:mm:ss" placeholder="选择创建时间" @change="handlePLanCoilChange(scope.row)" />
@@ -159,7 +184,7 @@
</el-row>
<el-dialog title="完成退火" :visible.sync="completeOpen" width="800px" append-to-body>
<div class="complete-tip">请为每条钢卷分配逻辑库区去向和关联合同未分配将无法完成</div>
<div class="complete-tip">请确认每条钢卷逻辑库区去向,所有钢卷须已在明细中绑定合同。</div>
<el-table :data="completeCoils" v-loading="completeLoading" height="360px">
<el-table-column label="入场钢卷号" prop="enterCoilNo" align="center" />
<el-table-column label="钢卷去向" align="center" width="270">
@@ -170,11 +195,9 @@
</el-select>
</template>
</el-table-column>
<el-table-column label="关联合同" align="center" width="270">
<el-table-column label="合同" align="center" width="140">
<template slot-scope="scope">
<div style="width: 100%; display: flex; align-items: center;">
<ContractSelect v-model="scope.row.contractId" placeholder="请选择合同" />
</div>
<span>{{ scope.row.contractCode || '-' }}</span>
</template>
</el-table-column>
</el-table>
@@ -238,6 +261,7 @@
import { listAnnealPlan, updateAnnealPlanCoil, getAnnealPlan, addAnnealPlan, updateAnnealPlan, delAnnealPlan, changeAnnealPlanStatus, inFurnace, completeAnnealPlan, listAnnealPlanCoils, bindAnnealPlanCoils, unbindAnnealPlanCoil } from "@/api/wms/annealPlan";
import { listAnnealFurnace } from "@/api/wms/annealFurnace";
import { listMaterialCoil } from "@/api/wms/coil";
import { listOrder } from "@/api/crm/order";
import { listCoilContractRel } from '@/api/wms/coilContractRel';
import { listWarehouse } from '@/api/wms/warehouse'
import WarehouseSelect from "@/components/KLPService/WarehouseSelect";
@@ -279,6 +303,8 @@ export default {
},
currentPlan: {},
coilList: [],
orderList: [],
orderLoading: false,
materialLoading: false,
materialTotal: 0,
materialList: [],
@@ -303,6 +329,7 @@ export default {
floatLayerConfig: {
columns: [
{ label: '入场钢卷号', prop: 'enterCoilNo' },
{ label: '合同号', prop: 'contractId' },
{ label: '当前钢卷号', prop: 'coil.currentCoilNo' },
{ label: '厂家卷号', prop: 'coil.supplierCoilNo' },
{ label: '逻辑库位', prop: 'coil.warehouseName' },
@@ -332,6 +359,7 @@ export default {
this.loadFurnaces();
this.getMaterialCoils();
this.loadWarehouses();
this.loadOrderList();
},
methods: {
getList() {
@@ -363,6 +391,33 @@ export default {
this.loadPlanCoils();
});
},
handleContractIdChange(row) {
updateAnnealPlanCoil(row).then(() => {
this.$message.success('合同号已更新');
});
},
loadOrderList() {
this.orderLoading = true;
listOrder({ pageNum: 1, pageSize: 100 }).then(response => {
this.orderList = response.rows || [];
this.orderLoading = false;
}).catch(() => {
this.orderLoading = false;
});
},
remoteSearchOrders(query) {
if (query) {
this.orderLoading = true;
listOrder({ pageNum: 1, pageSize: 20, keyword: query }).then(response => {
this.orderList = response.rows || [];
this.orderLoading = false;
}).catch(() => {
this.orderLoading = false;
});
} else {
this.loadOrderList();
}
},
getMaterialCoils() {
this.materialLoading = true;
listMaterialCoil(this.materialQueryParams).then(response => {
@@ -397,17 +452,10 @@ export default {
...item,
coilId: item.coilId,
enterCoilNo: item.enterCoilNo,
warehouseId: item.logicWarehouseId || null
warehouseId: item.logicWarehouseId || null,
contractId: item.contractId || null,
contractCode: (this.orderList.find(o => o.orderId === item.contractId) || {}).contractCode || null,
}));
// 查询每个钢卷绑定的合同号作为默认值
for (const coil of this.completeCoils) {
listCoilContractRel({ coilId: coil.coilId }).then(res => {
const rows = res.rows || []
if (rows.length > 0 && rows[0].contractId) {
this.$set(coil, 'contractId', rows[0].contractId)
}
})
}
this.completeLoading = false;
}).catch(() => {
this.completeLoading = false;
@@ -585,9 +633,14 @@ export default {
warehouseId: item.warehouseId,
contractId: item.contractId,
}));
const missing = locations.filter(item => !item.warehouseId || !item.contractId);
if (missing.length > 0) {
this.$message.warning('请先为所有钢卷分配实际库位和关联合同');
const missingWarehouse = locations.filter(item => !item.warehouseId);
if (missingWarehouse.length > 0) {
this.$message.warning('请先为所有钢卷分配实际库位');
return;
}
const missingContract = locations.filter(item => !item.contractId);
if (missingContract.length > 0) {
this.$message.warning('请先在明细中为所有钢卷绑定合同后再完成退火');
return;
}
this.completeLoading = true;
@@ -703,8 +756,7 @@ export default {
/* ========== 修复在这里 ========== */
.material-grid {
display: grid;
/* 核心修复:去掉固定 4 列,改用自动填充,实现真正自适应 */
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
grid-template-columns: repeat(2, 1fr);
gap: 12px;
min-height: 120px;
/* 必须加,让 grid 不受父级弹性压缩影响 */
@@ -712,15 +764,6 @@ export default {
box-sizing: border-box;
}
/* 媒体查询只需要控制最小宽度即可,不用写死列数 */
@media (max-width: 768px) {
.material-grid {
grid-template-columns: 1fr;
}
}
/* =============================== */
.material-card {
border: 1px solid #e9ecf2;
border-radius: 8px;
@@ -806,3 +849,6 @@ export default {
padding-bottom: 40px;
}
</style>
<style>
html { overflow-y: scroll; }
</style>

View File

@@ -47,9 +47,9 @@ public class WmsFurnacePlanCoil extends BaseEntity {
private Integer furnaceLevel;
/**
* 合同
* 合同ID
*/
private String contractNo;
private Long contractId;
/**
* 删除标志0=正常1=已删除)

View File

@@ -43,9 +43,9 @@ public class WmsFurnacePlanCoilBo extends BaseEntity {
private Integer furnaceLevel;
/**
* 合同
* 合同ID
*/
private String contractNo;
private Long contractId;
/**
* 钢卷ID列表逗号分隔

View File

@@ -34,8 +34,8 @@ public class WmsFurnacePlanCoilVo {
@ExcelProperty(value = "炉火层级")
private Integer furnaceLevel;
@ExcelProperty(value = "合同")
private String contractNo;
@ExcelProperty(value = "合同ID")
private Long contractId;
@ExcelProperty(value = "入场钢卷号")
private String enterCoilNo;

View File

@@ -64,7 +64,7 @@ public class WmsFurnacePlanCoilServiceImpl implements IWmsFurnacePlanCoilService
lqw.eq(bo.getCoilId() != null, WmsFurnacePlanCoil::getCoilId, bo.getCoilId());
lqw.eq(bo.getLogicWarehouseId() != null, WmsFurnacePlanCoil::getLogicWarehouseId, bo.getLogicWarehouseId());
lqw.eq(bo.getFurnaceLevel() != null, WmsFurnacePlanCoil::getFurnaceLevel, bo.getFurnaceLevel());
lqw.eq(bo.getContractNo() != null, WmsFurnacePlanCoil::getContractNo, bo.getContractNo());
lqw.eq(bo.getContractId() != null, WmsFurnacePlanCoil::getContractId, bo.getContractId());
return lqw;
}

View File

@@ -392,6 +392,11 @@ public class WmsFurnacePlanServiceImpl implements IWmsFurnacePlanService {
if (targetLocation == null) {
throw new ServiceException("钢卷" + coil.getEnterCoilNo() + "未分配库位");
}
// 校验合同ID必须所有钢卷都已绑定合同
Long contractId = contractIdMap.get(coil.getCoilId());
if (contractId == null) {
throw new ServiceException("钢卷" + coil.getEnterCoilNo() + "未绑定合同,请先在明细中设置合同");
}
WmsMaterialCoil oldCoil = materialCoilMapper.selectById(coil.getCoilId());
if (oldCoil == null) {
@@ -414,7 +419,7 @@ public class WmsFurnacePlanServiceImpl implements IWmsFurnacePlanService {
updateBo.setStatus(0);
updateBo.setExportBy(null);
updateBo.setExportTime(null);
updateBo.setContractId(contractIdMap.get(coil.getCoilId()));
updateBo.setContractId(contractId);
materialCoilService.updateByBo(updateBo, "annealing");

View File

@@ -10,7 +10,7 @@
<result property="coilId" column="coil_id"/>
<result property="logicWarehouseId" column="logic_warehouse_id"/>
<result property="furnaceLevel" column="furnace_level"/>
<result property="contractNo" column="contract_no"/>
<result property="contractId" column="contract_id"/>
<result property="delFlag" column="del_flag"/>
<result property="createBy" column="create_by"/>
<result property="updateBy" column="update_by"/>

View File

@@ -3976,6 +3976,7 @@ CREATE TABLE `wms_furnace_plan_coil` (
`coil_id` bigint NOT NULL COMMENT '钢卷ID',
`logic_warehouse_id` bigint NULL DEFAULT NULL COMMENT '逻辑库区去向(钢卷退火后目标逻辑库区)',
`furnace_level` tinyint(1) NULL DEFAULT NULL COMMENT '炉火层级1=一层2=二层3=三层)',
`contract_id` bigint NULL DEFAULT NULL COMMENT '合同ID',
`del_flag` tinyint NULL DEFAULT 0 COMMENT '删除标记(0正常 1删除)',
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,