add:增加近期的一些新增需求实现;

This commit is contained in:
2026-07-15 17:10:33 +08:00
parent 09d723e846
commit 45e7b12dbd
12 changed files with 122 additions and 64 deletions

View File

@@ -18,6 +18,9 @@ public interface AcsConfig {
String MAXINSTNUMBER = "maxInstNumber";
//同一任务创建最大RT车指令数
String MAXRTINSTNUMBER = "maxRtInstNumber";
//人工创建最大指令数
String MAXMANINSTNUMBER = "codeCreate";
//创建任务检查
String CREATETASKCHECK = "createTaskCheck";
//撤销任务检查

View File

@@ -85,8 +85,18 @@ public class AgvNdcOneDeviceDriver extends AbstractDeviceDriver implements Devic
int is_have = 0; //是否有货
int error = 0; //车辆故障
// 飞书消息去重缓存key为设备代码+错误类型value为最后发送时间
private final ConcurrentHashMap<String, Long> feiShuErrorCache = new ConcurrentHashMap<>();
// 飞书消息去重缓存key为设备代码+错误类型value为错误记录(含计数和最后发送时间
private final ConcurrentHashMap<String, FeiShuErrorRecord> feiShuErrorCache = new ConcurrentHashMap<>();
/**
* 飞书报警错误记录,用于计数和间隔推送控制
*/
@Data
private static class FeiShuErrorRecord {
private int num = 0; // 收到同一报警的次数
private long lastSendTime = 0; // 最后一次推送的时间戳(毫秒)
}
/**
* 缓存的参数值,避免频繁查询数据库
*/
@@ -202,7 +212,7 @@ public class AgvNdcOneDeviceDriver extends AbstractDeviceDriver implements Devic
//(需要WCS反馈)
} else if (phase == 0x05) {
data = ndcAgvService.sendAgvOneModeInst(phase, index, 0);
task.setTask_status("8");
task.setTask_status("4");
//车辆执行任务开始计时字段
if (StringUtils.isBlank(task.getTo_x())) {
task.setTo_x(DateUtil.now());
@@ -374,23 +384,36 @@ public class AgvNdcOneDeviceDriver extends AbstractDeviceDriver implements Devic
int endMinutes = endHour * 60 + endMinute;
// 判断当前时间是否在工作时间内
if (nowMinutes < startMinutes || nowMinutes >= endMinutes) {
// log.info("当前时间{}不在工作时间范围内({}),跳过发送飞书消息",
// DateUtil.formatTime(now), feiShuSendTime);
// log.info("当前时间{}不在工作时间范围内({}),跳过发送飞书消息",
// DateUtil.formatTime(now), feiShuSendTime);
return;
}
}
}
// 2. 重复消息筛选5分钟内相同设备的相同错误不重复发
// 2. 计数与间隔推送逻辑第1次收到不推送第2次收到首次推送之后按间隔推
String cacheKey = this.getDeviceCode() + errorMessage;
long currentTime = System.currentTimeMillis();
Long lastSendTime = feiShuErrorCache.get(cacheKey);
if (lastSendTime != null) {
long diffTime = currentTime - lastSendTime;
// 距离上次发送不足2分钟过滤掉该消息
FeiShuErrorRecord record = feiShuErrorCache.get(cacheKey);
if (record == null) {
// 第一次收到该报警num=1不推送
record = new FeiShuErrorRecord();
record.setNum(1);
feiShuErrorCache.put(cacheKey, record);
return;
}
// 每次收到报警,计数+1超过5次则清除缓存重新开始计数
record.setNum(record.getNum() + 1);
if (record.getNum() > 5) {
feiShuErrorCache.remove(cacheKey);
return;
}
if (record.getNum() > 2) {
// num > 2已推送过按间隔时间控制后续推送
int feiShuSendFreMin = Integer.parseInt(feiShuSendFre);
long diffTime = currentTime - record.getLastSendTime();
if (diffTime < feiShuSendFreMin * 60000L) {
log.debug("设备{}的{}在5分钟内已有过提醒,过滤掉本次重复提醒(距今{}ms",
this.getDeviceCode(), errorMessage, diffTime);
log.debug("设备{}的{}在{}分钟内已有过提醒,过滤掉本次重复提醒(距今{}ms",
this.getDeviceCode(), errorMessage, feiShuSendFreMin, diffTime);
return;
}
}
@@ -449,8 +472,8 @@ public class AgvNdcOneDeviceDriver extends AbstractDeviceDriver implements Devic
JSONObject jsonResponse = JSONObject.parseObject(response);
if (jsonResponse != null && jsonResponse.getIntValue("code") == 0) {
//log.info("设备{}的故障消息发送成功:{}", this.getDeviceCode(), errorMessage);
// 更新缓存:记录最后发送时间
feiShuErrorCache.put(cacheKey, currentTime);
// 更新记录:记录最后发送时间
record.setLastSendTime(currentTime);
} else {
log.error("设备{}的故障消息发送失败:{}", this.getDeviceCode(), response);
}

View File

@@ -371,7 +371,7 @@ public class InstructionServiceImpl extends CommonServiceImpl<InstructionMapper,
// dto.setIs_send(task.getLink_num());
// }
// if (task.getTask_type().equals(CommonFinalParam.ONE) || task.getTask_type().equals("2")) {
dto.setInstruction_type(task!=null?task.getTask_type():dto.getInstruction_type());
// dto.setInstruction_type(task.getTask_type());
// } else if (false) {
//
// } else {
@@ -379,7 +379,7 @@ public class InstructionServiceImpl extends CommonServiceImpl<InstructionMapper,
// }
// 查询是否存在相同指令号
// if (!StrUtil.isEmpty(dto.getVehicle_code() )) {
// if (!StzzzzzzrUtil.isEmpty(dto.getVehicle_code() )) {
// Instruction inst_dto = findByContainer(dto.getVehicle_code());
// if (inst_dto != null) {
// log.error("存在相同载具号任务,载具号"+dto.getVehicle_code());

View File

@@ -41,7 +41,7 @@ public class TaskDto implements Serializable {
/**
* 任务类型
*/
private String task_type = CommonFinalParam.ONE;
private String task_type ;
/**
* 立库任务类型

View File

@@ -183,7 +183,7 @@ public class TaskServiceImpl extends CommonServiceImpl<TaskMapper, Task> impleme
@Override
public List<TaskDto> queryAll() {
List<Task> taskList = new LambdaQueryChainWrapper<>(taskMapper)
.lt(Task::getTask_status, TaskStatusEnum.FINISHED.getIndex())
.in(Task::getTask_status, 0, 1, 4, 10, 99)
.eq(Task::getIs_delete, "0")
.orderByDesc(Task::getCreate_time)
.list();
@@ -251,7 +251,7 @@ public class TaskServiceImpl extends CommonServiceImpl<TaskMapper, Task> impleme
wrapper.lt(Task::getTask_status, TaskStatusEnum.FINISHED.getIndex());
}
}
wrapper.in(Task::getTask_status, 1, 4 ,10 ,0);
wrapper.in(Task::getTask_status, 0, 1, 4, 10, 99);
wrapper.orderByDesc(Task::getCreate_time);
IPage<Task> taskPage = taskMapper.selectPage(queryPage, wrapper);
final JSONObject json = (JSONObject) JSON.toJSON(ConvertUtil.convertPage(taskPage, TaskDto.class));
@@ -823,7 +823,7 @@ public class TaskServiceImpl extends CommonServiceImpl<TaskMapper, Task> impleme
//判断是否为WMS下发的任务如果是反馈任务状态给WMS
String hasWms = paramService.findByCode(AcsConfig.HASWMS).getValue();
//&& !StrUtil.equals(dto.getTask_status(),"0")
if (!StrUtil.startWith(entity.getTask_code(), "-") && StrUtil.equals(hasWms, "1")&& !StrUtil.equals(dto.getTask_status(), "8")) {
if (!StrUtil.startWith(entity.getTask_code(), "-") && StrUtil.equals(hasWms, "1") && !StrUtil.equals(dto.getTask_status(), TaskStatusEnum.FINISHEDMOVE.getIndex())) {
this.feedWmsTaskStatus(entity);
}
}
@@ -878,23 +878,17 @@ public class TaskServiceImpl extends CommonServiceImpl<TaskMapper, Task> impleme
}
String currentUsername = SecurityUtils.getCurrentUsername();
String now = DateUtil.now();
for (String taskId : taskIds) {
TaskDto entity = this.findById(taskId);
if (entity == null) {
throw new BadRequestException(LangProcess.msg("error_sysAuth"));
}
if (!"0".equals(entity.getTask_status())) {
throw new BadRequestException("只能修改待执行任务的优先级");
}
TaskDto updateDto = new TaskDto();
updateDto.setTask_id(taskId);
updateDto.setPriority(String.valueOf(priority));
updateDto.setUpdate_time(now);
updateDto.setUpdate_by(currentUsername);
updateDto.setTemperature(currentUsername + "" + now + "手动修改了优先级:"+priority);
Task task = ConvertUtil.convert(updateDto, Task.class);
taskMapper.updateById(task);
// 批量查询验证所有任务是否存在
List<Task> tasks = taskMapper.selectBatchIds(taskIds);
if (tasks.size() != taskIds.size()) {
throw new BadRequestException(LangProcess.msg("error_sysAuth"));
}
taskMapper.update(null, Wrappers.<Task>lambdaUpdate()
.in(Task::getTask_id, taskIds)
.set(Task::getPriority, String.valueOf(priority))
.set(Task::getUpdate_time, now)
.set(Task::getUpdate_by, currentUsername)
.set(Task::getTemperature, currentUsername + "" + now + "手动修改了优先级:" + priority));
}
@Override
@@ -1031,11 +1025,19 @@ public class TaskServiceImpl extends CommonServiceImpl<TaskMapper, Task> impleme
if (inst != null) {
throw new BadRequestException(LangProcess.msg("task_insRun"));
}
String maxManInstNumber = "5";
long unfinishedManInstructionCount = 0L;
String maxInstNumber = "0";
long unfinishedInstructionCount = 0L;
List<InstructionMybatis> unfinishedList = new LambdaQueryChainWrapper<>(instructionMapper)
.lt(InstructionMybatis::getInstruction_status, InstructionStatusEnum.FINISHED.getIndex())
.eq(InstructionMybatis::getIs_delete, "0").list();
maxManInstNumber = paramService.findByCode(AcsConfig.MAXMANINSTNUMBER).getValue();
unfinishedManInstructionCount = unfinishedList.stream().filter(r -> "2".equals(r.getCreate_type())).count();
long maxManInst = Long.parseLong(maxManInstNumber);
// if (unfinishedManInstructionCount >= maxManInst) {
// throw new BadRequestException("超过人工创建的最大指令数:" + maxInstNumber + "个,请等待指令列表完成后再创建!");
// }
if ("2".equals(acsTask.getCar_type())) {
maxInstNumber = paramService.findByCode(AcsConfig.MAXRTINSTNUMBER).getValue();
unfinishedInstructionCount = unfinishedList.stream().filter(r -> "2".equals(r.getCar_type())).count();
@@ -1044,8 +1046,8 @@ public class TaskServiceImpl extends CommonServiceImpl<TaskMapper, Task> impleme
unfinishedInstructionCount = unfinishedList.stream().filter(r -> !"2".equals(r.getCar_type())).count();
}
long maxInst = Long.parseLong(maxInstNumber);
if (unfinishedInstructionCount >= maxInst) {
throw new BadRequestException("超过最大指令数:" + maxInstNumber + ",请等待指令列表完成后再创建!");
if (unfinishedInstructionCount >= maxInst&&unfinishedManInstructionCount >= maxManInst) {
throw new BadRequestException("超过该车型的最大指令数,请等待指令列表完成后再创建!");
}
String startDeviceCode = acsTask.getStart_device_code();
if ("1".equals(acsTask.getTask_type()) && (startDeviceCode.contains("BCPRK") || startDeviceCode.contains("CPRK"))) {
@@ -1136,7 +1138,10 @@ public class TaskServiceImpl extends CommonServiceImpl<TaskMapper, Task> impleme
instdto.setNext_device_code(next_device_code);
instdto.setStart_point_code(start_point_code);
instdto.setNext_point_code(next_point_code);
instdto.setPriority(priority);
//人工创建指令优先级最高
instdto.setPriority("98");
//指令由人工创建
instdto.setCreate_type("2");
instdto.setInstruction_status(InstructionStatusEnum.READY.getIndex());
instdto.setExecute_device_code(start_point_code);
instdto.setVehicle_type(vehicleType);

View File

@@ -42,6 +42,10 @@ export default {
'Description': '描述信息',
'Cancel': '取消',
'Confirm': '确认',
'assign': '分配中',
'finished_move': '取货完成',
'exception': '异常',
'request': '二次分配请求',
'Ready': '就绪',
'In_progress': '执行中',
'Completed': '完成',

View File

@@ -150,6 +150,9 @@
<span v-if="scope.row.instruction_status=='1' ">{{ $t('task.select.In_progress') }}</span>
<span v-if="scope.row.instruction_status=='2' ">{{ $t('task.select.Completed') }}</span>
<span v-if="scope.row.instruction_status=='3' ">{{ $t('task.select.Cancel') }}</span>
<span v-if="scope.row.instruction_status=='4' ">{{ $t('task.select.finished_move') }}</span>
<span v-if="scope.row.instruction_status=='8' ">{{ $t('task.select.assign') }}</span>
<span v-if="scope.row.instruction_status=='10' ">{{ $t('task.select.request') }}</span>
</template>
</el-table-column>
<el-table-column prop="start_point_code" :label="$t('task.select.Start_point')" :min-width="flexWidth('start_point_code',crud.data,$t('task.select.Start_point'))" />

View File

@@ -295,10 +295,14 @@
</el-table-column>
<el-table-column prop="task_status" :label="$t('task.txt_box.Task_status')">
<template slot-scope="scope">
<span v-if="scope.row.task_status=='0' ">{{ $t('task.select.Ready') }}</span>
<span v-if="scope.row.task_status=='1' ">{{ $t('task.select.In_progress') }}</span>
<span v-if="scope.row.task_status=='2' ">{{ $t('task.select.Completed') }}</span>
<span v-if="scope.row.task_status=='3' ">{{ $t('task.select.Cancel') }}</span>
<span v-if="scope.row.task_status==='0' ">{{ $t('task.select.Ready') }}</span>
<span v-if="scope.row.task_status==='1' ">{{ $t('task.select.In_progress') }}</span>
<span v-if="scope.row.task_status==='2' ">{{ $t('task.select.Completed') }}</span>
<span v-if="scope.row.task_status==='3' ">{{ $t('task.select.Cancel') }}</span>
<span v-if="scope.row.task_status==='4' ">{{ $t('task.select.finished_move') }}</span>
<span v-if="scope.row.task_status==='8' ">{{ $t('task.select.assign') }}</span>
<span v-if="scope.row.task_status==='10' ">{{ $t('task.select.request') }}</span>
<span v-if="scope.row.task_status==='99' ">{{ $t('task.select.exception') }}</span>
</template>
</el-table-column>
<el-table-column prop="priority" :label="$t('TaskRecord.table.Priority')" :min-width="flexWidth('priority',crud.data,$t('TaskRecord.table.Priority'))" />

View File

@@ -587,6 +587,11 @@
<span v-if="scope.row.task_status==='0' ">{{ $t('task.select.Ready') }}</span>
<span v-if="scope.row.task_status==='1' ">{{ $t('task.select.In_progress') }}</span>
<span v-if="scope.row.task_status==='2' ">{{ $t('task.select.Completed') }}</span>
<span v-if="scope.row.task_status==='3' ">{{ $t('task.select.Cancel') }}</span>
<span v-if="scope.row.task_status==='4' ">{{ $t('task.select.finished_move') }}</span>
<span v-if="scope.row.task_status==='8' ">{{ $t('task.select.assign') }}</span>
<span v-if="scope.row.task_status==='10' ">{{ $t('task.select.request') }}</span>
<span v-if="scope.row.task_status==='99' ">{{ $t('task.select.exception') }}</span>
</template>
</el-table-column>
<el-table-column prop="priority" :label="$t('task.txt_box.Priority')" :min-width="flexWidth('priority',crud.data,$t('task.txt_box.Priority'))" />
@@ -974,11 +979,11 @@ export default {
return
}
// 校验所有选中的任务状态必须为 '0'(待执行)
const invalidSelections = selections.filter(item => item.task_status !== '0')
if (invalidSelections.length > 0) {
this.crud.notify('只能选择状态为"就绪"的任务', CRUD.NOTIFICATION_TYPE.WARNING)
return
}
// const invalidSelections = selections.filter(item => item.task_status !== '0' || item.task_status !== '1')
// if (invalidSelections.length > 0) {
// this.crud.notify('只能选择状态为"就绪"的任务', CRUD.NOTIFICATION_TYPE.WARNING)
// return
// }
// 取第一个选中任务的 task_code 展示
this.priorityForm.task_code = selections[0].task_code
this.priorityForm.priority = selections[0].priority ? Number(selections[0].priority) : 1