package com.zy.asrs.task;
|
|
import com.baomidou.mybatisplus.mapper.EntityWrapper;
|
import com.baomidou.mybatisplus.mapper.Wrapper;
|
import com.core.common.Cools;
|
import com.zy.asrs.entity.Task;
|
import com.zy.asrs.entity.WrkMast;
|
import com.zy.asrs.mapper.WrkMastMapper;
|
import com.zy.asrs.entity.WrkMastLog;
|
import com.zy.asrs.service.TaskService;
|
import com.zy.asrs.service.WrkMastLogService;
|
import com.zy.asrs.service.WrkMastService;
|
import com.zy.asrs.task.handler.AgvHandler;
|
import com.zy.common.properties.SchedulerProperties;
|
import com.zy.system.entity.Config;
|
import com.zy.system.service.ConfigService;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.stereotype.Component;
|
|
import javax.annotation.Resource;
|
import java.util.ArrayList;
|
import java.util.Arrays;
|
import java.util.Date;
|
import java.util.List;
|
|
/**
|
* @author pang.jiabao
|
* @description AGV交互相关定时任务
|
* @createDate 2025/11/18 14:18
|
*/
|
@Slf4j
|
@Component
|
public class AgvScheduler {
|
|
@Resource
|
private ConfigService configService;
|
|
@Resource
|
private AgvHandler agvHandler;
|
|
@Resource
|
private TaskService taskService;
|
|
@Resource
|
private WrkMastMapper wrkMastMapper;
|
|
@Resource
|
private WrkMastService wrkMastService;
|
|
@Resource
|
private WrkMastLogService wrkMastLogService;
|
|
@Resource
|
private SchedulerProperties schedulerProperties;
|
|
/**
|
* 呼叫agv搬运
|
*/
|
@Scheduled(cron = "0/5 * * * * ? ")
|
private void callAgv() {
|
if (!schedulerProperties.isEnabled()) {
|
return;
|
}
|
// 查询待呼叫agv任务,按id升序排序(id最小的优先呼叫)
|
List<Task> taskList = taskService.selectList(
|
new EntityWrapper<Task>()
|
.eq("wrk_sts", 7)
|
.orderBy("id", true) // 按id升序,id最小的优先
|
);
|
if(taskList.isEmpty()) {
|
return;
|
}
|
agvHandler.callAgv(taskList);
|
}
|
|
/**
|
* 货物到达出库口,生成agv任务
|
*/
|
@Scheduled(cron = "0/3 * * * * ? ")
|
private void createAgvOutTasks() {
|
if (!schedulerProperties.isEnabled()) {
|
return;
|
}
|
|
// 获取呼叫agv配置
|
List<Config> configs = configService.selectList(new EntityWrapper<Config>().in("code", "eastCallAgvControl", "westCallAgvControl").eq("status", 1));
|
if(configs.isEmpty()) {
|
return;
|
}
|
|
// 获取agv出库可用站点
|
List<String> sites = new ArrayList<>();
|
for(Config config: configs) {
|
String value = config.getValue();
|
if(Cools.isEmpty(value)) {
|
continue;
|
}
|
String[] split = value.split(";");
|
sites.addAll(Arrays.asList(split));
|
}
|
|
if(sites.isEmpty()) {
|
return;
|
}
|
|
agvHandler.createAgvOutTasks(sites);
|
}
|
|
/**
|
* 任务完成转历史
|
*/
|
@Scheduled(cron = "0/10 * * * * ? ")
|
private void moveTaskToHistory() {
|
if (!schedulerProperties.isEnabled()) {
|
return;
|
}
|
List<Task> taskList = taskService.selectList(new EntityWrapper<Task>().eq("wrk_sts", 9));
|
if(taskList.isEmpty()) {
|
return;
|
}
|
agvHandler.moveTaskToHistory(taskList);
|
}
|
|
/**
|
* 检查入库成功的任务,完结对应的AGV呼叫单
|
* 如果入库任务呼叫AGV后没有收到回调,但工作档已经入库成功,则完结AGV呼叫单
|
*/
|
@Scheduled(cron = "0/10 * * * * ? ")
|
private void checkInboundCompletedTasks() {
|
if (!schedulerProperties.isEnabled()) {
|
return;
|
}
|
try {
|
// 查询入库成功的工作档(状态4:入库完成,入库类型:1,10,53,57)
|
List<WrkMast> completedWrkMasts = wrkMastService.selectList(
|
new EntityWrapper<WrkMast>()
|
.eq("wrk_sts", 4L) // 入库完成
|
.in("io_type", 1, 10, 53, 57) // 入库类型
|
.isNotNull("wrk_no")
|
);
|
|
if (completedWrkMasts.isEmpty()) {
|
return;
|
}
|
|
Date now = new Date();
|
int completedCount = 0;
|
|
for (WrkMast wrkMast : completedWrkMasts) {
|
// 查找对应的AGV任务(优先通过wrk_no查询)
|
Wrapper<Task> taskWrapper1 = new EntityWrapper<Task>()
|
.eq("task_type", "agv")
|
.eq("wrk_sts", 8L) // 已呼叫AGV状态
|
.eq("wrk_no", wrkMast.getWrkNo());
|
List<Task> agvTasks = taskService.selectList(taskWrapper1);
|
|
// 如果通过wrk_no没找到,且有条码,则通过条码查询
|
if (agvTasks.isEmpty() && !Cools.isEmpty(wrkMast.getBarcode())) {
|
Wrapper<Task> taskWrapper2 = new EntityWrapper<Task>()
|
.eq("task_type", "agv")
|
.eq("wrk_sts", 8L)
|
.eq("barcode", wrkMast.getBarcode());
|
agvTasks = taskService.selectList(taskWrapper2);
|
}
|
|
for (Task agvTask : agvTasks) {
|
// 确保是入库任务
|
if (agvTask.getIoType() != null &&
|
(agvTask.getIoType() == 1 || agvTask.getIoType() == 10 ||
|
agvTask.getIoType() == 53 || agvTask.getIoType() == 57)) {
|
// 更新AGV任务状态为完成
|
agvTask.setWrkSts(9L);
|
agvTask.setModiTime(now);
|
if (taskService.updateById(agvTask)) {
|
completedCount++;
|
log.info("入库任务工作档已入库成功,完结AGV呼叫单,taskId:{},wrkNo:{},barcode:{}",
|
agvTask.getId(), wrkMast.getWrkNo(), wrkMast.getBarcode());
|
}
|
}
|
}
|
}
|
|
if (completedCount > 0) {
|
log.info("本次检查完结了{}个入库AGV呼叫单", completedCount);
|
}
|
} catch (Exception e) {
|
log.error("检查入库成功任务并完结AGV呼叫单异常", e);
|
}
|
}
|
|
/**
|
* 检查AGV任务对应的工作档是否已完成或已转历史档并完结
|
* 处理被跳过的AGV任务:如果工作档已完成(wrk_sts=4,5,14,15)或已转历史档并完结,则完结AGV任务
|
*/
|
@Scheduled(cron = "0/10 * * * * ? ")
|
private void checkCompletedTasksInHistory() {
|
if (!schedulerProperties.isEnabled()) {
|
return;
|
}
|
try {
|
// 查询状态为8(已呼叫AGV)的AGV任务
|
List<Task> agvTasks = taskService.selectList(
|
new EntityWrapper<Task>()
|
.eq("task_type", "agv")
|
.eq("wrk_sts", 8L) // 已呼叫AGV状态
|
.isNotNull("wrk_no")
|
);
|
|
if (agvTasks.isEmpty()) {
|
return;
|
}
|
|
Date now = new Date();
|
int completedCount = 0;
|
|
for (Task agvTask : agvTasks) {
|
boolean isCompleted = false;
|
String reason = "";
|
|
// 检查工作档是否存在
|
WrkMast wrkMast = null;
|
if (agvTask.getWrkNo() != null) {
|
wrkMast = wrkMastService.selectOne(
|
new EntityWrapper<WrkMast>().eq("wrk_no", agvTask.getWrkNo())
|
);
|
}
|
|
// 如果工作档存在,检查是否已完成
|
if (wrkMast != null) {
|
Long wrkSts = wrkMast.getWrkSts();
|
Integer ioType = agvTask.getIoType();
|
|
if (wrkSts != null && ioType != null) {
|
// 入库任务:状态4(入库完成)或5(库存更新完成)
|
if ((ioType == 1 || ioType == 10 || ioType == 53 || ioType == 57) &&
|
(wrkSts == 4L || wrkSts == 5L)) {
|
isCompleted = true;
|
reason = String.format("工作档已完成,状态:%d", wrkSts);
|
}
|
// 出库任务:状态14(已出库未确认)或15(出库更新完成)
|
else if ((ioType == 101 || ioType == 110 || ioType == 103 || ioType == 107) &&
|
(wrkSts == 14L || wrkSts == 15L)) {
|
isCompleted = true;
|
reason = String.format("工作档已完成,状态:%d", wrkSts);
|
}
|
}
|
} else {
|
// 如果工作档不存在,检查历史档
|
WrkMastLog wrkMastLog = null;
|
|
// 优先通过wrk_no查询历史档
|
if (agvTask.getWrkNo() != null) {
|
wrkMastLog = wrkMastLogService.selectOne(
|
new EntityWrapper<WrkMastLog>().eq("wrk_no", agvTask.getWrkNo())
|
);
|
}
|
|
// 如果通过wrk_no没找到,且有条码,则通过条码查询
|
if (wrkMastLog == null && !Cools.isEmpty(agvTask.getBarcode())) {
|
List<WrkMastLog> logList = wrkMastLogService.selectList(
|
new EntityWrapper<WrkMastLog>().eq("barcode", agvTask.getBarcode())
|
);
|
if (!logList.isEmpty()) {
|
wrkMastLog = logList.get(0); // 取第一个
|
}
|
}
|
|
// 如果历史档存在且已完结,则完结AGV任务
|
if (wrkMastLog != null) {
|
Integer ioType = agvTask.getIoType();
|
long logWrkSts = wrkMastLog.getWrkSts();
|
|
if (ioType != null) {
|
// 入库任务:状态5(库存更新完成)
|
if ((ioType == 1 || ioType == 10 || ioType == 53 || ioType == 57) &&
|
logWrkSts == 5L) {
|
isCompleted = true;
|
reason = String.format("工作档已转历史档并完结,历史档状态:%d", logWrkSts);
|
}
|
// 出库任务:状态15(出库更新完成)
|
else if ((ioType == 101 || ioType == 110 || ioType == 103 || ioType == 107) &&
|
logWrkSts == 15L) {
|
isCompleted = true;
|
reason = String.format("工作档已转历史档并完结,历史档状态:%d", logWrkSts);
|
}
|
}
|
}
|
}
|
|
// 如果已完成,更新AGV任务状态
|
if (isCompleted) {
|
agvTask.setWrkSts(9L);
|
agvTask.setModiTime(now);
|
if (taskService.updateById(agvTask)) {
|
completedCount++;
|
log.info("{},完结AGV呼叫单,taskId:{},wrkNo:{},barcode:{},站点:{}",
|
reason, agvTask.getId(), agvTask.getWrkNo(), agvTask.getBarcode(), agvTask.getStaNo());
|
}
|
}
|
}
|
|
if (completedCount > 0) {
|
log.info("本次检查完结了{}个AGV呼叫单(工作档已完成或已转历史档)", completedCount);
|
}
|
} catch (Exception e) {
|
log.error("检查工作档已完成或历史档完结任务并完结AGV呼叫单异常", e);
|
}
|
}
|
|
}
|