opt: AI优化结构

This commit is contained in:
2026-04-24 14:50:37 +08:00
parent be3dce46f2
commit 298ae2fa27

View File

@@ -1,8 +1,10 @@
package org.nl.b_lms.sch.tasks.slitter.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.nl.b_lms.sch.point.dao.mapper.StIvtCutpointivtMapper;
import org.nl.b_lms.sch.tasks.SlitterDownNewTrussTask;
@@ -106,6 +108,18 @@ public class SlitterServiceImpl implements SlitterService {
* 合单配送
*/
public final static String IS_COMBINED_ORDER = "IS_COMBINED_ORDER";
/**
* 分布式锁KEY 常量
*/
private static final String LOCK_KEY = "lock:doUpShaftToSlitterByDevice";
/**
* 锁等待时间 1秒
*/
private static final long LOCK_WAIT_TIME = 1;
/**
* 锁持有时间 10秒
*/
private static final long LOCK_LEASE_TIME = 10;
@Autowired
private BstIvtStockingivtMapper bstIvtStockingivtMapper;
@Autowired
@@ -2347,51 +2361,96 @@ public class SlitterServiceImpl implements SlitterService {
@Override
public JSONObject doUpShaftToSlitterByDevice(JSONObject param) {
log.info("手持申请分切上料参数:{}", param);
JSONObject res = new JSONObject();
res.put("status", HttpStatus.HTTP_OK);
res.put("message", "创建桁架任务成功!");
RLock open = redissonClient.getLock("lock:doUpShaftToSlitterByDevice");
boolean openLock = false;
log.info("手持申请分切上料,请求参数:{}", param);
// 1. 校验必传参数
checkParam(param);
RLock lock = redissonClient.getLock(LOCK_KEY);
boolean lockAcquired = false;
try {
openLock = open.tryLock(0, TimeUnit.SECONDS);
// 2. 尝试获取分布式锁等待1s持有10s
lockAcquired = lock.tryLock(LOCK_WAIT_TIME, LOCK_LEASE_TIME, TimeUnit.SECONDS);
if (!lockAcquired) {
log.error("获取分布式锁失败,请求频繁,参数:{}", param);
throw new BadRequestException("系统繁忙,请稍后再试!");
}
// 3. 核心业务逻辑
executeBusinessLogic(param);
// 4. 构造成功返回
return buildSuccessResult("创建桁架任务成功!");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
try {
if (openLock) {
// param: area, device_code
String area = param.getString("area");
String deviceCode = param.getString("device_code");
StIvtCutpointivt extCode = cutpointivtService.getPintByExtCode(deviceCode, true);
if (ObjectUtil.isEmpty(extCode)) {
throw new BadRequestException("该设备不存在或者被禁用,请检查!");
}
List<Deliverycachepointivt> cachePoints = slitterMapper.getReadyShaftCachePointByDevice(extCode);
List<BstIvtCutpointivt> cutPointList = slitterMapper.getReadyShaftPoint(deviceCode);
if (cachePoints.size() > 0) {
// 在缓存架子上
doUpShaftToSlitterByNew(param, cachePoints, extCode);
} else if (cutPointList.size() > 0) {
// 在对接位
// 找到该分切计划的点位
BstIvtCutpointivt newCutPoint = cutPointList.get(0);
// 创建任务
JSONObject taskParam = new JSONObject();
taskParam.put("point_code", newCutPoint.getPoint_code());
doUpShaftToSlitter(taskParam);
} else {
throw new BadRequestException("没有为设备[" + deviceCode + "]套好轴的位置!");
}
} else {
throw new BadRequestException("系统繁忙,稍后在试!!");
}
log.error("获取锁线程中断,参数:{}", param, e);
Thread.currentThread().interrupt();
throw new RuntimeException("系统异常,请稍后再试");
} finally {
if (openLock) {
open.unlock();
// 5. 安全释放锁:只有当前线程加的锁才能释放
if (lockAcquired && lock.isHeldByCurrentThread()) {
lock.unlock();
log.debug("分布式锁释放成功key{}", LOCK_KEY);
}
}
return res;
}
/**
* 校验必传参数
*/
private void checkParam(JSONObject param) {
String area = param.getString("area");
String deviceCode = param.getString("device_code");
if (ObjectUtil.isEmpty(area) || ObjectUtil.isEmpty(deviceCode)) {
log.error("分切上料参数缺失param{}", param);
throw new BadRequestException("参数不完整,请检查 area 和 device_code");
}
}
/**
* 执行业务逻辑
*/
private void executeBusinessLogic(JSONObject param) {
String area = param.getString("area");
String deviceCode = param.getString("device_code");
log.info("开始处理分切上料,设备:{},区域:{}", deviceCode, area);
// 1. 查询设备信息
StIvtCutpointivt deviceInfo = cutpointivtService.getPintByExtCode(deviceCode, true);
if (ObjectUtil.isEmpty(deviceInfo)) {
throw new BadRequestException("该设备不存在或已禁用,请检查!");
}
// 2. 查询缓存点位 + 可用点位
List<Deliverycachepointivt> cachePointList = slitterMapper.getReadyShaftCachePointByDevice(deviceInfo);
List<BstIvtCutpointivt> cutPointList = slitterMapper.getReadyShaftPoint(deviceCode);
// 3. 业务分支处理
if (!cachePointList.isEmpty()) {
log.info("设备{}:轴在缓存架子上,执行缓存上架逻辑", deviceCode);
doUpShaftToSlitterByNew(param, cachePointList, deviceInfo);
} else if (!cutPointList.isEmpty()) {
log.info("设备{}:轴在对接位,执行对接位上架逻辑", deviceCode);
BstIvtCutpointivt cutPoint = cutPointList.get(0);
JSONObject taskParam = new JSONObject();
taskParam.put("point_code", cutPoint.getPoint_code());
doUpShaftToSlitter(taskParam);
} else {
log.error("设备{}:未找到套好轴的位置", deviceCode);
throw new BadRequestException("没有为设备[" + deviceCode + "]套好轴的位置!");
}
}
/**
* 构建成功返回结果
*/
private JSONObject buildSuccessResult(String message) {
JSONObject result = new JSONObject();
result.put("status", HttpStatus.HTTP_OK);
result.put("message", message);
return result;
}
/**
@@ -2402,78 +2461,115 @@ public class SlitterServiceImpl implements SlitterService {
* @param device 设备实体
*/
public void doUpShaftToSlitterByNew(JSONObject param, List<Deliverycachepointivt> cachePoints, StIvtCutpointivt device) {
List<Deliverycachepointivt> actualPoints = cachePoints;
log.info("开始执行分切缓存上料任务,设备编码:{},缓存点位数量:{}", device.getExt_code(), cachePoints.size());
// 1. 点位数量校验
if (cachePoints.size() > 2) {
// todo: 需要过滤(正常不会出现,先不考虑)
log.error("缓存点位数量超过2个设备{},点位:{}", device.getExt_code(), cachePoints);
throw new BadRequestException("计划冗余,请检查!");
}
// 获取计划数据
List<String> qzznos = cachePoints.stream().map(Deliverycachepointivt::getQzzno).collect(Collectors.toList());
List<PdmBiSlittingproductionplan> plans = slittingproductionplanService.getByQzzNos(qzznos);
if (plans.isEmpty()) {
throw new BadRequestException("计划不存在!请检查点位:"
+ cachePoints.stream().map(Deliverycachepointivt::getPoint_code).collect(Collectors.toList())
+ "的数据!");
// 2. 获取气胀轴编号
List<String> qzznos = cachePoints.stream()
.map(Deliverycachepointivt::getQzzno)
.filter(StrUtil::isNotBlank)
.collect(Collectors.toList());
if (qzznos.isEmpty()) {
log.error("缓存点位中未找到有效的卷料号");
throw new BadRequestException("缓存点位未找到卷料号!");
}
JSONObject taskParam = new JSONObject();
// 根据计划筛选上下轴任务,并构建任务参数
// 3. 查询生产计划
List<PdmBiSlittingproductionplan> plans = slittingproductionplanService.getByQzzNos(qzznos);
if (CollUtil.isEmpty(plans)) {
log.error("未查询到分切计划,卷料号:{}", qzznos);
throw new BadRequestException("计划不存在!请检查点位数据!");
}
// 4. 筛选上下轴计划
PdmBiSlittingproductionplan nextUpPlan = plans.stream()
.filter(p -> SlitterConstant.SLITTER_SHAFT_UP.equals(p.getUp_or_down()))
.findFirst()
.orElse(null);
PdmBiSlittingproductionplan nextDownPlan = plans.stream()
.filter(p -> SlitterConstant.SLITTER_SHAFT_DOWN.equals(p.getUp_or_down()))
.findFirst()
.orElse(null);
Deliverycachepointivt upNeedPoint = actualPoints.stream()
.filter(p -> {
assert nextUpPlan != null;
return p.getQzzno().equals(nextUpPlan.getQzzno());
})
.findFirst()
.orElse(null);
Deliverycachepointivt downNeedPoint = actualPoints.stream()
.filter(p -> {
assert nextDownPlan != null;
return p.getQzzno().equals(nextDownPlan.getQzzno());
})
.findFirst()
.orElse(null);
if (ObjectUtil.isNotEmpty(nextUpPlan) && ObjectUtil.isNotEmpty(nextDownPlan)) {
// 上轴都不会空
// 双轴任务参数构建
assert downNeedPoint != null;
// 5. 匹配对应点位
Deliverycachepointivt upNeedPoint = null;
if (nextUpPlan != null) {
upNeedPoint = cachePoints.stream()
.filter(p -> nextUpPlan.getQzzno().equals(p.getQzzno()))
.findFirst()
.orElse(null);
}
Deliverycachepointivt downNeedPoint = null;
if (nextDownPlan != null) {
downNeedPoint = cachePoints.stream()
.filter(p -> nextDownPlan.getQzzno().equals(p.getQzzno()))
.findFirst()
.orElse(null);
}
// 6. 构建任务参数
JSONObject taskParam = new JSONObject();
boolean isDoubleShaft = nextUpPlan != null && nextDownPlan != null;
if (isDoubleShaft) {
// 双轴任务
if (downNeedPoint == null || upNeedPoint == null) {
log.error("双轴任务点位缺失upNeedPoint{}downNeedPoint{}", upNeedPoint, downNeedPoint);
throw new BadRequestException("双轴任务点位不完整!");
}
taskParam.put("point_code1", downNeedPoint.getPoint_code());
taskParam.put("point_code2", device.getDown_point_code());
assert upNeedPoint != null;
taskParam.put("point_code3", upNeedPoint.getPoint_code());
taskParam.put("point_code4", device.getUp_point_code());
taskParam.put("vehicle_code1", upNeedPoint.getQzzno());
taskParam.put("vehicle_code2", downNeedPoint.getQzzno());
log.info("双轴任务构建完成,上轴卷:{},下轴卷:{}", upNeedPoint.getQzzno(), downNeedPoint.getQzzno());
} else {
// 单轴任务参数构建
if (ObjectUtil.isNotEmpty(nextUpPlan)) {
// 上轴任务
assert upNeedPoint != null;
// 单轴任务
if (nextUpPlan != null) {
if (upNeedPoint == null) {
throw new BadRequestException("上轴任务未找到对应缓存点位!");
}
taskParam.put("point_code1", upNeedPoint.getPoint_code());
taskParam.put("point_code2", device.getUp_point_code());
taskParam.put("vehicle_code1", upNeedPoint.getQzzno());
} else {
// 下轴任务
assert downNeedPoint != null;
log.info("单上轴任务,卷号:{}", upNeedPoint.getQzzno());
} else if (nextDownPlan != null) {
if (downNeedPoint == null) {
throw new BadRequestException("下轴任务未找到对应缓存点位!");
}
taskParam.put("point_code1", downNeedPoint.getPoint_code());
taskParam.put("point_code2", device.getDown_point_code());
taskParam.put("vehicle_code2", downNeedPoint.getQzzno());
taskParam.put("vehicle_code1", downNeedPoint.getQzzno());
log.info("单下轴任务,卷号:{}", downNeedPoint.getQzzno());
} else {
log.error("未找到上轴/下轴类型计划plans{}", plans);
throw new BadRequestException("未匹配到有效上下轴计划!");
}
}
// 构建任务的其他参数
// 7. 公共任务参数
taskParam.put("truss_type", "1");
taskParam.put("empty_site", "0");
taskParam.put("task_type", SlitterEnum.TASK_TYPE.code("缓存上空轴任务"));
taskParam.put("product_area", SlitterConstant.SLITTER_TASK_AREA);
taskParam.put("u_containers", plans.stream().map(PdmBiSlittingproductionplan::getContainer_name).collect(Collectors.toList()));
// 创建任务
List<String> containers = plans.stream()
.map(PdmBiSlittingproductionplan::getContainer_name)
.filter(StrUtil::isNotBlank)
.collect(Collectors.toList());
taskParam.put("u_containers", containers);
// 8. 创建任务
log.info("最终创建桁架任务参数:{}", taskParam);
upShaftTrussNewTask.createTask(taskParam);
}