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.BasStationServiceImpl; import com.vincent.rsf.server.system.constant.GlobalConfigCode; import com.vincent.rsf.server.system.constant.SerialRuleCode; import com.vincent.rsf.server.system.entity.Config; 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 java.util.stream.Collectors; 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; /** * 自动生成库位明细 */ @Transactional(rollbackFor = Exception.class) @Scheduled(cron = "0/25 * * * * ?") public void insertRandomMats() { List list = locService.list(new LambdaQueryWrapper().eq(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_F.type)); for (Loc loc : list) { List items = locItemService.list(new LambdaQueryWrapper().eq(LocItem::getLocId, loc.getId())); if (!items.isEmpty()) { continue; } List matnrs = matnrService.list(new LambdaQueryWrapper().orderByAsc(Matnr::getBarcode).last("limit 100")); Collections.shuffle(matnrs); Matnr matnr = matnrs.stream().findFirst().get(); LocItem locItem = new LocItem(); BeanUtils.copyProperties(matnr, locItem); locItem.setBarcode(loc.getBarcode()) .setLocId(loc.getId()) .setMatnrCode(matnr.getCode()) .setMaktx(matnr.getName()) .setMatnrId(matnr.getId()) .setId(null) .setAnfme(45.0) .setLocCode(loc.getCode()); locItemService.save(locItem); } } // /** // * @author Ryan // * @date 2025/9/1 // * @description: 自动生成盘点跑库单 // * @version 1.0 // */ // @Scheduled(cron = "0/25 * * * * ?") // public void autoCheckOrders() { // // // } /** * @author Ryan * @date 2025/9/1 * @description: 自动完成盘点功能 * @version 1.0 */ @Scheduled(cron = "0/25 * * * * ?") @Transactional(rollbackFor = Exception.class) public void autoCheckComplete() { //获取任务列表中,为盘点出库的任务 List tasks = taskService.list(new LambdaQueryWrapper() .in(Task::getTaskType, Arrays.asList(TaskType.TASK_TYPE_CHECK_OUT.type, TaskType.TASK_TYPE_PICK_IN.type, TaskType.TASK_TYPE_PICK_AGAIN_OUT.type, TaskType.TASK_TYPE_CHECK_IN.type))); if (!tasks.isEmpty()) { tasks.forEach(task -> { if (task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_IN.type)) { if (task.getTaskStatus().equals(TaskStsType.COMPLETE_IN.id)) { } } else { if (task.getTaskStatus().equals(TaskStsType.WAVE_SEED.id)) { if (!stationService.update(new LambdaUpdateWrapper() .eq(BasStation::getStationName, task.getTargSite()) .set(BasStation::getUseStatus, LocStsType.LOC_STS_TYPE_R.type))) { log.error("站点状态修改完成失败,当前任务状态:", task.getTaskStatus()); // throw new CoolException("站点状态修改失败!!"); } try { taskService.pickOrCheckTask(task.getId(), task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_OUT.type) ? Constants.TASK_TYPE_OUT_CHECK : ""); } catch (Exception e) { log.error("error====>", e); } } } }); } } /** * @author Ryan * @date 2025/9/1 * @description: 自动生成任务 * @version 1.0 */ @Scheduled(cron = "0/5 * * * * ?") public void genRun() { Config config = configService.getOne(new LambdaQueryWrapper().eq(Config::getFlag, GlobalConfigCode.AUTO_RUN_CHECK_ORDERS)); if (!Boolean.parseBoolean(config.getVal())) { 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() >= 30) { return; } 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); List list = taskService.list(new LambdaQueryWrapper().eq(Task::getMemo, staTaskMemo)); if (!Cools.isEmpty(list) && list.size() >= 1) { return; } List locs = getAreaLocs(locGroupList, staGroupList, staTaskMemo); for (Loc loc : locs) { List locItems = locItemService.list(new LambdaQueryWrapper().eq(LocItem::getLocId, loc.getId())); if (!locItems.isEmpty()) { locItems.forEach(locItem -> { locItem.setOutQty(locItem.getAnfme()); }); List stations = stationService.list(new LambdaQueryWrapper() .eq(BasStation::getStatus, 1) .eq(BasStation::getUseStatus, LocStsType.LOC_STS_TYPE_O.type)); List stationNames = stations.stream().map(BasStation::getStationName).collect(Collectors.toList()); if (Cools.isEmpty(stations)) { throw new CoolException("无可用站点!!"); } DeviceSite deviceSite = deviceSiteService.getOne(new LambdaQueryWrapper() .in(DeviceSite::getSite, stationNames) .eq(DeviceSite::getType, TaskType.TASK_TYPE_CHECK_OUT.type), false); if (Cools.isEmpty(deviceSite)) { throw new CoolException("无可用路径!!"); } //生成盘点任务参数 LocToTaskParams locToTaskParams = new LocToTaskParams(); locToTaskParams.setType(Constants.TASK_TYPE_OUT_CHECK) .setItems(locItems) .setSiteNo(deviceSite.getSite()) .setOrgLoc(loc.getCode()); List tasks = taskService.list(new LambdaQueryWrapper().eq(Task::getTargSite, deviceSite.getSite())); if (!tasks.isEmpty()) { continue; } try { locItemService.generateTask(TaskResouceType.TASK_RESOUCE_CHECK_TYPE.val, locToTaskParams, getLoginUserId()); } catch (Exception e) { throw new CoolException(e.getMessage()); } } } // 入库 应该根据工作档回去 // this.runStaToLoc(locGroupList, staGroupList, staTaskMemo); // // 出库,需要校验工作档是否存在,存在就说明站点处于忙碌状态 // this.runLocToSta(locGroupList, staGroupList, staTaskMemo); // // 移库locGroupList // this.runLocToLoc(locGroupList, staTaskMemo); } private List getAreaLocs(List locGroupList, List staGroupList, String memo) { Integer startRow = Collections.min(locGroupList); Integer endRow = Collections.max(locGroupList); // 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 new ArrayList<>(); } Collections.shuffle(stockList); return stockList; } /** * 生成移库任务 * @param * @param */ // 移库 @Scheduled(cron = "0/7 * * * * ?") @Transactional(rollbackFor = Exception.class) public void runLocToLoc() { Config config = configService.getOne(new LambdaQueryWrapper().eq(Config::getFlag, GlobalConfigCode.AUTO_RUN_CHECK_ORDERS)); if (!Boolean.parseBoolean(config.getVal())) { return; } List locGroupList = new ArrayList<>(); //获取任务列表中,为盘点出库的任务 List tasks = taskService.list(new LambdaQueryWrapper() .eq(Task::getTaskType, TaskType.TASK_TYPE_LOC_MOVE.type)); if (!tasks.isEmpty() && tasks.size() >= 10) { return; } String autoRunArea = configService.getVal("AUTO_RUN_AREA", String.class); if (Cools.isEmpty(autoRunArea)) { return; } for (char c : autoRunArea.toCharArray()) { switch (c) { case '1': locGroupList = LocGroupConstant.FAR_RIGHT_LOC_ROW_LIST; break; case '2': locGroupList = LocGroupConstant.RIGHT_LOC_ROW_LIST; break; case '3': locGroupList = LocGroupConstant.MIDDLE_LOC_ROW_LIST; break; case '4': locGroupList = LocGroupConstant.LEFT_LOC_ROW_LIST; break; case '5': locGroupList = LocGroupConstant.FAR_LEFT_LOC_ROW_LIST; break; default: break; } } 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); } } 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; } }