opt:1.完善示教功能。2.添加 站点信息

This commit is contained in:
2025-07-09 10:47:29 +08:00
parent 7a24b1bd99
commit 3d57839042
15 changed files with 277 additions and 60 deletions

View File

@@ -14,7 +14,7 @@ import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication @SpringBootApplication
@EnableTransactionManagement @EnableTransactionManagement
@RestController @RestController
@MapperScan("org.nl.apt15e.**.config") @MapperScan("org.nl.apt15e.**.mapper")
public class Apt15EApplication { public class Apt15EApplication {
public static void main(String[] args) { public static void main(String[] args) {

View File

@@ -0,0 +1,43 @@
package org.nl.apt15e.apt.station;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author dsh
* 2025/7/7
*/
@Getter
@AllArgsConstructor
public enum StationTypeEnum {
//站点类型 Station工位点 Charge充电点 Breaks休息点 Docking对接点
STATION(1, "STATION", "工位点"),
CHARGE(2, "CHARGE", "充电点"),
BREAKS(3, "BREAKS", "休息点"),
DOCKING(4, "DOCKING", "对接点"),
//动作类型 Ascend升叉 Descend降叉 Move移动 Customize自定义
ASCEND(1, "Ascend", "升叉"),
DESCEND(2, "Descend", "降叉"),
MOVE(3, "Move", "移动"),
CUSTOMIZE(4, "Customize", "自定义");
/**
*索引
*/
private final Integer index;
/**
* 编码
*/
private final String code;
/**
*名称
*/
private final String name;
}

View File

@@ -1,6 +1,9 @@
package org.nl.apt15e.apt.station.dao; package org.nl.apt15e.apt.station.dao;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data; import lombok.Data;
import org.springframework.stereotype.Component;
import java.io.Serializable; import java.io.Serializable;
@@ -9,12 +12,14 @@ import java.io.Serializable;
* 2025/7/4 * 2025/7/4
*/ */
@Data @Data
@TableName("station")
public class Station implements Serializable { public class Station implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** /**
* 站点编码 对应地图上站点 * 站点编码 对应地图上站点
*/ */
@TableId
private String station_code; private String station_code;
/** /**
@@ -23,7 +28,12 @@ public class Station implements Serializable {
private String station_name; private String station_name;
/** /**
* 动作类型 * 站点类型 (Station工位点 Charge充电点 Breaks休息点 Docking对接点)
*/
private String station_type;
/**
* 动作类型 (Ascend升叉 Descend降叉 Move移动 Customize自定义)
*/ */
private String action_type; private String action_type;

View File

@@ -0,0 +1,17 @@
package org.nl.apt15e.apt.station.service;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.IService;
import org.nl.apt15e.apt.station.dao.Station;
import java.util.List;
/**
* @author dsh
* 2025/7/7
*/
public interface StationService extends IService<Station> {
JSONObject queryAllStation();
}

View File

@@ -0,0 +1,33 @@
package org.nl.apt15e.apt.station.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.nl.apt15e.apt.station.dao.Station;
import org.nl.apt15e.apt.station.service.StationService;
import org.nl.apt15e.apt.station.service.mapper.StationMapper;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* @author dsh
* 2025/7/7
*/
@Service
public class StationServiceImpl extends ServiceImpl<StationMapper, Station> implements StationService {
@Resource
private StationMapper stationMapper;
@Override
public JSONObject queryAllStation() {
JSONObject jsonObject = new JSONObject();
jsonObject.put("code", HttpStatus.OK.value());
jsonObject.put("data", stationMapper.selectList(null));
return jsonObject;
}
}

View File

@@ -0,0 +1,14 @@
package org.nl.apt15e.apt.station.service.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.nl.apt15e.apt.station.dao.Station;
/**
* @author dsh
* 2025/7/7
*/
@Mapper
public interface StationMapper extends BaseMapper<Station> {
}

View File

@@ -0,0 +1,28 @@
package org.nl.apt15e.apt.station.service.rest;
import lombok.extern.slf4j.Slf4j;
import org.nl.apt15e.apt.station.service.StationService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
/**
* @author dsh
* 2025/7/8
*/
@RestController
@Slf4j
@RequestMapping("/station")
public class StationController {
@Resource
private StationService stationService;
@GetMapping("/queryAllStation")
private ResponseEntity<Object> startMapping() {
return new ResponseEntity<>(stationService.queryAllStation(), HttpStatus.OK);
}
}

View File

@@ -58,7 +58,7 @@ public interface TeachingService {
* @param mapName * @param mapName
* @return * @return
*/ */
File getRunMapZip(String mapName); byte[] getRunMapZip(String mapName);
/** /**
* 同步地图到调度 * 同步地图到调度

View File

@@ -2,30 +2,21 @@ package org.nl.apt15e.apt.teaching.service.impl;
import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ZipUtil;
import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse; import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.nl.apt15e.apt.dao.VehicleException;
import org.nl.apt15e.apt.dao.VehicleInfo;
import org.nl.apt15e.apt.teaching.service.TeachingService; import org.nl.apt15e.apt.teaching.service.TeachingService;
import org.nl.apt15e.apt.vehicle.ProcessZip;
import org.nl.apt15e.apt.vehicle.service.impl.VehicleInfoServiceImpl;
import org.nl.apt15e.common.BadRequestException; import org.nl.apt15e.common.BadRequestException;
import org.nl.apt15e.util.HTTPUtil; import org.nl.apt15e.util.HTTPUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.io.ByteArrayInputStream; import javax.annotation.Resource;
import java.io.File; import java.io.File;
import java.nio.charset.Charset;
import java.util.Collections;
import java.util.Map; import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/** /**
* @author dsh * @author dsh
@@ -35,6 +26,9 @@ import java.util.zip.ZipInputStream;
@Service @Service
public class TeachingServiceImpl implements TeachingService { public class TeachingServiceImpl implements TeachingService {
@Resource
private ProcessZip processZip;
@Override @Override
public Map<String, Object> startMapping(String mapName) { public Map<String, Object> startMapping(String mapName) {
if ("".equals(mapName)){ if ("".equals(mapName)){
@@ -222,7 +216,7 @@ public class TeachingServiceImpl implements TeachingService {
} }
@Override @Override
public File getRunMapZip(String mapName) { public byte[] getRunMapZip(String mapName) {
if ("".equals(mapName)){ if ("".equals(mapName)){
throw new BadRequestException("mapName is empty"); throw new BadRequestException("mapName is empty");
} }
@@ -237,32 +231,12 @@ public class TeachingServiceImpl implements TeachingService {
} }
// 检查响应状态码 // 检查响应状态码
if (response.isOk()) { if (response.isOk()) {
// 获取响应体内容 // 获取zip包
// JSONObject body = JSON.parseObject(response.body());
// 3. 将响应体写入临时ZIP文件
byte[] zipBytes = response.bodyBytes(); byte[] zipBytes = response.bodyBytes();
File fileName = new File(mapName); processZip.processZipResponse(zipBytes);
File tempZipFile = FileUtil.writeBytes(zipBytes, FileUtil.createTempFile(fileName));
// 4. 解压ZIP文件
// File unzipDir = ZipUtil.unzip(tempZipFile, Charset.defaultCharset());
// 5. 处理解压后的文件
// File[] files = unzipDir.listFiles();
// if (files != null) {
// for (File file : files) {
// System.out.println("文件名: " + file.getName());
// System.out.println("文件内容: ");
// System.out.println(FileUtil.readUtf8String(file)); // 读取文本内容
// // 如果是二进制文件使用FileUtil.readBytes(file)
// }
// }
// 6. 清理临时文件(可选)
// FileUtil.del(tempZipFile);
// FileUtil.del(unzipDir);
log.info("获取地图包"); log.info("获取地图包");
return tempZipFile; return zipBytes;
} }
log.info("获取地图包失败"); log.info("获取地图包失败");
throw new BadRequestException("获取地图包失败"); throw new BadRequestException("获取地图包失败");
@@ -270,7 +244,8 @@ public class TeachingServiceImpl implements TeachingService {
@Override @Override
public Map<String, Object> synchronizeMap(String mapName) { public Map<String, Object> synchronizeMap(String mapName) {
File zipFile = this.getRunMapZip(mapName); byte[] zipFile = this.getRunMapZip(mapName);
HttpResponse response = null; HttpResponse response = null;
try { try {
response = HttpRequest.post("http://192.168.100.82:8081/map/uploadFile") response = HttpRequest.post("http://192.168.100.82:8081/map/uploadFile")
@@ -279,9 +254,8 @@ public class TeachingServiceImpl implements TeachingService {
.header("token", "admin123") .header("token", "admin123")
.header("name", "lx-script") .header("name", "lx-script")
.header("Content-Type", "multipart/form-data;charset=UTF-8") .header("Content-Type", "multipart/form-data;charset=UTF-8")
.form("areaId",1) .form("areaId", VehicleInfoServiceImpl.vehicleInfo.getAreaId())
.form("areaName","") .form("file",zipFile,mapName+".zip")
.form("data",zipFile)
.execute(); .execute();
} catch (Exception e) { } catch (Exception e) {
log.info("同步地图到调度接口报错:{}",e.getMessage()); log.info("同步地图到调度接口报错:{}",e.getMessage());

View File

@@ -0,0 +1,104 @@
package org.nl.apt15e.apt.vehicle;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.nl.apt15e.apt.station.StationTypeEnum;
import org.nl.apt15e.apt.station.dao.Station;
import org.nl.apt15e.apt.station.service.StationService;
import org.nl.apt15e.apt.station.service.impl.StationServiceImpl;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
* 解析迈尔微视地图包数据
* @author dsh
* 2025/7/7
*/
@Service
public class ProcessZip {
@Resource
private StationServiceImpl stationService;
public void processZipResponse(byte[] zipBytes) {
try (ByteArrayInputStream bais = new ByteArrayInputStream(zipBytes);
ZipInputStream zis = new ZipInputStream(bais, StandardCharsets.UTF_8)) {
ZipEntry entry;
// 遍历ZIP文件中的每个条目
while ((entry = zis.getNextEntry()) != null) {
String entryName = entry.getName();
// 3. 筛选.lxmap文件
if (entryName.toLowerCase().endsWith(".lxmap")) {
System.out.println("解析文件: " + entryName);
// 4. 读取文件内容使用BufferedReader按行处理
BufferedReader reader = new BufferedReader(
new InputStreamReader(zis, StandardCharsets.UTF_8));
//存储站点之前先清除站点表中数据
stationService.remove(new LambdaQueryWrapper<>());
String line;
int lineNumber = 0;
while ((line = reader.readLine()) != null) {
lineNumber++;
// 5. 处理每一行数据
processLine(line, lineNumber);
}
}
}
}
catch (Exception e) {
throw new RuntimeException("处理ZIP文件失败", e);
}
}
public void processLine(String line, int lineNumber) {
// 跳过空行
if (line.trim().isEmpty()) {
return;
}
// 检查是否以"Cairn: Goal"开头
if (line.startsWith("Cairn:")) {
// 截取开头后面的数据6个字符长度
String dataPart = line.substring(6).trim();
if (!dataPart.isEmpty()) {
// 按空格分割字段(多个连续空格视为一个分隔符)
String[] processData = dataPart.split("\\s+");
//判断数据是否是点位数据 && 数据长度正常 && 点位类型是1工位点(站点)
//满足以上条件 目前只记录站点
if ("Goal".equals(processData[0]) && processData.length > 9 && "1".equals(processData[8])) {
System.out.printf("行号 %d - 有效数据: %s%n", lineNumber, Arrays.toString(processData));
Station station = new Station();
station.setStation_code(processData[2]);
station.setStation_name(processData[2]);
station.setX(Double.valueOf(processData[5]));
station.setY(Double.valueOf(processData[6]));
station.setAngle(Double.valueOf(processData[7]));
station.setAction_type(StationTypeEnum.CUSTOMIZE.getCode());
station.setStation_type(StationTypeEnum.STATION.getCode());
stationService.save(station);
System.out.printf("行号 %d - 有效数据: %s%n", lineNumber, station);
}
} else {
System.out.printf("行号 %d - 警告: 'Cairn: Goal'后无内容%n", lineNumber);
}
} else {
// 非目标行,可根据需要处理或忽略
System.out.printf("行号 %d - 忽略: %s%n", lineNumber, line);
}
}
}

View File

@@ -1,4 +1,4 @@
package org.nl.apt15e.apt.dao; package org.nl.apt15e.apt.vehicle.dao;
import lombok.Data; import lombok.Data;

View File

@@ -1,4 +1,4 @@
package org.nl.apt15e.apt.dao; package org.nl.apt15e.apt.vehicle.dao;
import lombok.Data; import lombok.Data;

View File

@@ -1,9 +1,8 @@
package org.nl.apt15e.apt.rest; package org.nl.apt15e.apt.vehicle.rest;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.nl.apt15e.apt.dao.VehicleInfo; import org.nl.apt15e.apt.vehicle.dao.VehicleInfo;
import org.nl.apt15e.apt.service.VehicleInfoService; import org.nl.apt15e.apt.vehicle.service.VehicleInfoService;
import org.nl.apt15e.common.logging.annotation.Log;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;

View File

@@ -1,6 +1,6 @@
package org.nl.apt15e.apt.service; package org.nl.apt15e.apt.vehicle.service;
import org.nl.apt15e.apt.dao.VehicleInfo; import org.nl.apt15e.apt.vehicle.dao.VehicleInfo;
/** /**
* @author dsh * @author dsh

View File

@@ -1,19 +1,14 @@
package org.nl.apt15e.apt.service.impl; package org.nl.apt15e.apt.vehicle.service.impl;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse; import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.nl.apt15e.apt.dao.VehicleException; import org.nl.apt15e.apt.vehicle.dao.VehicleException;
import org.nl.apt15e.apt.dao.VehicleInfo; import org.nl.apt15e.apt.vehicle.dao.VehicleInfo;
import org.nl.apt15e.apt.service.VehicleInfoService; import org.nl.apt15e.apt.vehicle.service.VehicleInfoService;
import org.nl.apt15e.apt.websocket.WebSocketVehicleServer; import org.nl.apt15e.apt.websocket.WebSocketVehicleServer;
import org.nl.apt15e.util.HTTPUtil; import org.nl.apt15e.util.HTTPUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.TaskScheduler; import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;