diff --git a/cpte-boot-base-core/pom.xml b/cpte-boot-base-core/pom.xml
index d08ee04..ff29ec4 100644
--- a/cpte-boot-base-core/pom.xml
+++ b/cpte-boot-base-core/pom.xml
@@ -367,5 +367,6 @@
org.jeecgframework.boot3
jeecg-boot-starter-chatgpt
+
\ No newline at end of file
diff --git a/cpte-boot-module/cpte-module-demo/src/main/resources/static/desform/aitest/json/ai_control_main.json b/cpte-boot-module/cpte-module-demo/src/main/resources/static/desform/aitest/json/ai_control_main.json
index 495cb6c..8f231a9 100644
--- a/cpte-boot-module/cpte-module-demo/src/main/resources/static/desform/aitest/json/ai_control_main.json
+++ b/cpte-boot-module/cpte-module-demo/src/main/resources/static/desform/aitest/json/ai_control_main.json
@@ -2877,7 +2877,7 @@
"advancedSetting": {
"defaultValue": {
"type": "compose",
- "value": "https://help.jeecg.com/",
+ "value": "https://help.cpte.com/",
"format": "string",
"allowFunc": true,
"valueSplit": "",
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/agvTask/controller/AgvTaskController.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/agvTask/controller/AgvTaskController.java
index 295499b..4ae5814 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/agvTask/controller/AgvTaskController.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/agvTask/controller/AgvTaskController.java
@@ -8,8 +8,15 @@ import java.util.stream.Collectors;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
+
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
+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.hikAgv.service.IHikAgvService;
+import org.cpte.modules.shipping.entity.Task;
+import org.cpte.modules.tesAgv.service.ITesAgvService;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.query.QueryRuleEnum;
@@ -22,6 +29,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
+import org.jeecg.config.shiro.IgnoreAuth;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
@@ -38,127 +46,128 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.apache.shiro.authz.annotation.RequiresPermissions;
- /**
+
+/**
* @Description: AGV任务表
* @author: cpte
- * @Date: 2025-11-06
+ * @Date: 2025-11-06
* @Version: V1.0
*/
-@Tag(name="AGV任务表")
+@Tag(name = "AGV任务表")
@RestController
@RequestMapping("/agvTask")
@Slf4j
public class AgvTaskController extends JeecgController {
- @Autowired
- private IAgvTaskService agvTaskService;
-
- /**
- * 分页列表查询
- *
- * @param agvTask
- * @param pageNo
- * @param pageSize
- * @param req
- * @return
- */
- //@AutoLog(value = "AGV任务表-分页列表查询")
- @Operation(summary="AGV任务表-分页列表查询")
- @GetMapping(value = "/list")
- public Result> queryPageList(AgvTask agvTask,
- @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
- @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
- HttpServletRequest req) {
+ @Autowired
+ private IAgvTaskService agvTaskService;
+
+ /**
+ * 分页列表查询
+ *
+ * @param agvTask
+ * @param pageNo
+ * @param pageSize
+ * @param req
+ * @return
+ */
+ //@AutoLog(value = "AGV任务表-分页列表查询")
+ @Operation(summary = "AGV任务表-分页列表查询")
+ @GetMapping(value = "/list")
+ public Result> queryPageList(AgvTask agvTask,
+ @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
+ @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
+ HttpServletRequest req) {
QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(agvTask, req.getParameterMap());
- Page page = new Page(pageNo, pageSize);
- IPage pageList = agvTaskService.page(page, queryWrapper);
- return Result.OK(pageList);
- }
-
- /**
- * 添加
- *
- * @param agvTask
- * @return
- */
- @AutoLog(value = "AGV任务表-添加")
- @Operation(summary="AGV任务表-添加")
- @RequiresPermissions("agvTask:data_agv_task:add")
- @PostMapping(value = "/add")
- public Result add(@RequestBody AgvTask agvTask) {
- agvTaskService.save(agvTask);
- return Result.OK("添加成功!");
- }
-
- /**
- * 编辑
- *
- * @param agvTask
- * @return
- */
- @AutoLog(value = "AGV任务表-编辑")
- @Operation(summary="AGV任务表-编辑")
- @RequiresPermissions("agvTask:data_agv_task:edit")
- @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
- public Result edit(@RequestBody AgvTask agvTask) {
- agvTaskService.updateById(agvTask);
- return Result.OK("编辑成功!");
- }
-
- /**
- * 通过id删除
- *
- * @param id
- * @return
- */
- @AutoLog(value = "AGV任务表-通过id删除")
- @Operation(summary="AGV任务表-通过id删除")
- @RequiresPermissions("agvTask:data_agv_task:delete")
- @DeleteMapping(value = "/delete")
- public Result delete(@RequestParam(name="id",required=true) String id) {
- agvTaskService.removeById(id);
- return Result.OK("删除成功!");
- }
-
- /**
- * 批量删除
- *
- * @param ids
- * @return
- */
- @AutoLog(value = "AGV任务表-批量删除")
- @Operation(summary="AGV任务表-批量删除")
- @RequiresPermissions("agvTask:data_agv_task:deleteBatch")
- @DeleteMapping(value = "/deleteBatch")
- public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) {
- this.agvTaskService.removeByIds(Arrays.asList(ids.split(",")));
- return Result.OK("批量删除成功!");
- }
-
- /**
- * 通过id查询
- *
- * @param id
- * @return
- */
- //@AutoLog(value = "AGV任务表-通过id查询")
- @Operation(summary="AGV任务表-通过id查询")
- @GetMapping(value = "/queryById")
- public Result queryById(@RequestParam(name="id",required=true) String id) {
- AgvTask agvTask = agvTaskService.getById(id);
- if(agvTask==null) {
- return Result.error("未找到对应数据");
- }
- return Result.OK(agvTask);
- }
+ Page page = new Page(pageNo, pageSize);
+ IPage pageList = agvTaskService.page(page, queryWrapper);
+ return Result.OK(pageList);
+ }
/**
- * 导出excel
- *
- * @param request
- * @param agvTask
- */
+ * 添加
+ *
+ * @param agvTask
+ * @return
+ */
+ @AutoLog(value = "AGV任务表-添加")
+ @Operation(summary = "AGV任务表-添加")
+ @RequiresPermissions("agvTask:data_agv_task:add")
+ @PostMapping(value = "/add")
+ public Result add(@RequestBody AgvTask agvTask) {
+ agvTaskService.save(agvTask);
+ return Result.OK("添加成功!");
+ }
+
+ /**
+ * 编辑
+ *
+ * @param agvTask
+ * @return
+ */
+ @AutoLog(value = "AGV任务表-编辑")
+ @Operation(summary = "AGV任务表-编辑")
+ @RequiresPermissions("agvTask:data_agv_task:edit")
+ @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
+ public Result edit(@RequestBody AgvTask agvTask) {
+ agvTaskService.updateById(agvTask);
+ return Result.OK("编辑成功!");
+ }
+
+ /**
+ * 通过id删除
+ *
+ * @param id
+ * @return
+ */
+ @AutoLog(value = "AGV任务表-通过id删除")
+ @Operation(summary = "AGV任务表-通过id删除")
+ @RequiresPermissions("agvTask:data_agv_task:delete")
+ @DeleteMapping(value = "/delete")
+ public Result delete(@RequestParam(name = "id", required = true) String id) {
+ agvTaskService.removeById(id);
+ return Result.OK("删除成功!");
+ }
+
+ /**
+ * 批量删除
+ *
+ * @param ids
+ * @return
+ */
+ @AutoLog(value = "AGV任务表-批量删除")
+ @Operation(summary = "AGV任务表-批量删除")
+ @RequiresPermissions("agvTask:data_agv_task:deleteBatch")
+ @DeleteMapping(value = "/deleteBatch")
+ public Result deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
+ this.agvTaskService.removeByIds(Arrays.asList(ids.split(",")));
+ return Result.OK("批量删除成功!");
+ }
+
+ /**
+ * 通过id查询
+ *
+ * @param id
+ * @return
+ */
+ //@AutoLog(value = "AGV任务表-通过id查询")
+ @Operation(summary = "AGV任务表-通过id查询")
+ @GetMapping(value = "/queryById")
+ public Result queryById(@RequestParam(name = "id", required = true) String id) {
+ AgvTask agvTask = agvTaskService.getById(id);
+ if (agvTask == null) {
+ return Result.error("未找到对应数据");
+ }
+ return Result.OK(agvTask);
+ }
+
+ /**
+ * 导出excel
+ *
+ * @param request
+ * @param agvTask
+ */
@RequiresPermissions("agvTask:data_agv_task:exportXls")
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, AgvTask agvTask) {
@@ -166,16 +175,15 @@ public class AgvTaskController extends JeecgController
}
/**
- * 通过excel导入数据
- *
- * @param request
- * @param response
- * @return
- */
+ * 通过excel导入数据
+ *
+ * @param request
+ * @param response
+ * @return
+ */
@RequiresPermissions("agvTask:data_agv_task:importExcel")
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result> importExcel(HttpServletRequest request, HttpServletResponse response) {
return super.importExcel(request, response, AgvTask.class);
}
-
}
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/agvTask/service/IAgvTaskService.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/agvTask/service/IAgvTaskService.java
index 7fec850..aeada5e 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/agvTask/service/IAgvTaskService.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/agvTask/service/IAgvTaskService.java
@@ -16,7 +16,6 @@ public interface IAgvTaskService extends IService {
* 创建agvTask任务
*
* @param businessDetailId 业务ID
- * @param status 状态
* @param carrierCode 容器
* @param startCode 起点
* @param endCode 终点
@@ -24,6 +23,20 @@ public interface IAgvTaskService extends IService {
* @param type 业务类型
* @param agvVendor 供应商
*/
- AgvTask createAgvTask(Long businessDetailId, Integer status, String carrierCode, String startCode, String endCode, String taskType, String type, String agvVendor);
+ AgvTask createAgvTask(Long businessDetailId, String carrierCode, String startCode, String endCode, String taskType, String type, String agvVendor);
+
+ /**
+ * 创建agvTask任务
+ *
+ * @param businessDetailId 业务ID
+ * @param carrierCode 容器
+ * @param startCode 起点
+ * @param endCode 终点
+ * @param taskType 任务类型
+ * @param type 业务类型
+ * @param agvVendor 供应商
+ */
+ AgvTask bulidAgvTask(Long businessDetailId, String carrierCode, String startCode, String endCode, String taskType, String type, String agvVendor);
+
}
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/agvTask/service/impl/AgvTaskServiceImpl.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/agvTask/service/impl/AgvTaskServiceImpl.java
index 0cb8c54..5ec38af 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/agvTask/service/impl/AgvTaskServiceImpl.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/agvTask/service/impl/AgvTaskServiceImpl.java
@@ -1,16 +1,20 @@
package org.cpte.modules.agvTask.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import org.apache.shiro.SecurityUtils;
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.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.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
+import java.util.Date;
import java.util.List;
/**
@@ -24,7 +28,13 @@ public class AgvTaskServiceImpl extends ServiceImpl impl
@Override
@Transactional(rollbackFor = Exception.class)
- public AgvTask createAgvTask(Long businessDetailId, Integer status, String carrierCode, String startCode, String endCode, String taskType, String type, String agvVendor) {
+ public AgvTask createAgvTask(Long businessDetailId, String carrierCode, String startCode, String endCode, String taskType, String type, String agvVendor) {
+ LoginUser sysUser = null;
+ try {
+ sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+ } catch (Exception e) {
+ log.error("获取登录用户信息失败");
+ }
int priority = 99;
if (AgvVendorEnum.TES.getValue().equals(agvVendor)) {
priority = 3;
@@ -33,14 +43,48 @@ public class AgvTaskServiceImpl extends ServiceImpl impl
.businessDetailId(businessDetailId)
.carrierCode(carrierCode)
.type(type)
- .status(status)
+ .status(AgvStatusEnum.CREATED.getValue())
.startCode(startCode)
.endCode(endCode)
.carrierType(StockTypeEnum.TRAY.getValue())
.taskType(taskType)
.priority(priority)
.agvVendor(agvVendor)
+ .sysOrgCode(sysUser == null ? "A05" : sysUser.getOrgCode())
+ .tenantId(sysUser == null ? 1000L : Long.parseLong(sysUser.getRelTenantIds()))
+ .createBy(sysUser == null ? "system" : sysUser.getUsername())
+ .createTime(new Date())
.build();
return this.save(agvTask) ? agvTask : null;
}
+
+ @Override
+ public AgvTask bulidAgvTask(Long businessDetailId, String carrierCode, String startCode, String endCode, String taskType, String type, String agvVendor) {
+ LoginUser sysUser = null;
+ try {
+ sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+ } catch (Exception e) {
+ log.error("获取登录用户信息失败");
+ }
+ int priority = 99;
+ if (AgvVendorEnum.TES.getValue().equals(agvVendor)) {
+ priority = 3;
+ }
+ return AgvTask.builder()
+ .businessDetailId(businessDetailId)
+ .carrierCode(carrierCode)
+ .type(type)
+ .status(AgvStatusEnum.CREATED.getValue())
+ .startCode(startCode)
+ .endCode(endCode)
+ .carrierType(StockTypeEnum.TRAY.getValue())
+ .taskType(taskType)
+ .priority(priority)
+ .agvVendor(agvVendor)
+ .sysOrgCode(sysUser == null ? "A05" : sysUser.getOrgCode())
+ .tenantId(sysUser == null ? 1000L : Long.parseLong(sysUser.getRelTenantIds()))
+ .createBy(sysUser == null ? "system" : sysUser.getUsername())
+ .createTime(new Date())
+ .build();
+ }
}
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/entity/Point.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/entity/Point.java
index 635742a..353d7a6 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/entity/Point.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/entity/Point.java
@@ -65,19 +65,19 @@ public class Point implements Serializable {
*/
@Excel(name = "排", width = 15)
@Schema(description = "排")
- private java.lang.String rows;
+ private java.lang.String rowNum;
/**
* 列
*/
@Excel(name = "列", width = 15)
@Schema(description = "列")
- private java.lang.String cols;
+ private java.lang.String colNum;
/**
* 层
*/
@Excel(name = "层", width = 15)
@Schema(description = "层")
- private java.lang.String layers;
+ private java.lang.String layerNum;
/**
* 描述
*/
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/IPointService.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/IPointService.java
index 977cf4b..1cb5b1b 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/IPointService.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/IPointService.java
@@ -1,4 +1,5 @@
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;
@@ -19,6 +20,19 @@ public interface IPointService extends IService {
*/
Point validatePoint(String pointCode);
+ /**
+ * 占用点位
+ * @param point 点位
+ */
+ void bindPoint(Point point);
+
+ /**
+ * 释放点位
+ * @param point 点位
+ */
+ void unbindPoint(Point point);
+
+
/**
* 根据库位编码集合查询库位信息
*
@@ -42,4 +56,16 @@ public interface IPointService extends IService {
* @return Map
*/
Map queryByPointIdsToMap(List pointIds);
+
+ /**
+ * 获取输送线工作台点位,均衡分配点位任务
+ *
+ * @param status 状态
+ * @param areaCode 库区编码
+ * @param key 索引
+ * @return pointEntity
+ */
+ Point getWorkStationPoint(Integer status,String areaCode, String key);
+
+ Point queryToPoint(String pointCode,Integer status,String areaCode);
}
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/IStockService.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/IStockService.java
index 97199c5..6ada0e6 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/IStockService.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/IStockService.java
@@ -1,5 +1,6 @@
package org.cpte.modules.base.service;
+import org.cpte.modules.base.entity.Point;
import org.cpte.modules.base.entity.Stock;
import com.baomidou.mybatisplus.extension.service.IService;
@@ -21,6 +22,20 @@ public interface IStockService extends IService {
*/
Stock validateStock(String stockCode);
+ /**
+ * 验证容器状态
+ * @param stock 容器
+ */
+ void validateStockStatus(Stock stock);
+
+ /**
+ * 绑定容器
+ *
+ * @param stock 容器
+ * @param point 容器位置
+ */
+ void bindStock(Stock stock, Point point);
+
/**
* 根据容器编码集合查询容器信息
*
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/impl/PointServiceImpl.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/impl/PointServiceImpl.java
index 44a0d03..2913824 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/impl/PointServiceImpl.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/impl/PointServiceImpl.java
@@ -3,14 +3,13 @@ package org.cpte.modules.base.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Maps;
import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.cpte.modules.base.entity.Area;
import org.cpte.modules.base.entity.Point;
-import org.cpte.modules.base.entity.Stock;
-import org.cpte.modules.base.mapper.AreaMapper;
import org.cpte.modules.base.mapper.PointMapper;
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.jeecg.common.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -35,6 +34,9 @@ public class PointServiceImpl extends ServiceImpl implements
@Autowired
private PointMapper pointMapper;
+ @Autowired
+ private RedisUtil redisUtil;
+
/**
* 验证库位
*
@@ -56,6 +58,18 @@ public class PointServiceImpl extends ServiceImpl implements
return point;
}
+ @Override
+ public void bindPoint(Point point) {
+ point.setStatus(CommonStatusEnum.USED.getValue());
+ pointMapper.updateById(point);
+ }
+
+ @Override
+ public void unbindPoint(Point point) {
+ point.setStatus(CommonStatusEnum.FREE.getValue());
+ pointMapper.updateById(point);
+ }
+
/**
* 根据库位编码集合查询库位信息
*
@@ -106,4 +120,25 @@ public class PointServiceImpl extends ServiceImpl implements
}
return pointMap;
}
+
+ @Override
+ public Point getWorkStationPoint(Integer status, String areaCode, String key) {
+ List dstPointList = pointMapper.queryPoints(null, status, areaCode);
+ if (dstPointList.isEmpty()) {
+ String desc = AreaTypeEnum.getDescByValue(areaCode);
+ throw new RuntimeException("【" + desc + "】" + "无空闲库位");
+ }
+ long currentIndex = redisUtil.incr(key, 1) % dstPointList.size();
+ return dstPointList.get((int) currentIndex);
+ }
+
+ @Override
+ public Point queryToPoint(String pointCode, Integer status, String areaCode) {
+ Point dstPoint = null;
+ List dstPointList = pointMapper.queryPoints(pointCode, status, areaCode);
+ if (dstPointList.isEmpty()) {
+ throw new RuntimeException("【" + AreaTypeEnum.CPCCQ.getDesc() + "】无空闲库位");
+ }
+ return dstPoint = dstPointList.get(0);
+ }
}
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/impl/StockServiceImpl.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/impl/StockServiceImpl.java
index 676ae15..4c77b15 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/impl/StockServiceImpl.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/impl/StockServiceImpl.java
@@ -3,11 +3,14 @@ package org.cpte.modules.base.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Maps;
import org.apache.commons.collections4.CollectionUtils;
+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.StockMapper;
import org.cpte.modules.base.mapper.StockMapper;
import org.cpte.modules.base.service.IStockService;
+import org.cpte.modules.constant.enums.CommonStatusEnum;
+import org.cpte.modules.constant.enums.StockTypeEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -51,6 +54,20 @@ public class StockServiceImpl extends ServiceImpl implements
return stock;
}
+ @Override
+ public void validateStockStatus(Stock stock) {
+ if (CommonStatusEnum.USED.getValue().equals(stock.getStatus())) {
+ throw new RuntimeException(stock.getStockCode() + "容器已占用,请更换容器!");
+ }
+ }
+
+ @Override
+ public void bindStock(Stock stock, Point point) {
+ stock.setPointId(point.getId());
+ stock.setStatus(CommonStatusEnum.USED.getValue());
+ stockMapper.updateById(stock);
+ }
+
/**
* 根据容器编码集合查询容器信息
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/constant/CommonConstant.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/constant/CommonConstant.java
deleted file mode 100644
index 8855b31..0000000
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/constant/CommonConstant.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.cpte.modules.constant;
-
-/**
- * 通用常量
- */
-public interface CommonConstant {
- /**
- * 入库输送线任务均衡索引
- */
- String RK_DOCK_TASK_INDEX = "rk_dock_task_index";
-
- /**
- * 入库单规则编码
- */
- String ASN_ORDER_NO = "asn_order_no";
-
- /**
- * 出库单规则编码
- */
- String PICK_ORDER_NO = "pick_order_no";
-}
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/constant/GeneralConstant.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/constant/GeneralConstant.java
new file mode 100644
index 0000000..e04818d
--- /dev/null
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/constant/GeneralConstant.java
@@ -0,0 +1,57 @@
+package org.cpte.modules.constant;
+
+/**
+ * 通用常量
+ */
+public interface GeneralConstant {
+ /**
+ * 接口开关
+ */
+ final String OPEN_FLAG = "OPEN";
+
+ /**
+ * 成功码
+ */
+ final String AGV_SUCCESS_CODE = "SUCCESS";
+
+ /**
+ * 失败码
+ */
+ final String AGV_FAIL_CODE = "FAILED";
+
+ /**
+ * 成功码
+ */
+ final Integer TES_SUCCESS_CODE = 0;
+
+ /**
+ * 失败码
+ */
+ final Integer TES_FAIL_CODE = 500;
+
+ /**
+ * 入库输送线任务均衡索引
+ */
+ String RK_DOCK_TASK_INDEX = "rk_dock_task_index";
+
+ /**
+ * 出库输送线任务均衡索引
+ */
+ String CK_DOCK_TASK_INDEX = "ck_dock_task_index";
+
+
+ /**
+ * 入库单规则编码
+ */
+ String ASN_ORDER_NO = "asn_order_no";
+
+ /**
+ * 出库单规则编码
+ */
+ String PICK_ORDER_NO = "pick_order_no";
+
+ /**
+ * 入库回传接口
+ */
+ String INBOUND_CALLBACK = "7Q7sqpIh";
+}
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/constant/enums/AreaTypeEnum.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/constant/enums/AreaTypeEnum.java
index f011766..67c5f2e 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/constant/enums/AreaTypeEnum.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/constant/enums/AreaTypeEnum.java
@@ -31,4 +31,19 @@ public enum AreaTypeEnum {
this.desc = desc;
}
+ /**
+ * 根据值获取描述
+ *
+ * @param value 值
+ * @return 枚举
+ */
+ public static String getDescByValue(String value) {
+ for (AreaTypeEnum item : AreaTypeEnum.values()) {
+ if (item.value.equals(value)) {
+ return item.desc;
+ }
+ }
+ return null;
+ }
+
}
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/constant/enums/BaseEnum.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/constant/enums/BaseEnum.java
deleted file mode 100644
index 73a1b92..0000000
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/constant/enums/BaseEnum.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package org.cpte.modules.constant.enums;
-
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONAware;
-import com.alibaba.fastjson.JSONObject;
-import com.google.common.base.CaseFormat;
-import lombok.Data;
-
-import java.util.LinkedHashMap;
-import java.util.Objects;
-
-/**
- * 枚举类接口
- *
- * @Author YouChain: 胡克
- * @Date 2018-07-17 21:22:12
- * @Email huoj@youchain56.com
- */
-public interface BaseEnum {
-
- /**
- * 获取枚举类的值
- *
- * @return
- */
- Object getValue();
-
- /**
- * 获取枚举类的说明
- *
- * @return String
- */
- String getDesc();
-
- /**
- * 比较参数是否与枚举类的value相同
- *
- * @param value
- * @return boolean
- */
- default boolean equalsValue(Object value) {
- return Objects.equals(getValue(), value);
- }
-
- /**
- * 比较枚举类是否相同
- *
- * @param baseEnum
- * @return boolean
- */
- default boolean equals(BaseEnum baseEnum) {
- return Objects.equals(getValue(), baseEnum.getValue()) && Objects.equals(getDesc(), baseEnum.getDesc());
- }
-
- /**
- * 返回枚举类的说明
- *
- * @param clazz 枚举类类对象
- * @return
- */
- static String getInfo(Class extends BaseEnum> clazz) {
- BaseEnum[] enums = clazz.getEnumConstants();
- LinkedHashMap json = new LinkedHashMap<>(enums.length);
- for (BaseEnum e : enums) {
- JSONObject jsonObject = new JSONObject();
- jsonObject.put("value", new DeletedQuotationAware(e.getValue()));
- jsonObject.put("desc", new DeletedQuotationAware(e.getDesc()));
- json.put(e.toString(), jsonObject);
- }
-
- String enumJson = JSON.toJSONString(json, true);
- enumJson = enumJson.replaceAll("\"", "");
- enumJson = enumJson.replaceAll("\t", " ");
- enumJson = enumJson.replaceAll("\n", "
");
- String prefix = "
export const " + CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, clazz.getSimpleName() + " =
");
- return prefix + enumJson + "
";
- }
-
- @Data
- class DeletedQuotationAware implements JSONAware {
-
- private String value;
-
- public DeletedQuotationAware(Object value) {
- if (value instanceof String) {
- this.value = "'" + value + "'";
- } else {
- this.value = value.toString();
- }
- }
-
- @Override
- public String toJSONString() {
- return value;
- }
- }
-}
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/constant/enums/BusinessTypeEnum.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/constant/enums/BusinessTypeEnum.java
index 2e61242..eebda47 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/constant/enums/BusinessTypeEnum.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/constant/enums/BusinessTypeEnum.java
@@ -3,7 +3,7 @@ package org.cpte.modules.constant.enums;
import lombok.Getter;
/**
- * 业务类型枚举
+ * AGV业务类型枚举
*
* @author: cpte
*/
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/constant/enums/TaskTypeEnum.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/constant/enums/TaskTypeEnum.java
new file mode 100644
index 0000000..accc8f4
--- /dev/null
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/constant/enums/TaskTypeEnum.java
@@ -0,0 +1,26 @@
+package org.cpte.modules.constant.enums;
+
+import lombok.Getter;
+
+@Getter
+public enum TaskTypeEnum {
+ PICK(1, "出库"),
+ ;
+
+ TaskTypeEnum(Integer value, String desc) {
+ this.value = value;
+ this.desc = desc;
+ }
+
+ /**
+ * 值
+ */
+ final Integer value;
+
+ /**
+ * 描述
+ */
+ final String desc;
+
+
+}
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/conveyorLine/service/impl/IConveyorLineServiceImpl.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/conveyorLine/service/impl/IConveyorLineServiceImpl.java
index df29f09..86ae322 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/conveyorLine/service/impl/IConveyorLineServiceImpl.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/conveyorLine/service/impl/IConveyorLineServiceImpl.java
@@ -7,6 +7,7 @@ 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.IPointService;
import org.cpte.modules.constant.enums.*;
import org.cpte.modules.conveyorLine.request.ScanTrayRequest;
import org.cpte.modules.conveyorLine.service.IConveyorLineService;
@@ -38,6 +39,9 @@ public class IConveyorLineServiceImpl implements IConveyorLineService {
@Autowired
private InventoryMapper inventoryMapper;
+ @Autowired
+ private IPointService pointService;
+
@Autowired
private IAgvTaskService iAgvTaskService;
@@ -64,19 +68,17 @@ public class IConveyorLineServiceImpl implements IConveyorLineService {
throw new RuntimeException("【" + scanTrayRequest.getStockCode() + "】托盘已扫描,请勿重复扫描");
}
+ //输送线的起点
+ Point srcPoint=pointMapper.selectById(asnDetail.getToPointId());
+
//通过算法获取目标点位
- List dstPointList = pointMapper.queryPoints(null, CommonStatusEnum.FREE.getValue(), AreaTypeEnum.CPCCQ.getValue());
- if (dstPointList.isEmpty()) {
- throw new RuntimeException("【" + AreaTypeEnum.CPCCQ.getDesc() + "】无空闲库位");
- }
- Point dstPoint = dstPointList.get(0);
+ Point dstPoint=pointService.queryToPoint(null, CommonStatusEnum.FREE.getValue(), AreaTypeEnum.CPCCQ.getValue());
//锁定目标库位
- dstPoint.setStatus(CommonStatusEnum.USED.getValue());
- pointMapper.updateById(dstPoint);
+ pointService.bindPoint(dstPoint);
//验证通过,生成Tes任务
- iAgvTaskService.createAgvTask(asnDetail.getId(), AgvStatusEnum.CREATED.getValue(), stock.getStockCode(), null, dstPoint.getPointCode(), null, BusinessTypeEnum.INBOUND.getValue(), AgvVendorEnum.TES.getValue());
+ iAgvTaskService.createAgvTask(asnDetail.getId(), stock.getStockCode(), srcPoint.getPointCode(), dstPoint.getPointCode(), null, BusinessTypeEnum.INBOUND.getValue(), AgvVendorEnum.TES.getValue());
}
}
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/hikAgv/controller/HikAgvController.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/hikAgv/controller/HikAgvController.java
index b64935b..c578038 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/hikAgv/controller/HikAgvController.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/hikAgv/controller/HikAgvController.java
@@ -47,7 +47,6 @@ public class HikAgvController {
@AutoLog(value = "海康AGV-任务上报")
@Operation(summary = "海康AGV-任务上报")
@PostMapping(value = "/reporter/task")
- @IgnoreAuth
public HikResult taskReporter(@RequestBody TaskReporterRequest taskReporterRequest) {
try {
iHikAgvService.taskReporter(taskReporterRequest);
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/hikAgv/service/impl/IHikAgvServiceImpl.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/hikAgv/service/impl/IHikAgvServiceImpl.java
index 39097f9..f9443fe 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/hikAgv/service/impl/IHikAgvServiceImpl.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/hikAgv/service/impl/IHikAgvServiceImpl.java
@@ -7,6 +7,11 @@ 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.*;
import org.cpte.modules.hikAgv.request.SubmitRequest;
import org.cpte.modules.hikAgv.request.TaskReporterRequest;
@@ -25,27 +30,18 @@ import java.util.*;
@Slf4j
public class IHikAgvServiceImpl implements IHikAgvService {
- /**
- * 接口开关
- */
- final String open_flag = "OPEN";
-
- /**
- * 成功码
- */
- final String success_code = "SUCCESS";
-
- /**
- * 失败码
- */
- final String fail_code = "FAILED";
-
@Autowired
private SysDictMapper sysDictMapper;
@Autowired
private AgvTaskMapper agvTaskMapper;
+ @Autowired
+ private IStockService iStockService;
+
+ @Autowired
+ private IPointService iPointService;
+
@Autowired
private IAgvTaskService iAgvTaskService;
@@ -61,7 +57,7 @@ public class IHikAgvServiceImpl implements IHikAgvService {
SubmitRequest.TargetRoute dstTargetRoute = createDstTargetRoute(agvTask);
submitRequest.setTargetRoute(Arrays.asList(srcTargetRoute, dstTargetRoute));
- submitRequest.setInitPriority( agvTask.getPriority());
+ submitRequest.setInitPriority(agvTask.getPriority());
LocalDateTime now = LocalDateTime.now(ZoneOffset.UTC);
String deadline = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'"));
@@ -85,8 +81,8 @@ public class IHikAgvServiceImpl implements IHikAgvService {
public void sendHikAgvTask(String url, String json, AgvTask agvTask) {
log.info("请求报文:{}", json);
// 检查接口开关, 未开启则返回
- if (sysDictMapper.queryByDictCode(open_flag) == null) {
- updateAgvTaskResponse(agvTask, "接口未开启", fail_code);
+ if (sysDictMapper.queryByDictCode(GeneralConstant.OPEN_FLAG) == null) {
+ updateAgvTaskResponse(agvTask, "接口未开启", GeneralConstant.AGV_FAIL_CODE);
return;
}
@@ -112,16 +108,14 @@ public class IHikAgvServiceImpl implements IHikAgvService {
code = resulObject.getString("code");
message = resulObject.getString("message");
- if (!success_code.equals(code)) {
+ if (!GeneralConstant.AGV_SUCCESS_CODE.equals(code)) {
throw new RuntimeException("AGV返回消息:" + message);
}
// 更新任务状态
updateAgvTaskResponse(agvTask, message, code);
} catch (Exception e) {
- // 记录异常到 AgvTask
- updateAgvTaskResponse(agvTask, e.getMessage(), fail_code);
- throw e; // 继续向上抛出异常供 Controller 层处理
+ updateAgvTaskResponse(agvTask, e.getMessage(), GeneralConstant.AGV_FAIL_CODE);
}
}
@@ -132,6 +126,8 @@ 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());
String status = taskReporterRequest.getExtra().getValues().getMethod();
switch (status) {
case "outbin":
@@ -140,7 +136,7 @@ public class IHikAgvServiceImpl implements IHikAgvService {
break;
case "end":
//任务完成
- handleEnd(agvTask);
+ handleEnd(agvTask, stock, point);
break;
case "resend":
//重新发送
@@ -164,7 +160,10 @@ public class IHikAgvServiceImpl implements IHikAgvService {
*
* @param agvTask 任务
*/
- private void handleEnd(AgvTask agvTask) {
+ private void handleEnd(AgvTask agvTask, Stock stock, Point point) {
+ //绑定容器和点位
+ iStockService.bindStock(stock, point);
+ //更新任务状态
agvTask.setStatus(AgvStatusEnum.COMPLETED.getValue());
agvTask.setEndTime(new Date());
agvTaskMapper.updateById(agvTask);
@@ -176,11 +175,11 @@ public class IHikAgvServiceImpl implements IHikAgvService {
* @param agvTask 任务
*/
private void handleResend(AgvTask agvTask) {
- Long count = agvTaskMapper.existsByStockCode(agvTask.getCarrierCode(),AgvVendorEnum.HIK.getValue());
+ Long count = agvTaskMapper.existsByStockCode(agvTask.getCarrierCode(), AgvVendorEnum.HIK.getValue());
if (count > 0) {
throw new RuntimeException("任务已重新生成,请勿重复操作! ");
}
- AgvTask newAgvTask = iAgvTaskService.createAgvTask(agvTask.getBusinessDetailId(),AgvStatusEnum.CREATED.getValue(), agvTask.getCarrierCode(), agvTask.getStartCode(), agvTask.getEndCode(), null, agvTask.getType(),AgvVendorEnum.HIK.getValue());
+ AgvTask newAgvTask = iAgvTaskService.createAgvTask(agvTask.getBusinessDetailId(), agvTask.getCarrierCode(), agvTask.getStartCode(), agvTask.getEndCode(), null, agvTask.getType(), AgvVendorEnum.HIK.getValue());
switch (agvTask.getType()) {
case "INBOUND":
case "OUTBOUND":
@@ -195,7 +194,7 @@ public class IHikAgvServiceImpl implements IHikAgvService {
private void updateAgvTaskResponse(AgvTask agvTask, String message, String code) {
if (agvTask != null) {
- if (success_code.equals(code)) {
+ if (GeneralConstant.AGV_SUCCESS_CODE.equals(code)) {
agvTask.setStatus(AgvStatusEnum.EXECUTING.getValue());
}
agvTask.setResMessage(message);
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/inventory/service/impl/InventoryServiceImpl.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/inventory/service/impl/InventoryServiceImpl.java
index adeba64..8928d3d 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/inventory/service/impl/InventoryServiceImpl.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/inventory/service/impl/InventoryServiceImpl.java
@@ -41,7 +41,7 @@ public class InventoryServiceImpl extends ServiceImpl pickDetailList = pickDetailMapper.queryUnallocatedPickDetail();
- if (pickDetailList.isEmpty()) {
+ // 查询未分配或者部分分配的出库
+ List pickList = pickMapper.queryUnallocatedPick();
+ if (pickList.isEmpty()) {
return;
}
- // 分配出库明细
+ // 分配出库
long startTime = System.currentTimeMillis();
- List resultMsg = iPickService.allocatePickDetail2(pickDetailList);
+ List resultMsg = iPickService.allocatePick2(pickList);
long endTime = System.currentTimeMillis();
log.info("分配出库明细耗时:{}ms", endTime - startTime);
if (CollectionUtils.isNotEmpty(resultMsg)) {
@@ -69,6 +78,13 @@ public class AllocateJob implements Job {
}
}
}
+
+ //生成出库AGV出库任务
+ long startTime2 = System.currentTimeMillis();
+ List taskList = taskMapper.queryUnallocatedTask();
+ iTaskService.generateAgvTask(taskList);
+ long endTime2 = System.currentTimeMillis();
+ log.info("生成AGV出库任务耗时:{}ms", endTime2 - startTime2);
}
/**
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/quartz/job/HikAgvJob.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/quartz/job/HikAgvJob.java
index c5e7219..808c488 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/quartz/job/HikAgvJob.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/quartz/job/HikAgvJob.java
@@ -30,19 +30,15 @@ public class HikAgvJob implements Job {
}
String taskSubmitUrl = "http://localhost:8000/cpte-wms/rcs/rtas/api/robot/controller/task/submit";
for (AgvTask agvTask : agvTaskList) {
- try {
- // 判断起点无任务才允许下发
- boolean isStartCodeAvailable = agvTaskMapper.existsByStartCode(agvTask.getStartCode(), AgvVendorEnum.HIK.getValue()) == 0;
- if (isStartCodeAvailable) {
- hikAgvService.sendHikAgvTask(
- taskSubmitUrl,
- hikAgvService.generateHikAgvTaskJson(agvTask),
- agvTask
- );
- }
- } catch (Exception e) {
- log.error("发送AGV任务失败,任务ID: {}", agvTask.getId(), e);
+ boolean isStartCodeAvailable = agvTaskMapper.existsByStartCode(agvTask.getStartCode(), AgvVendorEnum.HIK.getValue()) == 0;
+ if (isStartCodeAvailable) {
+ hikAgvService.sendHikAgvTask(
+ taskSubmitUrl,
+ hikAgvService.generateHikAgvTaskJson(agvTask),
+ agvTask
+ );
}
+
}
}
}
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/quartz/job/TesAgvJob.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/quartz/job/TesAgvJob.java
index 87b2742..d0a3e31 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/quartz/job/TesAgvJob.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/quartz/job/TesAgvJob.java
@@ -31,15 +31,12 @@ public class TesAgvJob implements Job {
}
String taskSubmitUrl = "http://localhost:8000/cpte-wms/tes/apiv2/newMovePodTask";
for (AgvTask agvTask : agvTaskList) {
- try {
- tesAgvService.sendTesAgvTask(
- taskSubmitUrl,
- tesAgvService.generateTesAgvTaskJson(agvTask),
- agvTask
- );
- } catch (Exception e) {
- log.error("发送AGV任务失败,任务ID: {}", agvTask.getId(), e);
- }
+ tesAgvService.sendTesAgvTask(
+ taskSubmitUrl,
+ tesAgvService.generateTesAgvTaskJson(agvTask),
+ agvTask
+ );
+
}
}
}
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/controller/AsnController.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/controller/AsnController.java
index da46220..b92dcb5 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/controller/AsnController.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/controller/AsnController.java
@@ -8,7 +8,7 @@ import java.util.Map;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
-import org.cpte.modules.constant.CommonConstant;
+import org.cpte.modules.constant.GeneralConstant;
import org.cpte.modules.serialNumber.AsnSerialNumberRule;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
@@ -92,7 +92,7 @@ public class AsnController {
@PostMapping(value = "/add")
public Result add(@RequestBody AsnPage asnPage) {
Asn asn = new Asn();
- String orderNo = asnSerialNumberRule.generateSerialNumber(CommonConstant.ASN_ORDER_NO);
+ String orderNo = asnSerialNumberRule.generateSerialNumber(GeneralConstant.ASN_ORDER_NO);
asn.setOrderNo(orderNo);
BeanUtils.copyProperties(asnPage, asn);
asnService.saveMain(asn, asnPage.getAsnDetailList());
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/entity/Asn.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/entity/Asn.java
index a9a3ab7..6d86358 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/entity/Asn.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/entity/Asn.java
@@ -111,6 +111,22 @@ public class Asn implements Serializable {
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Schema(description = "订单日期")
private java.util.Date orderDate;
+
+ /**
+ * 返回报文
+ */
+ @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;
+
/**
* 所属部门
*/
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/entity/AsnDetail.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/entity/AsnDetail.java
index aef54e0..cb035fc 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/entity/AsnDetail.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/entity/AsnDetail.java
@@ -65,13 +65,20 @@ public class AsnDetail implements Serializable {
@Schema(description = "容器")
@JsonSerialize(using = ToStringSerializer.class)
private java.lang.Long stockId;
+
/**
- * 库位
+ * 起点库位
*/
- @Excel(name = "库位", width = 15)
- @Schema(description = "库位")
+ @Schema(description = "起点库位")
@JsonSerialize(using = ToStringSerializer.class)
- private java.lang.Long pointId;
+ private java.lang.Long fromPointId;
+ /**
+ * 终点库位
+ */
+ @Schema(description = "终点库位")
+ @JsonSerialize(using = ToStringSerializer.class)
+ private java.lang.Long toPointId;
+
/**
* 行号
*/
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/entity/ReceiveRecord.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/entity/ReceiveRecord.java
index e3372dc..8f96eec 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/entity/ReceiveRecord.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/entity/ReceiveRecord.java
@@ -45,11 +45,18 @@ public class ReceiveRecord implements Serializable {
@JsonSerialize(using = ToStringSerializer.class)
private java.lang.Long stockId;
/**
- * 库位
+ * 起点库位
*/
- @Schema(description = "库位")
+ @Schema(description = "起点库位")
@JsonSerialize(using = ToStringSerializer.class)
- private java.lang.Long pointId;
+ private java.lang.Long fromPointId;
+ /**
+ * 终点库位
+ */
+ @Schema(description = "终点库位")
+ @JsonSerialize(using = ToStringSerializer.class)
+ private java.lang.Long toPointId;
+
/**
* 物料
*/
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/IAsnService.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/IAsnService.java
index 5c5a546..aac4dc7 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/IAsnService.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/IAsnService.java
@@ -1,5 +1,6 @@
package org.cpte.modules.receive.service;
+import org.cpte.modules.base.entity.Stock;
import org.cpte.modules.receive.entity.AsnDetail;
import org.cpte.modules.receive.entity.Asn;
import com.baomidou.mybatisplus.extension.service.IService;
@@ -54,4 +55,12 @@ public interface IAsnService extends IService {
*/
void receiveGoods(Long asnDetailId, String pointCode);
+ /**
+ * 入库任务回传
+ *
+ * @param asn 入库单
+ * @param asnDetail 入库明细
+ * @param stock 容器
+ */
+ void receiveCallback(Asn asn, AsnDetail asnDetail, Stock stock);
}
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/impl/AsnServiceImpl.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/impl/AsnServiceImpl.java
index 877f37b..61c666a 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/impl/AsnServiceImpl.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/impl/AsnServiceImpl.java
@@ -1,13 +1,21 @@
package org.cpte.modules.receive.service.impl;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shiro.SecurityUtils;
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.IPointService;
+import org.cpte.modules.base.service.IStockService;
+import org.cpte.modules.constant.GeneralConstant;
import org.cpte.modules.constant.enums.AsnStatusEnum;
import org.cpte.modules.constant.enums.CommonStatusEnum;
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.receive.entity.Asn;
@@ -18,6 +26,11 @@ import org.cpte.modules.receive.mapper.AsnMapper;
import org.cpte.modules.receive.mapper.ReceiveRecordMapper;
import org.cpte.modules.receive.service.IAsnService;
import org.cpte.modules.utils.BigDecimalUtil;
+import org.jeecg.common.config.TenantContext;
+import org.jeecg.common.system.vo.LoginUser;
+import org.jeecg.common.util.oConvertUtils;
+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;
@@ -40,6 +53,7 @@ import java.util.concurrent.atomic.AtomicInteger;
@Service
@Slf4j
public class AsnServiceImpl extends ServiceImpl implements IAsnService {
+
@Autowired
private StockMapper stockMapper;
@Autowired
@@ -51,6 +65,16 @@ public class AsnServiceImpl extends ServiceImpl implements IAsnS
@Autowired
private ReceiveRecordMapper receiveRecordMapper;
@Autowired
+ private InventoryMapper inventoryMapper;
+ @Autowired
+ private OpenApiMapper openApiMapper;
+ @Autowired
+ private SysDictMapper sysDictMapper;
+ @Autowired
+ private IStockService iStockService;
+ @Autowired
+ private IPointService iPointService;
+ @Autowired
private IInventoryService iInventoryService;
@Autowired
private IInventoryLogService iInventoryLogService;
@@ -58,13 +82,16 @@ public class AsnServiceImpl extends ServiceImpl implements IAsnS
@Override
@Transactional(rollbackFor = Exception.class)
public void saveMain(Asn asn, List asnDetailList) {
+ LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+ asn.setTenantId(Long.parseLong(sysUser.getRelTenantIds()));
+ asn.setSysOrgCode(sysUser.getOrgCode());
asnMapper.insert(asn);
if (asnDetailList == null || asnDetailList.isEmpty()) {
throw new RuntimeException("请新增入库明细");
}
- if(asnDetailList.size()>1){
+ if (asnDetailList.size() > 1) {
throw new RuntimeException("入库明细只允许新增一条");
}
@@ -74,6 +101,8 @@ public class AsnServiceImpl extends ServiceImpl implements IAsnS
entity.setLineNo(lineNoCounter.getAndIncrement());
}
entity.setAsnId(asn.getId());
+ asn.setTenantId(Long.parseLong(sysUser.getRelTenantIds()));
+ asn.setSysOrgCode(sysUser.getOrgCode());
asnDetailMapper.insert(entity);
}
//刷新入库单
@@ -124,7 +153,7 @@ public class AsnServiceImpl extends ServiceImpl implements IAsnS
throw new RuntimeException("请新增入库明细");
}
- if(asnDetailList.size()>1){
+ if (asnDetailList.size() > 1) {
throw new RuntimeException("入库明细只允许新增一条");
}
@@ -183,6 +212,11 @@ public class AsnServiceImpl extends ServiceImpl implements IAsnS
throw new RuntimeException("未匹配到入库任务【" + asnDetailId + "】");
}
+ //验证容器是否入库
+ if (inventoryMapper.queryByStockId(asnDetail.getStockId()) != null) {
+ throw new RuntimeException("【" + asnDetail.getStockId() + "】容器已入库");
+ }
+
//入库单
Asn asn = this.getById(asnDetail.getAsnId());
@@ -214,10 +248,90 @@ public class AsnServiceImpl extends ServiceImpl implements IAsnS
refreshAsn(asn, asnDetailMapper.selectByMainId(asn.getId()));
//更新容器状态和位置
- updateStockPoint(stock, dstPoint);
+ iStockService.bindStock(stock, dstPoint);
+ iPointService.bindPoint(dstPoint);
//添加库存日志
- iInventoryLogService.addInboundInventoryLog(inventory, asnDetail.getPointId(), receivedQty, asn.getOrderNo(), asnDetail.getId(), asnDetail.getDescription());
+ iInventoryLogService.addInboundInventoryLog(inventory, asnDetail.getToPointId(), receivedQty, asn.getOrderNo(), asnDetail.getId(), asnDetail.getDescription());
+
+ //回传
+ receiveCallback(asn, asnDetail, stock);
+ }
+
+
+ /**
+ * 入库任务回传JSON
+ */
+ private String receiveCallbackJson(Asn asn, AsnDetail asnDetail, Stock stock) {
+ JSONObject jsonObject = new JSONObject(true);
+ jsonObject.put("No", asn.getNo());
+ jsonObject.put("OrderNo", asn.getThirdOrderNo());
+ jsonObject.put("State", 5);
+ jsonObject.put("LineNo", asnDetail.getLineNo());
+ jsonObject.put("Lpn", stock.getStockCode());
+ jsonObject.put("Qty", asnDetail.getOrderQty());
+ jsonObject.put("Project", asnDetail.getProject());
+ jsonObject.put("TaskNo", asnDetail.getTaskNo());
+ jsonObject.put("LotAtt04", asnDetail.getPropC1());
+ jsonObject.put("LotAtt010", asnDetail.getPropC3());
+ return jsonObject.toJSONString();
+ }
+
+ @Override
+ public void receiveCallback(Asn asn, AsnDetail asnDetail, Stock stock) {
+ String url = openApiMapper.getRequestUrl(GeneralConstant.INBOUND_CALLBACK);
+ String json = receiveCallbackJson(asn, asnDetail, stock);
+
+ log.info("入库回传请求报文:{}", json);
+ // 检查接口开关, 未开启则返回
+ if (sysDictMapper.queryByDictCode(GeneralConstant.OPEN_FLAG) == null) {
+ updateAsnDetailResponse(asn, "接口未开启");
+ return;
+ }
+
+ Boolean Success = null;
+ String Message = null;
+ try {
+ //String result = HttpPostUtil.sendPostReq(url, json);
+ String result = "{\n" +
+ " \"Success\": false,\n" +
+ " \"Message\": \"入库回传失败\"\n" +
+ "}";
+ if (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);
+ }
+ updateAsnDetailResponse(asn, Message);
+ } catch (Exception e) {
+ updateAsnDetailResponse(asn, e.getMessage());
+ }
+ }
+
+ /**
+ * 更新任务状态
+ *
+ * @param asn 入库单
+ * @param message 信息
+ */
+ private void updateAsnDetailResponse(Asn asn, String message) {
+ if (asn != null) {
+ asn.setResMessage(message);
+ asn.setResTime(new Date());
+ asnMapper.updateById(asn);
+ }
}
/**
@@ -227,7 +341,8 @@ public class AsnServiceImpl extends ServiceImpl implements IAsnS
ReceiveRecord receiveRecord = ReceiveRecord.builder()
.asnDetailId(asnDetail.getId())
.stockId(asnDetail.getStockId())
- .pointId(dstPointId)
+ .fromPointId(asnDetail.getToPointId())
+ .toPointId(dstPointId)
.itemId(asnDetail.getItemId())
.receivedQty(receivedQty)
.propC1(asnDetail.getPropC1())
@@ -244,19 +359,4 @@ public class AsnServiceImpl extends ServiceImpl implements IAsnS
return receiveRecord;
}
-
- /**
- * 更新容器位置和状态
- */
- private void updateStockPoint(Stock stock, Point point) {
- stock.setPointId(point.getId());
- stock.setStatus(CommonStatusEnum.USED.getValue());
- stockMapper.updateById(stock);
-
- // 更新库位状态为占用
- point.setStatus(CommonStatusEnum.USED.getValue()); // 占用状态
- pointMapper.updateById(point);
- }
-
-
}
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/controller/SaiWmsController.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/controller/SaiWmsController.java
index 1cb7a6a..7768540 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/controller/SaiWmsController.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/controller/SaiWmsController.java
@@ -33,7 +33,6 @@ public class SaiWmsController {
@AutoLog(value = "入库任务下发")
@Operation(summary = "赛意WMS-入库任务下发")
@PostMapping(value = "/inBound/inBoundTask")
- @IgnoreAuth
public Result inBoundTask(@RequestBody @Valid InboundRequest inboundRequest) {
iSaiWmsService.inBoundTask(inboundRequest);
return Result.OK("操作成功!");
@@ -47,7 +46,6 @@ public class SaiWmsController {
@AutoLog(value = "出库任务下发")
@Operation(summary = "赛意WMS-出库任务下发")
@PostMapping(value = "/outBound/outBoundTask")
- @IgnoreAuth
public Result outBoundTask(@RequestBody @Valid OutboundRequest outboundRequest) {
iSaiWmsService.outBoundTask(outboundRequest);
return Result.OK("操作成功!");
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/request/InboundRequest.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/request/InboundRequest.java
index 716cd37..7dc3c9f 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/request/InboundRequest.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/request/InboundRequest.java
@@ -1,10 +1,12 @@
package org.cpte.modules.saiWms.request;
import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
+import org.jeecgframework.poi.excel.annotation.Excel;
import java.math.BigDecimal;
import java.util.List;
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/ISaiWmsService.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/ISaiWmsService.java
index 39307df..6f97bdf 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/ISaiWmsService.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/ISaiWmsService.java
@@ -1,5 +1,8 @@
package org.cpte.modules.saiWms.service;
+import org.cpte.modules.base.entity.Stock;
+import org.cpte.modules.receive.entity.Asn;
+import org.cpte.modules.receive.entity.AsnDetail;
import org.cpte.modules.saiWms.request.InboundRequest;
import org.cpte.modules.saiWms.request.OutboundRequest;
@@ -17,4 +20,6 @@ public interface ISaiWmsService {
* @param outboundRequest 请求参数
*/
void outBoundTask(OutboundRequest outboundRequest);
+
+
}
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/impl/ISaiWmsServiceImpl.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/impl/ISaiWmsServiceImpl.java
index f32861b..0fa29f5 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/impl/ISaiWmsServiceImpl.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/impl/ISaiWmsServiceImpl.java
@@ -5,11 +5,10 @@ import org.cpte.modules.agvTask.service.IAgvTaskService;
import org.cpte.modules.base.entity.Item;
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.service.IItemService;
import org.cpte.modules.base.service.IPointService;
import org.cpte.modules.base.service.IStockService;
-import org.cpte.modules.constant.CommonConstant;
+import org.cpte.modules.constant.GeneralConstant;
import org.cpte.modules.constant.enums.*;
import org.cpte.modules.receive.entity.Asn;
import org.cpte.modules.receive.entity.AsnDetail;
@@ -24,7 +23,6 @@ import org.cpte.modules.shipping.entity.Pick;
import org.cpte.modules.shipping.entity.PickDetail;
import org.cpte.modules.shipping.mapper.PickMapper;
import org.cpte.modules.shipping.service.IPickService;
-import org.jeecg.common.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -36,10 +34,6 @@ import java.util.*;
@Slf4j
public class ISaiWmsServiceImpl implements ISaiWmsService {
-
- @Autowired
- private PointMapper pointMapper;
-
@Autowired
private AsnMapper asnMapper;
@@ -61,7 +55,6 @@ public class ISaiWmsServiceImpl implements ISaiWmsService {
@Autowired
private IPickService pickService;
-
@Autowired
private IAgvTaskService iAgvTaskService;
@@ -71,8 +64,6 @@ public class ISaiWmsServiceImpl implements ISaiWmsService {
@Autowired
private PickSerialNumberRule pickSerialNumberRule;
- @Autowired
- private RedisUtil redisUtil;
@Override
@Transactional(rollbackFor = Exception.class)
@@ -99,25 +90,22 @@ public class ISaiWmsServiceImpl implements ISaiWmsService {
Stock stock = iStockService.validateStock(stockCode);
//获取输送线工作台点位,均衡分配点位任务-轮询方式
- List dstPointList = pointMapper.queryPoints(null, CommonStatusEnum.FREE.getValue(), AreaTypeEnum.RK_DOCK.getValue());
- if (dstPointList.isEmpty()) {
- throw new RuntimeException("【" + AreaTypeEnum.RK_DOCK.getDesc() + "】" + "无空闲库位");
- }
- String key = CommonConstant.RK_DOCK_TASK_INDEX;
- long currentIndex = redisUtil.incr(key, 1) % dstPointList.size();
- Point dstPoint = dstPointList.get((int) currentIndex);
+ Point dstPoint = iPointService.getWorkStationPoint(CommonStatusEnum.FREE.getValue(), AreaTypeEnum.RK_DOCK.getValue(), GeneralConstant.RK_DOCK_TASK_INDEX);
// 创建入库单和明细
Asn createAsn = buildAsn(inboundRequest);
- AsnDetail asnDetail = buildAsnDetail(detail, srcPoint, item, stock);
+ AsnDetail asnDetail = buildAsnDetail(detail, srcPoint,dstPoint, item, stock);
// 保存入库单和入库明细
asnService.saveMain(createAsn, Collections.singletonList(asnDetail));
+ //绑定容器和起点
+ iStockService.bindStock(stock, srcPoint);
+
//成品入库需要生成AGV
if (AsnOrderTypeEnum.PRODUCT.getValue().equals(createAsn.getOrderType())) {
//创建AGV任务
- iAgvTaskService.createAgvTask(asnDetail.getId(), AgvStatusEnum.CREATED.getValue(), stock.getStockCode(), srcPoint.getPointCode(), dstPoint.getPointCode(), null, BusinessTypeEnum.INBOUND.getValue(), AgvVendorEnum.HIK.getValue());
+ iAgvTaskService.createAgvTask(asnDetail.getId(), stock.getStockCode(), srcPoint.getPointCode(), dstPoint.getPointCode(), null, BusinessTypeEnum.INBOUND.getValue(), AgvVendorEnum.HIK.getValue());
}
}
@@ -156,7 +144,7 @@ public class ISaiWmsServiceImpl implements ISaiWmsService {
* 构建入库单
*/
private Asn buildAsn(InboundRequest inboundRequest) {
- String orderNo = asnSerialNumberRule.generateSerialNumber(CommonConstant.ASN_ORDER_NO);
+ String orderNo = asnSerialNumberRule.generateSerialNumber(GeneralConstant.ASN_ORDER_NO);
return Asn.builder()
.orderNo(orderNo)
.thirdOrderNo(inboundRequest.getOrderNo())
@@ -166,16 +154,13 @@ public class ISaiWmsServiceImpl implements ISaiWmsService {
.orderType(inboundRequest.getType())
.status(AsnStatusEnum.CREATED.getValue())
.orderDate(new Date())
- .sysOrgCode("A05")
- .tenantId(1000L)
- .createBy("赛意")
.build();
}
/**
* 构建入库明细
*/
- private AsnDetail buildAsnDetail(InboundRequest.InboundDetail detail, Point srcPoint, Item item, Stock stock) {
+ private AsnDetail buildAsnDetail(InboundRequest.InboundDetail detail, Point srcPoint, Point dstPoint, Item item, Stock stock) {
// 由于明细只有一条,直接构建单个明细对象
return AsnDetail.builder()
.lineNo(Integer.parseInt(detail.getLineNo()))
@@ -184,7 +169,8 @@ public class ISaiWmsServiceImpl implements ISaiWmsService {
.orderQty(detail.getQty())
.receivedQty(BigDecimal.ZERO)
.stockId(stock.getId())
- .pointId(srcPoint.getId())
+ .fromPointId(srcPoint.getId())
+ .toPointId(dstPoint.getId())
.status(AsnStatusEnum.CREATED.getValue())
.project(detail.getProject())
.taskNo(detail.getTaskNo())
@@ -198,7 +184,7 @@ public class ISaiWmsServiceImpl implements ISaiWmsService {
* 构建出库单
*/
private Pick buildPick(OutboundRequest outboundRequest) {
- String orderNo = pickSerialNumberRule.generateSerialNumber(CommonConstant.PICK_ORDER_NO);
+ String orderNo = pickSerialNumberRule.generateSerialNumber(GeneralConstant.PICK_ORDER_NO);
return Pick.builder()
.orderNo(orderNo)
.thirdOrderNo(outboundRequest.getOrderNo())
@@ -208,9 +194,6 @@ public class ISaiWmsServiceImpl implements ISaiWmsService {
.orderType(outboundRequest.getType())
.status(PickStatusEnum.CREATED.getValue())
.orderDate(new Date())
- .sysOrgCode("A05")
- .tenantId(1000L)
- .createBy("赛意")
.build();
}
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/controller/PickController.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/controller/PickController.java
index 852d0c0..4cf2599 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/controller/PickController.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/controller/PickController.java
@@ -9,8 +9,15 @@ import java.util.Map;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
-import org.cpte.modules.constant.CommonConstant;
+import jakarta.validation.Valid;
+import org.cpte.modules.constant.GeneralConstant;
+import org.cpte.modules.saiWms.request.InboundRequest;
import org.cpte.modules.serialNumber.PickSerialNumberRule;
+import org.cpte.modules.shipping.entity.Task;
+import org.cpte.modules.shipping.mapper.PickMapper;
+import org.cpte.modules.shipping.mapper.TaskMapper;
+import org.cpte.modules.shipping.service.ITaskService;
+import org.jeecg.config.shiro.IgnoreAuth;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
@@ -53,11 +60,17 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
@RequestMapping("/shipping/pick")
@Slf4j
public class PickController {
+ @Autowired
+ private PickMapper pickMapper;
+ @Autowired
+ private TaskMapper taskMapper;
@Autowired
private IPickService pickService;
@Autowired
private IPickDetailService pickDetailService;
@Autowired
+ private ITaskService taskService;
+ @Autowired
private PickSerialNumberRule pickSerialNumberRule;
/**
@@ -94,7 +107,7 @@ public class PickController {
@PostMapping(value = "/add")
public Result add(@RequestBody PickPage pickPage) {
Pick pick = new Pick();
- String orderNo = pickSerialNumberRule.generateSerialNumber(CommonConstant.PICK_ORDER_NO);
+ String orderNo = pickSerialNumberRule.generateSerialNumber(GeneralConstant.PICK_ORDER_NO);
pick.setOrderNo(orderNo);
BeanUtils.copyProperties(pickPage, pick);
pickService.saveMain(pick, pickPage.getPickDetailList());
@@ -267,4 +280,19 @@ public class PickController {
return Result.OK("文件导入失败!");
}
+ /**
+ * 出库分配
+ */
+ @AutoLog(value = "出库分配")
+ @Operation(summary = "出库分配")
+ @PostMapping(value = "/allocatedPick")
+ @IgnoreAuth
+ public Result allocatedPick() {
+ List pickList = pickMapper.queryUnallocatedPick();
+ pickService.allocatePick2(pickList);
+ List taskList = taskMapper.queryUnallocatedTask();
+ taskService.generateAgvTask(taskList);
+ return Result.OK("操作成功!");
+ }
+
}
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/entity/Task.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/entity/Task.java
new file mode 100644
index 0000000..d8b27b2
--- /dev/null
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/entity/Task.java
@@ -0,0 +1,197 @@
+package org.cpte.modules.shipping.entity;
+
+import java.io.Serializable;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import lombok.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.jeecgframework.poi.excel.annotation.Excel;
+import io.swagger.v3.oas.annotations.media.Schema;
+
+/**
+ * @Description: 任务
+ * @author: cpte
+ * @Date: 2025-11-17
+ * @Version: V1.0
+ */
+@TableName("data_task")
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+@Schema(description = "任务")
+public class Task implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * id
+ */
+ @TableId(type = IdType.ASSIGN_ID)
+ @Schema(description = "id")
+ @JsonSerialize(using = ToStringSerializer.class)
+ private java.lang.Long id;
+ /**
+ * 任务编号
+ */
+ @Excel(name = "任务编号", width = 15)
+ @Schema(description = "任务编号")
+ private java.lang.String taskNo;
+ /**
+ * 商品ID
+ */
+ @Excel(name = "商品ID", width = 15)
+ @Schema(description = "商品ID")
+ @JsonSerialize(using = ToStringSerializer.class)
+ private java.lang.Long itemId;
+
+ @Schema(description = "商品")
+ private java.lang.String itemCode;
+
+ /**
+ * 原库位
+ */
+ @Excel(name = "原库位", width = 15)
+ @Schema(description = "原库位")
+ @JsonSerialize(using = ToStringSerializer.class)
+ private java.lang.Long fromPointId;
+
+ @Excel(name = "原库位", width = 15)
+ private java.lang.String fromPointCode;
+
+ /**
+ * 目标库位
+ */
+ @Excel(name = "目标库位", width = 15)
+ @Schema(description = "目标库位")
+ @JsonSerialize(using = ToStringSerializer.class)
+ private java.lang.Long toPointId;
+
+ @Schema(description = "目标库位")
+ private java.lang.String toPointCode;
+ /**
+ * 容器
+ */
+ @Excel(name = "容器", width = 15)
+ @Schema(description = "容器")
+ @JsonSerialize(using = ToStringSerializer.class)
+ private java.lang.Long stockId;
+
+ @Schema(description = "容器")
+ private java.lang.String stockCode;
+ /**
+ * 出库单ID
+ */
+ @Excel(name = "出库单ID", width = 15)
+ @Schema(description = "出库单ID")
+ @JsonSerialize(using = ToStringSerializer.class)
+ private java.lang.Long pickId;
+ /**
+ * 出库明细ID
+ */
+ @Excel(name = "出库明细ID", width = 15)
+ @Schema(description = "出库明细ID")
+ @JsonSerialize(using = ToStringSerializer.class)
+ private java.lang.Long pickDetailId;
+ /**
+ * 库存ID
+ */
+ @Excel(name = "库存ID", width = 15)
+ @Schema(description = "库存ID")
+ @JsonSerialize(using = ToStringSerializer.class)
+ private java.lang.Long inventoryId;
+
+ /**
+ * agvID
+ */
+ @Excel(name = "agvID", width = 15)
+ @Schema(description = "agvID")
+ private java.lang.Long agvTaskId;
+
+ /**
+ * 计划数量
+ */
+ @Excel(name = "计划数量", width = 15)
+ @Schema(description = "计划数量")
+ private java.math.BigDecimal planQty;
+ /**
+ * 已完成数量
+ */
+ @Excel(name = "已完成数量", width = 15)
+ @Schema(description = "已完成数量")
+ private java.math.BigDecimal moveQty;
+ /**
+ * 任务类型:1=拣货任务
+ */
+ @Excel(name = "任务类型", width = 15)
+ @Schema(description = "任务类型")
+ private java.lang.Integer taskType;
+ /**
+ * 任务状态:1=已创建,2=已完成,3=已取消
+ */
+ @Excel(name = "任务状态", width = 15)
+ @Schema(description = "任务状态")
+ private java.lang.Integer taskStatus;
+
+ /**
+ * 是否整托0整托,1拆托
+ */
+ @Excel(name = "是否整托", width = 15)
+ @Schema(description = "是否整托")
+ private java.lang.Integer izAll;
+ /**
+ * 开始时间
+ */
+ @Excel(name = "开始时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
+ @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 startTime;
+ /**
+ * 完成时间
+ */
+ @Excel(name = "完成时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
+ @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 completeTime;
+ /**
+ * 所属部门
+ */
+ @Schema(description = "所属部门")
+ private java.lang.String sysOrgCode;
+ /**
+ * 仓库ID
+ */
+ @Excel(name = "仓库ID", width = 15)
+ @Schema(description = "仓库ID")
+ private java.lang.Long tenantId;
+ /**
+ * 创建人
+ */
+ @Schema(description = "创建人")
+ private java.lang.String createBy;
+ /**
+ * 创建日期
+ */
+ @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 createTime;
+ /**
+ * 更新人
+ */
+ @Schema(description = "更新人")
+ private java.lang.String updateBy;
+ /**
+ * 更新日期
+ */
+ @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 updateTime;
+}
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/mapper/PickDetailMapper.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/mapper/PickDetailMapper.java
index 00f59a4..3d57358 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/mapper/PickDetailMapper.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/mapper/PickDetailMapper.java
@@ -31,10 +31,13 @@ public interface PickDetailMapper extends BaseMapper {
*/
public List selectByMainId(@Param("mainId") Long mainId);
- @Select("select * from data_pick_detail where status = 1 " +
- "union all " +
- "select * from data_pick_detail where status = 2 ")
- List queryUnallocatedPickDetail();
+ /**
+ * 通过出库单id集合查询出库明细
+ *
+ * @param pickIds 出库单id集合
+ * @return List
+ */
+ List queryByPickIds(@Param("pickIds") List pickIds);
@Select("select MAX(line_no) from data_pick_detail where pick_id = #{pickId} ")
Integer queryMaxLineNoByPickId(@Param("pickId") Long pickId);
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/mapper/PickMapper.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/mapper/PickMapper.java
index 3c8b9a0..f9803da 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/mapper/PickMapper.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/mapper/PickMapper.java
@@ -5,6 +5,9 @@ import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.cpte.modules.shipping.entity.Pick;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.cpte.modules.shipping.entity.PickDetail;
+
+import java.util.List;
/**
* @Description: 出库单
@@ -23,4 +26,14 @@ public interface PickMapper extends BaseMapper {
@Select("select * from data_pick where no = #{no} for update ")
Pick queryByNo(@Param("no") String no);
+ /**
+ * 查询未分配的出库单:已创建或者部分分配
+ *
+ * @return List
+ */
+ @Select("select id from data_pick where status = 1 " +
+ "union all " +
+ "select id from data_pick where status = 2 ")
+ List queryUnallocatedPick();
+
}
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/mapper/TaskMapper.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/mapper/TaskMapper.java
new file mode 100644
index 0000000..5a38f1f
--- /dev/null
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/mapper/TaskMapper.java
@@ -0,0 +1,25 @@
+package org.cpte.modules.shipping.mapper;
+
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import org.cpte.modules.shipping.entity.Pick;
+import org.cpte.modules.shipping.entity.Task;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+import java.util.List;
+
+/**
+ * @Description: 任务
+ * @author: cpte
+ * @Date: 2025-11-17
+ * @Version: V1.0
+ */
+public interface TaskMapper extends BaseMapper {
+ /**
+ * 查询未分配的AGV的Task任务
+ *
+ * @return List
+ */
+ @Select("select * from data_task where agv_task_id is null order by create_time")
+ List queryUnallocatedTask();
+}
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/mapper/xml/PickDetailMapper.xml b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/mapper/xml/PickDetailMapper.xml
index 087918b..1f4e42c 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/mapper/xml/PickDetailMapper.xml
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/mapper/xml/PickDetailMapper.xml
@@ -15,4 +15,14 @@
WHERE
pick_id = #{mainId}
+
+
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/mapper/xml/TaskMapper.xml b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/mapper/xml/TaskMapper.xml
new file mode 100644
index 0000000..d97e630
--- /dev/null
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/mapper/xml/TaskMapper.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/IPickService.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/IPickService.java
index c663893..e638970 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/IPickService.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/IPickService.java
@@ -47,17 +47,17 @@ public interface IPickService extends IService {
public void delBatchMain(Collection extends Serializable> idList);
/**
- * 分配出库单明细
+ * 分配出库单
*
- * @param pickDetails 出库单明细集合
+ * @param pickIds 出库单集合
*/
- List allocatePickDetail(List pickDetails);
+ List allocatePick(List pickIds);
/**
- * 分配出库单明细
+ * 分配出库单
*
- * @param pickDetails 出库单明细集合
+ * @param pickIds 出库单集合
*/
- List allocatePickDetail2(List pickDetails);
+ List allocatePick2(List pickIds);
}
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/ITaskService.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/ITaskService.java
new file mode 100644
index 0000000..85fcd9a
--- /dev/null
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/ITaskService.java
@@ -0,0 +1,60 @@
+package org.cpte.modules.shipping.service;
+
+import org.cpte.modules.base.entity.Item;
+import org.cpte.modules.base.entity.Point;
+import org.cpte.modules.base.entity.Stock;
+import org.cpte.modules.shipping.entity.Task;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * @Description: 任务
+ * @author: cpte
+ * @Date: 2025-11-17
+ * @Version: V1.0
+ */
+public interface ITaskService extends IService {
+ /**
+ * 创建任务
+ *
+ * @param taskNo 任务编号
+ * @param taskType 任务类型
+ * @param item 物料
+ * @param fromPoint 原点位
+ * @param toPoint 目标点位
+ * @param stock 容器
+ * @param pickId 出库单ID
+ * @param pickDetailId 出库单明细ID
+ * @param inventoryId 库存ID
+ * @param planQty 计划数量
+ * @param izAll 是否整托
+ * @return Task
+ */
+ Task createTask(String taskNo, Integer taskType, Item item, Point fromPoint, Point toPoint, Stock stock, Long pickId, Long pickDetailId, Long inventoryId, BigDecimal planQty, Integer izAll);
+
+ /**
+ * 构建任务
+ *
+ * @param taskNo 任务编号
+ * @param taskType 任务类型
+ * @param item 物料
+ * @param fromPoint 原点位
+ * @param toPoint 目标点位
+ * @param stock 容器
+ * @param pickId 出库单ID
+ * @param pickDetailId 出库单明细ID
+ * @param inventoryId 库存ID
+ * @param planQty 计划数量
+ * @param izAll 是否整托
+ * @return Task
+ */
+ Task bulidTask(String taskNo, Integer taskType, Item item, Point fromPoint, Point toPoint, Stock stock, Long pickId, Long pickDetailId, Long inventoryId, BigDecimal planQty, Integer izAll);
+
+ /**
+ * 根据Task集合生成AGV出库任务
+ */
+ void generateAgvTask(List taskList);
+
+}
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/impl/PickServiceImpl.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/impl/PickServiceImpl.java
index eefdfbb..2ce049e 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/impl/PickServiceImpl.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/impl/PickServiceImpl.java
@@ -2,28 +2,31 @@ package org.cpte.modules.shipping.service.impl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
+import org.apache.shiro.SecurityUtils;
import org.apache.shiro.lang.util.StringUtils;
+import org.cpte.modules.constant.GeneralConstant;
import org.cpte.modules.base.entity.Item;
import org.cpte.modules.base.entity.Point;
import org.cpte.modules.base.entity.Stock;
import org.cpte.modules.base.service.IItemService;
import org.cpte.modules.base.service.IPointService;
import org.cpte.modules.base.service.IStockService;
-import org.cpte.modules.constant.enums.AsnStatusEnum;
-import org.cpte.modules.constant.enums.InventoryStatusEnum;
-import org.cpte.modules.constant.enums.PickStatusEnum;
+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.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.BigDecimalUtil;
import org.jeecg.common.constant.CommonConstant;
+import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.base.service.BaseCommonService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -59,9 +62,13 @@ public class PickServiceImpl extends ServiceImpl implements IP
@Autowired
private IPointService iPointService;
@Autowired
+ private ITaskService iTaskService;
+ @Autowired
private IInventoryLogService iInventoryLogService;
@Autowired
private BaseCommonService baseCommonService;
+ @Autowired
+ private BatchUtils batchUtils;
/**
* 获取出库单Map
@@ -82,6 +89,9 @@ public class PickServiceImpl extends ServiceImpl implements IP
@Override
@Transactional(rollbackFor = Exception.class)
public void saveMain(Pick pick, List pickDetailList) {
+ LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+ pick.setTenantId(Long.parseLong(sysUser.getRelTenantIds()));
+ pick.setSysOrgCode(sysUser.getOrgCode());
pickMapper.insert(pick);
if (pickDetailList == null || pickDetailList.isEmpty()) {
@@ -97,6 +107,8 @@ public class PickServiceImpl extends ServiceImpl implements IP
entity.setLineNo(lineNoCounter.getAndIncrement());
}
entity.setPickId(pick.getId());
+ entity.setTenantId(Long.parseLong(sysUser.getRelTenantIds()));
+ entity.setSysOrgCode(sysUser.getOrgCode());
pickDetailMapper.insert(entity);
}
//刷新出库单
@@ -231,13 +243,15 @@ public class PickServiceImpl extends ServiceImpl implements IP
@Override
@Transactional(rollbackFor = Exception.class)
- public List allocatePickDetail(List pickDetails) {
+ public List allocatePick(List pickIds) {
List errorMsgList = new ArrayList<>();
//查询出库单
- List pickIds = pickDetails.stream().map(PickDetail::getPickId).distinct().toList();
Map pickMap = queryByPickIdsToMap(pickIds);
+ //查询出库单明细
+ List pickDetails = pickDetailMapper.queryByPickIds(pickIds);
+
//获取不为null、空字符的批次号
List propC1List = pickDetails.stream().map(PickDetail::getPropC1).filter(Objects::nonNull).filter(e -> !e.isEmpty()).distinct().toList();
@@ -378,15 +392,17 @@ public class PickServiceImpl extends ServiceImpl implements IP
@Override
@Transactional(rollbackFor = Exception.class)
- public List allocatePickDetail2(List pickDetails) {
+ public List allocatePick2(List pickIds) {
// 错误信息去重(LinkedHashSet保证顺序和唯一)
Set errorMsgSet = new LinkedHashSet<>();
// -------------------------- 1. 查询关联数据(批量查询,减少DB交互)--------------------------
- //获取出库单
- List pickIds = pickDetails.stream().map(PickDetail::getPickId).distinct().toList();
+ //查询出库单
Map pickMap = queryByPickIdsToMap(pickIds);
+ //查询出库单明细
+ List pickDetails = pickDetailMapper.queryByPickIds(pickIds);
+
//获取物料
List itemIds = pickDetails.stream().map(PickDetail::getItemId).distinct().toList();
Map itemMap = iItemService.queryByItemIdsToMap(itemIds);
@@ -426,6 +442,7 @@ public class PickServiceImpl extends ServiceImpl implements IP
// -------------------------- 3. 创建更新列表---------------------------
List updateToInventory = new ArrayList<>();
List updateToPickDetail = new ArrayList<>();
+ List createToTask = new ArrayList<>();
// -------------------------- 4. 循环分配库存 -------------------
for (PickDetail pickDetail : pickDetails) {
@@ -451,6 +468,11 @@ public class PickServiceImpl extends ServiceImpl implements IP
item.getItemCode(), item.getId(), pickDetail.getPropC1(), pickDetail.getPropC3(), pick.getWhCode()));
continue;
}
+
+ //获取输送线工作台点位,均衡分配点位任务-轮询方式
+ Point toPoint = iPointService.getWorkStationPoint(CommonStatusEnum.FREE.getValue(), AreaTypeEnum.CK_DOCK.getValue(), GeneralConstant.CK_DOCK_TASK_INDEX);
+ //记录当前容器
+ Long currStockId = 0L;
for (Inventory inventory : matchedInventories) {
if (unAllocatedQty.compareTo(BigDecimal.ZERO) <= 0) {
break;
@@ -475,13 +497,23 @@ public class PickServiceImpl extends ServiceImpl implements IP
//容器
Stock stock = stockMap.get(inventory.getStockId());
//库位
- Point point = pointMap.get(inventory.getPointId());
- String tuoType = inventory.getQuantity().compareTo(allocateQty) == 0 ? "整托" : "拆托";
- log.info("生成拣货任务: 容器:{} - 库位:{} - 类型:{}- 分配数量:{}", stock.getStockCode(), point.getPointCode(), tuoType, allocateQty);
+ Point fromPoint = pointMap.get(inventory.getPointId());
+ //是否整托:0整托、1拆托
+ Integer izAll = inventory.getQuantity().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);
+ }
+ //构建拣货任务存入集合批量新增
+ Task task = iTaskService.bulidTask(pick.getNo() + "_" + pickDetail.getLineNo(), TaskTypeEnum.PICK.getValue(), item, fromPoint, toPoint, stock, pick.getId(), pickDetail.getId(), inventory.getId(), allocateQty, izAll);
+ createToTask.add(task);
+ log.info("生成拣货任务:{}- 容器:{} - 库位:{} - 类型:{}- 分配数量:{}", task.getTaskNo(), stock.getStockCode(), fromPoint.getPointCode(), izAll, allocateQty);
//分配库存日志
iInventoryLogService.addAllocInventoryLog(inventory, allocateQty, pick.getOrderNo(), pickDetail.getId(), pickDetail.getDescription());
//更新未分配数量
unAllocatedQty = BigDecimalUtil.subtract(unAllocatedQty, allocateQty, 0);
+ //更新当前容器
+ currStockId = stock.getId();
}
//分配后仍有缺货,记录错误
if (unAllocatedQty.compareTo(BigDecimal.ZERO) > 0) {
@@ -494,10 +526,13 @@ public class PickServiceImpl extends ServiceImpl implements IP
// -------------------------- 5. 批量更新(减少DB交互)--------------------------
if (CollectionUtils.isNotEmpty(updateToInventory)) {
- inventoryMapper.updateById(updateToInventory);
+ batchUtils.updateBatchInventory(updateToInventory);
}
if (CollectionUtils.isNotEmpty(updateToPickDetail)) {
- pickDetailMapper.updateById(updateToPickDetail);
+ batchUtils.updateBatchPickDetail(updateToPickDetail);
+ }
+ if (CollectionUtils.isNotEmpty(createToTask)) {
+ batchUtils.saveBatchTask(createToTask);
}
// -------------------------- 6. 刷新出库单状态 --------------------------
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/impl/TaskServiceImpl.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/impl/TaskServiceImpl.java
new file mode 100644
index 0000000..e331480
--- /dev/null
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/impl/TaskServiceImpl.java
@@ -0,0 +1,156 @@
+package org.cpte.modules.shipping.service.impl;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.shiro.SecurityUtils;
+import org.cpte.modules.agvTask.entity.AgvTask;
+import org.cpte.modules.agvTask.service.IAgvTaskService;
+import org.cpte.modules.base.entity.Item;
+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.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.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;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @Description: 任务
+ * @author: cpte
+ * @Date: 2025-11-17
+ * @Version: V1.0
+ */
+@Service
+public class TaskServiceImpl extends ServiceImpl implements ITaskService {
+
+ @Autowired
+ private IAgvTaskService agvTaskService;
+
+ @Autowired
+ private BatchUtils batchUtils;
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public Task createTask(String taskNo, Integer taskType, Item item, Point fromPoint, Point toPoint, Stock stock, Long pickId, Long pickDetailId, Long inventoryId, BigDecimal planQty, Integer izAll) {
+ LoginUser sysUser = null;
+ try {
+ sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+ } catch (Exception e) {
+ log.error("获取登录用户信息失败");
+ }
+ Task task = Task.builder()
+ .taskNo(taskNo)
+ .itemId(item.getId())
+ .itemCode(item.getItemCode())
+ .fromPointId(fromPoint.getId())
+ .fromPointCode(fromPoint.getPointCode())
+ .toPointId(toPoint.getId())
+ .toPointCode(toPoint.getPointCode())
+ .stockId(stock.getId())
+ .stockCode(stock.getStockCode())
+ .pickId(pickId)
+ .pickDetailId(pickDetailId)
+ .inventoryId(inventoryId)
+ .planQty(planQty)
+ .moveQty(BigDecimal.ZERO)
+ .taskStatus(1)
+ .taskType(taskType)
+ .izAll(izAll)
+ .sysOrgCode(sysUser == null ? "A05" : sysUser.getOrgCode())
+ .tenantId(sysUser == null ? 1000L : Long.parseLong(sysUser.getRelTenantIds()))
+ .createBy(sysUser == null ? "system" : sysUser.getUsername())
+ .createTime(new Date())
+ .build();
+ this.save(task);
+ return task;
+ }
+
+ @Override
+ public Task bulidTask(String taskNo, Integer taskType, Item item, Point fromPoint, Point toPoint, Stock stock, Long pickId, Long pickDetailId, Long inventoryId, BigDecimal planQty, Integer izAll) {
+ LoginUser sysUser = null;
+ try {
+ sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+ } catch (Exception e) {
+ log.error("获取登录用户信息失败");
+ }
+ return Task.builder()
+ .taskNo(taskNo)
+ .itemId(item.getId())
+ .itemCode(item.getItemCode())
+ .fromPointId(fromPoint.getId())
+ .fromPointCode(fromPoint.getPointCode())
+ .toPointId(toPoint.getId())
+ .toPointCode(toPoint.getPointCode())
+ .stockId(stock.getId())
+ .stockCode(stock.getStockCode())
+ .pickId(pickId)
+ .pickDetailId(pickDetailId)
+ .inventoryId(inventoryId)
+ .planQty(planQty)
+ .moveQty(BigDecimal.ZERO)
+ .taskStatus(1)
+ .taskType(taskType)
+ .izAll(izAll)
+ .sysOrgCode(sysUser == null ? "A05" : sysUser.getOrgCode())
+ .tenantId(sysUser == null ? 1000L : Long.parseLong(sysUser.getRelTenantIds()))
+ .createBy(sysUser == null ? "system" : sysUser.getUsername())
+ .createTime(new Date())
+ .build();
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void generateAgvTask(List taskList) {
+ if (CollectionUtils.isEmpty(taskList)) {
+ return;
+ }
+ //根据stockCode、fromPointCode、toPointCode 分组
+ Map> taskGroupMap = taskList.stream()
+ .sorted(Comparator.comparing(Task::getCreateTime))
+ .collect(Collectors.groupingBy(task -> TaskGroupKey.of(
+ task.getStockCode(),
+ task.getFromPointCode(),
+ task.getToPointCode()
+ )));
+
+ //批量创建AGV任务
+ List createToAgvTaskList = new ArrayList<>();
+ Map groupToAgvTaskMap = new HashMap<>();
+ for (Map.Entry> entry : taskGroupMap.entrySet()) {
+ TaskGroupKey key = entry.getKey();
+ if(!groupToAgvTaskMap.containsKey(key)){
+ AgvTask agvTask = agvTaskService.bulidAgvTask(null, key.getStockCode(), key.getFromPointCode(), key.getToPointCode(), null, BusinessTypeEnum.OUTBOUND.getValue(), AgvVendorEnum.TES.getValue());
+ createToAgvTaskList.add(agvTask);
+ groupToAgvTaskMap.put(key, agvTask); // 建立映射
+ }
+ }
+ if (CollectionUtils.isNotEmpty(createToAgvTaskList)) {
+ batchUtils.saveBatchAgvTask(createToAgvTaskList);
+ }
+
+ //批量更新任务
+ List updateToTaskList = new ArrayList<>();
+ for (Map.Entry> entry : taskGroupMap.entrySet()) {
+ TaskGroupKey key = entry.getKey();
+ AgvTask agvTask = groupToAgvTaskMap.get(key); // 通过key获取
+ List list = entry.getValue();
+ for (Task task : list) {
+ task.setAgvTaskId(agvTask.getId());
+ updateToTaskList.add(task);
+ }
+ }
+ if (CollectionUtils.isNotEmpty(updateToTaskList)) {
+ batchUtils.updateBatchTask(updateToTaskList);
+ }
+ }
+}
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/vo/TaskGroupKey.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/vo/TaskGroupKey.java
new file mode 100644
index 0000000..fa7d1d8
--- /dev/null
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/vo/TaskGroupKey.java
@@ -0,0 +1,25 @@
+package org.cpte.modules.shipping.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@EqualsAndHashCode
+public class TaskGroupKey {
+ private String stockCode; // 容器
+ private String fromPointCode; // 原点位
+ private String toPointCode; // 目标点位
+
+ public static TaskGroupKey of(String stockCode, String fromPointCode, String toPointCode) {
+ return new TaskGroupKey(
+ StringUtils.defaultIfBlank(stockCode, ""), // 空值统一为"",避免分组不一致
+ StringUtils.defaultIfBlank(fromPointCode, ""),
+ StringUtils.defaultIfBlank(toPointCode, "")
+ );
+ }
+}
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/tesAgv/controller/TesAgvController.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/tesAgv/controller/TesAgvController.java
index e7aa3d3..2c1a5b1 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/tesAgv/controller/TesAgvController.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/tesAgv/controller/TesAgvController.java
@@ -52,7 +52,6 @@ public class TesAgvController {
@AutoLog(value = "TesAGV-任务上报")
@Operation(summary = "TesAGV-任务上报")
@PostMapping(value = "/callBackTask")
- @IgnoreAuth
public TesResult callBackTask(@RequestBody TesCallbackRequest tesCallbackRequest) {
try {
iTesAgvService.callBackTask(tesCallbackRequest);
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/tesAgv/service/impl/ITesAgvServiceImpl.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/tesAgv/service/impl/ITesAgvServiceImpl.java
index 3ffee93..53b0b0b 100644
--- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/tesAgv/service/impl/ITesAgvServiceImpl.java
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/tesAgv/service/impl/ITesAgvServiceImpl.java
@@ -7,6 +7,7 @@ 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.constant.GeneralConstant;
import org.cpte.modules.constant.enums.AgvStatusEnum;
import org.cpte.modules.constant.enums.AgvVendorEnum;
import org.cpte.modules.receive.service.IAsnService;
@@ -24,21 +25,6 @@ import java.util.*;
@Slf4j
public class ITesAgvServiceImpl implements ITesAgvService {
- /**
- * 接口开关
- */
- final String open_flag = "OPEN";
-
- /**
- * 成功码
- */
- final Integer success_code = 0;
-
- /**
- * 失败码
- */
- final Integer fail_code = 500;
-
@Autowired
private SysDictMapper sysDictMapper;
@@ -83,8 +69,8 @@ public class ITesAgvServiceImpl implements ITesAgvService {
public void sendTesAgvTask(String url, String json, AgvTask agvTask) {
log.info("请求报文:{}", json);
// 检查接口开关, 未开启则返回
- if (sysDictMapper.queryByDictCode(open_flag) == null) {
- updateAgvTaskResponse(agvTask, "接口未开启", fail_code);
+ if (sysDictMapper.queryByDictCode(GeneralConstant.OPEN_FLAG) == null) {
+ updateAgvTaskResponse(agvTask, "接口未开启", GeneralConstant.TES_FAIL_CODE);
return;
}
@@ -94,7 +80,7 @@ public class ITesAgvServiceImpl implements ITesAgvService {
//String result = HttpPostUtil.sendPostReq(url, json);
String result = "{" +
" \"returnCode\":0," +
- " \"returnMsg\":\"succ\"," +
+ " \"returnMsg\":\"成功\"," +
" \"returnUserMsg\":\"成功\"," +
" \"data\":{" +
" \"taskID\":74602" +
@@ -112,9 +98,9 @@ public class ITesAgvServiceImpl implements ITesAgvService {
}
returnCode = resulObject.getInteger("returnCode");
- returnMsg = resulObject.getString("returnUserMsg");
+ returnMsg = resulObject.getString("returnMsg");
- if (!success_code.equals(returnCode)) {
+ if (!GeneralConstant.TES_SUCCESS_CODE.equals(returnCode)) {
throw new RuntimeException("Tes返回消息:" + returnMsg);
}
@@ -122,8 +108,7 @@ public class ITesAgvServiceImpl implements ITesAgvService {
updateAgvTaskResponse(agvTask, returnMsg, returnCode);
} catch (Exception e) {
// 记录异常到 AgvTask
- updateAgvTaskResponse(agvTask, e.getMessage(), fail_code);
- throw e; // 继续向上抛出异常供 Controller 层处理
+ updateAgvTaskResponse(agvTask, e.getMessage(), GeneralConstant.TES_FAIL_CODE);
}
}
@@ -186,7 +171,7 @@ public class ITesAgvServiceImpl implements ITesAgvService {
if (count > 0) {
throw new RuntimeException("任务已重新生成,请勿重复操作! ");
}
- AgvTask newAgvTask = iAgvTaskService.createAgvTask(agvTask.getBusinessDetailId(), AgvStatusEnum.CREATED.getValue(), 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":
@@ -208,7 +193,7 @@ public class ITesAgvServiceImpl implements ITesAgvService {
*/
private void updateAgvTaskResponse(AgvTask agvTask, String message, Integer code) {
if (agvTask != null) {
- if (success_code.equals(code)) {
+ if (GeneralConstant.TES_SUCCESS_CODE.equals(code)) {
agvTask.setStatus(AgvStatusEnum.EXECUTING.getValue());
}
agvTask.setResMessage(message);
diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/BatchUtils.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/BatchUtils.java
new file mode 100644
index 0000000..133c688
--- /dev/null
+++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/BatchUtils.java
@@ -0,0 +1,294 @@
+package org.cpte.modules.utils;
+
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import org.cpte.modules.agvTask.entity.AgvTask;
+import org.cpte.modules.base.entity.Item;
+import org.cpte.modules.base.entity.Point;
+import org.cpte.modules.inventory.entity.Inventory;
+import org.cpte.modules.shipping.entity.PickDetail;
+import org.cpte.modules.shipping.entity.Task;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.core.BatchPreparedStatementSetter;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.sql.Date;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.List;
+import java.util.function.BiConsumer;
+
+@Service
+public class BatchUtils {
+
+ @Autowired
+ private JdbcTemplate jdbcTemplate;
+
+ // 默认批次大小
+ private static final int BATCH_SIZE = 1000;
+
+ /**
+ * 泛型批量插入方法
+ */
+ private void batchInsert(String sql, List dataList, BiConsumer setter) {
+ batchExecute(sql, dataList, setter);
+ }
+
+ /**
+ * 泛型批量更新方法
+ */
+ private void batchUpdate(String sql, List dataList, BiConsumer setter) {
+ batchExecute(sql, dataList, setter);
+ }
+
+
+ /**
+ * 分批执行SQL语句(支持插入与更新)
+ *
+ * @param sql SQL语句
+ * @param dataList 数据列表
+ * @param setter 设置每个对象对应PreparedStatement值的方法
+ * @param 对象类型
+ */
+ private void batchExecute(String sql, List dataList, BiConsumer setter) {
+ for (int i = 0; i < dataList.size(); i += BATCH_SIZE) {
+ int endIndex = Math.min(i + BATCH_SIZE, dataList.size());
+ List subList = dataList.subList(i, endIndex);
+
+ jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
+ @Override
+ public void setValues(PreparedStatement ps, int idx) throws SQLException {
+ T data = subList.get(idx);
+ setter.accept(ps, data);
+ }
+
+ @Override
+ public int getBatchSize() {
+ return subList.size();
+ }
+ });
+ }
+ }
+
+
+ /**
+ * 批量插入物料数据
+ */
+ @Transactional
+ public void saveBatchItem(List- items) {
+ String sql = "INSERT INTO base_item (item_code,item_name,description,iz_active, del_flag,sys_org_code,tenant_id,create_by,create_time) VALUES (?,?,?,?,?,?,?,?,?)";
+ batchInsert(sql, items, (ps, item) -> {
+ try {
+ ps.setString(1, item.getItemCode());
+ ps.setString(2, item.getItemName());
+ ps.setString(3, item.getDescription());
+ ps.setInt(4, item.getIzActive());
+ ps.setInt(5, item.getDelFlag());
+ ps.setString(6, item.getSysOrgCode());
+ ps.setLong(7, item.getTenantId());
+ ps.setString(8, item.getCreateBy());
+ ps.setDate(9, new Date(item.getCreateTime().getTime()));
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ }
+
+ /**
+ * 批量更新物料
+ */
+ @Transactional
+ public void updateBatchItem(List
- items) {
+ String sql = "UPDATE base_item SET item_code = ?, item_name = ?, description = ?, iz_active = ?, del_flag = ? WHERE id = ?";
+ batchUpdate(sql, items, (ps, item) -> {
+ try {
+ ps.setString(1, item.getItemCode());
+ ps.setString(2, item.getItemName());
+ ps.setString(3, item.getDescription());
+ ps.setInt(4, item.getIzActive());
+ ps.setInt(5, item.getDelFlag());
+ ps.setLong(6, item.getId());
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ }
+
+ /**
+ * 批量插入点位数据
+ */
+ @Transactional
+ public void saveBatchPoint(List points) {
+ String sql = "INSERT INTO base_point (area_id, point_code,status,row_num,col_num,layer_num,description,iz_active,del_flag,sys_org_code,tenant_id,create_by,create_time) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)";
+ batchInsert(sql, points, (ps, point) -> {
+ try {
+ ps.setLong(1, point.getAreaId());
+ ps.setString(2, point.getPointCode());
+ ps.setInt(3, point.getStatus());
+ ps.setString(4, point.getRowNum());
+ ps.setString(5, point.getColNum());
+ ps.setString(6, point.getLayerNum());
+ ps.setString(7, point.getDescription());
+ ps.setInt(8, point.getIzActive());
+ ps.setInt(9, point.getDelFlag());
+ ps.setString(10, point.getSysOrgCode());
+ ps.setLong(11, point.getTenantId());
+ ps.setString(12, point.getCreateBy());
+ ps.setDate(13, new Date(point.getCreateTime().getTime()));
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ }
+
+ /**
+ * 批量更新点位
+ */
+ @Transactional
+ public void batchUpdatePoints(List points) {
+ String sql = "UPDATE base_point SET area_id = ?, point_code = ?, status = ?, row_num = ?, col_num = ?, layer_num = ?, description = ?, iz_active = ?, del_flag = ? WHERE id = ?";
+ batchUpdate(sql, points, (ps, point) -> {
+ try {
+ ps.setLong(1, point.getAreaId());
+ ps.setString(2, point.getPointCode());
+ ps.setInt(3, point.getStatus());
+ ps.setString(4, point.getRowNum());
+ ps.setString(5, point.getColNum());
+ ps.setString(6, point.getLayerNum());
+ ps.setString(7, point.getDescription());
+ ps.setInt(8, point.getIzActive());
+ ps.setInt(9, point.getDelFlag());
+ ps.setLong(10, point.getId());
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ }
+
+
+ /**
+ * 批量更新出库明细
+ */
+ @Transactional
+ public void updateBatchPickDetail(List pickDetails) {
+ String sql = "UPDATE data_pick_detail SET allocated_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());
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ });
+
+ }
+
+ /**
+ * 批量插Task任务
+ */
+ @Transactional
+ public void saveBatchTask(List tasks) {
+ String sql = "INSERT INTO data_task (id,task_no,item_id,item_code,from_point_id,from_point_code,to_point_id,to_point_code,stock_id,stock_code,pick_id,pick_detail_id,inventory_id,plan_qty,move_qty,task_type,task_status,iz_all,sys_org_code,tenant_id,create_by,create_time) " +
+ "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
+ batchInsert(sql, tasks, (ps, task) -> {
+ try {
+ ps.setLong(1, IdWorker.getId());
+ ps.setString(2, task.getTaskNo());
+ ps.setLong(3, task.getItemId());
+ ps.setString(4, task.getItemCode());
+ ps.setLong(5, task.getFromPointId());
+ ps.setString(6, task.getFromPointCode());
+ ps.setLong(7, task.getToPointId());
+ ps.setString(8, task.getToPointCode());
+ ps.setLong(9, task.getStockId());
+ ps.setString(10, task.getStockCode());
+ ps.setLong(11, task.getPickId());
+ ps.setLong(12, task.getPickDetailId());
+ ps.setLong(13, task.getInventoryId());
+ ps.setBigDecimal(14, task.getPlanQty());
+ ps.setBigDecimal(15, task.getMoveQty());
+ ps.setInt(16, task.getTaskType());
+ ps.setInt(17, task.getTaskStatus());
+ ps.setInt(18, task.getIzAll());
+ ps.setString(19, task.getSysOrgCode());
+ ps.setLong(20, task.getTenantId());
+ ps.setString(21, task.getCreateBy());
+ ps.setTimestamp(22, new Timestamp(task.getCreateTime().getTime()));
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ }
+
+ /**
+ * 批量更新Task任务
+ */
+ @Transactional
+ public void updateBatchTask(List tasks) {
+ String sql = "UPDATE data_task SET agv_task_id = ? where id = ? ";
+ batchUpdate(sql, tasks, (ps, task) -> {
+ try {
+ ps.setObject(1, task.getAgvTaskId());
+ ps.setLong(2, task.getId());
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ });
+
+ }
+
+ /**
+ * 批量插AgvTask任务
+ */
+ @Transactional
+ public void saveBatchAgvTask(List 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 (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
+ batchInsert(sql, agvTasks, (ps, agvTask) -> {
+ try {
+ long id = IdWorker.getId();
+ agvTask.setId(id); // 关键:将生成的ID赋值给对象,解决null问题
+ ps.setLong(1, id);
+ ps.setObject(2, agvTask.getBusinessDetailId());
+ ps.setString(3, agvTask.getCarrierCode());
+ ps.setString(4, agvTask.getCarrierType());
+ ps.setString(5, agvTask.getTaskType());
+ ps.setString(6, agvTask.getType());
+ ps.setInt(7, agvTask.getStatus());
+ 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()));
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ }
+
+ /**
+ * 批量更新库存
+ */
+ @Transactional
+ public void updateBatchInventory(List inventories) {
+ String sql = "UPDATE data_inventory SET queued_qty = ?, status = ? where id = ?";
+ batchUpdate(sql, inventories, (ps, inventory) -> {
+ try {
+ ps.setBigDecimal(1, inventory.getQueuedQty());
+ ps.setInt(2, inventory.getStatus());
+ ps.setLong(3, inventory.getId());
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ }
+
+
+}
+
diff --git a/cpte-module-system/cpte-system-biz/src/main/java/org/jeecg/modules/openapi/filter/ApiAuthFilter.java b/cpte-module-system/cpte-system-biz/src/main/java/org/jeecg/modules/openapi/filter/ApiAuthFilter.java
index 1b6cd2a..051cc2e 100644
--- a/cpte-module-system/cpte-system-biz/src/main/java/org/jeecg/modules/openapi/filter/ApiAuthFilter.java
+++ b/cpte-module-system/cpte-system-biz/src/main/java/org/jeecg/modules/openapi/filter/ApiAuthFilter.java
@@ -200,6 +200,6 @@ public class ApiAuthFilter implements Filter {
public static void main(String[] args) {
long timestamp = System.currentTimeMillis();
System.out.println("timestamp:" + timestamp);
- System.out.println("signature:" + md5("ak-eAU25mrMxhtaZsyS" + "rjxMqB6YyUXpSHAz4DCIz8vZ5aozQQiV" + timestamp));
+ System.out.println("signature:" + md5("ak-h98TNj1bO5258uuS" + "E20j9w4vkTkLkv6tjALrzYqcybrvDaCx" + timestamp));
}
}
diff --git a/cpte-module-system/cpte-system-biz/src/main/java/org/jeecg/modules/openapi/mapper/OpenApiMapper.java b/cpte-module-system/cpte-system-biz/src/main/java/org/jeecg/modules/openapi/mapper/OpenApiMapper.java
index f9a4b67..a5b8a90 100644
--- a/cpte-module-system/cpte-system-biz/src/main/java/org/jeecg/modules/openapi/mapper/OpenApiMapper.java
+++ b/cpte-module-system/cpte-system-biz/src/main/java/org/jeecg/modules/openapi/mapper/OpenApiMapper.java
@@ -2,8 +2,18 @@ package org.jeecg.modules.openapi.mapper;
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.modules.openapi.entity.OpenApi;
@Mapper
public interface OpenApiMapper extends BaseMapper {
+ /**
+ * 通过接口地址获取原始地址
+ *
+ * @param requestUrl 接口地址
+ * @return String
+ */
+ @Select("select origin_url from open_api where request_url = #{requestUrl}")
+ String getRequestUrl(@Param("requestUrl") String requestUrl);
}
diff --git a/cpte-module-system/cpte-system-start/src/main/resources/application-dev.yml b/cpte-module-system/cpte-system-start/src/main/resources/application-dev.yml
index c8ab7d5..d4b616b 100644
--- a/cpte-module-system/cpte-system-start/src/main/resources/application-dev.yml
+++ b/cpte-module-system/cpte-system-start/src/main/resources/application-dev.yml
@@ -150,7 +150,7 @@ spring:
merge-sql: true
datasource:
master:
- url: jdbc:mysql://47.103.100.52:53306/cpte-wms?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
+ url: jdbc:mysql://47.103.100.52:53306/cpte-wms?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
username: root
password: Youchain@56
driver-class-name: com.mysql.cj.jdbc.Driver
diff --git a/cpte-module-system/cpte-system-start/src/main/resources/application-prod.yml b/cpte-module-system/cpte-system-start/src/main/resources/application-prod.yml
index e724746..616cdc0 100644
--- a/cpte-module-system/cpte-system-start/src/main/resources/application-prod.yml
+++ b/cpte-module-system/cpte-system-start/src/main/resources/application-prod.yml
@@ -142,7 +142,7 @@ spring:
slow-sql-millis: 5000
datasource:
master:
- url: jdbc:mysql://10.180.9.60:3306/cpte-wms?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
+ url: jdbc:mysql://10.180.9.60:3306/cpte-wms?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
username: root
password: cpte@123
driver-class-name: com.mysql.cj.jdbc.Driver
diff --git a/cpte-module-system/cpte-system-start/src/test/java/org/jeecg/TestMain.java b/cpte-module-system/cpte-system-start/src/test/java/org/jeecg/TestMain.java
index 35bf160..161c807 100644
--- a/cpte-module-system/cpte-system-start/src/test/java/org/jeecg/TestMain.java
+++ b/cpte-module-system/cpte-system-start/src/test/java/org/jeecg/TestMain.java
@@ -7,6 +7,9 @@ import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+
/**
* @Description: TODO
* @author: scott
@@ -14,7 +17,11 @@ import org.springframework.http.ResponseEntity;
*/
public class TestMain {
public static void main(String[] args) {
- // 请求地址
+ long timestamp = System.currentTimeMillis();
+ System.out.println("timestamp:" + timestamp);
+ System.out.println("signature:" + md5("ak-h98TNj1bO5258uuS" + "E20j9w4vkTkLkv6tjALrzYqcybrvDaCx" + timestamp));
+
+ /* // 请求地址
String url = "https://api3.boot.jeecg.com/sys/user/list";
// 请求 Header (用于传递Token)
HttpHeaders headers = getHeaders();
@@ -30,7 +37,32 @@ public class TestMain {
System.out.println("返回结果:" + result.getBody().toJSONString());
} else {
System.out.println("查询失败");
+ }*/
+ }
+
+ public static String md5(String sourceStr) {
+ String result = "";
+ try {
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ md.update(sourceStr.getBytes(StandardCharsets.UTF_8));
+ byte[] hash = md.digest();
+ int i;
+ StringBuffer buf = new StringBuffer(32);
+ for (int offset = 0; offset < hash.length; offset++) {
+ i = hash[offset];
+ if (i < 0) {
+ i += 256;
+ }
+ if (i < 16) {
+ buf.append("0");
+ }
+ buf.append(Integer.toHexString(i));
+ }
+ result = buf.toString();
+ } catch (Exception e) {
+ System.out.println("sign签名错误" + e);
}
+ return result;
}
private static HttpHeaders getHeaders() {
String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.50h-g6INOZRVnznExiawFb1U6PPjcVVA4POeYRA5a5Q";
diff --git a/cpte-module-system/cpte-system-start/src/test/java/org/jeecg/modules/openapi/test/SampleOpenApiTest.java b/cpte-module-system/cpte-system-start/src/test/java/org/jeecg/modules/openapi/test/SampleOpenApiTest.java
index ce55cfb..680860e 100644
--- a/cpte-module-system/cpte-system-start/src/test/java/org/jeecg/modules/openapi/test/SampleOpenApiTest.java
+++ b/cpte-module-system/cpte-system-start/src/test/java/org/jeecg/modules/openapi/test/SampleOpenApiTest.java
@@ -15,7 +15,7 @@ import java.security.MessageDigest;
public class SampleOpenApiTest {
- private final String base_url = "http://localhost:8080/jeecg-boot";
+ private final String base_url = "http://localhost:8080/cpte-wms";
private final String appKey = "ak-pFjyNHWRsJEFWlu6";
private final String searchKey = "4hV5dBrZtmGAtPdbA5yseaeKRYNpzGsS";