bug修复

This commit is contained in:
attiya 2025-08-05 09:49:29 +08:00
parent dc477a4398
commit cc8792c6fb
10 changed files with 262 additions and 14 deletions

View File

@ -27,6 +27,7 @@ public class SaTokenConfigure {
// 开放地址 // 开放地址
.addExclude("/order/**") .addExclude("/order/**")
.addExclude("/payment/**") .addExclude("/payment/**")
.addExclude("/operate/ebikeTracking/query")
// 鉴权方法每次访问进入 // 鉴权方法每次访问进入
.setAuth(obj -> { .setAuth(obj -> {
if (isCheck) { if (isCheck) {

View File

@ -27,6 +27,7 @@ import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.*; import java.util.*;
@ -792,7 +793,7 @@ public class EbikeBikeInfoController {
* @return * @return
*/ */
@GetMapping("getDispatchVehicleByOrderId") @GetMapping("getDispatchVehicleByOrderId")
public JsonResult<?> getDispatchVehicleByOrderId(@RequestParam(name = "orderId") String orderId) { public JsonResult<?> getDispatchVehicleByOrderId(@RequestParam(name = "orderId") String orderId) throws IOException {
ResDispatchVehicleDto resDispatchVehicleDto = ebikeBikeInfoService.getDispatchVehicleByOrderId(orderId); ResDispatchVehicleDto resDispatchVehicleDto = ebikeBikeInfoService.getDispatchVehicleByOrderId(orderId);
if (!StringUtils.isEmpty(resDispatchVehicleDto)) { if (!StringUtils.isEmpty(resDispatchVehicleDto)) {
return JsonResult.success("", resDispatchVehicleDto); return JsonResult.success("", resDispatchVehicleDto);

View File

@ -0,0 +1,179 @@
package com.cdzy.ebikemaintenance.model.dto;
import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 电动车调度记录表 实体类
*
* @author zjd
* @since 2025-04-23
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class EbikeDispatchRecordsDto implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 自增主键唯一标识一条记录
*/
@Id
private String id;
/**
* 工单ID表示对应的工单
*/
private String orderId;
private String ecuSn;
private Boolean connected = false;
/**
* 车辆编号表示调度的车辆
*/
private String bikeCode;
/**
* 区域代码
*/
private String areaCode;
/**
* 区域名称
*/
private String areaName;
/**
* 调度前站点ID
*/
private String startStationId;
/**
* 调度后站点ID
*/
private String endStationId;
/**
* 调度前站点
*/
private String startStation;
/**
* 调度前站点级别
*/
private Integer startStationLevel;
/**
* 调度后站点
*/
private String endStation;
/**
* 调度后站点级别
*/
private Integer endStationLevel;
/**
* 调度前车辆纬度
*/
private Double startVehicleLat;
/**
* 调度前车辆经度
*/
private Double startVehicleLng;
/**
* 调度后车辆纬度
*/
private Double endVehicleLat;
/**
* 调度后车辆经度
*/
private Double endVehicleLng;
/**
* 创建时间表示记录创建的时间
*/
@Column(onInsertValue = "now()")
private LocalDateTime createdAt;
/**
* 工单开始时间
*/
private LocalDateTime startTime;
/**
* 工单结束时间
*/
private LocalDateTime endTime;
/**
* 调度状态 0 待调度1 已调度
*/
@Column(onInsertValue = "0")
private String dispatchState;
/**
* 是否变化0表示无变化1表示有变化
*/
@Column(onInsertValue = "0")
private String changeState;
/**
* 是否合格
*/
@Column(onInsertValue = "0")
private String isQualified;
/**
* 调度前SOC电池电量百分比
*/
private Integer preSoc;
/**
* 调度后SOC电池电量百分比
*/
private Integer afterSoc;
/**
* 类型一般表示车辆类型等
*/
private Integer type;
/**
* 调度前图片URL
*/
private String preDispatchImage;
/**
* 调度后图片URL
*/
private String afterDispatchImage;
/**
* 调度前组内车辆数
*/
private Integer beforeGroupVeh;
/**
* 调度后组内车辆数
*/
private Integer afterGroupVeh;
}

View File

@ -1,5 +1,6 @@
package com.cdzy.ebikemaintenance.model.dto.response; package com.cdzy.ebikemaintenance.model.dto.response;
import com.cdzy.ebikemaintenance.model.dto.EbikeDispatchRecordsDto;
import com.cdzy.ebikemaintenance.model.pojo.EbikeBikeOrder; import com.cdzy.ebikemaintenance.model.pojo.EbikeBikeOrder;
import com.cdzy.ebikemaintenance.model.pojo.EbikeDispatchRecords; import com.cdzy.ebikemaintenance.model.pojo.EbikeDispatchRecords;
import com.cdzy.ebikemaintenance.model.pojo.EbikeScheduleWorkOrderExtension; import com.cdzy.ebikemaintenance.model.pojo.EbikeScheduleWorkOrderExtension;
@ -31,6 +32,6 @@ public class ResDispatchVehicleDto {
* 待投放车辆列表 * 待投放车辆列表
* *
*/ */
private List<EbikeDispatchRecords> dispatchRecords; private List<EbikeDispatchRecordsDto> dispatchRecords;
} }

View File

@ -11,6 +11,7 @@ import com.ebike.feign.model.rsp.RspBikeInfo;
import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.service.IService; import com.mybatisflex.core.service.IService;
import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -251,7 +252,7 @@ public interface EbikeBikeInfoService extends IService<EbikeBikeInfo> {
* @param orderId * @param orderId
* @return * @return
*/ */
ResDispatchVehicleDto getDispatchVehicleByOrderId(String orderId); ResDispatchVehicleDto getDispatchVehicleByOrderId(String orderId) throws IOException;
/** /**
* 有工单-根据工单ID 车辆编号 新增调度车车辆 * 有工单-根据工单ID 车辆编号 新增调度车车辆
* @param ebikeDispatchRecordDto * @param ebikeDispatchRecordDto

View File

@ -3,6 +3,7 @@ package com.cdzy.ebikemaintenance.service.impl;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.cdzy.common.enums.Code; import com.cdzy.common.enums.Code;
import com.cdzy.common.model.PageParam; import com.cdzy.common.model.PageParam;
@ -11,15 +12,13 @@ import com.cdzy.common.utils.CoordinateUtil;
import com.cdzy.ebikemaintenance.controller.EbikeInfoCoreController; import com.cdzy.ebikemaintenance.controller.EbikeInfoCoreController;
import com.cdzy.ebikemaintenance.enums.EbikeStatus; import com.cdzy.ebikemaintenance.enums.EbikeStatus;
import com.cdzy.ebikemaintenance.mapper.*; import com.cdzy.ebikemaintenance.mapper.*;
import com.cdzy.ebikemaintenance.model.dto.EbikeDispatchRecordsDto;
import com.cdzy.ebikemaintenance.model.dto.request.*; import com.cdzy.ebikemaintenance.model.dto.request.*;
import com.cdzy.ebikemaintenance.model.dto.response.*; import com.cdzy.ebikemaintenance.model.dto.response.*;
import com.cdzy.ebikemaintenance.model.pojo.*; import com.cdzy.ebikemaintenance.model.pojo.*;
import com.cdzy.ebikemaintenance.service.EbikeBikeInfoService; import com.cdzy.ebikemaintenance.service.EbikeBikeInfoService;
import com.cdzy.ebikemaintenance.service.EbikeBikeOrderService; import com.cdzy.ebikemaintenance.service.EbikeBikeOrderService;
import com.cdzy.ebikemaintenance.utils.GeoCodingUtil; import com.cdzy.ebikemaintenance.utils.*;
import com.cdzy.ebikemaintenance.utils.MinioUtil;
import com.cdzy.ebikemaintenance.utils.RedisUtil;
import com.cdzy.ebikemaintenance.utils.TimeUtils;
import com.ebike.feign.clients.OperateFeignClient; import com.ebike.feign.clients.OperateFeignClient;
import com.ebike.feign.clients.StaffFeignClient; import com.ebike.feign.clients.StaffFeignClient;
import com.ebike.feign.model.res.ReqEcuSnDto; import com.ebike.feign.model.res.ReqEcuSnDto;
@ -1266,15 +1265,32 @@ public class EbikeBikeInfoServiceImpl extends ServiceImpl<EbikeBikeInfoMapper, E
* @param orderId * @param orderId
* @return * @return
*/ */
public ResDispatchVehicleDto getDispatchVehicleByOrderId(String orderId) { public ResDispatchVehicleDto getDispatchVehicleByOrderId(String orderId) throws IOException {
ResDispatchVehicleDto resDispatchVehicleDto = new ResDispatchVehicleDto(); ResDispatchVehicleDto resDispatchVehicleDto = new ResDispatchVehicleDto();
EbikeBikeOrder ebikeBikeOrder = ebikeBikeOrderMapper.selectOneById(orderId); EbikeBikeOrder ebikeBikeOrder = ebikeBikeOrderMapper.selectOneById(orderId);
EbikeScheduleWorkOrderExtension ebikeScheduleWorkOrderExtension = ebikeScheduleWorkOrderExtensionMapper.selectOneById(orderId); EbikeScheduleWorkOrderExtension ebikeScheduleWorkOrderExtension = ebikeScheduleWorkOrderExtensionMapper.selectOneById(orderId);
QueryWrapper query = QueryWrapper.create(); QueryWrapper query = QueryWrapper.create();
query.eq("order_id", orderId); query.select(EBIKE_DISPATCH_RECORDS.ALL_COLUMNS,EBIKE_ECU_INFO.ECU_SN)
query.eq("dispatch_state", "0"); //并且查询待处理的工单 .where(EBIKE_DISPATCH_RECORDS.ORDER_ID.eq(orderId))
List<EbikeDispatchRecords> ebikeDispatchRecords = ebikeDispatchRecordsMapper.selectListByQuery(query); .where(EBIKE_DISPATCH_RECORDS.DISPATCH_STATE.eq("0"))
.leftJoin(EBIKE_BIKE_INFO).on(EBIKE_DISPATCH_RECORDS.BIKE_CODE.eq(EBIKE_BIKE_INFO.BIKE_CODE))
.rightJoin(EBIKE_ECU_INFO).on(EBIKE_BIKE_INFO.ECU_ID.eq(EBIKE_ECU_INFO.ECU_ID)); //并且查询待处理的工单
List<EbikeDispatchRecordsDto> ebikeDispatchRecords = ebikeDispatchRecordsMapper.selectListByQueryAs(query, EbikeDispatchRecordsDto.class);
List<String> bikeCodes = ebikeDispatchRecords.stream().map(EbikeDispatchRecordsDto::getBikeCode).toList();
query.clear();
query.select(EBIKE_ECU_INFO.ECU_SN).where(EBIKE_BIKE_INFO.BIKE_CODE.in(bikeCodes))
.leftJoin(EBIKE_ECU_INFO).on(EBIKE_ECU_INFO.ECU_ID.eq(EBIKE_BIKE_INFO.ECU_ID));
List<String> list = ebikeBikeInfoMapper.selectListByQueryAs(query, String.class);
JSONObject jsonObject = EmqxApiClient.isClientsOnline(list);
ebikeDispatchRecords.forEach(res->{
String ecuSn = res.getEcuSn();
JSONObject object = jsonObject.getJSONObject(ecuSn);
if (object != null && object.getBooleanValue("connected")){
res.setConnected(Boolean.TRUE);
}
});
resDispatchVehicleDto.setOrderId(orderId); resDispatchVehicleDto.setOrderId(orderId);
resDispatchVehicleDto.setDispatchRecords(ebikeDispatchRecords); resDispatchVehicleDto.setDispatchRecords(ebikeDispatchRecords);

View File

@ -4,6 +4,7 @@ import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.cdzy.ebikemaintenance.config.EmqxConfig; import com.cdzy.ebikemaintenance.config.EmqxConfig;
import okhttp3.*; import okhttp3.*;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -21,7 +22,22 @@ public class EmqxApiClient {
private static Request.Builder buildBaseRequest(String path) { private static Request.Builder buildBaseRequest(String path) {
return new Request.Builder() return new Request.Builder()
.url(EmqxConfig.getApiUrl() + path) .url(EmqxConfig.getApiUrl() + path)
.header("Authorization", Credentials.basic(EmqxConfig.getApiKey(), EmqxConfig.getApiSecret())); .header("Authorization", Credentials.basic(EmqxConfig.getApiKey(), EmqxConfig.getApiSecret()));
}
// 构建基础请求添加认证头
private static Request.Builder buildClientsRequest(String path, List<String> clientIds) {
String url = EmqxConfig.getApiUrl() + path;
StringBuilder urlBuilder = new StringBuilder();
urlBuilder.append(url);
for (String clientId : clientIds) {
urlBuilder.append("clientid=")
.append(clientId)
.append("&");
}
return new Request.Builder()
.url(urlBuilder.toString())
.header("Authorization", Credentials.basic(EmqxConfig.getApiKey(), EmqxConfig.getApiSecret()));
} }
// 发送 HTTP 请求并返回响应 // 发送 HTTP 请求并返回响应
@ -59,6 +75,28 @@ public class EmqxApiClient {
return json.getBooleanValue("connected"); return json.getBooleanValue("connected");
} }
// 查询设备在线状态
public static JSONObject isClientsOnline(List<String> clientsIds) throws IOException {
//TODO:数量问题可以考虑分批处理
Request request = buildClientsRequest("/clients?" ,clientsIds)
.get()
.build();
String response = executeRequest(request);
JSONObject json = JSONObject.parseObject(response);
List<JSONObject> list = json.getJSONArray("data").toList(JSONObject.class);
JSONObject result = new JSONObject();
list.forEach(e->{
boolean connected = e.getBooleanValue("connected");
JSONObject jsonObject = new JSONObject();
String clientid = e.getString("clientid");
jsonObject.put("connected", connected);
jsonObject.put("ecuSn", clientid);
result.put(clientid,jsonObject);
});
return result;
}
// 强制断开设备连接 // 强制断开设备连接
public static void kickClient(String clientId) throws IOException { public static void kickClient(String clientId) throws IOException {
Request request = buildBaseRequest("/clients/" + clientId) Request request = buildBaseRequest("/clients/" + clientId)
@ -100,4 +138,13 @@ public class EmqxApiClient {
executeRequest(request); executeRequest(request);
} }
// 将大列表分割为多个小列表
private static <T> List<List<T>> partitionList(List<T> list, int batchSize) {
List<List<T>> batches = new ArrayList<>();
for (int i = 0; i < list.size(); i += batchSize) {
batches.add(list.subList(i, Math.min(i + batchSize, list.size())));
}
return batches;
}
} }

View File

@ -57,7 +57,7 @@ public class EbikeTrackingServiceImpl implements EbikeTrackingService {
} }
@Override @Override
public List<EbikeTrackingDto> query(ReqEbikeTrackingDto reqEbikeTrackingDto) { public List<EbikeTrackingDto> query(ReqEbikeTrackingDto reqEbikeTrackingDto) {
try{ try{
JsonResult<?> jsonResult = maintenanceFeignClient.getEbikeEcuSnByID(reqEbikeTrackingDto.getEbikeCode()); JsonResult<?> jsonResult = maintenanceFeignClient.getEbikeEcuSnByID(reqEbikeTrackingDto.getEbikeCode());
if (jsonResult.getCode() == 200) { if (jsonResult.getCode() == 200) {

View File

@ -56,4 +56,6 @@ public class EbikeUserDto implements Serializable {
*/ */
private Boolean realNameStatus; private Boolean realNameStatus;
private String avatar;
} }

View File

@ -32,7 +32,7 @@ public class EbikeUserServiceImpl extends ServiceImpl<EbikeUserMapper, EbikeUser
public EbikeUserDto getUserByOpenId(String openId) { public EbikeUserDto getUserByOpenId(String openId) {
QueryWrapper query = QueryWrapper.create(); QueryWrapper query = QueryWrapper.create();
query.select(EBIKE_USER.USER_ID, EBIKE_USER.MOBILE, EBIKE_USER.NICKNAME, EBIKE_USER.CREATED_AT, query.select(EBIKE_USER.USER_ID, EBIKE_USER.MOBILE, EBIKE_USER.NICKNAME, EBIKE_USER.CREATED_AT,
EBIKE_USER.UPDATED_AT, EBIKE_USER.LAST_LOGIN_AT); EBIKE_USER.UPDATED_AT, EBIKE_USER.LAST_LOGIN_AT,EBIKE_USER.AVATAR);
query.select(QueryMethods.case_(EBIKE_USER.STATUS).when(1).then("正常") query.select(QueryMethods.case_(EBIKE_USER.STATUS).when(1).then("正常")
.else_("禁用").end().as("status")); .else_("禁用").end().as("status"));
query.select(QueryMethods.case_(EBIKE_USER_REALINFO.STATUS) query.select(QueryMethods.case_(EBIKE_USER_REALINFO.STATUS)