#update
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
package com.maibu.core.business;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.maibu.core.enums.CompareEnum;import lombok.Data;
|
||||
|
||||
|
||||
@Data
|
||||
@TableName("error_identification")
|
||||
public class ErrorIdentificationStandard {
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
private String field;
|
||||
private String compareValues;
|
||||
private CompareEnum compareType;
|
||||
private String errorDescription;
|
||||
private String errorName;
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
package com.maibu.core.business;
|
||||
|
||||
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 com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.maibu.core.domain.BaseDO;
|
||||
import com.maibu.core.enums.ConnectType;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 除了割草机器人之外的设备 包含其他的物联设备
|
||||
*
|
||||
* @author rqian
|
||||
* @date 2026-3-11
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@TableName("iot_device_common")
|
||||
public class IoTCommonDevice extends BaseDO {
|
||||
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 设备ID
|
||||
*/
|
||||
private String deviceId;
|
||||
|
||||
/**
|
||||
* 设备名称
|
||||
*/
|
||||
private String deviceName;
|
||||
|
||||
/**
|
||||
* 固件版本
|
||||
*/
|
||||
private BigDecimal firmwareVersion;
|
||||
|
||||
/**
|
||||
* 设备类型(1-直连设备、2-网关设备、3-监控设备)
|
||||
*/
|
||||
private Integer deviceType;
|
||||
|
||||
/**
|
||||
* 设备状态(1-未激活,2-禁用,3-在线,4-离线)
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 设备在线状态(1-在线,2-离线)
|
||||
*/
|
||||
private Integer onlineStatus;
|
||||
|
||||
/**
|
||||
* 设备所在地址
|
||||
*/
|
||||
private String networkAddress;
|
||||
|
||||
/**
|
||||
* 设备入网IP
|
||||
*/
|
||||
private String networkIp;
|
||||
|
||||
/**
|
||||
* 设备经度
|
||||
*/
|
||||
private BigDecimal longitude;
|
||||
|
||||
/**
|
||||
* 设备纬度
|
||||
*/
|
||||
private BigDecimal latitude;
|
||||
|
||||
/**
|
||||
* 激活时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
private Date activeTime;
|
||||
|
||||
/**
|
||||
* 物模型值
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private Map<String, Object> properties;
|
||||
|
||||
/**
|
||||
* 设备备注
|
||||
**/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 分组ID,用于分组查询
|
||||
**/
|
||||
private Long groupId;
|
||||
|
||||
/**
|
||||
* 是否是模拟设备
|
||||
*/
|
||||
private Integer isSimulate;
|
||||
|
||||
private ConnectType connectType;
|
||||
|
||||
@TableField(exist = false)
|
||||
private Boolean hasRegister;
|
||||
|
||||
private Long orgId; //组织id
|
||||
|
||||
private Long siteId; //场站id
|
||||
|
||||
private Long modelId; //属于某个设备模型
|
||||
|
||||
|
||||
/**
|
||||
* 产品ID
|
||||
*/
|
||||
private Long productId;
|
||||
|
||||
private String productName;
|
||||
|
||||
@TableField(exist = false)
|
||||
private List<DeviceModelProperty> propertyList;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.maibu.core.business;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class IoTCommonDeviceAction {
|
||||
|
||||
private String actionId;
|
||||
|
||||
private String deviceId;
|
||||
|
||||
private String command;
|
||||
|
||||
private String actionName;
|
||||
|
||||
private Map<String,Object> params; // 动作参数
|
||||
|
||||
private Integer status;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.maibu.core.business;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||
import com.maibu.core.domain.BaseDO;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springframework.data.annotation.Id;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("iot_common_product")
|
||||
public class IoTCommonProduct extends BaseDO {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
|
||||
private String code;
|
||||
|
||||
private String name;
|
||||
|
||||
private Long categoryId;
|
||||
|
||||
private String categoryName;
|
||||
|
||||
private String protocolCode;
|
||||
|
||||
private String transport;
|
||||
|
||||
private Integer vertificateMethod;
|
||||
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private List<IoTCommonThingsModel> thingsModels;
|
||||
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private List<IoTCommonDeviceAction> deviceActions;
|
||||
|
||||
private List<String> events;
|
||||
|
||||
private Integer status;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.maibu.core.business;
|
||||
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class IoTCommonThingsModel {
|
||||
|
||||
private String name;
|
||||
|
||||
private String code;
|
||||
|
||||
private Boolean required;
|
||||
|
||||
private Object min;
|
||||
|
||||
private Object max;
|
||||
|
||||
private String unit;
|
||||
|
||||
private String description;
|
||||
|
||||
private Object defaultValue;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.maibu.core.business.device;
|
||||
|
||||
import com.maibu.core.enums.ConnectorStatus;
|
||||
import io.netty.channel.Channel;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
@Data
|
||||
public class Connector {
|
||||
// 获取设备ID
|
||||
private final String connectorId;
|
||||
// 设备ID
|
||||
private ConnectorStatus connectorStatus; // 设备状态(可用、禁言、不可用)
|
||||
// 获取连接的设备列表
|
||||
private Set<Connector> connectedConnectors; // 连接的设备列表 主机绑定从机 从机无绑定
|
||||
|
||||
private Channel channel;
|
||||
|
||||
// 无参构造函数,解决Lombok需要默认构造函数的问题
|
||||
public Connector() {
|
||||
this.connectorId = "";
|
||||
this.connectorStatus = ConnectorStatus.ACTIVE;
|
||||
this.connectedConnectors = new HashSet<>();
|
||||
}
|
||||
|
||||
// 构造器
|
||||
public Connector(String connectorId) {
|
||||
this.connectorId = connectorId;
|
||||
this.connectorStatus = ConnectorStatus.ACTIVE; // 默认状态为完全可用
|
||||
this.connectedConnectors = new HashSet<>();
|
||||
}
|
||||
|
||||
//
|
||||
public void addConnectedDevice(Connector connector) {
|
||||
connectedConnectors.add(connector);
|
||||
}
|
||||
|
||||
// 移除连接的设备,确保双向移除
|
||||
public void removeConnectedDevice(Connector connector) {
|
||||
// 从当前设备的连接列表中移除
|
||||
connectedConnectors.remove(connector);
|
||||
|
||||
}
|
||||
|
||||
public boolean isOnline() {
|
||||
return channel != null && channel.isActive();
|
||||
}
|
||||
|
||||
public boolean canSend() {
|
||||
return connectorStatus == ConnectorStatus.ACTIVE;
|
||||
}
|
||||
|
||||
public boolean canReceive() {
|
||||
return connectorStatus != ConnectorStatus.DISABLED;
|
||||
}
|
||||
|
||||
// 打印设备信息
|
||||
public void printConnectorInfo() {
|
||||
System.out.println("Device ID: " + connectorId);
|
||||
System.out.println("Device Status: " + connectorStatus);
|
||||
System.out.println("Connected Devices: ");
|
||||
for (Connector connectedDevice : connectedConnectors) {
|
||||
System.out.println("- " + connectedDevice.getConnectorId());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.maibu.core.business.device;
|
||||
|
||||
|
||||
import com.maibu.core.business.DeviceRunStatistics;
|
||||
import com.maibu.core.enums.ConnectorType;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import com.maibu.core.business.path.LatAndLngEntity;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class NettyDevice extends Connector {
|
||||
|
||||
private ConnectorType deviceType; // 设备角色类型:MASTER、SLAVE、GENERAL
|
||||
|
||||
private String currentSlaveId;// 当前对应的下位机 master
|
||||
|
||||
private Long currentTaskId; //当前执行的任务;
|
||||
|
||||
private Integer onlineStatus; //在线状态 0 离线 1在线
|
||||
|
||||
private Queue<LatAndLngEntity> locationQueue = new LinkedList<>();
|
||||
|
||||
private DeviceRunStatistics latestStatus;
|
||||
|
||||
private Long latestLoginTime;
|
||||
|
||||
public NettyDevice(String connectorId) {
|
||||
super(connectorId);
|
||||
this.deviceType = ConnectorType.MASTER; // 默认上位机角色
|
||||
}
|
||||
|
||||
public NettyDevice(String connectorId, ConnectorType deviceType) {
|
||||
super(connectorId);
|
||||
this.deviceType = deviceType;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.maibu.core.business.path;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class LatAndLngEntity {
|
||||
private double lat;
|
||||
private double lng;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{" + lat + "," + lng + '}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,554 @@
|
||||
package com.maibu.core.business.path;
|
||||
|
||||
|
||||
|
||||
import com.maibu.utils.json.JsonUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
public class MowingPathGenerator {
|
||||
public static final double M_PI = 3.14159265358979323846;
|
||||
public static final double Earth_Radius = 6378137.0;
|
||||
public static final double EPSILON = 1e-6;
|
||||
public static final double REL_EPSILON = 1e-8;
|
||||
public static final double ABS_EPSILON = 1e-12;
|
||||
|
||||
public static class Point {
|
||||
public double x, y;
|
||||
|
||||
public Point(double x, double y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
}
|
||||
|
||||
public static class PathPoint {
|
||||
public double lat, lon;
|
||||
|
||||
public PathPoint(double lat, double lon) {
|
||||
this.lat = lat;
|
||||
this.lon = lon;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Polygon {
|
||||
public Point[] vertices;
|
||||
public int num_vertices;
|
||||
|
||||
public Polygon(Point[] vertices, int num_vertices) {
|
||||
this.vertices = vertices;
|
||||
this.num_vertices = num_vertices;
|
||||
}
|
||||
}
|
||||
|
||||
public static class PolygonWithHoles {
|
||||
public Polygon outer;
|
||||
public Polygon[] holes;
|
||||
public int num_holes;
|
||||
|
||||
public PolygonWithHoles(Polygon outer, Polygon[] holes, int num_holes) {
|
||||
this.outer = outer;
|
||||
this.holes = holes;
|
||||
this.num_holes = num_holes;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ProjectedPoint {
|
||||
public Point pt;
|
||||
public double proj;
|
||||
|
||||
public ProjectedPoint(Point pt, double proj) {
|
||||
this.pt = pt;
|
||||
this.proj = proj;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isEqual(double a, double b) {
|
||||
double diff = Math.abs(a - b);
|
||||
double max_ab = Math.max(Math.abs(a), Math.abs(b));
|
||||
double tolerance = REL_EPSILON * max_ab + ABS_EPSILON;
|
||||
return diff <= tolerance;
|
||||
}
|
||||
|
||||
public static double cross(Point a, Point b) {
|
||||
return a.x * b.y - a.y * b.x;
|
||||
}
|
||||
|
||||
public static boolean getLineIntersection(Point p1, Point p2, Point q1, Point q2, Point intersection) {
|
||||
Point r = new Point(p2.x - p1.x, p2.y - p1.y);
|
||||
Point s = new Point(q2.x - q1.x, q2.y - q1.y);
|
||||
double rxs = cross(r, s);
|
||||
Point qp = new Point(q1.x - p1.x, q1.y - p1.y);
|
||||
double q_p_cross_r = cross(qp, r);
|
||||
|
||||
if (Math.abs(rxs) < EPSILON) {
|
||||
return false;
|
||||
}
|
||||
|
||||
double t = cross(qp, s) / rxs;
|
||||
double u = q_p_cross_r / rxs;
|
||||
|
||||
if (t >= 0.0 - EPSILON && t <= 1.0 + EPSILON && u >= 0.0 - EPSILON && u <= 1.0 + EPSILON) {
|
||||
intersection.x = p1.x + t * r.x;
|
||||
intersection.y = p1.y + t * r.y;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isPointOnSegment(Point pt, Point p1, Point p2) {
|
||||
if (pt.x < Math.min(p1.x, p2.x) - EPSILON || pt.x > Math.max(p1.x, p2.x) + EPSILON) {
|
||||
return false;
|
||||
}
|
||||
if (pt.y < Math.min(p1.y, p2.y) - EPSILON || pt.y > Math.max(p1.y, p2.y) + EPSILON) {
|
||||
return false;
|
||||
}
|
||||
|
||||
double cross = (p2.x - p1.x) * (pt.y - p1.y) - (p2.y - p1.y) * (pt.x - p1.x);
|
||||
if (Math.abs(cross) > EPSILON) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void makeScanline(PolygonWithHoles field, Point lineStart, Point lineEnd, Point normal, double min_proj, Point dir) {
|
||||
double min_x = Double.POSITIVE_INFINITY, max_x = Double.NEGATIVE_INFINITY;
|
||||
double min_y = Double.POSITIVE_INFINITY, max_y = Double.NEGATIVE_INFINITY;
|
||||
|
||||
for (int i = 0; i < field.outer.num_vertices; i++) {
|
||||
Point p = field.outer.vertices[i];
|
||||
if (p.x < min_x) min_x = p.x;
|
||||
if (p.x > max_x) max_x = p.x;
|
||||
if (p.y < min_y) min_y = p.y;
|
||||
if (p.y > max_y) max_y = p.y;
|
||||
}
|
||||
|
||||
double dx = max_x - min_x, dy = max_y - min_y;
|
||||
double len_scan = Math.sqrt(dx * dx + dy * dy) * 1.1;
|
||||
|
||||
Point lineOrigin = new Point(normal.x * min_proj, normal.y * min_proj);
|
||||
|
||||
lineStart.x = lineOrigin.x - dir.x * len_scan;
|
||||
lineStart.y = lineOrigin.y - dir.y * len_scan;
|
||||
|
||||
lineEnd.x = lineOrigin.x + dir.x * len_scan;
|
||||
lineEnd.y = lineOrigin.y + dir.y * len_scan;
|
||||
}
|
||||
|
||||
public static void collectHoleIntersections(PolygonWithHoles poly, Point q1, Point q2, List<ProjectedPoint> intersections, Point dir) {
|
||||
intersections.clear();
|
||||
|
||||
for (int h = 0; h < poly.num_holes; h++) {
|
||||
for (int i = 0; i < poly.holes[h].num_vertices; i++) {
|
||||
Point p1 = poly.holes[h].vertices[i];
|
||||
Point p2 = poly.holes[h].vertices[(i + 1) % poly.holes[h].num_vertices];
|
||||
Point inter = new Point(0, 0);
|
||||
|
||||
if (getLineIntersection(p1, p2, q1, q2, inter)) {
|
||||
double proj = inter.x * dir.x + inter.y * dir.y;
|
||||
intersections.add(new ProjectedPoint(new Point(inter.x, inter.y), proj));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void collectOuterIntersections(PolygonWithHoles poly, Point q1, Point q2, List<ProjectedPoint> intersections, Point dir) {
|
||||
intersections.clear();
|
||||
|
||||
for (int i = 0; i < poly.outer.num_vertices; i++) {
|
||||
Point p1 = poly.outer.vertices[i];
|
||||
Point p2 = poly.outer.vertices[(i + 1) % poly.outer.num_vertices];
|
||||
Point inter = new Point(0, 0);
|
||||
|
||||
if (getLineIntersection(p1, p2, q1, q2, inter)) {
|
||||
double proj = inter.x * dir.x + inter.y * dir.y;
|
||||
intersections.add(new ProjectedPoint(new Point(inter.x, inter.y), proj));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void generateMowingPath(PolygonWithHoles field, double width, Point scanStart, Point scanEnd, List<Point> pathPoints) {
|
||||
pathPoints.clear();
|
||||
|
||||
Point dir = new Point(scanEnd.x - scanStart.x, scanEnd.y - scanStart.y);
|
||||
double len = Math.sqrt(dir.x * dir.x + dir.y * dir.y);
|
||||
dir.x /= len;
|
||||
dir.y /= len;
|
||||
Point normal = new Point(-dir.y, dir.x);
|
||||
|
||||
double min_proj = Double.POSITIVE_INFINITY, max_proj = Double.NEGATIVE_INFINITY;
|
||||
for (int i = 0; i < field.outer.num_vertices; i++) {
|
||||
Point p = field.outer.vertices[i];
|
||||
double proj = p.x * normal.x + p.y * normal.y;
|
||||
if (proj < min_proj) min_proj = proj;
|
||||
if (proj > max_proj) max_proj = proj;
|
||||
}
|
||||
|
||||
int lines = (int) ((max_proj - min_proj) / width + 1);
|
||||
int max_outer_points = lines * field.outer.num_vertices * 2;
|
||||
int max_hole_points = lines * field.num_holes * 10 * 2;
|
||||
|
||||
System.out.printf("dir = (%.4f, %.4f)\n", dir.x, dir.y);
|
||||
System.out.printf("normal = (%.4f, %.4f)\n", normal.x, normal.y);
|
||||
System.out.printf("Projection range: %.4f ~ %.4f (%.4f)\n", min_proj, max_proj, max_proj - min_proj);
|
||||
System.out.printf("lines = %d\n", lines);
|
||||
|
||||
Point lineStart = new Point(0, 0);
|
||||
Point lineEnd = new Point(0, 0);
|
||||
makeScanline(field, lineStart, lineEnd, normal, min_proj, dir);
|
||||
int direction = 1;
|
||||
|
||||
List<List<ProjectedPoint>> outerIntersections = new ArrayList<>();
|
||||
List<List<ProjectedPoint>> holeIntersections = new ArrayList<>();
|
||||
List<Integer> numHole = new ArrayList<>();
|
||||
List<Integer> numOuter = new ArrayList<>();
|
||||
|
||||
for (int l = 0; l < lines; l++) {
|
||||
List<ProjectedPoint> outerInts = new ArrayList<>();
|
||||
collectOuterIntersections(field, lineStart, lineEnd, outerInts, dir);
|
||||
|
||||
List<ProjectedPoint> holeInts = new ArrayList<>();
|
||||
collectHoleIntersections(field, lineStart, lineEnd, holeInts, dir);
|
||||
|
||||
holeInts.sort(Comparator.comparingDouble(p -> p.proj));
|
||||
|
||||
if (direction == -1) {
|
||||
Collections.reverse(holeInts);
|
||||
}
|
||||
|
||||
outerIntersections.add(outerInts);
|
||||
holeIntersections.add(holeInts);
|
||||
numHole.add(holeInts.size());
|
||||
numOuter.add(outerInts.size());
|
||||
|
||||
lineStart.x += normal.x * width;
|
||||
lineStart.y += normal.y * width;
|
||||
lineEnd.x += normal.x * width;
|
||||
lineEnd.y += normal.y * width;
|
||||
direction *= -1;
|
||||
}
|
||||
|
||||
direction = 1;
|
||||
|
||||
for (int l = 0; l < lines; l++) {
|
||||
List<ProjectedPoint> intersections = new ArrayList<>();
|
||||
intersections.addAll(outerIntersections.get(l));
|
||||
intersections.addAll(holeIntersections.get(l));
|
||||
|
||||
intersections.sort(Comparator.comparingDouble(p -> p.proj));
|
||||
|
||||
if (direction == -1) {
|
||||
Collections.reverse(intersections);
|
||||
}
|
||||
|
||||
boolean isHoleStart = false;
|
||||
int layerHoleNum = numHole.get(l);
|
||||
|
||||
if (layerHoleNum > 0) {
|
||||
ProjectedPoint holeStart = holeIntersections.get(l).get(0);
|
||||
ProjectedPoint holeEnd = holeIntersections.get(l).get(layerHoleNum - 1);
|
||||
|
||||
for (int i = 0; i < intersections.size(); i++) {
|
||||
ProjectedPoint testPoint = intersections.get(i);
|
||||
|
||||
if (isEqual(testPoint.proj, holeStart.proj)) {
|
||||
isHoleStart = true;
|
||||
}
|
||||
|
||||
if (isHoleStart) {
|
||||
pathPoints.add(holeStart.pt);
|
||||
|
||||
int holeId = -1;
|
||||
int startIndex = -1, endIndex = -1;
|
||||
boolean isHoleVertices = false;
|
||||
|
||||
for (int h = 0; h < field.num_holes; h++) {
|
||||
Polygon hole = field.holes[h];
|
||||
|
||||
for (int j = 0; j < hole.num_vertices; j++) {
|
||||
Point p1 = hole.vertices[j];
|
||||
Point p2 = hole.vertices[(j + 1) % hole.num_vertices];
|
||||
|
||||
if (isEqual(holeStart.pt.x, p1.x) && isEqual(holeStart.pt.y, p1.y)) {
|
||||
isHoleVertices = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (isPointOnSegment(holeStart.pt, p1, p2)) {
|
||||
holeId = h;
|
||||
startIndex = (j + 1) % hole.num_vertices;
|
||||
}
|
||||
|
||||
if (isPointOnSegment(holeEnd.pt, p1, p2)) {
|
||||
endIndex = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isHoleVertices) {
|
||||
if (holeId >= 0 && startIndex >= 0 && endIndex >= 0) {
|
||||
Polygon hole = field.holes[holeId];
|
||||
int index = startIndex;
|
||||
int indexHoleIntersections = 1;
|
||||
boolean forward = true;
|
||||
|
||||
for (int step = 0; step < hole.num_vertices; step++) {
|
||||
if (indexHoleIntersections < layerHoleNum - 1) {
|
||||
Point current = hole.vertices[index];
|
||||
Point next = hole.vertices[(index + 1) % hole.num_vertices];
|
||||
Point intersectionPt = holeIntersections.get(l).get(indexHoleIntersections).pt;
|
||||
|
||||
if (forward && !isPointOnSegment(intersectionPt, current, next)) {
|
||||
forward = false;
|
||||
index = (index - 1 + hole.num_vertices) % hole.num_vertices;
|
||||
endIndex = (endIndex + 1) % hole.num_vertices;
|
||||
System.out.println("is_point_on_segment");
|
||||
}
|
||||
|
||||
if (indexHoleIntersections % 2 != 0) {
|
||||
pathPoints.add(hole.vertices[index]);
|
||||
}
|
||||
|
||||
pathPoints.add(holeIntersections.get(l).get(indexHoleIntersections).pt);
|
||||
indexHoleIntersections++;
|
||||
i++;
|
||||
} else {
|
||||
pathPoints.add(hole.vertices[index]);
|
||||
}
|
||||
|
||||
if (index == endIndex) break;
|
||||
|
||||
if (forward) {
|
||||
index = (index + 1) % hole.num_vertices;
|
||||
} else {
|
||||
index = (index - 1 + hole.num_vertices) % hole.num_vertices;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pathPoints.add(holeEnd.pt);
|
||||
i++;
|
||||
isHoleStart = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
pathPoints.add(intersections.get(i).pt);
|
||||
}
|
||||
} else {
|
||||
for (ProjectedPoint pp : intersections) {
|
||||
pathPoints.add(pp.pt);
|
||||
}
|
||||
}
|
||||
|
||||
direction *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
public static void latlonToXY(double lat0, double lon0, double lat, double lon, Point result) {
|
||||
double d_lat = Math.toRadians(lat - lat0);
|
||||
double d_lon = Math.toRadians(lon - lon0);
|
||||
double lat0_rad = Math.toRadians(lat0);
|
||||
|
||||
result.x = Earth_Radius * d_lon * Math.cos(lat0_rad);
|
||||
result.y = Earth_Radius * d_lat;
|
||||
}
|
||||
|
||||
public static void xyToLatlon(double lat0, double lon0, double x, double y, PathPoint result) {
|
||||
double lat0_rad = Math.toRadians(lat0);
|
||||
|
||||
result.lat = lat0 + (y / Earth_Radius) * (180.0 / M_PI);
|
||||
result.lon = lon0 + (x / (Earth_Radius * Math.cos(lat0_rad))) * (180.0 / M_PI);
|
||||
}
|
||||
|
||||
public static void getCoord(PathPoint[] gps, Point[] points, PathPoint start, int cnt) {
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
latlonToXY(start.lat, start.lon, gps[i].lat, gps[i].lon, points[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void getLatlon(PathPoint[] gps, Point[] points, PathPoint start, int cnt) {
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
xyToLatlon(start.lat, start.lon, points[i].x, points[i].y, gps[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void parseJson(String json) {
|
||||
RPPathData data = JsonUtils.parseObject(json,RPPathData.class);
|
||||
|
||||
PathPoint refPoint = data.refPoint;
|
||||
PathPoint[] outer = data.Polygon.outer.toArray(new PathPoint[0]);
|
||||
PathPoint start = data.scanLine.start;
|
||||
PathPoint end = data.scanLine.end;
|
||||
PathPoint[] holes = data.Polygon.holes.toArray(new PathPoint[0]);
|
||||
// 打印验证
|
||||
System.out.println("Ref Point: " + refPoint);
|
||||
System.out.println("Start: " + start);
|
||||
System.out.println("End: " + end);
|
||||
System.out.println("Outer:");
|
||||
for (PathPoint p : outer) {
|
||||
System.out.println(" " + p);
|
||||
}
|
||||
System.out.println("Holes:");
|
||||
for (PathPoint p : holes) {
|
||||
System.out.println(" " + p);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static List<LatAndLngEntity> generateMowingPath(String json) {
|
||||
RPPathData data = JsonUtils.parseObject(json,RPPathData.class);
|
||||
|
||||
PathPoint refPoint = data.refPoint;
|
||||
PathPoint[] outer = data.Polygon.outer.toArray(new PathPoint[0]);
|
||||
PathPoint start = data.scanLine.start;
|
||||
PathPoint end = data.scanLine.end;
|
||||
List<PathPoint> allHolePoints = new ArrayList<>();
|
||||
for (List<PathPoint> hole : data.Polygon.holes) {
|
||||
allHolePoints.addAll(hole);
|
||||
}
|
||||
PathPoint[] holes = allHolePoints.toArray(new PathPoint[0]);
|
||||
|
||||
|
||||
Point[] outerPoint = new Point[outer.length];
|
||||
Point startPoint = new Point(0, 0);
|
||||
Point endPoint = new Point(0, 0);
|
||||
Point[] holesPoint = new Point[holes.length];
|
||||
|
||||
latlonToXY(refPoint.lat, refPoint.lon, start.lat, start.lon, startPoint);
|
||||
latlonToXY(refPoint.lat, refPoint.lon, end.lat, end.lon, endPoint);
|
||||
|
||||
for (int i = 0; i < outer.length; i++) {
|
||||
outerPoint[i] = new Point(0, 0);
|
||||
latlonToXY(refPoint.lat, refPoint.lon, outer[i].lat, outer[i].lon, outerPoint[i]);
|
||||
System.out.printf("(%.14f, %.14f)\n", outerPoint[i].x, outerPoint[i].y);
|
||||
// Log.d("MowingPathGenerator", "Outer Point: " + "(" + outerPoint[i].x + ", " + outerPoint[i].y + " )");
|
||||
}
|
||||
|
||||
if (holes.length > 0) {
|
||||
for (int i = 0; i < holes.length; i++) {
|
||||
holesPoint[i] = new Point(0, 0);
|
||||
latlonToXY(refPoint.lat, refPoint.lon, holes[i].lat, holes[i].lon, holesPoint[i]);
|
||||
// Log.d("MowingPathGenerator", "holes Point: " + "(" + holesPoint[i].x + ", " + holesPoint[i].y + " )");
|
||||
System.out.printf("(%.14f, %.14f)\n", holesPoint[i].x, holesPoint[i].y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Polygon outerPolygon = new Polygon(outerPoint, outer.length);
|
||||
|
||||
// Polygon holesPolygon[] = {new Polygon(holesPoint, holesPoint.length)};
|
||||
// PolygonWithHoles field = new PolygonWithHoles(outerPolygon, holesPolygon,holesPoint.length);
|
||||
|
||||
Polygon[] holesPolygons = new Polygon[data.Polygon.holes.size()];
|
||||
for (int i = 0; i < data.Polygon.holes.size(); i++) {
|
||||
List<PathPoint> hole = data.Polygon.holes.get(i);
|
||||
Point[] holePoints = new Point[hole.size()];
|
||||
for (int j = 0; j < hole.size(); j++) {
|
||||
holePoints[j] = new Point(0, 0);
|
||||
latlonToXY(refPoint.lat, refPoint.lon, hole.get(j).lat, hole.get(j).lon, holePoints[j]);
|
||||
}
|
||||
holesPolygons[i] = new Polygon(holePoints, holePoints.length);
|
||||
}
|
||||
PolygonWithHoles field = new PolygonWithHoles(outerPolygon, holesPolygons, holesPolygons.length);
|
||||
|
||||
|
||||
// PolygonWithHoles field = new PolygonWithHoles(outerPolygon, null,0);
|
||||
|
||||
double width = 0.8;
|
||||
List<Point> path = new ArrayList<>();
|
||||
|
||||
generateMowingPath(field, width, startPoint, endPoint, path);
|
||||
|
||||
PathPoint[] gpsout = new PathPoint[path.size()];
|
||||
|
||||
for (int i = 0; i < gpsout.length; i++) {
|
||||
gpsout[i] = new PathPoint(0, 0);
|
||||
}
|
||||
|
||||
for (int i = 0; i < path.size(); i++) {
|
||||
if (i >= gpsout.length) break;
|
||||
xyToLatlon(start.lat, start.lon, path.get(i).x, path.get(i).y, gpsout[i]);
|
||||
}
|
||||
List<LatAndLngEntity> Points = new ArrayList<>();
|
||||
|
||||
System.out.printf("Generated %d path points:\n", path.size());
|
||||
for (int i = 0; i < path.size(); i++) {
|
||||
if (i >= gpsout.length) break;
|
||||
System.out.printf("[%.14f, %.14f]\n", gpsout[i].lon, gpsout[i].lat);
|
||||
// Log.d("MowingPathGenerator", "gpsout Point: " + "(" + gpsout[i].lon + ", " + gpsout[i].lat + " )");
|
||||
LatAndLngEntity latAndLngEntity = new LatAndLngEntity();
|
||||
latAndLngEntity.setLat(gpsout[i].lat);
|
||||
latAndLngEntity.setLng(gpsout[i].lon);
|
||||
Points.add(latAndLngEntity);
|
||||
}
|
||||
|
||||
return Points;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// public static void main(String[] args) {
|
||||
//
|
||||
// PathPoint start = new PathPoint(32.08599985199932, 120.77586450935124);
|
||||
// PathPoint[] gpsout = new PathPoint[1024];
|
||||
// PathPoint[] gpsin = {
|
||||
// new PathPoint(32.08599985199932, 120.77586450935124),
|
||||
// new PathPoint(32.08624992154597, 120.77670803771835),
|
||||
// new PathPoint(32.08568874374706, 120.77710241458807),
|
||||
// new PathPoint(32.0854398968189, 120.77615838649545)
|
||||
// };
|
||||
//
|
||||
// PathPoint scanStart = new PathPoint(32.08599985199932, 120.77586450935124);
|
||||
// PathPoint scanEnd = new PathPoint(32.08624992154597, 120.77670803771835);
|
||||
// Point startPoint = new Point(0,0);
|
||||
// Point endPoint = new Point(0,0);
|
||||
//
|
||||
// latlonToXY(start.lat, start.lon, scanStart.lat, scanStart.lon, startPoint);
|
||||
// latlonToXY(start.lat, start.lon, scanEnd.lat, scanEnd.lon, endPoint);
|
||||
//
|
||||
// Point[] outerVertices = new Point[4];
|
||||
// for (int i = 0; i < 4; i++) {
|
||||
// outerVertices[i] = new Point(0, 0);
|
||||
// latlonToXY(start.lat, start.lon, gpsin[i].lat, gpsin[i].lon, outerVertices[i]);
|
||||
// System.out.printf("(%.14f, %.14f)\n", outerVertices[i].x, outerVertices[i].y);
|
||||
// }
|
||||
//
|
||||
// Polygon outer = new Polygon(outerVertices, 4);
|
||||
// Point[] hole1Vertices = {
|
||||
// new Point(40, -10), new Point(80, -10), new Point(80, -40),
|
||||
// new Point(60, -28), new Point(40, -40)
|
||||
// };
|
||||
// Polygon[] holes = {
|
||||
// new Polygon(hole1Vertices, 5)
|
||||
// };
|
||||
// PolygonWithHoles field = new PolygonWithHoles(outer, holes, 1);
|
||||
//
|
||||
// double width = 0.8;
|
||||
// List<Point> path = new ArrayList<>();
|
||||
//
|
||||
// generateMowingPath(field, width, startPoint, endPoint, path);
|
||||
//
|
||||
// for (int i = 0; i < gpsout.length; i++) {
|
||||
// gpsout[i] = new PathPoint(0, 0);
|
||||
// }
|
||||
//
|
||||
// for (int i = 0; i < path.size(); i++) {
|
||||
// if (i >= gpsout.length) break;
|
||||
// xyToLatlon(start.lat, start.lon, path.get(i).x, path.get(i).y, gpsout[i]);
|
||||
// }
|
||||
//
|
||||
// System.out.printf("Generated %d path points:\n", path.size());
|
||||
// for (int i = 0; i < path.size(); i++) {
|
||||
// if (i >= gpsout.length) break;
|
||||
// System.out.printf("{%.14f, %.14f}\n", gpsout[i].lon, gpsout[i].lat);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.maibu.core.business.path;
|
||||
|
||||
import java.util.List;
|
||||
import com.maibu.core.business.path.MowingPathGenerator.*;
|
||||
|
||||
public class RPPathData {
|
||||
public ScanLine scanLine;
|
||||
public PathPoint refPoint;
|
||||
public PolygonData Polygon;
|
||||
|
||||
public static class ScanLine {
|
||||
public PathPoint start;
|
||||
public PathPoint end;
|
||||
}
|
||||
|
||||
public static class PolygonData {
|
||||
public List<PathPoint> outer;
|
||||
public List<List<PathPoint>> holes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.maibu.core.business.path;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class RoutePlanRecEntity {
|
||||
private byte header1;
|
||||
private byte header2;
|
||||
private byte commandType;
|
||||
private short pointNum;
|
||||
private byte status;
|
||||
private short crc16;
|
||||
private byte endFlag1;
|
||||
private byte endFlag2;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RoutePlanRecEntity{" +
|
||||
"header1=" + header1 +
|
||||
", header2=" + header2 +
|
||||
", commandType=" + commandType +
|
||||
", pointNum=" + pointNum +
|
||||
", status=" + status +
|
||||
", crc16=" + crc16 +
|
||||
", endFlag1=" + endFlag1 +
|
||||
", endFlag2=" + endFlag2 +
|
||||
'}';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.maibu.core.business.path;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
@Data
|
||||
public class RoutePlanSendEntity {
|
||||
|
||||
public RoutePlanSendEntity() {
|
||||
header1 = (byte) 0xAB;
|
||||
header2 = (byte) 0xAA;
|
||||
commandType = 0x01;
|
||||
pointCounts = 1;
|
||||
targetLatitude = 0;
|
||||
targetLongitude = 0;
|
||||
speed = 0x3E8;
|
||||
crc16 = 0;
|
||||
endFlag1 = (byte) 0xAA;
|
||||
endFlag2 = (byte) 0xAB;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RoutePlanSendEntity{" +
|
||||
"header1=" + header1 +
|
||||
", header2=" + header2 +
|
||||
", commandType=" + commandType +
|
||||
", pointCounts=" + pointCounts +
|
||||
", targetLatitude=" + targetLatitude +
|
||||
", targetLongitude=" + targetLongitude +
|
||||
", speed=" + speed +
|
||||
", crc16=" + crc16 +
|
||||
", endFlag1=" + endFlag1 +
|
||||
", endFlag2=" + endFlag2 +
|
||||
'}';
|
||||
}
|
||||
|
||||
public byte[] toBytes() {
|
||||
ByteBuffer buffer = ByteBuffer.allocate(27); // 修改为27字节
|
||||
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
buffer.put((byte) 0xAB);
|
||||
buffer.put((byte) 0xAA);
|
||||
|
||||
buffer.put((byte) 0x01);
|
||||
|
||||
buffer.putShort(pointCounts);
|
||||
|
||||
|
||||
long latitudeBits = Double.doubleToLongBits(targetLatitude);
|
||||
buffer.putLong(latitudeBits);
|
||||
|
||||
long longitudeBits = Double.doubleToLongBits(targetLongitude);
|
||||
buffer.putLong(longitudeBits);
|
||||
|
||||
buffer.putShort(speed);
|
||||
buffer.putShort(crc16);
|
||||
|
||||
buffer.put((byte) 0xAA);
|
||||
buffer.put((byte) 0xAB);
|
||||
|
||||
return buffer.array();
|
||||
}
|
||||
|
||||
private byte header1;
|
||||
private byte header2;
|
||||
private byte commandType;
|
||||
private short pointCounts;
|
||||
private double targetLatitude; // 改为 double
|
||||
private double targetLongitude; // 改为 double
|
||||
private short speed;
|
||||
private short crc16;
|
||||
private byte endFlag1;
|
||||
private byte endFlag2;
|
||||
|
||||
}
|
||||
@@ -1,12 +1,16 @@
|
||||
package com.maibu.core.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 基类,时间类型改为LocalDateTime
|
||||
@@ -40,4 +44,15 @@ public class BaseDO implements Serializable {
|
||||
@TableLogic
|
||||
private Boolean delFlag;
|
||||
|
||||
/** 请求参数 */
|
||||
@TableField(exist = false)
|
||||
@ApiModelProperty("请求参数")
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
private Map<String, Object> params = new HashMap<>();
|
||||
|
||||
/** 备注 */
|
||||
@ApiModelProperty("备注")
|
||||
@TableField(exist = false)
|
||||
private String remark;
|
||||
|
||||
}
|
||||
|
||||
@@ -4,17 +4,11 @@ import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.maibu.core.domain.BaseDO;
|
||||
import com.maibu.core.domain.BaseEntity;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -25,7 +19,7 @@ import java.util.List;
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ApiModel(value = "SysMenu", description = "菜单权限表 sys_menu")
|
||||
@TableName(value = "sys_site")
|
||||
@TableName(value = "sys_menu")
|
||||
@Data
|
||||
public class SysMenu extends BaseDO {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.maibu.core.domain.entity;
|
||||
|
||||
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 com.maibu.core.domain.BaseDO;
|
||||
@@ -48,4 +49,7 @@ public class SysOrg extends BaseDO {
|
||||
*/
|
||||
private String manager;
|
||||
|
||||
@TableField(exist = false)
|
||||
private Long userId;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.maibu.core.domain.entity;
|
||||
|
||||
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 com.maibu.annotation.Excel;
|
||||
@@ -9,7 +10,9 @@ import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springframework.data.annotation.Transient;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -63,15 +66,13 @@ public class SysRole extends BaseDO {
|
||||
@Excel(name = "角色状态", readConverterExp = "0=正常,1=停用")
|
||||
private String status;
|
||||
|
||||
/** 删除标志(0代表存在 2代表删除) */
|
||||
@ApiModelProperty("删除标志")
|
||||
private String delFlag;
|
||||
|
||||
/** 用户是否存在此角色标识 默认不存在 */
|
||||
private boolean flag = false;
|
||||
|
||||
/** 菜单组 */
|
||||
@ApiModelProperty("菜单组")
|
||||
@TableField(exist = false)
|
||||
private String menuList;
|
||||
|
||||
@TableField(exist = false)
|
||||
private Long[] menuIds;
|
||||
|
||||
/** 部门组(数据权限) */
|
||||
@@ -107,6 +108,11 @@ public class SysRole extends BaseDO {
|
||||
*/
|
||||
private Boolean manager;
|
||||
|
||||
/**
|
||||
* 是否有场站设置的权限
|
||||
*/
|
||||
private Boolean siteAccess = false;
|
||||
|
||||
|
||||
public SysRole() {
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@ package com.maibu.core.domain.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.maibu.annotation.Excel;
|
||||
import com.maibu.annotation.Excels;
|
||||
import com.maibu.core.domain.BaseEntity;
|
||||
import com.maibu.core.domain.BaseDO;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
@@ -21,9 +21,10 @@ import java.util.List;
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ApiModel(value = "SysUser", description = "用户对象 sys_user")
|
||||
@TableName(value = "sys_user")
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class SysUser extends BaseEntity {
|
||||
public class SysUser extends BaseDO {
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* 用户ID
|
||||
@@ -40,6 +41,11 @@ public class SysUser extends BaseEntity {
|
||||
@Excel(name = "部门编号", type = Excel.Type.IMPORT)
|
||||
private Long deptId;
|
||||
|
||||
|
||||
private Long orgId;
|
||||
|
||||
private Long siteId;
|
||||
|
||||
/**
|
||||
* 用户账号
|
||||
*/
|
||||
@@ -97,12 +103,6 @@ public class SysUser extends BaseEntity {
|
||||
@Excel(name = "帐号状态", readConverterExp = "0=正常,1=停用")
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 删除标志(0代表存在 2代表删除)
|
||||
*/
|
||||
@ApiModelProperty("删除标志")
|
||||
private String delFlag;
|
||||
|
||||
/**
|
||||
* 最后登录IP
|
||||
*/
|
||||
@@ -117,66 +117,11 @@ public class SysUser extends BaseEntity {
|
||||
@Excel(name = "最后登录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Excel.Type.EXPORT)
|
||||
private Date loginDate;
|
||||
|
||||
/**
|
||||
* 部门对象
|
||||
*/
|
||||
@ApiModelProperty("部门对象")
|
||||
@Excels({
|
||||
@Excel(name = "部门名称", targetAttr = "deptName", type = Excel.Type.EXPORT),
|
||||
@Excel(name = "部门负责人", targetAttr = "leader", type = Excel.Type.EXPORT)
|
||||
})
|
||||
private SysDept dept;
|
||||
|
||||
/**
|
||||
* 角色对象
|
||||
*/
|
||||
@ApiModelProperty("角色对象")
|
||||
private List<SysRole> roles;
|
||||
|
||||
/**
|
||||
* 角色组
|
||||
*/
|
||||
@ApiModelProperty("角色组")
|
||||
private Long[] roleIds;
|
||||
|
||||
/**
|
||||
* 岗位组
|
||||
*/
|
||||
@ApiModelProperty("岗位组")
|
||||
private Long[] postIds;
|
||||
|
||||
/**
|
||||
* 角色ID
|
||||
*/
|
||||
@ApiModelProperty("角色ID")
|
||||
private Long roleId;
|
||||
|
||||
/**
|
||||
* 用,拼接的角色名称
|
||||
*/
|
||||
@ApiModelProperty("用,拼接的角色名称")
|
||||
private String roleNames;
|
||||
|
||||
/**
|
||||
* 用,拼接的角色名称
|
||||
*/
|
||||
@ApiModelProperty("sessionId")
|
||||
private String sessionId;
|
||||
|
||||
/**
|
||||
* 微信openid
|
||||
*/
|
||||
private String openId;
|
||||
|
||||
/**
|
||||
* 是否显示下级机构数据
|
||||
*/
|
||||
private Boolean showChild;
|
||||
|
||||
/**
|
||||
* 是否是机构管理员
|
||||
*/
|
||||
private Boolean manager;
|
||||
/**
|
||||
* 语言
|
||||
*/
|
||||
@@ -186,6 +131,40 @@ public class SysUser extends BaseEntity {
|
||||
*/
|
||||
private String timeZone;
|
||||
|
||||
/**
|
||||
* 角色对象
|
||||
*/
|
||||
@ApiModelProperty("角色对象")
|
||||
private List<SysRole> roles;
|
||||
|
||||
/**
|
||||
* 用,拼接的角色名称
|
||||
*/
|
||||
@ApiModelProperty("用,拼接的角色名称")
|
||||
private String roleNames;
|
||||
|
||||
/**
|
||||
* 角色组
|
||||
*/
|
||||
@ApiModelProperty("角色组")
|
||||
private Long[] roleIds;
|
||||
//
|
||||
// /**
|
||||
// * 岗位组
|
||||
// */
|
||||
// @ApiModelProperty("岗位组")
|
||||
// private Long[] postIds;
|
||||
|
||||
/**
|
||||
* 角色ID
|
||||
*/
|
||||
@ApiModelProperty("角色ID")
|
||||
private Long roleId;
|
||||
|
||||
|
||||
@ApiModelProperty("sessionId")
|
||||
private String sessionId;
|
||||
|
||||
/**
|
||||
* ai助手问答使用条数
|
||||
*/
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.maibu.core.domain.model;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import com.maibu.core.domain.entity.SysUser;
|
||||
import lombok.Data;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
@@ -13,6 +14,7 @@ import java.util.Set;
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Data
|
||||
public class LoginUser implements UserDetails {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -26,6 +28,21 @@ public class LoginUser implements UserDetails {
|
||||
*/
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 组织id
|
||||
*/
|
||||
private Long orgId;
|
||||
|
||||
/**
|
||||
* 区域id
|
||||
*/
|
||||
private Long siteId;
|
||||
|
||||
/**
|
||||
* 组织id
|
||||
*/
|
||||
private Long roleId;
|
||||
|
||||
/**
|
||||
* 用户唯一标识
|
||||
*/
|
||||
@@ -82,61 +99,6 @@ public class LoginUser implements UserDetails {
|
||||
*/
|
||||
private Integer sourceType;
|
||||
|
||||
public Integer getSourceType() {
|
||||
return sourceType;
|
||||
}
|
||||
|
||||
public void setSourceType(Integer s) {
|
||||
this.sourceType = s;
|
||||
}
|
||||
|
||||
public Boolean getNeverExpire() {
|
||||
return neverExpire;
|
||||
}
|
||||
|
||||
public void setNeverExpire(Boolean neverExpire) {
|
||||
this.neverExpire = neverExpire;
|
||||
}
|
||||
|
||||
public String getLanguage() {
|
||||
return language;
|
||||
}
|
||||
|
||||
public Long getDeptUserId() {
|
||||
return deptUserId;
|
||||
}
|
||||
|
||||
public void setDeptUserId(Long deptUserId) {
|
||||
this.deptUserId = deptUserId;
|
||||
}
|
||||
|
||||
public void setLanguage(String language) {
|
||||
this.language = language;
|
||||
}
|
||||
|
||||
public Long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(Long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public Long getDeptId() {
|
||||
return deptId;
|
||||
}
|
||||
|
||||
public void setDeptId(Long deptId) {
|
||||
this.deptId = deptId;
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public void setToken(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public LoginUser() {
|
||||
}
|
||||
@@ -146,9 +108,11 @@ public class LoginUser implements UserDetails {
|
||||
this.permissions = permissions;
|
||||
}
|
||||
|
||||
public LoginUser(Long userId, Long deptId, String language, SysUser user, Set<String> permissions) {
|
||||
public LoginUser(Long userId, Long deptId, Long orgId, Long siteId, String language, SysUser user, Set<String> permissions) {
|
||||
this.userId = userId;
|
||||
this.deptId = deptId;
|
||||
this.orgId = orgId;
|
||||
this.siteId = siteId;
|
||||
this.user = user;
|
||||
this.language = language;
|
||||
this.permissions = permissions;
|
||||
@@ -207,70 +171,6 @@ public class LoginUser implements UserDetails {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Long getLoginTime() {
|
||||
return loginTime;
|
||||
}
|
||||
|
||||
public void setLoginTime(Long loginTime) {
|
||||
this.loginTime = loginTime;
|
||||
}
|
||||
|
||||
public String getIpaddr() {
|
||||
return ipaddr;
|
||||
}
|
||||
|
||||
public void setIpaddr(String ipaddr) {
|
||||
this.ipaddr = ipaddr;
|
||||
}
|
||||
|
||||
public String getLoginLocation() {
|
||||
return loginLocation;
|
||||
}
|
||||
|
||||
public void setLoginLocation(String loginLocation) {
|
||||
this.loginLocation = loginLocation;
|
||||
}
|
||||
|
||||
public String getBrowser() {
|
||||
return browser;
|
||||
}
|
||||
|
||||
public void setBrowser(String browser) {
|
||||
this.browser = browser;
|
||||
}
|
||||
|
||||
public String getOs() {
|
||||
return os;
|
||||
}
|
||||
|
||||
public void setOs(String os) {
|
||||
this.os = os;
|
||||
}
|
||||
|
||||
public Long getExpireTime() {
|
||||
return expireTime;
|
||||
}
|
||||
|
||||
public void setExpireTime(Long expireTime) {
|
||||
this.expireTime = expireTime;
|
||||
}
|
||||
|
||||
public Set<String> getPermissions() {
|
||||
return permissions;
|
||||
}
|
||||
|
||||
public void setPermissions(Set<String> permissions) {
|
||||
this.permissions = permissions;
|
||||
}
|
||||
|
||||
public SysUser getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(SysUser user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||
return null;
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
package com.maibu.enums;
|
||||
|
||||
import com.maibu.core.text.IntArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 通用状态枚举
|
||||
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum CommonStatusEnum implements IntArrayValuable {
|
||||
|
||||
ENABLE(0, "开启"),
|
||||
DISABLE(1, "关闭");
|
||||
|
||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CommonStatusEnum::getStatus).toArray();
|
||||
|
||||
/**
|
||||
* 状态值
|
||||
*/
|
||||
private final Integer status;
|
||||
/**
|
||||
* 状态名
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public int[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
package com.maibu.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author gsb
|
||||
* @date 2023/6/3 14:09
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum DataEnum {
|
||||
|
||||
DECIMAL("decimal", "十进制"),
|
||||
DOUBLE("double", "双精度"),
|
||||
ENUM("enum","枚举"),
|
||||
BOOLEAN("bool","布尔类型"),
|
||||
INTEGER("integer","整形"),
|
||||
OBJECT("object", "对象"),
|
||||
STRING("string","字符串"),
|
||||
ARRAY("array","数组");
|
||||
|
||||
String type;
|
||||
String msg;
|
||||
|
||||
public static DataEnum convert(String type){
|
||||
for (DataEnum value : DataEnum.values()) {
|
||||
if (Objects.equals(value.type, type)){
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return DataEnum.STRING;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
package com.maibu.enums;
|
||||
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @author admin
|
||||
* @date 2024-07-18 14:52
|
||||
* @version 1.0
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum DeviceDistributeTypeEnum {
|
||||
|
||||
/**
|
||||
* 确保唯一,不能重复
|
||||
*/
|
||||
SELECT(1, "选择分配"),
|
||||
IMPORT(2,"导入分配");
|
||||
|
||||
/**
|
||||
* 渠道类型
|
||||
*/
|
||||
private Integer type;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private String desc;
|
||||
|
||||
public static String getDesc(Integer type) {
|
||||
for (DeviceDistributeTypeEnum item : DeviceDistributeTypeEnum.values()) {
|
||||
if (item.getType().equals(type)) {
|
||||
return item.getDesc();
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package com.maibu.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 场景管理物模型、变量类型枚举
|
||||
* 注意:以下4张表下的variable_type相关字段统一用该枚举,保持一致
|
||||
* scene_model_tag表、scene_tag_points表、scene_model_device表、scene_model_data表
|
||||
* @author fastb
|
||||
* @date 2024-05-22 10:01
|
||||
* @version 1.0
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum DeviceLogTypeEnum {
|
||||
|
||||
ATTRIBUTE_REPORT(1, "属性上报"),
|
||||
INVOKE_FUNCTION(2, "调用功能"),
|
||||
EVENT_REPORT(3, "事件上报"),
|
||||
DEVICE_UPDATE(4, "设备升级"),
|
||||
DEVICE_ONLINE(5, "设备上线"),
|
||||
DEVICE_OFFLINE(6, "设备离线"),
|
||||
SCENE_VARIABLE_REPORT(7, "场景录入、运算变量上报下发");
|
||||
|
||||
private final Integer type;
|
||||
|
||||
private final String desc;
|
||||
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package com.maibu.enums;
|
||||
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @author admin
|
||||
* @date 2024-07-18 14:52
|
||||
* @version 1.0
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum DeviceRecordTypeEnum {
|
||||
|
||||
/**
|
||||
* 确保唯一,不能重复
|
||||
*/
|
||||
IMPORT(1, "导入记录"),
|
||||
RECOVERY(2,"回收记录"),
|
||||
ASSIGNMENT(3,"分配记录"),
|
||||
ASSIGNMENT_DETAIL(4,"分配详细记录");
|
||||
|
||||
|
||||
/**
|
||||
* 渠道类型
|
||||
*/
|
||||
private Integer type;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private String desc;
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package com.maibu.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum JobType {
|
||||
//1==设备定时,2=设备告警,3=场景联动 4=规则引擎
|
||||
Device(1),
|
||||
DeviceAlert(2),
|
||||
Scene(3),
|
||||
RuleEngine(4);
|
||||
private final Integer value;
|
||||
|
||||
public static JobType fromValue(Integer value) {
|
||||
for (JobType type : JobType.values()) {
|
||||
if (Objects.equals(type.getValue(), value)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getName(Integer value) {
|
||||
for (JobType type : JobType.values()) {
|
||||
if (Objects.equals(type.getValue(), value)) {
|
||||
return type.name();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package com.maibu.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 推送类型
|
||||
* @author bill
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum PushType {
|
||||
|
||||
WECHAT_SERVER_PUSH("wechat_server_push","微信小程序服务号推送");
|
||||
|
||||
|
||||
/**
|
||||
* 业务编号
|
||||
*/
|
||||
private String serviceCode;
|
||||
|
||||
private String desc;
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
package com.maibu.enums;
|
||||
|
||||
import com.maibu.constant.HttpStatus;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
/**
|
||||
* API返回对象
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
public enum ResultCode implements IErrorCode {
|
||||
|
||||
SUCCESS(HttpStatus.SUCCESS,"请求成功"),
|
||||
FAILED(HttpStatus.ERROR,"系统内部错误"),
|
||||
ACCEPTED(HttpStatus.ACCEPTED,"请求已接收"),
|
||||
REDIRECT(HttpStatus.SEE_OTHER,"重定向"),
|
||||
UNAUTHORIZED(HttpStatus.UNAUTHORIZED,"暂未登录或token过期"),
|
||||
FORBIDDEN(HttpStatus.FORBIDDEN,"没有相关权限或授权过期"),
|
||||
NOT_FOUND(HttpStatus.NOT_FOUND,"资源未找到"),
|
||||
PARSE_MSG_EXCEPTION(4018, "解析协议异常"),
|
||||
TIMEOUT(502, "响应超时!"),
|
||||
FIRMWARE_VERSION_UNIQUE_ERROR(4022, "产品下已存在该版本固件"),
|
||||
FIRMWARE_SEQ_UNIQUE_ERROR(4023, "产品下已存在该升级序列号"),
|
||||
FIRMWARE_TASK_UNIQUE_ERROR(4024, "任务名已存在"),
|
||||
REPLY_TIMEOUT(4001, "超时未回执"),
|
||||
INVALID_USER_APP(4002, "用户信息不存在"),
|
||||
INVALID_MQTT_USER(1003, "内部mqtt服务用户异常"),
|
||||
DECODE_PROTOCOL_EXCEPTION(1000, "解析协议异常"),
|
||||
MQTT_TOPIC_INVALID(1001, "MQTT订阅topic格式非法");
|
||||
|
||||
private int code;
|
||||
private String message;
|
||||
|
||||
public int getCode(){return code;}
|
||||
|
||||
public String getMessage(){return message;}
|
||||
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package com.maibu.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 通用状态枚举
|
||||
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum StatusEnum {
|
||||
|
||||
SUCCESS(1, "成功"),
|
||||
FAIL(0, "失败");
|
||||
|
||||
|
||||
/**
|
||||
* 状态值
|
||||
*/
|
||||
private final Integer status;
|
||||
/**
|
||||
* 状态名
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package com.maibu.exception.iot;
|
||||
|
||||
import com.maibu.exception.GlobalException;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* mqtt客户端权限校验异常
|
||||
* @author gsb
|
||||
* @date 2022/10/8 14:11
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
public class MqttAuthorizationException extends GlobalException {
|
||||
|
||||
public MqttAuthorizationException(String messageId){
|
||||
super(messageId);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package com.maibu.exception.iot;
|
||||
|
||||
import com.maibu.exception.GlobalException;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* mqtt客户端校验 用户名或密码错误
|
||||
* @author gsb
|
||||
* @date 2022/10/8 14:15
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
public class MqttClientUserNameOrPassException extends GlobalException {
|
||||
|
||||
public MqttClientUserNameOrPassException(String message){
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package com.maibu.exception.job;
|
||||
|
||||
/**
|
||||
* 计划策略异常
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class TaskException extends Exception
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Code code;
|
||||
|
||||
public TaskException(String msg, Code code)
|
||||
{
|
||||
this(msg, code, null);
|
||||
}
|
||||
|
||||
public TaskException(String msg, Code code, Exception nestedEx)
|
||||
{
|
||||
super(msg, nestedEx);
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public Code getCode()
|
||||
{
|
||||
return code;
|
||||
}
|
||||
|
||||
public enum Code
|
||||
{
|
||||
TASK_EXISTS, NO_TASK_EXISTS, TASK_ALREADY_STARTED, UNKNOWN, CONFIG_ERROR, TASK_NODE_NOT_AVAILABLE
|
||||
}
|
||||
}
|
||||
@@ -127,13 +127,13 @@ public class SecurityUtils
|
||||
{
|
||||
String language = getLoginUser().getLanguage();
|
||||
if (StringUtils.isEmpty(language)){
|
||||
return "en-US";
|
||||
return "zh-CN";
|
||||
}
|
||||
return language;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return "en-US";
|
||||
return "zh-CN";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user