|
@@ -67,6 +67,7 @@ import java.math.BigDecimal;
|
|
|
import java.math.RoundingMode;
|
|
|
import java.text.DecimalFormat;
|
|
|
import java.util.*;
|
|
|
+import java.util.function.Function;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
@@ -663,31 +664,99 @@ public class BilletOriginalProductRecordController extends JeecgController<Bille
|
|
|
@AutoLog(value = "确认凉钢坯打印单")
|
|
|
@ApiOperation(value="确认凉钢坯打印单", notes="确认凉钢坯打印单")
|
|
|
@RequestMapping(value = "/coldConfirmRecord", method = {RequestMethod.PUT})
|
|
|
- public Result<String> coldConfirmRecord(@RequestBody BilletOriginalProductRecord billetOriginalProductRecord) {
|
|
|
+ public Result<String> coldConfirmRecord(@RequestBody BilletColdOriginalRecordVo billetOriginalProductRecordVo) {
|
|
|
Map<String, Integer> lengthCountMap = new HashMap<>();
|
|
|
- BilletOriginalProductRecord bopr = billetOriginalProductRecordService.getById(billetOriginalProductRecord.getId());
|
|
|
+ BilletOriginalProductRecord bopr = billetOriginalProductRecordService.getById(billetOriginalProductRecordVo.getId());
|
|
|
if(bopr == null) {
|
|
|
return Result.error("未找到对应数据,编辑失败!");
|
|
|
}
|
|
|
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
|
|
- applyColdConfirmInfo(billetOriginalProductRecord, sysUser);
|
|
|
- billetOriginalProductRecordService.updateById(billetOriginalProductRecord);
|
|
|
// 原始记录属于步进冷床的属于凉钢坯,要进行下垛操作,无须更新钢坯原始记录中的步进冷床数量
|
|
|
- // stackLength字段数据结构为:[{\"stackingCount\":24,\"stackingLength\":10680,\"stackingWeight\":58.056,\"stackingBhtcId\":\"9\"}]
|
|
|
+ // stackLength字段数据结构为:[{"stackingCount":20,"stackingLength":"11230","stackingWeight":50.871900000000004},{"stackingCount":68,"stackingLength":11880,"stackingWeight":182.97576}]
|
|
|
String stackLengthJson = bopr.getStackLength();
|
|
|
+ JSONObject item = null; // 初始化结果对象
|
|
|
if (StringUtils.isNotBlank(stackLengthJson)) {
|
|
|
try {
|
|
|
- JSONArray jsonArray = JSON.parseArray(stackLengthJson);
|
|
|
- for (int i = 0; i < jsonArray.size(); i++) {
|
|
|
- JSONObject item = jsonArray.getJSONObject(i);
|
|
|
+ JSONArray stackArray = JSON.parseArray(stackLengthJson);
|
|
|
+ int targetSize = billetOriginalProductRecordVo.getLength();
|
|
|
+ // 提取并转换stackingLength为整数的Function
|
|
|
+ Function<Object, Integer> parseLength = obj -> {
|
|
|
+ if (obj instanceof String) return Integer.parseInt((String) obj);
|
|
|
+ if (obj instanceof Number) return ((Number) obj).intValue();
|
|
|
+ return 0; // 默认值或抛出异常
|
|
|
+ };
|
|
|
+ // 使用Stream API查找匹配项,在流处理中转换类型
|
|
|
+ item = stackArray.stream()
|
|
|
+ .map(obj -> (JSONObject) obj)
|
|
|
+ .filter(obj -> parseLength.apply(obj.get("stackingLength")) == targetSize)
|
|
|
+ .findFirst()
|
|
|
+ .orElse(null);
|
|
|
+ if (item != null){
|
|
|
Integer stackingLength = item.getInteger("stackingLength");
|
|
|
Integer stackingCount = item.getInteger("stackingCount");
|
|
|
String bhtcId = item.getString("stackingBhtcId");
|
|
|
if (stackingLength == null || stackingCount == null || bhtcId == null) {
|
|
|
- log.info("步进冷床数据格式异常,跳过该记录: {}", item.toJSONString());
|
|
|
- continue;
|
|
|
+ log.info("凉坯确认异常: {}", item.toJSONString());
|
|
|
+ return Result.error("凉坯确认数据格式异常,请检查数据!");
|
|
|
+ }
|
|
|
+ int appointColdBilletCount = billetOriginalProductRecordVo.getColdAmount();
|
|
|
+ int finalStackingCount = stackingCount - appointColdBilletCount;
|
|
|
+ if (finalStackingCount < 0){
|
|
|
+ log.info("确认凉坯的数量不能超过总数: {}", item.toJSONString());
|
|
|
+ return Result.error("凉坯确认异常,确认凉坯的数量不能超过总数!");
|
|
|
+ }
|
|
|
+ if (finalStackingCount == 0){
|
|
|
+ applyColdConfirmInfo(bopr, sysUser);
|
|
|
+ }else {
|
|
|
+ // 拆分指定数量的凉坯单
|
|
|
+ String appointColdBilletJsonArray = handleAppointColdBillet(bopr, appointColdBilletCount, targetSize, sysUser.getRealname());
|
|
|
+ // 更新原堆垛信息,减去已拆分的数量和重量
|
|
|
+ if (stackArray != null && !stackArray.isEmpty()) {
|
|
|
+ try {
|
|
|
+ // 查找需要更新的堆垛记录
|
|
|
+ for (Object obj : stackArray) {
|
|
|
+ JSONObject stackingItem = (JSONObject) obj;
|
|
|
+ int currentLength = parseLength.apply(stackingItem.get("stackingLength"));
|
|
|
+ if (currentLength == targetSize) {
|
|
|
+ // 减去已拆分的数量
|
|
|
+ int originalCount = stackingItem.getInteger("stackingCount");
|
|
|
+ int newCount = originalCount - appointColdBilletCount;
|
|
|
+ // 更新堆垛数量
|
|
|
+ stackingItem.put("stackingCount", newCount);
|
|
|
+ // 更新重量
|
|
|
+ BigDecimal sizeDecimal = new BigDecimal(currentLength);
|
|
|
+ BigDecimal weight = calculateWeight(sizeDecimal, newCount);
|
|
|
+ stackingItem.put("stackingWeight", weight);
|
|
|
+ break; // 找到后跳出循环
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 更新bopr中的堆垛信息
|
|
|
+ bopr.setStackLength(stackArray.toJSONString());
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("凉坯拆分发生异常", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 判断一下bopr.getColdBilletInfo是否为空,不为空的话,把拆分后的数据保存在bopr.getColdBilletInfo()中
|
|
|
+ if (oConvertUtils.isNotEmpty(bopr.getColdBilletInfo())) {
|
|
|
+ try {
|
|
|
+ // 使用FastJSON解析现有数据和新数据
|
|
|
+ JSONArray existingArray = JSON.parseArray(bopr.getColdBilletInfo());
|
|
|
+ JSONArray newArray = JSON.parseArray(appointColdBilletJsonArray);
|
|
|
+ // 将新数组中的元素添加到现有数组
|
|
|
+ existingArray.addAll(newArray);
|
|
|
+ // 更新bopr中的冷坯信息
|
|
|
+ bopr.setColdBilletInfo(existingArray.toJSONString());
|
|
|
+ } catch (Exception e) {
|
|
|
+ // 处理JSON解析异常
|
|
|
+ log.error("合并冷坯信息时发生JSON解析错误", e);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 如果原数组为空,直接设置新数组
|
|
|
+ bopr.setColdBilletInfo(appointColdBilletJsonArray);
|
|
|
+ }
|
|
|
}
|
|
|
- int demandStackingSum = stackingCount / 4;
|
|
|
+ billetOriginalProductRecordService.updateById(bopr);
|
|
|
+ int demandStackingSum = appointColdBilletCount / 4;
|
|
|
// 确保下垛数量大于0并且是步进冷床类型,才进行容器释放(下垛)
|
|
|
if (demandStackingSum > 0 && "9".equals(bhtcId)){
|
|
|
// 下垛数量大于0时,执行指定数量的下垛操作
|
|
@@ -696,27 +765,121 @@ public class BilletOriginalProductRecordController extends JeecgController<Bille
|
|
|
lengthCountMap.merge(lengthKey, stackingCount, Integer::sum);
|
|
|
}
|
|
|
}
|
|
|
- }catch (Exception e){
|
|
|
+ } catch (Exception e) {
|
|
|
log.info("确认凉钢坯打印单JSON解析失败,数据:{}", stackLengthJson, e);
|
|
|
}
|
|
|
}
|
|
|
+ // 遍历每条记录构建 BilletUseInfoAddDTO 并保存
|
|
|
+ BilletUseInfoAddDTO addDTO = new BilletUseInfoAddDTO();
|
|
|
+ addDTO.setCcmNo(bopr.getCcmNo());
|
|
|
+ addDTO.setShift(bopr.getShift());
|
|
|
+ addDTO.setShiftGroup(bopr.getShiftGroup());
|
|
|
+ addDTO.setLengthToNumMap(lengthCountMap);
|
|
|
+ addDTO.setRecordId(bopr.getId());
|
|
|
+ addDTO.setHeatNo(bopr.getHeatNo());
|
|
|
+ bopr.setIsHot(0);
|
|
|
+ billetUseInfoService.saveBilletOneInfoAndDelayPush(addDTO, bopr);
|
|
|
|
|
|
- // 遍历每条记录构建 BilletUseInfoAddDTO 并保存
|
|
|
- BilletUseInfoAddDTO addDTO = new BilletUseInfoAddDTO();
|
|
|
- addDTO.setCcmNo(bopr.getCcmNo());
|
|
|
- addDTO.setShift(bopr.getShift());
|
|
|
- addDTO.setShiftGroup(bopr.getShiftGroup());
|
|
|
- addDTO.setLengthToNumMap(lengthCountMap);
|
|
|
- addDTO.setRecordId(bopr.getId());
|
|
|
- addDTO.setHeatNo(bopr.getHeatNo());
|
|
|
+ return Result.OK("确认成功!");
|
|
|
+ }
|
|
|
|
|
|
- bopr.setIsHot(0);
|
|
|
+ /**
|
|
|
+ * 处理指定数量的凉坯单
|
|
|
+ *
|
|
|
+ * @param
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private String handleAppointColdBillet(BilletOriginalProductRecord bopr, int appointColdBilletCount, int targetSize, String coldConfirmBy) {
|
|
|
|
|
|
- billetUseInfoService.saveBilletOneInfoAndDelayPush(addDTO, bopr);
|
|
|
+ BigDecimal sizeDecimal = new BigDecimal(targetSize);
|
|
|
+ BigDecimal weight = calculateWeight(sizeDecimal, appointColdBilletCount);
|
|
|
|
|
|
- return Result.OK("确认成功!");
|
|
|
- }
|
|
|
+ String brandNum = "";
|
|
|
+
|
|
|
+ if (bopr.getGrade() != null) {
|
|
|
+ brandNum = Optional.ofNullable(bopr.getGrade())
|
|
|
+ .map(bn -> sysDictService.queryDictTextByKey("billet_spec", bn))
|
|
|
+ .orElseGet(() -> sysDictService.queryDictTextByKey("billet_spec", "5"));
|
|
|
+ }
|
|
|
|
|
|
+ // 1. 构建最内层的 heatNoDetails 数据
|
|
|
+ Map<String, Object> heatNoDetail = new HashMap<>();
|
|
|
+ heatNoDetail.put("ccmNo", bopr.getCcmNo());
|
|
|
+ heatNoDetail.put("heatNo", bopr.getHeatNo());
|
|
|
+ heatNoDetail.put("heatNoAmount", appointColdBilletCount);
|
|
|
+ heatNoDetail.put("heatNoWeight", weight); // 重量用BigDecimal避免精度问题
|
|
|
+ heatNoDetail.put("createTime", new Date()); // 日期以字符串形式存储(或用Date对象,FastJSON会自动格式化)
|
|
|
+ heatNoDetail.put("updateTime", null);
|
|
|
+ heatNoDetail.put("shiftGroup", bopr.getShiftGroup());
|
|
|
+ heatNoDetail.put("shift", bopr.getShift());
|
|
|
+
|
|
|
+ // 包装为 heatNoDetails 列表(原始JSON中是数组)
|
|
|
+ List<Map<String, Object>> heatNoDetailsList = new ArrayList<>();
|
|
|
+ heatNoDetailsList.add(heatNoDetail);
|
|
|
+
|
|
|
+ // 2. 构建 rollSendDetails 列表
|
|
|
+ Map<String, Object> rollSendDetail = new HashMap<>();
|
|
|
+ rollSendDetail.put("size", targetSize);
|
|
|
+ rollSendDetail.put("spec", "170*170");
|
|
|
+ rollSendDetail.put("amount", appointColdBilletCount);
|
|
|
+ rollSendDetail.put("weight", weight);
|
|
|
+ rollSendDetail.put("createTime", new Date());
|
|
|
+
|
|
|
+ List<Map<String, Object>> rollSendDetailsList = new ArrayList<>();
|
|
|
+ rollSendDetailsList.add(rollSendDetail);
|
|
|
+
|
|
|
+ // 3. 构建 sizeDetails 列表
|
|
|
+ Map<String, Integer> coldLengthCumulativeCountMap = new HashMap<>(); // 冷坯起始位置
|
|
|
+ String lengthKey = String.valueOf(targetSize); // 统一使用字符串键
|
|
|
+
|
|
|
+ // 计算起始根数与终止根数 - 使用一致的字符串键
|
|
|
+ int lastEndAmount = coldLengthCumulativeCountMap.getOrDefault(lengthKey, 0);
|
|
|
+ int startAmount = lastEndAmount + 1;
|
|
|
+ int endAmount = lastEndAmount + appointColdBilletCount;
|
|
|
+ coldLengthCumulativeCountMap.put(lengthKey, endAmount); // 更新累计值
|
|
|
+
|
|
|
+ Map<String, Object> sizeDetail = new HashMap<>();
|
|
|
+ sizeDetail.put("size", targetSize);
|
|
|
+ sizeDetail.put("sizeAmount", appointColdBilletCount);
|
|
|
+ sizeDetail.put("sizeWeight", weight);
|
|
|
+ sizeDetail.put("startAmount", startAmount);
|
|
|
+ sizeDetail.put("endAmount", endAmount);
|
|
|
+
|
|
|
+ List<Map<String, Object>> sizeDetailsList = new ArrayList<>();
|
|
|
+ sizeDetailsList.add(sizeDetail);
|
|
|
+
|
|
|
+ // 4. 构建 rollHeightDetails
|
|
|
+ Map<String, Object> rollHeightDetails = new HashMap<>();
|
|
|
+ rollHeightDetails.put("id", bopr.getId());
|
|
|
+ rollHeightDetails.put("confirmTime", DateUtils.date2Str(new Date(), DateUtils.datetimeFormat.get()));
|
|
|
+ rollHeightDetails.put("brandNum", brandNum);
|
|
|
+ rollHeightDetails.put("totalAmount", appointColdBilletCount);
|
|
|
+ rollHeightDetails.put("totalWeight", weight);
|
|
|
+ rollHeightDetails.put("hotOrColdStaus", 1);
|
|
|
+ rollHeightDetails.put("sizeDetails", sizeDetailsList); // 嵌套sizeDetails列表
|
|
|
+ rollHeightDetails.put("rollSendDetails", rollSendDetailsList); // 嵌套rollSendDetails列表
|
|
|
+
|
|
|
+ rollHeightDetails.put("coldConfirmBy", coldConfirmBy);
|
|
|
+ rollHeightDetails.put("coldConfirmTime", DateUtils.date2Str(new Date(), DateUtils.datetimeFormat.get()));
|
|
|
+ rollHeightDetails.put("coldRemark", "凉送单确认无误(指定数量)!");
|
|
|
+
|
|
|
+ // 5. 构建 storageCenterHeatNoInvoicing
|
|
|
+ Map<String, Object> storageCenterHeatNoInvoicing = new HashMap<>();
|
|
|
+ storageCenterHeatNoInvoicing.put("rollHeightDetails", rollHeightDetails); // 嵌套rollHeightDetails
|
|
|
+
|
|
|
+ // 6. 构建外层对象(包含heatNoDetails和storageCenterHeatNoInvoicing)
|
|
|
+ Map<String, Object> outerObj = new HashMap<>();
|
|
|
+ outerObj.put("heatNoDetails", heatNoDetailsList); // 注意:原始JSON中是数组,这里用List对应
|
|
|
+ outerObj.put("storageCenterHeatNoInvoicing", storageCenterHeatNoInvoicing);
|
|
|
+
|
|
|
+ // 7. 最外层是列表,包含上面的outerObj
|
|
|
+ List<Map<String, Object>> finalList = new ArrayList<>();
|
|
|
+ finalList.add(outerObj);
|
|
|
+
|
|
|
+ // 8. 使用FastJSON将List<Map>转为JSON字符串
|
|
|
+ String jsonString = JSON.toJSONString(finalList, true); // 第二个参数true:格式化输出(可选)
|
|
|
+ return jsonString;
|
|
|
+ }
|
|
|
/**
|
|
|
* 推钢室快速创建装运单
|
|
|
*
|