feat: 增加日计划管芯现场调度
This commit is contained in:
@@ -23,6 +23,7 @@ public class DailyPlanClaimDO extends TenantBaseDO {
|
||||
private Integer version;
|
||||
private Integer claimStatus;
|
||||
private Integer activeFlag;
|
||||
private Boolean taskCreated;
|
||||
private LocalDateTime expireTime;
|
||||
private LocalDateTime confirmedTime;
|
||||
private String operator;
|
||||
|
||||
@@ -21,4 +21,42 @@ public interface CoreTubeMapper extends BaseMapperX<CoreTubeDO> {
|
||||
|
||||
/** 插入管芯实例。 */
|
||||
int insertCoreTube(@Param("tube") CoreTubeDO tube);
|
||||
|
||||
/** 查询对接位上一根可用的目标管芯。 */
|
||||
CoreTubeDO selectAvailableDockTube(@Param("materialId") Long materialId);
|
||||
|
||||
/** 查询管芯库中一根可用的目标管芯。 */
|
||||
CoreTubeDO selectAvailableWarehouseTube(@Param("materialId") Long materialId);
|
||||
|
||||
/** 原子预占一根管芯。 */
|
||||
int reserveTube(@Param("coreTubeId") Long coreTubeId, @Param("expectedStage") Integer expectedStage,
|
||||
@Param("newStage") Integer newStage, @Param("dailyPlanId") Long dailyPlanId,
|
||||
@Param("claimToken") String claimToken, @Param("expireTime") java.time.LocalDateTime expireTime,
|
||||
@Param("updater") String updater);
|
||||
|
||||
/** 绑定现场任务。 */
|
||||
int bindTask(@Param("coreTubeId") Long coreTubeId, @Param("taskId") Long taskId,
|
||||
@Param("updater") String updater);
|
||||
|
||||
/** 释放尚未落任务的管芯预占。 */
|
||||
int releaseReservation(@Param("coreTubeId") Long coreTubeId, @Param("claimToken") String claimToken,
|
||||
@Param("stage") Integer stage, @Param("updater") String updater);
|
||||
|
||||
/** 完成管芯位置转换。 */
|
||||
int completeTubeTask(@Param("coreTubeId") Long coreTubeId, @Param("taskId") Long taskId,
|
||||
@Param("stage") Integer stage, @Param("status") Integer status,
|
||||
@Param("locationType") Integer locationType,
|
||||
@Param("locationId") Long locationId, @Param("locationCode") String locationCode,
|
||||
@Param("clearVehicle") Boolean clearVehicle, @Param("updater") String updater);
|
||||
|
||||
/** 取消管芯任务并恢复可用。 */
|
||||
int cancelTubeTask(@Param("coreTubeId") Long coreTubeId, @Param("taskId") Long taskId,
|
||||
@Param("stage") Integer stage, @Param("updater") String updater);
|
||||
|
||||
/** 按托盘更新全部管芯当前位置。 */
|
||||
int updateVehicleLocation(@Param("vehicleCode") String vehicleCode,
|
||||
@Param("locationType") Integer locationType,
|
||||
@Param("locationId") Long locationId,
|
||||
@Param("locationCode") String locationCode,
|
||||
@Param("updater") String updater);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@ public interface DailyPlanClaimMapper extends BaseMapperX<DailyPlanClaimDO> {
|
||||
|
||||
int releaseClaim(@Param("claimToken") String claimToken, @Param("updater") String updater);
|
||||
|
||||
int markTaskCreated(@Param("claimToken") String claimToken, @Param("updater") String updater);
|
||||
|
||||
int renewClaim(@Param("claimToken") String claimToken, @Param("version") Integer version,
|
||||
@Param("expireTime") LocalDateTime expireTime,
|
||||
@Param("updater") String updater);
|
||||
|
||||
@@ -78,4 +78,26 @@ public interface StockingIvtMapper extends BaseMapperX<StockingIvtDO> {
|
||||
* 新增管芯托盘格位。
|
||||
*/
|
||||
int insertPaperVehicleCoreTube(@Param("tube") cn.code.nl.module.lms.dal.dataobject.coretube.CoreTubeDO tube);
|
||||
|
||||
/** 管芯离开托盘后清理格位绑定。 */
|
||||
int clearPaperVehicleCoreTube(@Param("coreTubeId") Long coreTubeId, @Param("updater") String updater);
|
||||
|
||||
/** 查询当前有托盘的对接位。 */
|
||||
StockingIvtDO selectOccupiedDockPoint();
|
||||
|
||||
/** 查询当前空闲的对接位。 */
|
||||
StockingIvtDO selectEmptyDockPoint();
|
||||
|
||||
/** 查询当前空闲的缓存位。 */
|
||||
StockingIvtDO selectEmptyCachePoint();
|
||||
|
||||
/** 为目标物料选择最合适的缓存位托盘。 */
|
||||
StockingIvtDO selectBestCacheVehicle(@Param("materialId") Long materialId,
|
||||
@Param("requiredQty") Integer requiredQty);
|
||||
|
||||
/** 完成托盘点位转移。 */
|
||||
int completeVehicleMove(@Param("sourcePointId") Long sourcePointId,
|
||||
@Param("targetPointId") Long targetPointId,
|
||||
@Param("vehicleCode") String vehicleCode,
|
||||
@Param("updater") String updater);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package cn.code.nl.module.lms.enums;
|
||||
|
||||
/** 管芯任务回调处理器编码。 */
|
||||
public interface CoreTubeHandleCodeConstants {
|
||||
String CORE_TUBE_STOCKING_TASK = "CORE_TUBE_STOCKING_TASK";
|
||||
String CORE_TUBE_SLEEVING_TASK = "CORE_TUBE_SLEEVING_TASK";
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package cn.code.nl.module.lms.enums;
|
||||
|
||||
/** 管芯现场任务业务类型。 */
|
||||
public enum CoreTubeTaskBizTypeEnum {
|
||||
CORE_TUBE_PALLET_IN,
|
||||
CORE_TUBE_PALLET_OUT,
|
||||
CORE_TUBE_STOCKING_PICK,
|
||||
CORE_TUBE_SLEEVING_OUT
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package cn.code.nl.module.lms.job;
|
||||
|
||||
import cn.code.nl.framework.tenant.core.job.TenantJob;
|
||||
import cn.code.nl.module.lms.service.coretube.CoreTubeTaskDispatchService;
|
||||
import com.xxl.job.core.context.XxlJobHelper;
|
||||
import com.xxl.job.core.handler.annotation.XxlJob;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/** 日计划管芯备货与套管定时调度。 */
|
||||
@Slf4j
|
||||
@Component
|
||||
public class DailyPlanCoreTubeJob {
|
||||
|
||||
@Resource
|
||||
private CoreTubeTaskDispatchService dispatchService;
|
||||
|
||||
/** 每次每租户最多创建一条备货现场任务。 */
|
||||
@XxlJob("dailyPlanStockingJob")
|
||||
@TenantJob
|
||||
public void dailyPlanStockingJob() {
|
||||
String result = dispatchService.dispatchStockingOnce();
|
||||
log.info("日计划备货调度完成:{}", result);
|
||||
XxlJobHelper.log(result);
|
||||
XxlJobHelper.handleSuccess(result);
|
||||
}
|
||||
|
||||
/** 每次每租户最多创建一条单根管芯出库任务。 */
|
||||
@XxlJob("dailyPlanSleevingJob")
|
||||
@TenantJob
|
||||
public void dailyPlanSleevingJob() {
|
||||
String result = dispatchService.dispatchSleevingOnce();
|
||||
log.info("日计划套管调度完成:{}", result);
|
||||
XxlJobHelper.log(result);
|
||||
XxlJobHelper.handleSuccess(result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package cn.code.nl.module.lms.service.coretube;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/** 管芯现场任务回调上下文。 */
|
||||
@Data
|
||||
public class CoreTubeTaskContext {
|
||||
private String bizType;
|
||||
private Long dailyPlanId;
|
||||
private String claimToken;
|
||||
private Long coreTubeId;
|
||||
private String coreTubeCode;
|
||||
private String vehicleCode;
|
||||
private Long sourcePointId;
|
||||
private String sourcePointCode;
|
||||
private Long targetPointId;
|
||||
private String targetPointCode;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package cn.code.nl.module.lms.service.coretube;
|
||||
|
||||
/** 管芯日计划现场任务调度服务。 */
|
||||
public interface CoreTubeTaskDispatchService {
|
||||
|
||||
/** 执行一轮备货调度。 */
|
||||
String dispatchStockingOnce();
|
||||
|
||||
/** 执行一轮套管调度。 */
|
||||
String dispatchSleevingOnce();
|
||||
|
||||
/** 处理任务完成。 */
|
||||
void handleFinished(Long taskId, boolean sleeving);
|
||||
|
||||
/** 处理任务取消。 */
|
||||
void handleCancelled(Long taskId, boolean sleeving);
|
||||
}
|
||||
@@ -0,0 +1,330 @@
|
||||
package cn.code.nl.module.lms.service.coretube;
|
||||
|
||||
import cn.code.nl.framework.common.pojo.CommonResult;
|
||||
import cn.code.nl.framework.common.util.json.JsonUtils;
|
||||
import cn.code.nl.module.lms.dal.dataobject.coretube.CoreTubeDO;
|
||||
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.CoreTubeHandleCodeConstants;
|
||||
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 cn.code.nl.module.lms.enums.CoreTubeTaskBizTypeEnum;
|
||||
import cn.code.nl.module.lms.service.dailyplan.DailyPlanScheduleCandidate;
|
||||
import cn.code.nl.module.lms.service.dailyplan.DailyPlanScheduleService;
|
||||
import cn.code.nl.module.task.api.TransportTaskApi;
|
||||
import cn.code.nl.module.task.dto.TaskInfoDTO;
|
||||
import cn.code.nl.module.task.dto.TransportTaskCreateReqDTO;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/** 管芯日计划现场任务调度服务实现。 */
|
||||
@Slf4j
|
||||
@Service
|
||||
public class CoreTubeTaskDispatchServiceImpl implements CoreTubeTaskDispatchService {
|
||||
|
||||
private static final String OPERATOR = "SCHEDULER";
|
||||
private static final String OWNER_SERVICE = "LMS";
|
||||
|
||||
@Resource
|
||||
private DailyPlanScheduleService dailyPlanScheduleService;
|
||||
@Resource
|
||||
private CoreTubeMapper coreTubeMapper;
|
||||
@Resource
|
||||
private StockingIvtMapper stockingIvtMapper;
|
||||
@Resource
|
||||
private TransportTaskApi transportTaskApi;
|
||||
|
||||
@Value("${lms.core-tube.agv-system-type:AGV}")
|
||||
private String agvSystemType;
|
||||
@Value("${lms.core-tube.pallet-in-acs-type:CORE_PALLET_IN}")
|
||||
private String palletInAcsType;
|
||||
@Value("${lms.core-tube.pallet-out-acs-type:CORE_PALLET_OUT}")
|
||||
private String palletOutAcsType;
|
||||
@Value("${lms.core-tube.stocking-pick-acs-type:CORE_STOCKING_PICK}")
|
||||
private String stockingPickAcsType;
|
||||
@Value("${lms.core-tube.sleeving-out-acs-type:CORE_SLEEVING_OUT}")
|
||||
private String sleevingOutAcsType;
|
||||
@Value("${lms.core-tube.stocking-target-point:CORE_WAREHOUSE_IN}")
|
||||
private String stockingTargetPoint;
|
||||
@Value("${lms.core-tube.sleeving-target-point:SLEEVING_IN}")
|
||||
private String sleevingTargetPoint;
|
||||
|
||||
/** 执行一轮备货调度。 */
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public String dispatchStockingOnce() {
|
||||
List<DailyPlanScheduleCandidate> candidates = dailyPlanScheduleService.previewStockingCandidates();
|
||||
if (candidates.isEmpty()) {
|
||||
return "没有待备货日计划";
|
||||
}
|
||||
Set<Long> checkedMaterials = new HashSet<>();
|
||||
for (DailyPlanScheduleCandidate candidate : candidates) {
|
||||
if (!checkedMaterials.add(candidate.getMaterialId())) {
|
||||
continue;
|
||||
}
|
||||
CoreTubeDO tube = coreTubeMapper.selectAvailableDockTube(candidate.getMaterialId());
|
||||
if (tube != null) {
|
||||
Long taskId = createSingleTubeTask(candidate, tube, false);
|
||||
return "已创建管芯抓取任务,taskId=" + taskId + ",管芯=" + tube.getCoreTubeCode();
|
||||
}
|
||||
}
|
||||
return createPalletTask(candidates, checkedMaterials);
|
||||
}
|
||||
|
||||
/** 执行一轮套管调度。 */
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public String dispatchSleevingOnce() {
|
||||
List<DailyPlanScheduleCandidate> candidates = dailyPlanScheduleService.previewSleevingCandidates();
|
||||
if (candidates.isEmpty()) {
|
||||
return "没有待套管日计划";
|
||||
}
|
||||
Set<Long> checkedMaterials = new HashSet<>();
|
||||
for (DailyPlanScheduleCandidate candidate : candidates) {
|
||||
if (!checkedMaterials.add(candidate.getMaterialId())) {
|
||||
continue;
|
||||
}
|
||||
CoreTubeDO tube = coreTubeMapper.selectAvailableWarehouseTube(candidate.getMaterialId());
|
||||
if (tube != null) {
|
||||
Long taskId = createSingleTubeTask(candidate, tube, true);
|
||||
return "已创建管芯出库任务,taskId=" + taskId + ",管芯=" + tube.getCoreTubeCode();
|
||||
}
|
||||
if (hasStockingTask(candidate.getMaterialId())) {
|
||||
log.info("{}管芯正在备货,跳过日计划{}", candidate.getMaterialSpec(), candidate.getPlanCode());
|
||||
} else {
|
||||
log.info("备货区{}管芯库存不足,跳过日计划{}", candidate.getMaterialSpec(), candidate.getPlanCode());
|
||||
}
|
||||
}
|
||||
return "全部待套管规格当前均无可出库管芯";
|
||||
}
|
||||
|
||||
/** 创建单根抓取或出库任务。 */
|
||||
protected Long createSingleTubeTask(DailyPlanScheduleCandidate preview, CoreTubeDO tube, boolean sleeving) {
|
||||
DailyPlanScheduleCandidate claim = sleeving
|
||||
? dailyPlanScheduleService.claimSleevingCandidate(preview.getDailyPlanId(), OPERATOR)
|
||||
: dailyPlanScheduleService.claimStockingCandidate(preview.getDailyPlanId(), OPERATOR);
|
||||
int oldStage = sleeving ? CoreTubeStageEnum.CORE_WAREHOUSE.getCode() : CoreTubeStageEnum.STOCKING_AREA.getCode();
|
||||
int newStage = sleeving ? CoreTubeStageEnum.CORE_OUTBOUND.getCode() : CoreTubeStageEnum.STOCKING_PICKING.getCode();
|
||||
if (coreTubeMapper.reserveTube(tube.getCoreTubeId(), oldStage, newStage, claim.getDailyPlanId(),
|
||||
claim.getClaimToken(), claim.getClaimExpireTime(), OPERATOR) != 1) {
|
||||
dailyPlanScheduleService.releaseClaim(claim.getClaimToken(), OPERATOR);
|
||||
throw new IllegalStateException("管芯已被其他任务占用");
|
||||
}
|
||||
CoreTubeTaskContext context = new CoreTubeTaskContext();
|
||||
context.setBizType((sleeving ? CoreTubeTaskBizTypeEnum.CORE_TUBE_SLEEVING_OUT
|
||||
: CoreTubeTaskBizTypeEnum.CORE_TUBE_STOCKING_PICK).name());
|
||||
context.setDailyPlanId(claim.getDailyPlanId());
|
||||
context.setClaimToken(claim.getClaimToken());
|
||||
context.setCoreTubeId(tube.getCoreTubeId());
|
||||
context.setCoreTubeCode(tube.getCoreTubeCode());
|
||||
context.setVehicleCode(tube.getVehicleCode());
|
||||
context.setSourcePointId(tube.getCurrentLocationId());
|
||||
context.setSourcePointCode(tube.getCurrentLocationCode());
|
||||
context.setTargetPointCode(sleeving ? sleevingTargetPoint : stockingTargetPoint);
|
||||
String bizType = context.getBizType();
|
||||
String bizId = tube.getCoreTubeCode();
|
||||
Long taskId = createTask(buildTubeTask(claim, tube, context, sleeving), bizType, bizId);
|
||||
if (coreTubeMapper.bindTask(tube.getCoreTubeId(), taskId, OPERATOR) != 1) {
|
||||
throw new IllegalStateException("管芯任务绑定失败");
|
||||
}
|
||||
dailyPlanScheduleService.confirmTaskCreated(claim.getClaimToken(), OPERATOR);
|
||||
return taskId;
|
||||
}
|
||||
|
||||
/** 所有规格不能直接抓取时创建一条托盘任务。 */
|
||||
private String createPalletTask(List<DailyPlanScheduleCandidate> candidates, Set<Long> checkedMaterials) {
|
||||
StockingIvtDO occupiedDock = stockingIvtMapper.selectOccupiedDockPoint();
|
||||
if (occupiedDock != null) {
|
||||
StockingIvtDO target = stockingIvtMapper.selectEmptyCachePoint();
|
||||
if (target == null) {
|
||||
return "对接位存在非目标托盘,但没有空缓存位可移出";
|
||||
}
|
||||
Long taskId = createPalletMoveTask(occupiedDock, target, occupiedDock.getVehicleCode(), true, null);
|
||||
return "已创建托盘移出任务,taskId=" + taskId;
|
||||
}
|
||||
StockingIvtDO dock = stockingIvtMapper.selectEmptyDockPoint();
|
||||
if (dock == null) {
|
||||
return "没有可用的备货对接位";
|
||||
}
|
||||
for (DailyPlanScheduleCandidate candidate : candidates) {
|
||||
if (!checkedMaterials.contains(candidate.getMaterialId())) {
|
||||
continue;
|
||||
}
|
||||
String materialBizId = "MATERIAL:" + candidate.getMaterialId();
|
||||
if (getUnfinished(CoreTubeTaskBizTypeEnum.CORE_TUBE_PALLET_IN.name(), materialBizId) != null) {
|
||||
continue;
|
||||
}
|
||||
StockingIvtDO source = stockingIvtMapper.selectBestCacheVehicle(candidate.getMaterialId(),
|
||||
candidate.getRemainingQuantity());
|
||||
if (source != null) {
|
||||
Long taskId = createPalletMoveTask(source, dock, source.getVehicleCode(), false, candidate);
|
||||
return "已创建托盘移入任务,taskId=" + taskId;
|
||||
}
|
||||
log.info("备货区没有可用的{}管芯,跳过日计划{}", candidate.getMaterialSpec(), candidate.getPlanCode());
|
||||
}
|
||||
return "备货区没有任何候选规格的可用管芯托盘";
|
||||
}
|
||||
|
||||
/** 创建托盘点位转移任务。 */
|
||||
private Long createPalletMoveTask(StockingIvtDO source, StockingIvtDO target, String vehicleCode,
|
||||
boolean moveOut, DailyPlanScheduleCandidate candidate) {
|
||||
CoreTubeTaskContext context = new CoreTubeTaskContext();
|
||||
context.setBizType((moveOut ? CoreTubeTaskBizTypeEnum.CORE_TUBE_PALLET_OUT
|
||||
: CoreTubeTaskBizTypeEnum.CORE_TUBE_PALLET_IN).name());
|
||||
context.setDailyPlanId(candidate == null ? null : candidate.getDailyPlanId());
|
||||
context.setVehicleCode(vehicleCode);
|
||||
context.setSourcePointId(source.getIvtId());
|
||||
context.setSourcePointCode(source.getPointCode());
|
||||
context.setTargetPointId(target.getIvtId());
|
||||
context.setTargetPointCode(target.getPointCode());
|
||||
TransportTaskCreateReqDTO request = baseTask(context, moveOut ? "管芯托盘移出" : "管芯托盘移入",
|
||||
moveOut ? palletOutAcsType : palletInAcsType, CoreTubeHandleCodeConstants.CORE_TUBE_STOCKING_TASK);
|
||||
request.setVehicleCode(vehicleCode);
|
||||
request.setPointCode1(source.getPointCode());
|
||||
request.setPointCode2(target.getPointCode());
|
||||
request.setMaterialId(candidate == null ? null : candidate.getMaterialId());
|
||||
request.setMaterialCode(candidate == null ? null : candidate.getMaterialCode());
|
||||
String bizId = moveOut ? "DOCK:" + source.getPointCode() : "MATERIAL:" + candidate.getMaterialId();
|
||||
return createTask(request, context.getBizType(), bizId);
|
||||
}
|
||||
|
||||
/** 构造单根管芯任务。 */
|
||||
private TransportTaskCreateReqDTO buildTubeTask(DailyPlanScheduleCandidate candidate, CoreTubeDO tube,
|
||||
CoreTubeTaskContext context, boolean sleeving) {
|
||||
TransportTaskCreateReqDTO request = baseTask(context, sleeving ? "日计划管芯出库" : "日计划管芯抓取",
|
||||
sleeving ? sleevingOutAcsType : stockingPickAcsType,
|
||||
sleeving ? CoreTubeHandleCodeConstants.CORE_TUBE_SLEEVING_TASK
|
||||
: CoreTubeHandleCodeConstants.CORE_TUBE_STOCKING_TASK);
|
||||
request.setPointCode1(tube.getCurrentLocationCode());
|
||||
request.setPointCode2(context.getTargetPointCode());
|
||||
request.setVehicleCode(tube.getCoreTubeCode());
|
||||
request.setMaterialId(candidate.getMaterialId());
|
||||
request.setMaterialCode(candidate.getMaterialCode());
|
||||
return request;
|
||||
}
|
||||
|
||||
/** 构造任务公共字段。 */
|
||||
private TransportTaskCreateReqDTO baseTask(CoreTubeTaskContext context, String taskName, String acsType,
|
||||
String handleCode) {
|
||||
TransportTaskCreateReqDTO request = new TransportTaskCreateReqDTO();
|
||||
request.setTaskName(taskName);
|
||||
request.setOwnerService(OWNER_SERVICE);
|
||||
request.setBizType(context.getBizType());
|
||||
request.setHandleCode(handleCode);
|
||||
request.setAcsTaskType(acsType);
|
||||
request.setAgvSystemType(agvSystemType);
|
||||
request.setIsAutoIssue("1");
|
||||
request.setIsCreateFinish(true);
|
||||
request.setRequestParam(JsonUtils.toJsonString(context));
|
||||
return request;
|
||||
}
|
||||
|
||||
/** 创建任务并处理响应不确定场景。 */
|
||||
private Long createTask(TransportTaskCreateReqDTO request, String bizType, String bizId) {
|
||||
request.setBizType(bizType);
|
||||
request.setBizId(bizId);
|
||||
CommonResult<Long> result = transportTaskApi.createTransportTask(request);
|
||||
if (result != null && result.isSuccess() && result.getData() != null) {
|
||||
return result.getData();
|
||||
}
|
||||
TaskInfoDTO existing = getUnfinished(bizType, bizId);
|
||||
if (existing != null) {
|
||||
return existing.getTaskId();
|
||||
}
|
||||
throw new IllegalStateException("创建现场任务失败:" + (result == null ? "无响应" : result.getMsg()));
|
||||
}
|
||||
|
||||
/** 查询未完成业务任务。 */
|
||||
private TaskInfoDTO getUnfinished(String bizType, String bizId) {
|
||||
CommonResult<TaskInfoDTO> result = transportTaskApi.getUnfinishedTaskByBiz(OWNER_SERVICE, bizType, bizId);
|
||||
return result != null && result.isSuccess() ? result.getData() : null;
|
||||
}
|
||||
|
||||
/** 判断目标物料是否正在备货。 */
|
||||
private boolean hasStockingTask(Long materialId) {
|
||||
if (getUnfinished(CoreTubeTaskBizTypeEnum.CORE_TUBE_PALLET_IN.name(), "MATERIAL:" + materialId) != null) {
|
||||
return true;
|
||||
}
|
||||
CommonResult<List<TaskInfoDTO>> result = transportTaskApi.getRunningTaskByMaterialId(materialId, OWNER_SERVICE);
|
||||
return result != null && result.isSuccess() && result.getData() != null
|
||||
&& result.getData().stream().anyMatch(task ->
|
||||
CoreTubeTaskBizTypeEnum.CORE_TUBE_PALLET_IN.name().equals(task.getBizType())
|
||||
|| CoreTubeTaskBizTypeEnum.CORE_TUBE_STOCKING_PICK.name().equals(task.getBizType()));
|
||||
}
|
||||
|
||||
/** 处理任务完成。 */
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void handleFinished(Long taskId, boolean sleeving) {
|
||||
TaskInfoDTO task = getTask(taskId);
|
||||
CoreTubeTaskContext context = JsonUtils.parseObject(task.getRequestParam(), CoreTubeTaskContext.class);
|
||||
if (CoreTubeTaskBizTypeEnum.CORE_TUBE_PALLET_IN.name().equals(context.getBizType())
|
||||
|| CoreTubeTaskBizTypeEnum.CORE_TUBE_PALLET_OUT.name().equals(context.getBizType())) {
|
||||
int affected = stockingIvtMapper.completeVehicleMove(context.getSourcePointId(),
|
||||
context.getTargetPointId(), context.getVehicleCode(), OPERATOR);
|
||||
if (affected == 0) {
|
||||
return;
|
||||
}
|
||||
if (affected != 2) {
|
||||
throw new IllegalStateException("托盘点位转移状态不完整,taskId=" + taskId);
|
||||
}
|
||||
int locationType = CoreTubeTaskBizTypeEnum.CORE_TUBE_PALLET_IN.name().equals(context.getBizType())
|
||||
? CoreTubeLocationTypeEnum.STOCKING_DOCK.getCode()
|
||||
: CoreTubeLocationTypeEnum.STOCKING_CACHE.getCode();
|
||||
coreTubeMapper.updateVehicleLocation(context.getVehicleCode(), locationType,
|
||||
context.getTargetPointId(), context.getTargetPointCode(), OPERATOR);
|
||||
return;
|
||||
}
|
||||
int stage = sleeving ? CoreTubeStageEnum.SLEEVING.getCode() : CoreTubeStageEnum.CORE_WAREHOUSE.getCode();
|
||||
int locationType = sleeving ? CoreTubeLocationTypeEnum.EQUIPMENT.getCode()
|
||||
: CoreTubeLocationTypeEnum.CORE_WAREHOUSE.getCode();
|
||||
if (coreTubeMapper.completeTubeTask(context.getCoreTubeId(), taskId, stage,
|
||||
sleeving ? CoreTubeStatusEnum.PROCESSING.getCode() : CoreTubeStatusEnum.AVAILABLE.getCode(),
|
||||
locationType, context.getTargetPointId(), context.getTargetPointCode(), true, OPERATOR) == 1) {
|
||||
if (sleeving) {
|
||||
dailyPlanScheduleService.increaseSleevedQuantity(context.getClaimToken(),
|
||||
context.getDailyPlanId(), 1, OPERATOR);
|
||||
} else {
|
||||
stockingIvtMapper.clearPaperVehicleCoreTube(context.getCoreTubeId(), OPERATOR);
|
||||
dailyPlanScheduleService.increaseStockedQuantity(context.getClaimToken(),
|
||||
context.getDailyPlanId(), 1, OPERATOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 处理任务取消。 */
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void handleCancelled(Long taskId, boolean sleeving) {
|
||||
TaskInfoDTO task = getTask(taskId);
|
||||
CoreTubeTaskContext context = JsonUtils.parseObject(task.getRequestParam(), CoreTubeTaskContext.class);
|
||||
if (context.getCoreTubeId() == null) {
|
||||
return;
|
||||
}
|
||||
int affected = coreTubeMapper.cancelTubeTask(context.getCoreTubeId(), taskId,
|
||||
sleeving ? CoreTubeStageEnum.CORE_WAREHOUSE.getCode() : CoreTubeStageEnum.STOCKING_AREA.getCode(),
|
||||
OPERATOR);
|
||||
if (affected == 1) {
|
||||
dailyPlanScheduleService.releaseClaim(context.getClaimToken(), OPERATOR);
|
||||
}
|
||||
}
|
||||
|
||||
/** 查询任务详情。 */
|
||||
private TaskInfoDTO getTask(Long taskId) {
|
||||
CommonResult<TaskInfoDTO> result = transportTaskApi.getTaskById(taskId);
|
||||
if (result == null || !result.isSuccess() || result.getData() == null) {
|
||||
throw new IllegalStateException("管芯任务不存在,taskId=" + taskId);
|
||||
}
|
||||
return result.getData();
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,8 @@ public class DailyPlanScheduleCandidate {
|
||||
private String materialSpec;
|
||||
/** 本轮建议处理数量。 */
|
||||
private Integer suggestedQuantity;
|
||||
/** 当前作业尚需处理数量,用于整托盘择优。 */
|
||||
private Integer remainingQuantity;
|
||||
/** 日计划乐观锁版本号。 */
|
||||
private Integer version;
|
||||
/** 本轮使用的策略模式。 */
|
||||
|
||||
@@ -107,7 +107,7 @@ public class DailyPlanScheduleServiceImpl implements DailyPlanScheduleService {
|
||||
}
|
||||
List<DailyPlanScheduleCandidate> result = new ArrayList<>(ordered.size());
|
||||
for (DailyPlanDO plan : ordered) {
|
||||
result.add(convertCandidate(plan, mode.getCode()));
|
||||
result.add(convertCandidate(plan, mode.getCode(), type));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -176,7 +176,7 @@ public class DailyPlanScheduleServiceImpl implements DailyPlanScheduleService {
|
||||
} catch (DuplicateKeyException ex) {
|
||||
throw exception(DAILY_PLAN_CLAIM_CONFLICT);
|
||||
}
|
||||
DailyPlanScheduleCandidate candidate = convertCandidate(plan, strategyMode);
|
||||
DailyPlanScheduleCandidate candidate = convertCandidate(plan, strategyMode, type);
|
||||
candidate.setSuggestedQuantity(quantity);
|
||||
candidate.setClaimToken(claim.getClaimToken());
|
||||
candidate.setClaimExpireTime(expireTime);
|
||||
@@ -184,7 +184,8 @@ public class DailyPlanScheduleServiceImpl implements DailyPlanScheduleService {
|
||||
}
|
||||
|
||||
/** 将日计划转换为调度候选。 */
|
||||
private DailyPlanScheduleCandidate convertCandidate(DailyPlanDO plan, Integer strategyMode) {
|
||||
private DailyPlanScheduleCandidate convertCandidate(DailyPlanDO plan, Integer strategyMode,
|
||||
DailyPlanStrategyTypeEnum type) {
|
||||
DailyPlanScheduleCandidate candidate = new DailyPlanScheduleCandidate();
|
||||
candidate.setDailyPlanId(plan.getDailyPlanId());
|
||||
candidate.setPlanCode(plan.getPlanCode());
|
||||
@@ -193,6 +194,9 @@ public class DailyPlanScheduleServiceImpl implements DailyPlanScheduleService {
|
||||
candidate.setMaterialName(plan.getMaterialName());
|
||||
candidate.setMaterialSpec(plan.getMaterialSpec());
|
||||
candidate.setSuggestedQuantity(1);
|
||||
int total = Math.addExact(plan.getPlanQty(), plan.getAppendQty());
|
||||
int progress = type == DailyPlanStrategyTypeEnum.STOCKING ? plan.getStockedQty() : plan.getSleevedQty();
|
||||
candidate.setRemainingQuantity(total - progress);
|
||||
candidate.setVersion(plan.getVersion());
|
||||
candidate.setStrategyMode(strategyMode);
|
||||
return candidate;
|
||||
@@ -204,6 +208,10 @@ public class DailyPlanScheduleServiceImpl implements DailyPlanScheduleService {
|
||||
public void confirmTaskCreated(String claimToken, String operator) {
|
||||
DailyPlanClaimDO claim = getClaimForUpdate(claimToken);
|
||||
validateActiveClaim(claim);
|
||||
if (!claim.getTaskCreated()
|
||||
&& dailyPlanClaimMapper.markTaskCreated(claimToken, normalizedOperator(operator)) != 1) {
|
||||
throw exception(DAILY_PLAN_CLAIM_INVALID);
|
||||
}
|
||||
DailyPlanStrategyTypeEnum type = DailyPlanStrategyTypeEnum.getByCode(claim.getStrategyType());
|
||||
if (type == null) {
|
||||
throw exception(DAILY_PLAN_STRATEGY_NOT_EXISTS);
|
||||
@@ -353,7 +361,7 @@ public class DailyPlanScheduleServiceImpl implements DailyPlanScheduleService {
|
||||
|
||||
private void validateActiveClaim(DailyPlanClaimDO claim) {
|
||||
if (!Integer.valueOf(CLAIM_ACTIVE).equals(claim.getClaimStatus()) || claim.getActiveFlag() == null
|
||||
|| !claim.getExpireTime().isAfter(LocalDateTime.now())) {
|
||||
|| !claim.getTaskCreated() && !claim.getExpireTime().isAfter(LocalDateTime.now())) {
|
||||
throw exception(DAILY_PLAN_CLAIM_INVALID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package cn.code.nl.module.lms.task;
|
||||
|
||||
import cn.code.nl.framework.execute.core.AbstractTask;
|
||||
import cn.code.nl.framework.execute.core.dto.TaskExecuteDTO;
|
||||
import cn.code.nl.module.lms.enums.CoreTubeHandleCodeConstants;
|
||||
import cn.code.nl.module.lms.service.coretube.CoreTubeTaskDispatchService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/** 管芯库单根出库任务回调。 */
|
||||
@Component(CoreTubeHandleCodeConstants.CORE_TUBE_SLEEVING_TASK)
|
||||
public class CoreTubeSleevingTask extends AbstractTask {
|
||||
|
||||
@Resource
|
||||
private CoreTubeTaskDispatchService dispatchService;
|
||||
|
||||
@Override
|
||||
public void doHandleFinish(TaskExecuteDTO taskExecuteDTO) {
|
||||
dispatchService.handleFinished(taskExecuteDTO.getTaskId(), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doHandleCancel(TaskExecuteDTO taskExecuteDTO) {
|
||||
dispatchService.handleCancelled(taskExecuteDTO.getTaskId(), true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package cn.code.nl.module.lms.task;
|
||||
|
||||
import cn.code.nl.framework.execute.core.AbstractTask;
|
||||
import cn.code.nl.framework.execute.core.dto.TaskExecuteDTO;
|
||||
import cn.code.nl.module.lms.enums.CoreTubeHandleCodeConstants;
|
||||
import cn.code.nl.module.lms.service.coretube.CoreTubeTaskDispatchService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/** 备货区托盘搬运及管芯抓取任务回调。 */
|
||||
@Component(CoreTubeHandleCodeConstants.CORE_TUBE_STOCKING_TASK)
|
||||
public class CoreTubeStockingTask extends AbstractTask {
|
||||
|
||||
@Resource
|
||||
private CoreTubeTaskDispatchService dispatchService;
|
||||
|
||||
@Override
|
||||
public void doHandleFinish(TaskExecuteDTO taskExecuteDTO) {
|
||||
dispatchService.handleFinished(taskExecuteDTO.getTaskId(), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doHandleCancel(TaskExecuteDTO taskExecuteDTO) {
|
||||
dispatchService.handleCancelled(taskExecuteDTO.getTaskId(), false);
|
||||
}
|
||||
}
|
||||
@@ -48,4 +48,88 @@
|
||||
#{tube.currentLocationType}, #{tube.currentLocationId}, #{tube.currentLocationCode},
|
||||
0, #{tube.creator}, #{tube.updater})
|
||||
</insert>
|
||||
|
||||
<select id="selectAvailableDockTube"
|
||||
resultType="cn.code.nl.module.lms.dal.dataobject.coretube.CoreTubeDO">
|
||||
SELECT tube.*
|
||||
FROM lms_core_tube tube
|
||||
JOIN lms_ivt_stockingivt point ON point.ivt_id = tube.current_location_id
|
||||
WHERE tube.material_id = #{materialId}
|
||||
AND tube.stage = 1 AND tube.status = 1
|
||||
AND tube.reserved_task_id IS NULL AND tube.deleted = b'0'
|
||||
AND point.point_type = '3' AND point.is_used = '0'
|
||||
ORDER BY point.sort_seq, tube.row_num, tube.col_num, tube.core_tube_id
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<select id="selectAvailableWarehouseTube"
|
||||
resultType="cn.code.nl.module.lms.dal.dataobject.coretube.CoreTubeDO">
|
||||
SELECT <include refid="coreTubeColumns"/>
|
||||
FROM lms_core_tube
|
||||
WHERE material_id = #{materialId}
|
||||
AND stage = 3 AND status = 1
|
||||
AND reserved_task_id IS NULL AND deleted = b'0'
|
||||
ORDER BY current_location_code, core_tube_id
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<update id="reserveTube">
|
||||
UPDATE lms_core_tube
|
||||
SET stage = #{newStage}, status = 2,
|
||||
reserved_daily_plan_id = #{dailyPlanId}, reserved_claim_token = #{claimToken},
|
||||
reserve_expire_time = #{expireTime}, updater = #{updater}, version = version + 1
|
||||
WHERE core_tube_id = #{coreTubeId}
|
||||
AND stage = #{expectedStage} AND status = 1
|
||||
AND reserved_task_id IS NULL AND deleted = b'0'
|
||||
</update>
|
||||
|
||||
<update id="bindTask">
|
||||
UPDATE lms_core_tube
|
||||
SET reserved_task_id = #{taskId}, status = 3, updater = #{updater}, version = version + 1
|
||||
WHERE core_tube_id = #{coreTubeId}
|
||||
AND status = 2 AND reserved_task_id IS NULL AND deleted = b'0'
|
||||
</update>
|
||||
|
||||
<update id="releaseReservation">
|
||||
UPDATE lms_core_tube
|
||||
SET stage = #{stage}, status = 1,
|
||||
reserved_daily_plan_id = NULL, reserved_claim_token = NULL,
|
||||
reserve_expire_time = NULL, updater = #{updater}, version = version + 1
|
||||
WHERE core_tube_id = #{coreTubeId}
|
||||
AND reserved_claim_token = #{claimToken}
|
||||
AND reserved_task_id IS NULL AND deleted = b'0'
|
||||
</update>
|
||||
|
||||
<update id="completeTubeTask">
|
||||
UPDATE lms_core_tube
|
||||
SET stage = #{stage}, status = #{status},
|
||||
current_location_type = #{locationType}, current_location_id = #{locationId},
|
||||
current_location_code = #{locationCode},
|
||||
vehicle_code = CASE WHEN #{clearVehicle} THEN NULL ELSE vehicle_code END,
|
||||
row_num = CASE WHEN #{clearVehicle} THEN NULL ELSE row_num END,
|
||||
col_num = CASE WHEN #{clearVehicle} THEN NULL ELSE col_num END,
|
||||
active_slot = CASE WHEN #{clearVehicle} THEN NULL ELSE active_slot END,
|
||||
reserved_daily_plan_id = NULL, reserved_claim_token = NULL,
|
||||
reserved_task_id = NULL, reserve_expire_time = NULL,
|
||||
updater = #{updater}, version = version + 1
|
||||
WHERE core_tube_id = #{coreTubeId}
|
||||
AND reserved_task_id = #{taskId} AND deleted = b'0'
|
||||
</update>
|
||||
|
||||
<update id="cancelTubeTask">
|
||||
UPDATE lms_core_tube
|
||||
SET stage = #{stage}, status = 1,
|
||||
reserved_daily_plan_id = NULL, reserved_claim_token = NULL,
|
||||
reserved_task_id = NULL, reserve_expire_time = NULL,
|
||||
updater = #{updater}, version = version + 1
|
||||
WHERE core_tube_id = #{coreTubeId}
|
||||
AND reserved_task_id = #{taskId} AND deleted = b'0'
|
||||
</update>
|
||||
|
||||
<update id="updateVehicleLocation">
|
||||
UPDATE lms_core_tube
|
||||
SET current_location_type = #{locationType}, current_location_id = #{locationId},
|
||||
current_location_code = #{locationCode}, updater = #{updater}, version = version + 1
|
||||
WHERE vehicle_code = #{vehicleCode} AND active_slot = 1 AND deleted = b'0'
|
||||
</update>
|
||||
</mapper>
|
||||
|
||||
@@ -4,17 +4,17 @@
|
||||
|
||||
<sql id="claimColumns">
|
||||
claim_id, claim_token, daily_plan_id, strategy_type, claimed_qty, plan_version, progress_qty, version,
|
||||
claim_status, active_flag, expire_time, confirmed_time, operator,
|
||||
claim_status, active_flag, task_created, expire_time, confirmed_time, operator,
|
||||
creator, create_time, updater, update_time, deleted, tenant_id
|
||||
</sql>
|
||||
|
||||
<insert id="insertClaim">
|
||||
INSERT INTO lms_daily_plan_claim
|
||||
(claim_id, claim_token, daily_plan_id, strategy_type, claimed_qty, plan_version, progress_qty, version,
|
||||
claim_status, active_flag, expire_time, operator, creator, updater)
|
||||
claim_status, active_flag, task_created, expire_time, operator, creator, updater)
|
||||
VALUES
|
||||
(#{claim.claimId}, #{claim.claimToken}, #{claim.dailyPlanId}, #{claim.strategyType},
|
||||
#{claim.claimedQty}, #{claim.planVersion}, #{claim.progressQty}, 0, 0, 1, #{claim.expireTime},
|
||||
#{claim.claimedQty}, #{claim.planVersion}, #{claim.progressQty}, 0, 0, 1, b'0', #{claim.expireTime},
|
||||
#{claim.operator}, #{claim.operator}, #{claim.operator})
|
||||
</insert>
|
||||
|
||||
@@ -35,6 +35,13 @@
|
||||
UPDATE lms_daily_plan_claim
|
||||
SET claim_status = 1, active_flag = NULL, confirmed_time = NOW(), updater = #{updater}, version = version + 1
|
||||
WHERE claim_id = #{claimId} AND version = #{version} AND claim_status = 0 AND active_flag = 1
|
||||
AND (task_created = b'1' OR expire_time > NOW(6)) AND deleted = b'0'
|
||||
</update>
|
||||
|
||||
<update id="markTaskCreated">
|
||||
UPDATE lms_daily_plan_claim
|
||||
SET task_created = b'1', updater = #{updater}, version = version + 1
|
||||
WHERE claim_token = #{claimToken} AND claim_status = 0 AND active_flag = 1
|
||||
AND expire_time > NOW(6) AND deleted = b'0'
|
||||
</update>
|
||||
|
||||
@@ -54,7 +61,8 @@
|
||||
<update id="expireClaims">
|
||||
UPDATE lms_daily_plan_claim
|
||||
SET claim_status = 3, active_flag = NULL, updater = #{updater}
|
||||
WHERE claim_status = 0 AND active_flag = 1 AND expire_time <= #{now} AND deleted = b'0'
|
||||
WHERE claim_status = 0 AND active_flag = 1 AND task_created = b'0'
|
||||
AND expire_time <= #{now} AND deleted = b'0'
|
||||
</update>
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
AND claim.tenant_id = lms_daily_plan.tenant_id
|
||||
AND claim.strategy_type = #{strategyType}
|
||||
AND claim.claim_status = 0 AND claim.active_flag = 1
|
||||
AND claim.expire_time > NOW(6) AND claim.deleted = b'0'
|
||||
AND (claim.task_created = b'1' OR claim.expire_time > NOW(6)) AND claim.deleted = b'0'
|
||||
)
|
||||
FOR UPDATE
|
||||
</select>
|
||||
@@ -124,7 +124,8 @@
|
||||
WHERE claim.daily_plan_id = lms_daily_plan.daily_plan_id
|
||||
AND claim.tenant_id = lms_daily_plan.tenant_id
|
||||
AND claim.strategy_type = 1 AND claim.claim_status = 0
|
||||
AND claim.active_flag = 1 AND claim.expire_time > NOW(6) AND claim.deleted = b'0'
|
||||
AND claim.active_flag = 1
|
||||
AND (claim.task_created = b'1' OR claim.expire_time > NOW(6)) AND claim.deleted = b'0'
|
||||
)
|
||||
ORDER BY sort_seq ASC, daily_plan_id ASC
|
||||
</select>
|
||||
@@ -142,7 +143,8 @@
|
||||
WHERE claim.daily_plan_id = lms_daily_plan.daily_plan_id
|
||||
AND claim.tenant_id = lms_daily_plan.tenant_id
|
||||
AND claim.strategy_type = 2 AND claim.claim_status = 0
|
||||
AND claim.active_flag = 1 AND claim.expire_time > NOW(6) AND claim.deleted = b'0'
|
||||
AND claim.active_flag = 1
|
||||
AND (claim.task_created = b'1' OR claim.expire_time > NOW(6)) AND claim.deleted = b'0'
|
||||
)
|
||||
ORDER BY sort_seq ASC, daily_plan_id ASC
|
||||
</select>
|
||||
|
||||
@@ -120,4 +120,73 @@
|
||||
#{tube.materialCode}, #{tube.materialName}, 1, #{tube.creator}, #{tube.updater})
|
||||
</insert>
|
||||
|
||||
<update id="clearPaperVehicleCoreTube">
|
||||
UPDATE lms_base_papervehicle
|
||||
SET core_tube_id = NULL,
|
||||
core_tube_code = NULL,
|
||||
material_code = NULL,
|
||||
material_name = NULL,
|
||||
qty = 0,
|
||||
updater = #{updater}
|
||||
WHERE core_tube_id = #{coreTubeId}
|
||||
</update>
|
||||
|
||||
<select id="selectOccupiedDockPoint"
|
||||
resultType="cn.code.nl.module.lms.dal.dataobject.stockingivt.StockingIvtDO">
|
||||
SELECT <include refid="stockingIvtColumns"/>
|
||||
FROM lms_ivt_stockingivt
|
||||
WHERE point_type = '3' AND is_used = '0'
|
||||
AND ivt_status = '2' AND vehicle_code IS NOT NULL AND vehicle_code != ''
|
||||
ORDER BY sort_seq, ivt_id
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<select id="selectEmptyDockPoint"
|
||||
resultType="cn.code.nl.module.lms.dal.dataobject.stockingivt.StockingIvtDO">
|
||||
SELECT <include refid="stockingIvtColumns"/>
|
||||
FROM lms_ivt_stockingivt
|
||||
WHERE point_type = '3' AND is_used = '0' AND ivt_status = '1'
|
||||
ORDER BY sort_seq, ivt_id
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<select id="selectEmptyCachePoint"
|
||||
resultType="cn.code.nl.module.lms.dal.dataobject.stockingivt.StockingIvtDO">
|
||||
SELECT <include refid="stockingIvtColumns"/>
|
||||
FROM lms_ivt_stockingivt
|
||||
WHERE point_type = '2' AND is_used = '0' AND ivt_status = '1'
|
||||
ORDER BY sort_seq, ivt_id
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<select id="selectBestCacheVehicle"
|
||||
resultType="cn.code.nl.module.lms.dal.dataobject.stockingivt.StockingIvtDO">
|
||||
SELECT point.ivt_id, point.point_code, point.point_name, point.vehicle_code,
|
||||
point.product_area, point.point_type, point.ivt_status, point.point_location,
|
||||
point.sort_seq, point.is_used, point.remark,
|
||||
point.creator, point.create_time, point.updater, point.update_time
|
||||
FROM lms_ivt_stockingivt point
|
||||
JOIN lms_core_tube tube ON tube.current_location_id = point.ivt_id
|
||||
WHERE point.point_type = '2' AND point.is_used = '0' AND point.ivt_status = '2'
|
||||
AND tube.material_id = #{materialId} AND tube.stage = 1 AND tube.status = 1
|
||||
AND tube.reserved_task_id IS NULL AND tube.deleted = b'0'
|
||||
GROUP BY point.ivt_id, point.point_code, point.point_name, point.vehicle_code,
|
||||
point.product_area, point.point_type, point.ivt_status, point.point_location,
|
||||
point.sort_seq, point.is_used, point.remark,
|
||||
point.creator, point.create_time, point.updater, point.update_time
|
||||
ORDER BY CASE WHEN COUNT(*) >= #{requiredQty} THEN 0 ELSE 1 END,
|
||||
CASE WHEN COUNT(*) >= #{requiredQty} THEN COUNT(*) END ASC,
|
||||
COUNT(*) DESC, point.sort_seq, point.ivt_id
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<update id="completeVehicleMove">
|
||||
UPDATE lms_ivt_stockingivt
|
||||
SET vehicle_code = CASE WHEN ivt_id = #{sourcePointId} THEN NULL ELSE #{vehicleCode} END,
|
||||
ivt_status = CASE WHEN ivt_id = #{sourcePointId} THEN '1' ELSE '2' END,
|
||||
updater = #{updater}
|
||||
WHERE (ivt_id = #{sourcePointId} AND vehicle_code = #{vehicleCode})
|
||||
OR (ivt_id = #{targetPointId} AND ivt_status = '1')
|
||||
</update>
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -48,6 +48,15 @@ PREPARE lms_core_tube_stmt FROM @lms_core_tube_ddl;
|
||||
EXECUTE lms_core_tube_stmt;
|
||||
DEALLOCATE PREPARE lms_core_tube_stmt;
|
||||
|
||||
SET @lms_core_tube_ddl = IF(
|
||||
EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE()
|
||||
AND table_name = 'lms_daily_plan_claim' AND column_name = 'task_created'),
|
||||
'SELECT 1',
|
||||
'ALTER TABLE lms_daily_plan_claim ADD COLUMN task_created BIT(1) NOT NULL DEFAULT b''0'' COMMENT ''是否已创建现场任务'' AFTER active_flag');
|
||||
PREPARE lms_core_tube_stmt FROM @lms_core_tube_ddl;
|
||||
EXECUTE lms_core_tube_stmt;
|
||||
DEALLOCATE PREPARE lms_core_tube_stmt;
|
||||
|
||||
SET @lms_core_tube_ddl = IF(
|
||||
EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE()
|
||||
AND table_name = 'lms_base_papervehicle' AND column_name = 'core_tube_code'),
|
||||
|
||||
@@ -81,6 +81,7 @@ CREATE TABLE IF NOT EXISTS `lms_daily_plan_claim` (
|
||||
`version` int NOT NULL DEFAULT 0 COMMENT '领取乐观锁版本号',
|
||||
`claim_status` tinyint NOT NULL DEFAULT 0 COMMENT '领取状态:0执行中,1已确认,2已释放,3已过期',
|
||||
`active_flag` tinyint DEFAULT 1 COMMENT '有效领取唯一标记,终态置空',
|
||||
`task_created` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否已创建现场任务',
|
||||
`expire_time` datetime(6) NOT NULL COMMENT '租约过期时间',
|
||||
`confirmed_time` datetime DEFAULT NULL COMMENT '确认时间',
|
||||
`operator` varchar(64) NOT NULL COMMENT '领取人/执行器',
|
||||
@@ -125,6 +126,14 @@ SET @lms_daily_plan_ddl = IF(
|
||||
PREPARE lms_daily_plan_stmt FROM @lms_daily_plan_ddl;
|
||||
EXECUTE lms_daily_plan_stmt;
|
||||
DEALLOCATE PREPARE lms_daily_plan_stmt;
|
||||
SET @lms_daily_plan_ddl = IF(
|
||||
EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE()
|
||||
AND table_name = 'lms_daily_plan_claim' AND column_name = 'task_created'),
|
||||
'SELECT 1',
|
||||
'ALTER TABLE lms_daily_plan_claim ADD COLUMN task_created BIT(1) NOT NULL DEFAULT b''0'' COMMENT ''是否已创建现场任务'' AFTER active_flag');
|
||||
PREPARE lms_daily_plan_stmt FROM @lms_daily_plan_ddl;
|
||||
EXECUTE lms_daily_plan_stmt;
|
||||
DEALLOCATE PREPARE lms_daily_plan_stmt;
|
||||
SET @lms_daily_plan_ddl = IF(
|
||||
EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE()
|
||||
AND table_name = 'lms_daily_plan_claim' AND column_name = 'expire_time'
|
||||
|
||||
Reference in New Issue
Block a user