opt: redission锁

This commit is contained in:
2026-01-29 17:41:14 +08:00
parent 4e4ce188c1
commit 08f1f84c8d
2 changed files with 259 additions and 163 deletions

View File

@@ -497,38 +497,50 @@ public class PdaProductionServiceImpl implements PdaProductionService {
* 入库 * 入库
* @param param * @param param
*/ */
@SneakyThrows
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void productionInStorage(JSONObject param, SchBasePoint point) { public void productionInStorage(JSONObject param, SchBasePoint point) {
// 入库库区 RLock lock = redissonClient.getLock("lock:productionInStorage");
String inSect = point.getIn_sect(); boolean tryLock = lock.tryLock(0, TimeUnit.SECONDS);
if (ObjectUtil.isEmpty(inSect)) { try {
throw new BadRequestException("点位【" + point.getPoint_code() + "】未配置入库库区!"); if (tryLock) {
} // 入库库区
Sectattr sectattr = sectattrService.findByCode(inSect, false); String inSect = point.getIn_sect();
if (ObjectUtil.isEmpty(sectattr)) { if (ObjectUtil.isEmpty(inSect)) {
throw new BadRequestException("库区不存在,请确保库区存在!"); throw new BadRequestException("点位【" + point.getPoint_code() + "】未配置入库库区!");
} }
Sectattr sectattr = sectattrService.findByCode(inSect, false);
// 入库三件套 if (ObjectUtil.isEmpty(sectattr)) {
param.put("bill_type", IOSEnum.IN_BILL_TYPE.code("粉碎入库")); throw new BadRequestException("库区不存在,请确保库区存在!");
// 设置rows(需要根据物料和批次区分) }
List<JSONObject> res = groupplateService.getPalletViewByVehicleCode(param.getString("vehicle_code")
, Arrays.asList("1"));
// 需要过滤出物料id+批次并汇总qty
JSONArray jsonArray = new JSONArray();
jsonArray.addAll(res);
List<JSONObject> jsonObjects = DefaultPdaBuildParamService.filterAndSumByMaterialIdAndPcsn(jsonArray);
param.put("rows", jsonObjects);
// 1 创建入库单、明细、分配明细
Map<String, Object> invObj = defaultPdaBuildParam.doBuildInvObj(param, point, sectattr);
String invId = rawAssistIStorService.insertDtl(invObj);
// 2 调用分配
Map<String, Object> divObj = defaultPdaBuildParam.buildDivStructData(param, sectattr, invId, true);
rawAssistIStorService.divStruct(divObj);
// 3 创建任务
Map<String, Object> jsonMst = defaultPdaBuildParam.buildTaskData(point, invId);
rawAssistIStorService.divPoint(jsonMst);
// 入库三件套
param.put("bill_type", IOSEnum.IN_BILL_TYPE.code("粉碎入库"));
// 设置rows(需要根据物料和批次区分)
List<JSONObject> res = groupplateService.getPalletViewByVehicleCode(param.getString("vehicle_code")
, Arrays.asList("1"));
// 需要过滤出物料id+批次并汇总qty
JSONArray jsonArray = new JSONArray();
jsonArray.addAll(res);
List<JSONObject> jsonObjects = DefaultPdaBuildParamService.filterAndSumByMaterialIdAndPcsn(jsonArray);
param.put("rows", jsonObjects);
// 1 创建入库单、明细、分配明细
Map<String, Object> invObj = defaultPdaBuildParam.doBuildInvObj(param, point, sectattr);
String invId = rawAssistIStorService.insertDtl(invObj);
// 2 调用分配
Map<String, Object> divObj = defaultPdaBuildParam.buildDivStructData(param, sectattr, invId, true);
rawAssistIStorService.divStruct(divObj);
// 3 创建任务
Map<String, Object> jsonMst = defaultPdaBuildParam.buildTaskData(point, invId);
rawAssistIStorService.divPoint(jsonMst);
} else {
throw new BadRequestException("速度太快啦,稍后再试...");
}
} finally {
if (tryLock) {
lock.unlock();
}
}
} }
@SneakyThrows @SneakyThrows
@@ -695,92 +707,118 @@ public class PdaProductionServiceImpl implements PdaProductionService {
return PdaResponse.requestParamOk(res); return PdaResponse.requestParamOk(res);
} }
@SneakyThrows
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public PdaResponse manualInbound(JSONObject param) { public PdaResponse manualInbound(JSONObject param) {
assertNotBlankJson(param, "当前点位不能为空!", "row", "current_point", "vehicle_code"); RLock lock = redissonClient.getLock("lock:manualInbound");
JSONObject row = param.getJSONObject("row"); boolean tryLock = lock.tryLock(0, TimeUnit.SECONDS);
String currentPoint = param.getString("current_point"); try {
String vehicleCode = param.getString("vehicle_code"); if (tryLock) {
// ACS 获取的重量 assertNotBlankJson(param, "当前点位不能为空!", "row", "current_point", "vehicle_code");
String total = param.getString("weight"); JSONObject row = param.getJSONObject("row");
String taskId = row.getString("task_id"); String currentPoint = param.getString("current_point");
if (ObjectUtil.isNotEmpty(taskId)) { String vehicleCode = param.getString("vehicle_code");
// 有任务直接任务完成 // ACS 获取的重量
SchBaseTask baseTask = taskService.getById(taskId); String total = param.getString("weight");
AbstractTask task = taskFactory.getTask(baseTask.getConfig_code()); String taskId = row.getString("task_id");
task.updateTaskStatus(baseTask.getTask_code(), TaskStatus.FINISHED); if (ObjectUtil.isNotEmpty(taskId)) {
return PdaResponse.requestOk(); // 有任务直接任务完成
SchBaseTask baseTask = taskService.getById(taskId);
AbstractTask task = taskFactory.getTask(baseTask.getConfig_code());
task.updateTaskStatus(baseTask.getTask_code(), TaskStatus.FINISHED);
return PdaResponse.requestOk();
}
SchBasePoint startPoint = pointService.getById(currentPoint);
// 没任务,证明是人工放上去录进去的
groupbucketService.upDateWeight(total, vehicleCode);
JSONObject param2 = new JSONObject();
// 创建入库任务
List<JSONObject> infos = groupbucketService.getBucketInfoByBucket(vehicleCode);
Sectattr sectattr = sectattrService.findByCode(startPoint.getIn_sect(), false);
param2.put("bill_type", IOSEnum.IN_BILL_TYPE.code("中间站入库"));
param2.put("rows", infos);
// 1 创建入库单、明细、分配明细
Map<String, Object> invObj = defaultPdaBuildParam.doBuildInvObj(param2, startPoint, sectattr);
String invId = rawAssistIStorService.insertDtl(invObj);
// 2 调用分配
Map<String, Object> divObj = defaultPdaBuildParam.buildDivStructData(param2, sectattr, invId, true);
rawAssistIStorService.divStruct(divObj);
// 3 创建任务
Map<String, Object> jsonMst = defaultPdaBuildParam.buildTaskData(startPoint, invId);
rawAssistIStorService.divPoint(jsonMst);
} else {
throw new BadRequestException("速度太快啦,稍后再试...");
}
} finally {
if (tryLock) {
lock.unlock();
}
} }
SchBasePoint startPoint = pointService.getById(currentPoint);
// 没任务,证明是人工放上去录进去的
groupbucketService.upDateWeight(total, vehicleCode);
JSONObject param2 = new JSONObject();
// 创建入库任务
List<JSONObject> infos = groupbucketService.getBucketInfoByBucket(vehicleCode);
Sectattr sectattr = sectattrService.findByCode(startPoint.getIn_sect(), false);
param2.put("bill_type", IOSEnum.IN_BILL_TYPE.code("中间站入库"));
param2.put("rows", infos);
// 1 创建入库单、明细、分配明细
Map<String, Object> invObj = defaultPdaBuildParam.doBuildInvObj(param2, startPoint, sectattr);
String invId = rawAssistIStorService.insertDtl(invObj);
// 2 调用分配
Map<String, Object> divObj = defaultPdaBuildParam.buildDivStructData(param2, sectattr, invId, true);
rawAssistIStorService.divStruct(divObj);
// 3 创建任务
Map<String, Object> jsonMst = defaultPdaBuildParam.buildTaskData(startPoint, invId);
rawAssistIStorService.divPoint(jsonMst);
return PdaResponse.requestOk(); return PdaResponse.requestOk();
} }
@SneakyThrows
@Override @Override
public PdaResponse manualOutbound(JSONObject param) { public PdaResponse manualOutbound(JSONObject param) {
assertNotBlankJson(param, "当前点位不能为空!", "row", "current_point", "vehicle_code"); RLock lock = redissonClient.getLock("lock:manualOutbound");
JSONObject row = param.getJSONObject("row"); boolean tryLock = lock.tryLock(0, TimeUnit.SECONDS);
String currentPoint = param.getString("current_point"); try {
String vehicleCode = param.getString("vehicle_code"); if (tryLock) {
// ACS 获取的重量 assertNotBlankJson(param, "当前点位不能为空!", "row", "current_point", "vehicle_code");
BigDecimal currentTotal = param.getBigDecimal("weight"); JSONObject row = param.getJSONObject("row");
BigDecimal originalQty = row.getBigDecimal("qty"); String currentPoint = param.getString("current_point");
Param threshold = paramService.findByCode("weighing_threshold"); String vehicleCode = param.getString("vehicle_code");
// 对比与组盘的重量是否大于阈值 // ACS 获取的重量
ThresholdChecker.ThresholdCheckResult result = ThresholdChecker.checkThresholdWithDetails( BigDecimal currentTotal = param.getBigDecimal("weight");
currentTotal, BigDecimal originalQty = row.getBigDecimal("qty");
originalQty, Param threshold = paramService.findByCode("weighing_threshold");
threshold.getValue() // 对比与组盘的重量是否大于阈值
); ThresholdChecker.ThresholdCheckResult result = ThresholdChecker.checkThresholdWithDetails(
if (result.isExceeded()) { currentTotal,
throw new BadRequestException(result.toString()); originalQty,
threshold.getValue()
);
if (result.isExceeded()) {
throw new BadRequestException(result.toString());
}
// 判断是否有任务
String taskId = row.getString("task_id");
if (ObjectUtil.isNotEmpty(taskId)) {
// 有任务直接任务完成
SchBaseTask baseTask = taskService.getById(taskId);
AbstractTask task = taskFactory.getTask(baseTask.getConfig_code());
task.updateTaskStatus(baseTask.getTask_code(), TaskStatus.FINISHED);
return PdaResponse.requestOk();
}
if (ObjectUtil.isEmpty(row.getString("station"))) {
throw new BadRequestException("请设置产线目标站!");
}
List<JSONObject> infoByBucket = groupbucketService.getBucketInfoByBucket(vehicleCode);
if (infoByBucket.size() == 0) {
throw new BadRequestException("桶物料信息不存在!请检查组桶!");
}
JSONObject bucket = infoByBucket.get(0);
JSONObject ext = new JSONObject();
// todo: 先固定包衣,后续改
ext.put("config_code", "CoatingUpTask");
ext.put("vehicle_code", vehicleCode);
ext.put("material_qty", currentTotal);
ext.put("material_name", bucket.getString("material_name"));
ext.put("material_id", bucket.getString("material_id"));
ext.put("group_id", bucket.getString("group_id"));
ext.put("point_code", currentPoint);
ext.put("target", row.getString("station"));
AbstractTask coatingUpTask = taskFactory.getTask("CoatingUpTask");
coatingUpTask.create(ext);
} else {
throw new BadRequestException("速度太快啦,稍后再试...");
}
} finally {
if (tryLock) {
lock.unlock();
}
} }
// 判断是否有任务
String taskId = row.getString("task_id");
if (ObjectUtil.isNotEmpty(taskId)) {
// 有任务直接任务完成
SchBaseTask baseTask = taskService.getById(taskId);
AbstractTask task = taskFactory.getTask(baseTask.getConfig_code());
task.updateTaskStatus(baseTask.getTask_code(), TaskStatus.FINISHED);
return PdaResponse.requestOk();
}
if (ObjectUtil.isEmpty(row.getString("station"))) {
throw new BadRequestException("请设置产线目标站!");
}
List<JSONObject> infoByBucket = groupbucketService.getBucketInfoByBucket(vehicleCode);
if (infoByBucket.size() == 0) {
throw new BadRequestException("桶物料信息不存在!请检查组桶!");
}
JSONObject bucket = infoByBucket.get(0);
JSONObject ext = new JSONObject();
// todo: 先固定包衣,后续改
ext.put("config_code", "CoatingUpTask");
ext.put("vehicle_code", vehicleCode);
ext.put("material_qty", currentTotal);
ext.put("material_name", bucket.getString("material_name"));
ext.put("material_id", bucket.getString("material_id"));
ext.put("group_id", bucket.getString("group_id"));
ext.put("point_code", currentPoint);
ext.put("target", row.getString("station"));
AbstractTask coatingUpTask = taskFactory.getTask("CoatingUpTask");
coatingUpTask.create(ext);
return PdaResponse.requestOk(); return PdaResponse.requestOk();
} }
} }

View File

@@ -2,6 +2,7 @@ package org.nl.wms.sch_manage.service.impl;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import lombok.SneakyThrows;
import org.nl.common.exception.BadRequestException; import org.nl.common.exception.BadRequestException;
import org.nl.common.utils.SecurityUtils; import org.nl.common.utils.SecurityUtils;
import org.nl.config.IdUtil; import org.nl.config.IdUtil;
@@ -19,12 +20,15 @@ import org.nl.wms.sch_manage.service.util.tasks.WrappingDownTask;
import org.nl.wms.sch_manage.service.util.tasks.WrappingUpTask; import org.nl.wms.sch_manage.service.util.tasks.WrappingUpTask;
import org.nl.wms.warehouse_management.service.IMdPbGroupplateService; import org.nl.wms.warehouse_management.service.IMdPbGroupplateService;
import org.nl.wms.warehouse_management.service.dao.GroupPlate; import org.nl.wms.warehouse_management.service.dao.GroupPlate;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit;
/** /**
* *
@@ -51,84 +55,138 @@ public class SecondaryPackagingServiceImpl implements SecondaryPackagingService
private EmptyDiskConveyTask emptyDiskConveyTask; private EmptyDiskConveyTask emptyDiskConveyTask;
@Resource(name = "EmptyDiskEnterTask") @Resource(name = "EmptyDiskEnterTask")
private EmptyDiskEnterTask emptyDiskEnterTask; private EmptyDiskEnterTask emptyDiskEnterTask;
@Resource
private RedissonClient redissonClient;
@SneakyThrows
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void palletizingDown(JSONObject param) { public void palletizingDown(JSONObject param) {
// device_code、material_code、qty、vehicle_seq、pcsn、cases RLock lock = redissonClient.getLock("lock:palletizingDown");
MdMeMaterialbase materialCode = materialbaseService.getByCode(param.getString("material_code")); boolean tryLock = lock.tryLock(0, TimeUnit.SECONDS);
// 组盘 try {
GroupPlate groupPlate = new GroupPlate(); if (tryLock) {
groupPlate.setGroup_id(IdUtil.getStringId()); // device_code、material_code、qty、vehicle_seq、pcsn、cases
groupPlate.setVehicle_code( DateUtil.format(new Date(), "yyyyMMddss") + "-" + param.getString("vehicle_seq")); MdMeMaterialbase materialCode = materialbaseService.getByCode(param.getString("material_code"));
groupPlate.setRemark(param.toJSONString()); // 组盘
groupPlate.setStatus("1"); GroupPlate groupPlate = new GroupPlate();
groupPlate.setQty(param.getBigDecimal("qty")); groupPlate.setGroup_id(IdUtil.getStringId());
groupPlate.setPcsn(param.getString("pcsn")); groupPlate.setVehicle_code( DateUtil.format(new Date(), "yyyyMMddss") + "-" + param.getString("vehicle_seq"));
groupPlate.setMaterial_id(materialCode.getMaterial_id()); groupPlate.setRemark(param.toJSONString());
groupPlate.setCreate_id(SecurityUtils.getCurrentUserId()); groupPlate.setStatus("1");
groupPlate.setCreate_name(SecurityUtils.getCurrentNickName()); groupPlate.setQty(param.getBigDecimal("qty"));
groupPlate.setCreate_time(DateUtil.now()); groupPlate.setPcsn(param.getString("pcsn"));
// ....待定 groupPlate.setMaterial_id(materialCode.getMaterial_id());
groupplateService.save(groupPlate); groupPlate.setCreate_id(SecurityUtils.getCurrentUserId());
groupPlate.setCreate_name(SecurityUtils.getCurrentNickName());
groupPlate.setCreate_time(DateUtil.now());
// ....待定
groupplateService.save(groupPlate);
// 校验任务 // 校验任务
Integer num = taskService.haveTaskAll(param.getString("device_code")); Integer num = taskService.haveTaskAll(param.getString("device_code"));
if (num > 0) { if (num > 0) {
throw new BadRequestException("该点位已存在任务!"); throw new BadRequestException("该点位已存在任务!");
}
param.put("config_code", "PalletizingDownTask");
param.put("group_id", groupPlate.getGroup_id());
param.put("material_id", materialCode.getMaterial_id());
param.put("material_qty", groupPlate.getQty());
param.put("vehicle_code", groupPlate.getVehicle_code());
AbstractTask palletizingDownTask = taskFactory.getTask("PalletizingDownTask");
palletizingDownTask.create(param);
} else {
throw new BadRequestException("速度太快啦,稍后再试...");
}
} finally {
if (tryLock) {
lock.unlock();
}
} }
param.put("config_code", "PalletizingDownTask");
param.put("group_id", groupPlate.getGroup_id());
param.put("material_id", materialCode.getMaterial_id());
param.put("material_qty", groupPlate.getQty());
param.put("vehicle_code", groupPlate.getVehicle_code());
AbstractTask palletizingDownTask = taskFactory.getTask("PalletizingDownTask");
palletizingDownTask.create(param);
} }
@SneakyThrows
@Override @Override
public void wrappingCall(JSONObject param) { public void wrappingCall(JSONObject param) {
// 校验任务 RLock lock = redissonClient.getLock("lock:wrappingCall");
Integer num = taskService.haveTaskAll(param.getString("device_code")); boolean tryLock = lock.tryLock(0, TimeUnit.SECONDS);
if (num > 0) { try {
throw new BadRequestException("该点位已存在任务!"); if (tryLock) {
// 校验任务
Integer num = taskService.haveTaskAll(param.getString("device_code"));
if (num > 0) {
throw new BadRequestException("该点位已存在任务!");
}
param.put("config_code", "WrappingUpTask");
wrappingUpTask.create(param);
} else {
throw new BadRequestException("速度太快啦,稍后再试...");
}
} finally {
if (tryLock) {
lock.unlock();
}
} }
param.put("config_code", "WrappingUpTask");
wrappingUpTask.create(param);
} }
@SneakyThrows
@Override @Override
public void wrappingDown(JSONObject param) { public void wrappingDown(JSONObject param) {
// 校验任务 RLock lock = redissonClient.getLock("lock:wrappingDown");
Integer num = taskService.haveTaskAll(param.getString("device_code")); boolean tryLock = lock.tryLock(0, TimeUnit.SECONDS);
if (num > 0) { try {
throw new BadRequestException("该点位已存在任务!"); if (tryLock) {
// 校验任务
Integer num = taskService.haveTaskAll(param.getString("device_code"));
if (num > 0) {
throw new BadRequestException("该点位已存在任务!");
}
param.put("config_code", "WrappingDownTask");
wrappingDownTask.create(param);
} else {
throw new BadRequestException("速度太快啦,稍后再试...");
}
} finally {
if (tryLock) {
lock.unlock();
}
} }
param.put("config_code", "WrappingDownTask");
wrappingDownTask.create(param);
} }
@SneakyThrows
@Override @Override
public void palletizingCallEmpty(JSONObject param) { public void palletizingCallEmpty(JSONObject param) {
// 空盘进入任务、空盘运输任务、 RLock lock = redissonClient.getLock("lock:palletizingCallEmpty");
// 校验任务 boolean tryLock = lock.tryLock(0, TimeUnit.SECONDS);
Integer num = taskService.haveTaskAll(param.getString("device_code")); try {
if (num > 0) { if (tryLock) {
throw new BadRequestException("该点位已存在任务!"); // 空盘进入任务、空盘运输任务、
// 校验任务
Integer num = taskService.haveTaskAll(param.getString("device_code"));
if (num > 0) {
throw new BadRequestException("该点位已存在任务!");
}
// 获取缓存点有空托盘的位置
List<SchBasePoint> palletPoints = pointService.getNoTaskPointByRegionAndType("WBZQ", "2", "3");
if (palletPoints.size() == 0) {
// 创建空盘进入任务
param.put("config_code", "EmptyDiskEnterTask");
emptyDiskEnterTask.create(param);
return;
}
SchBasePoint point = palletPoints.get(0);
// 创建运输任务
param.put("point_code1", point.getPoint_code());
param.put("point_code2", param.getString("device_code"));
param.put("config_code", "EmptyDiskEnterTask");
emptyDiskConveyTask.create(param);
} else {
throw new BadRequestException("速度太快啦,稍后再试...");
}
} finally {
if (tryLock) {
lock.unlock();
}
} }
// 获取缓存点有空托盘的位置
List<SchBasePoint> palletPoints = pointService.getNoTaskPointByRegionAndType("WBZQ", "2", "3");
if (palletPoints.size() == 0) {
// 创建空盘进入任务
param.put("config_code", "EmptyDiskEnterTask");
emptyDiskEnterTask.create(param);
return;
}
SchBasePoint point = palletPoints.get(0);
// 创建运输任务
param.put("point_code1", point.getPoint_code());
param.put("point_code2", param.getString("device_code"));
param.put("config_code", "EmptyDiskEnterTask");
emptyDiskConveyTask.create(param);
} }
} }