opt: AI优化结构
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user