no message

main
HUOJIN\92525 2025-11-28 16:33:56 +08:00
parent 50a9c19e15
commit d78b5e48ed
40 changed files with 991 additions and 300 deletions

View File

@ -108,6 +108,13 @@ public class AgvTask implements Serializable {
@Dict(dicCode = "agv_vendor")
private java.lang.String agvVendor;
/**
* 0,1
*/
@Excel(name = "是否整托", width = 15)
@Schema(description = "是否整托")
private java.lang.Integer izAll;
/**
*
*/

View File

@ -20,7 +20,7 @@ public interface AgvTaskMapper extends BaseMapper<AgvTask> {
* @param carrierCode
* @param agvVendor ;AGV/TES
*/
@Select(value = "select count(id) from data_agv_task where carrier_code = #{carrierCode} and agv_vendor = #{agvVendor} and status in (1,2,3) for update ")
@Select(value = "select count(id) from data_agv_task where carrier_code = #{carrierCode} and status in (1,2,3) and agv_vendor = #{agvVendor} for update ")
Long existsByStockCode(@Param("carrierCode") String carrierCode, @Param("agvVendor") String agvVendor);
/**
@ -29,7 +29,7 @@ public interface AgvTaskMapper extends BaseMapper<AgvTask> {
* @param startCode
* @param agvVendor ;AGV/TES
*/
@Select(value = "select count(id) from data_agv_task where start_code = #{startCode} and agv_vendor = #{agvVendor} and status in (2,3) for update ")
@Select(value = "select count(id) from data_agv_task where start_code = #{startCode} and status in (2,3) and agv_vendor = #{agvVendor} for update ")
Long existsByStartCode(@Param("startCode") String startCode, @Param("agvVendor") String agvVendor);
@ -39,8 +39,8 @@ public interface AgvTaskMapper extends BaseMapper<AgvTask> {
* @param endCode
* @param agvVendor ;AGV/TES
*/
@Select(value = "select count(id) from data_agv_task where end_code = #{pointCode} and agv_vendor = #{agvVendor} and status in (2,3) for update ")
Long existsByEndCode(@Param("pointCode") String endCode, @Param("agvVendor") String agvVendor);
@Select(value = "select count(id) from data_agv_task where end_code = #{endCode} and status in (2,3) and agv_vendor = #{agvVendor} for update ")
Long existsByEndCode(@Param("endCode") String endCode, @Param("agvVendor") String agvVendor);
/**
* AGV
@ -50,4 +50,12 @@ public interface AgvTaskMapper extends BaseMapper<AgvTask> {
*/
@Select(value = "select * from data_agv_task where status = #{status} and agv_vendor = #{agvVendor}")
List<AgvTask> queryAgvTaskList(@Param("status") Integer status, @Param("agvVendor") String agvVendor);
/**
* TES
*
* @param endCode
*/
@Select(value = "select * from data_agv_task where end_code = #{endCode} and type='OUTBOUND' and status = 4 and agv_vendor = 'TES' order by create_time desc limit 1 ")
AgvTask queryByLastEndCode(@Param("endCode") String endCode);
}

View File

@ -38,5 +38,4 @@ public interface IAgvTaskService extends IService<AgvTask> {
*/
AgvTask bulidAgvTask(Long businessDetailId, String carrierCode, String startCode, String endCode, String taskType, String type, String agvVendor);
}

View File

@ -9,6 +9,7 @@ import org.cpte.modules.constant.enums.AgvStatusEnum;
import org.cpte.modules.constant.enums.AgvVendorEnum;
import org.cpte.modules.constant.enums.StockTypeEnum;
import org.jeecg.common.system.vo.LoginUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

View File

@ -1,14 +1,16 @@
package org.cpte.modules.base.service;
import org.apache.ibatis.annotations.Param;
import org.cpte.modules.base.entity.Point;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
import java.util.Map;
/**
* @Description:
* @author: cpte
* @Date: 2025-10-28
* @Date: 2025-10-28
* @Version: V1.0
*/
public interface IPointService extends IService<Point> {
@ -22,12 +24,14 @@ public interface IPointService extends IService<Point> {
/**
*
*
* @param point
*/
void bindPoint(Point point);
/**
*
*
* @param point
*/
void unbindPoint(Point point);
@ -60,12 +64,21 @@ public interface IPointService extends IService<Point> {
/**
* 线
*
* @param status
* @param status
* @param areaCode
* @param key
* @return pointEntity
* @param key
* @return Point
*/
Point getWorkStationPoint(Integer status,String areaCode, String key);
Point getWorkStationPoint(Integer status, String areaCode, String key);
Point queryToPoint(String pointCode,Integer status,String areaCode);
/**
*
*
* @param pointCode 线
* @param key
* @return Point
*/
String getElevatorPoint(String pointCode, String key);
Point queryToPoint(String pointCode, Integer status, String areaCode);
}

View File

@ -9,6 +9,7 @@ import org.cpte.modules.base.service.IAreaService;
import org.cpte.modules.base.service.IPointService;
import org.cpte.modules.constant.enums.AreaTypeEnum;
import org.cpte.modules.constant.enums.CommonStatusEnum;
import org.cpte.modules.utils.ElevatorMapUtil;
import org.jeecg.common.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -132,6 +133,16 @@ public class PointServiceImpl extends ServiceImpl<PointMapper, Point> implements
return dstPointList.get((int) currentIndex);
}
@Override
public String getElevatorPoint(String pointCode, String key) {
List<String> pointCodes = ElevatorMapUtil.getValueByKey(pointCode);
if (pointCodes.isEmpty()) {
throw new RuntimeException("电梯库位未配置");
}
long currentIndex = redisUtil.incr(key, 1) % pointCodes.size();
return pointCodes.get((int) currentIndex);
}
@Override
public Point queryToPoint(String pointCode, Integer status, String areaCode) {
Point dstPoint = null;

View File

@ -39,6 +39,11 @@ public interface GeneralConstant {
*/
String CK_DOCK_TASK_INDEX = "ck_dock_task_index";
/**
*
*/
String CK_ELEVATOR_TASK_INDEX = "ck_elevator_task_index";
/**
*
@ -50,8 +55,23 @@ public interface GeneralConstant {
*/
String PICK_ORDER_NO = "pick_order_no";
/**
* TES
*/
String TES_POD_TASK = "atyYyn1T";
/**
* TES
*/
String TES_CANCEL_TASK = "gtKsKrUQ";
/**
*
*/
String INBOUND_CALLBACK = "7Q7sqpIh";
/**
*
*/
String OUTBOUND_CALLBACK = "oSD7sYxi";
}

View File

@ -24,4 +24,16 @@ public enum BusinessTypeEnum {
this.desc = desc;
}
/**
* valuedesc
*/
public static String getDescByValue(String value) {
for (BusinessTypeEnum item : BusinessTypeEnum.values()) {
if (item.value.equals(value)) {
return item.desc;
}
}
return null;
}
}

View File

@ -16,7 +16,7 @@ public enum PickStatusEnum {
ASSIGNED(3, "已分配"),
PICKING(4, "拣货"),
PICKING(4, "部分拣货"),
PICKED(5, "拣货完成"),

View File

@ -0,0 +1,38 @@
package org.cpte.modules.constant.enums;
import lombok.Getter;
/**
* Task
*
* @author: cpte
*/
@Getter
public enum TaskStatusEnum {
CREATED(1, "已创建"),
EXECUTING(2, "执行中"),
ARRIVED(3, "已到达"),
COMPLETED(4, "已完成"),
CANCELLED(5, "已取消"),
;
/**
*
*/
private final Integer value;
/**
*
*/
private final String desc;
TaskStatusEnum(Integer value, String desc) {
this.value = value;
this.desc = desc;
}
}

View File

@ -1,5 +1,6 @@
package org.cpte.modules.conveyorLine.controller;
import com.alibaba.fastjson.JSONObject;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
@ -10,10 +11,7 @@ import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
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 = "输送线")
@RestController
@ -37,13 +35,10 @@ public class ConveyorLineController {
return Result.OK("扫描成功");
}
@AutoLog(value = "输送线大屏")
@Operation(summary = "输送线-大屏显示")
@PostMapping(value = "/")
public Result<String> showConveyorLineBigScreen() {
iConveyorLineService.showConveyorLineBigScreen();
return Result.OK();
@GetMapping(value = "/showConveyorLine")
public Result<JSONObject> showConveyorLine(@RequestParam(name = "conveyorLine") String conveyorLine) {
return Result.OK(iConveyorLineService.showConveyorLine(conveyorLine));
}
}

View File

@ -1,5 +1,6 @@
package org.cpte.modules.conveyorLine.service;
import com.alibaba.fastjson.JSONObject;
import org.cpte.modules.conveyorLine.request.ScanTrayRequest;
public interface IConveyorLineService {
@ -11,5 +12,5 @@ public interface IConveyorLineService {
*/
void scanTray(ScanTrayRequest scanTrayRequest);
void showConveyorLineBigScreen();
JSONObject showConveyorLine(String conveyorLine);
}

View File

@ -1,6 +1,9 @@
package org.cpte.modules.conveyorLine.service.impl;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
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;
@ -14,6 +17,8 @@ import org.cpte.modules.conveyorLine.service.IConveyorLineService;
import org.cpte.modules.inventory.mapper.InventoryMapper;
import org.cpte.modules.receive.entity.AsnDetail;
import org.cpte.modules.receive.mapper.AsnDetailMapper;
import org.cpte.modules.shipping.entity.Task;
import org.cpte.modules.shipping.mapper.TaskMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -33,6 +38,9 @@ public class IConveyorLineServiceImpl implements IConveyorLineService {
@Autowired
private AsnDetailMapper asnDetailMapper;
@Autowired
private TaskMapper taskMapper;
@Autowired
private AgvTaskMapper agvTaskMapper;
@ -69,10 +77,10 @@ public class IConveyorLineServiceImpl implements IConveyorLineService {
}
//输送线的起点
Point srcPoint=pointMapper.selectById(asnDetail.getToPointId());
Point srcPoint = pointMapper.selectById(asnDetail.getToPointId());
//通过算法获取目标点位
Point dstPoint=pointService.queryToPoint(null, CommonStatusEnum.FREE.getValue(), AreaTypeEnum.CPCCQ.getValue());
Point dstPoint = pointService.queryToPoint(null, CommonStatusEnum.FREE.getValue(), AreaTypeEnum.CPCCQ.getValue());
//锁定目标库位
pointService.bindPoint(dstPoint);
@ -80,6 +88,41 @@ public class IConveyorLineServiceImpl implements IConveyorLineService {
//验证通过生成Tes任务
iAgvTaskService.createAgvTask(asnDetail.getId(), stock.getStockCode(), srcPoint.getPointCode(), dstPoint.getPointCode(), null, BusinessTypeEnum.INBOUND.getValue(), AgvVendorEnum.TES.getValue());
}
@Override
public JSONObject showConveyorLine(String conveyorLine) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("stockCode", "");
jsonObject.put("taskType", "");
jsonObject.put("endCode", "");
jsonObject.put("izAll", "");
jsonObject.put("description", "");
AgvTask agvTask = agvTaskMapper.queryByLastEndCode(conveyorLine);
if (agvTask == null) {
return jsonObject;
}
List<Task> tasks = taskMapper.queryByAgvTask(agvTask.getId());
if (CollectionUtils.isEmpty(tasks)) {
return jsonObject;
}
String stockCode = tasks.get(0).getStockCode();
String taskType = BusinessTypeEnum.getDescByValue(agvTask.getType());
String endCode = agvTask.getEndCode();
String izAll = agvTask.getIzAll()==1 ? "拆托" : "整托";
String description = izAll.equals("拆托")
? "请人工将托盘【" + stockCode + "】叉走,避免任务拥堵"
: "请等待AGV将托盘【" + stockCode + "】叉走";
jsonObject.put("stockCode", stockCode);
jsonObject.put("taskType", taskType);
jsonObject.put("endCode", endCode);
jsonObject.put("izAll", izAll);
jsonObject.put("description", description);
return jsonObject;
}
}

View File

@ -126,8 +126,12 @@ public class IHikAgvServiceImpl implements IHikAgvService {
if (agvTask == null) {
throw new RuntimeException("【" + taskReporterRequest.getRobotTaskCode() + "】任务不存在");
}
Stock stock = iStockService.validateStock(agvTask.getCarrierCode());
Point point = iPointService.validatePoint(agvTask.getEndCode());
Point point = null;
Stock stock = stock = iStockService.validateStock(agvTask.getCarrierCode());
if (BusinessTypeEnum.INBOUND.getValue().equals(agvTask.getType())) {
point = iPointService.validatePoint(agvTask.getEndCode());
}
String status = taskReporterRequest.getExtra().getValues().getMethod();
switch (status) {
case "outbin":
@ -161,8 +165,10 @@ public class IHikAgvServiceImpl implements IHikAgvService {
* @param agvTask
*/
private void handleEnd(AgvTask agvTask, Stock stock, Point point) {
//绑定容器和点位
iStockService.bindStock(stock, point);
if (BusinessTypeEnum.INBOUND.getValue().equals(agvTask.getType())) {
//绑定容器和点位
iStockService.bindStock(stock, point);
}
//更新任务状态
agvTask.setStatus(AgvStatusEnum.COMPLETED.getValue());
agvTask.setEndTime(new Date());

View File

@ -3,7 +3,7 @@
<mapper namespace="org.cpte.modules.inventory.mapper.InventoryMapper">
<select id="queryInventoryWithLock" resultType="org.cpte.modules.inventory.entity.Inventory">
SELECT * FROM data_inventory
WHERE status = 1
WHERE status in (1,2)
AND quantity > 0
AND item_id IN
<foreach collection="itemIds" item="itemId" open="(" separator="," close=")">

View File

@ -28,4 +28,12 @@ public interface IInventoryService extends IService<Inventory> {
* @return Inventory
*/
Inventory createInventory(Long stockId, BigDecimal receivedQty, Asn asn, AsnDetail asnDetail, ReceiveRecord receiveRecord);
/**
* ID
*
* @param inventoryIds ID
* @return Map<Long, Inventory>
*/
Map<Long, Inventory> queryByInventoryIdsToMap(List<Long> inventoryIds);
}

View File

@ -11,6 +11,7 @@ import org.cpte.modules.inventory.service.IInventoryService;
import org.cpte.modules.receive.entity.Asn;
import org.cpte.modules.receive.entity.AsnDetail;
import org.cpte.modules.receive.entity.ReceiveRecord;
import org.cpte.modules.shipping.entity.PickDetail;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -18,9 +19,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.*;
/**
* @Description:
@ -58,6 +57,21 @@ public class InventoryServiceImpl extends ServiceImpl<InventoryMapper, Inventory
.createBy(asnDetail.getCreateBy())
.createTime(new Date())
.build();
return this.save(inventory)?inventory: null;
return this.save(inventory) ? inventory : null;
}
@Override
public Map<Long, Inventory> queryByInventoryIdsToMap(List<Long> inventoryIds) {
if (CollectionUtils.isEmpty(inventoryIds)) {
return Collections.emptyMap();
}
Map<Long, Inventory> inventoryMap = new HashMap<>();
List<Inventory> inventories = inventoryMapper.selectByIds(inventoryIds);
for (Inventory inventory : inventories) {
inventoryMap.put(inventory.getId(), inventory);
}
return inventoryMap;
}
}

View File

@ -39,7 +39,7 @@ public class InventoryLogServiceImpl extends ServiceImpl<InventoryLogMapper, Inv
@Override
@Transactional(rollbackFor = Exception.class)
public void addInboundInventoryLog(Inventory inventory,Long srcPointId, BigDecimal changeQty, String businessNo, Long businessDetailId, String description) {
public void addInboundInventoryLog(Inventory inventory, Long srcPointId, BigDecimal changeQty, String businessNo, Long businessDetailId, String description) {
InventoryLog inventoryLog = buildInventoryLog(inventory, changeQty, businessNo, businessDetailId, description);
// 入库类型
inventoryLog.setLogType(InventoryLogEnum.INBOUND.getValue());
@ -66,8 +66,10 @@ public class InventoryLogServiceImpl extends ServiceImpl<InventoryLogMapper, Inv
//出库分配
inventoryLog.setLogType(InventoryLogEnum.ALLOC.getValue());
//实际数量不变
inventoryLog.setBeforeAllocatedQty(inventory.getQuantity());
inventoryLog.setAfterAllocatedQty(AllocatedQty);
inventoryLog.setChangeQty(BigDecimal.ZERO);
inventoryLog.setBeforeAllocatedQty(BigDecimalUtil.subtract(inventory.getQueuedQty(), AllocatedQty, 0));
inventoryLog.setAfterAllocatedQty(inventory.getQueuedQty());
log.debug("库存分配日志记录成功,变动前分配数量: {}, 变动后分配数量: {}", inventoryLog.getBeforeAllocatedQty(), inventoryLog.getAfterAllocatedQty());
addInventoryLog(inventoryLog);
}
@ -86,12 +88,15 @@ public class InventoryLogServiceImpl extends ServiceImpl<InventoryLogMapper, Inv
@Override
@Transactional(rollbackFor = Exception.class)
public void addPickInventoryLog(Inventory inventory, BigDecimal changeQty, String businessNo, Long businessDetailId, String description) {
InventoryLog inventoryLog = buildInventoryLog(inventory, changeQty, businessNo, businessDetailId, description);
InventoryLog inventoryLog = buildInventoryLog(inventory, BigDecimal.ZERO, businessNo, businessDetailId, description);
// 拣货类型
inventoryLog.setLogType(InventoryLogEnum.PICK.getValue());
inventoryLog.setLogType(InventoryLogEnum.OUTBOUND.getValue());
// 出库数量为负数
inventoryLog.setBeforeQty(BigDecimalUtil.add(inventory.getQuantity(), changeQty, 0));
inventoryLog.setChangeQty(changeQty.negate());
inventoryLog.setAfterQty(inventory.getQuantity());
inventoryLog.setAfterAllocatedQty(BigDecimal.ZERO);
inventoryLog.setBeforeAllocatedQty(BigDecimal.ZERO);
addInventoryLog(inventoryLog);
}

View File

@ -51,37 +51,35 @@ public class AllocateJob implements Job {
public void execute(JobExecutionContext jobExecutionContext) {
// 查询未分配或者部分分配的出库
List<Long> pickList = pickMapper.queryUnallocatedPick();
if (pickList.isEmpty()) {
return;
}
// 分配出库
long startTime = System.currentTimeMillis();
List<String> resultMsg = iPickService.allocatePick2(pickList);
long endTime = System.currentTimeMillis();
log.info("分配出库明细耗时:{}ms", endTime - startTime);
if (CollectionUtils.isNotEmpty(resultMsg)) {
// 生成缓存键
String cacheKey = generateCacheKey(resultMsg);
if (CollectionUtils.isNotEmpty(pickList)) {
// 分配出库
long startTime = System.currentTimeMillis();
List<String> resultMsg = iPickService.allocatePick(pickList);
long endTime = System.currentTimeMillis();
log.info("分配出库明细耗时:{}ms", endTime - startTime);
if (CollectionUtils.isNotEmpty(resultMsg)) {
// 生成缓存键
String cacheKey = generateCacheKey(resultMsg);
// 检查是否已经处理过相同的内容
if (!processedCache.containsKey(cacheKey)) {
// 新内容,记录日志
baseCommonService.addLog("出库任务分配:" + "\n" + cacheKey, CommonConstant.LOG_TYPE_2, CommonConstant.OPERATE_TYPE_1);
// 检查是否已经处理过相同的内容
if (!processedCache.containsKey(cacheKey)) {
// 新内容,记录日志
baseCommonService.addLog("出库任务分配:" + "\n" + cacheKey, CommonConstant.LOG_TYPE_2, CommonConstant.OPERATE_TYPE_1);
// 添加到缓存
processedCache.put(cacheKey, true);
// 添加到缓存
processedCache.put(cacheKey, true);
// 控制缓存大小
if (processedCache.size() > MAX_CACHE_SIZE) {
// 移除一部分旧缓存(简单实现,可以按需优化)
processedCache.clear();
// 控制缓存大小
if (processedCache.size() > MAX_CACHE_SIZE) {
// 移除一部分旧缓存(简单实现,可以按需优化)
processedCache.clear();
}
}
}
}
//生成出库AGV出库任务
long startTime2 = System.currentTimeMillis();
iTaskService.generateAgvTask();
long endTime2 = System.currentTimeMillis();
log.info("生成AGV出库任务耗时{}ms", endTime2 - startTime2);

View File

@ -5,6 +5,7 @@ import org.cpte.modules.agvTask.entity.AgvTask;
import org.cpte.modules.agvTask.mapper.AgvTaskMapper;
import org.cpte.modules.constant.enums.AgvStatusEnum;
import org.cpte.modules.constant.enums.AgvVendorEnum;
import org.cpte.modules.constant.enums.BusinessTypeEnum;
import org.cpte.modules.hikAgv.service.IHikAgvService;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
@ -30,13 +31,24 @@ public class HikAgvJob implements Job {
}
String taskSubmitUrl = "http://localhost:8000/cpte-wms/rcs/rtas/api/robot/controller/task/submit";
for (AgvTask agvTask : agvTaskList) {
boolean isStartCodeAvailable = agvTaskMapper.existsByStartCode(agvTask.getStartCode(), AgvVendorEnum.HIK.getValue()) == 0;
if (isStartCodeAvailable) {
hikAgvService.sendHikAgvTask(
taskSubmitUrl,
hikAgvService.generateHikAgvTaskJson(agvTask),
agvTask
);
if(BusinessTypeEnum.INBOUND.getValue().equals(agvTask.getType())){
boolean isStartCodeAvailable = agvTaskMapper.existsByStartCode(agvTask.getStartCode(), AgvVendorEnum.HIK.getValue()) == 0;
if (isStartCodeAvailable) {
hikAgvService.sendHikAgvTask(
taskSubmitUrl,
hikAgvService.generateHikAgvTaskJson(agvTask),
agvTask
);
}
}else if(BusinessTypeEnum.OUTBOUND.getValue().equals(agvTask.getType())){
boolean isEndCodeAvailable = agvTaskMapper.existsByEndCode(agvTask.getEndCode(), AgvVendorEnum.HIK.getValue()) == 0;
if (isEndCodeAvailable) {
hikAgvService.sendHikAgvTask(
taskSubmitUrl,
hikAgvService.generateHikAgvTaskJson(agvTask),
agvTask
);
}
}
}

View File

@ -285,9 +285,9 @@ public class AsnServiceImpl extends ServiceImpl<AsnMapper, Asn> implements IAsnS
updateAsnDetailResponse(asn, "接口未开启");
return;
}
if(AsnStatusEnum.){
/* if(AsnStatusEnum.){
}
}*/
String json = receiveCallbackJson(asn, asnDetail, stock);
String url = openApiMapper.getRequestUrl(GeneralConstant.INBOUND_CALLBACK);
log.info("入库回传请求报文:{}", json);

View File

@ -1,14 +1,13 @@
package org.cpte.modules.shipping.controller;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.cpte.modules.constant.GeneralConstant;
import org.cpte.modules.serialNumber.PickSerialNumberRule;
import org.cpte.modules.shipping.entity.Task;
@ -271,4 +270,52 @@ public class PickController {
}
return Result.OK("文件导入失败!");
}
@AutoLog(value = "出库分配")
@Operation(summary = "出库分配")
@RequiresPermissions("shipping:data_pick:allocatePick")
@GetMapping(value = "/allocatePick")
public Result<String> allocatePick(@RequestParam(name = "ids", required = true) String ids) {
if (StringUtils.isEmpty(ids)) {
return Result.error("请选择待分配的出库单");
}
try {
List<String> idsList = Arrays.asList(ids.split(","));
List<Long> idsLongList = idsList.stream().map(Long::parseLong).toList();
List<String> msgList = pickService.allocatePick(idsLongList);
String result = msgList.stream().filter(Objects::nonNull).collect(Collectors.joining("\n"));
if (StringUtils.isEmpty(result)) {
result = "分配成功";
return Result.OK(result);
} else {
return Result.error(result);
}
} catch (Exception e) {
return Result.error("分配异常:" + e.getMessage());
}
}
@AutoLog(value = "取消分配")
@Operation(summary = "取消分配")
@RequiresPermissions("shipping:data_pick:cancelAllocate")
@GetMapping(value = "/cancelAllocate")
public Result<String> cancelAllocate(@RequestParam(name = "ids", required = true) String ids) {
if (StringUtils.isEmpty(ids)) {
return Result.error("请选择需要取消的出库单");
}
try {
List<String> idsList = Arrays.asList(ids.split(","));
List<Long> idsLongList = idsList.stream().map(Long::parseLong).toList();
List<String> msgList = pickService.cancelAllocate(idsLongList);
String result = msgList.stream().filter(Objects::nonNull).collect(Collectors.joining("\n"));
if (StringUtils.isEmpty(result)) {
result = "取消成功";
return Result.OK(result);
} else {
return Result.error(result);
}
} catch (Exception e) {
return Result.error("取消异常:" + e.getMessage());
}
}
}

View File

@ -148,6 +148,22 @@ public class PickDetail implements Serializable {
@Excel(name = "备注", width = 15)
@Schema(description = "备注")
private java.lang.String description;
/**
*
*/
@Excel(name = "返回报文", width = 15)
@Schema(description = "返回报文")
private java.lang.String resMessage;
/**
*
*/
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Schema(description = "回传时间")
private java.util.Date resTime;
/**
* ID
*/

View File

@ -31,9 +31,6 @@ public interface PickMapper extends BaseMapper<Pick> {
*
* @return List<Pick>
*/
@Select("select id from data_pick where status = 1 " +
"union all " +
"select id from data_pick where status = 2 ")
@Select("select id from data_pick where status in (1,2,4) ")
List<Long> queryUnallocatedPick();
}

View File

@ -12,7 +12,7 @@ import java.util.List;
/**
* @Description:
* @author: cpte
* @Date: 2025-11-17
* @Date: 2025-11-17
* @Version: V1.0
*/
public interface TaskMapper extends BaseMapper<Task> {
@ -23,4 +23,9 @@ public interface TaskMapper extends BaseMapper<Task> {
*/
@Select("SELECT * FROM data_task WHERE agv_task_id is null order by create_time for update ")
List<Task> queryUnallocatedTask();
@Select("SELECT * FROM data_task WHERE agv_task_id = #{agvTaskId} ")
List<Task> queryByAgvTask(@Param("agvTaskId") Long agvTaskId);
List<Task> queryByPickIds(@Param("pickIds") List<Long> pickIds);
}

View File

@ -1,5 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.cpte.modules.shipping.mapper.TaskMapper">
<select id="queryByPickIds" resultType="org.cpte.modules.shipping.entity.Task">
SELECT * FROM data_task
WHERE pick_id IN
<foreach collection="pickIds" item="pickId" open="(" separator="," close=")">
#{pickId}
</foreach>
</select>
</mapper>

View File

@ -1,5 +1,6 @@
package org.cpte.modules.shipping.service;
import org.cpte.modules.base.entity.Point;
import org.cpte.modules.shipping.entity.PickDetail;
import org.cpte.modules.shipping.entity.Pick;
import com.baomidou.mybatisplus.extension.service.IService;
@ -54,19 +55,31 @@ public interface IPickService extends IService<Pick> {
*/
List<String> allocatePick(List<Long> pickIds);
/**
*
*
*
* @param pickIds
*/
List<String> allocatePick2(List<Long> pickIds);
List<String> cancelAllocate(List<Long> pickIds);
/**
*
*
* @param tasks
*/
void pickTask(List<Task> tasks, Point endPoint);
/**
*
*
* @param task
* @param pick
* @param pickDetail
* @param task
* @param state 5.7
*/
void pickTaskCallback(Task task);
void pickTaskCallback(Pick pick, PickDetail pickDetail, Task task, Integer state);
}

View File

@ -1,5 +1,7 @@
package org.cpte.modules.shipping.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.shiro.SecurityUtils;
@ -14,20 +16,24 @@ import org.cpte.modules.base.service.IStockService;
import org.cpte.modules.constant.enums.*;
import org.cpte.modules.inventory.entity.Inventory;
import org.cpte.modules.inventory.mapper.InventoryMapper;
import org.cpte.modules.inventory.service.IInventoryService;
import org.cpte.modules.inventoryLog.service.IInventoryLogService;
import org.cpte.modules.shipping.entity.Pick;
import org.cpte.modules.shipping.entity.PickDetail;
import org.cpte.modules.shipping.entity.Task;
import org.cpte.modules.shipping.mapper.PickDetailMapper;
import org.cpte.modules.shipping.mapper.PickMapper;
import org.cpte.modules.shipping.mapper.TaskMapper;
import org.cpte.modules.shipping.service.IPickService;
import org.cpte.modules.shipping.service.ITaskService;
import org.cpte.modules.shipping.vo.InventoryGroupKey;
import org.cpte.modules.utils.BatchUtils;
import org.cpte.modules.utils.BatchUtil;
import org.cpte.modules.utils.BigDecimalUtil;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.base.service.BaseCommonService;
import org.jeecg.modules.openapi.mapper.OpenApiMapper;
import org.jeecg.modules.system.mapper.SysDictMapper;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
@ -54,8 +60,14 @@ public class PickServiceImpl extends ServiceImpl<PickMapper, Pick> implements IP
@Autowired
private PickDetailMapper pickDetailMapper;
@Autowired
private TaskMapper taskMapper;
@Autowired
private InventoryMapper inventoryMapper;
@Autowired
private SysDictMapper sysDictMapper;
@Autowired
private OpenApiMapper openApiMapper;
@Autowired
private IItemService iItemService;
@Autowired
private IStockService iStockService;
@ -64,11 +76,13 @@ public class PickServiceImpl extends ServiceImpl<PickMapper, Pick> implements IP
@Autowired
private ITaskService iTaskService;
@Autowired
private IInventoryService inventoryService;
@Autowired
private IInventoryLogService iInventoryLogService;
@Autowired
private BaseCommonService baseCommonService;
@Autowired
private BatchUtils batchUtils;
private BatchUtil batchUtils;
/**
* Map
@ -77,6 +91,9 @@ public class PickServiceImpl extends ServiceImpl<PickMapper, Pick> implements IP
* @return Map
*/
private Map<Long, Pick> queryByPickIdsToMap(List<Long> pickIds) {
if (CollectionUtils.isEmpty(pickIds)) {
return Collections.emptyMap();
}
Map<Long, Pick> pickMap = new HashMap<>();
List<Pick> pickList = pickMapper.selectByIds(pickIds);
for (Pick pick : pickList) {
@ -85,6 +102,36 @@ public class PickServiceImpl extends ServiceImpl<PickMapper, Pick> implements IP
return pickMap;
}
/**
* Map
*
* @param pickDetailIds id
* @return Map
*/
private Map<Long, PickDetail> queryByPickDetailIdsToMap(List<Long> pickDetailIds) {
if (CollectionUtils.isEmpty(pickDetailIds)) {
return Collections.emptyMap();
}
Map<Long, PickDetail> pickDetailMap = new HashMap<>();
List<PickDetail> pickDetails = pickDetailMapper.selectByIds(pickDetailIds);
for (PickDetail pickDetail : pickDetails) {
pickDetailMap.put(pickDetail.getId(), pickDetail);
}
return pickDetailMap;
}
private Map<Long, PickDetail> queryPickDetailByPickIds(List<Long> pickIds) {
if (CollectionUtils.isEmpty(pickIds)) {
return Collections.emptyMap();
}
List<PickDetail> pickDetails = pickDetailMapper.queryByPickIds(pickIds);
Map<Long, PickDetail> pickDetailMap = new HashMap<>();
for (PickDetail pickDetail : pickDetails) {
pickDetailMap.put(pickDetail.getId(), pickDetail);
}
return pickDetailMap;
}
@Override
@Transactional(rollbackFor = Exception.class)
@ -151,14 +198,21 @@ public class PickServiceImpl extends ServiceImpl<PickMapper, Pick> implements IP
status = PickStatusEnum.PARTIAL.getValue();
}
// 如果开始拣货但未完成
else if (pickedQty.compareTo(BigDecimal.ZERO) > 0 && pickedQty.compareTo(allocatedQty) < 0) {
else if (pickedQty.compareTo(BigDecimal.ZERO) > 0 && pickedQty.compareTo(orderQty) < 0) {
status = PickStatusEnum.PICKING.getValue();
}
// 如果已完成拣货
else if (pickedQty.compareTo(allocatedQty) >= 0 && allocatedQty.compareTo(BigDecimal.ZERO) > 0) {
else if (pickedQty.compareTo(orderQty) >= 0 && orderQty.compareTo(BigDecimal.ZERO) > 0) {
status = PickStatusEnum.PICKED.getValue();
}
//明细的状态都是已关闭则出库单状态为已关闭
boolean isClosed = pickDetails.stream().allMatch(detail -> PickStatusEnum.CLOSED.getValue().equals(detail.getStatus()));
log.info("出库单明细是否全部关闭:{}", isClosed);
if (isClosed) {
status = PickStatusEnum.CLOSED.getValue();
}
// 更新实体属性
pick.setOrderQty(orderQty);
pick.setAllocatedQty(allocatedQty);
@ -244,155 +298,6 @@ public class PickServiceImpl extends ServiceImpl<PickMapper, Pick> implements IP
@Override
@Transactional(rollbackFor = Exception.class)
public List<String> allocatePick(List<Long> pickIds) {
List<String> errorMsgList = new ArrayList<>();
//查询出库单
Map<Long, Pick> pickMap = queryByPickIdsToMap(pickIds);
//查询出库单明细
List<PickDetail> pickDetails = pickDetailMapper.queryByPickIds(pickIds);
//获取不为null、空字符的批次号
List<String> propC1List = pickDetails.stream().map(PickDetail::getPropC1).filter(Objects::nonNull).filter(e -> !e.isEmpty()).distinct().toList();
//获取不为null、空字符的外部库存状态
List<String> propC3List = pickDetails.stream().map(PickDetail::getPropC3).filter(Objects::nonNull).filter(e -> !e.isEmpty()).distinct().toList();
//获取不为null、空字符的仓库代码
List<String> whCodeList = pickMap.values().stream().map(Pick::getWhCode).filter(Objects::nonNull).filter(e -> !e.isEmpty()).distinct().toList();
//查询需要分配的物料
List<Long> itemIds = pickDetails.stream().map(PickDetail::getItemId).distinct().toList();
Map<Long, Item> itemMap = iItemService.queryByItemIdsToMap(itemIds);
//根据物料、批次号、外部库存状态、外部仓库代码批量查询库存
List<Inventory> inventories = inventoryMapper.queryInventoryWithLock(itemIds, propC1List, propC3List, whCodeList);
if (inventories.isEmpty()) {
List<String> itemCodes = itemMap.values().stream().map(Item::getItemCode).toList();
errorMsgList.add(itemCodes + "物料库存不足");
return errorMsgList;
}
//容器
List<Long> stockIds = inventories.stream().map(Inventory::getStockId).distinct().toList();
Map<Long, Stock> stockMap = iStockService.queryByStockIdsToMap(stockIds);
//目标库位
List<Long> pointIds = inventories.stream().map(Inventory::getPointId).distinct().toList();
Map<Long, Point> pointMap = iPointService.queryByPointIdsToMap(pointIds);
List<Inventory> updateToInventory = new ArrayList<>();
List<PickDetail> updateToPickDetail = new ArrayList<>();
for (PickDetail pickDetail : pickDetails) {
Pick pick = pickMap.get(pickDetail.getPickId());
Item item = itemMap.get(pickDetail.getItemId());
//待分配数量
BigDecimal unAllocatedQty = BigDecimalUtil.subtract(pickDetail.getOrderQty(), pickDetail.getAllocatedQty(), 0);
// 如果已经满足需求则跳过
if (unAllocatedQty.compareTo(BigDecimal.ZERO) <= 0) {
continue;
}
for (Inventory inventory : inventories) {
// 筛选符合要求的库存记录
if (!inventory.getItemId().equals(pickDetail.getItemId())) {
continue;
}
// 匹配批次号(如果有指定)
if (pickDetail.getPropC1() != null && !pickDetail.getPropC1().isEmpty()) {
if (!pickDetail.getPropC1().equals(inventory.getPropC1())) {
continue;
}
}
// 匹配库存状态(如果有指定)
if (pickDetail.getPropC3() != null && !pickDetail.getPropC3().isEmpty()) {
if (!pickDetail.getPropC3().equals(inventory.getPropC3())) {
continue;
}
}
// 匹配仓库
if (!pick.getWhCode().equals(inventory.getWhCode())) {
continue;
}
//库存可用数量
BigDecimal availableQty = BigDecimalUtil.subtract(inventory.getQuantity(), inventory.getQueuedQty(), 0);
if (availableQty.compareTo(BigDecimal.ZERO) <= 0) {
continue;
}
BigDecimal allocateQty = unAllocatedQty.compareTo(availableQty) < 0 ? unAllocatedQty : availableQty;
// 更新库存占用数量
inventory.setQueuedQty(BigDecimalUtil.add(inventory.getQueuedQty(), allocateQty, 0));
inventory.setStatus(InventoryStatusEnum.ALLOCATED.getValue());
updateToInventory.add(inventory);
// 更新明细分配数量
BigDecimal fpQty = BigDecimalUtil.add(pickDetail.getAllocatedQty(), allocateQty, 0);
pickDetail.setAllocatedQty(fpQty);
// 更新明细状态
if (fpQty.compareTo(pickDetail.getOrderQty()) >= 0) {
pickDetail.setStatus(PickStatusEnum.ASSIGNED.getValue());
} else {
pickDetail.setStatus(PickStatusEnum.PARTIAL.getValue());
}
updateToPickDetail.add(pickDetail);
//容器
Stock stock = stockMap.get(inventory.getStockId());
//库位
Point point = pointMap.get(inventory.getPointId());
//TODO 后续补充生成Task任务
//判断是否整托
String tuo = "拆托";
if (inventory.getQuantity().compareTo(allocateQty) == 0) {
tuo = "整托";
}
log.info("生成任务: {} - {} - {}", stock.getStockCode(), point.getPointCode(), tuo);
unAllocatedQty = BigDecimalUtil.subtract(unAllocatedQty, allocateQty, 0);
//分配库存日志
iInventoryLogService.addAllocInventoryLog(inventory, allocateQty, pick.getOrderNo(), pickDetail.getId(), pickDetail.getDescription());
// 如果已完全分配,则跳出内层循环
if (unAllocatedQty.compareTo(BigDecimal.ZERO) <= 0) {
break;
}
}
// 若仍有未分配的数量,说明库存不足
if (unAllocatedQty.compareTo(BigDecimal.ZERO) > 0) {
errorMsgList.add(item.getItemCode() + "物料库存不足");
continue;
}
}
//批量操作
if (CollectionUtils.isNotEmpty(updateToInventory)) {
inventoryMapper.updateById(updateToInventory);
}
if (CollectionUtils.isNotEmpty(updateToPickDetail)) {
pickDetailMapper.updateById(updateToPickDetail);
}
//刷新出库单
for (Pick pick : pickMap.values()) {
refreshPick(pick, pickDetailMapper.selectByMainId(pick.getId()));
}
return errorMsgList;
}
@Override
@Transactional(rollbackFor = Exception.class)
public List<String> allocatePick2(List<Long> pickIds) {
// 错误信息去重LinkedHashSet保证顺序和唯一
Set<String> errorMsgSet = new LinkedHashSet<>();
@ -499,7 +404,7 @@ public class PickServiceImpl extends ServiceImpl<PickMapper, Pick> implements IP
//库位
Point fromPoint = pointMap.get(inventory.getPointId());
//是否整托:0整托、1拆托
Integer izAll = inventory.getQuantity().compareTo(allocateQty) == 0 ? 0 : 1;
Integer izAll = availableQty.compareTo(allocateQty) == 0 ? 0 : 1;
//判断当前容器是否一致,同一个容器去同一个目标库位
if (!currStockId.equals(stock.getId())) {
toPoint = iPointService.getWorkStationPoint(CommonStatusEnum.FREE.getValue(), AreaTypeEnum.CK_DOCK.getValue(), GeneralConstant.CK_DOCK_TASK_INDEX);
@ -517,10 +422,16 @@ public class PickServiceImpl extends ServiceImpl<PickMapper, Pick> implements IP
}
//分配后仍有缺货,记录错误
if (unAllocatedQty.compareTo(BigDecimal.ZERO) > 0) {
errorMsgSet.add(String.format("物料【%s】库存不足需求:%s已分配:%s缺货:%s",
item.getItemCode(), pickDetail.getOrderQty(),
String failInfo = String.format(
"物料【%s】库存不足任务号:%s行号:%d需求:%s已分配:%s缺货:%s",
item.getItemCode(),
pick.getNo(),
pickDetail.getLineNo(),
pickDetail.getOrderQty(),
BigDecimalUtil.subtract(pickDetail.getOrderQty(), unAllocatedQty, 0),
unAllocatedQty));
unAllocatedQty
);
errorMsgSet.add(failInfo);
}
}
@ -543,8 +454,263 @@ public class PickServiceImpl extends ServiceImpl<PickMapper, Pick> implements IP
}
@Override
public void pickTaskCallback(Task task) {
Pick pick = pickMapper.selectById(task.getPickId());
@Transactional(rollbackFor = Exception.class)
public List<String> cancelAllocate(List<Long> pickIds) {
Set<String> errorMsgSet = new LinkedHashSet<>();
// -------------------------- 1. 查询关联数据批量查询减少DB交互--------------------------
Map<Long, Pick> pickMap = queryByPickIdsToMap(pickIds);
Map<Long, PickDetail> pickDetailMap = queryPickDetailByPickIds(pickIds);
List<Task> tasks = taskMapper.queryByPickIds(pickIds);
List<Long> inventoryIds = tasks.stream().map(Task::getInventoryId).distinct().toList();
Map<Long, Inventory> inventoryMap = inventoryService.queryByInventoryIdsToMap(inventoryIds);
// -------------------------- 2. 创建更新列表---------------------------
List<Inventory> updateToInventory = new ArrayList<>();
List<PickDetail> updateToPickDetail = new ArrayList<>();
List<Task> deleteToTask = new ArrayList<>();
// -------------------------- 3. 循环处理任务---------------------------
for (Task task : tasks) {
Pick pick = pickMap.get(task.getPickId());
PickDetail pickDetail = pickDetailMap.get(task.getPickDetailId());
if (task.getAgvTaskId() != null) {
errorMsgSet.add(String.format("取消失败:【%s】已生成AGV任务", pick.getNo()));
continue;
}
//取消数量
BigDecimal cancelQty = task.getPlanQty();
Inventory inventory = inventoryMap.get(task.getInventoryId());
inventory.setQueuedQty(BigDecimalUtil.subtract(inventory.getQueuedQty(), cancelQty, 0));
Integer inv_status = inventory.getQueuedQty().compareTo(BigDecimal.ZERO) > 0 ? InventoryStatusEnum.ALLOCATED.getValue() : InventoryStatusEnum.AVAILABLE.getValue();
inventory.setStatus(inv_status);
updateToInventory.add(inventory);
pickDetail.setAllocatedQty(BigDecimalUtil.subtract(pickDetail.getAllocatedQty(), cancelQty, 0));
Integer pd_status = pickDetail.getStatus();
if (pickDetail.getAllocatedQty().compareTo(BigDecimal.ZERO) <= 0) {
pd_status = PickStatusEnum.CREATED.getValue();
} else if (pickDetail.getAllocatedQty().compareTo(pickDetail.getOrderQty()) < 0) {
pd_status = PickStatusEnum.PARTIAL.getValue();
}
pickDetail.setStatus(pd_status);
updateToPickDetail.add(pickDetail);
deleteToTask.add(task);
iInventoryLogService.addUnAllocInventoryLog(inventory, cancelQty, pick.getOrderNo(), pickDetail.getId(), pickDetail.getDescription());
}
// -------------------------- 4. 批量更新减少DB交互--------------------------
if (CollectionUtils.isNotEmpty(updateToInventory)) {
batchUtils.updateBatchInventory(updateToInventory);
}
if (CollectionUtils.isNotEmpty(updateToPickDetail)) {
batchUtils.updateBatchPickDetail(updateToPickDetail);
}
if (CollectionUtils.isNotEmpty(deleteToTask)) {
taskMapper.deleteByIds(deleteToTask);
}
// -------------------------- 5. 刷新出库单状态 --------------------------
for (Pick pick : pickMap.values()) {
refreshPick(pick, pickDetailMapper.selectByMainId(pick.getId()));
}
return new ArrayList<>(errorMsgSet);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void pickTask(List<Task> tasks,Point endPoint) {
if (CollectionUtils.isEmpty(tasks)) {
throw new RuntimeException("无拣货任务");
}
// ================= 1. 数据准备 (批量查询) =================
// 1.1 获取出库单
List<Long> pickIds = tasks.stream().map(Task::getPickId).distinct().toList();
List<Long> pickDetailIds = tasks.stream().map(Task::getPickDetailId).distinct().toList();
List<Long> inventoryIds = tasks.stream().map(Task::getInventoryId).distinct().toList();
// 1.2 构建映射 Map
Map<Long, Pick> pickMap = queryByPickIdsToMap(pickIds);
Map<Long, PickDetail> pickDetailMap = queryByPickDetailIdsToMap(pickDetailIds);
Map<Long, Inventory> inventoryMap = inventoryService.queryByInventoryIdsToMap(inventoryIds);
// -------------------------- 2. 创建更新列表---------------------------
List<PickDetail> updateToPickDetail = new ArrayList<>();
List<Task> updateToTask = new ArrayList<>();
List<Inventory> updateToInventory = new ArrayList<>();
List<Long> deleteToInventoryIds = new ArrayList<>();
// -------------------------- 3. 循环拣货 -------------------
for (Task task : tasks) {
BigDecimal pickedQty = BigDecimalUtil.subtract(task.getPlanQty(), task.getMoveQty(), 0);
if (pickedQty.compareTo(BigDecimal.ZERO) <= 0) {
continue;
}
Pick pick = pickMap.get(task.getPickId());
PickDetail pickDetail = pickDetailMap.get(task.getPickDetailId());
// 更新拣货数量,状态
pickDetail.setPickedQty(BigDecimalUtil.add(pickDetail.getPickedQty(), pickedQty, 0));
Integer status = pickedQty.compareTo(pickDetail.getOrderQty()) >= 0 ? PickStatusEnum.PICKED.getValue() : PickStatusEnum.PICKING.getValue();
pickDetail.setStatus(status);
updateToPickDetail.add(pickDetail);
// 更新任务
task.setMoveQty(pickedQty);
task.setTaskStatus(TaskStatusEnum.COMPLETED.getValue());
updateToTask.add(task);
//扣减库存
Inventory inventory = inventoryMap.get(task.getInventoryId());
inventory.setQuantity(BigDecimalUtil.subtract(inventory.getQuantity(), pickedQty, 0));
inventory.setQueuedQty(BigDecimalUtil.subtract(inventory.getQueuedQty(), pickedQty, 0));
inventory.setPointId(endPoint.getId());
updateToInventory.add(inventory);
//库存为0删除库存
if (inventory.getQuantity().compareTo(BigDecimal.ZERO) <= 0) {
deleteToInventoryIds.add(inventory.getId());
}
iInventoryLogService.addPickInventoryLog(inventory, pickedQty, pick.getOrderNo(), task.getPickDetailId(), null);
}
// -------------------------- 4. 批量操作 --------------------------
if (CollectionUtils.isNotEmpty(updateToPickDetail)) {
batchUtils.updateBatchPickDetail(updateToPickDetail);
}
if (CollectionUtils.isNotEmpty(updateToTask)) {
batchUtils.updateBatchTask(updateToTask);
}
if (CollectionUtils.isNotEmpty(updateToInventory)) {
batchUtils.updateBatchInventory(updateToInventory);
}
if (CollectionUtils.isNotEmpty(deleteToInventoryIds)) {
inventoryService.removeByIds(deleteToInventoryIds);
}
// -------------------------- 6. 出库回传 --------------------------
Map<Long, List<PickDetail>> pickDetailsCache = new HashMap<>();
for (Task task : tasks) {
Pick pick = pickMap.get(task.getPickId());
PickDetail pickDetail = pickDetailMap.get(task.getPickDetailId());
// 缓存查询结果,避免重复查询
Long pickId = pick.getId();
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;
try {
pickTaskCallback(pick, pickDetail, task, state);
} catch (Exception e) {
log.error("出库任务回传失败任务ID: {}, 错误信息: {}", task.getId(), e.getMessage(), e);
}
// 刷新时重新查询最新的数据
List<PickDetail> latestPickDetails = pickDetailMapper.selectByMainId(pick.getId());
pickDetailsCache.put(pickId, latestPickDetails); // 更新缓存
refreshPick(pick, latestPickDetails);
}
}
/**
* JSON
*/
private String pickTaskCallbackJson(Pick pick, PickDetail pickDetail, Task task, Integer state) {
JSONObject jsonObject = new JSONObject(true);
jsonObject.put("No", pick.getNo());
jsonObject.put("OrderNo", pick.getThirdOrderNo());
jsonObject.put("State", state);
jsonObject.put("LineNo", pickDetail.getLineNo());
jsonObject.put("Lpn", task.getStockCode());
jsonObject.put("Qty", task.getPlanQty());
jsonObject.put("IsTakeDown", task.getIzAll());
jsonObject.put("Project", pickDetail.getProject());
jsonObject.put("TaskNo", pickDetail.getTaskNo());
jsonObject.put("LotAtt04", pickDetail.getPropC1());
jsonObject.put("LotAtt010", pickDetail.getPropC3());
return jsonObject.toJSONString();
}
@Override
public void pickTaskCallback(Pick pick, PickDetail pickDetail, Task task, Integer state) {
// 检查接口开关, 未开启则返回
if (sysDictMapper.queryByDictCode(GeneralConstant.OPEN_FLAG) == null) {
updatePickDetailResponse(pickDetail, "接口未开启", Boolean.FALSE);
return;
}
if (PickStatusEnum.CLOSED.getValue().equals(pickDetail.getStatus())) {
return;
}
String json = pickTaskCallbackJson(pick, pickDetail, task, state);
String url = openApiMapper.getRequestUrl(GeneralConstant.OUTBOUND_CALLBACK);
log.info("出库回传请求报文:{}", json);
Boolean Success = null;
String Message = null;
try {
//String result = HttpPostUtil.sendPostReq(url, json);
String result = "{\n" +
" \"Success\": true,\n" +
" \"Message\": \"出库回传成功\"\n" +
"}";
if (org.apache.commons.lang3.StringUtils.isEmpty(result)) {
Message = "出库回传返回信息:接口调用失败";
throw new RuntimeException(Message);
}
JSONObject resulObject = JSON.parseObject(result);
if (resulObject == null) {
Message = "出库回传返回信息:接口返回为空";
throw new RuntimeException(Message);
}
Success = resulObject.getBoolean("Success");
Message = resulObject.getString("Message");
if (!Success) {
throw new RuntimeException("出库回传返回信息:" + Message);
}
updatePickDetailResponse(pickDetail, Message, Success);
} catch (Exception e) {
updatePickDetailResponse(pickDetail, e.getMessage(), Boolean.FALSE);
}
}
/**
*
*
* @param pickDetail
* @param message
*/
private void updatePickDetailResponse(PickDetail pickDetail, String message, Boolean Success) {
if (pickDetail != null) {
if (Success) {
pickDetail.setStatus(PickStatusEnum.CLOSED.getValue());
}
pickDetail.setResMessage(message);
pickDetail.setResTime(new Date());
pickDetailMapper.updateById(pickDetail);
}
}
}

View File

@ -1,6 +1,5 @@
package org.cpte.modules.shipping.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.shiro.SecurityUtils;
@ -11,11 +10,14 @@ import org.cpte.modules.base.entity.Point;
import org.cpte.modules.base.entity.Stock;
import org.cpte.modules.constant.enums.AgvVendorEnum;
import org.cpte.modules.constant.enums.BusinessTypeEnum;
import org.cpte.modules.constant.enums.InventoryStatusEnum;
import org.cpte.modules.inventory.entity.Inventory;
import org.cpte.modules.inventory.mapper.InventoryMapper;
import org.cpte.modules.shipping.entity.Task;
import org.cpte.modules.shipping.mapper.TaskMapper;
import org.cpte.modules.shipping.service.ITaskService;
import org.cpte.modules.shipping.vo.TaskGroupKey;
import org.cpte.modules.utils.BatchUtils;
import org.cpte.modules.utils.BatchUtil;
import org.jeecg.common.system.vo.LoginUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -39,11 +41,14 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements IT
@Autowired
private TaskMapper taskMapper;
@Autowired
private InventoryMapper inventoryMapper;
@Autowired
private IAgvTaskService agvTaskService;
@Autowired
private BatchUtils batchUtils;
private BatchUtil batchUtils;
@Override
@Transactional(rollbackFor = Exception.class)
@ -136,9 +141,13 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements IT
Map<TaskGroupKey, AgvTask> groupToAgvTaskMap = new HashMap<>();
for (Map.Entry<TaskGroupKey, List<Task>> entry : taskGroupMap.entrySet()) {
TaskGroupKey key = entry.getKey();
List<Task> tasks = entry.getValue();
boolean allSplit = tasks.stream().allMatch(task -> task != null && task.getIzAll() == 1);
Integer izAll = allSplit ? 1 : 0;
log.info("任务分组:{}", key);
if (!groupToAgvTaskMap.containsKey(key)) {
AgvTask agvTask = agvTaskService.bulidAgvTask(null, key.getStockCode(), key.getFromPointCode(), key.getToPointCode(), null, BusinessTypeEnum.OUTBOUND.getValue(), AgvVendorEnum.TES.getValue());
agvTask.setIzAll(izAll);
createToAgvTaskList.add(agvTask);
groupToAgvTaskMap.put(key, agvTask); // 建立映射
log.info("创建AGV任务{}", agvTask);
@ -162,5 +171,14 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements IT
if (CollectionUtils.isNotEmpty(updateToTaskList)) {
batchUtils.updateBatchTask(updateToTaskList);
}
List<Long> inventoryIdList = taskList.stream().map(Task::getInventoryId).distinct().toList();
List<Inventory> inventoryList = inventoryMapper.selectByIds(inventoryIdList);
for (Inventory inventory : inventoryList) {
inventory.setStatus(InventoryStatusEnum.OUTBOUND.getValue());
}
if (CollectionUtils.isNotEmpty(inventoryList)) {
batchUtils.updateBatchInventory(inventoryList);
}
}
}

View File

@ -4,6 +4,8 @@ import com.alibaba.fastjson.JSON;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.cpte.modules.agvTask.entity.AgvTask;
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.response.TesResult;
@ -60,4 +62,30 @@ public class TesAgvController {
return TesResult.error("系统异常: " + e.getMessage());
}
}
@AutoLog(value = "TesAGV-取消任务")
@Operation(summary = "TesAGV-取消任务")
@PostMapping(value = "/cancelTask")
public TesResult cancelTask(@RequestBody CancelTaskRequest cancelTask) {
try {
iTesAgvService.cancelTask(cancelTask);
return TesResult.success();
} catch (Exception e) {
return TesResult.error(e.getMessage());
}
}
@AutoLog(value = "TesAGV-重送任务")
@Operation(summary = "TesAGV-重送任务")
@PostMapping(value = "/resendTesTask")
public TesResult resendTesTask(@RequestBody AgvTask agvTask) {
try {
iTesAgvService.resendTesTask(agvTask);
return TesResult.success();
} catch (Exception e) {
return TesResult.error(e.getMessage());
}
}
}

View File

@ -0,0 +1,32 @@
package org.cpte.modules.tesAgv.request;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public abstract class BaseRequest {
/**
* ID
*/
@JsonProperty("warehouseID")
private String warehouseID;
/**
* ID
*/
@JsonProperty("requestID")
private String requestID;
/**
*
*/
@JsonProperty("requestTime")
private String requestTime;
/**
*
*/
@JsonProperty("clientCode")
private String clientCode;
}

View File

@ -0,0 +1,23 @@
package org.cpte.modules.tesAgv.request;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public class CancelTaskRequest extends BaseRequest {
// 任务ID
@JsonProperty("taskID")
private String taskID;
// 取消原因
@JsonProperty("reason")
private String reason;
// - 0 默认取消;- 1 强制取消
@JsonProperty("force")
private Integer force;
// - 0 默认取消;- 1 已经开始执行,则不取消
@JsonProperty("withoutRunning")
private Integer withoutRunning;
}

View File

@ -32,25 +32,7 @@ import java.util.List;
"bizExt"
})
@Data
public class NewMovePodTaskRequest {
/**
* ID
*/
@JsonProperty("warehouseID")
private String warehouseID;
/**
* ID
*/
@JsonProperty("requestID")
private String requestID;
/**
*
*/
@JsonProperty("clientCode")
private String clientCode;
public class NewMovePodTaskRequest extends BaseRequest{
/**
* (1-9)9

View File

@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public class TesCallbackRequest {
public class TesCallbackRequest{
/**
*
*/
@ -17,12 +17,6 @@ public class TesCallbackRequest {
@JsonProperty("messageType")
private Integer messageType;
/**
* ID
*/
@JsonProperty("warehouseID")
private String warehouseID;
/**
*
*/

View File

@ -1,6 +1,7 @@
package org.cpte.modules.tesAgv.service;
import org.cpte.modules.agvTask.entity.AgvTask;
import org.cpte.modules.tesAgv.request.CancelTaskRequest;
import org.cpte.modules.tesAgv.request.TesCallbackRequest;
public interface ITesAgvService {
@ -14,11 +15,11 @@ public interface ITesAgvService {
/**
*
*
* @param url
* @param openApi
* @param json json
* @param agvTask
*/
void sendTesAgvTask(String url, String json, AgvTask agvTask);
void sendTesAgvTask(String openApi, String json, AgvTask agvTask);
/**
*
@ -26,4 +27,18 @@ public interface ITesAgvService {
* @param tesCallbackRequest
*/
void callBackTask(TesCallbackRequest tesCallbackRequest);
/**
*
*
* @param cancelTask
*/
void cancelTask(CancelTaskRequest cancelTask);
/**
*
*
* @param agvTask
*/
void resendTesTask(AgvTask agvTask);
}

View File

@ -7,18 +7,29 @@ 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;
import org.cpte.modules.constant.enums.BusinessTypeEnum;
import org.cpte.modules.receive.service.IAsnService;
import org.cpte.modules.shipping.entity.Task;
import org.cpte.modules.shipping.mapper.TaskMapper;
import org.cpte.modules.shipping.service.IPickService;
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.jeecg.modules.openapi.mapper.OpenApiMapper;
import org.jeecg.modules.system.mapper.SysDictMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.text.SimpleDateFormat;
import java.util.*;
@Service
@ -28,12 +39,27 @@ public class ITesAgvServiceImpl implements ITesAgvService {
@Autowired
private SysDictMapper sysDictMapper;
@Autowired
private TaskMapper taskMapper;
@Autowired
private AgvTaskMapper agvTaskMapper;
@Autowired
private OpenApiMapper openApiMapper;
@Autowired
private IPointService iPointService;
@Autowired
private IStockService iStockService;
@Autowired
private IAsnService iAsnService;
@Autowired
private IPickService iPickService;
@Autowired
private IAgvTaskService iAgvTaskService;
@ -42,6 +68,7 @@ public class ITesAgvServiceImpl implements ITesAgvService {
NewMovePodTaskRequest newMovePodTaskRequest = new NewMovePodTaskRequest();
newMovePodTaskRequest.setWarehouseID("HETU");
newMovePodTaskRequest.setRequestID(String.valueOf(System.currentTimeMillis()));
newMovePodTaskRequest.setRequestTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
newMovePodTaskRequest.setClientCode("WCS");
newMovePodTaskRequest.setPriority(agvTask.getPriority());
@ -66,13 +93,14 @@ public class ITesAgvServiceImpl implements ITesAgvService {
}
@Override
public void sendTesAgvTask(String url, String json, AgvTask agvTask) {
public void sendTesAgvTask(String openApi, String json, AgvTask agvTask) {
log.info("请求报文:{}", json);
// 检查接口开关, 未开启则返回
if (sysDictMapper.queryByDictCode(GeneralConstant.OPEN_FLAG) == null) {
updateAgvTaskResponse(agvTask, "接口未开启", GeneralConstant.TES_FAIL_CODE);
return;
}
String url = openApiMapper.getRequestUrl(openApi);
Integer returnCode = null;
String returnMsg = null;
@ -87,13 +115,13 @@ public class ITesAgvServiceImpl implements ITesAgvService {
" }\n" +
"}";
if (StringUtils.isEmpty(result)) {
returnMsg = "Tes返回信息:下发任务接口调用失败";
returnMsg = "Tes返回信息:接口调用失败";
throw new RuntimeException(returnMsg);
}
JSONObject resulObject = JSON.parseObject(result);
if (resulObject == null) {
returnMsg = "Tes返回信息:下发任务接口返回为空";
returnMsg = "Tes返回信息:接口返回为空";
throw new RuntimeException(returnMsg);
}
@ -103,9 +131,9 @@ public class ITesAgvServiceImpl implements ITesAgvService {
if (!GeneralConstant.TES_SUCCESS_CODE.equals(returnCode)) {
throw new RuntimeException("Tes返回消息:" + returnMsg);
}
// 更新任务状态
updateAgvTaskResponse(agvTask, returnMsg, returnCode);
} catch (Exception e) {
// 记录异常到 AgvTask
updateAgvTaskResponse(agvTask, e.getMessage(), GeneralConstant.TES_FAIL_CODE);
@ -120,6 +148,7 @@ public class ITesAgvServiceImpl implements ITesAgvService {
if (agvTask == null) {
throw new RuntimeException("【" + tesCallbackRequest.getContent().getBizID() + "】任务不存在");
}
int status = tesCallbackRequest.getContent().getStatus();
switch (status) {
case 4:
@ -137,14 +166,92 @@ 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.setForce(0);
cancelTaskRequest.setWithoutRunning(0);
return JSON.toJSONString(cancelTaskRequest);
}
@Override
public void cancelTask(CancelTaskRequest cancelTask) {
AgvTask agvTask = agvTaskMapper.selectById(cancelTask.getTaskID());
String url = openApiMapper.getRequestUrl(GeneralConstant.TES_CANCEL_TASK);
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" +
"}";
if (StringUtils.isEmpty(result)) {
returnMsg = "Tes返回信息:接口调用失败";
throw new RuntimeException(returnMsg);
}
JSONObject resulObject = JSON.parseObject(result);
if (resulObject == null) {
returnMsg = "Tes返回信息:接口返回为空";
throw new RuntimeException(returnMsg);
}
returnCode = resulObject.getInteger("returnCode");
returnMsg = resulObject.getString("returnMsg");
if (!GeneralConstant.TES_SUCCESS_CODE.equals(returnCode)) {
throw new RuntimeException("Tes返回消息:" + returnMsg);
}
handleCelled(agvTask);
}
@Override
public void resendTesTask(AgvTask agvTask) {
handleResend(agvTask);
}
/**
*
*
* @param agvTask
*/
private void handleEnd(Long asnDetailId, AgvTask agvTask) {
//确认收货
iAsnService.receiveGoods(asnDetailId, agvTask.getEndCode());
if (BusinessTypeEnum.INBOUND.getValue().equals(agvTask.getType())) {
//收货
iAsnService.receiveGoods(asnDetailId, agvTask.getEndCode());
} else if (BusinessTypeEnum.OUTBOUND.getValue().equals(agvTask.getType())) {
//拣货
Point endPoint = iPointService.validatePoint(agvTask.getEndCode());
List<Task> tasks = taskMapper.queryByAgvTask(agvTask.getId());
iPickService.pickTask(tasks, endPoint);
Point startPoint = iPointService.validatePoint(agvTask.getStartCode());
Stock stock = iStockService.validateStock(agvTask.getCarrierCode());
iPointService.unbindPoint(startPoint);
iStockService.bindStock(stock, endPoint);
//判断AGV任务是否整托整托生成AGV搬运任务
if (agvTask.getIzAll() == 0) {
//查询电梯口点位作为目标点位
String endCode = iPointService.getElevatorPoint(agvTask.getEndCode(), GeneralConstant.CK_ELEVATOR_TASK_INDEX);
iAgvTaskService.createAgvTask(null, agvTask.getCarrierCode(), agvTask.getEndCode(), endCode, null, BusinessTypeEnum.OUTBOUND.getValue(), AgvVendorEnum.HIK.getValue());
}
}
agvTask.setStatus(AgvStatusEnum.COMPLETED.getValue());
agvTask.setEndTime(new Date());
agvTaskMapper.updateById(agvTask);
@ -171,7 +278,7 @@ public class ITesAgvServiceImpl implements ITesAgvService {
if (count > 0) {
throw new RuntimeException("任务已重新生成,请勿重复操作! ");
}
AgvTask newAgvTask = iAgvTaskService.createAgvTask(agvTask.getBusinessDetailId(),agvTask.getCarrierCode(), agvTask.getStartCode(), agvTask.getEndCode(), null, agvTask.getType(), AgvVendorEnum.TES.getValue());
AgvTask newAgvTask = iAgvTaskService.createAgvTask(agvTask.getBusinessDetailId(), agvTask.getCarrierCode(), agvTask.getStartCode(), agvTask.getEndCode(), null, agvTask.getType(), AgvVendorEnum.TES.getValue());
switch (agvTask.getType()) {
case "INBOUND":
case "OUTBOUND":

View File

@ -21,7 +21,7 @@ import java.util.List;
import java.util.function.BiConsumer;
@Service
public class BatchUtils {
public class BatchUtil {
@Autowired
private JdbcTemplate jdbcTemplate;
@ -173,12 +173,13 @@ public class BatchUtils {
*/
@Transactional
public void updateBatchPickDetail(List<PickDetail> pickDetails) {
String sql = "UPDATE data_pick_detail SET allocated_qty = ?, status = ? where id = ?";
String sql = "UPDATE data_pick_detail SET allocated_qty = ?,picked_qty = ?, status = ? where id = ?";
batchUpdate(sql, pickDetails, (ps, pickDetail) -> {
try {
ps.setBigDecimal(1, pickDetail.getAllocatedQty());
ps.setInt(2, pickDetail.getStatus());
ps.setLong(3, pickDetail.getId());
ps.setBigDecimal(2, pickDetail.getPickedQty());
ps.setInt(3, pickDetail.getStatus());
ps.setLong(4, pickDetail.getId());
} catch (SQLException e) {
throw new RuntimeException(e);
}
@ -228,11 +229,13 @@ public class BatchUtils {
*/
@Transactional
public void updateBatchTask(List<Task> tasks) {
String sql = "UPDATE data_task SET agv_task_id = ? where id = ? ";
String sql = "UPDATE data_task SET move_qty = ?,task_status = ? , agv_task_id = ? where id = ? ";
batchUpdate(sql, tasks, (ps, task) -> {
try {
ps.setObject(1, task.getAgvTaskId());
ps.setLong(2, task.getId());
ps.setBigDecimal(1, task.getMoveQty());
ps.setInt(2, task.getTaskStatus());
ps.setObject(3, task.getAgvTaskId());
ps.setLong(4, task.getId());
} catch (SQLException e) {
throw new RuntimeException(e);
}
@ -245,8 +248,8 @@ public class BatchUtils {
*/
@Transactional
public void saveBatchAgvTask(List<AgvTask> agvTasks) {
String sql = "INSERT INTO data_agv_task (id,business_detail_id,carrier_code,carrier_type,task_type,type,status,priority,start_code,end_code,agv_vendor,sys_org_code,tenant_id,create_by,create_time) " +
"VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
String sql = "INSERT INTO data_agv_task (id,business_detail_id,carrier_code,carrier_type,task_type,type,status,priority,start_code,end_code,iz_all,agv_vendor,sys_org_code,tenant_id,create_by,create_time) " +
"VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
batchInsert(sql, agvTasks, (ps, agvTask) -> {
try {
long id = IdWorker.getId();
@ -261,11 +264,12 @@ public class BatchUtils {
ps.setInt(8, agvTask.getPriority());
ps.setString(9, agvTask.getStartCode());
ps.setString(10, agvTask.getEndCode());
ps.setString(11, agvTask.getAgvVendor());
ps.setString(12, agvTask.getSysOrgCode());
ps.setLong(13, agvTask.getTenantId());
ps.setString(14, agvTask.getCreateBy());
ps.setTimestamp(15, new Timestamp(agvTask.getCreateTime().getTime()));
ps.setInt(11, agvTask.getIzAll());
ps.setString(12, agvTask.getAgvVendor());
ps.setString(13, agvTask.getSysOrgCode());
ps.setLong(14, agvTask.getTenantId());
ps.setString(15, agvTask.getCreateBy());
ps.setTimestamp(16, new Timestamp(agvTask.getCreateTime().getTime()));
} catch (SQLException e) {
throw new RuntimeException(e);
}
@ -277,12 +281,14 @@ public class BatchUtils {
*/
@Transactional
public void updateBatchInventory(List<Inventory> inventories) {
String sql = "UPDATE data_inventory SET queued_qty = ?, status = ? where id = ?";
String sql = "UPDATE data_inventory SET quantity = ?, queued_qty = ?, status = ? , point_id = ? where id = ?";
batchUpdate(sql, inventories, (ps, inventory) -> {
try {
ps.setBigDecimal(1, inventory.getQueuedQty());
ps.setInt(2, inventory.getStatus());
ps.setLong(3, inventory.getId());
ps.setBigDecimal(1, inventory.getQuantity());
ps.setBigDecimal(2, inventory.getQueuedQty());
ps.setInt(3, inventory.getStatus());
ps.setLong(4, inventory.getPointId());
ps.setLong(5, inventory.getId());
} catch (SQLException e) {
throw new RuntimeException(e);
}

View File

@ -0,0 +1,35 @@
package org.cpte.modules.utils;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
*
*/
@Component
public class ElevatorMapUtil {
/**
*
*/
public static final Map<String, List<String>> dataMap;
static {
dataMap = new ConcurrentHashMap<>();
List<String> CKJBK01 = Arrays.asList("DT001", "DT002");
List<String> CKJBK02 = Arrays.asList("DT003", "DT004");
// 初始化Map
dataMap.put("CKJBK01", CKJBK01);
dataMap.put("CKJBK02", CKJBK02);
}
/**
* keyvalue
*/
public static List<String> getValueByKey(String key) {
return dataMap.get(key);
}
}

View File

@ -94,6 +94,7 @@ public class OpenApiController extends JeecgController<OpenApi, OpenApiService>
@PutMapping(value = "/edit")
public Result<?> edit(@RequestBody OpenApi openApi) {
service.updateById(openApi);
redisUtil.del(openApi.getRequestUrl());
return Result.ok("修改成功!");
}
@ -106,6 +107,8 @@ public class OpenApiController extends JeecgController<OpenApi, OpenApiService>
*/
@DeleteMapping(value = "/delete")
public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
OpenApi openApi = service.getById(id);
redisUtil.del(openApi.getRequestUrl());
service.removeById(id);
return Result.ok("删除成功!");
}
@ -118,7 +121,11 @@ public class OpenApiController extends JeecgController<OpenApi, OpenApiService>
*/
@DeleteMapping(value = "/deleteBatch")
public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
List<String> list= Arrays.asList(ids.split(","));
list.forEach(id->{
OpenApi openApi = service.getById(id);
redisUtil.del(openApi.getRequestUrl());
});
this.service.removeByIds(Arrays.asList(ids.split(",")));
return Result.ok("批量删除成功!");
}

View File

@ -4,7 +4,9 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.jeecg.common.constant.CacheConstant;
import org.jeecg.modules.openapi.entity.OpenApi;
import org.springframework.cache.annotation.Cacheable;
@Mapper
public interface OpenApiMapper extends BaseMapper<OpenApi> {
@ -15,5 +17,6 @@ public interface OpenApiMapper extends BaseMapper<OpenApi> {
* @return String
*/
@Select("select origin_url from open_api where request_url = #{requestUrl}")
@Cacheable(value =CacheConstant.SYS_DICT_CACHE ,key = "#requestUrl", unless = "#result == null ")
String getRequestUrl(@Param("requestUrl") String requestUrl);
}