feat: 增加管芯托盘绑定基础能力(任务1-2)
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
package cn.code.nl.module.lms.controller.pda.coretube;
|
||||
|
||||
import cn.code.nl.framework.common.pojo.CommonResult;
|
||||
import cn.code.nl.module.lms.controller.pda.coretube.vo.CoreTubeBindReqVO;
|
||||
import cn.code.nl.module.lms.controller.pda.coretube.vo.CoreTubeBindRespVO;
|
||||
import cn.code.nl.module.lms.controller.pda.coretube.vo.CoreTubePalletRespVO;
|
||||
import cn.code.nl.module.lms.service.coretube.CoreTubeBindingService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.code.nl.framework.common.pojo.CommonResult.success;
|
||||
|
||||
/**
|
||||
* PDA 管芯托盘绑定接口。
|
||||
*/
|
||||
@Tag(name = "PDA - 管芯托盘绑定")
|
||||
@RestController
|
||||
@RequestMapping("/api/pda/coreTube")
|
||||
@Validated
|
||||
public class CoreTubePdaController {
|
||||
|
||||
@Resource
|
||||
private CoreTubeBindingService coreTubeBindingService;
|
||||
|
||||
/** 查询管芯托盘和5×5格位。 */
|
||||
@GetMapping("/pallet")
|
||||
@Operation(summary = "查询管芯托盘和5×5格位")
|
||||
@Parameter(name = "vehicleCode", description = "管芯托盘号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('lms:core-tube:bind')")
|
||||
public CommonResult<CoreTubePalletRespVO> getPallet(
|
||||
@RequestParam("vehicleCode") @NotBlank String vehicleCode) {
|
||||
return success(coreTubeBindingService.getPallet(vehicleCode));
|
||||
}
|
||||
|
||||
/** 批量绑定管芯到托盘格位。 */
|
||||
@PostMapping("/bind")
|
||||
@Operation(summary = "批量绑定管芯到托盘格位")
|
||||
@PreAuthorize("@ss.hasPermission('lms:core-tube:bind')")
|
||||
public CommonResult<List<CoreTubeBindRespVO>> bind(@Valid @RequestBody CoreTubeBindReqVO reqVO) {
|
||||
return success(coreTubeBindingService.bind(reqVO));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package cn.code.nl.module.lms.controller.pda.coretube.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.DecimalMin;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* PDA 管芯格位绑定请求。
|
||||
*/
|
||||
@Schema(description = "PDA - 管芯格位绑定 Request VO")
|
||||
@Data
|
||||
public class CoreTubeBindItemReqVO {
|
||||
|
||||
@Schema(description = "行号", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "行号不能为空")
|
||||
@Min(value = 1, message = "行号必须在1到5之间")
|
||||
@Max(value = 5, message = "行号必须在1到5之间")
|
||||
private Integer rowNum;
|
||||
|
||||
@Schema(description = "列号", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "列号不能为空")
|
||||
@Min(value = 1, message = "列号必须在1到5之间")
|
||||
@Max(value = 5, message = "列号必须在1到5之间")
|
||||
private Integer colNum;
|
||||
|
||||
@Schema(description = "管芯重量(kg)", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "管芯重量不能为空")
|
||||
@DecimalMin(value = "0.001", message = "管芯重量必须大于0")
|
||||
private BigDecimal coreWeight;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package cn.code.nl.module.lms.controller.pda.coretube.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Positive;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* PDA 批量绑定管芯请求。
|
||||
*/
|
||||
@Schema(description = "PDA - 批量绑定管芯 Request VO")
|
||||
@Data
|
||||
public class CoreTubeBindReqVO {
|
||||
|
||||
@Schema(description = "客户端请求号", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "客户端请求号不能为空")
|
||||
@Size(max = 64, message = "客户端请求号不能超过64个字符")
|
||||
private String requestNo;
|
||||
|
||||
@Schema(description = "管芯托盘号", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "管芯托盘号不能为空")
|
||||
@Size(max = 32, message = "管芯托盘号不能超过32个字符")
|
||||
private String vehicleCode;
|
||||
|
||||
@Schema(description = "管芯物料ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "管芯物料ID不能为空")
|
||||
@Positive(message = "管芯物料ID必须为正数")
|
||||
private Long materialId;
|
||||
|
||||
@Schema(description = "待绑定格位", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotEmpty(message = "待绑定格位不能为空")
|
||||
@Size(max = 25, message = "一次最多绑定25根管芯")
|
||||
@Valid
|
||||
private List<CoreTubeBindItemReqVO> items;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package cn.code.nl.module.lms.controller.pda.coretube.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* PDA 管芯绑定结果。
|
||||
*/
|
||||
@Schema(description = "PDA - 管芯绑定 Response VO")
|
||||
@Data
|
||||
public class CoreTubeBindRespVO {
|
||||
|
||||
@Schema(description = "管芯实例ID")
|
||||
private Long coreTubeId;
|
||||
@Schema(description = "虚拟管芯编号")
|
||||
private String coreTubeCode;
|
||||
@Schema(description = "行号")
|
||||
private Integer rowNum;
|
||||
@Schema(description = "列号")
|
||||
private Integer colNum;
|
||||
@Schema(description = "管芯重量(kg)")
|
||||
private BigDecimal coreWeight;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package cn.code.nl.module.lms.controller.pda.coretube.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* PDA 管芯托盘详情。
|
||||
*/
|
||||
@Schema(description = "PDA - 管芯托盘详情 Response VO")
|
||||
@Data
|
||||
public class CoreTubePalletRespVO {
|
||||
|
||||
@Schema(description = "管芯托盘号")
|
||||
private String vehicleCode;
|
||||
@Schema(description = "所在点位ID")
|
||||
private Long pointId;
|
||||
@Schema(description = "所在点位编码")
|
||||
private String pointCode;
|
||||
@Schema(description = "所在点位名称")
|
||||
private String pointName;
|
||||
@Schema(description = "点位类型")
|
||||
private String pointType;
|
||||
@Schema(description = "5×5格位中已有的管芯")
|
||||
private List<CoreTubeSlotRespVO> slots;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package cn.code.nl.module.lms.controller.pda.coretube.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* PDA 管芯托盘格位。
|
||||
*/
|
||||
@Schema(description = "PDA - 管芯托盘格位 Response VO")
|
||||
@Data
|
||||
public class CoreTubeSlotRespVO {
|
||||
|
||||
@Schema(description = "行号")
|
||||
private Integer rowNum;
|
||||
@Schema(description = "列号")
|
||||
private Integer colNum;
|
||||
@Schema(description = "管芯实例ID")
|
||||
private Long coreTubeId;
|
||||
@Schema(description = "虚拟管芯编号")
|
||||
private String coreTubeCode;
|
||||
@Schema(description = "物料编码")
|
||||
private String materialCode;
|
||||
@Schema(description = "物料名称")
|
||||
private String materialName;
|
||||
@Schema(description = "物料规格")
|
||||
private String materialSpec;
|
||||
@Schema(description = "管芯重量(kg)")
|
||||
private BigDecimal coreWeight;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package cn.code.nl.module.lms.dal.dataobject.coretube;
|
||||
|
||||
import cn.code.nl.framework.tenant.core.db.TenantBaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 管芯实例数据对象。
|
||||
*/
|
||||
@TableName("lms_core_tube")
|
||||
@Data
|
||||
public class CoreTubeDO extends TenantBaseDO {
|
||||
|
||||
/** 管芯实例ID。 */
|
||||
@TableId
|
||||
private Long coreTubeId;
|
||||
/** 虚拟管芯编号。 */
|
||||
private String coreTubeCode;
|
||||
/** PDA绑定请求号。 */
|
||||
private String bindRequestNo;
|
||||
/** 物料ID。 */
|
||||
private Long materialId;
|
||||
/** 物料编码。 */
|
||||
private String materialCode;
|
||||
/** 物料名称。 */
|
||||
private String materialName;
|
||||
/** 物料规格。 */
|
||||
private String materialSpec;
|
||||
/** 管芯重量。 */
|
||||
private BigDecimal coreWeight;
|
||||
/** 重量单位。 */
|
||||
private String weightUnit;
|
||||
/** 生命周期阶段。 */
|
||||
private Integer stage;
|
||||
/** 占用状态。 */
|
||||
private Integer status;
|
||||
/** 当前托盘号。 */
|
||||
private String vehicleCode;
|
||||
/** 托盘行号。 */
|
||||
private Integer rowNum;
|
||||
/** 托盘列号。 */
|
||||
private Integer colNum;
|
||||
/** 有效托盘格位唯一标记。 */
|
||||
private Integer activeSlot;
|
||||
/** 当前位置类型。 */
|
||||
private Integer currentLocationType;
|
||||
/** 当前位置记录ID。 */
|
||||
private Long currentLocationId;
|
||||
/** 当前位置编码。 */
|
||||
private String currentLocationCode;
|
||||
/** 来源日计划ID。 */
|
||||
private Long sourceDailyPlanId;
|
||||
/** 当前预占日计划ID。 */
|
||||
private Long reservedDailyPlanId;
|
||||
/** 当前调度领取标识。 */
|
||||
private String reservedClaimToken;
|
||||
/** 当前现场任务ID。 */
|
||||
private Long reservedTaskId;
|
||||
/** 预占过期时间。 */
|
||||
private LocalDateTime reserveExpireTime;
|
||||
/** 乐观锁版本。 */
|
||||
private Integer version;
|
||||
}
|
||||
@@ -16,6 +16,10 @@ public class PaperVehicleDO {
|
||||
/** 库存记录标识。 */
|
||||
@TableId
|
||||
private String ivtId;
|
||||
/** 管芯实例ID。 */
|
||||
private Long coreTubeId;
|
||||
/** 虚拟管芯编号。 */
|
||||
private String coreTubeCode;
|
||||
/** 托盘号。 */
|
||||
private String vehicleCode;
|
||||
/** 行号。 */
|
||||
@@ -26,6 +30,10 @@ public class PaperVehicleDO {
|
||||
private String materialCode;
|
||||
/** 物料名称。 */
|
||||
private String materialName;
|
||||
/** 物料规格。 */
|
||||
private String materialSpec;
|
||||
/** 管芯重量。 */
|
||||
private BigDecimal coreWeight;
|
||||
/** 数量。 */
|
||||
private BigDecimal qty;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package cn.code.nl.module.lms.dal.mysql.coretube;
|
||||
|
||||
import cn.code.nl.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.code.nl.module.lms.dal.dataobject.coretube.CoreTubeDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 管芯实例 Mapper。
|
||||
*/
|
||||
@Mapper
|
||||
public interface CoreTubeMapper extends BaseMapperX<CoreTubeDO> {
|
||||
|
||||
/** 根据绑定请求号查询管芯。 */
|
||||
List<CoreTubeDO> selectByBindRequestNo(@Param("bindRequestNo") String bindRequestNo);
|
||||
|
||||
/** 根据托盘号查询管芯。 */
|
||||
List<CoreTubeDO> selectByVehicleCode(@Param("vehicleCode") String vehicleCode);
|
||||
|
||||
/** 插入管芯实例。 */
|
||||
int insertCoreTube(@Param("tube") CoreTubeDO tube);
|
||||
}
|
||||
@@ -37,6 +37,16 @@ public interface StockingIvtMapper extends BaseMapperX<StockingIvtDO> {
|
||||
*/
|
||||
StockingIvtDO selectStockingIvtById(@Param("ivtId") Long ivtId);
|
||||
|
||||
/**
|
||||
* 根据托盘号查询所在点位。
|
||||
*/
|
||||
StockingIvtDO selectByVehicleCode(@Param("vehicleCode") String vehicleCode);
|
||||
|
||||
/**
|
||||
* 锁定托盘所在点位。
|
||||
*/
|
||||
StockingIvtDO selectByVehicleCodeForUpdate(@Param("vehicleCode") String vehicleCode);
|
||||
|
||||
/**
|
||||
* 更新备货区域点位的可编辑字段。
|
||||
*/
|
||||
@@ -46,4 +56,26 @@ public interface StockingIvtMapper extends BaseMapperX<StockingIvtDO> {
|
||||
* 根据托盘号查询纸管库存。
|
||||
*/
|
||||
List<PaperVehicleDO> selectPaperVehicleList(@Param("vehicleCode") String vehicleCode);
|
||||
|
||||
/**
|
||||
* 锁定指定托盘格位。
|
||||
*/
|
||||
PaperVehicleDO selectPaperVehicleSlotForUpdate(@Param("vehicleCode") String vehicleCode,
|
||||
@Param("rowNum") Integer rowNum,
|
||||
@Param("colNum") Integer colNum);
|
||||
|
||||
/**
|
||||
* 将已有托盘格位绑定到管芯。
|
||||
*/
|
||||
int updatePaperVehicleCoreTube(@Param("ivtId") String ivtId,
|
||||
@Param("coreTubeId") Long coreTubeId,
|
||||
@Param("coreTubeCode") String coreTubeCode,
|
||||
@Param("materialCode") String materialCode,
|
||||
@Param("materialName") String materialName,
|
||||
@Param("updater") String updater);
|
||||
|
||||
/**
|
||||
* 新增管芯托盘格位。
|
||||
*/
|
||||
int insertPaperVehicleCoreTube(@Param("tube") cn.code.nl.module.lms.dal.dataobject.coretube.CoreTubeDO tube);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package cn.code.nl.module.lms.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 管芯当前位置类型。
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum CoreTubeLocationTypeEnum {
|
||||
|
||||
STOCKING_BINDING(1),
|
||||
STOCKING_CACHE(2),
|
||||
STOCKING_DOCK(3),
|
||||
CORE_WAREHOUSE(4),
|
||||
EQUIPMENT(5),
|
||||
IN_TRANSIT(6),
|
||||
SLEEVING_CACHE(7);
|
||||
|
||||
private final Integer code;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package cn.code.nl.module.lms.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 管芯生命周期阶段。
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum CoreTubeStageEnum {
|
||||
|
||||
STOCKING_AREA(1),
|
||||
STOCKING_PICKING(2),
|
||||
CORE_WAREHOUSE(3),
|
||||
CORE_OUTBOUND(4),
|
||||
SLEEVING(5),
|
||||
SLEEVING_CACHE(6),
|
||||
CONSUMED(7),
|
||||
ABNORMAL(8);
|
||||
|
||||
private final Integer code;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package cn.code.nl.module.lms.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 管芯占用状态。
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum CoreTubeStatusEnum {
|
||||
|
||||
AVAILABLE(1),
|
||||
RESERVED(2),
|
||||
PROCESSING(3),
|
||||
USED(4),
|
||||
FROZEN(5),
|
||||
ABNORMAL(6);
|
||||
|
||||
private final Integer code;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package cn.code.nl.module.lms.service.coretube;
|
||||
|
||||
import cn.code.nl.module.lms.controller.pda.coretube.vo.CoreTubeBindReqVO;
|
||||
import cn.code.nl.module.lms.controller.pda.coretube.vo.CoreTubeBindRespVO;
|
||||
import cn.code.nl.module.lms.controller.pda.coretube.vo.CoreTubePalletRespVO;
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 管芯托盘绑定服务。
|
||||
*/
|
||||
public interface CoreTubeBindingService {
|
||||
|
||||
/** 查询管芯托盘详情。 */
|
||||
CoreTubePalletRespVO getPallet(String vehicleCode);
|
||||
|
||||
/** 批量绑定管芯到托盘格位。 */
|
||||
List<CoreTubeBindRespVO> bind(@Valid CoreTubeBindReqVO reqVO);
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
package cn.code.nl.module.lms.service.coretube;
|
||||
|
||||
import cn.code.nl.framework.common.exception.ServiceException;
|
||||
import cn.code.nl.framework.common.pojo.CommonResult;
|
||||
import cn.code.nl.module.base.api.codegen.CodeGenApi;
|
||||
import cn.code.nl.module.base.api.codegen.dto.CodeGenerateReqDTO;
|
||||
import cn.code.nl.module.base.api.materialbase.MaterialBaseApi;
|
||||
import cn.code.nl.module.base.api.materialbase.dto.MaterialBaseRespDTO;
|
||||
import cn.code.nl.module.lms.controller.pda.coretube.vo.CoreTubeBindItemReqVO;
|
||||
import cn.code.nl.module.lms.controller.pda.coretube.vo.CoreTubeBindReqVO;
|
||||
import cn.code.nl.module.lms.controller.pda.coretube.vo.CoreTubeBindRespVO;
|
||||
import cn.code.nl.module.lms.controller.pda.coretube.vo.CoreTubePalletRespVO;
|
||||
import cn.code.nl.module.lms.controller.pda.coretube.vo.CoreTubeSlotRespVO;
|
||||
import cn.code.nl.module.lms.dal.dataobject.coretube.CoreTubeDO;
|
||||
import cn.code.nl.module.lms.dal.dataobject.stockingivt.PaperVehicleDO;
|
||||
import cn.code.nl.module.lms.dal.dataobject.stockingivt.StockingIvtDO;
|
||||
import cn.code.nl.module.lms.dal.mysql.coretube.CoreTubeMapper;
|
||||
import cn.code.nl.module.lms.dal.mysql.stockingivt.StockingIvtMapper;
|
||||
import cn.code.nl.module.lms.enums.CoreTubeLocationTypeEnum;
|
||||
import cn.code.nl.module.lms.enums.CoreTubeStageEnum;
|
||||
import cn.code.nl.module.lms.enums.CoreTubeStatusEnum;
|
||||
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.code.nl.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.code.nl.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
import static cn.code.nl.module.lms.enums.ErrorCodeConstants.CORE_TUBE_BIND_FAILED;
|
||||
import static cn.code.nl.module.lms.enums.ErrorCodeConstants.CORE_TUBE_BIND_POINT_NOT_ALLOWED;
|
||||
import static cn.code.nl.module.lms.enums.ErrorCodeConstants.CORE_TUBE_BIND_POINT_NOT_EXISTS;
|
||||
import static cn.code.nl.module.lms.enums.ErrorCodeConstants.CORE_TUBE_BIND_REQUEST_CONFLICT;
|
||||
import static cn.code.nl.module.lms.enums.ErrorCodeConstants.CORE_TUBE_BIND_SLOT_DUPLICATED;
|
||||
import static cn.code.nl.module.lms.enums.ErrorCodeConstants.CORE_TUBE_BIND_SLOT_OCCUPIED;
|
||||
import static cn.code.nl.module.lms.enums.ErrorCodeConstants.CORE_TUBE_CODE_GENERATE_FAILED;
|
||||
import static cn.code.nl.module.lms.enums.ErrorCodeConstants.CORE_TUBE_MATERIAL_NOT_EXISTS;
|
||||
|
||||
/**
|
||||
* 管芯托盘绑定服务实现。
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class CoreTubeBindingServiceImpl implements CoreTubeBindingService {
|
||||
|
||||
private static final String CORE_TUBE_CODE_RULE = "CORE_TUBE_CODE";
|
||||
private static final String BINDING_POINT_TYPE = "1";
|
||||
private static final String ENABLED = "0";
|
||||
private static final String WEIGHT_UNIT = "kg";
|
||||
|
||||
@Resource
|
||||
private CoreTubeMapper coreTubeMapper;
|
||||
@Resource
|
||||
private StockingIvtMapper stockingIvtMapper;
|
||||
@Resource
|
||||
private MaterialBaseApi materialBaseApi;
|
||||
@Resource
|
||||
private CodeGenApi codeGenApi;
|
||||
|
||||
/** 查询管芯托盘详情。 */
|
||||
@Override
|
||||
public CoreTubePalletRespVO getPallet(String vehicleCode) {
|
||||
StockingIvtDO point = stockingIvtMapper.selectByVehicleCode(vehicleCode);
|
||||
if (point == null) {
|
||||
throw exception(CORE_TUBE_BIND_POINT_NOT_EXISTS);
|
||||
}
|
||||
CoreTubePalletRespVO response = new CoreTubePalletRespVO();
|
||||
response.setVehicleCode(vehicleCode);
|
||||
response.setPointId(point.getIvtId());
|
||||
response.setPointCode(point.getPointCode());
|
||||
response.setPointName(point.getPointName());
|
||||
response.setPointType(point.getPointType());
|
||||
List<PaperVehicleDO> inventory = stockingIvtMapper.selectPaperVehicleList(vehicleCode);
|
||||
List<CoreTubeSlotRespVO> slots = new ArrayList<>(inventory.size());
|
||||
for (PaperVehicleDO item : inventory) {
|
||||
CoreTubeSlotRespVO slot = new CoreTubeSlotRespVO();
|
||||
slot.setRowNum(item.getRowNum());
|
||||
slot.setColNum(item.getColNum());
|
||||
slot.setCoreTubeId(item.getCoreTubeId());
|
||||
slot.setCoreTubeCode(item.getCoreTubeCode());
|
||||
slot.setMaterialCode(item.getMaterialCode());
|
||||
slot.setMaterialName(item.getMaterialName());
|
||||
slot.setMaterialSpec(item.getMaterialSpec());
|
||||
slot.setCoreWeight(item.getCoreWeight());
|
||||
slots.add(slot);
|
||||
}
|
||||
response.setSlots(slots);
|
||||
return response;
|
||||
}
|
||||
|
||||
/** 批量绑定管芯到托盘格位。 */
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public List<CoreTubeBindRespVO> bind(CoreTubeBindReqVO reqVO) {
|
||||
List<CoreTubeDO> existing = coreTubeMapper.selectByBindRequestNo(reqVO.getRequestNo());
|
||||
if (!CollectionUtils.isEmpty(existing)) {
|
||||
if (!reqVO.getVehicleCode().equals(existing.get(0).getVehicleCode())) {
|
||||
throw exception(CORE_TUBE_BIND_REQUEST_CONFLICT);
|
||||
}
|
||||
return convertBindResult(existing);
|
||||
}
|
||||
StockingIvtDO point = stockingIvtMapper.selectByVehicleCodeForUpdate(reqVO.getVehicleCode());
|
||||
if (point == null) {
|
||||
throw exception(CORE_TUBE_BIND_POINT_NOT_EXISTS);
|
||||
}
|
||||
if (!BINDING_POINT_TYPE.equals(point.getPointType()) || !ENABLED.equals(point.getIsUsed())) {
|
||||
throw exception(CORE_TUBE_BIND_POINT_NOT_ALLOWED);
|
||||
}
|
||||
MaterialBaseRespDTO material = getMaterial(reqVO.getMaterialId());
|
||||
Set<String> positions = new HashSet<>();
|
||||
for (CoreTubeBindItemReqVO item : reqVO.getItems()) {
|
||||
String position = item.getRowNum() + ":" + item.getColNum();
|
||||
if (!positions.add(position)) {
|
||||
throw exception(CORE_TUBE_BIND_SLOT_DUPLICATED, position);
|
||||
}
|
||||
}
|
||||
String operator = String.valueOf(getLoginUserId());
|
||||
List<CoreTubeDO> created = new ArrayList<>(reqVO.getItems().size());
|
||||
try {
|
||||
for (CoreTubeBindItemReqVO item : reqVO.getItems()) {
|
||||
created.add(bindOne(reqVO, item, point, material, operator));
|
||||
}
|
||||
} catch (DuplicateKeyException ex) {
|
||||
throw exception(CORE_TUBE_BIND_FAILED);
|
||||
}
|
||||
return convertBindResult(created);
|
||||
}
|
||||
|
||||
/** 绑定单根管芯。 */
|
||||
private CoreTubeDO bindOne(CoreTubeBindReqVO reqVO, CoreTubeBindItemReqVO item, StockingIvtDO point,
|
||||
MaterialBaseRespDTO material, String operator) {
|
||||
PaperVehicleDO slot = stockingIvtMapper.selectPaperVehicleSlotForUpdate(
|
||||
reqVO.getVehicleCode(), item.getRowNum(), item.getColNum());
|
||||
if (slot != null && slot.getCoreTubeId() != null) {
|
||||
throw exception(CORE_TUBE_BIND_SLOT_OCCUPIED, item.getRowNum() + ":" + item.getColNum());
|
||||
}
|
||||
CoreTubeDO tube = new CoreTubeDO();
|
||||
tube.setCoreTubeId(IdWorker.getId());
|
||||
tube.setCoreTubeCode(generateCoreTubeCode());
|
||||
tube.setBindRequestNo(reqVO.getRequestNo());
|
||||
tube.setMaterialId(material.getMaterialId());
|
||||
tube.setMaterialCode(material.getMaterialCode());
|
||||
tube.setMaterialName(material.getMaterialName());
|
||||
tube.setMaterialSpec(material.getMaterialSpec());
|
||||
tube.setCoreWeight(item.getCoreWeight());
|
||||
tube.setWeightUnit(WEIGHT_UNIT);
|
||||
tube.setStage(CoreTubeStageEnum.STOCKING_AREA.getCode());
|
||||
tube.setStatus(CoreTubeStatusEnum.AVAILABLE.getCode());
|
||||
tube.setVehicleCode(reqVO.getVehicleCode());
|
||||
tube.setRowNum(item.getRowNum());
|
||||
tube.setColNum(item.getColNum());
|
||||
tube.setCurrentLocationType(CoreTubeLocationTypeEnum.STOCKING_BINDING.getCode());
|
||||
tube.setCurrentLocationId(point.getIvtId());
|
||||
tube.setCurrentLocationCode(point.getPointCode());
|
||||
tube.setCreator(operator);
|
||||
tube.setUpdater(operator);
|
||||
if (coreTubeMapper.insertCoreTube(tube) != 1) {
|
||||
throw exception(CORE_TUBE_BIND_FAILED);
|
||||
}
|
||||
int affected = slot == null
|
||||
? stockingIvtMapper.insertPaperVehicleCoreTube(tube)
|
||||
: stockingIvtMapper.updatePaperVehicleCoreTube(slot.getIvtId(), tube.getCoreTubeId(),
|
||||
tube.getCoreTubeCode(), tube.getMaterialCode(), tube.getMaterialName(), operator);
|
||||
if (affected != 1) {
|
||||
throw exception(CORE_TUBE_BIND_FAILED);
|
||||
}
|
||||
return tube;
|
||||
}
|
||||
|
||||
/** 查询并校验物料。 */
|
||||
private MaterialBaseRespDTO getMaterial(Long materialId) {
|
||||
CommonResult<MaterialBaseRespDTO> result = materialBaseApi.getMaterialBase(materialId);
|
||||
if (result == null) {
|
||||
throw exception(CORE_TUBE_MATERIAL_NOT_EXISTS);
|
||||
}
|
||||
if (!result.isSuccess()) {
|
||||
throw new ServiceException(result.getCode(), result.getMsg());
|
||||
}
|
||||
if (result.getData() == null) {
|
||||
throw exception(CORE_TUBE_MATERIAL_NOT_EXISTS);
|
||||
}
|
||||
return result.getData();
|
||||
}
|
||||
|
||||
/** 生成虚拟管芯编号。 */
|
||||
private String generateCoreTubeCode() {
|
||||
CodeGenerateReqDTO request = new CodeGenerateReqDTO();
|
||||
request.setRuleCode(CORE_TUBE_CODE_RULE);
|
||||
CommonResult<String> result = codeGenApi.generate(request);
|
||||
if (result == null) {
|
||||
throw exception(CORE_TUBE_CODE_GENERATE_FAILED);
|
||||
}
|
||||
if (!result.isSuccess()) {
|
||||
throw new ServiceException(result.getCode(), result.getMsg());
|
||||
}
|
||||
if (result.getData() == null || result.getData().isBlank()) {
|
||||
throw exception(CORE_TUBE_CODE_GENERATE_FAILED);
|
||||
}
|
||||
return result.getData();
|
||||
}
|
||||
|
||||
/** 转换绑定结果。 */
|
||||
private List<CoreTubeBindRespVO> convertBindResult(List<CoreTubeDO> tubes) {
|
||||
List<CoreTubeBindRespVO> result = new ArrayList<>(tubes.size());
|
||||
for (CoreTubeDO tube : tubes) {
|
||||
CoreTubeBindRespVO item = new CoreTubeBindRespVO();
|
||||
item.setCoreTubeId(tube.getCoreTubeId());
|
||||
item.setCoreTubeCode(tube.getCoreTubeCode());
|
||||
item.setRowNum(tube.getRowNum());
|
||||
item.setColNum(tube.getColNum());
|
||||
item.setCoreWeight(tube.getCoreWeight());
|
||||
result.add(item);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="cn.code.nl.module.lms.dal.mysql.coretube.CoreTubeMapper">
|
||||
|
||||
<sql id="coreTubeColumns">
|
||||
core_tube_id, core_tube_code, bind_request_no,
|
||||
material_id, material_code, material_name, material_spec,
|
||||
core_weight, weight_unit, stage, status,
|
||||
vehicle_code, row_num, col_num, active_slot,
|
||||
current_location_type, current_location_id, current_location_code,
|
||||
source_daily_plan_id, reserved_daily_plan_id, reserved_claim_token,
|
||||
reserved_task_id, reserve_expire_time, version,
|
||||
creator, create_time, updater, update_time, deleted, tenant_id
|
||||
</sql>
|
||||
|
||||
<select id="selectByBindRequestNo"
|
||||
resultType="cn.code.nl.module.lms.dal.dataobject.coretube.CoreTubeDO">
|
||||
SELECT <include refid="coreTubeColumns"/>
|
||||
FROM lms_core_tube
|
||||
WHERE bind_request_no = #{bindRequestNo}
|
||||
AND deleted = b'0'
|
||||
ORDER BY row_num, col_num, core_tube_id
|
||||
</select>
|
||||
|
||||
<select id="selectByVehicleCode"
|
||||
resultType="cn.code.nl.module.lms.dal.dataobject.coretube.CoreTubeDO">
|
||||
SELECT <include refid="coreTubeColumns"/>
|
||||
FROM lms_core_tube
|
||||
WHERE vehicle_code = #{vehicleCode}
|
||||
AND active_slot = 1
|
||||
AND deleted = b'0'
|
||||
ORDER BY row_num, col_num, core_tube_id
|
||||
</select>
|
||||
|
||||
<insert id="insertCoreTube">
|
||||
INSERT INTO lms_core_tube
|
||||
(core_tube_id, core_tube_code, bind_request_no,
|
||||
material_id, material_code, material_name, material_spec,
|
||||
core_weight, weight_unit, stage, status,
|
||||
vehicle_code, row_num, col_num, active_slot,
|
||||
current_location_type, current_location_id, current_location_code,
|
||||
version, creator, updater)
|
||||
VALUES
|
||||
(#{tube.coreTubeId}, #{tube.coreTubeCode}, #{tube.bindRequestNo},
|
||||
#{tube.materialId}, #{tube.materialCode}, #{tube.materialName}, #{tube.materialSpec},
|
||||
#{tube.coreWeight}, #{tube.weightUnit}, #{tube.stage}, #{tube.status},
|
||||
#{tube.vehicleCode}, #{tube.rowNum}, #{tube.colNum}, 1,
|
||||
#{tube.currentLocationType}, #{tube.currentLocationId}, #{tube.currentLocationCode},
|
||||
0, #{tube.creator}, #{tube.updater})
|
||||
</insert>
|
||||
</mapper>
|
||||
@@ -42,6 +42,21 @@
|
||||
WHERE ivt_id = #{ivtId}
|
||||
</select>
|
||||
|
||||
<select id="selectByVehicleCode"
|
||||
resultType="cn.code.nl.module.lms.dal.dataobject.stockingivt.StockingIvtDO">
|
||||
SELECT <include refid="stockingIvtColumns"/>
|
||||
FROM lms_ivt_stockingivt
|
||||
WHERE vehicle_code = #{vehicleCode}
|
||||
</select>
|
||||
|
||||
<select id="selectByVehicleCodeForUpdate"
|
||||
resultType="cn.code.nl.module.lms.dal.dataobject.stockingivt.StockingIvtDO">
|
||||
SELECT <include refid="stockingIvtColumns"/>
|
||||
FROM lms_ivt_stockingivt
|
||||
WHERE vehicle_code = #{vehicleCode}
|
||||
FOR UPDATE
|
||||
</select>
|
||||
|
||||
<update id="updateStockingIvt">
|
||||
UPDATE lms_ivt_stockingivt
|
||||
SET vehicle_code = #{vehicleCode},
|
||||
@@ -57,13 +72,52 @@
|
||||
|
||||
<select id="selectPaperVehicleList"
|
||||
resultType="cn.code.nl.module.lms.dal.dataobject.stockingivt.PaperVehicleDO">
|
||||
SELECT ivt_id, vehicle_code,
|
||||
SELECT paper.ivt_id, paper.core_tube_id, paper.core_tube_code, paper.vehicle_code,
|
||||
CAST(paper.row_num AS SIGNED) AS row_num,
|
||||
CAST(paper.col_num AS SIGNED) AS col_num,
|
||||
COALESCE(tube.material_code, paper.material_code) AS material_code,
|
||||
COALESCE(tube.material_name, paper.material_name) AS material_name,
|
||||
tube.material_spec, tube.core_weight, paper.qty
|
||||
FROM lms_base_papervehicle paper
|
||||
LEFT JOIN lms_core_tube tube ON tube.core_tube_id = paper.core_tube_id
|
||||
AND tube.deleted = b'0'
|
||||
WHERE paper.vehicle_code = #{vehicleCode}
|
||||
ORDER BY CAST(paper.row_num AS UNSIGNED), CAST(paper.col_num AS UNSIGNED), paper.ivt_id
|
||||
</select>
|
||||
|
||||
<select id="selectPaperVehicleSlotForUpdate"
|
||||
resultType="cn.code.nl.module.lms.dal.dataobject.stockingivt.PaperVehicleDO">
|
||||
SELECT ivt_id, core_tube_id, core_tube_code, vehicle_code,
|
||||
CAST(row_num AS SIGNED) AS row_num,
|
||||
CAST(col_num AS SIGNED) AS col_num,
|
||||
material_code, material_name, qty
|
||||
FROM lms_base_papervehicle
|
||||
WHERE vehicle_code = #{vehicleCode}
|
||||
ORDER BY CAST(row_num AS UNSIGNED), CAST(col_num AS UNSIGNED), ivt_id
|
||||
AND CAST(row_num AS UNSIGNED) = #{rowNum}
|
||||
AND CAST(col_num AS UNSIGNED) = #{colNum}
|
||||
FOR UPDATE
|
||||
</select>
|
||||
|
||||
<update id="updatePaperVehicleCoreTube">
|
||||
UPDATE lms_base_papervehicle
|
||||
SET core_tube_id = #{coreTubeId},
|
||||
core_tube_code = #{coreTubeCode},
|
||||
material_code = #{materialCode},
|
||||
material_name = #{materialName},
|
||||
qty = 1,
|
||||
updater = #{updater}
|
||||
WHERE ivt_id = #{ivtId}
|
||||
AND core_tube_id IS NULL
|
||||
</update>
|
||||
|
||||
<insert id="insertPaperVehicleCoreTube">
|
||||
INSERT INTO lms_base_papervehicle
|
||||
(ivt_id, core_tube_id, core_tube_code, vehicle_code, row_num, col_num,
|
||||
material_code, material_name, qty, creator, updater)
|
||||
VALUES
|
||||
(CAST(#{tube.coreTubeId} AS CHAR), #{tube.coreTubeId}, #{tube.coreTubeCode},
|
||||
#{tube.vehicleCode}, CAST(#{tube.rowNum} AS CHAR), CAST(#{tube.colNum} AS CHAR),
|
||||
#{tube.materialCode}, #{tube.materialName}, 1, #{tube.creator}, #{tube.updater})
|
||||
</insert>
|
||||
|
||||
</mapper>
|
||||
|
||||
Reference in New Issue
Block a user