no message
parent
50a9c19e15
commit
d78b5e48ed
|
|
@ -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;
|
||||
|
||||
/**
|
||||
* 返回报文
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,4 +24,16 @@ public enum BusinessTypeEnum {
|
|||
this.desc = desc;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据value获取desc
|
||||
*/
|
||||
public static String getDescByValue(String value) {
|
||||
for (BusinessTypeEnum item : BusinessTypeEnum.values()) {
|
||||
if (item.value.equals(value)) {
|
||||
return item.desc;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ public enum PickStatusEnum {
|
|||
|
||||
ASSIGNED(3, "已分配"),
|
||||
|
||||
PICKING(4, "拣货中"),
|
||||
PICKING(4, "部分拣货"),
|
||||
|
||||
PICKED(5, "拣货完成"),
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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=")">
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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是最高
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
/**
|
||||
* 消息产生时间
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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":
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过key获取value
|
||||
*/
|
||||
public static List<String> getValueByKey(String key) {
|
||||
return dataMap.get(key);
|
||||
}
|
||||
}
|
||||
|
|
@ -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("批量删除成功!");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue