diff --git a/README.md b/README.md index 7578fe3..a5ad77e 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,18 @@ # ams-social +- 框架/依赖说明 + - JDK17 + - SpringBoot 3.1.7 + - sa-token 登陆认证 + - mapstruct、orika 对象拷贝 + - mybatis-plus 数据持久化 + - easy-excel excel导入导出 + - hikari 数据库连接池 + - openapi 注解生成接口文档 + - rabbitmq 消息队列 + - redis 缓存 + - actuator/prometheus 监控 + - huawei obs 对象存储 + - fastjson2/gson/jackson json + - maven-pmd-plugin 静态代码检查插件 +- 功能说明 \ No newline at end of file diff --git a/social/pom.xml b/social/pom.xml index fb16e35..6fe0db3 100644 --- a/social/pom.xml +++ b/social/pom.xml @@ -104,7 +104,11 @@ mapstruct-processor provided - + + com.huaweicloud + esdk-obs-java + 3.20.6.1 + \ No newline at end of file diff --git a/social/src/main/java/com/jiagutech/ams/controller/JobController.java b/social/src/main/java/com/jiagutech/ams/controller/JobController.java index 5e394cd..22bde56 100644 --- a/social/src/main/java/com/jiagutech/ams/controller/JobController.java +++ b/social/src/main/java/com/jiagutech/ams/controller/JobController.java @@ -3,27 +3,31 @@ package com.jiagutech.ams.controller; import cn.dev33.satoken.annotation.SaCheckRole; import cn.dev33.satoken.annotation.SaMode; import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.map.MapUtil; +import com.jiagutech.ams.listener.JobFinishListener; import com.jiagutech.ams.model.TrackImageVO; import com.jiagutech.ams.model.TrackItem; 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.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.JobStatusRequest; import com.jiagutech.ams.model.response.JobCreateResponse; import com.jiagutech.ams.model.response.JobItem; -import com.jiagutech.ams.model.response.JobTypeItem; import com.jiagutech.ams.service.JobService; +import com.jiagutech.ams.utils.TrackUtil; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; +import org.apache.commons.collections4.MapUtils; import org.springframework.web.bind.annotation.*; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * @ClassName JobController @@ -39,6 +43,8 @@ import java.util.List; public class JobController { private final JobService jobService; + private final JobFinishListener jobFinishListener; + @GetMapping("/types") @Operation(summary = "作业类型列表") public R> getJobTypes() { @@ -75,13 +81,13 @@ public class JobController { } - @PostMapping(value = "/export",consumes = "application/json") + @PostMapping(value = "/export", consumes = "application/json") @Operation(summary = "导出作业记录") public void exportJobs(@RequestBody(required = false) JobPageRequest jobPageRequest, HttpServletResponse response) { jobService.exportJobs(jobPageRequest, response); } - @PostMapping(value = "/exportByFarmer",consumes = "application/json") + @PostMapping(value = "/exportByFarmer", consumes = "application/json") @Operation(summary = "导出作业记录") public void exportByFarmer(@RequestBody(required = false) JobPageRequest jobPageRequest, HttpServletResponse response) { jobService.exportByFarmer(jobPageRequest, response); @@ -100,5 +106,39 @@ public class JobController { return R.ok(); } + @GetMapping("/tracksByZhongnong") + @Operation(summary = "从中农云获取作业轨迹列表") + public R> getTracksByZhongnongList(@RequestParam("deviceId") String deviceId, + @RequestParam long startTime, + @RequestParam long endTime) { + + return R.ok(jobFinishListener.getTracks(deviceId, startTime, endTime)); + } + + @GetMapping("/countAreaByZhongnong/{jobId}") + @Operation(summary = "从中农云获取轨迹计算面积") + public R countAreaByZhongnong(@PathVariable("jobId") Long jobId) { + jobFinishListener.refreshJobArea(jobId); + return R.ok(); + } + + @GetMapping("/calcAreaByZhongnong") + @Operation(summary = "重新计算面积") + public R calcAreaByZhongnong(@RequestParam("deviceId") String deviceId, + @RequestParam long startTime, + @RequestParam long endTime, + @RequestParam float breadth) { + + List tracks = jobService.getTracks(deviceId, startTime, endTime); + List tracks1 = jobFinishListener.getTracks(deviceId, startTime, endTime); + float noFilter = TrackUtil.calcAreaByBlockDataNoFilter(tracks,breadth); + float byFilter = TrackUtil.calcAreaByBlockData(tracks); + float zhongnongArea = TrackUtil.calcAreaByBlockDataNoFilter(tracks1,breadth); + Map areas = new HashMap<>(4); + areas.put("noFilter", noFilter); + areas.put("byFilter", byFilter); + areas.put("zhongnongArea", zhongnongArea); + return R.ok(areas); + } } diff --git a/social/src/main/java/com/jiagutech/ams/controller/MessageDataController.java b/social/src/main/java/com/jiagutech/ams/controller/MessageDataController.java new file mode 100644 index 0000000..5c87aa2 --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/controller/MessageDataController.java @@ -0,0 +1,48 @@ +package com.jiagutech.ams.controller; + +import com.alibaba.fastjson2.JSONObject; +import com.jiagutech.ams.model.common.R; +import com.jiagutech.ams.model.request.MachImage; +import com.jiagutech.ams.model.request.RealTimeData; +import com.jiagutech.ams.model.request.WorkRecord; +import com.jiagutech.ams.service.MessageDataService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@Slf4j +@RestController +@RequiredArgsConstructor +@RequestMapping("/MessageDataService") +public class MessageDataController { + + private final MessageDataService messageDataService; + + @PostMapping("/machineryRealtimeData") + public R addRealTimeData(@RequestBody List realTimeDatas) { + //if (checkSign(request,response)) { + log.info("RealTimeData:{}", JSONObject.toJSONString(realTimeDatas)); + messageDataService.addRealTimeData(realTimeDatas); + return R.ok("success"); + + } + + @PostMapping(value = "/machineryImage", consumes = "multipart/form-data") + public R machineryImage(@ModelAttribute MachImage machImage) { + + log.info("workRecord:{}", machImage.getVehicleId()); + messageDataService.machineryImage(machImage); + return R.ok("success"); + + } + + @PostMapping("/machineryAreaDataList") + public R addWorkData(@RequestBody List workRecords) { + log.info("WorkRecord:{}", JSONObject.toJSONString(workRecords)); + messageDataService.addWorkData(workRecords); + + return R.ok("success"); + } +} diff --git a/social/src/main/java/com/jiagutech/ams/listener/JobFinishListener.java b/social/src/main/java/com/jiagutech/ams/listener/JobFinishListener.java index 8b39958..658b28d 100644 --- a/social/src/main/java/com/jiagutech/ams/listener/JobFinishListener.java +++ b/social/src/main/java/com/jiagutech/ams/listener/JobFinishListener.java @@ -5,21 +5,28 @@ 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.ZhongNongTrack; import com.jiagutech.ams.model.dto.DeviceDTO; import com.jiagutech.ams.model.dto.JobDTO; +import com.jiagutech.ams.rest.TrackRestClient; +import com.jiagutech.ams.rest.ZhongNongRestClient; import com.jiagutech.ams.scheduled.JobScheduled; import com.jiagutech.ams.service.JobService; -import com.jiagutech.ams.utils.FlightTrackerUtils; +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; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; import java.time.Duration; import java.time.Instant; -import java.time.LocalDateTime; -import java.time.ZoneId; import java.util.List; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -36,11 +43,18 @@ import java.util.concurrent.TimeUnit; @Component @RequiredArgsConstructor public class JobFinishListener { - private final JobService jobService; private final JobMapper jobMapper; private final DeviceMapper deviceMapper; private final ScheduledExecutorService taskScheduler = Executors.newScheduledThreadPool(1); - private final JobScheduled jobScheduled; + 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) public void finishJob(JobFinishEvent event) { @@ -53,12 +67,66 @@ public class JobFinishListener { Instant instant2 = Instant.ofEpochMilli(endTime); Duration duration = Duration.between(instant1, instant2); jobDTO.setDuration((int) duration.toSeconds()); - jobMapper.updateById(jobDTO); - jobScheduled.handleArea(jobDTO, 0); + taskScheduler.schedule(() -> handleArea(jobDTO), 30, TimeUnit.SECONDS); + + } catch (Exception e) { throw new RuntimeException(e); } } + public List getTracks(String deviceId, long startTime, long endTime) { + + List trackList = getTracksFromZhongNong(deviceId, startTime, endTime); + log.info("tracks length={}", trackList.size()); + return trackList; + } + + public void refreshJobArea(long jobId) { + JobDTO jobDTO = jobMapper.selectById(jobId); + if ((jobDTO.getDuration()==null ||jobDTO.getDuration() == 0) && jobDTO.getStartTime() != null && jobDTO.getEndTime() != null) { + Instant instant1 = Instant.ofEpochMilli(jobDTO.getStartTime()); + Instant instant2 = Instant.ofEpochMilli(jobDTO.getEndTime()); + Duration duration = Duration.between(instant1, instant2); + jobDTO.setDuration((int) duration.toSeconds()); + } + handleArea(jobDTO); + + } + + public void handleArea(JobDTO jobDTO) { + log.info("job:{},去获取轨迹计算作业面积", jobDTO.getId()); + DeviceDTO deviceDTO = deviceMapper.selectById(jobDTO.getDeviceId()); + log.info("从td-engine中获取轨迹"); + List tracks = jobService.getTracks(deviceDTO.getBoxNum(), jobDTO.getStartTime(), jobDTO.getEndTime()); + if (CollectionUtil.isEmpty(tracks)) { + log.info("从中农云中获取轨迹"); + tracks = getTracksFromZhongNong(deviceDTO.getBoxNum(), jobDTO.getStartTime(), jobDTO.getEndTime()); + } + jobDTO.setArea(TrackUtil.calcAreaByBlockData(tracks)); + TrackItem trackItem = tracks.get(tracks.size() - 1); + jobDTO.setLat(trackItem.getLat()).setLng(trackItem.getLng()); + deviceDTO.setLat(trackItem.getLat()).setLng(trackItem.getLng()).setUpdateTime(trackItem.getTimestamp()); + deviceMapper.updateById(deviceDTO); + jobMapper.updateById(jobDTO); + + } + + private List getTracksFromZhongNong(String vehicleId, Long startTime, Long endTime) { + List tracks = trackRestClient.getZhongNongTracks(keyId, secretKey, vehicleId, startTime, endTime); + log.info("中农云获取到的轨迹数量:{}", tracks != null ? tracks.size() : 0); + TrackMapping mapping = TrackMapping.INSTANCE; + return mapping.convertToTrackItemsByZhongNongTracks(tracks); + } + + + @SneakyThrows + private String signature(String keyId, long timestamp, String secretKey) { + MessageDigest md = MessageDigest.getInstance("MD5"); + String str = "keyId=" + keyId + "×tamp=" + timestamp + "&secretKey=" + secretKey; + byte[] digest = md.digest(str.getBytes(StandardCharsets.UTF_8)); + return Hex.encodeHexString(digest); + } + } diff --git a/social/src/main/java/com/jiagutech/ams/model/TrackImageMapping.java b/social/src/main/java/com/jiagutech/ams/model/TrackImageMapping.java new file mode 100644 index 0000000..f732927 --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/model/TrackImageMapping.java @@ -0,0 +1,15 @@ +package com.jiagutech.ams.model; + +import com.jiagutech.ams.model.request.MachImage; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface TrackImageMapping { + + TrackImageMapping INTANCE = Mappers.getMapper(TrackImageMapping.class); + + + TrackImageVO convertByMachImage(MachImage machImage); + +} \ No newline at end of file diff --git a/social/src/main/java/com/jiagutech/ams/model/TrackItem.java b/social/src/main/java/com/jiagutech/ams/model/TrackItem.java index 1820674..b07cc72 100644 --- a/social/src/main/java/com/jiagutech/ams/model/TrackItem.java +++ b/social/src/main/java/com/jiagutech/ams/model/TrackItem.java @@ -26,6 +26,8 @@ public class TrackItem { private Float seeding; + private Double breadth; + private String imageUrl; diff --git a/social/src/main/java/com/jiagutech/ams/model/TrackMapping.java b/social/src/main/java/com/jiagutech/ams/model/TrackMapping.java index 4713eb4..7bc9924 100644 --- a/social/src/main/java/com/jiagutech/ams/model/TrackMapping.java +++ b/social/src/main/java/com/jiagutech/ams/model/TrackMapping.java @@ -4,8 +4,14 @@ import com.jiagutech.ams.model.dto.TrackImageDTO; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.Mappings; +import org.mapstruct.Named; import org.mapstruct.factory.Mappers; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; +import java.util.List; + @Mapper public interface TrackMapping { @@ -20,5 +26,21 @@ public interface TrackMapping { TrackItem convertToTrackItemByLocus(Locus track); + @Mappings(value = { + @Mapping(target = "timestamp", source = "sendTime",qualifiedByName = "timeStrToLong"), + @Mapping(target = "lng", source = "longitude"), + @Mapping(target = "lat", source = "latitude") + }) + TrackItem convertToTrackItemByZhongNongTrack(ZhongNongTrack track); + + List convertToTrackItemsByZhongNongTracks(List zhongNongTrack); + @Named("timeStrToLong") + default Long timeStrToLong(String timeStr) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + LocalDateTime localDateTime = LocalDateTime.parse(timeStr, formatter); + return localDateTime.toInstant(ZoneOffset.ofHours(8)).toEpochMilli(); // 使用UTC+8的时区偏移量 + } + + List convertToTrackItemsByLocus(List locusList); } diff --git a/social/src/main/java/com/jiagutech/ams/model/ZhongNongTrack.java b/social/src/main/java/com/jiagutech/ams/model/ZhongNongTrack.java new file mode 100644 index 0000000..5a6ddcb --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/model/ZhongNongTrack.java @@ -0,0 +1,20 @@ +package com.jiagutech.ams.model; + +import lombok.Data; + +@Data +public class ZhongNongTrack { + + private String simNo; + + private String sendTime; + + private Float velocity; + + private Double latitude; + + private Double longitude; + + private Integer direction; + +} diff --git a/social/src/main/java/com/jiagutech/ams/model/request/MachImage.java b/social/src/main/java/com/jiagutech/ams/model/request/MachImage.java new file mode 100644 index 0000000..75dfa50 --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/model/request/MachImage.java @@ -0,0 +1,21 @@ +package com.jiagutech.ams.model.request; + +import lombok.Data; +import org.springframework.web.multipart.MultipartFile; + +@Data +public class MachImage { + + // 设备Id + private String vehicleId; + // 时间戳 + private long timestamp; + // 纬度,最多保留7位小数(CGCS2000 坐标系) + private double lat; + // 经度,最多保留7位小数(CGCS2000 坐标系) + private double lng; + + private MultipartFile image; + + private String imageUrl; +} diff --git a/social/src/main/java/com/jiagutech/ams/model/request/RealTimeData.java b/social/src/main/java/com/jiagutech/ams/model/request/RealTimeData.java new file mode 100644 index 0000000..0bfa831 --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/model/request/RealTimeData.java @@ -0,0 +1,29 @@ +package com.jiagutech.ams.model.request; + +import lombok.Data; + +@Data +public class RealTimeData { + + // 设备Id + private String vehicleId; + // 时间戳 + private long timestamp; + // 纬度,最多保留7位小数(CGCS2000 坐标系) + private double lat; + // 经度,最多保留7位小数(CGCS2000 坐标系) + private double lng; + // 状态[1位数字](0=不工作,1=工作,3=合格) + private int status; + // 幅宽(米)[浮点数,最多保留两位小数] + private Double breadth; // 可选字段 + // 速度(千米/小时)[浮点数,最多保留一位小数] + private Double velocity; // 可选字段 + // 耕深(厘米)[浮点数,最多保留一位小数] + private Double deep; // 可选字段 + // 流量(脉冲值)[浮点数,最多保留一位小数] + // 流量(脉冲值)[浮点数,最多保留一位小数] + private Double flow; // 可选字段 + // 播种速度 粒/s转对应实体类 + private Double seeding; // 可选字段 +} diff --git a/social/src/main/java/com/jiagutech/ams/model/request/WorkRecord.java b/social/src/main/java/com/jiagutech/ams/model/request/WorkRecord.java new file mode 100644 index 0000000..c0c82cd --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/model/request/WorkRecord.java @@ -0,0 +1,41 @@ +package com.jiagutech.ams.model.request; + +import com.jiagutech.ams.model.Locus; +import lombok.Data; + +import java.util.List; + +// 主要的作业记录类 +@Data +public class WorkRecord { + // 达标面积(亩) + private Double qualifiedWorkArea; + // 重复作业面积(亩) + private Double repeatWorkArea; + // 作业面积(亩) + private Double workArea; + // 开始时间,毫秒时间戳 + private Long startAt; + // 结束时间,毫秒时间戳 + private Long endAt; + // 设备Id + private String vehicleId; + // 作业地点经度 + private Double longitude; + // 作业地点纬度 + private Double latitude; + // 耕深(厘米) + private Double avgDeep; + // 合格率 + private Double qualifiedRate; + // 行驶里程(米) + private Double distance; + // 作业类型,编码见附表1 + private Long module; + // 总流量(单位:L) + private Double sumFlow; + // 总播种量 (单位:粒) + private Integer seedingNumber; + // 地块轨迹 + private List locus; +} \ No newline at end of file diff --git a/social/src/main/java/com/jiagutech/ams/rest/TrackRestClient.java b/social/src/main/java/com/jiagutech/ams/rest/TrackRestClient.java index ec25e06..4264300 100644 --- a/social/src/main/java/com/jiagutech/ams/rest/TrackRestClient.java +++ b/social/src/main/java/com/jiagutech/ams/rest/TrackRestClient.java @@ -3,6 +3,7 @@ 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.ZhongNongTrack; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; @@ -28,7 +29,7 @@ public class TrackRestClient { @Value("${center-track.client.url}") - private String CenterTrackUrl; + private String centerBaseUrl; public List getTractorByDroneIdAndTime(String droneid, Long startTime, Long endTime) { @@ -36,9 +37,29 @@ public class TrackRestClient { map.put("droneid", droneid); map.put("startTime", startTime); map.put("endTime", endTime); - String res = restTemplate.getForObject(CenterTrackUrl + "?droneid={droneid}&start={startTime}&end={endTime}", String.class, map); - return JSON.parseObject(res, new TypeReference>() {}); + String res = restTemplate.getForObject(centerBaseUrl + "/track?droneid={droneid}&start={startTime}&end={endTime}", String.class, map); + return JSON.parseObject(res, new TypeReference>() { + }); } + public String saveTractor(List tracks) { + String s = JSON.toJSONString(tracks); + log.info("传参==>" + s); + String result = restTemplate.postForObject(centerBaseUrl + "/track/saveTractor", s, String.class); + return result; + } + + public List getZhongNongTracks(String keyId, String secretKey, String droneId, Long startTime, Long endTime) { + Map map = new HashMap<>(); + map.put("droneId", droneId); + map.put("startTime", startTime); + map.put("endTime", endTime); + map.put("keyId", keyId); + map.put("secretKey", secretKey); + String res = restTemplate.getForObject(centerBaseUrl + "/zhongnong/tracks?keyId={keyId}&secretKey={secretKey}&droneId={droneId}&start={startTime}&end={endTime}", String.class, map); + return JSON.parseObject(res, new TypeReference>() { + }); + } + } diff --git a/social/src/main/java/com/jiagutech/ams/rest/ZhongNongRestClient.java b/social/src/main/java/com/jiagutech/ams/rest/ZhongNongRestClient.java new file mode 100644 index 0000000..e1cc19a --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/rest/ZhongNongRestClient.java @@ -0,0 +1,75 @@ +package com.jiagutech.ams.rest; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.jiagutech.ams.model.ZhongNongTrack; +import io.swagger.v3.core.util.Json; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import java.time.Instant; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.List; + +@Slf4j +@Component +@RequiredArgsConstructor +public class ZhongNongRestClient { + + + private final RestTemplate restTemplate; + + + @Value("${zhong-nong.client.base_url}") + private String baseUrl; + + public String getAccessToken(String keyId, String signature, long timestamp) { + // 设置请求头和请求体 + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + JSONObject body = new JSONObject(); + body.put("keyId", keyId); + body.put("signature", signature); + body.put("timestamp", timestamp); + HttpEntity requestEntity = new HttpEntity<>(body.toJSONString(), headers); + ResponseEntity response = restTemplate.postForEntity(baseUrl + "/ThirdParty/sso", requestEntity, String.class); + if (response.getStatusCode().is2xxSuccessful()) { + return response.getBody(); + } else { + log.error("获取token失败:{}", response); + return null; + } + + } + + + public List getTracks(String accessToken, String simNo, long startTime, long endTime) { + // 设置请求头和请求体 + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.set("concrete-token-id", accessToken); + JSONObject body = new JSONObject(); + body.put("simNo", simNo); + DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") + .withZone(ZoneId.of("Asia/Shanghai")); + body.put("startTime", df.format(Instant.ofEpochMilli(startTime))); + body.put("endTime", df.format(Instant.ofEpochMilli(endTime))); + log.info(" get tracks params :{}", body); + HttpEntity requestEntity = new HttpEntity<>(body.toJSONString(), headers); + ResponseEntity response = restTemplate.postForEntity(baseUrl + "/MessageDataService/vehicleLocusList", requestEntity, String.class); + if (response.getStatusCode().is2xxSuccessful()) { + return JSON.parseArray(response.getBody(), ZhongNongTrack.class); + } else { + log.error("获取轨迹失败:{}", response); + return null; + } + } +} diff --git a/social/src/main/java/com/jiagutech/ams/scheduled/JobScheduled.java b/social/src/main/java/com/jiagutech/ams/scheduled/JobScheduled.java index eda80a2..cfc5ed2 100644 --- a/social/src/main/java/com/jiagutech/ams/scheduled/JobScheduled.java +++ b/social/src/main/java/com/jiagutech/ams/scheduled/JobScheduled.java @@ -6,24 +6,20 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.jiagutech.ams.mapper.DeviceMapper; import com.jiagutech.ams.mapper.JobMapper; import com.jiagutech.ams.model.TrackItem; -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.request.JobPageRequest; -import com.jiagutech.ams.model.response.JobItem; import com.jiagutech.ams.service.JobService; -import com.jiagutech.ams.utils.FlightTrackerUtils; +import com.jiagutech.ams.utils.TrackUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; -import java.time.*; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneOffset; import java.util.List; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; @Slf4j @Component @@ -32,7 +28,6 @@ public class JobScheduled { private final JobService jobService; private final JobMapper jobMapper; private final DeviceMapper deviceMapper; - private final ScheduledExecutorService taskScheduler = Executors.newScheduledThreadPool(1); @Scheduled(cron = "0 20 0 * * ?") public void cronTask() { @@ -52,10 +47,6 @@ public class JobScheduled { queryWrapper.eq("area", 0); List jobDTOS = jobMapper.selectList(queryWrapper); for (JobDTO jobDTO : jobDTOS) { - Long startTime = jobDTO.getStartTime(); - Long endTime = System.currentTimeMillis(); - Instant instant1 = Instant.ofEpochMilli(startTime); - Instant instant2 = Instant.ofEpochMilli(endTime); List trackList = jobService.getTrackList(jobDTO.getId()); if (CollectionUtil.isEmpty(trackList)) { continue; @@ -66,25 +57,8 @@ public class JobScheduled { } - public void handleArea(JobDTO jobDTO, int retryCount) { - log.info("job:{}去获取轨迹计算作业面积,当前重试次数:{}", jobDTO.getId(), retryCount); - List trackList = jobService.getTrackList(jobDTO.getId()); - if (CollectionUtil.isNotEmpty(trackList)) { - update(jobDTO, trackList); - } else { - if (retryCount < 3) { - int[] retryDelays = {60, 120, 300}; - int delay = retryDelays[retryCount]; - taskScheduler.schedule(() -> handleArea(jobDTO, retryCount + 1), delay, TimeUnit.SECONDS); - } else { - log.info("job:{}达到最大重试次数,面积计算未成功,终止任务", jobDTO.getId()); - } - } - - } - private void update(JobDTO jobDTO, List trackList) { - jobDTO.setArea(calculateArea(trackList)); + jobDTO.setArea(TrackUtil.calcAreaByBlockData(trackList)); TrackItem trackItem = trackList.get(trackList.size() - 1); jobDTO.setLat(trackItem.getLat()).setLng(trackItem.getLng()); DeviceDTO deviceDTO = new DeviceDTO().setId(jobDTO.getDeviceId()).setLat(trackItem.getLat()).setLng(trackItem.getLng()).setUpdateTime(trackItem.getTimestamp()); @@ -93,24 +67,4 @@ public class JobScheduled { } - private float calculateArea(List trackList) { - try { - if (CollectionUtil.isEmpty(trackList)) { - return 0.0f; - } - List pointTemps = trackList.stream().map(item -> { - LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(item.getTimestamp()), ZoneId.systemDefault()); - int speed = Math.round(item.getVelocity() * 5 / 18); - return new FlightTrackerUtils.PointTemp(localDateTime, item.getLat(), item.getLng(), speed); - }).toList(); - if (CollectionUtil.isEmpty(pointTemps)) { - return 0.0f; - } - return (float) FlightTrackerUtils.calculateArea(pointTemps); - } catch (Exception e) { - log.error("calculate area error", e); - return 0.0f; - } - } - } diff --git a/social/src/main/java/com/jiagutech/ams/service/JobService.java b/social/src/main/java/com/jiagutech/ams/service/JobService.java index bccac69..90c3c1c 100644 --- a/social/src/main/java/com/jiagutech/ams/service/JobService.java +++ b/social/src/main/java/com/jiagutech/ams/service/JobService.java @@ -34,4 +34,6 @@ public interface JobService { void saveJobImages(TrackImageVO trackImageDTO); + List getTracks(String droneId,long startTime,long endTime); + } diff --git a/social/src/main/java/com/jiagutech/ams/service/JobServiceImpl.java b/social/src/main/java/com/jiagutech/ams/service/JobServiceImpl.java index 26aa3ee..b389cbf 100644 --- a/social/src/main/java/com/jiagutech/ams/service/JobServiceImpl.java +++ b/social/src/main/java/com/jiagutech/ams/service/JobServiceImpl.java @@ -229,4 +229,10 @@ public class JobServiceImpl implements JobService { } return queryWrapper; } + + @Override + public List getTracks(String droneId, long startTime, long endTime) { + List tractorByDroneIdAndTime = trackRestClient.getTractorByDroneIdAndTime(droneId, startTime, endTime); + return TrackMapping.INSTANCE.convertToTrackItemsByLocus(tractorByDroneIdAndTime); + } } diff --git a/social/src/main/java/com/jiagutech/ams/service/MessageDataService.java b/social/src/main/java/com/jiagutech/ams/service/MessageDataService.java new file mode 100644 index 0000000..ce1249b --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/service/MessageDataService.java @@ -0,0 +1,16 @@ +package com.jiagutech.ams.service; + +import com.jiagutech.ams.model.request.MachImage; +import com.jiagutech.ams.model.request.RealTimeData; +import com.jiagutech.ams.model.request.WorkRecord; + +import java.util.List; + +public interface MessageDataService { + + void addRealTimeData(List realTimeDatas); + + void machineryImage(MachImage machImage); + + void addWorkData(List workRecords); +} diff --git a/social/src/main/java/com/jiagutech/ams/service/MessageDataServiceImpl.java b/social/src/main/java/com/jiagutech/ams/service/MessageDataServiceImpl.java new file mode 100644 index 0000000..b06beb9 --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/service/MessageDataServiceImpl.java @@ -0,0 +1,72 @@ +package com.jiagutech.ams.service; + +import com.alibaba.fastjson2.JSONObject; +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.request.MachImage; +import com.jiagutech.ams.model.request.RealTimeData; +import com.jiagutech.ams.model.request.WorkRecord; +import com.jiagutech.ams.rest.TrackRestClient; +import com.jiagutech.ams.utils.HuaweiObs; +import lombok.Data; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.concurrent.TimeUnit; + +@Slf4j +@Service +@RequiredArgsConstructor +public class MessageDataServiceImpl implements MessageDataService { + private final StringRedisTemplate stringRedisTemplate; + private final HuaweiObs huaweiObs; + + private final JobService jobService; + + private final TrackRestClient trackRestClient; + + public void addRealTimeData(List realTimeDatas) { + for (RealTimeData realTimeData : realTimeDatas) { + TrackDataJG uavTrackDataRVO = new TrackDataJG(); + uavTrackDataRVO.setLat(realTimeData.getLat()); + uavTrackDataRVO.setLng(realTimeData.getLng()); + uavTrackDataRVO.setDroneId(realTimeData.getVehicleId()); + uavTrackDataRVO.setHvel(Float.parseFloat(String.valueOf(realTimeData.getVelocity()))); + uavTrackDataRVO.setTimeStamp(realTimeData.getTimestamp()); + String s = JSONObject.toJSONString(uavTrackDataRVO); + stringRedisTemplate.opsForValue().set("mtrack:" + realTimeData.getVehicleId(), s, 2, TimeUnit.MINUTES); + } + } + + + @SneakyThrows + public void machineryImage(MachImage machImage) { + String upload = huaweiObs.upload(machImage.getImage()); + if (upload != null) { + log.info("保存图片到ams,图片链接:{}", upload); + machImage.setImageUrl(upload); + machImage.setImage(null); + TrackImageMapping mapping = TrackImageMapping.INTANCE; + jobService.saveJobImages(mapping.convertByMachImage(machImage)); + } + + } + + @Override + public void addWorkData(List workRecords) { + for (WorkRecord workRecord : workRecords) { + List locus = workRecord.getLocus(); + //轨迹插入 + if (locus.size() > 0) { + trackRestClient.saveTractor(locus); + } + } + } + +} diff --git a/social/src/main/java/com/jiagutech/ams/utils/FlightTrackerUtils.java b/social/src/main/java/com/jiagutech/ams/utils/FlightTrackerUtils.java index 2fb483f..8675d41 100644 --- a/social/src/main/java/com/jiagutech/ams/utils/FlightTrackerUtils.java +++ b/social/src/main/java/com/jiagutech/ams/utils/FlightTrackerUtils.java @@ -7,10 +7,7 @@ import org.apache.commons.csv.CSVParser; import org.apache.commons.csv.CSVRecord; import org.locationtech.jts.geom.*; -import org.locationtech.proj4j.BasicCoordinateTransform; -import org.locationtech.proj4j.CRSFactory; -import org.locationtech.proj4j.CoordinateReferenceSystem; -import org.locationtech.proj4j.ProjCoordinate; +import org.locationtech.proj4j.*; import java.io.FileReader; @@ -364,5 +361,22 @@ public class FlightTrackerUtils { System.out.println(sorties.get(i).toJson()); } } + public static ProjCoordinate CGS2000ToWGS84(double x, double y) { + // 定义坐标转换器 + CoordinateTransformFactory ctFactory = new CoordinateTransformFactory(); + // 定义源和目标投影 + CRSFactory crsFactory = new CRSFactory(); + CoordinateReferenceSystem sourceCRS = crsFactory.createFromName("EPSG:4547"); // 原始坐标系 + CoordinateReferenceSystem targetCRS = crsFactory.createFromName("EPSG:4326"); // 目标坐标系 + // 创建转换器 + CoordinateTransform transform = ctFactory.createTransform(sourceCRS, targetCRS); + // 执行坐标转换 + ProjCoordinate srcCoord = new ProjCoordinate(x, y); + ProjCoordinate targetCoord = new ProjCoordinate(); + transform.transform(srcCoord, targetCoord); + // 4. 输出转换后的正常经纬度坐标 + return targetCoord; + } + } diff --git a/social/src/main/java/com/jiagutech/ams/utils/HuaweiObs.java b/social/src/main/java/com/jiagutech/ams/utils/HuaweiObs.java new file mode 100644 index 0000000..94d6730 --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/utils/HuaweiObs.java @@ -0,0 +1,264 @@ +package com.jiagutech.ams.utils; + +import cn.hutool.core.util.IdUtil; +import com.alibaba.fastjson2.JSON; +import com.obs.services.ObsClient; +import com.obs.services.model.*; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.IOUtils; +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Calendar; +import java.util.HashMap; +import java.util.Map; + +/** + * @author Lenovo + */ +@Slf4j +@Component +public class HuaweiObs { + + //Access Key Id + //private String ak = "Access Key Id"; + + //Secret Access Key + //private String sk = "Secret Access Key"; + + //桶名称 + private String bucketName = "jg-iot"; + + // 终端节点访问Endpoint + //private String endpoint = "Endpoint"; + + // 文件目录 + private String prifix = "/farm"; + + // 访问域名 在域名后面或文件目录前加“/” + private String path = "/farm/"; + + + @Resource + private ObsClient obsClient; + + /** + * 文件上传 + * + * @param file + * @return + * @throws IOException + */ + public String upload(MultipartFile file) throws IOException { + //ObsClient obsClient = null; + + Calendar cal = Calendar.getInstance(); + int year = cal.get(Calendar.YEAR); + int month = cal.get(Calendar.MONTH); + int day = cal.get(Calendar.DATE); + String fileName = IdUtil.simpleUUID() + file.getOriginalFilename().substring(file.getOriginalFilename().indexOf(".")); + String objectName = prifix + "/" + year + "/" + month + "/" + day + "/" + fileName; + //obsClient = new ObsClient(ak, sk, endpoint); + PutObjectResult response = obsClient.putObject(bucketName, objectName, file.getInputStream()); + log.info(JSON.toJSONString(response)); + // 可选:调用成功后,记录调用成功的HTTP状态码和服务端请求ID + int statusCode = response.getStatusCode(); + + if (200 == statusCode) { + + return response.getObjectUrl(); + } + + return null; + } + + /** + * 上传文件--流式 + * + * @param fileName 上传文件名称 + * @param is 文件流 + * @return + */ + public String uploadFile(String fileName, InputStream is) throws IOException { + //ObsClient obsClient = null; + try { + Calendar cal = Calendar.getInstance(); + int year = cal.get(Calendar.YEAR); + int month = cal.get(Calendar.MONTH); + int day = cal.get(Calendar.DATE); + String objectName = prifix + "/" + year + "/" + month + "/" + day + "/" + fileName; + //obsClient = new ObsClient(ak, sk, endpoint); + HeaderResponse response = obsClient.putObject(bucketName, objectName, is); + log.info(JSON.toJSONString(response)); + // 可选:调用成功后,记录调用成功的HTTP状态码和服务端请求ID + int statusCode = response.getStatusCode(); + if (200 == statusCode) { + String objectUrl = path + objectName; + return objectUrl; + } + } finally { + obsClient.close(); + } + return null; + } + + /** + * 上传文件--字节数组 + * + * @param fileName 上传文件名称 + * @param fileType 文件路径 + * @param is 文件流 + * @return + */ + public boolean uploadFileByte(String fileName, FileType fileType, byte[] is) { + //ObsClient obsClient = null; + try { + String objectName = fileType.getType().concat("/").concat(fileName); + //obsClient = new ObsClient(ak, sk, endpoint); + HeaderResponse response = obsClient.putObject(bucketName, objectName, new ByteArrayInputStream(is)); + // 可选:调用成功后,记录调用成功的HTTP状态码和服务端请求ID + int statusCode = response.getStatusCode(); + if (200 == statusCode) { + return true; + } + obsClient.close(); + } catch (IOException e) { + log.info("文件上传失败:{}", e.getMessage(), e); + } + return false; + } + + /** + * 下载文件 + * + * @param fileName 文件名称 + * @param fileType 文件路径 + * @return + */ + public String getDownloadUrl(String fileName, FileType fileType) { + //ObsClient obsClient = null; + //obsClient = new ObsClient(ak, sk, endpoint); + // URL有效期,3600秒.5分钟 + long expireSeconds = 3600L; + String objectName = fileType.getType().concat("/").concat(fileName); + TemporarySignatureRequest request = new TemporarySignatureRequest(HttpMethodEnum.GET, expireSeconds); + request.setBucketName(bucketName); + request.setObjectKey(objectName); + TemporarySignatureResponse response = obsClient.createTemporarySignature(request); + return response.getSignedUrl(); + } + + /** + * 获取上传地址 + * + * @param fileName 文件名称 + * @param fileType 文件路径 + * @return + */ + public String getUploadUrl(String fileName, FileType fileType) { + try { + // 创建ObsClient实例 + //ObsClient obsClient = new ObsClient(ak, sk, endpoint); + // URL有效期,3600秒 + long expireSeconds = 3600L; + Map headers = new HashMap(); + headers.put("Content-Type", "application/octet-stream"); + String objectName = fileType.getType().concat("/").concat(fileName); + TemporarySignatureRequest request = new TemporarySignatureRequest(HttpMethodEnum.PUT, expireSeconds); + request.setBucketName(bucketName); + request.setObjectKey(objectName); + request.setHeaders(headers); + TemporarySignatureResponse response = obsClient.createTemporarySignature(request); + return response.getSignedUrl(); + } catch (Exception e) { + log.error("获取上传地址异常:{}", e.getMessage(), e); + } + return null; + } + + /** + * 下载文件返回字节数组 + * + * @param fileName 文件名称 + * @param fileType 文件路径 + * @return + */ + public byte[] downloadFile(String fileName, FileType fileType) { + try { + InputStream inputStream = downloadFileInputStream(fileName, fileType); + byte[] bytes = IOUtils.toByteArray(inputStream); + return bytes; + } catch (Exception e) { + log.error("下载文件异常:{}", e.getMessage(), e); + } + return null; + } + + /** + * 上传视频 + * + * @param fileName 文件名称 + * @param fileType 文件路径 + * @return + */ + public boolean uploadFileVideo(String fileName, FileType fileType, InputStream is) { + try { + String objectName = fileType.getType().concat("/").concat(fileName); + //ObsClient obsClient = new ObsClient(ak, sk, endpoint); + // 添加 ContentType (添加后可在浏览器中直接浏览,而非下载链接) + obsClient.putObject(bucketName, objectName, is); + obsClient.close(); + return true; + } catch (Exception e) { + log.error("上传视频文件异常:{}", e.getMessage(), e); + } + return false; + } + + /** + * 下载文件返回流式 + * + * @param fileName 文件名称 + * @param fileType 文件路径 + * @return + */ + public InputStream downloadFileInputStream(String fileName, FileType fileType) { + try { + String objectName = fileType.getType().concat("/").concat(fileName); + // 用户拿到STS临时凭证后,通过其中的安全令牌(SecurityToken)和临时访问密钥(AccessKeyId和AccessKeySecret)生成OSSClient。 + //ObsClient obsClient = new ObsClient(ak, sk, endpoint); + ObsObject obsObject = obsClient.getObject(bucketName, objectName); + obsClient.close(); + return obsObject.getObjectContent(); + } catch (Exception e) { + log.error("下载文件异常:{}", e.getMessage(), e); + } + return null; + } + + + public enum FileType { + TEST("TEST", "测试"); + + private String type; + private String desc; + + FileType(String type, String desc) { + this.type = type; + this.desc = desc; + } + + public String getType() { + return type; + } + + public String getDesc() { + return desc; + } + } +} + diff --git a/social/src/main/java/com/jiagutech/ams/utils/TrackUtil.java b/social/src/main/java/com/jiagutech/ams/utils/TrackUtil.java new file mode 100644 index 0000000..c472932 --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/utils/TrackUtil.java @@ -0,0 +1,104 @@ +package com.jiagutech.ams.utils; + +import cn.hutool.core.collection.CollectionUtil; +import com.jiagutech.ams.model.TrackItem; +import lombok.extern.slf4j.Slf4j; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; + +@Slf4j +public class TrackUtil { + + public static float calculateArea(List trackList) { + try { + if (CollectionUtil.isEmpty(trackList)) { + return 0.0f; + } + List pointTemps = trackList.stream().map(item -> { + LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(item.getTimestamp()), ZoneId.systemDefault()); + int speed = Math.round(item.getVelocity() * 5 / 18); + return new FlightTrackerUtils.PointTemp(localDateTime, item.getLat(), item.getLng(), speed); + }).toList(); + if (CollectionUtil.isEmpty(pointTemps)) { + return 0.0f; + } + return (float) FlightTrackerUtils.calculateArea(pointTemps); + } catch (Exception e) { + log.error("calculate area error", e); + return 0.0f; + } + } + + private static final double EARTH_RADIUS = 6371000; + + // 计算总作业面积 + public static double calculateArea(List coordinates, double width) { + double totalDistance = 0.0; + + // 累加轨迹点之间的距离 + for (int i = 1; i < coordinates.size(); i++) { + double[] start = coordinates.get(i - 1); + double[] end = coordinates.get(i); + + totalDistance += haversineDistance(start[1], start[0], end[1], end[0]); + } + + // 作业面积 = 作业宽度 * 总距离 * 作业效率系数 + return width * totalDistance * 0.7 * 0.0015; // Convert to mu (亩) + + } + + public static double haversineDistance(double lat1, double lon1, double lat2, double lon2) { + // 将纬度和经度从度转换为弧度 + double lat1Rad = Math.toRadians(lat1); + double lon1Rad = Math.toRadians(lon1); + double lat2Rad = Math.toRadians(lat2); + double lon2Rad = Math.toRadians(lon2); + + // 计算差值 + double deltaLat = lat2Rad - lat1Rad; + double deltaLon = lon2Rad - lon1Rad; + + // 应用Haversine公式 + double a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) + + Math.cos(lat1Rad) * Math.cos(lat2Rad) + * Math.sin(deltaLon / 2) * Math.sin(deltaLon / 2); + double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + + // 返回距离(米) + return EARTH_RADIUS * c; + } +// // Haversine公式计算两点之间的距离 +// public static double calculateDistance(double lat1, double lon1, double lat2, double lon2) { +// double dLat = Math.toRadians(lat2 - lat1); +// double dLon = Math.toRadians(lon2 - lon1); +// double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +// + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) +// * Math.sin(dLon / 2) * Math.sin(dLon / 2); +// double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); +// return EARTH_RADIUS * c; +// } + + + public static float calcAreaByBlockData(List pointTemps) { + AtomicReference breadth = new AtomicReference<>((double) 0); + List coordinates = pointTemps.stream() + .filter(p -> p.getVelocity() > 0) + .filter(p -> p.getBreadth()!=null && p.getBreadth() > 0) + .map(item -> { + breadth.set(item.getBreadth()); + return new double[]{item.getLng(), item.getLat()}; + }).toList(); + return (float) calculateArea(coordinates, breadth.get()); + } + + public static float calcAreaByBlockDataNoFilter(List pointTemps,double breadth) { + List coordinates = pointTemps.stream() + .map(item -> new double[]{item.getLng(), item.getLat()}).toList(); + return (float) calculateArea(coordinates, breadth); + } +} diff --git a/web/pom.xml b/web/pom.xml index 6f0a9c4..49bfe6c 100644 --- a/web/pom.xml +++ b/web/pom.xml @@ -1,208 +1,214 @@ - 4.0.0 - - com.jiagutech - ams-social - ${revision} - + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + com.jiagutech + ams-social + ${revision} + - web - jar - ams-social + web + jar + ams-social - - 17 - 17 - UTF-8 - + + 17 + 17 + UTF-8 + - - - dev - - - dev - info - - - - true - - - - zyg - - zyg - info - - - - prod - - prod - info - - - - - - com.jiagutech - system - 1.0.0-SNAPSHOT - - - com.jiagutech - social - 1.0.0-SNAPSHOT - - - org.springframework.boot - spring-boot-starter-data-jdbc - - - mysql - mysql-connector-java - - - org.springdoc - springdoc-openapi-starter-webmvc-ui + + + dev + + + dev + info + + + + true + + + + zyg + + zyg + info + + + + prod + + prod + info + + + + + + com.jiagutech + system + 1.0.0-SNAPSHOT + + + com.jiagutech + social + 1.0.0-SNAPSHOT + + + org.springframework.boot + spring-boot-starter-data-jdbc + + + mysql + mysql-connector-java + + + org.springdoc + springdoc-openapi-starter-webmvc-ui - - - org.springdoc - springdoc-openapi-starter-webmvc-api - - - org.apache.commons - commons-pool2 - 2.12.0 - - - cn.dev33 - sa-token-spring-boot3-starter - + + + org.springdoc + springdoc-openapi-starter-webmvc-api + + + org.apache.commons + commons-pool2 + 2.12.0 + + + cn.dev33 + sa-token-spring-boot3-starter + - - cn.dev33 - sa-token-redis-jackson - - - - org.mapstruct - mapstruct - - - org.springframework.amqp - spring-rabbit - - - org.springframework.amqp - spring-amqp - - - org.springframework.boot - spring-boot-starter-actuator - + + cn.dev33 + sa-token-redis-jackson + + + + org.mapstruct + mapstruct + + + org.springframework.amqp + spring-rabbit + + + org.springframework.amqp + spring-amqp + + + org.springframework.boot + spring-boot-starter-actuator + - - io.micrometer - micrometer-registry-prometheus - - - - ${project.parent.artifactId} - - - src/main/resources - true - - application.yml - application-${profiles.active}.yml - *.xml - - - - - - org.springframework.boot - spring-boot-maven-plugin - ${spring-boot.version} - - - - repackage - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - 17 - 17 - - - - org.projectlombok - lombok - ${lombok.version} - - - - - - - org.apache.maven.plugins - maven-pmd-plugin - 3.15.0 - - - net.sourceforge.pmd - pmd-core - 6.38.0 - - - net.sourceforge.pmd - pmd-java - 6.38.0 - - - org.ow2.asm - asm - 9.2 - - - - false - UTF-8 - 100 - 17 - true - ${project.build.directory}/pmd/pmd.cache - ${project.build.directory}/pmd - html - false - - - - pmd-check - verify - - check - cpd-check - pmd - - - - - + + io.micrometer + micrometer-registry-prometheus + + + com.huaweicloud + esdk-obs-java + 3.20.6.1 + compile + + + + ${project.parent.artifactId} + + + src/main/resources + true + + application.yml + application-${profiles.active}.yml + *.xml + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + 17 + 17 + + + + org.projectlombok + lombok + ${lombok.version} + + + + + + + org.apache.maven.plugins + maven-pmd-plugin + 3.15.0 + + + net.sourceforge.pmd + pmd-core + 6.38.0 + + + net.sourceforge.pmd + pmd-java + 6.38.0 + + + org.ow2.asm + asm + 9.2 + + + + false + UTF-8 + 100 + 17 + true + ${project.build.directory}/pmd/pmd.cache + ${project.build.directory}/pmd + html + false + + + + pmd-check + verify + + check + cpd-check + pmd + + + + + - + \ No newline at end of file diff --git a/web/src/main/java/com/jiagutech/ams/common/RestTemplateInterceptor.java b/web/src/main/java/com/jiagutech/ams/common/RestTemplateInterceptor.java index f9fd9c1..dccefe1 100644 --- a/web/src/main/java/com/jiagutech/ams/common/RestTemplateInterceptor.java +++ b/web/src/main/java/com/jiagutech/ams/common/RestTemplateInterceptor.java @@ -19,7 +19,7 @@ public class RestTemplateInterceptor implements ClientHttpRequestInterceptor { // 打印出请求的详细信息 log.info("URI: {}", request.getURI()); if (body != null && body.length > 0) { - log.debug("Request Body: {}", new String(body, StandardCharsets.UTF_8)); + log.info("Request Body: {}", new String(body, StandardCharsets.UTF_8)); } // 执行请求并获取响应 diff --git a/web/src/main/java/com/jiagutech/ams/config/ObsConfig.java b/web/src/main/java/com/jiagutech/ams/config/ObsConfig.java new file mode 100644 index 0000000..1c851ea --- /dev/null +++ b/web/src/main/java/com/jiagutech/ams/config/ObsConfig.java @@ -0,0 +1,30 @@ +package com.jiagutech.ams.config; + + +import com.obs.services.ObsClient; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Data +@Configuration +@NoArgsConstructor +@ConfigurationProperties(prefix = "huawei.obs") +public class ObsConfig { + + + private String endPoint; + private String ak; + private String sk; + + private String bucketName; + private String pathPrefix; + + @Bean + public ObsClient obsClient() { + ObsClient obsClient= new ObsClient(ak, sk, endPoint); + return obsClient; + } +} \ No newline at end of file diff --git a/web/src/main/java/com/jiagutech/ams/config/SaPermissionImpl.java b/web/src/main/java/com/jiagutech/ams/config/SaPermissionImpl.java index aab257d..84bfeb0 100644 --- a/web/src/main/java/com/jiagutech/ams/config/SaPermissionImpl.java +++ b/web/src/main/java/com/jiagutech/ams/config/SaPermissionImpl.java @@ -1,12 +1,9 @@ package com.jiagutech.ams.config; import cn.dev33.satoken.stp.StpInterface; -import cn.dev33.satoken.stp.StpUtil; -import com.jiagutech.ams.constant.UserConstants; import com.jiagutech.ams.model.LoginUser; import com.jiagutech.ams.utils.LoginUtil; - import java.util.ArrayList; import java.util.List; diff --git a/web/src/main/resources/application-dev.yml b/web/src/main/resources/application-dev.yml index 3c0a93c..39f7b24 100644 --- a/web/src/main/resources/application-dev.yml +++ b/web/src/main/resources/application-dev.yml @@ -23,5 +23,5 @@ spring: center-track: client: - url: http://localhost:11003/iot/farm/track + url: http://localhost:11003/iot/farm diff --git a/web/src/main/resources/application-prod.yml b/web/src/main/resources/application-prod.yml index b97104e..45b7d61 100644 --- a/web/src/main/resources/application-prod.yml +++ b/web/src/main/resources/application-prod.yml @@ -24,5 +24,5 @@ spring: center-track: client: - url: http://192.168.0.17:11003/iot/farm/track + url: http://192.168.0.6:11003/iot/farm diff --git a/web/src/main/resources/application.yml b/web/src/main/resources/application.yml index ef6bbf2..b95f40d 100644 --- a/web/src/main/resources/application.yml +++ b/web/src/main/resources/application.yml @@ -106,4 +106,20 @@ info: version: 1.0.0 java: 17 author: zhangyeguang - description: 贵州农机监管平台-合作社模块 \ No newline at end of file + description: 贵州农机监管平台-合作社模块 + + + +zhong-nong: + client: + base_url: http://47.104.95.74:8080/eop + key_id: 59B9D06F2CD5E50C9F5EFFACDBEB46DE + secret_key: 366466118BBB799F12479CFB4DCC9AB4 + +huawei: + obs: + end-point: "obs.cn-east-2.myhuaweicloud.com" + ak: "NMUAWG3TN50OSJESCIRV" + sk: "qG0VFwhiTAtiCuUaMAxJL3zsusp3W4GHs7THR9pC" + bucket-name: iot + path-prefix: farm \ No newline at end of file