Browse Source

二期功能开发

master
zhangyeguang 5 months ago
parent
commit
0b78385bfb
  1. 1
      .gitignore
  2. 1
      common/src/main/java/com/jiagutech/ams/annotation/RateLimiter.java
  3. 12
      common/src/main/java/com/jiagutech/ams/model/dto/DeptDTO.java
  4. 6
      common/src/main/java/com/jiagutech/ams/model/dto/RegionDTO.java
  5. 4
      common/src/main/java/com/jiagutech/ams/model/dto/RoleDTO.java
  6. 1
      common/src/main/java/com/jiagutech/ams/model/dto/UserDTO.java
  7. 2
      common/src/main/java/com/jiagutech/ams/model/dto/UserDeptDTO.java
  8. 2
      common/src/main/java/com/jiagutech/ams/model/dto/UserRoleDTO.java
  9. 26
      common/src/main/java/com/jiagutech/ams/utils/TraceIdUtil.java
  10. 2
      social/pom.xml
  11. 21
      social/src/main/java/com/jiagutech/ams/controller/DeviceController.java
  12. 26
      social/src/main/java/com/jiagutech/ams/controller/JobController.java
  13. 6
      social/src/main/java/com/jiagutech/ams/controller/MessageDataController.java
  14. 33
      social/src/main/java/com/jiagutech/ams/listener/JobFinishListener.java
  15. 6
      social/src/main/java/com/jiagutech/ams/mapper/DeviceMapper.java
  16. 5
      social/src/main/java/com/jiagutech/ams/mapper/JobMapper.java
  17. 2
      social/src/main/java/com/jiagutech/ams/model/dto/DeviceDTO.java
  18. 2
      social/src/main/java/com/jiagutech/ams/model/dto/JobDTO.java
  19. 2
      social/src/main/java/com/jiagutech/ams/model/mapping/DeviceMapping.java
  20. 2
      social/src/main/java/com/jiagutech/ams/model/mapping/JobMapping.java
  21. 3
      social/src/main/java/com/jiagutech/ams/model/mapping/SortieMapping.java
  22. 3
      social/src/main/java/com/jiagutech/ams/model/mapping/TrackImageMapping.java
  23. 6
      social/src/main/java/com/jiagutech/ams/model/mapping/TrackMapping.java
  24. 15
      social/src/main/java/com/jiagutech/ams/model/request/DeviceRequest.java
  25. 39
      social/src/main/java/com/jiagutech/ams/model/request/JobSegmentRequest.java
  26. 12
      social/src/main/java/com/jiagutech/ams/model/response/ChartItem.java
  27. 13
      social/src/main/java/com/jiagutech/ams/model/response/ChartMultiItem.java
  28. 4
      social/src/main/java/com/jiagutech/ams/model/response/JobItem.java
  29. 26
      social/src/main/java/com/jiagutech/ams/rest/TrackRestClient.java
  30. 8
      social/src/main/java/com/jiagutech/ams/service/DeviceService.java
  31. 82
      social/src/main/java/com/jiagutech/ams/service/DeviceServiceImpl.java
  32. 8
      social/src/main/java/com/jiagutech/ams/service/JobService.java
  33. 149
      social/src/main/java/com/jiagutech/ams/service/JobServiceImpl.java
  34. 91
      social/src/main/java/com/jiagutech/ams/service/MessageDataServiceImpl.java
  35. 131
      social/src/main/java/com/jiagutech/ams/utils/Pro4jUtil.java
  36. 30
      social/src/main/resources/mapper/DeviceMapper.xml
  37. 38
      social/src/main/resources/mapper/JobMapper.xml
  38. 8
      system/src/main/java/com/jiagutech/ams/controller/DeptController.java
  39. 11
      system/src/main/java/com/jiagutech/ams/controller/UserController.java
  40. 21
      system/src/main/java/com/jiagutech/ams/model/request/DeptAddRequest.java
  41. 17
      system/src/main/java/com/jiagutech/ams/model/request/FarmerAddRequest.java
  42. 2
      system/src/main/java/com/jiagutech/ams/model/request/UserRequest.java
  43. 42
      system/src/main/java/com/jiagutech/ams/service/DeptServcieImpl.java
  44. 3
      system/src/main/java/com/jiagutech/ams/service/DeptService.java
  45. 75
      system/src/main/java/com/jiagutech/ams/service/DeptServiceImpl.java
  46. 7
      system/src/main/java/com/jiagutech/ams/service/UserService.java
  47. 32
      system/src/main/java/com/jiagutech/ams/service/UserServiceImpl.java
  48. 4
      system/src/main/resources/mapper/UserMapper.xml
  49. 2
      web/src/main/java/com/jiagutech/ams/SocialApplication.java
  50. 7
      web/src/main/java/com/jiagutech/ams/common/GlobalExceptionHandler.java
  51. 46
      web/src/main/java/com/jiagutech/ams/config/CommonInterceptor.java
  52. 1
      web/src/main/java/com/jiagutech/ams/config/SaPermissionImpl.java
  53. 9
      web/src/main/java/com/jiagutech/ams/config/SaTokenConfigure.java
  54. 2
      web/src/main/resources/logback-spring.xml

1
.gitignore

@ -39,3 +39,4 @@ buildNumber.properties
.idea/
.DS_Store
/.fleet/

1
common/src/main/java/com/jiagutech/ams/annotation/RateLimiter.java

@ -9,7 +9,6 @@ import java.lang.annotation.*;
/**
* 限流注解
*
* @author Lion Li
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)

12
common/src/main/java/com/jiagutech/ams/model/dto/DeptDTO.java

@ -4,21 +4,29 @@ import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serial;
import java.io.Serializable;
/**
* @author zhangyeguang
* @ClassName DeptDTO
* @author: zhangyeguang
* @create: 2024-09-01 10:22
* @create 2024-09-01 10:22
* @Version 1.0
* @description:
**/
@Data
@Accessors(chain = true)
@TableName("ams_dept")
public class DeptDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
private String name;
private Long regionCode;
private String regionPath;
}

6
common/src/main/java/com/jiagutech/ams/model/dto/RegionDTO.java

@ -5,9 +5,9 @@ import lombok.Data;
/**
* @ClassName RegionDTO
* @author: zhangyeguang
* @create: 2024-09-02 17:59
* @Version 1.0
* @author zhangyeguang
* @create 2024-09-02 17:59
* @version 1.0
* @description:
**/
@Data

4
common/src/main/java/com/jiagutech/ams/model/dto/RoleDTO.java

@ -10,9 +10,9 @@ import java.io.Serializable;
/**
* @ClassName RoleDTO
* @author: zhangyeguang
* @author zhangyeguang
* @create: 2024-09-01 09:29
* @Version 1.0
* @version 1.0
* @description:
**/
@Data

1
common/src/main/java/com/jiagutech/ams/model/dto/UserDTO.java

@ -26,6 +26,7 @@ public class UserDTO {
private String regionPath;
private String regionName;
private String contactPhone;
private String identityCardNum;
}

2
common/src/main/java/com/jiagutech/ams/model/dto/UserDeptDTO.java

@ -1,7 +1,5 @@
package com.jiagutech.ams.model.dto;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;

2
common/src/main/java/com/jiagutech/ams/model/dto/UserRoleDTO.java

@ -1,7 +1,5 @@
package com.jiagutech.ams.model.dto;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;

26
common/src/main/java/com/jiagutech/ams/utils/TraceIdUtil.java

@ -0,0 +1,26 @@
package com.jiagutech.ams.utils;
import java.nio.ByteBuffer;
import java.util.Base64;
import java.util.UUID;
public class TraceIdUtil {
private static final ThreadLocal<String> TRACE_ID = new InheritableThreadLocal<>();
public static void setTraceId(String traceId) {
TRACE_ID.set(traceId);
}
public static String getTraceId() {
return TRACE_ID.get();
}
public static void clear() {
TRACE_ID.remove();
}
public static String generateTraceId() {
UUID uuid = UUID.randomUUID();
return Long.toHexString(uuid.getMostSignificantBits());
}
}

2
social/pom.xml

@ -109,6 +109,8 @@
<artifactId>esdk-obs-java</artifactId>
<version>3.20.6.1</version>
</dependency>
</dependencies>
</project>

21
social/src/main/java/com/jiagutech/ams/controller/DeviceController.java

@ -6,7 +6,8 @@ import com.jiagutech.ams.model.common.PageRequest;
import com.jiagutech.ams.model.common.PageResult;
import com.jiagutech.ams.model.common.R;
import com.jiagutech.ams.model.dto.DeviceDTO;
import com.jiagutech.ams.model.request.JobPageRequest;
import com.jiagutech.ams.model.request.DeviceRequest;
import com.jiagutech.ams.model.response.ChartItem;
import com.jiagutech.ams.model.response.DeviceDetail;
import com.jiagutech.ams.model.response.DeviceInfo;
import com.jiagutech.ams.service.DeviceService;
@ -44,13 +45,12 @@ public class DeviceController {
@Operation(summary = "设备列表")
@PostMapping("/page")
@SaCheckRole(value = {"manager", "admin"}, mode = SaMode.OR)
public R<PageResult<DeviceDTO>> page(@RequestBody PageRequest<Void> pageRequest) {
@SaCheckRole(value = {"manager", "admin", "gov"}, mode = SaMode.OR)
public R<PageResult<DeviceDTO>> page(@RequestBody PageRequest<DeviceRequest> pageRequest) {
return R.ok(deviceService.page(pageRequest));
}
@Operation(summary = "获取所有设备列表")
@GetMapping("/list")
public R<List<DeviceInfo>> list() {
@ -63,4 +63,17 @@ public class DeviceController {
return R.ok(deviceService.deviceDetail(deviceId));
}
@Operation(summary = "获取最近一次绑定的农机")
@GetMapping("/latest")
@SaCheckRole(value = "machinist")
public R<DeviceInfo> latestDeviceInfo() {
return R.ok(deviceService.latestDeviceInfo());
}
@GetMapping("/chart")
@Operation(summary = "获取设备统计图表")
@SaCheckRole(value = "gov")
public R<List<ChartItem>> chart() {
return R.ok(deviceService.chart());
}
}

26
social/src/main/java/com/jiagutech/ams/controller/JobController.java

@ -4,6 +4,7 @@ import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.annotation.SaMode;
import cn.hutool.core.collection.CollectionUtil;
import com.jiagutech.ams.listener.JobFinishListener;
import com.jiagutech.ams.model.request.JobSegmentRequest;
import com.jiagutech.ams.model.TrackImageVO;
import com.jiagutech.ams.model.TrackItem;
import com.jiagutech.ams.model.common.PageRequest;
@ -13,9 +14,12 @@ import com.jiagutech.ams.model.dto.JobTypeDTO;
import com.jiagutech.ams.model.request.JobCreateRequest;
import com.jiagutech.ams.model.request.JobPageRequest;
import com.jiagutech.ams.model.request.JobStatusRequest;
import com.jiagutech.ams.model.response.ChartItem;
import com.jiagutech.ams.model.response.ChartMultiItem;
import com.jiagutech.ams.model.response.JobCreateResponse;
import com.jiagutech.ams.model.response.JobItem;
import com.jiagutech.ams.service.JobService;
import com.jiagutech.ams.utils.Pro4jUtil;
import com.jiagutech.ams.utils.TrackUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@ -105,6 +109,14 @@ public class JobController {
return R.ok();
}
@Operation(summary = "切分作业记录")
@PostMapping("/segment")
public R<Void> segmentJob(@RequestBody JobSegmentRequest jobSegmentRequest) {
jobService.segmentJob(jobSegmentRequest);
return R.ok();
}
@GetMapping("/tracksByZhongnong")
@Operation(summary = "从中农云获取作业轨迹列表")
public R<List<TrackItem>> getTracksByZhongnongList(@RequestParam("deviceId") String deviceId,
@ -128,18 +140,22 @@ public class JobController {
@RequestParam long endTime,
@RequestParam float breadth) {
List<TrackItem> tracks = jobService.getTracks(deviceId, startTime, endTime);
List<TrackItem> tracks1 = jobFinishListener.getTracks(deviceId, startTime, endTime);
float noFilter = TrackUtil.calcAreaByBlockDataNoFilter(tracks, breadth);
float byFilter = TrackUtil.calcAreaByBlockData(tracks);
float zhongnongArea = TrackUtil.calcAreaByBlockDataNoFilter(tracks1, breadth);
float zhongnongArea1 = TrackUtil.calcAreaByBlockData(tracks1, breadth);
Map<String, Float> areas = new HashMap<>(4);
areas.put("noFilter", noFilter);
areas.put("byFilter", byFilter);
areas.put("zhongnongArea", zhongnongArea);
areas.put("zhongnongArea1", zhongnongArea1);
float v = Pro4jUtil.calculateAreaByCGCS2000(tracks1);
areas.put("polygonArea", v);
return R.ok(areas);
}
@SaCheckRole("gov")
@Operation(summary = "作业统计图表")
@GetMapping("/chart")
public R<List<ChartMultiItem>> getJobChart() {
return R.ok(jobService.getJobChart());
}
}

6
social/src/main/java/com/jiagutech/ams/controller/MessageDataController.java

@ -21,7 +21,7 @@ public class MessageDataController {
private final MessageDataService messageDataService;
@PostMapping("/machineryRealtimeData")
public R addRealTimeData(@RequestBody List<RealTimeData> realTimeDatas) {
public R<String> addRealTimeData(@RequestBody List<RealTimeData> realTimeDatas) {
//if (checkSign(request,response)) {
log.info("RealTimeData:{}", JSONObject.toJSONString(realTimeDatas));
messageDataService.addRealTimeData(realTimeDatas);
@ -30,7 +30,7 @@ public class MessageDataController {
}
@PostMapping(value = "/machineryImage", consumes = "multipart/form-data")
public R machineryImage(@ModelAttribute MachImage machImage) {
public R<String> machineryImage(@ModelAttribute MachImage machImage) {
log.info("workRecord:{}", machImage.getVehicleId());
messageDataService.machineryImage(machImage);
@ -39,7 +39,7 @@ public class MessageDataController {
}
@PostMapping("/machineryAreaDataList")
public R addWorkData(@RequestBody List<WorkRecord> workRecords) {
public R<String> addWorkData(@RequestBody List<WorkRecord> workRecords) {
log.info("WorkRecord:{}", JSONObject.toJSONString(workRecords));
messageDataService.addWorkData(workRecords);

33
social/src/main/java/com/jiagutech/ams/listener/JobFinishListener.java

@ -5,18 +5,16 @@ import com.jiagutech.ams.event.JobFinishEvent;
import com.jiagutech.ams.mapper.DeviceMapper;
import com.jiagutech.ams.mapper.JobMapper;
import com.jiagutech.ams.model.TrackItem;
import com.jiagutech.ams.model.TrackMapping;
import com.jiagutech.ams.model.ZhongNongTrackData;
import com.jiagutech.ams.model.dto.DeviceDTO;
import com.jiagutech.ams.model.dto.JobDTO;
import com.jiagutech.ams.rest.TrackRestClient;
import com.jiagutech.ams.service.JobService;
import com.jiagutech.ams.utils.Pro4jUtil;
import com.jiagutech.ams.utils.TrackUtil;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Hex;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
@ -47,11 +45,6 @@ public class JobFinishListener {
private final TrackRestClient trackRestClient;
private final JobService jobService;
@Value("${zhong-nong.client.key_id}")
private String keyId;
@Value("${zhong-nong.client.secret_key}")
private String secretKey;
@Async
@EventListener(JobFinishEvent.class)
@ -76,7 +69,7 @@ public class JobFinishListener {
public List<TrackItem> getTracks(String deviceId, long startTime, long endTime) {
List<TrackItem> trackList = getTracksFromZhongNong(deviceId, startTime, endTime);
List<TrackItem> trackList = trackRestClient.getTracksFromZhongNong(deviceId, startTime, endTime);
log.info("tracks length={}", trackList.size());
return trackList;
}
@ -99,6 +92,9 @@ public class JobFinishListener {
log.info("从td-engine中获取轨迹");
List<TrackItem> tracks = jobService.getTracks(deviceDTO.getBoxNum(), jobDTO.getStartTime(), jobDTO.getEndTime());
double breadth = 0;
log.info("从中农云中获取轨迹");
tracks = trackRestClient.getTracksFromZhongNong(deviceDTO.getBoxNum(), jobDTO.getStartTime(), jobDTO.getEndTime());
if (CollectionUtil.isNotEmpty(tracks)) {
for (TrackItem track : tracks) {
if (track.getBreadth() > 0) {
@ -107,11 +103,10 @@ public class JobFinishListener {
}
}
}
log.info("从中农云中获取轨迹");
tracks = getTracksFromZhongNong(deviceDTO.getBoxNum(), jobDTO.getStartTime(), jobDTO.getEndTime());
jobDTO.setArea(TrackUtil.calcAreaByBlockData(tracks, breadth));
float areaByPoly = Pro4jUtil.calculateAreaByCGCS2000(tracks);
float areaByBreadth = TrackUtil.calcAreaByBlockData(tracks, breadth);
log.info("作业面积:多边形计算的面积={},宽幅(当前宽幅:{})计算的面积={}", areaByPoly, breadth, areaByBreadth);
jobDTO.setArea(areaByBreadth);
TrackItem trackItem = tracks.get(tracks.size() - 1);
jobDTO.setLat(trackItem.getLat()).setLng(trackItem.getLng());
deviceDTO.setLat(trackItem.getLat()).setLng(trackItem.getLng()).setUpdateTime(trackItem.getTimestamp());
@ -120,16 +115,6 @@ public class JobFinishListener {
}
private List<TrackItem> getTracksFromZhongNong(String vehicleId, Long startTime, Long endTime) {
ZhongNongTrackData tracks = trackRestClient.getZhongNongTracks(keyId, secretKey, vehicleId, startTime, endTime);
log.info("中农云获取到的轨迹数量:{}", tracks != null ? tracks.getVehicleLocusList().size() : 0);
TrackMapping mapping = TrackMapping.INSTANCE;
assert tracks != null;
List<TrackItem> items = mapping.convertToTrackItemsByZhongNongTracks(tracks.getVehicleLocusList());
items.get(0).setBreadth(tracks.getBreadth());
return items;
}
@SneakyThrows
private String signature(String keyId, long timestamp, String secretKey) {

6
social/src/main/java/com/jiagutech/ams/mapper/DeviceMapper.java

@ -2,7 +2,9 @@ package com.jiagutech.ams.mapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jiagutech.ams.model.dto.DeviceDTO;
import com.jiagutech.ams.model.response.ChartItem;
import com.jiagutech.ams.model.response.DeviceDetail;
import com.jiagutech.ams.model.response.DeviceInfo;
import org.apache.ibatis.annotations.Param;
@ -14,4 +16,8 @@ public interface DeviceMapper extends BaseMapper<DeviceDTO> {
List<DeviceInfo> queryDeviceList(Long detpId);
DeviceDetail selectDetail(@Param("ew") QueryWrapper<DeviceDetail> queryWrapper);
Page<DeviceDTO> deivcePage(Page<DeviceDTO> page, @Param("ew") QueryWrapper<DeviceDTO> queryWrapper);
List<ChartItem> selectChart(@Param("level") int level, @Param("regionPath") String regionPath);
}

5
social/src/main/java/com/jiagutech/ams/mapper/JobMapper.java

@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jiagutech.ams.model.dto.JobDTO;
import com.jiagutech.ams.model.response.ChartMultiItem;
import com.jiagutech.ams.model.response.JobItem;
import org.apache.ibatis.annotations.Param;
@ -19,4 +20,8 @@ public interface JobMapper extends BaseMapper<JobDTO> {
List<JobItem> jobListCountByFarmer(@Param("ew") QueryWrapper wrapper);
List<JobItem> inJob(@Param("ew") QueryWrapper<JobItem> queryWrapper);
List<JobDTO> inProcessJob(@Param("ew") QueryWrapper<JobDTO> queryWrapper);
List<ChartMultiItem> selectChart(@Param("level") int level, @Param("regionPath") String regionPath);
}

2
social/src/main/java/com/jiagutech/ams/model/dto/DeviceDTO.java

@ -31,6 +31,8 @@ public class DeviceDTO {
private Long deptId;
private String deptName;
private Double lat;
private Double lng;

2
social/src/main/java/com/jiagutech/ams/model/dto/JobDTO.java

@ -45,4 +45,6 @@ public class JobDTO {
private Double lng;
private Integer finishedType;
}

2
social/src/main/java/com/jiagutech/ams/model/DeviceMapping.java → social/src/main/java/com/jiagutech/ams/model/mapping/DeviceMapping.java

@ -1,4 +1,4 @@
package com.jiagutech.ams.model;
package com.jiagutech.ams.model.mapping;
import com.jiagutech.ams.model.dto.DeviceDTO;
import com.jiagutech.ams.model.response.DeviceInfo;

2
social/src/main/java/com/jiagutech/ams/model/JobMapping.java → social/src/main/java/com/jiagutech/ams/model/mapping/JobMapping.java

@ -1,4 +1,4 @@
package com.jiagutech.ams.model;
package com.jiagutech.ams.model.mapping;
import com.jiagutech.ams.model.dto.JobDTO;
import com.jiagutech.ams.model.request.JobCreateRequest;

3
social/src/main/java/com/jiagutech/ams/model/SortieMapping.java → social/src/main/java/com/jiagutech/ams/model/mapping/SortieMapping.java

@ -1,5 +1,6 @@
package com.jiagutech.ams.model;
package com.jiagutech.ams.model.mapping;
import com.jiagutech.ams.model.UavSortie;
import com.jiagutech.ams.model.dto.SortieDTO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

3
social/src/main/java/com/jiagutech/ams/model/TrackImageMapping.java → social/src/main/java/com/jiagutech/ams/model/mapping/TrackImageMapping.java

@ -1,5 +1,6 @@
package com.jiagutech.ams.model;
package com.jiagutech.ams.model.mapping;
import com.jiagutech.ams.model.TrackImageVO;
import com.jiagutech.ams.model.request.MachImage;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;

6
social/src/main/java/com/jiagutech/ams/model/TrackMapping.java → social/src/main/java/com/jiagutech/ams/model/mapping/TrackMapping.java

@ -1,5 +1,9 @@
package com.jiagutech.ams.model;
package com.jiagutech.ams.model.mapping;
import com.jiagutech.ams.model.Locus;
import com.jiagutech.ams.model.TrackImageVO;
import com.jiagutech.ams.model.TrackItem;
import com.jiagutech.ams.model.ZhongNongTrack;
import com.jiagutech.ams.model.dto.TrackImageDTO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

15
social/src/main/java/com/jiagutech/ams/model/request/DeviceRequest.java

@ -0,0 +1,15 @@
package com.jiagutech.ams.model.request;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(name = "设备列表请求条件")
public class DeviceRequest {
@Schema(description = "区域编码")
private Long regionCode;
@Schema(description = "合作社ID")
private Integer deptId;
@Schema(description = "设备车牌")
private String licensePlate;
}

39
social/src/main/java/com/jiagutech/ams/model/request/JobSegmentRequest.java

@ -0,0 +1,39 @@
package com.jiagutech.ams.model.request;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.jiagutech.ams.utils.StringToLongDeserializer;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
@Schema(name = "切分作业请求")
public class JobSegmentRequest {
@Schema(description = "原始作业ID", example = "123456789")
@JsonDeserialize(using = StringToLongDeserializer.class)
private long originalJobId;
@Schema(description = "切分作业内容")
private List<JobSegment> segments;
@Data
@Schema(name = "切分作业内容")
public static class JobSegment {
@Schema(description = "作业开始时间", example = "123456789")
private Long startTime;
@Schema(description = "作业结束时间", example = "123456789")
private Long endTime;
@Schema(description = "操作员ID", example = "123456789")
@JsonDeserialize(using = StringToLongDeserializer.class)
private long operatorId;
@Schema(description = "农户ID", example = "123456789")
@JsonDeserialize(using = StringToLongDeserializer.class)
private long farmerId;
// @Schema(description = "地块面积", example = "123456789")
// private Float area;
}
}

12
social/src/main/java/com/jiagutech/ams/model/response/ChartItem.java

@ -0,0 +1,12 @@
package com.jiagutech.ams.model.response;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class ChartItem {
private Long code;
private String name;
private Integer count;
}

13
social/src/main/java/com/jiagutech/ams/model/response/ChartMultiItem.java

@ -0,0 +1,13 @@
package com.jiagutech.ams.model.response;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class ChartMultiItem {
private Long code;
private String name;
private Integer count;
private Float value;
}

4
social/src/main/java/com/jiagutech/ams/model/response/JobItem.java

@ -4,6 +4,7 @@ import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
@ -13,6 +14,7 @@ import lombok.Data;
* @Version 1.0
* @description:
**/
@Schema(name = "作业记录")
@Data
public class JobItem {
@ExcelIgnore
@ -70,5 +72,7 @@ public class JobItem {
private String licensePlate;
@ExcelProperty(value = "盒子编号")
private String boxNum;
@Schema(description = "作业完成类型,1=手动完成,2=自动完成,3=人工处理完成")
private Integer finishedType;
}

26
social/src/main/java/com/jiagutech/ams/rest/TrackRestClient.java

@ -3,10 +3,13 @@ package com.jiagutech.ams.rest;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import com.jiagutech.ams.model.Locus;
import com.jiagutech.ams.model.TrackItem;
import com.jiagutech.ams.model.ZhongNongTrackData;
import com.jiagutech.ams.model.mapping.TrackMapping;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
@ -30,7 +33,10 @@ public class TrackRestClient {
@Value("${center-track.client.url}")
private String centerBaseUrl;
@Value("${zhong-nong.client.key_id}")
private String keyId;
@Value("${zhong-nong.client.secret_key}")
private String secretKey;
public List<Locus> getTractorByDroneIdAndTime(String droneid, Long startTime, Long endTime) {
Map<String, Object> map = new HashMap<>();
@ -42,12 +48,12 @@ public class TrackRestClient {
});
}
public String saveTractor(List<Locus> tracks) {
@Async
public void saveTractor(List<Locus> tracks) {
String s = JSON.toJSONString(tracks);
log.info("传参==>" + s);
// log.info("传参==>" + s);
String result = restTemplate.postForObject(centerBaseUrl + "/track/saveTractor", s, String.class);
return result;
log.info("轨迹保存完成:{}", result);
}
public ZhongNongTrackData getZhongNongTracks(String keyId, String secretKey, String droneId, Long startTime, Long endTime) {
@ -61,4 +67,14 @@ public class TrackRestClient {
return JSON.parseObject(res, ZhongNongTrackData.class);
}
public List<TrackItem> getTracksFromZhongNong( String vehicleId, Long startTime, Long endTime) {
ZhongNongTrackData tracks = getZhongNongTracks(keyId, secretKey, vehicleId, startTime, endTime);
log.info("中农云获取到的轨迹数量:{}", tracks != null ? tracks.getVehicleLocusList().size() : 0);
TrackMapping mapping = TrackMapping.INSTANCE;
assert tracks != null;
List<TrackItem> items = mapping.convertToTrackItemsByZhongNongTracks(tracks.getVehicleLocusList());
log.info("breadth={}", tracks.getBreadth());
items.get(0).setBreadth(tracks.getBreadth());
return items;
}
}

8
social/src/main/java/com/jiagutech/ams/service/DeviceService.java

@ -3,6 +3,8 @@ package com.jiagutech.ams.service;
import com.jiagutech.ams.model.common.PageRequest;
import com.jiagutech.ams.model.common.PageResult;
import com.jiagutech.ams.model.dto.DeviceDTO;
import com.jiagutech.ams.model.request.DeviceRequest;
import com.jiagutech.ams.model.response.ChartItem;
import com.jiagutech.ams.model.response.DeviceDetail;
import com.jiagutech.ams.model.response.DeviceInfo;
@ -11,9 +13,13 @@ import java.util.List;
public interface DeviceService {
List<DeviceInfo> onlineAndRound(double maxLng, double maxLat, double minLng, double minLat);
PageResult<DeviceDTO> page(PageRequest<Void> pageRequest);
PageResult<DeviceDTO> page(PageRequest<DeviceRequest> pageRequest);
List<DeviceInfo> deviceList();
DeviceDetail deviceDetail(Integer deviceId);
DeviceInfo latestDeviceInfo();
List<ChartItem> chart();
}

82
social/src/main/java/com/jiagutech/ams/service/DeviceServiceImpl.java

@ -3,24 +3,31 @@ package com.jiagutech.ams.service;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jiagutech.ams.mapper.DeviceMapper;
import com.jiagutech.ams.model.DeviceMapping;
import com.jiagutech.ams.mapper.JobMapper;
import com.jiagutech.ams.model.mapping.DeviceMapping;
import com.jiagutech.ams.model.LoginUser;
import com.jiagutech.ams.model.TrackDataJG;
import com.jiagutech.ams.model.common.PageRequest;
import com.jiagutech.ams.model.common.PageResult;
import com.jiagutech.ams.model.dto.DeviceDTO;
import com.jiagutech.ams.model.dto.JobDTO;
import com.jiagutech.ams.model.dto.RoleDTO;
import com.jiagutech.ams.model.request.DeviceRequest;
import com.jiagutech.ams.model.response.ChartItem;
import com.jiagutech.ams.model.response.DeviceDetail;
import com.jiagutech.ams.model.response.DeviceInfo;
import com.jiagutech.ams.utils.LoginUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import java.util.*;
import java.util.function.Consumer;
@ -40,6 +47,7 @@ public class DeviceServiceImpl implements DeviceService {
public static final String TRACK_PREFIX_REDIS_KEY = "mtrack:*";
private final StringRedisTemplate stringRedisTemplate;
private final DeviceMapper deviceMapper;
private final JobMapper jobMapper;
@Override
public List<DeviceInfo> onlineAndRound(double maxLng, double maxLat, double minLng, double minLat) {
@ -89,13 +97,41 @@ public class DeviceServiceImpl implements DeviceService {
}
@Override
public PageResult<DeviceDTO> page(PageRequest<Void> pageRequest) {
public PageResult<DeviceDTO> page(PageRequest<DeviceRequest> pageRequest) {
Page<DeviceDTO> page = new Page(pageRequest.getPageNum(), pageRequest.getPageSize());
QueryWrapper<DeviceDTO> queryWrapper = buildQueryWrapper(pageRequest.getRequest());
Page<DeviceDTO> result = deviceMapper.deivcePage(page, queryWrapper);
return PageResult.of((int) result.getTotal(), pageRequest.getPageSize(), (int) result.getCurrent(), result.getRecords());
}
private QueryWrapper<DeviceDTO> buildQueryWrapper(DeviceRequest deviceRequest) {
QueryWrapper<DeviceDTO> queryWrapper = Wrappers.query();
if (!ObjectUtils.isEmpty(deviceRequest)) {
if (deviceRequest.getRegionCode() != null && deviceRequest.getRegionCode() != 0L) {
queryWrapper.eq("dp.region_code", deviceRequest.getRegionCode());
}
if (deviceRequest.getDeptId() != null && deviceRequest.getDeptId() != 0L) {
queryWrapper.eq("d.dept_id", deviceRequest.getDeptId());
}
if (StringUtils.isNotBlank(deviceRequest.getLicensePlate())) {
queryWrapper.like("d.license_plate", deviceRequest.getLicensePlate());
}
}
LoginUser loginUser = LoginUtil.getLoginUser();
queryWrapper.eq("dept_id", loginUser.getDept().getId());
Page<DeviceDTO> result = deviceMapper.selectPage(page, queryWrapper);
return PageResult.of((int) result.getTotal(), (int) pageRequest.getPageSize(), (int) result.getCurrent(), result.getRecords());
Predicate<RoleDTO> predicate1 = r -> r.getKey().equals("manager");
Predicate<RoleDTO> predicate2 = r -> r.getKey().equals("gov");
boolean hasManager = loginUser.getRoles().stream().anyMatch(predicate1);
boolean hasGov = loginUser.getRoles().stream().anyMatch(predicate2);
if (hasManager) {
queryWrapper.eq("d.dept_id", loginUser.getDept().getId());
}
if (hasGov && loginUser.getRegionPath() != null) {
queryWrapper.likeRight("dp.region_path", loginUser.getRegionPath());
}
queryWrapper.orderByAsc("d.dept_id").orderByDesc("d.update_time");
return queryWrapper;
}
@Override
@ -147,4 +183,40 @@ public class DeviceServiceImpl implements DeviceService {
}
return deviceDetail;
}
@Override
public DeviceInfo latestDeviceInfo() {
QueryWrapper<JobDTO> queryWrapper = Wrappers.query();
LoginUser loginUser = LoginUtil.getLoginUser();
Assert.notNull(loginUser, "用户未登录");
Long userId = loginUser.getUserId();
queryWrapper.eq("operator_id", userId);
queryWrapper.orderByDesc("start_time");
queryWrapper.last("limit 1");
JobDTO jobDTO = jobMapper.selectOne(queryWrapper);
if (ObjectUtil.isEmpty(jobDTO)) {
return null;
}
DeviceDTO deviceDTO = deviceMapper.selectById(jobDTO.getDeviceId());
DeviceInfo deviceInfo = DeviceMapping.INSTANCE.convertDeviceInfo(deviceDTO);
if (Boolean.TRUE.equals(stringRedisTemplate.hasKey("mtrack:" + deviceDTO.getBoxNum()))) {
deviceInfo.setStatus(1);
} else {
deviceInfo.setStatus(2);
}
return deviceInfo;
}
@Override
public List<ChartItem> chart() {
LoginUser loginUser = LoginUtil.getLoginUser();
String regionPath = loginUser.getRegionPath();
if (StringUtils.isNotBlank(regionPath)) {
int level = regionPath.split("->").length;
return deviceMapper.selectChart(level, regionPath);
}
return Collections.emptyList();
}
}

8
social/src/main/java/com/jiagutech/ams/service/JobService.java

@ -8,6 +8,9 @@ import com.jiagutech.ams.model.dto.JobTypeDTO;
import com.jiagutech.ams.model.dto.TrackImageDTO;
import com.jiagutech.ams.model.request.JobCreateRequest;
import com.jiagutech.ams.model.request.JobPageRequest;
import com.jiagutech.ams.model.request.JobSegmentRequest;
import com.jiagutech.ams.model.response.ChartItem;
import com.jiagutech.ams.model.response.ChartMultiItem;
import com.jiagutech.ams.model.response.JobCreateResponse;
import com.jiagutech.ams.model.response.JobItem;
import jakarta.servlet.http.HttpServletResponse;
@ -34,6 +37,9 @@ public interface JobService {
void saveJobImages(TrackImageVO trackImageDTO);
List<TrackItem> getTracks(String droneId,long startTime,long endTime);
List<TrackItem> getTracks(String droneId, long startTime, long endTime);
void segmentJob(JobSegmentRequest jobSegmentRequest);
List<ChartMultiItem> getJobChart();
}

149
social/src/main/java/com/jiagutech/ams/service/JobServiceImpl.java

@ -7,7 +7,6 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jiagutech.ams.constant.UserConstants;
import com.jiagutech.ams.event.JobFinishEvent;
import com.jiagutech.ams.exception.BizCode;
import com.jiagutech.ams.exception.BusinessException;
@ -16,27 +15,32 @@ import com.jiagutech.ams.model.*;
import com.jiagutech.ams.model.common.PageRequest;
import com.jiagutech.ams.model.common.PageResult;
import com.jiagutech.ams.model.dto.*;
import com.jiagutech.ams.model.mapping.JobMapping;
import com.jiagutech.ams.model.mapping.TrackMapping;
import com.jiagutech.ams.model.request.JobCreateRequest;
import com.jiagutech.ams.model.request.JobPageRequest;
import com.jiagutech.ams.model.response.JobCreateResponse;
import com.jiagutech.ams.model.response.JobItem;
import com.jiagutech.ams.model.response.JobPolyItem;
import com.jiagutech.ams.model.request.JobSegmentRequest;
import com.jiagutech.ams.model.response.*;
import com.jiagutech.ams.rest.TrackRestClient;
import com.jiagutech.ams.utils.ExcelUtil;
import com.jiagutech.ams.utils.LoginUtil;
import com.jiagutech.ams.utils.Pro4jUtil;
import com.jiagutech.ams.utils.TrackUtil;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
* @ClassName JobServiceImpl
@ -63,7 +67,10 @@ public class JobServiceImpl implements JobService {
private final TrackImageMapper trackImageMapper;
private final ApplicationContext applicationContext;
@Value("${zhong-nong.client.key_id}")
private String keyId;
@Value("${zhong-nong.client.secret_key}")
private String secretKey;
@Override
public JobCreateResponse createJob(JobCreateRequest jobCreateRequest) {
@ -98,7 +105,7 @@ public class JobServiceImpl implements JobService {
JobPageRequest requestParam = pageRequest.getRequest();
QueryWrapper<JobItem> queryWrapper = buildQueryWrapper(requestParam);
queryWrapper.orderByDesc("j.start_time");
Page<JobItem> page = new Page(pageRequest.getPageNum(), pageRequest.getPageSize());
Page<JobItem> page = new Page<>(pageRequest.getPageNum(), pageRequest.getPageSize());
Page<JobItem> result = jobMapper.jobPage(page, queryWrapper);
return PageResult.of((int) result.getTotal(), (int) result.getSize(), (int) result.getCurrent(), result.getRecords());
}
@ -120,6 +127,7 @@ public class JobServiceImpl implements JobService {
@Override
public void exportJobs(JobPageRequest jobPageRequest, HttpServletResponse response) {
QueryWrapper<JobItem> queryWrapper = buildQueryWrapper(jobPageRequest);
queryWrapper.in("finish_type", 1, 3);
List<JobItem> jobItems = jobMapper.jobList(queryWrapper);
ExcelUtil.exportExcel(jobItems, "作业记录", JobItem.class, response);
}
@ -127,6 +135,7 @@ public class JobServiceImpl implements JobService {
@Override
public void exportByFarmer(JobPageRequest jobPageRequest, HttpServletResponse response) {
QueryWrapper<JobItem> queryWrapper = buildQueryWrapper(jobPageRequest);
queryWrapper.in("finish_type", 1, 3);
List<JobItem> jobItems = jobMapper.jobListCountByFarmer(queryWrapper);
List<JobPolyItem> jobPolyItems = JobMapping.INSTANCE.jobItemListToJobPolyItemList(jobItems);
ExcelUtil.exportExcel(jobPolyItems, "作业记录", JobPolyItem.class, response);
@ -135,32 +144,47 @@ public class JobServiceImpl implements JobService {
@Override
public List<TrackItem> getTrackList(Long jobId) {
if (jobId != null) {
JobDTO job = jobMapper.selectById(jobId);
DeviceDTO deviceDTO = deviceMapper.selectById(job.getDeviceId());
if (ObjectUtil.isEmpty(job) || ObjectUtil.isEmpty(deviceDTO)) {
return Collections.emptyList();
}
List<Locus> locusList = trackRestClient.getTractorByDroneIdAndTime(deviceDTO.getBoxNum(), job.getStartTime(), job.getEndTime());
QueryWrapper<TrackImageDTO> query = Wrappers.query();
List<TrackImageDTO> trackImageDTOS = trackImageMapper.selectList(
query.eq("device_id", job.getDeviceId())
.between("ts", job.getStartTime(), job.getEndTime())
);
if (locusList == null && CollectionUtil.isEmpty(locusList)) {
return Collections.emptyList();
}
List<TrackItem> trackItems = new ArrayList<>(locusList.size());
assert jobId != null;
JobDTO job = jobMapper.selectById(jobId);
DeviceDTO deviceDTO = deviceMapper.selectById(job.getDeviceId());
if (ObjectUtil.isEmpty(job) || ObjectUtil.isEmpty(deviceDTO)) {
return Collections.emptyList();
}
long endTime;
if (job.getStatus() == 1) {
endTime = System.currentTimeMillis();
} else {
endTime = job.getEndTime();
}
List<Locus> locusList = trackRestClient.getTractorByDroneIdAndTime(deviceDTO.getBoxNum(), job.getStartTime(), endTime);
QueryWrapper<TrackImageDTO> query = Wrappers.query();
List<TrackImageDTO> trackImageDTOS = trackImageMapper.selectList(
query.eq("device_id", job.getDeviceId())
.between("ts", job.getStartTime(), job.getEndTime())
);
List<TrackItem> trackItems;
if (CollectionUtil.isNotEmpty(locusList)) {
trackItems = new ArrayList<>(locusList.size());
for (Locus locus : locusList) {
TrackItem trackItem = TrackMapping.INSTANCE.convertToTrackItemByLocus(locus);
Optional<TrackImageDTO> imageDTOOptional = trackImageDTOS.stream().filter(t -> t.getTs().equals(locus.getTimestamp())).findFirst();
imageDTOOptional.ifPresent(trackImageDTO -> trackItem.setImageUrl(trackImageDTO.getImageUrl()));
trackItems.add(trackItem);
}
return trackItems;
} else {
ZhongNongTrackData tracks = trackRestClient.getZhongNongTracks(keyId, secretKey, deviceDTO.getBoxNum(), job.getStartTime(), endTime);
log.info("中农云获取到的轨迹数量:{}", tracks != null ? tracks.getVehicleLocusList().size() : 0);
TrackMapping mapping = TrackMapping.INSTANCE;
assert tracks != null;
trackItems = mapping.convertToTrackItemsByZhongNongTracks(tracks.getVehicleLocusList());
for (TrackItem trackItem : trackItems) {
Optional<TrackImageDTO> imageDTOOptional = trackImageDTOS.stream().filter(t -> t.getTs().equals(trackItem.getTimestamp())).findFirst();
imageDTOOptional.ifPresent(trackImageDTO -> trackItem.setImageUrl(trackImageDTO.getImageUrl()));
}
}
return List.of();
return trackItems;
}
@Override
@ -178,7 +202,7 @@ public class JobServiceImpl implements JobService {
private QueryWrapper<JobItem> buildQueryWrapper(JobPageRequest requestParam) {
QueryWrapper queryWrapper = Wrappers.query();
QueryWrapper<JobItem> queryWrapper = Wrappers.query();
if (requestParam != null) {
if (requestParam.getStartTimeBegin() != 0l && requestParam.getStartTimeEnd() != 0l) {
queryWrapper.between("j.start_time", requestParam.getStartTimeBegin(), requestParam.getStartTimeEnd());
@ -235,4 +259,73 @@ public class JobServiceImpl implements JobService {
List<Locus> tractorByDroneIdAndTime = trackRestClient.getTractorByDroneIdAndTime(droneId, startTime, endTime);
return TrackMapping.INSTANCE.convertToTrackItemsByLocus(tractorByDroneIdAndTime);
}
@Transactional
@Override
public void segmentJob(JobSegmentRequest jobSegmentRequest) {
long originalJobId = jobSegmentRequest.getOriginalJobId();
JobDTO originalJob = jobMapper.selectById(originalJobId);
if (originalJob != null) {
DeviceDTO deviceDTO = deviceMapper.selectById(originalJob.getDeviceId());
int count = 0;
for (JobSegmentRequest.JobSegment jobSegment : jobSegmentRequest.getSegments()) {
JobDTO jobDTO = new JobDTO();
jobDTO.setJobType(originalJob.getJobType())
.setFinishedType(3)
.setStatus(2)
.setDeptId(originalJob.getDeptId())
.setRegionCode(originalJob.getRegionCode())
.setDeviceId(originalJob.getDeviceId())
.setOperatorId(jobSegment.getOperatorId())
.setFarmerId(jobSegment.getFarmerId())
.setStartTime(jobSegment.getStartTime())
.setEndTime(jobSegment.getEndTime());
Instant instant1 = Instant.ofEpochMilli(jobDTO.getStartTime());
Instant instant2 = Instant.ofEpochMilli(jobDTO.getEndTime());
Duration duration = Duration.between(instant1, instant2);
jobDTO.setDuration((int) duration.toSeconds());
calculateArea(jobDTO, deviceDTO);
if (jobMapper.insert(jobDTO) > 1) {
count++;
}
}
if (count == jobSegmentRequest.getSegments().size()) {
jobMapper.deleteById(originalJobId);
}
}
}
private void calculateArea(JobDTO jobDTO, DeviceDTO deviceDTO) {
double breadth = 0;
log.info("从中农云中获取轨迹");
List<TrackItem> tracks = trackRestClient.getTracksFromZhongNong(deviceDTO.getBoxNum(), jobDTO.getStartTime(), jobDTO.getEndTime());
if (CollectionUtil.isNotEmpty(tracks)) {
for (TrackItem track : tracks) {
if (track.getBreadth() > 0) {
breadth = track.getBreadth();
break;
}
}
}
float areaByPoly = Pro4jUtil.calculateAreaByCGCS2000(tracks);
float areaByBreadth = TrackUtil.calcAreaByBlockData(tracks, breadth);
log.info("作业面积:多边形计算的面积={},宽幅(当前宽幅:{})计算的面积={}", areaByPoly, breadth, areaByBreadth);
jobDTO.setArea(areaByBreadth);
}
@Override
public List<ChartMultiItem> getJobChart() {
LoginUser loginUser = LoginUtil.getLoginUser();
String regionPath = loginUser.getRegionPath();
if (org.apache.commons.lang3.StringUtils.isNotBlank(regionPath)) {
int level = regionPath.split("->").length;
return jobMapper.selectChart(level, regionPath);
}
return Collections.emptyList();
}
}

91
social/src/main/java/com/jiagutech/ams/service/MessageDataServiceImpl.java

@ -1,10 +1,16 @@
package com.jiagutech.ams.service;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.jiagutech.ams.mapper.DeviceMapper;
import com.jiagutech.ams.mapper.JobMapper;
import com.jiagutech.ams.model.Locus;
import com.jiagutech.ams.model.TrackDataJG;
import com.jiagutech.ams.model.TrackImageMapping;
import com.jiagutech.ams.model.UavSortie;
import com.jiagutech.ams.model.dto.DeviceDTO;
import com.jiagutech.ams.model.dto.JobDTO;
import com.jiagutech.ams.model.mapping.TrackImageMapping;
import com.jiagutech.ams.model.request.MachImage;
import com.jiagutech.ams.model.request.RealTimeData;
import com.jiagutech.ams.model.request.WorkRecord;
@ -16,7 +22,15 @@ import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Duration;
import java.time.Instant;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;
@ -30,6 +44,8 @@ public class MessageDataServiceImpl implements MessageDataService {
private final JobService jobService;
private final TrackRestClient trackRestClient;
private final JobMapper jobMapper;
private final DeviceMapper deviceMapper;
public void addRealTimeData(List<RealTimeData> realTimeDatas) {
for (RealTimeData realTimeData : realTimeDatas) {
@ -58,14 +74,85 @@ public class MessageDataServiceImpl implements MessageDataService {
}
/**
* 优先判断是否有正在作业时相匹配的记录如果有则选择结束当前作业
* 再判断是否有相匹配的自动完成的作业如果有则更新此作业数据
* 最后添加或更新不完整的完全由中农云切分的作业
*
* @param workRecords
*/
@Override
public void addWorkData(List<WorkRecord> workRecords) {
for (WorkRecord workRecord : workRecords) {
List<Locus> locus = workRecord.getLocus();
//轨迹插入
if (locus.size() > 0) {
if (!locus.isEmpty()) {
trackRestClient.saveTractor(locus);
}
String vehicleId = workRecord.getVehicleId();
DeviceDTO deviceDTO = deviceMapper.selectOne(Wrappers.query(DeviceDTO.class).eq("box_num", vehicleId));
QueryWrapper<JobDTO> wrapper = Wrappers.query();
long startBegin = workRecord.getStartAt() - 5 * 60 * 1000;
long endBegin = workRecord.getStartAt() + 5 * 60 * 1000;
wrapper.eq("device_id", deviceDTO.getId());
wrapper.gt("start_time", startBegin);
wrapper.lt("start_time", endBegin);
wrapper.orderByDesc("start_time");
wrapper.last("limit 1");
JobDTO job = jobMapper.selectOne(wrapper);
if (!ObjectUtils.isEmpty(job)) {
if (job.getStatus() == 1) {
BigDecimal b = BigDecimal.valueOf(workRecord.getWorkArea());
job.setArea(b.setScale(2, RoundingMode.HALF_UP).floatValue());
job.setEndTime(workRecord.getEndAt());
Instant instant1 = Instant.ofEpochMilli(job.getStartTime());
Instant instant2 = Instant.ofEpochMilli(workRecord.getEndAt());
Duration duration = Duration.between(instant1, instant2);
job.setDuration((int) duration.toSeconds());
job.setFinishedType(2);
job.setJobType(workRecord.getModule().intValue());
jobMapper.updateById(job);
continue;
}
if (job.getFinishedType() == 2 && job.getStatus() == 2) {
job.setEndTime(workRecord.getEndAt());
job.setArea(workRecord.getWorkArea().floatValue());
Instant instant1 = Instant.ofEpochMilli(job.getStartTime());
Instant instant2 = Instant.ofEpochMilli(workRecord.getEndAt());
Duration duration = Duration.between(instant1, instant2);
job.setDuration((int) duration.toSeconds());
jobMapper.updateById(job);
continue;
}
if (job.getFinishedType() == 1 && job.getStatus() == 2) {
job.setJobType(workRecord.getModule().intValue());
jobMapper.updateById(job);
continue;
}
if (job.getOperatorId() == null || job.getOperatorId() == 0) {
job.setEndTime(workRecord.getEndAt());
BigDecimal b = BigDecimal.valueOf(workRecord.getWorkArea());
job.setArea(b.setScale(2, RoundingMode.HALF_UP).floatValue());
jobMapper.updateById(job);
}
} else {
JobDTO jobDTO = new JobDTO();
jobDTO.setDeviceId(deviceDTO.getId());
jobDTO.setStartTime(workRecord.getStartAt());
jobDTO.setEndTime(workRecord.getEndAt());
BigDecimal b = BigDecimal.valueOf(workRecord.getWorkArea());
jobDTO.setArea(b.setScale(2, RoundingMode.HALF_UP).floatValue());
jobDTO.setStatus(2);
jobDTO.setDeptId(deviceDTO.getDeptId());
jobDTO.setJobType(workRecord.getModule().intValue());
Instant instant1 = Instant.ofEpochMilli(workRecord.getStartAt());
Instant instant2 = Instant.ofEpochMilli(workRecord.getEndAt());
Duration duration = Duration.between(instant1, instant2);
jobDTO.setDuration((int) duration.toSeconds());
jobMapper.insert(jobDTO);
}
}
}

131
social/src/main/java/com/jiagutech/ams/utils/Pro4jUtil.java

@ -0,0 +1,131 @@
package com.jiagutech.ams.utils;
import com.jiagutech.ams.model.TrackItem;
import lombok.extern.slf4j.Slf4j;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Point;
import org.locationtech.proj4j.BasicCoordinateTransform;
import org.locationtech.proj4j.CRSFactory;
import org.locationtech.proj4j.CoordinateReferenceSystem;
import org.locationtech.proj4j.ProjCoordinate;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Slf4j
public class Pro4jUtil {
/**
* 计算地理多边形的面积
*
* @param polygonLatLon 多边形顶点的经纬度数组格式{{纬度1, 经度1}, {纬度2, 经度2}, ...}
* @param targetEPSG 平面投影的 EPSG 编号例如 "EPSG:32633" 表示 UTM Zone 33N
* @return 多边形面积单位为平方米
*/
public static double calculatePolygonArea(double[][] polygonLatLon, String sourceEPSG, String targetEPSG) {
// 1. 初始化投影系统
CRSFactory crsFactory = new CRSFactory();
CoordinateReferenceSystem sourceCRS = crsFactory.createFromName(sourceEPSG);
CoordinateReferenceSystem targetCRS = crsFactory.createFromName(targetEPSG); // 平面投影
log.info("sourceCRS: {}, targetCRS: {}", sourceCRS, targetCRS);
// 2. 初始化坐标转换器
BasicCoordinateTransform transform = new BasicCoordinateTransform(sourceCRS, targetCRS);
// 3. 转换多边形的经纬度为平面坐标
ProjCoordinate srcCoord = new ProjCoordinate();
ProjCoordinate destCoord = new ProjCoordinate();
double[][] polygonXY = new double[polygonLatLon.length][2];
for (int i = 0; i < polygonLatLon.length; i++) {
srcCoord.x = polygonLatLon[i][1]; // 经度
srcCoord.y = polygonLatLon[i][0]; // 纬度
transform.transform(srcCoord, destCoord);
polygonXY[i][0] = destCoord.x;
polygonXY[i][1] = destCoord.y;
}
// 4. 确保多边形闭合
if (!Arrays.equals(polygonXY[0], polygonXY[polygonXY.length - 1])) {
polygonXY = Arrays.copyOf(polygonXY, polygonXY.length + 1);
polygonXY[polygonXY.length - 1] = polygonXY[0];
}
// 4. 计算多边形面积
return calculateAreaFromXY(polygonXY);
}
/**
* 使用 Shoelace 公式计算平面多边形的面积
*
* @param polygonXY 多边形顶点的平面坐标数组格式{{x1, y1}, {x2, y2}, ...}
* @return 多边形面积单位与坐标单位一致
*/
private static double calculateAreaFromXY(double[][] polygonXY) {
double area = 0.0;
int n = polygonXY.length;
for (int i = 0; i < n - 1; i++) {
area += polygonXY[i][0] * polygonXY[i + 1][1] - polygonXY[i + 1][0] * polygonXY[i][1];
}
area = Math.abs(area) / 2.0;
return area;
}
public static float calculateAreaByCGCS2000(List<TrackItem> trackItemList) {
double[][] polygonLatLon = new double[trackItemList.size()][2];
for (int i = 0; i < trackItemList.size(); i++) {
polygonLatLon[i][0] = trackItemList.get(i).getLat();
polygonLatLon[i][1] = trackItemList.get(i).getLng();
}
double area = calculatePolygonArea(polygonLatLon, "EPSG:4490", "EPSG:4543");
area = area * 0.0015;
BigDecimal b = new BigDecimal(area);
return b.setScale(2, RoundingMode.HALF_UP).floatValue();
}
public static double haversineDistance(double lat1, double lon1, double lat2, double lon2) {
GeometryFactory geometryFactory = new GeometryFactory();
Coordinate coord1 = fromLatLngToPoint(lat1, lon1);
Coordinate coord2 = fromLatLngToPoint(lat2, lon2);
Point point1 = geometryFactory.createPoint(coord1);
Point point2 = geometryFactory.createPoint(coord2);
return point1.distance(point2);
}
private static final double DEG_TO_RAD = Math.PI / 180;
public static Coordinate fromLatLngToPoint(double lat, double lng) {
double x = lng * 20037508.34 / 180;
double y = Math.log(Math.tan((90 + lat) * DEG_TO_RAD / 2)) / DEG_TO_RAD;
y = y * 20037508.34 / 180;
return new Coordinate(x, y);
}
public static List<TrackItem> removeStationaryPoints(List<TrackItem> points, double threshold) {
List<TrackItem> filteredPoints = new ArrayList<>();
filteredPoints.add(points.get(0));
for (int i = 1; i < points.size(); i++) {
TrackItem previousPoint = points.get(i - 1);
TrackItem currentPoint = points.get(i);
double distance = haversineDistance(previousPoint.getLat(), previousPoint.getLng(), currentPoint.getLat(), currentPoint.getLng());
if (distance >= threshold) {
filteredPoints.add(currentPoint);
}
}
return filteredPoints;
}
}

30
social/src/main/resources/mapper/DeviceMapper.xml

@ -45,4 +45,34 @@
${ew.getCustomSqlSegment}
</select>
<select id="deivcePage" resultType="com.jiagutech.ams.model.dto.DeviceDTO">
select d.*,dp.name as deptName from ams_device_info d left join ams_dept dp on d.dept_id = dp.id
${ew.getCustomSqlSegment}
</select>
<select id="selectChart" resultType="com.jiagutech.ams.model.response.ChartItem">
<if test="level &lt; 3">
select
p.region_code as code,
i.region_name as name,
count(d.id) as count
from ams_device_info d
left join
ams_dept p on d.dept_id = p.id
left join region_info i
on p.region_code=i.region_code
where p.region_path like concat(#{regionPath},'%')
group by p.region_code,i.region_name
</if>
<if test="level == 3">
select
p.id as code,
p.name,
count(d.id) as count
from ams_device_info d
left join
ams_dept p on d.dept_id = p.id
where p.region_path like concat(#{regionPath},'%')
group by p.id,p.name
</if>
</select>
</mapper>

38
social/src/main/resources/mapper/JobMapper.xml

@ -14,6 +14,7 @@
dd.box_num,
j.operator_id,
j.duration,
j.finished_type,
FROM_UNIXTIME(j.start_time / 1000, '%Y-%m-%d %H:%i:%s') as start_time_str,
u1.nick_name as operator_name,
u1.phone as operator_phone,
@ -73,7 +74,7 @@
${ew.getCustomSqlSegment} order by j.farmer_id,j.start_time
</select>
<select id="inJob">
<select id="inJob" resultType="com.jiagutech.ams.model.response.JobItem">
select j.id as job_id,
j.start_time,
j.end_time,
@ -117,8 +118,39 @@
group by j.farmer_id, j.job_type, t.name, d.id, d.name, u2.nick_name
order by j.farmer_id, j.job_type
</select>
<select id="inProcessJob" resultType="com.jiagutech.ams.model.dto.JobDTO">
select j.*
from ams_job_info j
left join ams_device_info d on d.id = j.device_id
${ew.getCustomSqlSegment}
order by j.start_time desc
</select>
<select id="selectChart" resultType="com.jiagutech.ams.model.response.ChartMultiItem">
<if test="level &lt; 3">
select
d.region_code as code,
i.region_name as name,
count(j.id) as count,
ROUND(sum(j.area), 2) as value
from ams_job_info j
left join ams_dept d on j.dept_id = d.id
left join region_info i
on d.region_code=i.region_code
where d.region_path like concat(#{regionPath},'%')
group by d.region_code,i.region_name
</if>
<if test="level == 3">
select
d.id as code,
d.name,
count(j.id) as count,
ROUND(sum(j.area), 2) as value
from ams_job_info j
left join ams_dept d on j.dept_id = d.id
where d.region_path like concat(#{regionPath},'%')
group by d.id,d.name
</if>
</select>
</mapper>

8
system/src/main/java/com/jiagutech/ams/controller/DeptController.java

@ -5,6 +5,7 @@ import com.jiagutech.ams.model.DeptItem;
import com.jiagutech.ams.model.common.PageRequest;
import com.jiagutech.ams.model.common.PageResult;
import com.jiagutech.ams.model.common.R;
import com.jiagutech.ams.model.request.DeptAddRequest;
import com.jiagutech.ams.model.request.DeptPageRequest;
import com.jiagutech.ams.service.DeptService;
import io.swagger.v3.oas.annotations.tags.Tag;
@ -31,4 +32,11 @@ public class DeptController {
return R.ok(deptService.selectPage(pageRequest));
}
@SaCheckRole("gov")
@PutMapping("/add")
public R<Boolean> selectById(@RequestBody DeptAddRequest deptAddRequest) {
return deptService.add(deptAddRequest) ? R.ok() : R.fail("添加合作社失败");
}
}

11
system/src/main/java/com/jiagutech/ams/controller/UserController.java

@ -6,10 +6,7 @@ import com.jiagutech.ams.model.LoginUser;
import com.jiagutech.ams.model.common.PageRequest;
import com.jiagutech.ams.model.common.PageResult;
import com.jiagutech.ams.model.common.R;
import com.jiagutech.ams.model.request.LoginRequest;
import com.jiagutech.ams.model.request.PageUserRequest;
import com.jiagutech.ams.model.request.UserFarmerRequest;
import com.jiagutech.ams.model.request.UserRequest;
import com.jiagutech.ams.model.request.*;
import com.jiagutech.ams.model.response.LoginResponse;
import com.jiagutech.ams.model.UserDetail;
import com.jiagutech.ams.service.UserService;
@ -50,6 +47,12 @@ public class UserController {
userService.addUser(user);
return R.ok();
}
@Operation(summary = "添加农户")
@PostMapping("/addFarmer")
public R<Void> addFarmer(@Validated @RequestBody FarmerAddRequest farmerAddRequest) {
return userService.addFarmer(farmerAddRequest)? R.ok():R.fail("添加农户失败");
}
@Operation(summary = "获取用户登陆信息")
@GetMapping("/getUserInfo")

21
system/src/main/java/com/jiagutech/ams/model/request/DeptAddRequest.java

@ -0,0 +1,21 @@
package com.jiagutech.ams.model.request;
import lombok.Data;
@Data
public class DeptAddRequest {
/**
* 合作社名称
*/
private String deptName;
/**
* 合作社负责人ID
*/
private String managerName ;
private String managerPhone;
private String managerPassword;
}

17
system/src/main/java/com/jiagutech/ams/model/request/FarmerAddRequest.java

@ -0,0 +1,17 @@
package com.jiagutech.ams.model.request;
import jakarta.validation.constraints.Pattern;
import lombok.Data;
@Data
public class FarmerAddRequest {
private String nickName;
@Pattern(regexp = "^1[34578]\\d{9}$", message = "手机号码格式不正确")
private String phone;
private String identityCardNum;
private Long regionCode;
}

2
system/src/main/java/com/jiagutech/ams/model/request/UserRequest.java

@ -34,8 +34,6 @@ public class UserRequest {
* 用户账号
*/
@JsonIgnore
//@NotBlank(message = "用户账号不能为空")
@Size(min = 0, max = 30, message = "用户账号长度不能超过{max}个字符")
private String userName;
/**

42
system/src/main/java/com/jiagutech/ams/service/DeptServcieImpl.java

@ -1,42 +0,0 @@
package com.jiagutech.ams.service;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jiagutech.ams.constant.UserConstants;
import com.jiagutech.ams.mapper.DeptMapper;
import com.jiagutech.ams.model.DeptItem;
import com.jiagutech.ams.model.LoginUser;
import com.jiagutech.ams.model.common.PageRequest;
import com.jiagutech.ams.model.common.PageResult;
import com.jiagutech.ams.model.request.DeptPageRequest;
import com.jiagutech.ams.utils.LoginUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
/**
* @ClassName DeptServcieImpl
* @author: zhangyeguang
* @create: 2024-09-02 17:35
* @Version 1.0
* @description:
**/
@Service
@RequiredArgsConstructor
public class DeptServcieImpl implements DeptService {
private final DeptMapper deptMapper;
@Override
public PageResult<DeptItem> selectPage(PageRequest<DeptPageRequest> pageRequest) {
DeptPageRequest requestParam = pageRequest.getRequest();
Page<DeptItem> page = new Page(pageRequest.getPageNum(), pageRequest.getPageSize());
LoginUser loginUser = LoginUtil.getLoginUser();
Page<DeptItem> result = deptMapper.deptPage(page,requestParam!=null ?requestParam.getDeptName():null, loginUser.getRegionPath());
return PageResult.of((int) result.getTotal(), (int) result.getSize(), (int) result.getCurrent(), result.getRecords());
}
}

3
system/src/main/java/com/jiagutech/ams/service/DeptService.java

@ -3,6 +3,7 @@ package com.jiagutech.ams.service;
import com.jiagutech.ams.model.DeptItem;
import com.jiagutech.ams.model.common.PageRequest;
import com.jiagutech.ams.model.common.PageResult;
import com.jiagutech.ams.model.request.DeptAddRequest;
import com.jiagutech.ams.model.request.DeptPageRequest;
/**
@ -14,4 +15,6 @@ import com.jiagutech.ams.model.request.DeptPageRequest;
**/
public interface DeptService {
PageResult<DeptItem> selectPage(PageRequest<DeptPageRequest> pageRequest);
Boolean add(DeptAddRequest deptAddRequest);
}

75
system/src/main/java/com/jiagutech/ams/service/DeptServiceImpl.java

@ -0,0 +1,75 @@
package com.jiagutech.ams.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jiagutech.ams.mapper.DeptMapper;
import com.jiagutech.ams.mapper.UserDeptMapper;
import com.jiagutech.ams.mapper.UserMapper;
import com.jiagutech.ams.model.DeptItem;
import com.jiagutech.ams.model.LoginUser;
import com.jiagutech.ams.model.common.PageRequest;
import com.jiagutech.ams.model.common.PageResult;
import com.jiagutech.ams.model.dto.DeptDTO;
import com.jiagutech.ams.model.dto.UserDTO;
import com.jiagutech.ams.model.dto.UserDeptDTO;
import com.jiagutech.ams.model.request.DeptAddRequest;
import com.jiagutech.ams.model.request.DeptPageRequest;
import com.jiagutech.ams.utils.LoginUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* @author zhangyeguang
* @version 1.0
* @ClassName DeptServcieImpl
* @create: 2024-09-02 17:35
* @description:
**/
@Service
@RequiredArgsConstructor
public class DeptServiceImpl implements DeptService {
private final DeptMapper deptMapper;
private final UserDeptMapper userDeptMapper;
private final UserMapper userMapper;
@Override
public PageResult<DeptItem> selectPage(PageRequest<DeptPageRequest> pageRequest) {
DeptPageRequest requestParam = pageRequest.getRequest();
Page<DeptItem> page = new Page(pageRequest.getPageNum(), pageRequest.getPageSize());
LoginUser loginUser = LoginUtil.getLoginUser();
Page<DeptItem> result = deptMapper.deptPage(page, requestParam != null ? requestParam.getDeptName() : null, loginUser.getRegionPath());
return PageResult.of((int) result.getTotal(), (int) result.getSize(), (int) result.getCurrent(), result.getRecords());
}
@Override
@Transactional
public Boolean add(DeptAddRequest deptAddRequest) {
LoginUser loginUser = LoginUtil.getLoginUser();
assert loginUser != null;
DeptDTO deptDTO = new DeptDTO().setName(deptAddRequest.getDeptName())
.setRegionCode(loginUser.getRegionCode())
.setRegionPath(loginUser.getRegionPath());
int row = deptMapper.insert(deptDTO);
if (row > 0) {
UserDTO userDTO = new UserDTO();
userDTO.setPassword(deptAddRequest.getManagerPassword());
userDTO.setNickName(deptAddRequest.getManagerName());
userDTO.setPhone(deptAddRequest.getManagerPhone());
int insert = userMapper.insert(userDTO);
if (insert > 0) {
UserDeptDTO userDeptDTO = new UserDeptDTO();
userDeptDTO.setDeptId(deptDTO.getId());
userDeptDTO.setUserId(userDTO.getId());
userDeptMapper.insert(userDeptDTO);
return true;
}
}
return false;
}
}

7
system/src/main/java/com/jiagutech/ams/service/UserService.java

@ -4,10 +4,7 @@ package com.jiagutech.ams.service;
import com.jiagutech.ams.model.UserDetail;
import com.jiagutech.ams.model.common.PageRequest;
import com.jiagutech.ams.model.common.PageResult;
import com.jiagutech.ams.model.request.LoginRequest;
import com.jiagutech.ams.model.request.PageUserRequest;
import com.jiagutech.ams.model.request.UserFarmerRequest;
import com.jiagutech.ams.model.request.UserRequest;
import com.jiagutech.ams.model.request.*;
import com.jiagutech.ams.model.response.LoginResponse;
import java.util.List;
@ -29,4 +26,6 @@ public interface UserService {
PageResult<UserDetail> getUserPage(PageRequest<PageUserRequest> pageRequest);
List<UserDetail> getAllFarmersByRegionCode(Long regionCode,String nickName);
boolean addFarmer(FarmerAddRequest farmerAddRequest);
}

32
system/src/main/java/com/jiagutech/ams/service/UserServiceImpl.java

@ -28,10 +28,7 @@ import com.jiagutech.ams.model.dto.RoleDTO;
import com.jiagutech.ams.model.dto.UserDTO;
import com.jiagutech.ams.model.dto.UserDeptDTO;
import com.jiagutech.ams.model.dto.UserRoleDTO;
import com.jiagutech.ams.model.request.LoginRequest;
import com.jiagutech.ams.model.request.PageUserRequest;
import com.jiagutech.ams.model.request.UserFarmerRequest;
import com.jiagutech.ams.model.request.UserRequest;
import com.jiagutech.ams.model.request.*;
import com.jiagutech.ams.model.response.LoginResponse;
import com.jiagutech.ams.utils.LoginUtil;
import lombok.RequiredArgsConstructor;
@ -72,16 +69,11 @@ public class UserServiceImpl implements UserService {
if (loginRequest.getClientType() == 1) {
validateCaptcha(code, uuid);
}
Integer clientType = loginRequest.getClientType();
LoginUser user = userMapper.selectLoginUserByPhone(phone);
if (user == null) {
throw new BusinessException(BizCode.USER_NOT_FOUND);
}
Predicate<RoleDTO> predicate = role -> role.getKey().equals("admin") || role.getKey().equals("manager") || role.getKey().equals("machinist");
if (clientType == 2 && user.getRoles().stream().noneMatch(predicate)) {
throw new BusinessException(BizCode.LOGIN_TYPE_ERROR);
}
boolean checkpw = BCrypt.checkpw(password, user.getPassword());
if (!checkpw) {
throw new BusinessException(BizCode.PASSWORD_ERROR);
@ -108,7 +100,7 @@ public class UserServiceImpl implements UserService {
public void addUser(UserRequest userRequest) {
UserDTO userDTO = UserMapping.INSTANCE.userToUserDTO(userRequest);
userDTO.setId(null);
userDTO.setPassword(BCrypt.hashpw(userRequest.getPassword()));
userDTO.setPassword(BCrypt.hashpw(userRequest.getPassword()));
if (userDTO.getRegionCode() != null && userDTO.getRegionCode() != 0l) {
RegionVO completeRegionInfo = regionMapper.getCompleteRegionInfo(userDTO.getRegionCode());
if (completeRegionInfo != null) {
@ -242,4 +234,24 @@ public class UserServiceImpl implements UserService {
throw new BusinessException(BizCode.CAPTCHA_ERROR);
}
}
@Override
public boolean addFarmer(FarmerAddRequest farmerAddRequest) {
UserDTO userDTO = new UserDTO();
userDTO.setPhone(farmerAddRequest.getPhone());
userDTO.setNickName(farmerAddRequest.getNickName());
userDTO.setIdentityCardNum(farmerAddRequest.getIdentityCardNum());
userDTO.setRegionCode(farmerAddRequest.getRegionCode());
if (userDTO.getRegionCode() != null && userDTO.getRegionCode() != 0L) {
RegionVO completeRegionInfo = regionMapper.getCompleteRegionInfo(userDTO.getRegionCode());
if (completeRegionInfo != null) {
userDTO.setRegionPath(completeRegionInfo.getRegionCode());
userDTO.setRegionName(completeRegionInfo.getRegionName());
}
}
userMapper.insert(userDTO);
insertUserRoleAndDept(userDTO, "farmer", 0L);
return false;
}
}

4
system/src/main/resources/mapper/UserMapper.xml

@ -28,9 +28,9 @@
avatar,
region_path,
region_name
from ams_user
from ams_user u
where phone = #{phone}
and del_flag = 0
and del_flag = 0 and exists(select 1 from ams_user_role ur where ur.user_id = u.id and ur.role_id != 5)
</select>
<select id="selectUserDetail" resultMap="UserDetailResult">
select id as user_id,

2
web/src/main/java/com/jiagutech/ams/SocialApplication.java

@ -9,7 +9,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
* @ClassName SocialApplication
* @author: zhangyeguang
* @create: 2024-08-30 14:26
* @Version 1.0
* @version 1.0
* @description:
**/
@EnableAsync

7
web/src/main/java/com/jiagutech/ams/common/GlobalExceptionHandler.java

@ -58,7 +58,7 @@ public class GlobalExceptionHandler {
@ExceptionHandler(NotLoginException.class)
public ResponseEntity<R> handleLoginException(Exception ex) {
log.error("系统异常", ex);
log.error("认证失败", ex);
return new ResponseEntity<>(R.fail(BizCode.USER_NOT_LOGIN.getCode(), BizCode.USER_NOT_LOGIN.getMsg()), HttpStatus.UNAUTHORIZED);
}
@ -73,4 +73,9 @@ public class GlobalExceptionHandler {
log.error("数据重复", ex);
return new ResponseEntity<>(R.fail(BizCode.USER_PHONE_EXIST.getCode(), BizCode.USER_PHONE_EXIST.getMsg()), HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<R> handleCustomException(Exception ex) {
log.error("服务器异常", ex);
return new ResponseEntity<>(R.fail(BizCode.ServerError.getCode(), BizCode.ServerError.getMsg()), HttpStatus.BAD_REQUEST);
}
}

46
web/src/main/java/com/jiagutech/ams/config/CommonInterceptor.java

@ -0,0 +1,46 @@
package com.jiagutech.ams.config;
import com.jiagutech.ams.utils.TraceIdUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@Slf4j
@Component
public class CommonInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler) throws Exception {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
request.setAttribute("stopWatch", stopWatch);
String traceId = TraceIdUtil.generateTraceId();
TraceIdUtil.setTraceId(traceId);
// 将 traceId 放入 MDC,供日志打印
MDC.put("traceId", traceId);
return true;
}
@Override
public void postHandle(HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler, ModelAndView modelAndView) throws Exception {
StopWatch stopWatch = (StopWatch) request.getAttribute("stopWatch");
stopWatch.stop();
log.info("path={}处理完成,耗时={}ms", request.getRequestURI(), stopWatch.getTotalTimeMillis());
TraceIdUtil.clear();
MDC.remove("traceId");
}
@Override
public void afterCompletion(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler, Exception ex) throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}

1
web/src/main/java/com/jiagutech/ams/config/SaPermissionImpl.java

@ -10,7 +10,6 @@ import java.util.List;
/**
* sa-token 权限管理实现类
*
* @author Lion Li
*/
public class SaPermissionImpl implements StpInterface {

9
web/src/main/java/com/jiagutech/ams/config/SaTokenConfigure.java

@ -1,16 +1,21 @@
package com.jiagutech.ams.config;
import cn.dev33.satoken.interceptor.SaInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {
// 注册 Sa-Token 拦截器,打开注解式鉴权功能
@Autowired
private CommonInterceptor commonInterceptor;
// 注册 Sa-Token 拦截器,打开注解式鉴权功能
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册 Sa-Token 拦截器,打开注解式鉴权功能
registry.addInterceptor(new SaInterceptor()).addPathPatterns("/**");
registry.addInterceptor(new SaInterceptor()).order(10).addPathPatterns("/**");
registry.addInterceptor(commonInterceptor).order(-999).addPathPatterns("/**");
}
}

2
web/src/main/resources/logback-spring.xml

@ -7,7 +7,7 @@
<!-- Example for logging into the build folder of your project -->
<property name="LOG_FILE" value="log"/>
<property name="LOG_PATTERN"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%.-5level) -- %X{traceId:-} -- [%10.10t] %cyan(%-36.36logger{32}) : %m%n"/>
value="%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%.-5level) - %X{traceId:-} - [%10.10t] %cyan(%-36.36logger{32}) : %m%n"/>
<!-- Appender to log to console -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">

Loading…
Cancel
Save