package com.vincent.rsf.server.manager.schedules; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.vincent.rsf.framework.common.Cools; import com.vincent.rsf.framework.exception.CoolException; import com.vincent.rsf.server.common.constant.Constants; import com.vincent.rsf.server.manager.constant.LocGroupConstant; import com.vincent.rsf.server.manager.constant.StaGroupConstant; import com.vincent.rsf.server.manager.controller.params.LocToTaskParams; import com.vincent.rsf.server.manager.entity.*; import com.vincent.rsf.server.manager.enums.*; import com.vincent.rsf.server.manager.service.*; import com.vincent.rsf.server.manager.service.impl.DeviceSiteServiceImpl; import com.vincent.rsf.server.system.constant.SerialRuleCode; import com.vincent.rsf.server.system.service.ConfigService; import com.vincent.rsf.server.system.utils.SerialRuleUtils; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import java.util.*; import static com.vincent.rsf.server.system.utils.SystemAuthUtils.getLoginUserId; /** * 自动跑库程序 */ @Slf4j @Component public class AutoRunSchedules { @Autowired private LocService locService; @Autowired private ConfigService configService; @Autowired private BasStationService stationService; @Autowired private TaskService taskService; @Autowired private TaskItemService taskItemService; @Autowired private MatnrService matnrService; @Autowired private LocItemService locItemService; @Autowired private DeviceSiteService deviceSiteService; /** * @author Ryan * @date 2025/9/1 * @description: 自动生成盘点跑库单 * @version 1.0 */ public void autoCheckOrders() { Boolean autoRunArea = configService.getVal("AUTO_RUN_CHECK_ORDERS", Boolean.class); if (!autoRunArea) { return; } //获取任务列表中,为盘点出库的任务 List tasks = taskService.list(new LambdaQueryWrapper() .in(Task::getTaskType, Arrays.asList(TaskType.TASK_TYPE_CHECK_OUT.type, TaskType.TASK_TYPE_CHECK_IN.type))); if (tasks.size() >= 10) { return; } List locs = locService.list(new LambdaQueryWrapper().eq(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_F.type).last("limit 1")); locs.forEach(loc -> { List locItems = locItemService.list(new LambdaQueryWrapper().eq(LocItem::getLocId, loc.getId())); if (!locItems.isEmpty()) { DeviceSite deviceSite = deviceSiteService.getOne(new LambdaQueryWrapper().eq(DeviceSite::getType, TaskType.TASK_TYPE_CHECK_OUT.type), false); //生成盘点任务参数 LocToTaskParams locToTaskParams = new LocToTaskParams(); locToTaskParams.setType(Constants.TASK_TYPE_OUT_CHECK) .setItems(locItems) .setSiteNo(deviceSite.getSite()) .setOrgLoc(loc.getCode()); try { locItemService.generateTask(TaskResouceType.TASK_RESOUCE_CHECK_TYPE.val, locToTaskParams, getLoginUserId()); } catch (Exception e) { throw new CoolException(e.getMessage()); } } }); } /** * @author Ryan * @date 2025/9/1 * @description: 自动完成盘点功能 * @version 1.0 */ public void autoCheckComplete() { Boolean autoRunArea = configService.getVal("AUTO_RUN_CHECK_ORDERS", Boolean.class); if (!autoRunArea) { return; } //获取任务列表中,为盘点出库的任务 List tasks = taskService.list(new LambdaQueryWrapper() .in(Task::getTaskType, Arrays.asList(TaskType.TASK_TYPE_CHECK_OUT.type, TaskType.TASK_TYPE_CHECK_IN.type))); if (tasks.size() >= 5) { return; } if (!tasks.isEmpty()) { tasks.forEach(task -> { if (task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_IN.type)) { if (task.getTaskStatus().equals(TaskStsType.GENERATE_IN.id)) { task.setTaskStatus(TaskStsType.COMPLETE_IN.id); if (!taskService.updateById(task)) { throw new CoolException("盘点再入库任务完成失败!!"); } } } else { //创建出库任务状态 if (task.getTaskStatus().equals(TaskStsType.GENERATE_OUT.id)) { task.setTaskStatus(TaskStsType.COMPLETE_OUT.id); if (!taskService.updateById(task)) { throw new CoolException("盘点出库任务完成失败!!"); } //出库已完成,等待盘点中 } else if (task.getTaskStatus().equals(TaskStsType.WAVE_SEED.id)) { try { taskService.pickOrCheckTask(task.getId(), Constants.TASK_TYPE_OUT_CHECK); } catch (Exception e) { throw new CoolException(e.getMessage()); } } } }); } } public void genRun() { String autoRunArea = configService.getVal("AUTO_RUN_AREA", String.class); if (Cools.isEmpty(autoRunArea)) { return; } for (char c : autoRunArea.toCharArray()) { switch (c) { case '1': this.autoRun(LocGroupConstant.FAR_RIGHT_LOC_ROW_LIST, StaGroupConstant.FAR_RIGHT_STA_ROW_LIST); break; case '2': this.autoRun(LocGroupConstant.RIGHT_LOC_ROW_LIST, StaGroupConstant.RIGHT_STA_ROW_LIST); break; case '3': this.autoRun(LocGroupConstant.MIDDLE_LOC_ROW_LIST, StaGroupConstant.MIDDLE_STA_ROW_LIST); break; case '4': this.autoRun(LocGroupConstant.LEFT_LOC_ROW_LIST, StaGroupConstant.LEFT_STA_ROW_LIST); break; case '5': this.autoRun(LocGroupConstant.FAR_LEFT_LOC_ROW_LIST, StaGroupConstant.FAR_LEFT_STA_ROW_LIST); break; default: break; } } } private void autoRun(List locGroupList, List staGroupList) { List staPreNos = getStaPrefixes(staGroupList); String staTaskMemo = "DEMO_STA_" + String.join("-", staPreNos); log.error("=========>"); log.info(staTaskMemo); System.out.println(staTaskMemo); List list = taskService.list(new LambdaQueryWrapper().eq(Task::getMemo, staTaskMemo)); if (!Cools.isEmpty(list) && list.size() > 30) { return; } // 入库 应该根据工作档回去 this.runStaToLoc(locGroupList, staGroupList, staTaskMemo); // 出库,需要校验工作档是否存在,存在就说明站点处于忙碌状态 this.runLocToSta(locGroupList, staGroupList, staTaskMemo); // 移库 this.runLocToLoc(locGroupList, staTaskMemo); } // 入库 private void runStaToLoc(List locGroupList, List staGroupList, String memo) { Integer startRow = Collections.min(locGroupList); Integer endRow = Collections.max(locGroupList); // STA IDLE LambdaQueryWrapper idleWrapper = new LambdaQueryWrapper().eq(BasStation::getUseStatus, LocStsType.LOC_STS_TYPE_F.type).in(BasStation::getStationName, staGroupList); List idleList = stationService.list(idleWrapper); if (Cools.isEmpty(idleList)) { return; } Collections.shuffle(idleList); // LOC STOCK LambdaQueryWrapper stockWrapper = new LambdaQueryWrapper().eq(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_O.type); if (null != startRow) { stockWrapper.ge(Loc::getRow, startRow); } if (null != endRow) { stockWrapper.le(Loc::getRow, endRow); } List stockList = locService.list(stockWrapper); if (Cools.isEmpty(stockList)) { return; } Collections.shuffle(stockList); //生成入库工作档 generateTask(idleList.get(0).getStationName(), stockList.get(0).getCode(), idleList.get(0).getBarcode()); } // 出库 private void runLocToSta(List locGroupList, List staGroupList, String memo) { Integer startRow = Collections.min(locGroupList); Integer endRow = Collections.max(locGroupList); // STA IDLE LambdaQueryWrapper idleWrapper = new LambdaQueryWrapper().eq(BasStation::getUseStatus, LocStsType.LOC_STS_TYPE_O.type).in(BasStation::getStationName, staGroupList); List idleList = stationService.list(idleWrapper); if (Cools.isEmpty(idleList)) { return; } Collections.shuffle(idleList); // LOC STOCK LambdaQueryWrapper stockWrapper = new LambdaQueryWrapper().eq(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_F.type); if (null != startRow) { stockWrapper.ge(Loc::getRow, startRow); } if (null != endRow) { stockWrapper.le(Loc::getRow, endRow); } List stockList = locService.list(stockWrapper); if (Cools.isEmpty(stockList)) { return; } Collections.shuffle(stockList); Loc loc = stockList.get(0); List list = locItemService.list(new LambdaQueryWrapper().eq(LocItem::getLocId, loc.getId())); LocToTaskParams param = new LocToTaskParams(); param.setType(Constants.TASK_TYPE_OUT_STOCK); param.setTarLoc(loc.getCode()); param.setItems(list); param.setSiteNo(idleList.get(0).getStationName()); param.setMemo(memo); //生成出库工作档 try { locItemService.generateTask(TaskResouceType.TASK_RESOUCE_STOCK_TYPE.val, param, getLoginUserId()); } catch (Exception e) { log.info("生成出库任务失败", e); } } // 移库 private void runLocToLoc(List locGroupList, String staTaskMemo) { Integer startRow = Collections.min(locGroupList); Integer endRow = Collections.max(locGroupList); String memo = "DEMO_LOC_" + startRow + "-" + endRow; // STOCK LambdaQueryWrapper stockWrapper = new LambdaQueryWrapper().eq(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_F.type); if (null != startRow) { stockWrapper.ge(Loc::getRow, startRow); } if (null != endRow) { stockWrapper.le(Loc::getRow, endRow); } List stockList = locService.list(stockWrapper); if (Cools.isEmpty(stockList)) { return; } Collections.shuffle(stockList); // IDLE LambdaQueryWrapper idleWrapper = new LambdaQueryWrapper().eq(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_O.type); if (null != startRow) { idleWrapper.ge(Loc::getRow, startRow); } if (null != endRow) { idleWrapper.le(Loc::getRow, endRow); } List idleList = locService.list(idleWrapper); if (Cools.isEmpty(idleList)) { return; } Collections.shuffle(idleList); //生成移库任务 Loc loc = stockList.get(0); List list = locItemService.list(new LambdaQueryWrapper().eq(LocItem::getLocId, loc.getId())); LocToTaskParams param = new LocToTaskParams(); param.setType(Constants.TASK_TYPE_OUT_CHECK); param.setTarLoc(idleList.get(0).getCode()); param.setItems(list); param.setOrgLoc(stockList.get(0).getCode()); param.setMemo(memo); //生成移库工作档 try { locItemService.genMoveTask(param, 6666L); } catch (Exception e) { log.info("生成出库任务失败", e); } } private void generateTask(String sourceStaNo, String locNo, String barcode) { String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_TASK_CODE, null); if (StringUtils.isBlank(ruleCode)) { throw new CoolException("编码错误:请确认编码「SYS_TASK_CODE」是否已生成!!"); } Task task = new Task(); task.setTaskCode(ruleCode) .setTaskStatus(TaskStsType.GENERATE_IN.id) .setTaskType(TaskType.TASK_TYPE_IN.type) .setResource(TaskResouceType.TASK_RESOUCE_PAKIN_TYPE.val) .setTargLoc(locNo) .setBarcode(barcode) .setOrgSite(sourceStaNo) .setCreateBy(6666L) .setUpdateBy(6666L); if (!taskService.save(task)) { throw new CoolException("任务保存失败!!"); } LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(Matnr::getStatus, 1); wrapper.orderByAsc(Matnr::getUpdateTime); List list = matnrService.page(new Page<>(1, 100), wrapper).getRecords(); Collections.shuffle(list); List taskItems = new ArrayList<>(); int i = 0; for (Matnr item : list) { if (i > 5) { break; } TaskItem taskItem = new TaskItem(); BeanUtils.copyProperties(item, taskItem); taskItem.setTaskId(task.getId()) .setOrderType(OrderType.ORDER_IN.type) .setCreateBy(6666L) .setUpdateBy(6666L) .setExtendFields(item.getExtendFields()); taskItems.add(taskItem); item.setUpdateTime(new Date()); matnrService.updateById(item); i++; } taskItemService.saveBatch(taskItems); } public static List getStaPrefixes(List staGroupList) { Set rowSet = new HashSet<>(); for (String s : staGroupList) { rowSet.add(s.split("-")[0]); } List result = new ArrayList<>(rowSet); result.sort(Comparator.comparingInt(Integer::parseInt)); return result; } }