no message
parent
f521e2cb73
commit
d73d0d454f
|
|
@ -93,6 +93,22 @@ public class Point implements Serializable {
|
||||||
@Schema(description = "位置坐标y")
|
@Schema(description = "位置坐标y")
|
||||||
private java.lang.Integer positionY;
|
private java.lang.Integer positionY;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 位置坐标x
|
||||||
|
*/
|
||||||
|
@Excel(name = "第二层坐标X", width = 15)
|
||||||
|
@Schema(description = "位置坐标x")
|
||||||
|
private java.lang.Integer positionTwoX;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 位置坐标y
|
||||||
|
*/
|
||||||
|
@Excel(name = "第二层坐标Y", width = 15)
|
||||||
|
@Schema(description = "第二层坐标Y")
|
||||||
|
private java.lang.Integer positionTwoY;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否双通道
|
* 是否双通道
|
||||||
* 0-单通道 1-双通道
|
* 0-单通道 1-双通道
|
||||||
|
|
|
||||||
|
|
@ -48,4 +48,5 @@ public interface PointMapper extends BaseMapper<Point> {
|
||||||
|
|
||||||
@Select("SELECT * FROM base_point WHERE col_num = #{colNum} AND layer_num = #{layerNum} ORDER BY row_num ASC")
|
@Select("SELECT * FROM base_point WHERE col_num = #{colNum} AND layer_num = #{layerNum} ORDER BY row_num ASC")
|
||||||
List<Point> findByColAndLayer(@Param("colNum") String colNum, @Param("layerNum") String layerNum);
|
List<Point> findByColAndLayer(@Param("colNum") String colNum, @Param("layerNum") String layerNum);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ import org.cpte.modules.base.entity.Point;
|
||||||
import org.cpte.modules.base.entity.Stock;
|
import org.cpte.modules.base.entity.Stock;
|
||||||
import org.cpte.modules.base.mapper.PointMapper;
|
import org.cpte.modules.base.mapper.PointMapper;
|
||||||
import org.cpte.modules.base.mapper.StockMapper;
|
import org.cpte.modules.base.mapper.StockMapper;
|
||||||
|
import org.cpte.modules.constant.enums.CommonStatusEnum;
|
||||||
|
import org.cpte.modules.constant.enums.TaskTypeEnum;
|
||||||
import org.cpte.modules.inventory.entity.Inventory;
|
import org.cpte.modules.inventory.entity.Inventory;
|
||||||
import org.cpte.modules.inventory.mapper.InventoryMapper;
|
import org.cpte.modules.inventory.mapper.InventoryMapper;
|
||||||
import org.cpte.modules.inventoryLog.entity.InventoryLog;
|
import org.cpte.modules.inventoryLog.entity.InventoryLog;
|
||||||
|
|
@ -142,6 +144,7 @@ public class BatchProcessor {
|
||||||
if (CollectionUtils.isNotEmpty(updateToPickDetail)) {
|
if (CollectionUtils.isNotEmpty(updateToPickDetail)) {
|
||||||
batchUtil.updateBatchPickDetail(updateToPickDetail);
|
batchUtil.updateBatchPickDetail(updateToPickDetail);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CollectionUtils.isNotEmpty(deleteToTask)) {
|
if (CollectionUtils.isNotEmpty(deleteToTask)) {
|
||||||
taskMapper.deleteByIds(deleteToTask);
|
taskMapper.deleteByIds(deleteToTask);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,10 @@ public enum CommonStatusEnum {
|
||||||
|
|
||||||
USED(1, "占用"),
|
USED(1, "占用"),
|
||||||
|
|
||||||
|
ONE(1, "一层"),
|
||||||
|
|
||||||
|
TWO(2, "二层"),
|
||||||
|
|
||||||
;
|
;
|
||||||
/**
|
/**
|
||||||
* 值
|
* 值
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import org.cpte.modules.constant.enums.*;
|
||||||
import org.cpte.modules.conveyorLine.request.ScanTrayRequest;
|
import org.cpte.modules.conveyorLine.request.ScanTrayRequest;
|
||||||
import org.cpte.modules.conveyorLine.vo.PointScore;
|
import org.cpte.modules.conveyorLine.vo.PointScore;
|
||||||
import org.cpte.modules.conveyorLine.vo.ScanTrayData;
|
import org.cpte.modules.conveyorLine.vo.ScanTrayData;
|
||||||
|
import org.cpte.modules.conveyorLine.vo.Station;
|
||||||
import org.cpte.modules.inventory.entity.Inventory;
|
import org.cpte.modules.inventory.entity.Inventory;
|
||||||
import org.cpte.modules.inventory.mapper.InventoryMapper;
|
import org.cpte.modules.inventory.mapper.InventoryMapper;
|
||||||
import org.cpte.modules.receive.entity.Asn;
|
import org.cpte.modules.receive.entity.Asn;
|
||||||
|
|
@ -28,6 +29,7 @@ import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 扫描托盘处理
|
* 扫描托盘处理
|
||||||
|
|
@ -78,7 +80,7 @@ public class ScanTrayProcessor {
|
||||||
|
|
||||||
// 4.智能分配库位
|
// 4.智能分配库位
|
||||||
String areaCode = getAreaCode(data.getAsn().getOrderType());
|
String areaCode = getAreaCode(data.getAsn().getOrderType());
|
||||||
Point dstPoint = allocatePoint(data.getItemKeys(), data.getStation(), areaCode);
|
Point dstPoint = allocatePoint(data.getItemKeys(), data.getStation(), areaCode, BusinessTypeEnum.INBOUND.getValue());
|
||||||
|
|
||||||
// 5.生成TES任务
|
// 5.生成TES任务
|
||||||
agvTaskService.processAgvTask(data, dstPoint);
|
agvTaskService.processAgvTask(data, dstPoint);
|
||||||
|
|
@ -192,21 +194,63 @@ public class ScanTrayProcessor {
|
||||||
*
|
*
|
||||||
* @param itemKeys 物料属性
|
* @param itemKeys 物料属性
|
||||||
* @param station 工作站
|
* @param station 工作站
|
||||||
|
* @param areaCode 库区
|
||||||
|
* @param type 业务类型
|
||||||
* @return 目标库位
|
* @return 目标库位
|
||||||
*/
|
*/
|
||||||
public Point allocatePoint(List<ItemKey> itemKeys, Point station, String areaCode) {
|
public Point allocatePoint(List<ItemKey> itemKeys, Point station, String areaCode, String type) {
|
||||||
//1.优先寻找同物料/同仓库/同项目号/同任务号/同批次/同外部库存状态
|
//1.优先寻找同物料/同仓库/同项目号/同任务号/同批次/同外部库存状态的库位
|
||||||
List<Long> itemKeyIds = itemKeys.stream().map(ItemKey::getId).toList();
|
List<Long> itemKeyIds = itemKeys.stream().map(ItemKey::getId).toList();
|
||||||
List<Point> availablePoints = pointService.findClusterPoint(itemKeyIds, areaCode);
|
List<Point> availablePoints = pointService.findClusterPoint(itemKeyIds, areaCode);
|
||||||
if (CollectionUtils.isEmpty(availablePoints)) {
|
if (CollectionUtils.isEmpty(availablePoints)) {
|
||||||
//2.获取所有可用库位
|
//2.获取所有可用库位
|
||||||
availablePoints = pointMapper.queryPoints(null, CommonStatusEnum.FREE.getValue(), areaCode);
|
availablePoints = pointMapper.queryPoints(null, CommonStatusEnum.FREE.getValue(), areaCode);
|
||||||
}
|
}
|
||||||
//根据巷到分组,得到每个巷道有多个库位,<巷道编号,库位个数>
|
//根据巷道分组,得到每个巷道有多个库位,<巷道编号,库位个数>
|
||||||
Map<String, Long> colMap = getColMap(areaCode);
|
Map<String, Long> colMap = getColMap(areaCode);
|
||||||
|
|
||||||
List<PointScore> scoredPoints = availablePoints.stream()
|
//根据layerNum层来分组
|
||||||
.map(point -> clusterPointScore(point, station, itemKeys, colMap))
|
Map<String, List<Point>> layerMap = availablePoints.stream().collect(Collectors.groupingBy(Point::getLayerNum));
|
||||||
|
|
||||||
|
List<PointScore> firstScoredPoints = new ArrayList<>();
|
||||||
|
List<PointScore> secondScoredPoints = new ArrayList<>();
|
||||||
|
|
||||||
|
//移位选择最优库位
|
||||||
|
if (type.equals(BusinessTypeEnum.MOVE.getValue())) {
|
||||||
|
String layerNum = station.getLayerNum();
|
||||||
|
Station currentStation = new Station(station.getPositionX(), station.getPositionY());
|
||||||
|
List<Point> firstLevelPoints = layerMap.get(layerNum);
|
||||||
|
if (CollectionUtils.isNotEmpty(firstLevelPoints)) {
|
||||||
|
firstScoredPoints = firstLevelPoints.stream()
|
||||||
|
.map(point -> clusterPointScore(point, currentStation, itemKeys, colMap))
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//入库选择最优库位
|
||||||
|
//计算第一层的库位分数
|
||||||
|
Station firstStation = new Station(station.getPositionX(), station.getPositionY());
|
||||||
|
List<Point> firstLevelPoints = layerMap.get(String.valueOf(CommonStatusEnum.ONE.getValue()));
|
||||||
|
if (CollectionUtils.isNotEmpty(firstLevelPoints)) {
|
||||||
|
firstScoredPoints = firstLevelPoints.stream()
|
||||||
|
.map(point -> clusterPointScore(point, firstStation, itemKeys, colMap))
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
//计算第二层的库位分数
|
||||||
|
Station secondStation = new Station(station.getPositionTwoX(), station.getPositionTwoY());
|
||||||
|
List<Point> secondLevelPoints = layerMap.get(String.valueOf(CommonStatusEnum.TWO.getValue()));
|
||||||
|
if (CollectionUtils.isNotEmpty(secondLevelPoints)) {
|
||||||
|
secondScoredPoints = secondLevelPoints.stream()
|
||||||
|
.map(point -> clusterPointScore(point, secondStation, itemKeys, colMap))
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//合并获取最优库位
|
||||||
|
List<PointScore> scoredPoints = Stream.concat(
|
||||||
|
firstScoredPoints.stream(),
|
||||||
|
secondScoredPoints.stream()
|
||||||
|
)
|
||||||
.sorted(Comparator.comparing(PointScore::getScore).reversed())
|
.sorted(Comparator.comparing(PointScore::getScore).reversed())
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
|
|
@ -221,7 +265,7 @@ public class ScanTrayProcessor {
|
||||||
/**
|
/**
|
||||||
* 库位评分计算
|
* 库位评分计算
|
||||||
*/
|
*/
|
||||||
private PointScore clusterPointScore(Point point, Point station, List<ItemKey> itemKeys, Map<String, Long> colMap) {
|
private PointScore clusterPointScore(Point point, Station station, List<ItemKey> itemKeys, Map<String, Long> colMap) {
|
||||||
double totalScore;
|
double totalScore;
|
||||||
|
|
||||||
// 1. 距离评分 - 考虑从入库口到库位的距离
|
// 1. 距离评分 - 考虑从入库口到库位的距离
|
||||||
|
|
@ -241,6 +285,7 @@ public class ScanTrayProcessor {
|
||||||
|
|
||||||
totalScore = distanceScore + channelDepthScore + channelScore;
|
totalScore = distanceScore + channelDepthScore + channelScore;
|
||||||
log.info("【{}】库位总分:{} - 距离评分: {} - 通道深度策略评分: {} - 通道类型评分: {} - 均衡评分: {} - 物料聚集评分: {}", point.getPointCode(), totalScore, distanceScore, channelDepthScore, channelScore, 0, 0);
|
log.info("【{}】库位总分:{} - 距离评分: {} - 通道深度策略评分: {} - 通道类型评分: {} - 均衡评分: {} - 物料聚集评分: {}", point.getPointCode(), totalScore, distanceScore, channelDepthScore, channelScore, 0, 0);
|
||||||
|
|
||||||
return new PointScore(point, totalScore);
|
return new PointScore(point, totalScore);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -406,11 +451,13 @@ public class ScanTrayProcessor {
|
||||||
* 计算距离评分
|
* 计算距离评分
|
||||||
* 基于入库口位置和库位坐标计算最短路径距离
|
* 基于入库口位置和库位坐标计算最短路径距离
|
||||||
*/
|
*/
|
||||||
private double calculateClusterDistanceCost(Point point, Point station) {
|
|
||||||
|
private double calculateClusterDistanceCost(Point point, Station station) {
|
||||||
// 计算曼哈顿距离
|
// 计算曼哈顿距离
|
||||||
double distance = Math.abs(point.getPositionX() - station.getPositionX()) + Math.abs(point.getPositionY() - station.getPositionY());
|
double distance = Math.abs(point.getPositionX() - station.getPositionX()) + Math.abs(point.getPositionY() - station.getPositionY());
|
||||||
|
|
||||||
// 使用更大的标准化参数(根据实际坐标范围)
|
// 使用更大的标准化参数(根据实际坐标范围)
|
||||||
double normalizationFactor = 250000.0; // 或使用动态计算的最大距离值
|
double normalizationFactor = 300000.0;
|
||||||
// 距离越小分数越高
|
// 距离越小分数越高
|
||||||
return Math.max(0, 100 - (distance / normalizationFactor) * 100);
|
return Math.max(0, 100 - (distance / normalizationFactor) * 100);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package org.cpte.modules.conveyorLine.vo;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.cpte.modules.base.entity.Point;
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class Station {
|
||||||
|
// X坐标
|
||||||
|
private Integer positionX;
|
||||||
|
// Y坐标
|
||||||
|
private Integer positionY;
|
||||||
|
}
|
||||||
|
|
@ -12,7 +12,12 @@ import java.net.URLDecoder;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import org.cpte.modules.base.entity.ItemKey;
|
import org.cpte.modules.base.entity.ItemKey;
|
||||||
|
import org.cpte.modules.base.entity.Point;
|
||||||
|
import org.cpte.modules.base.entity.Stock;
|
||||||
|
import org.cpte.modules.base.mapper.PointMapper;
|
||||||
|
import org.cpte.modules.base.mapper.StockMapper;
|
||||||
import org.cpte.modules.base.service.IItemKeyService;
|
import org.cpte.modules.base.service.IItemKeyService;
|
||||||
|
import org.cpte.modules.constant.enums.CommonStatusEnum;
|
||||||
import org.jeecg.common.api.vo.Result;
|
import org.jeecg.common.api.vo.Result;
|
||||||
import org.jeecg.common.system.query.QueryGenerator;
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
import org.jeecg.common.system.query.QueryRuleEnum;
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
|
|
@ -53,12 +58,19 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
@RequestMapping("/inventory")
|
@RequestMapping("/inventory")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class InventoryController extends JeecgController<Inventory, IInventoryService> {
|
public class InventoryController extends JeecgController<Inventory, IInventoryService> {
|
||||||
|
@Autowired
|
||||||
|
private StockMapper stockMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PointMapper pointMapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private IInventoryService inventoryService;
|
private IInventoryService inventoryService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private IItemKeyService itemKeyService;
|
private IItemKeyService itemKeyService;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分页列表查询
|
* 分页列表查询
|
||||||
*
|
*
|
||||||
|
|
@ -125,6 +137,15 @@ public class InventoryController extends JeecgController<Inventory, IInventorySe
|
||||||
@RequiresPermissions("inventory:data_inventory:edit")
|
@RequiresPermissions("inventory:data_inventory:edit")
|
||||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
|
||||||
public Result<String> edit(@RequestBody Inventory inventory) {
|
public Result<String> edit(@RequestBody Inventory inventory) {
|
||||||
|
Inventory oldInventory = inventoryService.getById(inventory.getId());
|
||||||
|
Point oldPoint = pointMapper.selectById(oldInventory.getPointId());
|
||||||
|
Point newPoint = pointMapper.selectById(inventory.getPointId());
|
||||||
|
if(!oldPoint.getId().equals(newPoint.getId())){
|
||||||
|
oldPoint.setStatus(CommonStatusEnum.FREE.getValue());
|
||||||
|
pointMapper.updateById(oldPoint);
|
||||||
|
newPoint.setStatus(CommonStatusEnum.USED.getValue());
|
||||||
|
pointMapper.updateById(newPoint);
|
||||||
|
}
|
||||||
ItemKey itemKey = itemKeyService.createItemKey(inventory.getItemId(), inventory.getWhCode(), inventory.getProject(), inventory.getTaskNo(), inventory.getPropC1(), inventory.getPropC3());
|
ItemKey itemKey = itemKeyService.createItemKey(inventory.getItemId(), inventory.getWhCode(), inventory.getProject(), inventory.getTaskNo(), inventory.getPropC1(), inventory.getPropC3());
|
||||||
inventory.setItemKeyId(itemKey.getId());
|
inventory.setItemKeyId(itemKey.getId());
|
||||||
inventoryService.updateById(inventory);
|
inventoryService.updateById(inventory);
|
||||||
|
|
@ -142,6 +163,17 @@ public class InventoryController extends JeecgController<Inventory, IInventorySe
|
||||||
@RequiresPermissions("inventory:data_inventory:delete")
|
@RequiresPermissions("inventory:data_inventory:delete")
|
||||||
@DeleteMapping(value = "/delete")
|
@DeleteMapping(value = "/delete")
|
||||||
public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
|
public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
|
||||||
|
Inventory inventory = inventoryService.getById(id);
|
||||||
|
Stock stock = stockMapper.selectById(inventory.getStockId());
|
||||||
|
if (stock != null) {
|
||||||
|
stock.setStatus(CommonStatusEnum.FREE.getValue());
|
||||||
|
stockMapper.updateById(stock);
|
||||||
|
}
|
||||||
|
Point point = pointMapper.selectById(inventory.getPointId());
|
||||||
|
if (point != null) {
|
||||||
|
point.setStatus(CommonStatusEnum.FREE.getValue());
|
||||||
|
pointMapper.updateById(point);
|
||||||
|
}
|
||||||
inventoryService.removeById(id);
|
inventoryService.removeById(id);
|
||||||
return Result.OK("删除成功!");
|
return Result.OK("删除成功!");
|
||||||
}
|
}
|
||||||
|
|
@ -157,7 +189,21 @@ public class InventoryController extends JeecgController<Inventory, IInventorySe
|
||||||
@RequiresPermissions("inventory:data_inventory:deleteBatch")
|
@RequiresPermissions("inventory:data_inventory:deleteBatch")
|
||||||
@DeleteMapping(value = "/deleteBatch")
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
|
public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
|
||||||
this.inventoryService.removeByIds(Arrays.asList(ids.split(",")));
|
List<Long> invIds = Arrays.stream(ids.split(",")).map(Long::parseLong).toList();
|
||||||
|
List<Inventory> inventories = inventoryService.listByIds(invIds);
|
||||||
|
for (Inventory inventory : inventories) {
|
||||||
|
Stock stock = stockMapper.selectById(inventory.getStockId());
|
||||||
|
if (stock != null) {
|
||||||
|
stock.setStatus(CommonStatusEnum.FREE.getValue());
|
||||||
|
stockMapper.updateById(stock);
|
||||||
|
}
|
||||||
|
Point point = pointMapper.selectById(inventory.getPointId());
|
||||||
|
if (point != null) {
|
||||||
|
point.setStatus(CommonStatusEnum.FREE.getValue());
|
||||||
|
pointMapper.updateById(point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.inventoryService.removeByIds(invIds);
|
||||||
return Result.OK("批量删除成功!");
|
return Result.OK("批量删除成功!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import org.cpte.modules.receive.entity.Asn;
|
import org.cpte.modules.receive.entity.Asn;
|
||||||
import org.cpte.modules.receive.entity.AsnDetail;
|
import org.cpte.modules.receive.entity.AsnDetail;
|
||||||
import org.cpte.modules.receive.entity.ReceiveRecord;
|
import org.cpte.modules.receive.entity.ReceiveRecord;
|
||||||
|
import org.cpte.modules.shipping.entity.Task;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -53,4 +54,10 @@ public interface IInventoryService extends IService<Inventory> {
|
||||||
* @param stockIds 容器ID
|
* @param stockIds 容器ID
|
||||||
*/
|
*/
|
||||||
void deleteByStockIds(List<Long> stockIds);
|
void deleteByStockIds(List<Long> stockIds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移动库存
|
||||||
|
* @param tasks 移位任务
|
||||||
|
*/
|
||||||
|
void moveInventory(List<Task> tasks);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,17 @@ package org.cpte.modules.inventory.service.impl;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
|
import org.cpte.modules.base.entity.Point;
|
||||||
|
import org.cpte.modules.base.mapper.PointMapper;
|
||||||
|
import org.cpte.modules.constant.enums.CommonStatusEnum;
|
||||||
import org.cpte.modules.constant.enums.InventoryStatusEnum;
|
import org.cpte.modules.constant.enums.InventoryStatusEnum;
|
||||||
import org.cpte.modules.inventory.entity.Inventory;
|
import org.cpte.modules.inventory.entity.Inventory;
|
||||||
import org.cpte.modules.inventory.mapper.InventoryMapper;
|
import org.cpte.modules.inventory.mapper.InventoryMapper;
|
||||||
import org.cpte.modules.inventory.service.IInventoryService;
|
import org.cpte.modules.inventory.service.IInventoryService;
|
||||||
import org.cpte.modules.receive.entity.Asn;
|
import org.cpte.modules.receive.entity.Asn;
|
||||||
import org.cpte.modules.receive.entity.ReceiveRecord;
|
import org.cpte.modules.receive.entity.ReceiveRecord;
|
||||||
|
import org.cpte.modules.shipping.entity.Task;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
@ -23,6 +28,9 @@ import java.util.*;
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class InventoryServiceImpl extends ServiceImpl<InventoryMapper, Inventory> implements IInventoryService {
|
public class InventoryServiceImpl extends ServiceImpl<InventoryMapper, Inventory> implements IInventoryService {
|
||||||
|
@Autowired
|
||||||
|
private PointMapper pointMapper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Inventory buildInventory(Long stockId, BigDecimal receivedQty, Asn asn, ReceiveRecord receiveRecord) {
|
public Inventory buildInventory(Long stockId, BigDecimal receivedQty, Asn asn, ReceiveRecord receiveRecord) {
|
||||||
return Inventory.builder()
|
return Inventory.builder()
|
||||||
|
|
@ -82,5 +90,30 @@ public class InventoryServiceImpl extends ServiceImpl<InventoryMapper, Inventory
|
||||||
this.baseMapper.deleteByStockIds(stockIds);
|
this.baseMapper.deleteByStockIds(stockIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void moveInventory(List<Task> tasks) {
|
||||||
|
List<Inventory> updateToInventoryList = new ArrayList<>();
|
||||||
|
List<Point> updateToPointList = new ArrayList<>();
|
||||||
|
for (Task task : tasks) {
|
||||||
|
Inventory inventory = this.baseMapper.selectById(task.getInventoryId());
|
||||||
|
inventory.setPointId(task.getToPointId());
|
||||||
|
inventory.setStatus(InventoryStatusEnum.AVAILABLE.getValue());
|
||||||
|
updateToInventoryList.add(inventory);
|
||||||
|
}
|
||||||
|
List<Long> srcPointIds = tasks.stream().map(Task::getFromPointId).distinct().toList();
|
||||||
|
List<Point> srcPoints = pointMapper.selectByIds(srcPointIds);
|
||||||
|
for (Point point : srcPoints) {
|
||||||
|
point.setStatus(CommonStatusEnum.FREE.getValue());
|
||||||
|
updateToPointList.add(point);
|
||||||
|
}
|
||||||
|
if (CollectionUtils.isNotEmpty(updateToInventoryList)) {
|
||||||
|
this.baseMapper.updateById(updateToInventoryList);
|
||||||
|
}
|
||||||
|
if (CollectionUtils.isNotEmpty(updateToPointList)) {
|
||||||
|
pointMapper.updateById(updateToPointList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,6 @@ public interface AsnDetailMapper extends BaseMapper<AsnDetail> {
|
||||||
* @param status 状态
|
* @param status 状态
|
||||||
* @return AsnDetail
|
* @return AsnDetail
|
||||||
*/
|
*/
|
||||||
@Select("select * from data_asn_detail where stock_id = #{stockId} and status = #{status} ")
|
|
||||||
List<AsnDetail> queryByStockCode(@Param("stockId") Long stockId, @Param("status") Integer status);
|
List<AsnDetail> queryByStockCode(@Param("stockId") Long stockId, @Param("status") Integer status);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,4 +15,14 @@
|
||||||
WHERE
|
WHERE
|
||||||
asn_id = #{mainId}
|
asn_id = #{mainId}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="queryByStockCode" resultType="org.cpte.modules.receive.entity.AsnDetail">
|
||||||
|
SELECT *
|
||||||
|
FROM data_asn_detail
|
||||||
|
WHERE
|
||||||
|
stock_id = #{stockId}
|
||||||
|
<if test="status != null">
|
||||||
|
AND status = #{status}
|
||||||
|
</if>
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,11 @@ import org.cpte.modules.base.service.IItemService;
|
||||||
import org.cpte.modules.base.service.IPointService;
|
import org.cpte.modules.base.service.IPointService;
|
||||||
import org.cpte.modules.base.service.IStockService;
|
import org.cpte.modules.base.service.IStockService;
|
||||||
import org.cpte.modules.constant.GeneralConstant;
|
import org.cpte.modules.constant.GeneralConstant;
|
||||||
import org.cpte.modules.constant.enums.AgvVendorEnum;
|
import org.cpte.modules.constant.enums.*;
|
||||||
import org.cpte.modules.constant.enums.AreaTypeEnum;
|
|
||||||
import org.cpte.modules.constant.enums.AsnOrderTypeEnum;
|
|
||||||
import org.cpte.modules.constant.enums.BusinessTypeEnum;
|
|
||||||
import org.cpte.modules.inventory.mapper.InventoryMapper;
|
import org.cpte.modules.inventory.mapper.InventoryMapper;
|
||||||
import org.cpte.modules.receive.entity.Asn;
|
import org.cpte.modules.receive.entity.Asn;
|
||||||
import org.cpte.modules.receive.entity.AsnDetail;
|
import org.cpte.modules.receive.entity.AsnDetail;
|
||||||
|
import org.cpte.modules.receive.mapper.AsnDetailMapper;
|
||||||
import org.cpte.modules.receive.mapper.AsnMapper;
|
import org.cpte.modules.receive.mapper.AsnMapper;
|
||||||
import org.cpte.modules.receive.service.IAsnDetailService;
|
import org.cpte.modules.receive.service.IAsnDetailService;
|
||||||
import org.cpte.modules.receive.service.IAsnService;
|
import org.cpte.modules.receive.service.IAsnService;
|
||||||
|
|
@ -42,6 +40,9 @@ public class InBoundTaskProcessor {
|
||||||
@Autowired
|
@Autowired
|
||||||
private AsnMapper asnMapper;
|
private AsnMapper asnMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AsnDetailMapper asnDetailMapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private InventoryMapper inventoryMapper;
|
private InventoryMapper inventoryMapper;
|
||||||
|
|
||||||
|
|
@ -148,11 +149,24 @@ public class InBoundTaskProcessor {
|
||||||
String lpn = lpns.iterator().next();
|
String lpn = lpns.iterator().next();
|
||||||
Stock stock = stockService.validateStock(lpn);
|
Stock stock = stockService.validateStock(lpn);
|
||||||
if (inventoryMapper.exitsStockInventory(stock.getId()) != null) {
|
if (inventoryMapper.exitsStockInventory(stock.getId()) != null) {
|
||||||
throw new RuntimeException("【" + lpn + "】托盘已入库");
|
throw new RuntimeException("【" + lpn + "】托盘已入库,请勿下发");
|
||||||
|
}
|
||||||
|
|
||||||
|
//验证托盘未完成,不能继续下发当前托盘的任务
|
||||||
|
List<AsnDetail> asnDetail = asnDetailMapper.queryByStockCode(stock.getId(), null);
|
||||||
|
boolean hasUnfinishedTask = asnDetail.stream().anyMatch(ad -> !isAsnCompleted(ad));
|
||||||
|
if (hasUnfinishedTask) {
|
||||||
|
throw new RuntimeException("【" + lpn + "】托盘任务未完成,请勿下发");
|
||||||
}
|
}
|
||||||
return stock;
|
return stock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 辅助方法 - 判断 ASN 是否已完成
|
||||||
|
private boolean isAsnCompleted(AsnDetail asnDetail) {
|
||||||
|
return AsnStatusEnum.CLOSED.getValue().equals(asnDetail.getStatus())
|
||||||
|
|| AsnStatusEnum.CANCELED.getValue().equals(asnDetail.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证任务号
|
* 验证任务号
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -31,4 +31,6 @@ public interface TaskMapper extends BaseMapper<Task> {
|
||||||
|
|
||||||
@Select("SELECT * FROM data_task WHERE pick_id = #{pickId} ")
|
@Select("SELECT * FROM data_task WHERE pick_id = #{pickId} ")
|
||||||
List<Task> queryTaskByMainId(@Param("pickId")Long pickId);
|
List<Task> queryTaskByMainId(@Param("pickId")Long pickId);
|
||||||
|
|
||||||
|
List<Task> queryByInventoryIds(@Param("inventoryIds") List<Long> inventoryIds);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,4 +8,12 @@
|
||||||
#{pickId}
|
#{pickId}
|
||||||
</foreach>
|
</foreach>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="queryByInventoryIds" resultType="org.cpte.modules.shipping.entity.Task">
|
||||||
|
SELECT * FROM data_task
|
||||||
|
WHERE inventory_id IN
|
||||||
|
<foreach collection="inventoryIds" item="inventoryId" open="(" separator="," close=")">
|
||||||
|
#{inventoryId}
|
||||||
|
</foreach>
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|
@ -64,4 +64,6 @@ public interface ITaskService extends IService<Task> {
|
||||||
* @return List<Task>
|
* @return List<Task>
|
||||||
*/
|
*/
|
||||||
List<Task> queryTaskByMainId(Long id);
|
List<Task> queryTaskByMainId(Long id);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||||
import org.cpte.modules.base.entity.*;
|
import org.cpte.modules.base.entity.*;
|
||||||
import org.cpte.modules.base.mapper.AreaMapper;
|
import org.cpte.modules.base.mapper.AreaMapper;
|
||||||
import org.cpte.modules.base.mapper.ItemKeyMapper;
|
import org.cpte.modules.base.mapper.ItemKeyMapper;
|
||||||
|
import org.cpte.modules.base.mapper.PointMapper;
|
||||||
import org.cpte.modules.base.service.IItemKeyService;
|
import org.cpte.modules.base.service.IItemKeyService;
|
||||||
import org.cpte.modules.base.service.IItemService;
|
import org.cpte.modules.base.service.IItemService;
|
||||||
import org.cpte.modules.base.service.IPointService;
|
import org.cpte.modules.base.service.IPointService;
|
||||||
|
|
@ -22,6 +23,7 @@ import org.cpte.modules.shipping.entity.Pick;
|
||||||
import org.cpte.modules.shipping.entity.PickDetail;
|
import org.cpte.modules.shipping.entity.PickDetail;
|
||||||
import org.cpte.modules.shipping.entity.Task;
|
import org.cpte.modules.shipping.entity.Task;
|
||||||
import org.cpte.modules.shipping.mapper.PickDetailMapper;
|
import org.cpte.modules.shipping.mapper.PickDetailMapper;
|
||||||
|
import org.cpte.modules.shipping.mapper.TaskMapper;
|
||||||
import org.cpte.modules.shipping.service.IPickDetailService;
|
import org.cpte.modules.shipping.service.IPickDetailService;
|
||||||
import org.cpte.modules.shipping.service.ITaskService;
|
import org.cpte.modules.shipping.service.ITaskService;
|
||||||
import org.cpte.modules.shipping.vo.AllocationData;
|
import org.cpte.modules.shipping.vo.AllocationData;
|
||||||
|
|
@ -46,12 +48,17 @@ public class AllocateProcessor {
|
||||||
@Autowired
|
@Autowired
|
||||||
private AreaMapper areaMapper;
|
private AreaMapper areaMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PointMapper pointMapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private PickDetailMapper pickDetailMapper;
|
private PickDetailMapper pickDetailMapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ItemKeyMapper itemKeyMapper;
|
private ItemKeyMapper itemKeyMapper;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private InventoryMapper inventoryMapper;
|
private InventoryMapper inventoryMapper;
|
||||||
|
|
||||||
|
|
@ -391,18 +398,6 @@ public class AllocateProcessor {
|
||||||
.toList();
|
.toList();
|
||||||
Map<Long, Point> pointMap = pointService.queryByPointIdsToMap(pointIds);
|
Map<Long, Point> pointMap = pointService.queryByPointIdsToMap(pointIds);
|
||||||
|
|
||||||
// 按巷道和层分组
|
|
||||||
Map<String, List<Point>> colLayerPointsMap = new HashMap<>();
|
|
||||||
|
|
||||||
for (Point point : pointMap.values()) {
|
|
||||||
String key = point.getColNum() + "-" + point.getLayerNum();
|
|
||||||
if (colLayerPointsMap.containsKey(key)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
List<Point> points = pointService.findByColAndLayer(point.getColNum(), point.getLayerNum());
|
|
||||||
colLayerPointsMap.put(key, points);
|
|
||||||
}
|
|
||||||
|
|
||||||
//获取出库口的库位
|
//获取出库口的库位
|
||||||
List<Point> outPoints = pointService.queryPoints(null, null, AreaTypeEnum.CK_DOCK.getValue());
|
List<Point> outPoints = pointService.queryPoints(null, null, AreaTypeEnum.CK_DOCK.getValue());
|
||||||
|
|
||||||
|
|
@ -410,9 +405,7 @@ public class AllocateProcessor {
|
||||||
return matchedInventories.stream()
|
return matchedInventories.stream()
|
||||||
.map(inventory -> {
|
.map(inventory -> {
|
||||||
Point currPoint = pointMap.get(inventory.getPointId());
|
Point currPoint = pointMap.get(inventory.getPointId());
|
||||||
String key = currPoint.getColNum() + "-" + currPoint.getLayerNum();
|
return calculateMoveCount(inventory, currPoint, outPoints);
|
||||||
List<Point> points = colLayerPointsMap.get(key);
|
|
||||||
return calculateMoveCount(inventory, currPoint, points, outPoints);
|
|
||||||
})
|
})
|
||||||
//按分数倒序排序、移动次数升序排序
|
//按分数倒序排序、移动次数升序排序
|
||||||
.sorted(Comparator.comparing(InventoryScore::getScore).reversed()
|
.sorted(Comparator.comparing(InventoryScore::getScore).reversed()
|
||||||
|
|
@ -426,10 +419,9 @@ public class AllocateProcessor {
|
||||||
*
|
*
|
||||||
* @param inventory 库存
|
* @param inventory 库存
|
||||||
* @param currPoint 当前库位
|
* @param currPoint 当前库位
|
||||||
* @param points 当前库位巷道的库位集合
|
|
||||||
* @return 库位位移次数
|
* @return 库位位移次数
|
||||||
*/
|
*/
|
||||||
private InventoryScore calculateMoveCount(Inventory inventory, Point currPoint, List<Point> points, List<Point> outPoints) {
|
private InventoryScore calculateMoveCount(Inventory inventory, Point currPoint, List<Point> outPoints) {
|
||||||
// 位移分数
|
// 位移分数
|
||||||
double moveScore;
|
double moveScore;
|
||||||
//移位库位
|
//移位库位
|
||||||
|
|
@ -439,6 +431,9 @@ public class AllocateProcessor {
|
||||||
Point bestPoint = getBestOutboundPoint(currPoint, outPoints);
|
Point bestPoint = getBestOutboundPoint(currPoint, outPoints);
|
||||||
double distanceScore = calculateClusterDistanceCost(currPoint, bestPoint) * 0.3;
|
double distanceScore = calculateClusterDistanceCost(currPoint, bestPoint) * 0.3;
|
||||||
|
|
||||||
|
//当前巷道的库位数
|
||||||
|
List<Point> points= pointMapper.findByColAndLayer(currPoint.getColNum(), currPoint.getLayerNum());
|
||||||
|
|
||||||
// 目标库位的深度位转换为索引
|
// 目标库位的深度位转换为索引
|
||||||
int targetIndex = Integer.parseInt(currPoint.getRowNum()) - 1;
|
int targetIndex = Integer.parseInt(currPoint.getRowNum()) - 1;
|
||||||
|
|
||||||
|
|
@ -729,6 +724,7 @@ public class AllocateProcessor {
|
||||||
Point toPoint = allocatePoint(fromPoint, itemKeyMap.get(inv.getItemKeyId()));
|
Point toPoint = allocatePoint(fromPoint, itemKeyMap.get(inv.getItemKeyId()));
|
||||||
Task moveTask = taskService.bulidTask(taskNo, TaskTypeEnum.MOVE.getValue(), moveItem, fromPoint, toPoint, stock, null, null, inv.getItemKeyId(), inv.getId(), inv.getQuantity(), 0);
|
Task moveTask = taskService.bulidTask(taskNo, TaskTypeEnum.MOVE.getValue(), moveItem, fromPoint, toPoint, stock, null, null, inv.getItemKeyId(), inv.getId(), inv.getQuantity(), 0);
|
||||||
moveList.add(moveTask);
|
moveList.add(moveTask);
|
||||||
|
pointService.bindPoint(toPoint);
|
||||||
log.info("生成移位任务:{}- 容器:{} - 库位:{} - 库存数量:{}", taskNo, stock.getStockCode(), fromPoint.getPointCode(), inv.getQuantity());
|
log.info("生成移位任务:{}- 容器:{} - 库位:{} - 库存数量:{}", taskNo, stock.getStockCode(), fromPoint.getPointCode(), inv.getQuantity());
|
||||||
}
|
}
|
||||||
return moveList;
|
return moveList;
|
||||||
|
|
@ -744,7 +740,7 @@ public class AllocateProcessor {
|
||||||
Area area = areaMapper.selectById(currentPoint.getAreaId());
|
Area area = areaMapper.selectById(currentPoint.getAreaId());
|
||||||
String areaCode = area.getAreaCode();
|
String areaCode = area.getAreaCode();
|
||||||
List<ItemKey> itemKeyIds = Collections.singletonList(itemKey);
|
List<ItemKey> itemKeyIds = Collections.singletonList(itemKey);
|
||||||
return scanTrayProcessor.allocatePoint(itemKeyIds, currentPoint, areaCode);
|
return scanTrayProcessor.allocatePoint(itemKeyIds, currentPoint, areaCode,BusinessTypeEnum.MOVE.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@ import org.cpte.modules.constant.GeneralConstant;
|
||||||
import org.cpte.modules.constant.enums.AgvStatusEnum;
|
import org.cpte.modules.constant.enums.AgvStatusEnum;
|
||||||
import org.cpte.modules.constant.enums.AgvVendorEnum;
|
import org.cpte.modules.constant.enums.AgvVendorEnum;
|
||||||
import org.cpte.modules.constant.enums.BusinessTypeEnum;
|
import org.cpte.modules.constant.enums.BusinessTypeEnum;
|
||||||
|
import org.cpte.modules.inventory.service.IInventoryService;
|
||||||
|
import org.cpte.modules.inventory.service.impl.InventoryServiceImpl;
|
||||||
import org.cpte.modules.receive.service.IAsnService;
|
import org.cpte.modules.receive.service.IAsnService;
|
||||||
import org.cpte.modules.shipping.entity.Task;
|
import org.cpte.modules.shipping.entity.Task;
|
||||||
import org.cpte.modules.shipping.mapper.TaskMapper;
|
import org.cpte.modules.shipping.mapper.TaskMapper;
|
||||||
|
|
@ -55,6 +57,9 @@ public class ITesAgvServiceImpl implements ITesAgvService {
|
||||||
@Autowired
|
@Autowired
|
||||||
private IAgvTaskService agvTaskService;
|
private IAgvTaskService agvTaskService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IInventoryService inventoryService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String generateTesAgvTaskJson(AgvTask agvTask) {
|
public String generateTesAgvTaskJson(AgvTask agvTask) {
|
||||||
NewMovePodTaskRequest newMovePodTaskRequest = new NewMovePodTaskRequest();
|
NewMovePodTaskRequest newMovePodTaskRequest = new NewMovePodTaskRequest();
|
||||||
|
|
@ -214,6 +219,9 @@ public class ITesAgvServiceImpl implements ITesAgvService {
|
||||||
String endCode = pointService.getElevatorPoint(agvTask.getEndCode(), GeneralConstant.CK_ELEVATOR_TASK_INDEX);
|
String endCode = pointService.getElevatorPoint(agvTask.getEndCode(), GeneralConstant.CK_ELEVATOR_TASK_INDEX);
|
||||||
agvTaskService.createAgvTask(null, agvTask.getCarrierCode(), agvTask.getEndCode(), endCode, null, BusinessTypeEnum.OUTBOUND.getValue(), 0, AgvVendorEnum.HIK.getValue());
|
agvTaskService.createAgvTask(null, agvTask.getCarrierCode(), agvTask.getEndCode(), endCode, null, BusinessTypeEnum.OUTBOUND.getValue(), 0, AgvVendorEnum.HIK.getValue());
|
||||||
}*/
|
}*/
|
||||||
|
}else if(BusinessTypeEnum.MOVE.getValue().equals(agvTask.getType())){
|
||||||
|
List<Task> tasks = taskMapper.queryByAgvTask(agvTask.getId());
|
||||||
|
inventoryService.moveInventory(tasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
agvTask.setStatus(AgvStatusEnum.COMPLETED.getValue());
|
agvTask.setStatus(AgvStatusEnum.COMPLETED.getValue());
|
||||||
|
|
|
||||||
|
|
@ -299,8 +299,8 @@ public class BatchUtil {
|
||||||
ps.setString(8, task.getToPointCode());
|
ps.setString(8, task.getToPointCode());
|
||||||
ps.setLong(9, task.getStockId());
|
ps.setLong(9, task.getStockId());
|
||||||
ps.setString(10, task.getStockCode());
|
ps.setString(10, task.getStockCode());
|
||||||
ps.setLong(11, task.getPickId());
|
ps.setObject(11, task.getPickId());
|
||||||
ps.setLong(12, task.getPickDetailId());
|
ps.setObject(12, task.getPickDetailId());
|
||||||
ps.setLong(13, task.getItemKeyId());
|
ps.setLong(13, task.getItemKeyId());
|
||||||
ps.setLong(14, task.getInventoryId());
|
ps.setLong(14, task.getInventoryId());
|
||||||
ps.setBigDecimal(15, task.getPlanQty());
|
ps.setBigDecimal(15, task.getPlanQty());
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue