将coilId的存储模式改成string

This commit is contained in:
2025-10-29 11:17:52 +08:00
parent 5f9f395193
commit c1705181dc
5 changed files with 318 additions and 284 deletions

147
README.md
View File

@@ -1,146 +1 @@
## 平台简介
[![Gitee Repo star](https://gitee.com/KonBAI-Q/klp-flowable-plus/badge/star.svg?theme=dark)](https://gitee.com/KonBAI-Q/klp-flowable-plus/stargazers)
[![GitHub Repo stars](https://img.shields.io/github/stars/KonBAI-Q/KLP?style=social)](https://github.com/KonBAI-Q/KLP/stargazers)
[![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://gitee.com/KonBAI-Q/klp-flowable-plus/blob/master/LICENSE)
[![使用IntelliJ IDEA开发维护](https://img.shields.io/badge/IntelliJ%20IDEA-提供支持-blue.svg)](https://www.jetbrains.com)
[![Spring Boot](https://img.shields.io/badge/Spring%20Boot-2.7-blue.svg)]()
[![JDK-8+](https://img.shields.io/badge/JDK-8-green.svg)]()
[![JDK-11](`https://img.shields.io/badge/JDK-11-green.svg)]()
- 本项目基于 [RuoYi-Vue-Plus](https://gitee.com/dromara/RuoYi-Vue-Plus) 进行二次开发,采用 `Flowable` 扩展工作流应用场景,支持在线表单设计和丰富的工作流程设计能力。
- 本项目主要针对`Flowable`工作流场景开发,脚手架功能同步更新 [RuoYi-Vue-Plus](https://gitee.com/dromara/RuoYi-Vue-Plus) 项目。
- 采用`MIT开源协议`,完全免费给个人及企业使用。
- 项目处于开发阶段,工作流流程还存在不足。因此,目前仅推荐用于学习、毕业设计等个人使用。
## 赞助商
[![驰骋BPM](https://gitee.com/KonBAI-Q/klp-flowable-plus-vuepress/raw/master/imgs/chicheng-logo.png)](http://ccflow.org/?frm=KonBAI)
## 参考文档
- 项目文档:[RuoYi-Flowable-Plus开发文档](http://rfp-doc.konbai.work)
- 项目文档(备用)[RuoYi-Flowable-Plus开发文档](http://159.75.158.189:81/)
- 脚手架文档:[RuoYi-Vue-Plus文档](https://gitee.com/dromara/RuoYi-Vue-Plus/wikis/pages)
## 项目地址
- Gitee<https://gitee.com/KonBAI-Q/klp-flowable-plus>
- GitHub<https://github.com/KonBAI-Q/KLP>
## 在线演示
演示服务不限制CURD操作希望大家按需使用不要恶意添加脏数据或对服务器进行攻击等操作。将不定期清理数据
[KLP 在线演示](http://159.75.158.189/)
| | 账号 | 密码 |
|---------------- | ----- | -------- |
| 超管账户 | admin | admin123 |
| 监控中心(未运行) | klp | 123456 |
| 任务调度中心 | admin | 123456 |
| 数据监控中心 | klp | 123456 |
## 技术交流群
交流1群 🈵️ [![加入QQ群](https://img.shields.io/badge/QQ群-1007207992-blue.svg?style=flat)](https://jq.qq.com/?_wv=1027\&k=PYDZa1tA) </br>
交流2群 🈵️ [![加入QQ群](https://img.shields.io/badge/QQ群-725502135-blue.svg?style=flat)](https://jq.qq.com/?_wv=1027&k=J4zeZaKo) </br>
交流3群 🈵️ [![加入QQ群](https://img.shields.io/badge/QQ群-860980043-blue.svg?style=flat)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=NfqIsFMASOvIC6yHYwY6bnaSfdgcD1La&authKey=SeFDA4oFkb%2FkdvnI%2FJ3aJTJZkyzDaz8v8gybpzUATAilnKSCmyKhCE6R2jkXc5e2&noverify=0&group_code=860980043) </br>
交流4群 [![加入QQ群](https://img.shields.io/badge/QQ群-683510042-blue.svg?style=flat)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=RBXhJKfZT0GSjEPa0CcViGmP_mnVE82j&authKey=J9shEDSoCujDRJO9wcpqzsbvCQskcEvo0idGd54I0uk735K90HhA0v5ywEkUdxK3&noverify=0&group_code=683510042) </br>
## 参与开源
- 如遇到问题,欢迎提交到 [issues](https://gitee.com/KonBAI-Q/klp-flowable-plus/issues)(请按模版进行填写信息)。
- 欢迎提交 [PR](https://gitee.com/KonBAI-Q/klp-flowable-plus/pulls) ,注意请提交到 `develop` 开发分支 统一测试发版。
## 特别鸣谢
- [RuoYi-Vue-Plus](https://gitee.com/dromara/RuoYi-Vue-Plus)
- [RuoYi-flowable](https://gitee.com/tony2y/RuoYi-flowable)
- [bpmn-process-designer](https://gitee.com/MiyueSC/bpmn-process-designer)
## 支持项目
如果项目对你有帮助请给项目点个Star。也可以通过下方二维码请作者喝一杯奶茶
![输入图片说明](http://qiniu-flowable.konbai.work/Collection-Code.jpg)
## 友情链接
- [玩转RuoYi-Cloud-Plus - Flowable基础](https://blog.csdn.net/zhaozhiqiang1981/article/details/129240406)文档包含Flowable基础知识、项目使用说明、源码解析等。新人必看
- [基于若依的Flowable工作流实战](https://space.bilibili.com/400188320/channel/collectiondetail?sid=1002899)Flowable视频学习专栏项目基本覆盖了Flowable的方方面面也拓展了很多为了达到生产级别项目而附加的表结构工具类等知识点
## 推荐图书
- 大家在使用本项目时,推荐结合贺波老师的书[《深入Flowable流程引擎核心原理与高阶实战》](https://item.jd.com/14804836.html)学习。这本书得到了Flowable创始人Tijs Rademakers亲笔作序推荐对系统学习和深入掌握Flowable的用法非常有帮助。
![深入Flowable流程引擎核心原理与高阶实战](https://foruda.gitee.com/images/1727508315476163030/4e083d99_5096840.jpeg)
- 大家在使用本项目时,推荐结合贺波老师的书[《深入Activiti流程引擎核心原理与高阶实战》](https://item.m.jd.com/product/13928958.html?gx=RnAomTM2bmCImZxDqYAkVCoIHuIYVqc)这本书对系统学习和深入掌握Activiti/Flowable的用法非常有帮助。
![深入Activiti流程引擎核心原理与高阶实战](https://foruda.gitee.com/images/1727508299212519153/0791b5ac_5096840.jpeg)
## 演示图例
<table style="width:100%; text-align:center">
<tbody>
<tr>
<td>
<span>登录页面</span>
<img src="https://images.gitee.com/uploads/images/2022/0424/164043_74b57010_5096840.png" alt="登录页面"/>
</td>
<td>
<span>用户管理</span>
<img src="https://images.gitee.com/uploads/images/2022/0424/164236_2de3b8da_5096840.png" alt="用户管理"/>
</td>
</tr>
<tr>
<td>
<span>流程分类</span>
<img src="https://images.gitee.com/uploads/images/2022/0424/164839_ca79b066_5096840.png" alt="流程分类"/>
</td>
<td>
<span>流程表单</span>
<img src="https://images.gitee.com/uploads/images/2022/0424/165118_688209fd_5096840.png" alt="流程表单"/>
</td>
</tr>
<tr>
<td>
<span>流程定义</span>
<img src="https://images.gitee.com/uploads/images/2022/0424/165916_825a85c8_5096840.png" alt="流程定义"/>
</td>
<td>
<span>流程发起</span>
<img src="https://images.gitee.com/uploads/images/2022/0424/171409_ffb0faf3_5096840.png" alt="流程发起"/>
</td>
</tr>
<tr>
<td>
<span>表单设计</span>
<img src="https://images.gitee.com/uploads/images/2022/0424/172933_7222c0f2_5096840.png" alt="表单设计"/>
</td>
<td>
<span>流程设计</span>
<img src="https://images.gitee.com/uploads/images/2022/0424/165827_44fa412b_5096840.png" alt="流程设计"/>
</td>
</tr>
<tr>
<td>
<span>发起流程</span>
<img src="https://images.gitee.com/uploads/images/2022/0424/171651_4639254b_5096840.png" alt="发起流程"/>
</td>
<td>
<span>待办任务</span>
<img src="https://images.gitee.com/uploads/images/2022/0424/171916_7ba22063_5096840.png" alt="代办任务"/>
</td>
</tr>
<tr>
<td>
<span>任务办理</span>
<img src="https://images.gitee.com/uploads/images/2022/0424/172204_04753399_5096840.png" alt="任务办理"/>
</td>
<td>
<span>流转记录</span>
<img src="https://images.gitee.com/uploads/images/2022/0424/172350_179e8341_5096840.png" alt="流转记录"/>
</td>
</tr>
<tr>
<td>
<span>流程跟踪</span>
<img src="https://images.gitee.com/uploads/images/2022/0424/172547_fe7414d4_5096840.png" alt="流程跟踪"/>
</td>
<td>
<span>流程完结</span>
<img src="https://images.gitee.com/uploads/images/2022/0424/173159_8cc57e74_5096840.png" alt="流程完结"/>
</td>
</tr>
</tbody>
</table>
下面我需要你写前端手机端uniapp web管理端

View File

@@ -58,9 +58,9 @@ spring:
driverClassName: com.mysql.cj.jdbc.Driver
# jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562
# rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题)
url: jdbc:mysql://140.143.206.120:13306/klp-oa?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
url: jdbc:mysql://140.143.206.120:3306/klp-oa?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
username: klp
password: KeLunPu@123
password: KeLunPu123@
# 从库数据源
slave:
lazy: true

View File

@@ -6,6 +6,7 @@ import com.klp.common.annotation.ExcelDictFormat;
import com.klp.common.convert.ExcelDictConvert;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
/**
@@ -152,6 +153,11 @@ public class WmsMaterialCoilVo {
*/
private Object product; // 产品VO待定义
/**
* BOM列表原材料对应的BOM项目信息
*/
private List<WmsBomItemVo> bomItemList;
}

View File

@@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.klp.common.helper.LoginHelper;
import com.klp.common.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@@ -17,6 +18,10 @@ import com.klp.domain.vo.WmsMaterialCoilVo;
import com.klp.domain.vo.WmsGenerateRecordVo;
import com.klp.domain.vo.WmsWarehouseVo;
import com.klp.domain.vo.WmsRawMaterialVo;
import com.klp.domain.vo.WmsProductBomVo;
import com.klp.domain.vo.WmsBomItemVo;
import com.klp.domain.bo.WmsProductBomBo;
import com.klp.domain.bo.WmsBomItemBo;
import com.klp.domain.WmsMaterialCoil;
import com.klp.domain.WmsStock;
import com.klp.domain.bo.WmsStockBo;
@@ -28,6 +33,8 @@ import com.klp.service.IWmsStockService;
import com.klp.service.IWmsGenerateRecordService;
import com.klp.service.IWmsWarehouseService;
import com.klp.service.IWmsRawMaterialService;
import com.klp.service.IWmsProductBomService;
import com.klp.service.IWmsBomItemService;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;
@@ -55,6 +62,8 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
private final IWmsGenerateRecordService generateRecordService;
private final IWmsWarehouseService warehouseService;
private final IWmsRawMaterialService rawMaterialService;
private final IWmsProductBomService productBomService;
private final IWmsBomItemService bomItemService;
/**
* 查询钢卷物料表
@@ -66,6 +75,22 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
return null;
}
// 如果查询到的是历史数据,尝试查找对应的当前数据
if (vo.getDataType() != null && vo.getDataType() == 0) {
// 根据入场钢卷号查找当前数据
LambdaQueryWrapper<WmsMaterialCoil> lqw = Wrappers.lambdaQuery();
lqw.eq(WmsMaterialCoil::getEnterCoilNo, vo.getEnterCoilNo())
.eq(WmsMaterialCoil::getDataType, 1) // 查找当前数据
.orderByDesc(WmsMaterialCoil::getCreateTime); // 按创建时间倒序,获取最新的
List<WmsMaterialCoilVo> currentDataList = baseMapper.selectVoList(lqw);
if (!currentDataList.isEmpty()) {
// 如果找到当前数据,返回最新的当前数据
vo = currentDataList.get(0);
}
// 如果没有找到当前数据,仍然返回历史数据供查看
}
// 查询关联对象
fillRelatedObjects(vo);
@@ -98,6 +123,14 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
if ("raw_material".equals(vo.getItemType()) && vo.getItemId() != null) {
WmsRawMaterialVo rawMaterial = rawMaterialService.queryById(vo.getItemId());
vo.setRawMaterial(rawMaterial);
// 查询原材料对应的BOM信息通过bomId查询BomItem列表
if (rawMaterial != null && rawMaterial.getBomId() != null) {
WmsBomItemBo bomItemBo = new WmsBomItemBo();
bomItemBo.setBomId(rawMaterial.getBomId());
List<WmsBomItemVo> bomItemList = bomItemService.queryList(bomItemBo);
vo.setBomItemList(bomItemList);
}
}
// 查询产品信息当itemType为product时
@@ -320,6 +353,21 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
newCoil.setCoilId(null); // 清空ID让数据库自动生成新的ID
newCoil.setDataType(1); // 设置为当前数据
newCoil.setQrcodeRecordId(oldCoil.getQrcodeRecordId()); // 继承二维码ID
// 确保关键字段不丢失
if (newCoil.getEnterCoilNo() == null) {
newCoil.setEnterCoilNo(oldCoil.getEnterCoilNo());
}
if (newCoil.getSupplierCoilNo() == null) {
newCoil.setSupplierCoilNo(oldCoil.getSupplierCoilNo()); // 保留厂家原料卷号
}
if (newCoil.getItemType() == null) {
newCoil.setItemType(oldCoil.getItemType());
}
if (newCoil.getItemId() == null) {
newCoil.setItemId(oldCoil.getItemId());
}
validEntityBeforeSave(newCoil);
boolean flag = baseMapper.insert(newCoil) > 0;
if (flag) {
@@ -389,7 +437,16 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
WmsMaterialCoil newCoil = BeanUtil.toBean(newCoilBo, WmsMaterialCoil.class);
newCoil.setCoilId(null);
newCoil.setDataType(1);
// 继承原钢卷的基本信息
newCoil.setEnterCoilNo(oldCoil.getEnterCoilNo());
newCoil.setSupplierCoilNo(oldCoil.getSupplierCoilNo()); // 保留厂家原料卷号
newCoil.setItemType(oldCoil.getItemType());
newCoil.setItemId(oldCoil.getItemId());
newCoil.setTeam(oldCoil.getTeam());
// 如果没有指定库区,使用原库区
if (newCoil.getWarehouseId() == null) {
newCoil.setWarehouseId(oldCoil.getWarehouseId());
}
// 为每个子钢卷生成独立二维码
Long newQrcodeId = generateQrcodeForSplit(oldCoil, newCoilBo, allNewCoilNos);
@@ -421,13 +478,28 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
WmsMaterialCoil newCoil = BeanUtil.toBean(bo, WmsMaterialCoil.class);
newCoil.setCoilId(null);
newCoil.setDataType(1);
// 合卷后的钢卷使用自己的enterCoilNo如果没有则从参与合卷的原始钢卷中获取
if (newCoil.getEnterCoilNo() == null && !bo.getNewCoils().isEmpty()) {
// 从第一个参与合卷的原始钢卷获取enterCoilNo
// 从第一个参与合卷的原始钢卷获取基本信息
if (!bo.getNewCoils().isEmpty()) {
WmsMaterialCoil firstOriginalCoil = baseMapper.selectById(bo.getNewCoils().get(0).getCoilId());
if (firstOriginalCoil != null) {
// 继承基本信息
if (newCoil.getEnterCoilNo() == null) {
newCoil.setEnterCoilNo(firstOriginalCoil.getEnterCoilNo());
}
if (newCoil.getSupplierCoilNo() == null) {
newCoil.setSupplierCoilNo(firstOriginalCoil.getSupplierCoilNo()); // 保留厂家原料卷号
}
if (newCoil.getItemType() == null) {
newCoil.setItemType(firstOriginalCoil.getItemType());
}
if (newCoil.getItemId() == null) {
newCoil.setItemId(firstOriginalCoil.getItemId());
}
if (newCoil.getTeam() == null) {
newCoil.setTeam(firstOriginalCoil.getTeam());
}
}
}
newCoil.setQrcodeRecordId(mergedQrcodeId);
@@ -477,6 +549,7 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
splitStep.put("old_coil_id", String.valueOf(oldCoil.getCoilId()));
splitStep.put("new_current_coil_nos", String.join(",", allNewCoilNos));
splitStep.put("child_coils", allNewCoilNos);
splitStep.put("operator", LoginHelper.getUsername()); // 操作者
steps.add(splitStep);
contentMap.put("steps", steps);
@@ -568,9 +641,12 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
mergeStep.put("parent_coil_nos", String.join(",", originalCoilNos));
mergeStep.put("parent_coil_ids", String.join(",", originalCoilIds));
mergeStep.put("new_current_coil_no", mergedCoilBo.getCurrentCoilNo());
mergeStep.put("operator", LoginHelper.getUsername()); // 操作者
steps.add(mergeStep);
contentMap.put("steps", steps);
// 将父钢卷ID也存储到顶层方便快速查询
contentMap.put("parent_coil_ids", String.join(",", originalCoilIds));
ObjectMapper objectMapper = new ObjectMapper();
String contentJson = objectMapper.writeValueAsString(contentMap);
@@ -649,6 +725,7 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
newStep.put("old_current_coil_no", oldCoil.getCurrentCoilNo()); // 原当前钢卷号
newStep.put("new_current_coil_no", bo.getCurrentCoilNo()); // 新当前钢卷号
newStep.put("coil_id", String.valueOf(bo.getCoilId())); // 钢卷ID
newStep.put("operator", LoginHelper.getUsername()); // 操作者
// 判断操作类型
if (bo.getHasMergeSplit() != null && bo.getHasMergeSplit() == 2) {
@@ -707,19 +784,35 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
@Override
public Map<String, Object> queryTrace(String enterCoilNo, String currentCoilNo) {
try {
// 1. 根据入场钢卷号查询二维码记录
// 1. 查询所有相关的二维码记录(包括分卷后的独立二维码)
List<WmsGenerateRecordVo> allQrRecords = new ArrayList<>();
// 首先查询主二维码(以入场钢卷号为序列号的)
WmsGenerateRecordBo qrBo = new WmsGenerateRecordBo();
qrBo.setSerialNumber(enterCoilNo);
List<WmsGenerateRecordVo> qrRecords = generateRecordService.queryList(qrBo);
List<WmsGenerateRecordVo> mainQrRecords = generateRecordService.queryList(qrBo);
allQrRecords.addAll(mainQrRecords);
if (qrRecords.isEmpty()) {
// 然后查询所有以该入场钢卷号开头的二维码(分卷后的二维码)
WmsGenerateRecordBo splitQrBo = new WmsGenerateRecordBo();
List<WmsGenerateRecordVo> allRecords = generateRecordService.queryList(splitQrBo);
for (WmsGenerateRecordVo record : allRecords) {
if (record.getSerialNumber() != null &&
record.getSerialNumber().startsWith(enterCoilNo + "-") &&
!allQrRecords.contains(record)) {
allQrRecords.add(record);
}
}
if (allQrRecords.isEmpty()) {
throw new RuntimeException("未找到对应的二维码记录");
}
// 取第一个(应该只有一个)
WmsGenerateRecordVo qrRecord = qrRecords.get(0);
// 2. 合并所有二维码的steps信息去重并重新编号
Map<String, Map<String, Object>> uniqueSteps = new HashMap<>(); // 用于去重
Set<String> allCoilNos = new HashSet<>();
// 2. 解析二维码content中的steps
for (WmsGenerateRecordVo qrRecord : allQrRecords) {
ObjectMapper objectMapper = new ObjectMapper();
@SuppressWarnings("unchecked")
Map<String, Object> contentMap = objectMapper.readValue(qrRecord.getContent(), Map.class);
@@ -727,48 +820,76 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
@SuppressWarnings("unchecked")
List<Map<String, Object>> steps = (List<Map<String, Object>>) contentMap.get("steps");
// 3. 从steps中提取所有钢卷号
Set<String> coilNos = new HashSet<>();
if (steps != null) {
for (Map<String, Object> step : steps) {
// 提取各种可能的钢卷号字段
extractCoilNo(step, "current_coil_no", coilNos);
extractCoilNo(step, "new_current_coil_no", coilNos);
extractCoilNo(step, "old_current_coil_no", coilNos);
extractCoilNo(step, "new_current_coil_nos", coilNos);
extractCoilNo(step, "merged_from", coilNos);
extractCoilNo(step, "parent_coil_nos", coilNos);
// 提取钢卷ID字段
extractCoilId(step, "coil_id", coilNos);
extractCoilId(step, "old_coil_id", coilNos);
extractCoilId(step, "parent_coil_ids", coilNos);
// 创建唯一标识:操作类型 + 相关钢卷号
String stepKey = createStepKey(step);
// 如果是新的步骤,添加到唯一步骤集合中
if (!uniqueSteps.containsKey(stepKey)) {
Map<String, Object> uniqueStep = new HashMap<>(step);
uniqueStep.put("qrcode_serial", qrRecord.getSerialNumber());
uniqueStep.put("qrcode_id", qrRecord.getRecordId());
uniqueSteps.put(stepKey, uniqueStep);
}
// 提取钢卷号
extractCoilNo(step, "current_coil_no", allCoilNos);
extractCoilNo(step, "new_current_coil_no", allCoilNos);
extractCoilNo(step, "old_current_coil_no", allCoilNos);
extractCoilNo(step, "new_current_coil_nos", allCoilNos);
extractCoilNo(step, "merged_from", allCoilNos);
extractCoilNo(step, "parent_coil_nos", allCoilNos);
extractCoilId(step, "coil_id", allCoilNos);
extractCoilId(step, "old_coil_id", allCoilNos);
extractCoilId(step, "parent_coil_ids", allCoilNos);
}
}
}
// 4. 如果指定了当前钢卷号,过滤出相关的钢卷号
Set<String> filteredCoilNos = coilNos;
// 转换为列表并按原始步骤号排序(保持时间顺序)
List<Map<String, Object>> allSteps = new ArrayList<>(uniqueSteps.values());
// 按原始步骤号排序,保持实际操作的时间顺序
allSteps.sort((a, b) -> {
Integer stepA = (Integer) a.get("step");
Integer stepB = (Integer) b.get("step");
if (stepA == null) stepA = 0;
if (stepB == null) stepB = 0;
return stepA.compareTo(stepB);
});
// 重新编号(保持连续性)
for (int i = 0; i < allSteps.size(); i++) {
allSteps.get(i).put("display_step", i + 1);
// 保留原始步骤号用于调试
allSteps.get(i).put("original_step", allSteps.get(i).get("step"));
}
// 3. 如果指定了当前钢卷号,过滤出相关的钢卷号
Set<String> filteredCoilNos = allCoilNos;
if (currentCoilNo != null && !currentCoilNo.trim().isEmpty()) {
final String filterValue = currentCoilNo; // 用于lambda的final变量
filteredCoilNos = coilNos.stream()
final String filterValue = currentCoilNo;
filteredCoilNos = allCoilNos.stream()
.filter(coilNo -> coilNo.contains(filterValue))
.collect(Collectors.toSet());
}
// 5. 根据提取的钢卷号反向查询数据库
// 4. 根据提取的钢卷号反向查询数据库
List<WmsMaterialCoilVo> result = new ArrayList<>();
if (!filteredCoilNos.isEmpty()) {
LambdaQueryWrapper<WmsMaterialCoil> lqw = Wrappers.lambdaQuery();
lqw.eq(WmsMaterialCoil::getEnterCoilNo, enterCoilNo);
// 查询包含提取出的钢卷号的记录
final Set<String> finalCoilNos = filteredCoilNos; // 用于lambda的final变量
final Set<String> finalCoilNos = filteredCoilNos;
lqw.and(wrapper -> {
int count = 0;
for (String coilNo : finalCoilNos) {
if (count == 0) {
wrapper.like(WmsMaterialCoil::getCurrentCoilNo, coilNo);
wrapper.eq(WmsMaterialCoil::getCurrentCoilNo, coilNo);
} else {
wrapper.or().like(WmsMaterialCoil::getCurrentCoilNo, coilNo);
wrapper.or().eq(WmsMaterialCoil::getCurrentCoilNo, coilNo);
}
count++;
}
@@ -776,13 +897,32 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
lqw.orderByAsc(WmsMaterialCoil::getCreateTime);
result = baseMapper.selectVoList(lqw);
// 填充每个记录的关联对象信息(如库区)
for (WmsMaterialCoilVo vo : result) {
fillRelatedObjects(vo);
}
}
// 6. 构建返回结果
// 如果没有找到记录,尝试查询所有相关的钢卷(包括历史数据)
if (result.isEmpty()) {
LambdaQueryWrapper<WmsMaterialCoil> lqw = Wrappers.lambdaQuery();
lqw.eq(WmsMaterialCoil::getEnterCoilNo, enterCoilNo);
lqw.orderByAsc(WmsMaterialCoil::getCreateTime);
result = baseMapper.selectVoList(lqw);
// 填充每个记录的关联对象信息
for (WmsMaterialCoilVo vo : result) {
fillRelatedObjects(vo);
}
}
// 5. 构建返回结果
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("qrcode", qrRecord);
resultMap.put("steps", steps);
resultMap.put("records", result);
resultMap.put("qrcode", allQrRecords.get(0)); // 主二维码
resultMap.put("all_qrcodes", allQrRecords); // 所有相关二维码
resultMap.put("steps", allSteps); // 所有步骤
resultMap.put("records", result); // 所有钢卷记录
return resultMap;
} catch (Exception e) {
@@ -790,6 +930,38 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
}
}
/**
* 创建步骤唯一标识
*/
private String createStepKey(Map<String, Object> step) {
StringBuilder keyBuilder = new StringBuilder();
// 使用操作类型和主要标识符创建唯一key
String operation = (String) step.get("operation");
keyBuilder.append(operation).append("-");
// 根据操作类型使用不同的标识符
if ("分卷".equals(operation)) {
// 分卷:使用原钢卷号 + 分卷列表
keyBuilder.append(step.get("old_current_coil_no")).append("->");
keyBuilder.append(step.get("new_current_coil_nos"));
} else if ("合卷".equals(operation)) {
// 合卷:使用父钢卷列表 + 新钢卷号
keyBuilder.append(step.get("parent_coil_nos")).append("->");
keyBuilder.append(step.get("new_current_coil_no"));
} else if ("新增".equals(operation)) {
// 新增:使用当前钢卷号
keyBuilder.append(step.get("current_coil_no"));
} else {
// 其他更新:使用原钢卷号 -> 新钢卷号
keyBuilder.append(step.get("old_current_coil_no")).append("->");
keyBuilder.append(step.get("new_current_coil_no"));
}
return keyBuilder.toString();
}
/**
* 从step中提取钢卷号
*/

View File

@@ -1,5 +1,6 @@
DROP TABLE IF EXISTS `wms_stock`;
DROP TABLE IF EXISTS `wms_material_coil`;
create table wms_stock
(