From cc8792c6fb23370f30f2435742b71ac884ff0df1 Mon Sep 17 00:00:00 2001 From: attiya <2413103649@qq.com> Date: Tue, 5 Aug 2025 09:49:29 +0800 Subject: [PATCH] =?UTF-8?q?bug=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cdzy/gateway/config/SaTokenConfigure.java | 1 + .../controller/EbikeBikeInfoController.java | 3 +- .../model/dto/EbikeDispatchRecordsDto.java | 179 ++++++++++++++++++ .../dto/response/ResDispatchVehicleDto.java | 3 +- .../service/EbikeBikeInfoService.java | 3 +- .../impl/EbikeBikeInfoServiceImpl.java | 32 +++- .../ebikemaintenance/utils/EmqxApiClient.java | 49 ++++- .../impl/EbikeTrackingServiceImpl.java | 2 +- .../orders/model/dto/res/EbikeUserDto.java | 2 + .../service/impl/EbikeUserServiceImpl.java | 2 +- 10 files changed, 262 insertions(+), 14 deletions(-) create mode 100644 ebike-maintenance/src/main/java/com/cdzy/ebikemaintenance/model/dto/EbikeDispatchRecordsDto.java diff --git a/ebike-gateway/src/main/java/com/cdzy/gateway/config/SaTokenConfigure.java b/ebike-gateway/src/main/java/com/cdzy/gateway/config/SaTokenConfigure.java index cca601ed..0a15062e 100644 --- a/ebike-gateway/src/main/java/com/cdzy/gateway/config/SaTokenConfigure.java +++ b/ebike-gateway/src/main/java/com/cdzy/gateway/config/SaTokenConfigure.java @@ -27,6 +27,7 @@ public class SaTokenConfigure { // 开放地址 .addExclude("/order/**") .addExclude("/payment/**") + .addExclude("/operate/ebikeTracking/query") // 鉴权方法:每次访问进入 .setAuth(obj -> { if (isCheck) { diff --git a/ebike-maintenance/src/main/java/com/cdzy/ebikemaintenance/controller/EbikeBikeInfoController.java b/ebike-maintenance/src/main/java/com/cdzy/ebikemaintenance/controller/EbikeBikeInfoController.java index 1f88bb23..0cf6b2e6 100644 --- a/ebike-maintenance/src/main/java/com/cdzy/ebikemaintenance/controller/EbikeBikeInfoController.java +++ b/ebike-maintenance/src/main/java/com/cdzy/ebikemaintenance/controller/EbikeBikeInfoController.java @@ -27,6 +27,7 @@ import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; +import java.io.IOException; import java.io.InputStream; import java.time.LocalDateTime; import java.util.*; @@ -792,7 +793,7 @@ public class EbikeBikeInfoController { * @return */ @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); if (!StringUtils.isEmpty(resDispatchVehicleDto)) { return JsonResult.success("", resDispatchVehicleDto); diff --git a/ebike-maintenance/src/main/java/com/cdzy/ebikemaintenance/model/dto/EbikeDispatchRecordsDto.java b/ebike-maintenance/src/main/java/com/cdzy/ebikemaintenance/model/dto/EbikeDispatchRecordsDto.java new file mode 100644 index 00000000..9508e846 --- /dev/null +++ b/ebike-maintenance/src/main/java/com/cdzy/ebikemaintenance/model/dto/EbikeDispatchRecordsDto.java @@ -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; + +} diff --git a/ebike-maintenance/src/main/java/com/cdzy/ebikemaintenance/model/dto/response/ResDispatchVehicleDto.java b/ebike-maintenance/src/main/java/com/cdzy/ebikemaintenance/model/dto/response/ResDispatchVehicleDto.java index 490d2847..11015760 100644 --- a/ebike-maintenance/src/main/java/com/cdzy/ebikemaintenance/model/dto/response/ResDispatchVehicleDto.java +++ b/ebike-maintenance/src/main/java/com/cdzy/ebikemaintenance/model/dto/response/ResDispatchVehicleDto.java @@ -1,5 +1,6 @@ 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.EbikeDispatchRecords; import com.cdzy.ebikemaintenance.model.pojo.EbikeScheduleWorkOrderExtension; @@ -31,6 +32,6 @@ public class ResDispatchVehicleDto { * 待投放车辆列表 * */ - private List dispatchRecords; + private List dispatchRecords; } diff --git a/ebike-maintenance/src/main/java/com/cdzy/ebikemaintenance/service/EbikeBikeInfoService.java b/ebike-maintenance/src/main/java/com/cdzy/ebikemaintenance/service/EbikeBikeInfoService.java index 7a43c531..4605bc90 100644 --- a/ebike-maintenance/src/main/java/com/cdzy/ebikemaintenance/service/EbikeBikeInfoService.java +++ b/ebike-maintenance/src/main/java/com/cdzy/ebikemaintenance/service/EbikeBikeInfoService.java @@ -11,6 +11,7 @@ import com.ebike.feign.model.rsp.RspBikeInfo; import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.service.IService; +import java.io.IOException; import java.util.List; import java.util.Map; @@ -251,7 +252,7 @@ public interface EbikeBikeInfoService extends IService { * @param orderId * @return */ - ResDispatchVehicleDto getDispatchVehicleByOrderId(String orderId); + ResDispatchVehicleDto getDispatchVehicleByOrderId(String orderId) throws IOException; /** * 有工单-根据工单ID 车辆编号 新增调度车车辆 * @param ebikeDispatchRecordDto diff --git a/ebike-maintenance/src/main/java/com/cdzy/ebikemaintenance/service/impl/EbikeBikeInfoServiceImpl.java b/ebike-maintenance/src/main/java/com/cdzy/ebikemaintenance/service/impl/EbikeBikeInfoServiceImpl.java index 0afcb466..aa08bd87 100644 --- a/ebike-maintenance/src/main/java/com/cdzy/ebikemaintenance/service/impl/EbikeBikeInfoServiceImpl.java +++ b/ebike-maintenance/src/main/java/com/cdzy/ebikemaintenance/service/impl/EbikeBikeInfoServiceImpl.java @@ -3,6 +3,7 @@ package com.cdzy.ebikemaintenance.service.impl; import cn.dev33.satoken.stp.StpUtil; import cn.hutool.core.map.MapUtil; import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.cdzy.common.enums.Code; 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.enums.EbikeStatus; 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.response.*; import com.cdzy.ebikemaintenance.model.pojo.*; import com.cdzy.ebikemaintenance.service.EbikeBikeInfoService; import com.cdzy.ebikemaintenance.service.EbikeBikeOrderService; -import com.cdzy.ebikemaintenance.utils.GeoCodingUtil; -import com.cdzy.ebikemaintenance.utils.MinioUtil; -import com.cdzy.ebikemaintenance.utils.RedisUtil; -import com.cdzy.ebikemaintenance.utils.TimeUtils; +import com.cdzy.ebikemaintenance.utils.*; import com.ebike.feign.clients.OperateFeignClient; import com.ebike.feign.clients.StaffFeignClient; import com.ebike.feign.model.res.ReqEcuSnDto; @@ -1266,15 +1265,32 @@ public class EbikeBikeInfoServiceImpl extends ServiceImpl ebikeDispatchRecords = ebikeDispatchRecordsMapper.selectListByQuery(query); + query.select(EBIKE_DISPATCH_RECORDS.ALL_COLUMNS,EBIKE_ECU_INFO.ECU_SN) + .where(EBIKE_DISPATCH_RECORDS.ORDER_ID.eq(orderId)) + .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 ebikeDispatchRecords = ebikeDispatchRecordsMapper.selectListByQueryAs(query, EbikeDispatchRecordsDto.class); + List 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 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.setDispatchRecords(ebikeDispatchRecords); diff --git a/ebike-maintenance/src/main/java/com/cdzy/ebikemaintenance/utils/EmqxApiClient.java b/ebike-maintenance/src/main/java/com/cdzy/ebikemaintenance/utils/EmqxApiClient.java index 21f6124f..4f2ab582 100644 --- a/ebike-maintenance/src/main/java/com/cdzy/ebikemaintenance/utils/EmqxApiClient.java +++ b/ebike-maintenance/src/main/java/com/cdzy/ebikemaintenance/utils/EmqxApiClient.java @@ -4,6 +4,7 @@ import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.cdzy.ebikemaintenance.config.EmqxConfig; import okhttp3.*; + import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -21,7 +22,22 @@ public class EmqxApiClient { private static Request.Builder buildBaseRequest(String path) { return new Request.Builder() .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 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 请求并返回响应 @@ -59,6 +75,28 @@ public class EmqxApiClient { return json.getBooleanValue("connected"); } + // 查询设备在线状态 + public static JSONObject isClientsOnline(List clientsIds) throws IOException { + //TODO:数量问题可以考虑分批处理 + Request request = buildClientsRequest("/clients?" ,clientsIds) + .get() + .build(); + + String response = executeRequest(request); + JSONObject json = JSONObject.parseObject(response); + List 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 { Request request = buildBaseRequest("/clients/" + clientId) @@ -100,4 +138,13 @@ public class EmqxApiClient { executeRequest(request); } + + // 将大列表分割为多个小列表 + private static List> partitionList(List list, int batchSize) { + List> 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; + } } diff --git a/ebike-operate/src/main/java/com/cdzy/ebikeoperate/service/impl/EbikeTrackingServiceImpl.java b/ebike-operate/src/main/java/com/cdzy/ebikeoperate/service/impl/EbikeTrackingServiceImpl.java index aa437d97..a424b573 100644 --- a/ebike-operate/src/main/java/com/cdzy/ebikeoperate/service/impl/EbikeTrackingServiceImpl.java +++ b/ebike-operate/src/main/java/com/cdzy/ebikeoperate/service/impl/EbikeTrackingServiceImpl.java @@ -57,7 +57,7 @@ public class EbikeTrackingServiceImpl implements EbikeTrackingService { } @Override - public List query(ReqEbikeTrackingDto reqEbikeTrackingDto) { + public List query(ReqEbikeTrackingDto reqEbikeTrackingDto) { try{ JsonResult jsonResult = maintenanceFeignClient.getEbikeEcuSnByID(reqEbikeTrackingDto.getEbikeCode()); if (jsonResult.getCode() == 200) { diff --git a/ebike-orders/src/main/java/com/cdzy/orders/model/dto/res/EbikeUserDto.java b/ebike-orders/src/main/java/com/cdzy/orders/model/dto/res/EbikeUserDto.java index 2143c0e7..6f984de3 100644 --- a/ebike-orders/src/main/java/com/cdzy/orders/model/dto/res/EbikeUserDto.java +++ b/ebike-orders/src/main/java/com/cdzy/orders/model/dto/res/EbikeUserDto.java @@ -56,4 +56,6 @@ public class EbikeUserDto implements Serializable { */ private Boolean realNameStatus; + private String avatar; + } diff --git a/ebike-orders/src/main/java/com/cdzy/orders/service/impl/EbikeUserServiceImpl.java b/ebike-orders/src/main/java/com/cdzy/orders/service/impl/EbikeUserServiceImpl.java index 7a756c52..e4f55a2c 100644 --- a/ebike-orders/src/main/java/com/cdzy/orders/service/impl/EbikeUserServiceImpl.java +++ b/ebike-orders/src/main/java/com/cdzy/orders/service/impl/EbikeUserServiceImpl.java @@ -32,7 +32,7 @@ public class EbikeUserServiceImpl extends ServiceImpl