feat: 增加管芯托盘绑定基础能力(任务1-2)

This commit is contained in:
zhouz
2026-08-17 10:34:42 +08:00
parent 9fa231693c
commit 0331aca1a9
21 changed files with 941 additions and 2 deletions

View File

@@ -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));
}
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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;
}
}

View File

@@ -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>

View File

@@ -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>