opt:西门子优化,增加SD01重复入库功能

This commit is contained in:
2026-02-26 16:29:44 +08:00
parent 4fad5fc928
commit f76e7b1142
53 changed files with 1143 additions and 41 deletions

2
.gitignore vendored
View File

@@ -1,3 +1,5 @@
lms/nladmin-system/nlsso-server/.idea/
lms/nladmin-system/logPath_IS_UNDEFINED/
acs/nladmin-system/nlsso-server/.idea/
*.log
lms/nladmin-ui/dist.rar

View File

@@ -3,6 +3,7 @@ package org.nl.acs.agv.server.impl;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.nl.acs.AcsConfig;
import org.nl.acs.agv.server.NDCAgvService;
import org.nl.acs.agv.server.dto.AgvDto;
@@ -16,6 +17,8 @@ import org.nl.acs.log.LokiLogType;
import org.nl.acs.log.service.DeviceExecuteLogService;
import org.nl.acs.opc.DeviceAppService;
import org.nl.acs.opc.DeviceAppServiceImpl;
import org.nl.acs.storage_cell.domain.StorageCell;
import org.nl.acs.storage_cell.service.StorageCellService;
import org.nl.system.service.dict.ISysDictService;
import org.nl.system.service.dict.dao.Dict;
import org.nl.system.service.param.ISysParamService;
@@ -38,6 +41,7 @@ public class NDCAgvServiceImpl implements NDCAgvService {
private final ISysParamService paramService;
private final AcsToWmsService acsToWmsService;
private final ISysDictService dictService;
private final StorageCellService storageCellService;
private final DeviceExecuteLogService logServer;
@@ -85,8 +89,22 @@ public class NDCAgvServiceImpl implements NDCAgvService {
int priority = Integer.parseInt(inst.getPriority()) + 128;
DeviceAppService appService = SpringContextHolder.getBean(DeviceAppServiceImpl.class);
DeviceService deviceService = SpringContextHolder.getBean(DeviceServiceImpl.class);
int startAddress = deviceService.queryAddressBydeviceCode(inst.getStart_point_code());
int nextAddress=deviceService.queryAddressBydeviceCode(inst.getNext_point_code());
int startAddress = 0;
int nextAddress = 0;
//如果起始点在PS15起始点位区间、终点也在PS15终点区间则使用PS15type=2其他情况type =1
StorageCell startStorageCell = storageCellService.getByCode(inst.getStart_point_code());
StorageCell endStorageCell = storageCellService.getByCode(inst.getNext_point_code());
if(null != startStorageCell && null != endStorageCell
&& "2".equals(startStorageCell.getCar_type())){
inst.setCar_type("2");
startAddress = deviceService.queryAddressBydeviceCode(inst.getStart_point_code());
nextAddress = deviceService.queryEndAddressBydeviceCode(inst.getNext_point_code());
} else {
inst.setCar_type("1");
startAddress = deviceService.queryAddressBydeviceCode(inst.getStart_point_code());
nextAddress = deviceService.queryAddressBydeviceCode(inst.getNext_point_code());
}
byte ikeyhigh = (byte) IntToHexHigh(Integer.parseInt(instcode));
byte ikeylow = (byte) IntToHexLow(Integer.parseInt(instcode));
byte typehigh = (byte) IntToHexHigh(Integer.parseInt(inst.getInstruction_type()));
@@ -96,6 +114,8 @@ public class NDCAgvServiceImpl implements NDCAgvService {
byte fhdhigh = (byte) IntToHexHigh(nextAddress);
byte fhdlow = (byte) IntToHexLow(nextAddress);
byte prioritylow = (byte) IntToHexLow(priority);
byte carTypeHigh = (byte) IntToHexHigh(Integer.parseInt(inst.getCar_type()));
byte carTypeLow = (byte) IntToHexLow(Integer.parseInt(inst.getCar_type()));
String str = "十进制下发:";
String str1 = "十六进制下发:";
str += "ikey:" + (Integer.parseInt(instcode));
@@ -108,16 +128,18 @@ public class NDCAgvServiceImpl implements NDCAgvService {
str1 += "/fhd:" + hexToString(fhdhigh & 0xFF) + hexToString(fhdlow & 0xFF);
str += "/priority:" + (priority);
str1 += "/priority:" + hexToString(prioritylow & 0xFF);
str += "/carType:" + (Integer.parseInt(inst.getCar_type()));
str1 += "/carType:" + hexToString(carTypeHigh & 0xFF) + hexToString(carTypeLow & 0xFF);
System.out.println(str);
System.out.println(str1);
byte[] b = null;
if(type == 1){
b = new byte[]{(byte) 0X87, (byte) 0XCD,
(byte) 0X00, (byte) 0X08,
(byte) 0X00, (byte) 0X14,
(byte) 0X00, (byte) 0X16,
(byte) 0X00, (byte) 0X01,
(byte) 0X00, (byte) 0X71,
(byte) 0X00, (byte) 0X10,
(byte) 0X00, (byte) 0X12,
(byte) 0X01, (byte) prioritylow,
(byte) 0X00, (byte) 0X01,
(byte) ikeyhigh, (byte) ikeylow,
@@ -126,9 +148,10 @@ public class NDCAgvServiceImpl implements NDCAgvService {
(byte) qhdhigh, (byte) qhdlow,
(byte) 0X00, (byte) 0X00,
(byte) fhdhigh, (byte) fhdlow,
(byte) carTypeHigh, (byte) carTypeLow,
};
}else if(type == 2){
}else if(type == 2){//没有使用
b = new byte[]{(byte) 0X87, (byte) 0XCD,
(byte) 0X00, (byte) 0X08,
(byte) 0X00, (byte) 0X14,
@@ -143,10 +166,12 @@ public class NDCAgvServiceImpl implements NDCAgvService {
(byte) qhdhigh, (byte) qhdlow,
(byte) fhdhigh, (byte) fhdlow,
(byte) 0X00, (byte) 0X00,
(byte) carTypeHigh, (byte) carTypeLow,
};
}
log.info("下发AGV作业指令--{}", str1);
log.info("下发AGV作业指令--{}", str);
System.out.println("下发agv指令数据:" + Bytes2HexString(b));
OneNDCSocketConnectionAutoRun.write(b);
System.out.println("下发agv指令数据:" + Bytes2HexString(b));
log.info("下发agv指令数据:" + Bytes2HexString(b));

View File

@@ -301,6 +301,8 @@ public interface DeviceService extends CommonService<Device> {
int queryAddressBydeviceCode(String code);
int queryEndAddressBydeviceCode(String code);
String queryDeviceCodeByAddress(int address);
List<Device> findCacheDevice();

View File

@@ -1740,12 +1740,29 @@ public class DeviceServiceImpl extends CommonServiceImpl<DeviceMapper, Device> i
return 0;
}
@Override
public int queryEndAddressBydeviceCode(String code) {
Iterator iterator = storageCells.iterator();
while (iterator.hasNext()) {
StorageCellDto storageCellDto = (StorageCellDto) iterator.next();
if (storageCellDto.getStorage_code().equals(code)) {
if (null != storageCellDto.getEnd_address()) {
return storageCellDto.getEnd_address();
} else {
return storageCellDto.getAddress();
}
}
}
return 0;
}
@Override
public String queryDeviceCodeByAddress(int code) {
Iterator iterator = storageCells.iterator();
while (iterator.hasNext()) {
StorageCellDto storageCellDto = (StorageCellDto) iterator.next();
if (storageCellDto.getAddress()!=null && storageCellDto.getAddress() == code) {
if ((storageCellDto.getAddress()!=null && storageCellDto.getAddress() == code)
|| (storageCellDto.getEnd_address()!=null && storageCellDto.getEnd_address() == code)) {
return storageCellDto.getStorage_code();
}
}

View File

@@ -357,6 +357,8 @@ public class AgvNdcOneDeviceDriver extends AbstractDeviceDriver implements Devic
}
device = deviceAppService.findDeviceByCode(device_code);
if (ObjectUtil.isEmpty(device_code)) {
old_device_code = deviceService.queryDeviceCodeByAddress(agvaddr);
device_code = old_device_code;
log.info(agvaddr + "对应设备号为空!");
return;
}

View File

@@ -202,6 +202,7 @@ public class CargoLiftConveyorDeviceDriver extends AbstractOpcDeviceDriver imple
String start_point_code = task.getStart_point_code();
String start_device_code = task.getStart_device_code();
String route_plan_code = task.getRoute_plan_code();
String car_type = task.getCar_type();
String next_device_code = "";
/**
@@ -263,6 +264,7 @@ public class CargoLiftConveyorDeviceDriver extends AbstractOpcDeviceDriver imple
instdto.setPriority(priority);
instdto.setInstruction_status("0");
instdto.setExecute_device_code(start_point_code);
instdto.setCar_type(car_type);
try {
instructionService.create(instdto);
} catch (Exception e) {

View File

@@ -13,10 +13,9 @@ import org.nl.acs.log.service.DeviceExecuteLogService;
import org.nl.acs.monitor.DeviceStageMonitor;
import org.nl.config.SpringContextHolder;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.RejectedExecutionException;
/**
* 告警灯驱动
@@ -41,7 +40,6 @@ public class GuardLampDeviceDriver extends AbstractOpcDeviceDriver implements De
return this.device;
}
@Override
public void execute() {
String message = null;
@@ -60,18 +58,43 @@ public class GuardLampDeviceDriver extends AbstractOpcDeviceDriver implements De
last_toOpen = toOpen;
}
public void writing(String param, String value) {
String to_param = this.getDevice().getOpc_server_code() + "." + this.getDevice().getOpc_plc_code() + "." + this.getDevice().getDevice_code()
+ "." + param;
Map<String, Object> itemMap = new HashMap<String, Object>();
itemMap.put(to_param, Integer.parseInt(value));
this.control(itemMap);
// 改动1恢复线程池状态打印和你原代码一致方便监控
java.util.concurrent.ThreadPoolExecutor executor = (java.util.concurrent.ThreadPoolExecutor) ThreadPoolUtil.getGlobalFixedExecutor();
log.info("线程池状态 - 活跃线程数: {}, 队列大小: {}, 已完成任务数: {}",
executor.getActiveCount(),
executor.getQueue().size(),
executor.getCompletedTaskCount());
// 改动2加try-catch捕获线程池满的拒绝异常实现「满了就拒绝」
try {
// 核心全局线程池直接执行control无任何嵌套新建线程
ThreadPoolUtil.getGlobalFixedExecutor().submit(new Runnable() {
@Override
public void run() {
try {
control(itemMap);
} catch (Exception e) {
log.error("异步执行 control 方法失败,参数:" + to_param, e);
}
}
});
} catch (RejectedExecutionException e) {
// 改动3线程池满拒绝时打错误日志+记录执行日志,不影响主流程
log.error("线程池队列满,下发任务被拒绝,参数:{}", to_param, e);
logServer.deviceExecuteLog(device_code, "", "", "下发电气信号失败:线程池队列满,参数:" + to_param + ",值:" + value);
return; // 拒绝后直接返回,不记录成功日志
}
// 仅任务提交成功时,记录正常下发日志
logServer.deviceExecuteLog(device_code, "", "", "下发电气信号设备号:" + device_code + ",下发电气:" + to_param + ",下发电气值:" + value);
}
@Override
public JSONObject getDeviceStatusName() {
JSONObject jo = new JSONObject();
@@ -93,5 +116,4 @@ public class GuardLampDeviceDriver extends AbstractOpcDeviceDriver implements De
}
}

View File

@@ -0,0 +1,28 @@
package org.nl.acs.device_driver.basedriver.guard_lamp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.PreDestroy;
/**
* Spring 容器关闭回调处理器,用于释放全局资源(如线程池)
*/
@Component // 关键:交给 Spring 容器管理,成为单例 Bean
public class SpringContextShutdownHandler {
private static final Logger log = LoggerFactory.getLogger(SpringContextShutdownHandler.class);
/**
* Spring 容器关闭时自动执行(仅单例 Bean 生效)
*/
@PreDestroy
public void onContextClosed() {
log.info("Spring 容器即将关闭,开始释放全局资源...");
// 调用 ThreadPoolUtil 的 shutdown 方法,关闭全局线程池
ThreadPoolUtil.shutdown();
log.info("全局线程池已优雅关闭Spring 容器关闭完成");
}
}

View File

@@ -0,0 +1,29 @@
package org.nl.acs.device_driver.basedriver.guard_lamp;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ThreadPoolUtil {
// 全局单例固定线程池核心线程数10最大线程数10使用有界队列队列容量5000
// 修正注释使用AbortPolicy队列满时抛RejectedExecutionException实现任务拒绝
private static final ExecutorService GLOBAL_FIXED_EXECUTOR =
new ThreadPoolExecutor(10, 10, 0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(5000),
new ThreadPoolExecutor.AbortPolicy());
public static ExecutorService getGlobalFixedExecutor() {
return GLOBAL_FIXED_EXECUTOR;
}
// 禁止外部实例化
private ThreadPoolUtil() {}
// 应用关闭时关闭线程池可在Spring的销毁方法、容器关闭钩子中调用
public static void shutdown() {
if (!GLOBAL_FIXED_EXECUTOR.isShutdown()) {
GLOBAL_FIXED_EXECUTOR.shutdown();
}
}
}

View File

@@ -549,6 +549,7 @@ public class OvenGantryManipulatorDeviceDriver extends AbstractOpcDeviceDriver i
String route_plan_code = task.getRoute_plan_code();
String next_point_code = task.getNext_point_code();
String next_device_code = task.getNext_device_code();
String car_type = task.getCar_type();
Instruction instdto = new Instruction();
instdto.setInstruction_id(IdUtil.simpleUUID());
@@ -569,6 +570,7 @@ public class OvenGantryManipulatorDeviceDriver extends AbstractOpcDeviceDriver i
instdto.setPriority(priority);
instdto.setInstruction_status("0");
instdto.setExecute_device_code(start_point_code);
instdto.setCar_type(car_type);
//判断关联的同一列烘箱设备是否都关门 都关门返回false有一个不关门就返回true
boolean isCloseDoor = this.judgeCloseDoor(instdto.getStart_device_code(), instdto.getNext_device_code());

View File

@@ -653,6 +653,7 @@ public class SiemensConveyorDeviceDriver extends AbstractOpcDeviceDriver impleme
instdto.setPriority(priority);
instdto.setInstruction_status("0");
instdto.setExecute_device_code(start_point_code);
instdto.setCar_type(taskdto.getCar_type());
try {
instructionService.create(instdto);
} catch (Exception e) {

View File

@@ -615,6 +615,7 @@ public class SiemensConveyorCkkDeviceDriver extends AbstractOpcDeviceDriver impl
instdto.setPriority(priority);
instdto.setInstruction_status("0");
instdto.setExecute_device_code(start_point_code);
instdto.setCar_type(taskdto.getCar_type());
try {
instructionService.create(instdto);
} catch (Exception e) {

View File

@@ -633,6 +633,7 @@ public class SiemensConveyorLabelingDeviceDriver extends AbstractOpcDeviceDriver
instdto.setPriority(priority);
instdto.setInstruction_status("0");
instdto.setExecute_device_code(start_point_code);
instdto.setCar_type(taskdto.getCar_type());
try {
instructionService.create(instdto);
} catch (Exception e) {

View File

@@ -1074,7 +1074,7 @@ public class SlitTwoManipulatorDeviceDriver extends AbstractOpcDeviceDriver impl
instdto.setStart_point_code2(start_point_code2);
instdto.setNext_device_code2(next_device_code2);
instdto.setNext_point_code2(next_point_code2);
instdto.setCar_type(taskDto.getCar_type());
try {
logServer.deviceExecuteLog(this.getDeviceCode(), "", "", "" +
"执行就绪状态下的任务生成指令时:起点1为:" + start_device_code + "起点2为:" + start_device_code2

View File

@@ -701,6 +701,7 @@ public class StandardCoveyorControlWithPlcScannerDeviceDriver extends AbstractOp
instdto.setPriority(priority);
instdto.setInstruction_status("0");
instdto.setExecute_device_code(start_point_code);
instdto.setCar_type(task.getCar_type());
try {
instructionService.create(instdto);
} catch (Exception e) {
@@ -811,6 +812,7 @@ public class StandardCoveyorControlWithPlcScannerDeviceDriver extends AbstractOp
instdto.setPriority(priority);
instdto.setInstruction_status("0");
instdto.setExecute_device_code(start_point_code);
instdto.setCar_type(task.getCar_type());
try {
instructionService.create(instdto);
} catch (Exception e) {

View File

@@ -652,6 +652,7 @@ public class StandardCoveyorControlWithScannerDeviceDriver extends AbstractOpcDe
instdto.setPriority(priority);
instdto.setInstruction_status("0");
instdto.setExecute_device_code(start_point_code);
instdto.setCar_type(taskdto.getCar_type());
try {
instructionService.create(instdto);
} catch (Exception e) {

View File

@@ -61,6 +61,12 @@ public class CreateTaskRequest extends BaseRequest {
*/
String remark;
/**
* 备注
*/
String car_type;
/**
* 扩展属性
*/

View File

@@ -484,6 +484,7 @@ public class WmsToAcsServiceImpl implements WmsToAcsService {
String task_type = req.getTask_type();
String agv_task_type = req.getAgv_task_type();
String remark = req.getRemark();
String car_type = req.getCar_type();
Map<String, String> params = req.getParams();
String start_point_code = "";
@@ -600,6 +601,7 @@ public class WmsToAcsServiceImpl implements WmsToAcsService {
jo.put("vehicle_type", vehicle_type);
jo.put("agv_system_type", agv_task_type);
jo.put("remark", remark);
jo.put("car_type", car_type);
jo.put("params", params);
jo.put("task_type", StrUtil.isEmpty(task_type) ? 1 : Integer.parseInt(task_type));

View File

@@ -348,4 +348,10 @@ public class InstructionDto implements Serializable {
*/
private String agv_system_type;
/**
* 车辆类型
*/
private String car_type;
}

View File

@@ -344,9 +344,8 @@ public class RouteLineServiceImpl extends CommonServiceImpl<RouteLineMapper, Rou
routeLineMapper.insert(entity);
List list1 = routeLines.get("normal");
list1.add(ConvertUtil.convert(dto, RouteLineDto.class));
} else {
throw new BadRequestException("已存在该路由路线!");
}
//如果重复了,则跳过,不要影响新增。
}
}
reload();

View File

@@ -55,6 +55,9 @@ public class StorageCell extends CommonModel<StorageCell> implements Serializabl
@ApiModelProperty(value = "地址")
private Integer address;
@ApiModelProperty(value = "放货地址")
private Integer end_address;
@ApiModelProperty(value = "备注")
private String remark;
@@ -87,6 +90,9 @@ public class StorageCell extends CommonModel<StorageCell> implements Serializabl
@ApiModelProperty(value = "父级货位编码")
private String parent_storage_code;
@ApiModelProperty(value = "车辆类型")
private String car_type;
public void copyFrom(StorageCell source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
}

View File

@@ -38,7 +38,7 @@ public interface StorageCellService extends CommonService<StorageCell> {
StorageCell getById(String id);
StorageCellDto findById(String id);
StorageCell getByCode(String code);
/**
* 插入一条新数据。
*/

View File

@@ -42,6 +42,9 @@ public class StorageCellDto implements Serializable {
@ApiModelProperty(value = "地址")
private Integer address;
@ApiModelProperty(value = "放货地址")
private Integer end_address;
@ApiModelProperty(value = "备注")
private String remark;
@@ -65,4 +68,7 @@ public class StorageCellDto implements Serializable {
@ApiModelProperty(value = "父级货位编码")
private String parent_storage_code;
@ApiModelProperty(value = "车辆类型")
private String car_type;
}

View File

@@ -1,5 +1,6 @@
package org.nl.acs.storage_cell.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil;
@@ -14,6 +15,7 @@ import lombok.AllArgsConstructor;
import org.nl.acs.common.base.PageInfo;
import org.nl.acs.common.base.QueryHelpMybatisPlus;
import org.nl.acs.common.base.impl.CommonServiceImpl;
import org.nl.acs.opc.domain.OpcPlc;
import org.nl.common.exception.BadRequestException;
import org.nl.acs.utils.ConvertUtil;
import org.nl.common.utils.FileUtil;
@@ -67,6 +69,17 @@ public class StorageCellServiceImpl extends CommonServiceImpl<StorageCellMapper,
return storageCellMapper.selectById(id);
}
@Override
public StorageCell getByCode(String code) {
List<StorageCell> storageCellList = storageCellMapper.selectList(new LambdaQueryWrapper<StorageCell>()
.eq(StorageCell::getStorage_code, code)
.last("LIMIT 1"));
if(CollectionUtil.isNotEmpty(storageCellList)){
return storageCellList.get(0);
}
return null;
}
// @Override
// // @Cacheable(key = "'id:' + #p0")
// public StorageCellDto findById(String id) {
@@ -149,8 +162,12 @@ public class StorageCellServiceImpl extends CommonServiceImpl<StorageCellMapper,
LambdaQueryWrapper<StorageCell> wrapper = new LambdaQueryWrapper<>();
wrapper.like(StringUtils.isNotBlank(storage_code), StorageCell::getStorage_code,storage_code);
wrapper.like(StringUtils.isNotBlank(parent_storage_code), StorageCell::getParent_storage_code,parent_storage_code);
wrapper.like(StringUtils.isNotBlank(address), StorageCell::getAddress,address);
IPage<StorageCell> storageCellIPage = storageCellMapper.selectPage(queryPage,wrapper);
if (StringUtils.isNotBlank(address)) {
// 使用 nested 方法分组,确保内部的 or 只作用于 address 和 end_address不影响外部条件
wrapper.nested(w -> w.like(StorageCell::getAddress, address)
.or()
.like(StorageCell::getEnd_address, address));
} IPage<StorageCell> storageCellIPage = storageCellMapper.selectPage(queryPage,wrapper);
final JSONObject json = (JSONObject) JSON.toJSON(ConvertUtil.convertPage(storageCellIPage, StorageCell.class));
return json;
}

View File

@@ -232,6 +232,9 @@ public class Task extends CommonModel<Task> implements Serializable {
@ApiModelProperty(value = "时间")
private String oven_time;
@ApiModelProperty(value = "车辆类型")
private String car_type;
public void copyFrom(Task source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
}

View File

@@ -301,5 +301,10 @@ public class TaskDto implements Serializable {
*/
private String next_height;
/**
* 车辆类型
*/
private String car_type;
}

View File

@@ -1101,6 +1101,7 @@ public class TaskServiceImpl extends CommonServiceImpl<TaskMapper, Task> impleme
String to_x = acsTask.getTo_x();
String to_y = acsTask.getTo_y();
String to_z = acsTask.getTo_z();
String car_type = acsTask.getCar_type();
/** 开始平均分解校验 */
String this_device_code =
@@ -1167,6 +1168,7 @@ public class TaskServiceImpl extends CommonServiceImpl<TaskMapper, Task> impleme
instdto.setTo_x(to_x);
instdto.setTo_y(to_y);
instdto.setTo_z(to_z);
instdto.setCar_type(car_type);
// 判断agv系统
// 1、1楼叉车系统
@@ -1280,6 +1282,7 @@ public class TaskServiceImpl extends CommonServiceImpl<TaskMapper, Task> impleme
instdto.setNext_point_code2(next_point_code2);
instdto.setAgv_system_type(agv_system_type);
instdto.setAgv_inst_type("1");
instdto.setCar_type(acsTask.getCar_type());
instructionservice.create2(instdto);
// acsTask.setTask_status("1");

View File

@@ -388,6 +388,7 @@ public class HandServiceImpl implements HandService {
String start_device_code = taskDto.getStart_device_code();
String next_device_code = taskDto.getNext_device_code();
String task_id = taskDto.getTask_id();
String car_type = taskDto.getCar_type();
if(StrUtil.equals(taskDto.getTask_status(),"2")||StrUtil.equals(taskDto.getTask_status(),"3")){
resultJson.put("message", "任务已完成或已取消,无法操作");
@@ -412,6 +413,7 @@ public class HandServiceImpl implements HandService {
instdto.setStart_device_code(start_device_code);
instdto.setNext_device_code(next_device_code);
instdto.setInstruction_status("0");
instdto.setCar_type(car_type);
InstructionMybatis instructionMybatis = instructionService.lambdaQuery()
.eq(InstructionMybatis::getStart_device_code, start_device_code)
.eq(InstructionMybatis::getNext_device_code, next_device_code)

View File

@@ -54,6 +54,7 @@ public class AutoCreateInst {
String start_device_code = acsTask.getStart_device_code();
String route_plan_code = acsTask.getRoute_plan_code();
String vehicleType = acsTask.getVehicle_type();
String car_type = acsTask.getCar_type();
//是否复合任务 =0非复合任务
String compound_task = acsTask.getCompound_task();
String compound_task_data = null;
@@ -199,6 +200,7 @@ public class AutoCreateInst {
instdto.setInstruction_status("0");
instdto.setExecute_device_code(start_point_code);
instdto.setVehicle_type(vehicleType);
instdto.setCar_type(car_type);
try {
instructionService.create(instdto);
} catch (Exception e) {

View File

@@ -20,11 +20,15 @@ public class NdcAutoReconnection {
AutoRunService autoRunService;
public void run(String threadCode) throws Exception {
String[] threadCodes = threadCode.split(",");
for (String code : threadCodes) {
if (!autoRunService.getThreadByCode(code).isAlive()) {
autoRunService.startThread(code);
try {
String[] threadCodes = threadCode.split(",");
for (String code : threadCodes) {
if (!autoRunService.getThreadByCode(code).isAlive()) {
autoRunService.startThread(code);
}
}
} catch (Exception e) {
log.error("定时任务执行异常", e);
}
}
}

View File

@@ -7,7 +7,7 @@ spring:
db-type: com.alibaba.druid.pool.DruidDataSource
driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
# url: jdbc:log4jdbc:mysql://${DB_HOST:192.168.81.252}:${DB_PORT:3306}/${DB_NAME:stand_acs}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true
url: jdbc:log4jdbc:mysql://${DB_HOST:127.0.0.1}:${DB_PORT:3306}/${DB_NAME:acs}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true
url: jdbc:log4jdbc:mysql://${DB_HOST:127.0.0.1}:${DB_PORT:3306}/${DB_NAME:ximenzi_acs}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true
username: ${DB_USER:root}
# password: ${DB_PWD:Root.123456}
password: ${DB_PWD:123456}

View File

@@ -2,7 +2,7 @@ spring:
freemarker:
check-template-location: false
profiles:
active: prod
active: dev
jackson:
time-zone: GMT+8
data:

View File

@@ -50,9 +50,12 @@
<el-form-item label="" prop="z">
<el-input v-model="form.z" style="width: 370px;" />
</el-form-item>
<el-form-item label="AGV编码">
<el-form-item label="老车AGV编码">
<el-input v-model="form.address" style="width: 370px;" />
</el-form-item>
<el-form-item label="新车AGV编码">
<el-input v-model="form.end_address" style="width: 370px;" />
</el-form-item>
<el-form-item label="父级系统编码" prop="parent_storage_code">
<el-input v-model="form.parent_storage_code" style="width: 370px;" />
</el-form-item>
@@ -72,7 +75,8 @@
<el-table-column prop="x" label="" />
<el-table-column prop="y" label="" />
<el-table-column prop="z" label="" />
<el-table-column prop="address" label="地址" />
<el-table-column prop="address" label="老车地址" />
<el-table-column prop="end_address" label="新车地址" />
<el-table-column prop="create_by" label="创建者" />
<el-table-column prop="create_time" label="创建时间" />
<el-table-column prop="parent_storage_code" label="父级系统编码" />
@@ -99,7 +103,7 @@ import udOperation from '@crud/UD.operation'
import pagination from '@crud/Pagination'
import rrOperation from '@crud/RR.operation'
const defaultForm = { storage_id: null, storage_code: null, x: null, y: null, z: null, address: null, remark: null, is_active: null, is_delete: null, create_by: null, create_time: null, update_by: null, update_time: null, parent_storage_code: null }
const defaultForm = { storage_id: null, storage_code: null, x: null, y: null, z: null, address: null, end_address: null, remark: null, is_active: null, is_delete: null, create_by: null, create_time: null, update_by: null, update_time: null, parent_storage_code: null }
export default {
name: 'StorageCell',
components: { pagination, crudOperation, udOperation, rrOperation },

View File

@@ -19,6 +19,9 @@ public enum RegionEnum {
ZDZWQ("自动折弯区","ZDZWQ"),
NBGD("内部过道加工区","NBGDJGQ"),
QTJG("其他加工送料暂存区","111-22"),
LAG("S04存放点","LAG"),
S("空容器货架C","S"),
;
private final String region_name;
private final String region_code;

View File

@@ -5,6 +5,7 @@ import org.nl.common.domain.query.PageQuery;
import com.baomidou.mybatisplus.extension.service.IService;
import org.nl.wms.database.vehicle.service.dao.MdBaseVehicle;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -46,4 +47,10 @@ public interface IMdBaseVehicleService extends IService<MdBaseVehicle> {
* @param vehicle_code
*/
MdBaseVehicle selectByVehicleCode(String vehicle_code);
/**
* 根据载具号查询
* @param vehicle_code_list
*/
List<MdBaseVehicle> selectListByVehicleCode(List<String> vehicle_code_list);
}

View File

@@ -19,6 +19,7 @@ import org.nl.wms.database.vehicle.service.dao.MdBaseVehicle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -89,4 +90,10 @@ public class MdBaseVehicleServiceImpl extends ServiceImpl<MdBaseVehicleMapper, M
.eq(MdBaseVehicle::getVehicle_code, vehicle_code));
}
@Override
public List<MdBaseVehicle> selectListByVehicleCode(List<String> vehicle_code_list) {
return mdBaseVehicleMapper.selectList(Wrappers.lambdaQuery(MdBaseVehicle.class)
.in(MdBaseVehicle::getVehicle_code, vehicle_code_list));
}
}

View File

@@ -8,9 +8,11 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.nl.common.base.TableDataInfo;
import org.nl.common.exception.BadRequestException;
import org.nl.common.logging.annotation.Log;
import org.nl.wms.ext.fab.service.dto.CallEmpVo;
import org.nl.wms.ext.fab.service.impl.FabServiceImpl;
import org.nl.wms.ext.handheld.dto.EmptyVehicleWarehousingDto;
import org.nl.wms.ext.handheld.service.HandheldService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
@@ -42,6 +44,13 @@ public class HandheldController {
return new ResponseEntity<>(HttpStatus.OK);
}
@PostMapping("/emptyVehicleWarehousing")
@Log("空载具入库")
public ResponseEntity<Object> emptyVehicleWarehousing(@RequestBody EmptyVehicleWarehousingDto dto) {
handheldService.emptyVehicleWarehousing(dto);
return new ResponseEntity<>(HttpStatus.OK);
}
@PostMapping("/rack")
@Log("外协区空料架送回")
@@ -73,6 +82,12 @@ public class HandheldController {
return new ResponseEntity<>(HttpStatus.OK);
}
@PostMapping("/getSD01GroupLog")
@Log("获取SD01出库组盘")
public ResponseEntity<Object> getSD01GroupLog(@RequestBody JSONObject param) {
return new ResponseEntity<>( handheldService.getSD01GroupLog(param),HttpStatus.OK);
}
@PostMapping("/lock")
@Log("点位锁定释放")

View File

@@ -0,0 +1,14 @@
package org.nl.wms.ext.handheld.dto;
import lombok.Data;
import java.util.List;
/**
* 空载具入库Dto
*/
@Data
public class EmptyVehicleWarehousingDto {
List<VehicleDto> vehicleList;
}

View File

@@ -0,0 +1,21 @@
package org.nl.wms.ext.handheld.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* 空载具入库Dto
*/
@Data
public class VehicleDto {
@NotBlank
@ApiModelProperty(value = "点位不能为空")
private String point_code;
@NotBlank
@ApiModelProperty(value = "载具编码不能为空")
private String vehicle_code;
}

View File

@@ -2,6 +2,8 @@ package org.nl.wms.ext.handheld.service;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.nl.wms.ext.handheld.dto.EmptyVehicleWarehousingDto;
import org.nl.wms.sch.group_delete_log.service.dto.SD01GroupLogRespondDto;
import java.util.List;
@@ -18,6 +20,13 @@ public interface HandheldService {
*/
void emptyCageStorageTask(JSONObject param);
/**
* 空载具入库
* @param param
* @return
*/
void emptyVehicleWarehousing(EmptyVehicleWarehousingDto param);
/**
* 手持呼叫空料笼
@@ -32,6 +41,12 @@ public interface HandheldService {
*/
void cageBlankingTask(JSONObject param);
/**
* 获取SD01出库组盘
* @param param
*/
SD01GroupLogRespondDto getSD01GroupLog(JSONObject param);
/**
* 点位锁定
* @param param

View File

@@ -23,6 +23,12 @@ import org.nl.common.enums.VehicleTypeEnum;
import org.nl.common.enums.region.RegionEnum;
import org.nl.system.service.dict.ISysDictService;
import org.nl.system.service.dict.dao.Dict;
import org.nl.wms.ext.handheld.dto.EmptyVehicleWarehousingDto;
import org.nl.wms.ext.handheld.dto.VehicleDto;
import org.nl.wms.sch.group_delete_log.service.dao.SchBaseVehiclematerialgroupDeleteLog;
import org.nl.wms.sch.group_delete_log.service.ISchBaseVehiclematerialgroupDeleteLogService;
import org.nl.wms.sch.group_delete_log.service.dto.LogMaterialDto;
import org.nl.wms.sch.group_delete_log.service.dto.SD01GroupLogRespondDto;
import org.nl.wms.sch.task.service.dao.SchBaseTask;
import org.nl.wms.sch.task_manage.enums.GroupBindMaterialStatusEnum;
import org.nl.common.exception.BadRequestException;
@@ -53,6 +59,7 @@ import org.nl.wms.sch.task_manage.GeneralDefinition;
import org.nl.wms.sch.task_manage.task.TaskFactory;
import org.nl.wms.sch.task_manage.task.core.TaskStatus;
import org.nl.wms.sch.task_manage.task.core.TaskType;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
@@ -101,6 +108,9 @@ public class HandheldServiceImpl implements HandheldService {
@Autowired
private ISysDictService dictService;
@Autowired
private ISchBaseVehiclematerialgroupDeleteLogService iSchBaseVehiclematerialgroupDeleteLogService;
@Autowired
private SchBasePointMapper schBasePointMapper;
static final Map<String, String> STATUS = MapOf.of("释放", "0", "锁定", "1");
@@ -132,6 +142,115 @@ public class HandheldServiceImpl implements HandheldService {
}
/**
* 手持创建空载具入库,批量
* @param param
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class) // 新增:事务控制,保证任务生成原子性
public void emptyVehicleWarehousing(EmptyVehicleWarehousingDto param) {
// 抽取魔法值为常量,便于后续维护
final String OUTSOURCE_TEMP_AREA = "外协加工暂存区";
final String MSG_VEHICLE_NOT_EXIST_BATCH = "载具%s不存在";
final String MSG_VEHICLE_OCCUPIED_BATCH = "以下载具已占用点位,无法入库:%s";
// 1. 提取载具列表并判空
List<VehicleDto> vehicleList = param.getVehicleList();
if (CollectionUtil.isEmpty(vehicleList)) {
throw new BadRequestException("载具列表不能为空!");
}
// 2. 提取载具编码过滤null/空字符串,避免无效查询),并校验
List<String> vehicleCodeList = vehicleList.stream()
.map(VehicleDto::getVehicle_code)
.filter(org.springframework.util.StringUtils::hasText) // 统一使用spring的字符串工具类过滤无效值
.collect(Collectors.toList());
if (CollectionUtil.isEmpty(vehicleCodeList)) {
throw new BadRequestException("载具编码不能为空!");
}
// 3. 查询数据库中存在的载具,批量校验无效载具
List<MdBaseVehicle> mdBaseVehicleList = iMdBaseVehicleService.selectListByVehicleCode(vehicleCodeList);
if (CollectionUtil.isEmpty(mdBaseVehicleList)) {
throw new BadRequestException("载具在系统中不存在,请在系统中维护!");
}
Set<String> existVehicleCodeSet = mdBaseVehicleList.stream()
.map(MdBaseVehicle::getVehicle_code)
.collect(Collectors.toSet());
// 批量收集所有无效载具,统一提示(优化用户体验)
List<String> invalidVehicleCodes = vehicleCodeList.stream()
.filter(vehicleCode -> !existVehicleCodeSet.contains(vehicleCode))
.collect(Collectors.toList());
if (!CollectionUtil.isEmpty(invalidVehicleCodes)) {
String invalidVehicleMsg = String.join(",", invalidVehicleCodes);
throw new BadRequestException(String.format(MSG_VEHICLE_NOT_EXIST_BATCH, invalidVehicleMsg));
}
// 4. 校验载具是否已占用有效点位,批量提示违规载具
List<SchBasePoint> occupiedPoints = iSchBasePointService.list(Wrappers.lambdaQuery(SchBasePoint.class)
.in(SchBasePoint::getVehicle_code, existVehicleCodeSet)
.ne(SchBasePoint::getRegion_name, OUTSOURCE_TEMP_AREA) // 使用常量,消除魔法值
.eq(SchBasePoint::getIs_used, true));
if (!CollectionUtil.isEmpty(occupiedPoints)) {
String occupiedMsg = occupiedPoints.stream()
.map(point -> String.format("%s点位%s", point.getVehicle_code(), point.getPoint_code()))
.collect(Collectors.joining(","));
throw new BadRequestException(String.format(MSG_VEHICLE_OCCUPIED_BATCH, occupiedMsg));
}
// 5. 点位校验(保留你的优化,仅统一工具类和冗余调用)
List<String> pointCodeList = vehicleList.stream()
.map(VehicleDto::getPoint_code)
.filter(org.springframework.util.StringUtils::hasText)
.collect(Collectors.toList());
if (CollectionUtil.isEmpty(pointCodeList)) {
throw new BadRequestException("点位编码不能为空!");
}
List<SchBasePoint> pointList = iSchBasePointService.selectListByPointCode(pointCodeList);
Set<String> existPointCodeSet = pointList.stream()
.map(SchBasePoint::getPoint_code)
.collect(Collectors.toSet());
List<String> invalidPointCodes = pointCodeList.stream()
.filter(pointCode -> !existPointCodeSet.contains(pointCode))
.collect(Collectors.toList());
if (!CollectionUtil.isEmpty(invalidPointCodes)) {
throw new BadRequestException("点位" + String.join(",", invalidPointCodes) + "不存在!");
}
// 6. 点位排序(保持原有逻辑)
List<SchBasePoint> sortedPointList = pointList.stream()
.sorted(Comparator.comparing(
SchBasePoint::getOut_empty_seq,
Comparator.nullsLast(Integer::compareTo)
))
.collect(Collectors.toList());
// 7. 匹配点位和载具生成任务优化构建Map消除双层嵌套循环提升性能
Map<String, List<VehicleDto>> point2VehicleMap = vehicleList.stream()
.collect(Collectors.groupingBy(VehicleDto::getPoint_code));
for (SchBasePoint schBasePoint : sortedPointList) {
String pointCode = schBasePoint.getPoint_code();
List<VehicleDto> matchVehicleDtos = point2VehicleMap.get(pointCode);
if (CollectionUtil.isNotEmpty(matchVehicleDtos)) {
for (VehicleDto vehicleDto : matchVehicleDtos) {
// 生成任务(可添加日志记录,便于生产环境排查问题)
artificialBendingNew(vehicleDto.getVehicle_code(), vehicleDto.getPoint_code());
}
}
}
}
/**
* 空载具送回货架
*/
@@ -192,6 +311,22 @@ public class HandheldServiceImpl implements HandheldService {
rackTask(param, vehicle, device_code, mdBaseVehicle);
}
/**
* 空料框送回
*/
private void artificialBendingNew(String vehicle_code, String point_code) {
SchBasePoint schBasePoint = iSchBasePointService.selectByPointCode(point_code);
if (ObjectUtil.isEmpty(schBasePoint)) throw new BadRequestException("设备点位不存在!");
AbstractTask connectorTask = taskFactory.getTask("EMPTYCAGENEWTask");
// 准备参数:设备编码
JSONObject jo = new JSONObject();
jo.put("device_code", point_code);
jo.put("config_code", "EMPTYCAGENEWTask");
jo.put("create_mode", GeneralDefinition.AUTO_CREATION);
jo.put("vehicle_code", vehicle_code);
connectorTask.apply(jo);
}
/**
* 空料框送回
*/
@@ -287,6 +422,43 @@ public class HandheldServiceImpl implements HandheldService {
String vehicle_code = param.getString("vehicle_code");
String type = param.getString("type");
AbstractTask connectorTask = taskFactory.getTask("BLANKINGTask");
//是否需要从日志表重新入库的标志
Boolean reentry_flag = param.getBoolean("reentry_flag");
reentry_flag = true;
//如果当前点位是SD01点位且当前载具在组盘表中不存在
List<Map> groups = iSchBaseVehiclematerialgroupService.selectGroupByVehicleCode(param.getString("vehicle_code"));
if (reentry_flag!= null && reentry_flag && "SD01".equals(device_code) && CollectionUtil.isEmpty(groups) ) {
List<Dict> dictList = dictService.getDictByName("sd01_interval_hour");
if(CollectionUtil.isNotEmpty(dictList)){
Dict dict = dictList.get(0);
if("hour".equals(dict.getLabel())){
String hour = dict.getValue();
List<SchBaseVehiclematerialgroupDeleteLog> logList = iSchBaseVehiclematerialgroupDeleteLogService
.list(Wrappers.lambdaQuery(SchBaseVehiclematerialgroupDeleteLog.class)
// 1. 对数据库字段用Lambda + 字段名MyBatis-Plus会自动转下划线
.eq(SchBaseVehiclematerialgroupDeleteLog::getVehicle_code, vehicle_code)
// 2. 对非数据库字段(@TableField(exist=false)改用apply手动拼接
.apply("point_code = {0}", device_code)
// 3. 核心新增:筛选 hour 小时内删除的数据
.apply("delete_time >= DATE_SUB(NOW(), INTERVAL {0} HOUR)", hour)
.orderByDesc(SchBaseVehiclematerialgroupDeleteLog::getDelete_time)
.last("LIMIT 1"));
//则自动将log表中的数据库插入到组盘表中
if(CollectionUtil.isNotEmpty(logList)){
SchBaseVehiclematerialgroupDeleteLog log = logList.get(0);
SchBaseVehiclematerialgroup group = new SchBaseVehiclematerialgroup();
BeanUtils.copyProperties(log,group);
iSchBaseVehiclematerialgroupService.save(group);
}
}
}
}
switch (type) {
case "1":
goShelves(schBasePoint, param, region_code, device_code, vehicle_code, connectorTask);
@@ -308,6 +480,63 @@ public class HandheldServiceImpl implements HandheldService {
}
}
@Override
public SD01GroupLogRespondDto getSD01GroupLog(JSONObject param) {
String device_code = param.getString("device_code");
String vehicle_code = param.getString("vehicle_code");
if(!"SD01".equals(device_code) || StringUtils.isBlank(vehicle_code)){
return null;
}
List<Dict> dictList = dictService.getDictByName("sd01_interval_hour");
if(CollectionUtil.isEmpty(dictList)){
return null;
}
Dict dict = dictList.get(0);
if(!"hour".equals(dict.getLabel())){
return null;
}
String hour = dict.getValue();
// 修复后的查询代码兼容下划线字段的Lambda写法
List<SchBaseVehiclematerialgroupDeleteLog> logList = iSchBaseVehiclematerialgroupDeleteLogService
.list(Wrappers.lambdaQuery(SchBaseVehiclematerialgroupDeleteLog.class)
// 1. 对数据库字段用Lambda + 字段名MyBatis-Plus会自动转下划线
.eq(SchBaseVehiclematerialgroupDeleteLog::getVehicle_code, vehicle_code)
// 2. 对非数据库字段(@TableField(exist=false)改用apply手动拼接
.apply("point_code = {0}", device_code)
// 3. 核心新增:筛选 hour 小时内删除的数据
.apply("delete_time >= DATE_SUB(NOW(), INTERVAL {0} HOUR)", hour)
.orderByDesc(SchBaseVehiclematerialgroupDeleteLog::getDelete_time)
.last("LIMIT 1"));
if(CollectionUtil.isEmpty(logList)){
return null;
}
SD01GroupLogRespondDto sd01GroupLogRespondDto = new SD01GroupLogRespondDto();
LogMaterialDto logMaterialDto = new LogMaterialDto();
logMaterialDto.setMaterial_qty(logList.get(0).getMaterial_qty());
logMaterialDto.setMaterial_code(logList.get(0).getMaterial_id());
logMaterialDto.setDue_date(logList.get(0).getDue_date());
logMaterialDto.setOrder_code(logList.get(0).getOrder_code());
List<LogMaterialDto> logMaterialDtos = new ArrayList<>();
logMaterialDtos.add(logMaterialDto);
sd01GroupLogRespondDto.setMaterial(logMaterialDtos);
sd01GroupLogRespondDto.setDevice_code(device_code);
sd01GroupLogRespondDto.setRegionCode(logList.get(0).getRegion_code());
sd01GroupLogRespondDto.setRegion_Code(logList.get(0).getRegion_code());
sd01GroupLogRespondDto.setVehicle_code(vehicle_code);
return sd01GroupLogRespondDto;
}
/**
* connector下料入库
*/

View File

@@ -0,0 +1,13 @@
package org.nl.wms.sch.group_delete_log.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.nl.wms.sch.group_delete_log.service.dao.SchBaseVehiclematerialgroupDeleteLog;
/**
* @description 服务接口
* @author zxm
* @date 2026年2月25日10:54:29
**/
public interface ISchBaseVehiclematerialgroupDeleteLogService extends IService<SchBaseVehiclematerialgroupDeleteLog> {
}

View File

@@ -0,0 +1,197 @@
package org.nl.wms.sch.group_delete_log.service.dao;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;
/**
* @author lyd
* @description /
* @date 2023-05-16
**/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("sch_base_vehiclematerialgroup_delete_log")
public class SchBaseVehiclematerialgroupDeleteLog implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "group_id", type = IdType.NONE)
@ApiModelProperty(value = "组盘标识")
private String group_id;
@ApiModelProperty(value = "区域编码")
private String region_code;
@ApiModelProperty(value = "载具编码")
private String vehicle_code;
@ApiModelProperty(value = "物料标识")
private String material_id;
@ApiModelProperty(value = "载具类型")
private String vehicle_type;
@ApiModelProperty(value = "子载具编码")
private String child_vehicle_code;
@ApiModelProperty(value = "来源载具编码")
private String source_vehicle_code;
@TableField(exist = false)
@ApiModelProperty(value = "点位编码")
private String point_code;
@TableField(exist = false)
@ApiModelProperty(value = "点位名称")
private String point_name;
@ApiModelProperty(value = "是否满托")
private Boolean is_full;
@ApiModelProperty(value = "批次")
private String pcsn;
@ApiModelProperty(value = "入库时间")
private String instorage_time;
@ApiModelProperty(value = "静置时间(分钟)")
private Integer standing_time;
@ApiModelProperty(value = "物料数量")
private Integer material_qty;
@ApiModelProperty(value = "connector任务号")
private String job_name;
@ApiModelProperty(value = "物料重量")
private BigDecimal material_weight;
@ApiModelProperty(value = "搬运工单编码")
private String order_code;
@ApiModelProperty(value = "组盘次数")
private Integer group_number;
@ApiModelProperty(value = "任务编码")
private String task_code;
@ApiModelProperty(value = "额外信息")
private String ext_data;
@ApiModelProperty(value = "是否已加工")
private Boolean has_work;
@ApiModelProperty(value = "交期时间")
private String due_date;
@ApiModelProperty(value = "车间编码")
private String workshop_code;
@ApiModelProperty(value = "组盘状态")
private String group_status;
@ApiModelProperty(value = "业务表表名")
private String table_name;
@ApiModelProperty(value = "业务表表名主键字段")
private String table_fk;
@ApiModelProperty(value = "业务表表名主键值")
private String table_fk_id;
@ApiModelProperty(value = "业务链路标识")
private String buss_move_id;
@ApiModelProperty(value = "优先级")
private String priority;
@ApiModelProperty(value = "流程编码")
private String flow_code;
@ApiModelProperty(value = "流程顺序")
private BigDecimal flow_num;
@ApiModelProperty(value = "上一任务编码")
private String before_task_code;
@ApiModelProperty(value = "下一任务编码")
private String next_task_code;
@ApiModelProperty(value = "扩展")
private String extend;
@ApiModelProperty(value = "备注")
private String remark;
@ApiModelProperty(value = "1:待绑定2:已绑定3:已解绑")
private String group_bind_material_status;
@ApiModelProperty(value = "是否删除")
private Boolean is_delete;
@ApiModelProperty(value = "创建人")
private String create_id;
@ApiModelProperty(value = "创建人")
private String create_name;
@ApiModelProperty(value = "创建时间")
private String create_time;
@ApiModelProperty(value = "修改人")
private String update_id;
@ApiModelProperty(value = "修改人")
private String update_name;
@ApiModelProperty(value = "修改时间")
private String update_time;
@ApiModelProperty(value = "移动途径")
private String move_way;
@ApiModelProperty(value = "物料图片路径")
private String material_path;
@ApiModelProperty(value = "托盘图片路径")
private String vehicle_path;
//货架待命 1 、任务中 2 、人工处理中 3
@ApiModelProperty(value = "状态")
private String status;
//货架待命 1 、任务中 2 、人工处理中 3
@ApiModelProperty(value = "删除时间")
private String delete_time;
@TableField(exist = false)
private String materialFile;
@TableField(exist = false)
private String daybetween;
@TableField(exist = false)
private String material_name;
@TableField(exist = false)
private String theLocation;
@TableField(exist = false)
private boolean hasChildren;
@TableField(exist = false)
private List<SchBaseVehiclematerialgroupDeleteLog> children;
@TableField(exist = false)
private String material_code;
@TableField(exist = false)
private String material_spec;
@TableField(exist = false)
private String region_name;
@TableField(exist = false)
private String group_bind_material_status_name;
}

View File

@@ -0,0 +1,22 @@
package org.nl.wms.sch.group_delete_log.service.dao.mapper;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.ibatis.annotations.Param;
import org.nl.wms.ext.fab.service.dto.SendVehicleVo;
import org.nl.wms.sch.group.service.dao.SchBaseVehiclematerialgroup;
import org.nl.wms.sch.group.service.dto.SchBaseVehiclematerialgroupQuery;
import org.nl.wms.sch.group_delete_log.service.dao.SchBaseVehiclematerialgroupDeleteLog;
import java.util.List;
import java.util.Map;
/**
* @author zxm
* @date 2026年2月25日10:59:40
**/
public interface SchBaseVehiclematerialgroupDeleteLogMapper extends BaseMapper<SchBaseVehiclematerialgroupDeleteLog> {
}

View File

@@ -0,0 +1,11 @@
package org.nl.wms.sch.group_delete_log.service.dto;
import lombok.Data;
@Data
public class LogMaterialDto {
private String order_code;
private String material_code;
private Integer material_qty;
private String due_date;
}

View File

@@ -0,0 +1,16 @@
package org.nl.wms.sch.group_delete_log.service.dto;
import lombok.Data;
import java.util.List;
@Data
public class SD01GroupLogRespondDto {
private String device_code;
private String regionCode;
private String region_Code;
private String vehicle_code;
List<LogMaterialDto> material;
}

View File

@@ -0,0 +1,65 @@
package org.nl.wms.sch.group_delete_log.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.nl.common.domain.query.PageQuery;
import org.nl.common.exception.BadRequestException;
import org.nl.common.utils.SecurityUtils;
import org.nl.wms.database.material.service.IMdBaseMaterialService;
import org.nl.wms.database.material.service.dao.MdBaseMaterial;
import org.nl.wms.database.vehicle.service.IMdBaseVehicleService;
import org.nl.wms.database.vehicle.service.dao.MdBaseVehicle;
import org.nl.wms.ext.fab.service.dto.SendVehicleVo;
import org.nl.wms.sch.group.service.ISchBaseVehiclematerialgroupService;
import org.nl.wms.sch.group.service.dao.SchBaseVehiclematerialgroup;
import org.nl.wms.sch.group.service.dao.mapper.SchBaseVehiclematerialgroupMapper;
import org.nl.wms.sch.group.service.dto.SchBaseVehiclematerialgroupQuery;
import org.nl.wms.sch.group_delete_log.service.ISchBaseVehiclematerialgroupDeleteLogService;
import org.nl.wms.sch.group_delete_log.service.dao.SchBaseVehiclematerialgroupDeleteLog;
import org.nl.wms.sch.group_delete_log.service.dao.mapper.SchBaseVehiclematerialgroupDeleteLogMapper;
import org.nl.wms.sch.point.service.ISchBasePointService;
import org.nl.wms.sch.point.service.dao.SchBasePoint;
import org.nl.wms.sch.process_flow.service.ProcessFlowService;
import org.nl.wms.sch.task_manage.task.tasks.pcoperation.PcOperationCMTask;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author lyd
* @description 服务实现
* @date 2023-05-16
**/
@Slf4j
@Service
public class SchBaseVehiclematerialgroupDeleteLogServiceImpl extends ServiceImpl<SchBaseVehiclematerialgroupDeleteLogMapper, SchBaseVehiclematerialgroupDeleteLog> implements ISchBaseVehiclematerialgroupDeleteLogService {
}

View File

@@ -107,11 +107,19 @@ public interface ISchBasePointService extends IService<SchBasePoint> {
/**
* 根据点位编码查询
*
* @param start_device_code
* @param device_code
* @return
*/
SchBasePoint selectByPointCode(String device_code);
/**
* 根据点位编码查询
*
* @param device_code
* @return
*/
List<SchBasePoint> selectListByPointCode(List<String> device_code_list);
/**
* 查询二次分配的虚拟站点
*

View File

@@ -317,6 +317,13 @@ public class SchBasePointServiceImpl extends ServiceImpl<SchBasePointMapper, Sch
.eq(SchBasePoint::getIs_used, true));
}
@Override
public List<SchBasePoint> selectListByPointCode(List<String> device_code_list) {
return pointMapper.selectList(Wrappers.lambdaQuery(SchBasePoint.class)
.in(SchBasePoint::getPoint_code, device_code_list)
.eq(SchBasePoint::getIs_used, true));
}
@Override
public SchBasePoint selectByReassign(String region_code, String vehicleCode) {
synchronized (SchBasePointServiceImpl.class) {

View File

@@ -0,0 +1,243 @@
package org.nl.wms.sch.task_manage.task.tasks.handheld;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.nl.common.enums.GoodsEnum;
import org.nl.common.enums.VehicleTypeEnum;
import org.nl.common.enums.region.RegionEnum;
import org.nl.common.exception.BadRequestException;
import org.nl.config.MapOf;
import org.nl.system.service.notice.ISysNoticeService;
import org.nl.wms.database.vehicle.service.IMdBaseVehicleService;
import org.nl.wms.database.vehicle.service.dao.MdBaseVehicle;
import org.nl.wms.ext.acs.service.dto.to.BaseResponse;
import org.nl.wms.sch.group.service.ISchBaseVehiclematerialgroupService;
import org.nl.wms.sch.point.service.ISchBasePointService;
import org.nl.wms.sch.point.service.dao.SchBasePoint;
import org.nl.wms.sch.task.service.ISchBaseTaskService;
import org.nl.wms.sch.task.service.ISchBaseTaskconfigService;
import org.nl.wms.sch.task.service.dao.SchBaseTask;
import org.nl.wms.sch.task_manage.AbstractTask;
import org.nl.wms.sch.task_manage.GeneralDefinition;
import org.nl.wms.sch.task_manage.enums.NoticeTypeEnum;
import org.nl.wms.sch.task_manage.enums.TaskFinishedTypeEnum;
import org.nl.wms.sch.task_manage.task.core.TaskStatus;
import org.nl.wms.util.PointUtils;
import org.nl.wms.util.TaskUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.List;
/**
* 手持创建空料笼入库新,主要是新增小车
*/
@Component("EMPTYCAGENEWTask")
public class EmptyCageNewTask extends AbstractTask {
private static final String TASK_CONFIG_CODE = "EMPTYCAGENEWTask";
@Autowired
private ISchBasePointService pointService;
@Autowired
private ISchBaseTaskService taskService;
@Autowired
private ISchBaseTaskconfigService taskConfigService;
@Autowired
private ISysNoticeService noticeService;
@Autowired
private ISchBasePointService schBasePointService;
@Autowired
private ISchBaseVehiclematerialgroupService schBaseVehiclematerialgroupService;
@Autowired
private IMdBaseVehicleService iMdBaseVehicleService;
private static final HashMap<String,Integer> IS_VEHICLE = MapOf.of("vehicles",2,"vehicle_code",1);
private static final HashMap<String,Integer> POINT_TYPE = MapOf.of("空托盘",0,"满托盘",1);
@Override
protected void create() throws BadRequestException {
// 获取任务
List<SchBaseTask> tasks = taskService.findTasksByTaskStatus(TASK_CONFIG_CODE, TaskStatus.APPLY);
// 配置信息
for (SchBaseTask task : tasks) {
String vehicle_type = getVehicleType(task);
SchBasePoint schBasePoint = null;
switch (vehicle_type) {
case "R01":
schBasePoint = schBasePointService.selectStackPoint(RegionEnum.S.getRegion_code(),
GoodsEnum.OUT_OF_STOCK.getValue(), VehicleTypeEnum.FRAME_R01.getVehicleCode(), IS_VEHICLE.get("vehicles"), POINT_TYPE.get("空托盘"));
break;
case "R02":
schBasePoint = schBasePointService.selectStackPoint(RegionEnum.S.getRegion_code(),
GoodsEnum.OUT_OF_STOCK.getValue(), VehicleTypeEnum.FRAME_R02.getVehicleCode(), IS_VEHICLE.get("vehicles"), POINT_TYPE.get("空托盘"));
break;
case "S04":
schBasePoint = schBasePointService.selectStackPoint(RegionEnum.LAG.getRegion_code(),
GoodsEnum.OUT_OF_STOCK.getValue(), VehicleTypeEnum.RACKS_S04.getVehicleCode(), IS_VEHICLE.get("vehicle_code"), POINT_TYPE.get("空托盘"));
if (ObjectUtil.isEmpty(schBasePoint)) {
schBasePoint = schBasePointService.selectStackPoint(RegionEnum.S.getRegion_code(),
GoodsEnum.OUT_OF_STOCK.getValue(), VehicleTypeEnum.RACKS_S04.getVehicleCode(), IS_VEHICLE.get("vehicle_code"), POINT_TYPE.get("空托盘"));
}
break;
case "S06":
schBasePoint = schBasePointService.selectStackPoint(RegionEnum.LAG.getRegion_code(),
GoodsEnum.OUT_OF_STOCK.getValue(), VehicleTypeEnum.RACKS_S06.getVehicleCode(), IS_VEHICLE.get("vehicle_code"), POINT_TYPE.get("空托盘"));
if (ObjectUtil.isEmpty(schBasePoint)) {
schBasePoint = schBasePointService.selectStackPoint(RegionEnum.S.getRegion_code(),
GoodsEnum.OUT_OF_STOCK.getValue(), VehicleTypeEnum.RACKS_S06.getVehicleCode(), IS_VEHICLE.get("vehicle_code"), POINT_TYPE.get("空托盘"));
}
break;
default:
break;
}
if (ObjectUtil.isEmpty(schBasePoint)) {
task.setRemark("未找到所需点位!");
taskService.updateById(task);
// 消息通知
noticeService.createNotice("未找到所需点位!", TASK_CONFIG_CODE + task.getTask_code(),
NoticeTypeEnum.WARN.getCode());
continue;
}
// 设置终点并修改创建成功状态
TaskUtils.setUpdateByAcs(task);
task.setPoint_code2(schBasePoint.getPoint_code());
task.setVehicle_type(vehicle_type);
task.setRemark("");
task.setTask_status(TaskStatus.CREATED.getCode());
taskService.updateById(task);
}
}
/**
* 获取托盘类型
* @param task 任务对象
* @return 托盘类型
*/
private String getVehicleType(SchBaseTask task) {
String vehicle_type = task.getVehicle_type();
String vehicle_code = task.getVehicle_code();
if (StrUtil.isNotEmpty(vehicle_code)) {
String vehicleCode = vehicle_code;
if(vehicle_code.contains(",")){
String[] split = vehicle_code.split(",");
vehicleCode = split[0];
}
MdBaseVehicle mdBaseVehicle = iMdBaseVehicleService.selectByVehicleCode(vehicleCode);
vehicle_type = mdBaseVehicle.getVehicle_type();
}
return vehicle_type;
}
@Override
protected void updateStatus(String task_code, TaskStatus status) {
//TODO:完成任务的时候将int_task_code的清除
}
@Override
public void forceFinish(String task_code) {
SchBaseTask taskObj = taskService.getByCode(task_code);
if (ObjectUtil.isEmpty(taskObj)) {
throw new BadRequestException("该任务不存在");
}
this.finishTask(taskObj, TaskFinishedTypeEnum.MANUAL_CONNECTOR);
}
@Override
public void cancel(String task_code) {
//TODO:取消任务的时候将int_task_code的清除
SchBaseTask taskObj = taskService.getByCode(task_code);
cancelPoint(taskObj.getPoint_code1());
cancelPoint(taskObj.getPoint_code2());
if (ObjectUtil.isEmpty(taskObj)) {
throw new BadRequestException("该任务不存在");
}
this.cancelTask(taskObj, TaskFinishedTypeEnum.MANUAL_CONNECTOR);
}
/**
* 取消任务还原点位状态
*
* @param pointCode 点位名称
*/
private void cancelPoint(String pointCode) {
SchBasePoint schBasePoint = schBasePointService.selectByPointCode(pointCode);
if (ObjectUtil.isNotEmpty(schBasePoint)) {
schBasePoint.setIs_lock(false);
PointUtils.setUpdateByAcs(schBasePoint);
schBasePointService.updateById(schBasePoint);
}
}
@Override
protected void feedbackTaskState(JSONObject param, SchBaseTask schBaseTask, BaseResponse result) {
}
/**
* 更新任务状态
*
* @param taskObj
* @param taskFinishedType
*/
public void finishTask(SchBaseTask taskObj, TaskFinishedTypeEnum taskFinishedType) {
updateStartPointStatus(taskObj);
updateEndPointStatus(taskObj);
// 任务完成
taskObj.setTask_status(TaskStatus.FINISHED.getCode());
taskObj.setRemark(GeneralDefinition.TASK_FINISH);
taskObj.setFinished_type(taskFinishedType.getCode());
TaskUtils.setUpdateByType(taskObj, taskFinishedType);
taskService.updateById(taskObj);
}
/**
* 更新起点点位状态
*
* @param taskObj 任务对象
*/
private void updateStartPointStatus(SchBaseTask taskObj) {
String startPoint = taskObj.getPoint_code1();
SchBasePoint schBasePoint = pointService.selectByPointCode(startPoint);
if (ObjectUtil.isNotEmpty(schBasePoint)) {
PointUtils.updateByIngTaskCode(schBasePoint);
pointService.update(Wrappers.lambdaUpdate(SchBasePoint.class)
.eq(SchBasePoint::getPoint_code, startPoint)
.set(SchBasePoint::getIs_lock, false));
}
}
/**
* 更新终点点位状态
*
* @param taskObj 任务对象
*/
private void updateEndPointStatus(SchBaseTask taskObj) {
String point_code2 = taskObj.getPoint_code2();
SchBasePoint schBasePoint2 = pointService.selectByPointCode(point_code2);
if (ObjectUtil.isNotEmpty(schBasePoint2)) {
String vehicle_type = taskObj.getVehicle_type();
if (vehicle_type.equals(VehicleTypeEnum.FRAME_R01.getVehicleCode()) || vehicle_type.equals(VehicleTypeEnum.FRAME_R02.getVehicleCode())) {
schBasePoint2.setVehicles(taskObj.getVehicle_code());
schBasePoint2.setVehicle_qty(taskObj.getVehicle_qty());
} else {
schBasePoint2.setVehicle_code(taskObj.getVehicle_code());
}
schBasePoint2.setPoint_status(GoodsEnum.EMPTY_PALLETS.getValue());
schBasePoint2.setIs_lock(false);
PointUtils.setUpdateByAcs(schBasePoint2);
pointService.updateById(schBasePoint2);
}
}
public void cancelTask(SchBaseTask taskObj, TaskFinishedTypeEnum taskFinishedType) {
taskObj.setRemark(GeneralDefinition.TASK_CANCEL);
taskObj.setTask_status(TaskStatus.CANCELED.getCode());
taskObj.setFinished_type(taskFinishedType.getCode());
TaskUtils.setUpdateByType(taskObj, taskFinishedType);
taskService.updateById(taskObj);
}
}

View File

@@ -57,11 +57,21 @@ public class ToStoreHouseTask extends AbstractTask {
// 配置信息
for (SchBaseTask task : tasks) {
SchBasePoint schBasePoint = null;
//这个修改 优先拿在满拖库的
if (task.getVehicle_type().equals(VehicleTypeEnum.FRAME_R02.getVehicleCode()) || task.getVehicle_type().equals(VehicleTypeEnum.FRAME_R01.getVehicleCode())) {
schBasePoint = schBasePointService.selectByEmptyCage(RegionEnum.DDLK.getRegion_code(),
schBasePoint = schBasePointService.selectByEmptyCage(RegionEnum.S.getRegion_code(),
task.getVehicle_type(), GoodsEnum.EMPTY_PALLETS.getValue(), true, task);
if (ObjectUtil.isEmpty(schBasePoint)) {
schBasePoint = schBasePointService.selectByEmptyCage(RegionEnum.DDLK.getRegion_code(),
task.getVehicle_type(), GoodsEnum.EMPTY_PALLETS.getValue(), true, task);
}
} else if (task.getVehicle_type().equals(VehicleTypeEnum.RACKS_S04.getVehicleCode()) || task.getVehicle_type().equals(VehicleTypeEnum.RACKS_S06.getVehicleCode())) {
schBasePoint = schBasePointService.selectByEmptyCage(RegionEnum.LAG.getRegion_code(),
task.getVehicle_type(), GoodsEnum.EMPTY_PALLETS.getValue(), true, task);
if (ObjectUtil.isEmpty(schBasePoint)) {
schBasePoint = schBasePointService.selectByEmptyCage(RegionEnum.S.getRegion_code(),
task.getVehicle_type(), GoodsEnum.EMPTY_PALLETS.getValue(), true, task);
}
} else {
schBasePoint = schBasePointService.selectByVehicleQty(task.getVehicle_type());
}

View File

@@ -29,7 +29,7 @@ spring:
datasource:
mysql:
driver-class-name: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
url: jdbc:log4jdbc:mysql://${DB_HOST:192.168.81.251}:${DB_PORT:3306}/${DB_NAME:ximenzi_lms}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true
url: jdbc:log4jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:3306}/${DB_NAME:ximenzi_lms}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true
username: ${DB_USER:root}
password: ${DB_PWD:123456}
type: com.alibaba.druid.pool.DruidDataSource
@@ -42,11 +42,10 @@ spring:
redis:
#数据库索引
database: ${REDIS_DB:2}
database: ${REDIS_DB:1}
# host: ${REDIS_HOST:10.44.101.112}
host: ${REDIS_HOST:127.0.0.1}
port: ${REDIS_PORT:6379}
password: ${REDIS_PWD:}
# 登录相关配置
login:
@@ -141,16 +140,14 @@ sa-token:
token-session-check-login: false
alone-redis:
# Redis数据库索引默认为0
database: 2
database: 1
# Redis服务器地址
host: 127.0.0.1
# Redis服务器连接端口
port: 6379
# Redis服务器连接密码默认为空
password:
# 连接超时时间
timeout: 10s
lucene:
index:
path: E:\lms\lucene\index
path: D:\lms\lucene\index

View File

@@ -112,6 +112,6 @@ mybatis-plus:
id-type: INPUT
lucene:
index:
path: E:\lms\lucene\index
path: D:\lms\lucene\index
tlog:
enable-invoke-time-print: true