地址映射工具类、工单车辆详情

This commit is contained in:
attiya 2025-12-03 16:45:32 +08:00
parent 09e8a8d5c0
commit 924b62671f
7 changed files with 371 additions and 5 deletions

View File

@ -0,0 +1,22 @@
package com.cdzy.operations.config;
import com.cdzy.operations.utils.GeoCodingUtil;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Setter
@Getter
@Configuration
@ConfigurationProperties(prefix = "geo-coding")
public class GeoCodingConfig {
private String apiUrl;
private String accessKey;
@Bean
public GeoCodingUtil geoCodingUtil() {
return new GeoCodingUtil(apiUrl, accessKey);
}
}

View File

@ -7,6 +7,7 @@ import com.cdzy.common.model.response.JsonResult;
import com.cdzy.operations.enums.BikeOrderHandleState; import com.cdzy.operations.enums.BikeOrderHandleState;
import com.cdzy.operations.model.dto.EbikeBikeOrderInfoDto; import com.cdzy.operations.model.dto.EbikeBikeOrderInfoDto;
import com.cdzy.operations.model.dto.EbikeBikeOrderPageDto; import com.cdzy.operations.model.dto.EbikeBikeOrderPageDto;
import com.cdzy.operations.model.dto.EbikeOrderBikeInfoDto;
import com.cdzy.operations.model.vo.EbikeBatteryChangeVo; import com.cdzy.operations.model.vo.EbikeBatteryChangeVo;
import com.cdzy.operations.model.vo.EbikeBatteryClaimReturnVo; import com.cdzy.operations.model.vo.EbikeBatteryClaimReturnVo;
import com.cdzy.operations.model.vo.FaultOrderVo; import com.cdzy.operations.model.vo.FaultOrderVo;
@ -207,4 +208,15 @@ public class EbikeBikeOrderController {
ebikeBikeOrderService.batteryChange(changeVo); ebikeBikeOrderService.batteryChange(changeVo);
return JsonResult.success(Message.SUCCESS); return JsonResult.success(Message.SUCCESS);
} }
/**
* 车辆详情工单用
*
* @return 操作结果
*/
@GetMapping("bikeInfo")
public JsonResult<?> bikeInfo(@RequestParam("bikeCode") String bikeCode) {
EbikeOrderBikeInfoDto info = ebikeBikeOrderService.bikeInfo(bikeCode);
return JsonResult.success(info);
}
} }

View File

@ -6,8 +6,6 @@ import com.cdzy.operations.handler.PGpointTypeHandler;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.mybatisflex.annotation.Column; import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.Table;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
@ -19,7 +17,7 @@ import java.io.Serializable;
import java.time.LocalDateTime; import java.time.LocalDateTime;
/** /**
* 实体类 * 车辆详情
* *
* @author attiya * @author attiya
* @since 2025-10-21 * @since 2025-10-21
@ -28,7 +26,6 @@ import java.time.LocalDateTime;
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@Table("ebike_bike_info")
public class EbikeBikeInfoDto implements Serializable { public class EbikeBikeInfoDto implements Serializable {
@Serial @Serial
@ -37,7 +34,6 @@ public class EbikeBikeInfoDto implements Serializable {
/** /**
* 车辆详情ID * 车辆详情ID
*/ */
@Id
private Long bikeInfoId; private Long bikeInfoId;
/** /**

View File

@ -0,0 +1,129 @@
package com.cdzy.operations.model.dto;
import com.cdzy.operations.handler.PGpointDeserializer;
import com.cdzy.operations.handler.PGpointSerializer;
import com.cdzy.operations.handler.PGpointTypeHandler;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.mybatisflex.annotation.Column;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.postgresql.geometric.PGpoint;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 车辆详情
*
* @author attiya
* @since 2025-10-21
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class EbikeOrderBikeInfoDto implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 车辆详情ID
*/
private Long bikeInfoId;
/**
* 运营商ID
*/
private Long operatorId;
/**
* 运营区ID
*/
private Long regionId;
/**
* 运营区名称
*/
private String regionName;
/**
* 车辆编号与车辆二维码编号相同
*/
private String bikeCode;
/**
* 电池ID
*/
private Long batteryId;
/**
* 中控ID
*/
private Long ecuId;
/**
* 头盔ID
*/
private Long helmetId;
/**
* 定位
*/
@Column(typeHandler = PGpointTypeHandler.class)
@JsonSerialize(using = PGpointSerializer.class)
@JsonDeserialize(using = PGpointDeserializer.class)
private PGpoint location;
/**
* 备注
*/
private String remarks;
/**
* 车辆状态
*/
private Integer status;
/**
* 车辆使用状态
*/
private Integer usageStatus;
/**
* 创建时间
*/
@Column(onInsertValue = "now()")
private LocalDateTime createdAt;
/**
* 创建人
*/
private Long createdBy;
/**
* 修改时间
*/
@Column(onUpdateValue = "now()")
private LocalDateTime updatedAt;
/**
* 修改人
*/
private Long updatedBy;
/**
* 删除与否
*/
private Boolean isDeleted;
/**
* 是否包含头盔
*/
private Boolean hasHelme;
}

View File

@ -1,6 +1,7 @@
package com.cdzy.operations.service; package com.cdzy.operations.service;
import com.cdzy.operations.model.dto.EbikeBikeOrderInfoDto; import com.cdzy.operations.model.dto.EbikeBikeOrderInfoDto;
import com.cdzy.operations.model.dto.EbikeOrderBikeInfoDto;
import com.cdzy.operations.model.entity.EbikeBikeOrder; import com.cdzy.operations.model.entity.EbikeBikeOrder;
import com.cdzy.operations.model.vo.EbikeBatteryChangeVo; import com.cdzy.operations.model.vo.EbikeBatteryChangeVo;
import com.cdzy.operations.model.vo.EbikeBatteryClaimReturnVo; import com.cdzy.operations.model.vo.EbikeBatteryClaimReturnVo;
@ -86,4 +87,11 @@ public interface EbikeBikeOrderService extends IService<EbikeBikeOrder> {
* @param changeVo 更换信息 * @param changeVo 更换信息
*/ */
void batteryChange(EbikeBatteryChangeVo changeVo); void batteryChange(EbikeBatteryChangeVo changeVo);
/**
* 获取车辆详情
* @param bikeCode 车辆编号
* @return 详情
*/
EbikeOrderBikeInfoDto bikeInfo(String bikeCode);
} }

View File

@ -7,6 +7,7 @@ import com.cdzy.common.model.dto.ResGPSDto;
import com.cdzy.operations.enums.*; import com.cdzy.operations.enums.*;
import com.cdzy.operations.mapper.*; import com.cdzy.operations.mapper.*;
import com.cdzy.operations.model.dto.EbikeBikeOrderInfoDto; import com.cdzy.operations.model.dto.EbikeBikeOrderInfoDto;
import com.cdzy.operations.model.dto.EbikeOrderBikeInfoDto;
import com.cdzy.operations.model.entity.*; import com.cdzy.operations.model.entity.*;
import com.cdzy.operations.model.vo.EbikeBatteryChangeVo; import com.cdzy.operations.model.vo.EbikeBatteryChangeVo;
import com.cdzy.operations.model.vo.EbikeBatteryClaimReturnVo; import com.cdzy.operations.model.vo.EbikeBatteryClaimReturnVo;
@ -369,6 +370,11 @@ public class EbikeBikeOrderServiceImpl extends ServiceImpl<EbikeBikeOrderMapper,
} }
@Override
public EbikeOrderBikeInfoDto bikeInfo(String bikeCode) {
return null;
}
EbikeBikeInfo checkBikeCode(String bikeCode) { EbikeBikeInfo checkBikeCode(String bikeCode) {
QueryWrapper queryWrapper = QueryWrapper.create() QueryWrapper queryWrapper = QueryWrapper.create()
.where(EBIKE_BIKE_INFO.BIKE_CODE.eq(bikeCode)) .where(EBIKE_BIKE_INFO.BIKE_CODE.eq(bikeCode))

View File

@ -0,0 +1,193 @@
package com.cdzy.operations.utils;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.stereotype.Service;
import java.util.Arrays;
/**
* 地址解析反解析工具类
* 目前实现的高德地图webservice,位置是[经度, 维度], 腾讯地图webservice的位置是[维度, 经度]
*
* @author dingchao
* @since 2025/4/3
*/
@Slf4j
@Service
public class GeoCodingUtil {
// webservice接口腾讯地图webservice 为空
private final static String LOCATION_TO_ADDRESS = "regeo";
private final static String ADDRESS_TO_LOCATION = "geo";
private final static String STATUS_KEY = "status";
private final static String LONGITUDE_KEY = "lng";
private final static String LATITUDE_KEY = "lat";
// 结果键 高德地图webservice 为geocodesregeocode腾讯地图webservice为result
private final static String ADDRESS_RESULT_KEY = "regeocode";
private final static String LOCATION_RESULT_KEY = "geocodes";
//private final static String RESULT_KEY = "geocodes";
// 成功状态码 高德地图webservice 为1腾讯地图webservice为0
private final static int CODE_STATUS_SUCCESS = 1;
// 地址键 高德地图webservice 为formatted_address腾讯地图webservice为formatted_addresses-->standard_address
//private final static String ADDRESS_KEY = "formatted_addresses";
private final static String ADDRESS_KEY = "formatted_address";
private final static String STANDARD_ADDRESS_KEY = "standard_address";
// 位置键 高德地图webservice 为location腾讯地图webservice为location
private final static String LOCATION_KEY = "location";
// 地址详情键 高德地图webservice 为addressComponent腾讯地图webservice为ad_info
private final static String ADDRESS_COMPONENT_KEY = "addressComponent";
private final static String DISTRICT_KEY = "district";
private final static String ADCODE_KEY = "adcode";
private final static String MSG_KEY = "message";
private final String url;
private final String accessKey;
private final OkHttpClient client;
private final ObjectMapper objectMapper;
/**
* 地理编码工具类构造函数
* 目前实现的腾讯地图webservice
*
* @param apiUrl
* @param accessKey
*/
public GeoCodingUtil(String apiUrl, String accessKey) {
this.url = apiUrl;
this.accessKey = accessKey;
this.client = new OkHttpClient();
this.objectMapper = new ObjectMapper();
}
/**
* 输入经纬度返回地址
*
* @param location 经纬度
* @return 地址
*/
public String getLocationToAddress(JsonNode location) {
//String locationStr = String.format("%f,%f", location.getDouble(LATITUDE_KEY), location.getDouble(LONGITUDE_KEY));
String locationStr = String.format("%f,%f", location.get(LONGITUDE_KEY).asDouble(), location.get(LATITUDE_KEY).asDouble());
Request request = new Request.Builder()
.url(url + "/"+LOCATION_TO_ADDRESS + "?"+"location=" + locationStr + "&key=" + accessKey)
.build();
try(Response response = client.newCall(request).execute()) {
if(response.isSuccessful()) {
if (response.body()!= null) {
String result = response.body().string();
JsonNode jsonObject = objectMapper.readTree(result);
if (jsonObject.get(STATUS_KEY).asInt() == CODE_STATUS_SUCCESS) {
//return jsonObject.getJSONObject(RESULT_KEY).getJSONObject(ADDRESS_KEY).getString(STANDARD_ADDRESS_KEY);
return jsonObject.get(ADDRESS_RESULT_KEY).get(ADDRESS_KEY).asText();
}
logError("地址解析失败==>{}", jsonObject.get(MSG_KEY).asText());
return null;
}
logError("地址解析失败==>{}", response.message());
return null;
}
logError("地址解析失败==>{}", response.message());
return null;
} catch (Exception e) {
logError("地址解析失败==>{}", e.getMessage() + Arrays.toString(e.getStackTrace()));
return null;
}
}
/**
* 输入经纬度返回地址明细(含区域ID县区名)
*
* @param location 经纬度
* @return 地址
*/
public JsonNode getLocationToAddressDetails(JsonNode location) {
//String locationStr = String.format("%f,%f", location.getDouble(LATITUDE_KEY), location.getDouble(LONGITUDE_KEY));
String locationStr = String.format("%f,%f", location.get(LONGITUDE_KEY).asDouble(), location.get(LATITUDE_KEY).asDouble());
Request request = new Request.Builder()
.url(url + "/"+LOCATION_TO_ADDRESS + "?location=" + locationStr + "&key=" + accessKey)
.build();
try(Response response = client.newCall(request).execute()) {
if(response.isSuccessful()) {
if (response.body()!= null) {
String result = response.body().string();
JsonNode jsonObject = objectMapper.readTree(result);
if (jsonObject.get(STATUS_KEY).asInt() == CODE_STATUS_SUCCESS) {
JsonNode address = objectMapper.createObjectNode();
//String detail = jsonObject.getJSONObject(ADDRESS_RESULT_KEY).getJSONObject(ADDRESS_KEY).getString(STANDARD_ADDRESS_KEY);
String detail = jsonObject.get(ADDRESS_RESULT_KEY).get(ADDRESS_KEY).asText();
((com.fasterxml.jackson.databind.node.ObjectNode) address).put("detail", detail);
//String district = jsonObject.getJSONObject(ADDRESS_RESULT_KEY).getJSONObject(ADDRESS_COMPONENT_KEY).getString(DISTRICT_KEY);
String district = jsonObject.get(ADDRESS_RESULT_KEY).get(ADDRESS_COMPONENT_KEY).get(DISTRICT_KEY).asText();
((com.fasterxml.jackson.databind.node.ObjectNode) address).put("district", district);
//String adcode = jsonObject.getJSONObject(ADDRESS_RESULT_KEY).getJSONObject(ADDRESS_COMPONENT_KEY).getString(ADCODE_KEY);
String adcode = jsonObject.get(ADDRESS_RESULT_KEY).get(ADDRESS_COMPONENT_KEY).get(ADCODE_KEY).asText();
((com.fasterxml.jackson.databind.node.ObjectNode) address).put("adcode", adcode);
return address;
}
logError("地址解析失败==>{}", jsonObject.get(MSG_KEY).asText());
return null;
}
logError("地址解析失败==>{}", response.message());
return null;
}
logError("地址解析失败==>{}", response.message());
return null;
} catch (Exception e) {
logError("地址解析失败==>{}", e.getMessage() + Arrays.toString(e.getStackTrace()));
return null;
}
}
/**
* 输入地址返回经纬度(GCJ02)
*
* @param address 地址
* @return 经纬度
*/
public JsonNode getAddressToLocation(String address) {
Request request = new Request.Builder()
.url(url + "/"+ADDRESS_TO_LOCATION + "?address=" + address + "&key=" + accessKey)
.build();
try(Response response = client.newCall(request).execute()) {
if(response.isSuccessful()) {
if (response.body() != null) {
String result = response.body().string();
JsonNode jsonObject = objectMapper.readTree(result);
if (jsonObject.get(STATUS_KEY).asInt() == CODE_STATUS_SUCCESS) {
// 腾讯地图webservice的位置是 JSONObject {"lat": 39.9042, "lng": 116.4074}
//return jsonObject.getJSONObject(LOCATION_RESULT_KEY).getJSONObject(LOCATION_KEY);
String loc = jsonObject.get(LOCATION_RESULT_KEY).get(0).get(LOCATION_KEY).asText();
String[] locArr = loc.split(",");
ObjectNode location = objectMapper.createObjectNode();
location.put("lng", Double.valueOf(locArr[0]));
location.put("lat", Double.valueOf(locArr[1]));
return location;
}else{
logError("位置解析失败==>{}", jsonObject.get(MSG_KEY).asText());
return null;
}
}else{
logError("位置解析失败==>{}", response.message());
return null;
}
}else{
logError("位置解析失败==>{}", response.message());
return null;
}
} catch (Exception e) {
logError("位置解析失败==>{}", e.getMessage() + Arrays.toString(e.getStackTrace()));
return null;
}
}
private void logError(String errDesc, String errorMessage) {
log.error(errDesc, errorMessage);
}
}