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.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;
|
|
|
/**
|
* 自动生成库位明细
|
*/
|
@Transactional(rollbackFor = Exception.class)
|
// @Scheduled(cron = "0/25 * * * * ?")
|
public void insertRandomMats() {
|
List<Loc> list = locService.list(new LambdaQueryWrapper<Loc>().eq(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_F.type));
|
for (Loc loc : list) {
|
List<LocItem> items = locItemService.list(new LambdaQueryWrapper<LocItem>().eq(LocItem::getLocId, loc.getId()));
|
if (!items.isEmpty()) {
|
continue;
|
}
|
List<Matnr> matnrs = matnrService.list(new LambdaQueryWrapper<Matnr>().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/35 * * * * ?")
|
public void autoCheckComplete() {
|
Boolean autoRunArea = configService.getVal("AUTO_RUN_CHECK_ORDERS", Boolean.class);
|
if (!autoRunArea) {
|
return;
|
}
|
//获取任务列表中,为盘点出库的任务
|
List<Task> tasks = taskService.list(new LambdaQueryWrapper<Task>()
|
.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.COMPLETE_IN.id)) {
|
if (!stationService.update(new LambdaUpdateWrapper<BasStation>()
|
.eq(BasStation::getStationName, task.getOrgSite())
|
.set(BasStation::getUseStatus, LocStsType.LOC_STS_TYPE_O.type))) {
|
throw new CoolException("站点状态修改失败!!");
|
}
|
}
|
} else {
|
//创建出库任务状态
|
// if (task.getTaskStatus().equals(TaskStsType.WCS_EXECUTE_OUT.id)) {
|
// task.setTaskStatus(TaskStsType.COMPLETE_OUT.id);
|
// if (!taskService.updateById(task)) {
|
// throw new CoolException("盘点出库任务完成失败!!");
|
// }
|
// //出库已完成,等待盘点中
|
// } else
|
|
if (task.getTaskStatus().equals(TaskStsType.WAVE_SEED.id)) {
|
if (!stationService.update(new LambdaUpdateWrapper<BasStation>()
|
.eq(BasStation::getStationName, task.getOrgSite())
|
.set(BasStation::getUseStatus, LocStsType.LOC_STS_TYPE_F.type))) {
|
throw new CoolException("站点状态修改失败!!");
|
}
|
try {
|
taskService.pickOrCheckTask(task.getId(), Constants.TASK_TYPE_OUT_CHECK);
|
|
if (!stationService.update(new LambdaUpdateWrapper<BasStation>()
|
.eq(BasStation::getStationName, task.getOrgSite())
|
.set(BasStation::getUseStatus, LocStsType.LOC_STS_TYPE_R.type))) {
|
throw new CoolException("站点状态修改失败!!");
|
}
|
} catch (Exception e) {
|
throw new CoolException(e.getMessage());
|
}
|
}
|
}
|
});
|
}
|
}
|
|
|
/**
|
* @author Ryan
|
* @date 2025/9/1
|
* @description: 自动完成盘点功能
|
* @version 1.0
|
*/
|
@Scheduled(cron = "0/25 * * * * ?")
|
public void genRun() {
|
Boolean flagAuto = configService.getVal("AUTO_RUN_CHECK_ORDERS", Boolean.class);
|
if (!flagAuto) {
|
return;
|
}
|
//获取任务列表中,为盘点出库的任务
|
List<Task> tasks = taskService.list(new LambdaQueryWrapper<Task>()
|
.in(Task::getTaskType, Arrays.asList(TaskType.TASK_TYPE_CHECK_OUT.type, TaskType.TASK_TYPE_CHECK_IN.type)));
|
if (tasks.size() >= 6) {
|
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<Integer> locGroupList, List<String> staGroupList) {
|
List<String> staPreNos = getStaPrefixes(staGroupList);
|
String staTaskMemo = "DEMO_STA_" + String.join("-", staPreNos);
|
List<Task> list = taskService.list(new LambdaQueryWrapper<Task>().eq(Task::getMemo, staTaskMemo));
|
if (!Cools.isEmpty(list) && list.size() >= 1) {
|
return;
|
}
|
|
List<Loc> locs = getAreaLocs(locGroupList, staGroupList, staTaskMemo);
|
|
for (Loc loc : locs) {
|
List<LocItem> locItems = locItemService.list(new LambdaQueryWrapper<LocItem>().eq(LocItem::getLocId, loc.getId()));
|
if (!locItems.isEmpty()) {
|
locItems.forEach(locItem -> {
|
locItem.setOutQty(locItem.getAnfme());
|
});
|
List<BasStation> stations = stationService.list(new LambdaQueryWrapper<BasStation>().eq(BasStation::getUseStatus, LocStsType.LOC_STS_TYPE_O.type));
|
if (Cools.isEmpty(stations)) {
|
throw new CoolException("无可用站点!!");
|
}
|
DeviceSite deviceSite = deviceSiteService.getOne(new LambdaQueryWrapper<DeviceSite>()
|
.in(DeviceSite::getSite, stations)
|
.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<Task> tasks = taskService.list(new LambdaQueryWrapper<Task>().eq(Task::getTargSite, deviceSite.getSite()));
|
if (!tasks.isEmpty()) {
|
continue;
|
}
|
try {
|
//生成盘点出库任务,站点预约
|
if (!stationService.update(new LambdaUpdateWrapper<BasStation>()
|
.eq(BasStation::getStationName, deviceSite.getSite())
|
.set(BasStation::getUseStatus, LocStsType.LOC_STS_TYPE_S.type))) {
|
throw new CoolException("站点状态更新失败!!");
|
}
|
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);
|
// // 移库
|
// this.runLocToLoc(locGroupList, staTaskMemo);
|
}
|
|
|
private List<Loc> getAreaLocs(List<Integer> locGroupList, List<String> staGroupList, String memo) {
|
Integer startRow = Collections.min(locGroupList);
|
Integer endRow = Collections.max(locGroupList);
|
|
// STA IDLE
|
// LambdaQueryWrapper<BasStation> idleWrapper = new LambdaQueryWrapper<BasStation>().eq(BasStation::getUseStatus, LocStsType.LOC_STS_TYPE_O.type).in(BasStation::getStationName, staGroupList);
|
// List<BasStation> idleList = stationService.list(idleWrapper);
|
// if (Cools.isEmpty(idleList)) {
|
// return new ArrayList<>();
|
// }
|
// Collections.shuffle(idleList);
|
|
// LOC STOCK
|
LambdaQueryWrapper<Loc> stockWrapper = new LambdaQueryWrapper<Loc>().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<Loc> stockList = locService.list(stockWrapper);
|
if (Cools.isEmpty(stockList)) {
|
return new ArrayList<>();
|
}
|
Collections.shuffle(stockList);
|
|
return stockList;
|
//生成入库工作档
|
// generateTask(idleList.get(0).getStationName(), stockList.get(0).getCode(), idleList.get(0).getBarcode());
|
}
|
|
|
// 出库
|
private void runLocToSta(List<Integer> locGroupList, List<String> staGroupList, String memo) {
|
Integer startRow = Collections.min(locGroupList);
|
Integer endRow = Collections.max(locGroupList);
|
|
|
// STA IDLE
|
LambdaQueryWrapper<BasStation> idleWrapper = new LambdaQueryWrapper<BasStation>().eq(BasStation::getUseStatus, LocStsType.LOC_STS_TYPE_O.type).in(BasStation::getStationName, staGroupList);
|
List<BasStation> idleList = stationService.list(idleWrapper);
|
if (Cools.isEmpty(idleList)) {
|
return;
|
}
|
Collections.shuffle(idleList);
|
|
// LOC STOCK
|
LambdaQueryWrapper<Loc> stockWrapper = new LambdaQueryWrapper<Loc>().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<Loc> stockList = locService.list(stockWrapper);
|
if (Cools.isEmpty(stockList)) {
|
return;
|
}
|
Collections.shuffle(stockList);
|
|
|
Loc loc = stockList.get(0);
|
List<LocItem> list = locItemService.list(new LambdaQueryWrapper<LocItem>().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<Integer> locGroupList, String staTaskMemo) {
|
Integer startRow = Collections.min(locGroupList);
|
Integer endRow = Collections.max(locGroupList);
|
|
String memo = "DEMO_LOC_" + startRow + "-" + endRow;
|
|
|
// STOCK
|
LambdaQueryWrapper<Loc> stockWrapper = new LambdaQueryWrapper<Loc>().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<Loc> stockList = locService.list(stockWrapper);
|
if (Cools.isEmpty(stockList)) {
|
return;
|
}
|
Collections.shuffle(stockList);
|
|
// IDLE
|
LambdaQueryWrapper<Loc> idleWrapper = new LambdaQueryWrapper<Loc>().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<Loc> idleList = locService.list(idleWrapper);
|
if (Cools.isEmpty(idleList)) {
|
return;
|
}
|
Collections.shuffle(idleList);
|
//生成移库任务
|
Loc loc = stockList.get(0);
|
List<LocItem> list = locItemService.list(new LambdaQueryWrapper<LocItem>().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<Matnr> wrapper = new LambdaQueryWrapper<>();
|
wrapper.eq(Matnr::getStatus, 1);
|
wrapper.orderByAsc(Matnr::getUpdateTime);
|
List<Matnr> list = matnrService.page(new Page<>(1, 100), wrapper).getRecords();
|
Collections.shuffle(list);
|
List<TaskItem> 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<String> getStaPrefixes(List<String> staGroupList) {
|
Set<String> rowSet = new HashSet<>();
|
for (String s : staGroupList) {
|
rowSet.add(s.split("-")[0]);
|
}
|
List<String> result = new ArrayList<>(rowSet);
|
result.sort(Comparator.comparingInt(Integer::parseInt));
|
return result;
|
}
|
}
|