no message

main
HUOJIN\92525 2025-12-31 18:02:34 +08:00
parent 77a5d00542
commit 2566ff544b
14 changed files with 127 additions and 107 deletions

View File

@ -41,6 +41,14 @@ public class AgvTask implements Serializable {
@JsonSerialize(using = ToStringSerializer.class)
private java.lang.Long id;
/**
* ID
*/
@Excel(name = "上游ID", width = 15)
@Schema(description = "上游ID")
@JsonSerialize(using = ToStringSerializer.class)
private java.lang.Long tesId;
/**
* ID
*/

View File

@ -4,7 +4,7 @@
<select id="queryPoints" resultType="org.cpte.modules.base.entity.Point">
SELECT point.* FROM base_point point
JOIN base_area area ON point.area_id = area.id
<where>
WHERE point.iz_active = 1
<if test="pointCode != null and pointCode != ''">
AND point.point_code = #{pointCode}
</if>
@ -14,7 +14,6 @@
<if test="areaCode != null and areaCode != ''">
AND area.area_code = #{areaCode}
</if>
</where>
</select>
<select id="findPointsWithSkuBatchPo" resultType="org.cpte.modules.base.entity.Point">
@ -24,6 +23,7 @@
JOIN data_inventory inv ON bp2.id = inv.point_id
JOIN base_item_key bik ON inv.item_key_id = bik.id
WHERE bp1.status = 0
AND bp1.iz_active=1
AND ba.area_code = #{areaCode}
AND bik.id IN
<foreach collection="itemKeyIds" item="itemKeyId" open="(" separator="," close=")">

View File

@ -103,7 +103,7 @@ public interface GeneralConstant {
/**
* AGV
*/
String HIK_CANCEL_TASK = "gtKsKrUQ";
String HIK_CANCEL_TASK = "gtKsKrUQ12";
/**
*

View File

@ -16,7 +16,7 @@ import org.springframework.web.bind.annotation.*;
@Tag(name = "输送线")
@RestController
@RequestMapping("/api/conveyorLine")
@RequestMapping("/conveyorLine")
@Slf4j
public class ConveyorLineController {
@ -31,8 +31,8 @@ public class ConveyorLineController {
@AutoLog(value = "输送线扫描")
@Operation(summary = "输送线-扫描托盘")
@PostMapping(value = "/scanTray")
@RequiresPermissions("conveyorLine:data_asn:scanTray")
public Result<String> scanTray(@RequestBody @Valid ScanTrayRequest scanTrayRequest) {
@IgnoreAuth
public Result<String> scanTray(@RequestBody ScanTrayRequest scanTrayRequest) {
iConveyorLineService.scanTray(scanTrayRequest);
return Result.OK("扫描成功");
}

View File

@ -6,11 +6,28 @@ import lombok.Data;
@Data
public class ScanTrayRequest {
//托盘码
@JsonProperty("stockCode")
private String stockCode;
//工作站
@JsonProperty("station")
private String station;
@JsonProperty("messageID")
private String messageID;
@JsonProperty("messageType")
private String messageType;
@JsonProperty("content")
private Content content;
@Data
public static class Content {
@JsonProperty("stationCode")
private String stationCode;
@JsonProperty("signal")
private Signal signal;
}
@Data
public static class Signal{
@JsonProperty("barCode")
private String barCode;
}
}

View File

@ -36,7 +36,7 @@ public class IConveyorLineServiceImpl implements IConveyorLineService {
@Override
public void scanTray(ScanTrayRequest scanTrayRequest) {
String lockKey = "scanTray:" + scanTrayRequest.getStockCode();
String lockKey = "scanTray:" + scanTrayRequest.getContent().getSignal().getBarCode();
String lockValue = null;
try {
lockValue = redissonLock.tryLock(lockKey, 10);

View File

@ -71,10 +71,8 @@ public class ScanTrayProcessor {
* @param scanTrayRequest
*/
public void scanTray(ScanTrayRequest scanTrayRequest) {
// 1.参数校验
validateParams(scanTrayRequest);
//2.数据准备
//1.数据准备
ScanTrayData data = prepareScanTrayData(scanTrayRequest);
//3.验证托盘
@ -94,10 +92,10 @@ public class ScanTrayProcessor {
* @param scanTrayRequest
*/
private void validateParams(ScanTrayRequest scanTrayRequest) {
if (StringUtils.isBlank(scanTrayRequest.getStockCode())) {
if (StringUtils.isBlank(scanTrayRequest.getContent().getSignal().getBarCode())) {
throw new RuntimeException("托盘码不能为空");
}
if (StringUtils.isBlank(scanTrayRequest.getStation())) {
if (StringUtils.isBlank(scanTrayRequest.getContent().getStationCode())) {
throw new RuntimeException("工作站不能为空");
}
}
@ -111,14 +109,24 @@ public class ScanTrayProcessor {
private ScanTrayData prepareScanTrayData(ScanTrayRequest scanTrayRequest) {
ScanTrayData data = new ScanTrayData();
//工作站
Point station = pointMapper.queryByPointCode(scanTrayRequest.getStation());
Point station = pointMapper.queryByPointCode(scanTrayRequest.getContent().getStationCode());
if (station == null) {
throw new RuntimeException("工作站【" + scanTrayRequest.getContent().getStationCode() + "】不存在");
}
data.setStation(station);
//容器
Stock stock = stockMapper.queryByStockCode(scanTrayRequest.getStockCode());
Stock stock = stockMapper.queryByStockCode(scanTrayRequest.getContent().getSignal().getBarCode());
if (stock == null) {
throw new RuntimeException("托盘【" + scanTrayRequest.getContent().getSignal().getBarCode() + "】不存在");
}
data.setStock(stock);
List<AsnDetail> asnDetails = asnDetailMapper.queryByStockCode(stock.getId(), AsnStatusEnum.CREATED.getValue());
if (CollectionUtils.isEmpty(asnDetails)) {
throw new RuntimeException("【" + stock.getStockCode() + "】托盘,无入库任务");
}
if (CollectionUtils.isNotEmpty(asnDetails)) {
//明细集合
data.setAsnDetails(asnDetails);
@ -153,22 +161,16 @@ public class ScanTrayProcessor {
Long stockId = data.getStock().getId();
String stockCode = data.getStock().getStockCode();
Asn asn = data.getAsn();
//验证当前托盘是否生成了TES任务
if (AsnStatusEnum.SCAN.getValue().equals(asn.getStatus())) {
throw new RuntimeException("【" + stockCode + "】托盘已扫描,请勿重复扫描");
}
List<AsnDetail> asnDetails = asnDetailMapper.queryByStockCode(stockId, AsnStatusEnum.CREATED.getValue());
if (CollectionUtils.isEmpty(asnDetails)) {
throw new RuntimeException("【" + stockCode + "】托盘,无入库任务");
}
//验证托盘是否有库存
if (inventoryMapper.exitsStockInventory(stockId) != null) {
throw new RuntimeException("【" + stockCode + "】托盘已入库");
}
}
/**
@ -206,6 +208,7 @@ public class ScanTrayProcessor {
List<PointScore> scoredPoints = availablePoints.stream()
.map(point -> clusterPointScore(point, station, itemKeys))
.sorted(Comparator.comparing(PointScore::getScore).reversed())
.limit(50)
.toList();
if (!scoredPoints.isEmpty()) {
@ -231,13 +234,13 @@ public class ScanTrayProcessor {
double channelScore = calculateChannelScore(point) * 0.15; // 权重15%
// 4. 均衡评分 - 避免热点区域
double balanceScore = calculateBalanceScore(point) * 0.1; // 权重10%
// double balanceScore = calculateBalanceScore(point) * 0.1; // 权重10%
// 5. 物料聚集潜力评分 - 新增
double clusterPotentialScore = calculateClusterPotentialScore(point, itemKeys) * 0.2; // 权重20%
// double clusterPotentialScore = calculateClusterPotentialScore(point, itemKeys) * 0.2; // 权重20%
totalScore = distanceScore + channelDepthScore + channelScore + balanceScore + clusterPotentialScore;
log.info("【{}】库位总分:{} - 距离评分: {} - 通道深度策略评分: {} - 通道类型评分: {} - 均衡评分: {} - 物料聚集评分: {}", point.getPointCode(), totalScore, distanceScore, channelDepthScore, channelScore, balanceScore, clusterPotentialScore);
totalScore = distanceScore + channelDepthScore + channelScore ;
log.info("【{}】库位总分:{} - 距离评分: {} - 通道深度策略评分: {} - 通道类型评分: {} - 均衡评分: {} - 物料聚集评分: {}", point.getPointCode(), totalScore, distanceScore, channelDepthScore, channelScore, 0, 0);
return new PointScore(point, totalScore);
}

View File

@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.cpte.modules.constant.GeneralConstant;
import org.cpte.modules.constant.enums.PickStatusEnum;
import org.cpte.modules.constant.enums.TaskStatusEnum;
@ -106,6 +107,7 @@ public class PickBackProcessor {
*/
public void pickBack(PickData data, List<Task> tasks) {
Map<Long, List<PickDetail>> pickDetailsCache = new HashMap<>();
tasks = tasks.stream().filter(task -> task.getPlanQty().equals(task.getMoveQty())).toList();
for (Task task : tasks) {
Pick pick = data.getPickMap().get(task.getPickId());
PickDetail pickDetail = data.getPickDetailMap().get(task.getPickDetailId());
@ -115,9 +117,11 @@ public class PickBackProcessor {
List<PickDetail> pickDetails = pickDetailsCache.computeIfAbsent(pickId, id -> pickDetailMapper.selectByMainId(id));
//已关闭的出库单
List<PickDetail> closedPickDetails = pickDetails.stream().filter(detail -> PickStatusEnum.CLOSED.getValue().equals(detail.getStatus())).toList();
int state = pickDetails.size() - closedPickDetails.size() == 1 ? 5 : 7;
int state = 7;
List<PickDetail> pickPickDetails = pickDetails.stream().filter(detail -> PickStatusEnum.PICKED.getValue().equals(detail.getStatus())).toList();
if (CollectionUtils.isNotEmpty(pickPickDetails)) {
state = pickDetails.size() - pickPickDetails.size() == 0 ? 5 : 7;
}
pickBackProcessor(pick, pickDetail, task, state);
} catch (Exception e) {
@ -184,7 +188,7 @@ public class PickBackProcessor {
*/
private void updatePickDetailResponse(PickDetail pickDetail, Task task, String code, String message) {
if (GeneralConstant.SMOM_SUCCESS_CODE.equals(code)) {
if (PickStatusEnum.PICKED.getValue().equals(pickDetail.getStatus())) {
if (pickDetail.getOrderQty().equals(pickDetail.getPickedQty())) {
pickDetail.setStatus(PickStatusEnum.CLOSED.getValue());
pickDetailMapper.updateById(pickDetail);
}

View File

@ -237,12 +237,14 @@ public class PickProcessor {
*/
private void updateInventory(Inventory inventory, BigDecimal pickedQty,
Map<Long, Inventory> inventoryUpdateMap) {
Inventory targetInventory = inventoryUpdateMap.getOrDefault(inventory.getId(), inventory);
BigDecimal quantity = BigDecimalUtil.subtract(targetInventory.getQuantity(), pickedQty, 0);
BigDecimal queuedQty = BigDecimalUtil.subtract(targetInventory.getQueuedQty(), pickedQty, 0);
targetInventory.setQuantity(quantity);
targetInventory.setQueuedQty(queuedQty);
inventoryUpdateMap.put(targetInventory.getId(), targetInventory);
if (inventory != null) {
Inventory targetInventory = inventoryUpdateMap.getOrDefault(inventory.getId(), inventory);
BigDecimal quantity = BigDecimalUtil.subtract(targetInventory.getQuantity(), pickedQty, 0);
BigDecimal queuedQty = BigDecimalUtil.subtract(targetInventory.getQueuedQty(), pickedQty, 0);
targetInventory.setQuantity(quantity);
targetInventory.setQueuedQty(queuedQty);
inventoryUpdateMap.put(targetInventory.getId(), targetInventory);
}
}
/**
@ -253,8 +255,10 @@ public class PickProcessor {
*/
private void deleteInventory(PickData data, Task task, List<Inventory> deleteToInventory) {
Inventory inventory = data.getInventoryMap().get(task.getInventoryId());
if (!deleteToInventory.contains(inventory)) {
deleteToInventory.add(inventory);
if (inventory != null) {
if (!deleteToInventory.contains(inventory)) {
deleteToInventory.add(inventory);
}
}
}
@ -302,11 +306,13 @@ public class PickProcessor {
*/
private void updateToStock(PickData data, Task task, List<Stock> updateToStock) {
Stock stock = data.getStockMap().get(task.getStockId());
if (!updateToStock.contains(stock)) {
stock.setStatus(CommonStatusEnum.FREE.getValue());
updateToStock.add(stock);
if (stock != null) {
if (!updateToStock.contains(stock)) {
stock.setStatus(CommonStatusEnum.FREE.getValue());
updateToStock.add(stock);
}
}
}
/**
@ -317,9 +323,11 @@ public class PickProcessor {
*/
private void updateToPoint(PickData data, Task task, List<Point> updateToPoint) {
Point point = data.getPointMap().get(task.getFromPointId());
if (!updateToPoint.contains(point)) {
point.setStatus(CommonStatusEnum.FREE.getValue());
updateToPoint.add(point);
if (point != null) {
if (!updateToPoint.contains(point)) {
point.setStatus(CommonStatusEnum.FREE.getValue());
updateToPoint.add(point);
}
}
}
@ -332,9 +340,11 @@ public class PickProcessor {
*/
private void addInventoryLog(PickData data, Task task, BigDecimal pickedQty, Map<Long, Inventory> inventoryUpdateMap) {
Inventory inventory = data.getInventoryMap().get(task.getInventoryId());
updateInventory(inventory, pickedQty, inventoryUpdateMap);
Pick pick = data.getPickMap().get(task.getPickId());
inventoryLogService.addPickInventoryLog(inventoryUpdateMap.get(inventory.getId()), task.getToPointId(), pickedQty, pick.getOrderNo(), task.getId(), null);
if (inventory != null) {
updateInventory(inventory, pickedQty, inventoryUpdateMap);
Pick pick = data.getPickMap().get(task.getPickId());
inventoryLogService.addPickInventoryLog(inventoryUpdateMap.get(inventory.getId()), task.getToPointId(), pickedQty, pick.getOrderNo(), task.getId(), null);
}
}
/**

View File

@ -12,16 +12,14 @@ import org.cpte.modules.tesAgv.request.TesCallbackRequest;
import org.cpte.modules.tesAgv.service.ITesAgvService;
import org.jeecg.common.api.vo.TesResult;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.util.UUIDGenerator;
import org.jeecg.config.shiro.IgnoreAuth;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
@Tag(name = "TES")
@RestController
@RequestMapping("/tes/apiv2")
@RequestMapping("/tes")
@Slf4j
public class TesAgvController {
@ -50,6 +48,7 @@ public class TesAgvController {
@AutoLog(value = "TES-任务上报")
@Operation(summary = "TES-任务上报")
@PostMapping(value = "/callBackTask")
@IgnoreAuth
public TesResult callBackTask(@RequestBody TesCallbackRequest tesCallbackRequest) {
try {
iTesAgvService.callBackTask(tesCallbackRequest);
@ -61,10 +60,11 @@ public class TesAgvController {
@AutoLog(value = "TES-取消任务")
@Operation(summary = "TES-取消任务")
@PostMapping(value = "/cancelTes")
public TesResult cancelTes(@RequestBody CancelTaskRequest cancelTask) {
@GetMapping(value = "/cancelTes")
@IgnoreAuth
public TesResult cancelTes(@RequestParam(name = "id", required = true) Long id) {
try {
iTesAgvService.cancelTes(cancelTask);
iTesAgvService.cancelTes(id);
return TesResult.success();
} catch (Exception e) {
return TesResult.error(e.getMessage());

View File

@ -7,11 +7,7 @@ import lombok.Data;
public class CancelTaskRequest extends BaseRequest {
// 任务ID
@JsonProperty("taskID")
private String taskID;
// 取消原因
@JsonProperty("reason")
private String reason;
private Long taskID;
// - 0 默认取消;- 1 强制取消
@JsonProperty("force")

View File

@ -31,9 +31,9 @@ public interface ITesAgvService {
/**
*
*
* @param cancelTask
* @param tesId
*/
void cancelTes(CancelTaskRequest cancelTask);
void cancelTes(Long tesId);
/**
*

View File

@ -7,10 +7,6 @@ import org.apache.commons.lang3.StringUtils;
import org.cpte.modules.agvTask.entity.AgvTask;
import org.cpte.modules.agvTask.mapper.AgvTaskMapper;
import org.cpte.modules.agvTask.service.IAgvTaskService;
import org.cpte.modules.base.entity.Point;
import org.cpte.modules.base.entity.Stock;
import org.cpte.modules.base.service.IPointService;
import org.cpte.modules.base.service.IStockService;
import org.cpte.modules.constant.GeneralConstant;
import org.cpte.modules.constant.enums.AgvStatusEnum;
import org.cpte.modules.constant.enums.AgvVendorEnum;
@ -23,6 +19,8 @@ import org.cpte.modules.tesAgv.request.CancelTaskRequest;
import org.cpte.modules.tesAgv.request.NewMovePodTaskRequest;
import org.cpte.modules.tesAgv.request.TesCallbackRequest;
import org.cpte.modules.tesAgv.service.ITesAgvService;
import org.cpte.modules.utils.HttpPostUtil;
import org.jeecg.common.util.UUIDGenerator;
import org.jeecg.modules.openapi.mapper.OpenApiMapper;
import org.jeecg.modules.system.mapper.SysDictMapper;
import org.springframework.beans.factory.annotation.Autowired;
@ -61,7 +59,7 @@ public class ITesAgvServiceImpl implements ITesAgvService {
public String generateTesAgvTaskJson(AgvTask agvTask) {
NewMovePodTaskRequest newMovePodTaskRequest = new NewMovePodTaskRequest();
newMovePodTaskRequest.setWarehouseID("HETU");
newMovePodTaskRequest.setRequestID(String.valueOf(System.currentTimeMillis()));
newMovePodTaskRequest.setRequestID(UUIDGenerator.generate());
newMovePodTaskRequest.setClientCode("WMS");
newMovePodTaskRequest.setSrcType(1);
@ -82,7 +80,7 @@ public class ITesAgvServiceImpl implements ITesAgvService {
log.info("请求报文:{}", json);
// 检查接口开关, 未开启则返回
if (sysDictMapper.queryByDictCode(GeneralConstant.OPEN_FLAG) == null) {
updateAgvTaskResponse(agvTask, "接口未开启", GeneralConstant.TES_FAIL_CODE);
updateAgvTaskResponse(agvTask, null, "接口未开启", GeneralConstant.TES_FAIL_CODE);
return;
}
String url = openApiMapper.getRequestUrl(openApi).getOriginUrl();
@ -90,15 +88,8 @@ public class ITesAgvServiceImpl implements ITesAgvService {
Integer returnCode = null;
String returnMsg = null;
try {
//String result = HttpPostUtil.sendPostReq(url, json);
String result = "{" +
" \"returnCode\":0," +
" \"returnMsg\":\"成功\"," +
" \"returnUserMsg\":\"成功\"," +
" \"data\":{" +
" \"taskID\":74602" +
" }\n" +
"}";
String result = HttpPostUtil.sendPostReq(url, json, null);
log.info("TES任务下发URL:{} - 请求参数:{} - 响应结果:{}", url, json, result);
if (StringUtils.isEmpty(result)) {
returnMsg = "Tes返回信息:接口调用失败";
@ -114,15 +105,18 @@ public class ITesAgvServiceImpl implements ITesAgvService {
returnCode = resulObject.getInteger("returnCode");
returnMsg = resulObject.getString("returnMsg");
if (!GeneralConstant.TES_SUCCESS_CODE.equals(returnCode)) {
throw new RuntimeException("Tes返回消息:" + returnMsg);
}
JSONObject data = resulObject.getJSONObject("data");
String tesId = data.getString("taskID");
// 更新任务状态
updateAgvTaskResponse(agvTask, returnMsg, returnCode);
updateAgvTaskResponse(agvTask, Long.parseLong(tesId), returnMsg, returnCode);
} catch (Exception e) {
// 记录异常到 AgvTask
updateAgvTaskResponse(agvTask, e.getMessage(), GeneralConstant.TES_FAIL_CODE);
updateAgvTaskResponse(agvTask, null, e.getMessage(), GeneralConstant.TES_FAIL_CODE);
}
}
@ -152,34 +146,22 @@ public class ITesAgvServiceImpl implements ITesAgvService {
public String generateCancelTaskJson(AgvTask agvTask) {
CancelTaskRequest cancelTaskRequest = new CancelTaskRequest();
cancelTaskRequest.setWarehouseID("HETU");
cancelTaskRequest.setRequestID(String.valueOf(System.currentTimeMillis()));
cancelTaskRequest.setRequestTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
cancelTaskRequest.setClientCode("WCS");
cancelTaskRequest.setTaskID(agvTask.getId().toString());
cancelTaskRequest.setReason("取消任务");
cancelTaskRequest.setRequestID(UUIDGenerator.generate());
cancelTaskRequest.setClientCode("WMS");
cancelTaskRequest.setTaskID(agvTask.getTesId());
cancelTaskRequest.setForce(0);
cancelTaskRequest.setWithoutRunning(0);
return JSON.toJSONString(cancelTaskRequest);
}
@Override
public void cancelTes(CancelTaskRequest cancelTask) {
AgvTask agvTask = agvTaskMapper.selectById(cancelTask.getTaskID());
public void cancelTes(Long id) {
AgvTask agvTask = agvTaskMapper.selectById(id);
String url = openApiMapper.getRequestUrl(GeneralConstant.TES_CANCEL_TASK).getOriginUrl();
String json = generateCancelTaskJson(agvTask);
Integer returnCode = null;
String returnMsg = null;
//String result = HttpPostUtil.sendPostReq(url, json);
String result = "{" +
" \"returnCode\":0," +
" \"returnMsg\":\"成功\"," +
" \"returnUserMsg\":\"成功\"," +
" \"data\":{" +
" \"taskID\":74602" +
" }\n" +
"}";
String result = HttpPostUtil.sendPostReq(url, json, null);
if (StringUtils.isEmpty(result)) {
returnMsg = "Tes返回信息:接口调用失败";
throw new RuntimeException(returnMsg);
@ -276,13 +258,15 @@ public class ITesAgvServiceImpl implements ITesAgvService {
*
*
* @param agvTask
* @param tesId ID
* @param message
* @param code
*/
private void updateAgvTaskResponse(AgvTask agvTask, String message, Integer code) {
private void updateAgvTaskResponse(AgvTask agvTask, Long tesId, String message, Integer code) {
if (agvTask != null) {
if (GeneralConstant.TES_SUCCESS_CODE.equals(code)) {
agvTask.setStatus(AgvStatusEnum.EXECUTING.getValue());
agvTask.setTesId(tesId);
}
agvTask.setResMessage(message);
agvTask.setStartTime(new Date());

View File

@ -20,10 +20,8 @@ public class ElevatorMapUtil {
static {
dataMap = new ConcurrentHashMap<>();
List<String> ST102 = Arrays.asList("DT001", "DT002");
List<String> ST104 = Arrays.asList("DT003", "DT004");
// 初始化Map
dataMap.put("ST102", ST102);
dataMap.put("ST104", ST104);
dataMap.put("3F-F1-OUT-01-01-R", ST102);
}
/**