feat:任务编码修改

This commit is contained in:
zhouz
2026-08-24 16:23:32 +08:00
parent bca5dbf71b
commit 1f51f66bca
11 changed files with 103 additions and 28 deletions

View File

@@ -1,6 +1,7 @@
package cn.code.nl.module.wms.api.emptybox.dto;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import lombok.Data;
/**
@@ -11,4 +12,8 @@ public class EmptyBoxOutboundCreateReq {
@NotBlank(message = "木箱规格编码不能为空")
private String materialCode;
@NotBlank(message = "异常点位不能为空")
@Pattern(regexp = "YCD01|YCD02", message = "异常点位不在可选范围内")
private String destinationPoint;
}

View File

@@ -0,0 +1,34 @@
package cn.code.nl.module.wms.enums.task;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* WMS 运输任务类型。
*
* <p>任务类型同时区分库存对象和作业方向,便于任务查询、统计和调度。</p>
*/
@Getter
@AllArgsConstructor
public enum WmsTaskTypeEnum {
/** 成品入库。 */
FINISHED_GOODS_INBOUND("010501"),
/** 成品出库。 */
FINISHED_GOODS_OUTBOUND("010502"),
/** 成品移库。 */
FINISHED_GOODS_MOVE("010503"),
/** 空托盘入库。 */
EMPTY_PALLET_INBOUND("010504"),
/** 空托盘出库。 */
EMPTY_PALLET_OUTBOUND("010505"),
/** 空木箱入库。 */
EMPTY_BOX_INBOUND("010506"),
/** 空木箱出库。 */
EMPTY_BOX_OUTBOUND("010507"),
/** 空木箱移库。 */
EMPTY_BOX_MOVE("010508");
/** 任务类型编码。 */
private final String code;
}

View File

@@ -19,6 +19,7 @@ import cn.code.nl.module.wms.dal.mysql.boxinfo.BoxInfoMapper;
import cn.code.nl.module.wms.dal.mysql.boxtype.BoxTypeMapper;
import cn.code.nl.module.wms.dal.mysql.structAttr.StrucAttrMapper;
import cn.code.nl.module.wms.enums.emptybox.EmptyBoxStatusEnum;
import cn.code.nl.module.wms.enums.task.WmsTaskTypeEnum;
import cn.hutool.core.util.IdUtil;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
@@ -40,8 +41,6 @@ public class EmptyBoxServiceImpl implements EmptyBoxService {
private static final String TRUSS_INBOUND_POINT = "FHD01";
private static final String INBOUND_LOCK = "8";
private static final String OUTBOUND_LOCK = "9";
private static final String OUTBOUND_POINT_1 = "ZXQ_01";
private static final String OUTBOUND_POINT_2 = "ZXQ_02";
private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@Resource
@@ -66,7 +65,7 @@ public class EmptyBoxServiceImpl implements EmptyBoxService {
throw new ServiceException(500, "木箱规格不存在");
}
String boxNo = generateBoxNo();
String reservationCode = "EMPTY_BOX_" + IdUtil.getSnowflakeNextIdStr();
String reservationCode = generateReservationCode();
StrucAttrDO struct = reserveInboundStruct(req.getMaterialCode(), reservationCode, boxNo);
if (struct == null) {
throw new ServiceException(500, "未找到符合条件的空木箱入库仓位");
@@ -101,7 +100,7 @@ public class EmptyBoxServiceImpl implements EmptyBoxService {
task.setOwnerService(OWNER_SERVICE);
task.setBizType("EMPTY_BOX_TRUSS_IN");
task.setHandleCode(TRUSS_HANDLE_CODE);
task.setTaskType("010501");
task.setTaskType(WmsTaskTypeEnum.EMPTY_BOX_INBOUND.getCode());
task.setAcsTaskType("7");
task.setAgvSystemType("1");
task.setPointCode1(req.getPointCode());
@@ -124,12 +123,12 @@ public class EmptyBoxServiceImpl implements EmptyBoxService {
if (boxTypeMapper.selectByMaterialCode(req.getMaterialCode()) == null) {
throw new ServiceException(500, "木箱规格不存在");
}
String reservationCode = "EMPTY_BOX_" + IdUtil.getSnowflakeNextIdStr();
String reservationCode = generateReservationCode();
BoxInfoDO box = reserveOutboundBox(req.getMaterialCode(), reservationCode);
if (box == null) {
throw new ServiceException(500, "没有可出库的该规格空木箱");
}
String destinationPoint = selectOutboundPoint();
String destinationPoint = req.getDestinationPoint();
StrucAttrDO struct = new StrucAttrDO();
struct.setStructId(box.getStructId());
struct.setStructCode(box.getStructCode());
@@ -195,6 +194,13 @@ public class EmptyBoxServiceImpl implements EmptyBoxService {
return codeGenApi.generate(req).getCheckedData();
}
/**
* 生成仓位临时预占码,长度不得超过 wms_structattr.task_code 的 20 个字符。
*/
String generateReservationCode() {
return IdUtil.getSnowflakeNextIdStr();
}
/**
* 按同规格排、全空排的顺序预占入库仓位。
*/
@@ -254,20 +260,6 @@ public class EmptyBoxServiceImpl implements EmptyBoxService {
return null;
}
/**
* 按任务和点位库存综合负载选择出库点。
*/
private String selectOutboundPoint() {
// TODO 后续改为调用 LMS 接口,统一获取候选出库点和点位库存占用情况。
long point1Load = transportTaskApi.countUnfinishedByDestination(
OUTBOUND_POINT_1, OWNER_SERVICE).getCheckedData()
+ strucAttrMapper.countEmptyBoxAtPoint(OUTBOUND_POINT_1);
long point2Load = transportTaskApi.countUnfinishedByDestination(
OUTBOUND_POINT_2, OWNER_SERVICE).getCheckedData()
+ strucAttrMapper.countEmptyBoxAtPoint(OUTBOUND_POINT_2);
return point1Load <= point2Load ? OUTBOUND_POINT_1 : OUTBOUND_POINT_2;
}
/**
* 创建搬运任务。
*/
@@ -279,7 +271,9 @@ public class EmptyBoxServiceImpl implements EmptyBoxService {
task.setBizType(bizType);
task.setBizId(struct.getStructId());
task.setHandleCode(HANDLE_CODE);
task.setTaskType("EMPTY_BOX_IN".equals(bizType) ? "010501" : "010503");
task.setTaskType("EMPTY_BOX_IN".equals(bizType)
? WmsTaskTypeEnum.EMPTY_BOX_INBOUND.getCode()
: WmsTaskTypeEnum.EMPTY_BOX_OUTBOUND.getCode());
task.setAcsTaskType("7");
task.setAgvSystemType("1");
task.setPointCode1(startPoint);

View File

@@ -6,6 +6,7 @@ import cn.code.nl.module.wms.controller.admin.emptyvehicle.vo.EmptyVehicleTaskCr
import cn.code.nl.module.wms.dal.dataobject.structAttr.StrucAttrDO;
import cn.code.nl.module.wms.dal.dataobject.structAttr.EmptyVehicleRowCandidate;
import cn.code.nl.module.wms.dal.mysql.structAttr.StrucAttrMapper;
import cn.code.nl.module.wms.enums.task.WmsTaskTypeEnum;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -39,7 +40,8 @@ public class EmptyVehicleServiceImpl implements EmptyVehicleService {
task.setBizType(inbound ? "EMPTY_VEHICLE_IN" : "EMPTY_VEHICLE_OUT");
task.setBizId(struct.getStructId());
task.setHandleCode("EMPTYVEHICLETASK");
task.setTaskType(inbound ? "010501" : "010503");
task.setTaskType(inbound ? WmsTaskTypeEnum.EMPTY_PALLET_INBOUND.getCode()
: WmsTaskTypeEnum.EMPTY_PALLET_OUTBOUND.getCode());
task.setAcsTaskType("7");
task.setAgvSystemType("1");
task.setPointCode1(inbound ? reqVO.getDeviceCode() : struct.getStructCode());

View File

@@ -1,6 +1,7 @@
package cn.code.nl.module.wms.service.iostorinv;
import cn.code.nl.module.wms.task.InTask;
import cn.code.nl.module.wms.enums.task.WmsTaskTypeEnum;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.code.nl.framework.common.pojo.CommonResult;
@@ -553,7 +554,7 @@ public class InboundIostorInvServiceImpl implements InboundIostorInvService {
task.setBizType("INBOUND");
task.setBizId(bizId);
task.setHandleCode(InTask.class.getName());
task.setTaskType("010501");
task.setTaskType(WmsTaskTypeEnum.FINISHED_GOODS_INBOUND.getCode());
task.setAcsTaskType("7");
task.setAgvSystemType("1");
task.setPointCode1(sourcePoint);

View File

@@ -2,6 +2,7 @@ package cn.code.nl.module.wms.service.iostorinv;
import cn.code.nl.module.wms.task.MoveTask;
import cn.code.nl.module.wms.task.OutTask;
import cn.code.nl.module.wms.enums.task.WmsTaskTypeEnum;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
@@ -618,7 +619,7 @@ public class IostorInvServiceImpl implements IostorInvService {
.findFirst()
.orElseThrow();
// 10. 任务起点、目的点严格使用移库单明细,保证移库任务与移库单据完全一致。
Long taskId = createAndIssueTask("010505", "移库任务",
Long taskId = createAndIssueTask(WmsTaskTypeEnum.FINISHED_GOODS_MOVE.getCode(), "移库任务",
moveDetail.getTurnoutStructCode(), moveDetail.getTurninStructCode(),
action.vehicleCode(), null, null, taskGroupId, ++sortSeq,
"MOVE", String.valueOf(moveDetail.getMoveinvdtlId()));
@@ -633,7 +634,7 @@ public class IostorInvServiceImpl implements IostorInvService {
}
// 13. 比较两个出库点未完成任务数,选择当前负载较小的目的点。
String destinationPoint = chooseDestination(destinationLoads);
Long taskId = createAndIssueTask("010503", "出库任务", source.getStructCode(),
Long taskId = createAndIssueTask(WmsTaskTypeEnum.FINISHED_GOODS_OUTBOUND.getCode(), "出库任务", source.getStructCode(),
destinationPoint, action.vehicleCode(), detail.getMaterialId(),
detail.getMaterialCode(), taskGroupId, ++sortSeq, "OUT",
vehicleAllocations.get(0).getIostorinvdisId());

View File

@@ -10,6 +10,7 @@ import cn.code.nl.module.wms.dal.dataobject.point.ShippingPointRowCandidate;
import cn.code.nl.module.wms.dal.dataobject.point.WmsPointDO;
import cn.code.nl.module.wms.dal.mysql.iostorinvdis.IostorinvDisMapper;
import cn.code.nl.module.wms.dal.mysql.point.WmsPointMapper;
import cn.code.nl.module.wms.enums.task.WmsTaskTypeEnum;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -117,7 +118,7 @@ public class ShippingAreaServiceImpl implements ShippingAreaService {
task.setBizType(SHIPPING_AREA_BIZ_TYPE);
task.setBizId(billId);
task.setHandleCode(SHIPPING_AREA_HANDLE_CODE);
task.setTaskType("010503");
task.setTaskType(WmsTaskTypeEnum.FINISHED_GOODS_OUTBOUND.getCode());
task.setAcsTaskType("7");
task.setAgvSystemType("1");
task.setPointCode1(reqVO.getDeviceCode());

View File

@@ -4,9 +4,19 @@ import cn.code.nl.module.task.dto.TransportTaskCreateReqDTO;
import cn.code.nl.module.wms.api.emptybox.dto.EmptyBoxTrussInboundCreateReq;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
class EmptyBoxServiceImplTest {
@Test
void shouldGenerateReservationCodeWithinStructTaskCodeLimit() {
String reservationCode = new EmptyBoxServiceImpl().generateReservationCode();
assertFalse(reservationCode.isBlank());
assertTrue(reservationCode.length() <= 20);
}
@Test
void shouldBuildEmptyBoxTrussInboundTask() {
EmptyBoxTrussInboundCreateReq req = new EmptyBoxTrussInboundCreateReq();

View File

@@ -4,7 +4,7 @@ VITE_PORT=5999
VITE_BASE=/
# 请求路径
VITE_BASE_URL=http://127.0.0.1:48080
VITE_BASE_URL=http://localhost:48080
# 接口地址
VITE_GLOB_API_URL=/admin-api
# 文件上传类型server - 后端上传, client - 前端直连上传仅支持S3服务

View File

@@ -1,7 +1,7 @@
VITE_BASE=/
# 请求路径
VITE_BASE_URL=http://127.0.0.1:48080
VITE_BASE_URL=http://localhost:48080
# 接口地址
VITE_GLOB_API_URL=/admin-api
# 文件上传类型server - 后端上传, client - 前端直连上传仅支持S3服务

View File

@@ -0,0 +1,27 @@
-- WMS 运输任务类型。编码同时区分库存对象和作业方向。
-- 脚本按任务分类根节点和编码幂等插入,可重复执行。
INSERT INTO base_classstandard
(class_id, class_code, class_name, class_desc, parent_class_id, deleted,
sort, status, creator, create_time, updater, update_time)
SELECT 229000000000010500 + task_type.sort, task_type.class_code, task_type.class_name,
task_type.class_name, root.class_id, '0', task_type.sort, 0,
'1', NOW(), '1', NOW()
FROM base_classstandard root
JOIN (
SELECT '010501' class_code, '成品入库' class_name, 1 sort
UNION ALL SELECT '010502', '成品出库', 2
UNION ALL SELECT '010503', '成品移库', 3
UNION ALL SELECT '010504', '空托盘入库', 4
UNION ALL SELECT '010505', '空托盘出库', 5
UNION ALL SELECT '010506', '空木箱入库', 6
UNION ALL SELECT '010507', '空木箱出库', 7
UNION ALL SELECT '010508', '空木箱移库', 8
) task_type ON 1 = 1
WHERE root.class_code = '0002'
AND root.deleted = '0'
AND NOT EXISTS (
SELECT 1 FROM base_classstandard existing
WHERE existing.class_code = task_type.class_code
AND existing.deleted = '0'
);