29 changed files with 1178 additions and 275 deletions
			
			
		@ -1,2 +1,18 @@ | 
			
		|||||
# ams-social | 
				# 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 静态代码检查插件 | 
			
		||||
 | 
				- 功能说明 | 
			
		||||
@ -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<RealTimeData> 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<WorkRecord> workRecords) { | 
			
		||||
 | 
				        log.info("WorkRecord:{}", JSONObject.toJSONString(workRecords)); | 
			
		||||
 | 
				        messageDataService.addWorkData(workRecords); | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				        return R.ok("success"); | 
			
		||||
 | 
				    } | 
			
		||||
 | 
				} | 
			
		||||
@ -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); | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				} | 
			
		||||
@ -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; | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				} | 
			
		||||
@ -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; | 
			
		||||
 | 
				} | 
			
		||||
@ -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; // 可选字段
 | 
			
		||||
 | 
				    // 速度(千米/小时<km/h>)[浮点数,最多保留一位小数]
 | 
			
		||||
 | 
				    private Double velocity; // 可选字段
 | 
			
		||||
 | 
				    // 耕深(厘米)[浮点数,最多保留一位小数]
 | 
			
		||||
 | 
				    private Double deep; // 可选字段
 | 
			
		||||
 | 
				    // 流量(脉冲值)[浮点数,最多保留一位小数]
 | 
			
		||||
 | 
				    // 流量(脉冲值)[浮点数,最多保留一位小数]
 | 
			
		||||
 | 
				    private Double flow; // 可选字段
 | 
			
		||||
 | 
				    // 播种速度 粒/s转对应实体类
 | 
			
		||||
 | 
				    private Double seeding; // 可选字段
 | 
			
		||||
 | 
				} | 
			
		||||
@ -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> locus; | 
			
		||||
 | 
				} | 
			
		||||
@ -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<String> requestEntity = new HttpEntity<>(body.toJSONString(), headers); | 
			
		||||
 | 
				        ResponseEntity<String> 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<ZhongNongTrack> 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<String> requestEntity = new HttpEntity<>(body.toJSONString(), headers); | 
			
		||||
 | 
				        ResponseEntity<String> 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; | 
			
		||||
 | 
				        } | 
			
		||||
 | 
				    } | 
			
		||||
 | 
				} | 
			
		||||
@ -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<RealTimeData> realTimeDatas); | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				    void machineryImage(MachImage machImage); | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				    void addWorkData(List<WorkRecord> workRecords); | 
			
		||||
 | 
				} | 
			
		||||
@ -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<RealTimeData> 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<WorkRecord> workRecords) { | 
			
		||||
 | 
				        for (WorkRecord workRecord : workRecords) { | 
			
		||||
 | 
				            List<Locus> locus = workRecord.getLocus(); | 
			
		||||
 | 
				            //轨迹插入
 | 
			
		||||
 | 
				            if (locus.size() > 0) { | 
			
		||||
 | 
				                trackRestClient.saveTractor(locus); | 
			
		||||
 | 
				            } | 
			
		||||
 | 
				        } | 
			
		||||
 | 
				    } | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				} | 
			
		||||
@ -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<String, String> headers = new HashMap<String, String>(); | 
			
		||||
 | 
				            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; | 
			
		||||
 | 
				        } | 
			
		||||
 | 
				    } | 
			
		||||
 | 
				} | 
			
		||||
 | 
				
 | 
			
		||||
@ -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<TrackItem> trackList) { | 
			
		||||
 | 
				        try { | 
			
		||||
 | 
				            if (CollectionUtil.isEmpty(trackList)) { | 
			
		||||
 | 
				                return 0.0f; | 
			
		||||
 | 
				            } | 
			
		||||
 | 
				            List<FlightTrackerUtils.PointTemp> 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<double[]> 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<TrackItem> pointTemps) { | 
			
		||||
 | 
				        AtomicReference<Double> breadth = new AtomicReference<>((double) 0); | 
			
		||||
 | 
				        List<double[]> 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<TrackItem> pointTemps,double breadth) { | 
			
		||||
 | 
				        List<double[]> coordinates = pointTemps.stream() | 
			
		||||
 | 
				                .map(item -> new double[]{item.getLng(), item.getLat()}).toList(); | 
			
		||||
 | 
				        return (float) calculateArea(coordinates, breadth); | 
			
		||||
 | 
				    } | 
			
		||||
 | 
				} | 
			
		||||
@ -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; | 
			
		||||
 | 
				    } | 
			
		||||
 | 
				} | 
			
		||||
					Loading…
					
					
				
		Reference in new issue