调整首页, 优化接口

This commit is contained in:
andy 2025-05-15 17:29:07 +08:00
parent c7da74d85b
commit f4f5766eeb
48 changed files with 1267 additions and 242 deletions

View File

@ -43,7 +43,6 @@ import org.springframework.util.StringUtils;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
@Slf4j
@ -231,13 +230,13 @@ public class LoginServiceImpl implements LoginService {
}
private void asyncIndexTask(){
CompletableFuture<Void> asyncTask = CompletableFuture.runAsync(()->{
try {
cloudService.loadIndexData();
} catch (Exception e) {
log.error("异步处理首页数据异常:{}", e.getMessage());
}
});
// CompletableFuture<Void> asyncTask = CompletableFuture.runAsync(()->{
// try {
// cloudService.loadIndexData();
// } catch (Exception e) {
// log.error("异步处理首页数据异常:{}", e.getMessage());
// }
// });
}

View File

@ -0,0 +1,34 @@
package com.evotech.hd.common.core.Dto.request.template;
import lombok.Data;
import java.util.List;
import java.util.Map;
/**
*
*
* @ClassName:AlarmTemplateDto
* @date: 2025年05月05日 16:29
* @author: andy.shi
* @contact: 17330188597
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
@Data
public class StopServerTemplateDto {
/***
* key 用户的wuid, value为用户的车牌号信息
*/
Map<String,String> plateNum;
/***
* 站管理员的wuid
*/
List<String> adminWuId;
String stationName;
String reason;
}

View File

@ -0,0 +1,35 @@
package com.evotech.hd.common.core.Dto.result.home;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Date;
/**
*
*
* @ClassName:HomeOrderInfo
* @date: 2025年05月08日 17:34
* @author: andy.shi
* @contact: 17330188597
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
@Data
@Schema(name = "首页换电订单信息")
public class HomeOrderInfo {
@Schema(description = "换电时间")
@JsonFormat( pattern = "yyyy-MM-dd HH:mm:ss")
private Date swapTime;
@Schema(description = "换电车辆")
private String swapCar;
@Schema(description = "换电人")
private String swapUserName;
@Schema(description = "换电金额")
private Double swapAmount;
}

View File

@ -16,6 +16,8 @@ public class HomeOrderSwapBatteryAmountDto {
Double amount;
Long dataCount;
Integer status;
}

View File

@ -24,9 +24,9 @@ public class HomeOrderSwapBatteryHalfYearAmountDto {
@Schema(description = "交易金额")
private Double totalMoney;
@Schema(description = "类型")
private Integer status;
@Schema(description = "支付类型")
private Integer payType;
// @Schema(description = "类型")
// private Integer status;
//
// @Schema(description = "支付类型")
// private Integer payType;
}

View File

@ -22,7 +22,8 @@ public class HomeOrderSwapBatteryProportionDto {
String stationCode;
@Schema(description = "换电站订单数量")
Long quantity;
@Schema(description = "订单类型")
Integer orderType;
// @Schema(description = "订单类型")
// Integer orderType;
}

View File

@ -2,14 +2,10 @@ package com.evotech.hd.common.core.dao.cloud;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.evotech.hd.common.core.Dto.request.HomeRequestDto;
import com.evotech.hd.common.core.Dto.result.home.HomeOrderSwapBatteryAmountDto;
import com.evotech.hd.common.core.Dto.result.home.HomeOrderSwapBatteryHalfYearAmountDto;
import com.evotech.hd.common.core.Dto.result.home.HomeOrderSwapBatteryHalfYearDto;
import com.evotech.hd.common.core.Dto.result.home.HomeOrderSwapBatteryProportionDto;
import com.evotech.hd.common.core.Dto.result.home.*;
import com.evotech.hd.common.core.constant.HDConstant;
import com.evotech.hd.common.core.entity.cloud.OrderSwapBattery;
import com.evotech.hd.common.core.permission.DataScope;
import com.evotech.hd.common.core.permission.DataScopeOpenMethod;
import com.evotech.hd.common.core.permission.DataScopes;
import org.apache.ibatis.annotations.Param;
@ -24,7 +20,7 @@ import java.util.List;
@DataScope(permissionObject = HDConstant.OPERATOR_ROLE_CODE, permissionScopeName = "station_code", permissionScopeRedisKey = HDConstant.PermissionConstant.PERMISSION_STATION_CODE),
@DataScope(permissionObject = HDConstant.COMPANY_ROLE_CODE, permissionScopeName = "plate_num", permissionScopeRedisKey = HDConstant.PermissionConstant.PERMISSION_CAR_CODE),
})
@DataScopeOpenMethod(openMethod = true, methodName = {"homeFindHalfYearAmountData"})
//@DataScopeOpenMethod(openMethod = true, methodName = {"homeFindHalfYearAmountData"})
public interface OrderSwapBatteryDao extends BaseMapper<OrderSwapBattery> {
@ -34,10 +30,14 @@ public interface OrderSwapBatteryDao extends BaseMapper<OrderSwapBattery> {
List<HomeOrderSwapBatteryHalfYearDto> homeFindHalfYearOrderData(@Param("params") HomeRequestDto params);
@DataScope(permissionObject = HDConstant.OPERATOR_ROLE_CODE, tableAlias = "osb", permissionScopeName = "station_code", permissionScopeRedisKey = HDConstant.PermissionConstant.PERMISSION_STATION_CODE)
// @DataScope(permissionObject = HDConstant.OPERATOR_ROLE_CODE, tableAlias = "osb", permissionScopeName = "station_code", permissionScopeRedisKey = HDConstant.PermissionConstant.PERMISSION_STATION_CODE)
List<HomeOrderSwapBatteryHalfYearAmountDto> homeFindHalfYearAmountData(@Param("params") HomeRequestDto params);
//因为站端不需要显示金额, 所有重新写一个
List<HomeOrderSwapBatteryHalfYearAmountDto> homeFindHalfYearStationAmountData(@Param("params") HomeRequestDto params);
Long homeFindOrderCountData(@Param("date") Date date);
Double homeFindOrderAmountData(@Param("date") Date date);
List<HomeOrderInfo> findOrderListByStatus(@Param("status") Integer status);
}

View File

@ -10,6 +10,12 @@ package com.evotech.hd.common.constant;
*/
public class MongoConstant {
public class ErrorCode{
//站端告警标识
public static final Integer STATION_ALARM_CODE= 2;
}
//电池实时信息数据库
public static final String BATTERY_DATA_BASE="battery_info";
//电池箱实时信息数据库
@ -27,7 +33,7 @@ public class MongoConstant {
* 条件查询, 示例
* put(查询类型+"条件名称","条件值")
*/
public static final String AND = "and";
public static final String EQ = "and";
public static final String IN = "in";
public static final String NOT_IN = "not_in";
public static final String GT = "gt";

View File

@ -177,7 +177,7 @@ public class MongoDBService {
String[] keyAndQueryType = key.split(MongoConstant.SEPARATION);
//根据类型做查询
switch (keyAndQueryType[0]){
case MongoConstant.AND:
case MongoConstant.EQ:
query.addCriteria(Criteria.where(keyAndQueryType[1]).is(params.get(key)));
break;
case MongoConstant.IN:

View File

@ -1,6 +1,5 @@
package com.evotech.hd.cloud.controller;
import com.evotech.hd.cloud.entity.request.HomeDataRequest;
import com.evotech.hd.cloud.entity.vo.*;
import com.evotech.hd.cloud.service.HomeService;
import com.evotech.hd.common.core.Dto.Result;
@ -9,7 +8,6 @@ import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@ -25,58 +23,133 @@ public class HomeController {
@Resource
private HomeService homeService;
@Operation(summary = "数据1-运营商,换电站,电池,机器人")
@GetMapping("/data1")
@Operation(summary = "平台首页===> 数据1-运营商,换电站,认证公司, 机器人 电池")
@GetMapping("/platform/data1")
@ApiOperationSupport(order = 1)
public Result<HomeData1> homeData1(@ParameterObject HomeDataRequest hd) {
return homeService.homeData1(hd);
public Result<HomePlatformData1> platformData1() {
return homeService.platformData1();
}
@Operation(summary = "数据2-公司、用户、车辆")
@GetMapping("/data2")
@Operation(summary = "平台首页===> 数据2-金额 占比, 半年交易情况等")
@GetMapping("/platform/data2")
@ApiOperationSupport(order = 2)
public Result<HomeData2> homeData2() {
return homeService.homeData2();
public Result<HomePlatformData2> platformData2() {
return homeService.platformData2();
}
@Operation(summary = "数据3-订单总数 订单占比")
@GetMapping("/data3")
@Operation(summary = "运营商首页===> 换电站 机器人 电池")
@GetMapping("/roxy/data1")
@ApiOperationSupport(order = 3)
public Result<HomeData3> homeData3(@ParameterObject HomeDataRequest hd) {
return homeService.homeData3(hd);
public Result<HomePoxyData> roxyData1() {
return homeService.roxyData1();
}
@Operation(summary = "数据4-收入/支出金额")
@GetMapping("/data4")
@Operation(summary = "运营商首页===> 当月订单情况, 和近半年情况 ")
@GetMapping("/roxy/data2")
@ApiOperationSupport(order = 4)
public Result<HomeData4> homeData4(@ParameterObject HomeDataRequest hd) {
return homeService.homeData4(hd);
public Result<HomePoxyData2> roxyData2() {
return homeService.roxyData2();
}
@Operation(summary = "数据5-近6个月订单统计")
@GetMapping("/data5")
@Operation(summary = "站端首页===> 机器人 电池 , 订单")
@GetMapping("/station/data1")
@ApiOperationSupport(order = 5)
public Result<List<HomeData5>> homeData5(@ParameterObject HomeDataRequest hd) {
return homeService.homeData5(hd);
public Result<HomeStationData> stationData1() {
return homeService.stationData1();
}
@Operation(summary = "数据6-近6个月交易统计")
@GetMapping("/data6")
@Operation(summary = "公司首页")
@GetMapping("/company/data")
@ApiOperationSupport(order = 6)
public Result<List<HomeData6>> homeData6(@ParameterObject HomeDataRequest hd) {
return homeService.homeData6(hd);
public Result<HomeCompanyData> company() {
return homeService.company();
}
@Operation(summary = "数据7-同比、环比")
@GetMapping("/data7")
@Operation(summary = "告警信息")
@GetMapping("/alarm/data")
@ApiOperationSupport(order = 7)
public Result<HomeData7> homeData7(Integer type) {
return homeService.homeData7(type);
public Result<List<HomeAlarmData>> alarmData() {
return homeService.alarmData();
}
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
// @Operation(summary = "数据1-运营商,换电站,电池,机器人")
// @GetMapping("/data1")
// @ApiOperationSupport(order = 1)
// public Result<HomeData1> homeData1(@ParameterObject HomeDataRequest hd) {
// return homeService.homeData1(hd);
// }
//
// @Operation(summary = "数据2-公司、用户、车辆")
// @GetMapping("/data2")
// @ApiOperationSupport(order = 2)
// public Result<HomeData2> homeData2() {
// return homeService.homeData2();
// }
//
// @Operation(summary = "数据3-订单总数 订单占比")
// @GetMapping("/data3")
// @ApiOperationSupport(order = 3)
// public Result<HomeData3> homeData3(@ParameterObject HomeDataRequest hd) {
// return homeService.homeData3(hd);
// }
//
// @Operation(summary = "数据4-收入/支出金额")
// @GetMapping("/data4")
// @ApiOperationSupport(order = 4)
// public Result<HomeData4> homeData4(@ParameterObject HomeDataRequest hd) {
// return homeService.homeData4(hd);
// }
//
// @Operation(summary = "数据5-近6个月订单统计")
// @GetMapping("/data5")
// @ApiOperationSupport(order = 5)
// public Result<List<HomeData5>> homeData5(@ParameterObject HomeDataRequest hd) {
// return homeService.homeData5(hd);
// }
//
// @Operation(summary = "数据6-近6个月交易统计")
// @GetMapping("/data6")
// @ApiOperationSupport(order = 6)
// public Result<List<HomeData6>> homeData6(@ParameterObject HomeDataRequest hd) {
// return homeService.homeData6(hd);
// }
//
//
// @Operation(summary = "数据7-同比、环比")
// @GetMapping("/data7")
// @ApiOperationSupport(order = 7)
// public Result<HomeData7> homeData7(Integer type) {
// return homeService.homeData7(type);
// }
@Operation(hidden = true)
@GetMapping("/login/data")
public void loginData() {
homeService.loginData();

View File

@ -13,8 +13,8 @@ import com.evotech.hd.cloud.dao.VehicleWechatUserRelationDao;
import com.evotech.hd.cloud.device.dh.DHRequestUtil;
import com.evotech.hd.cloud.mqtt.message.MessageTopic;
import com.evotech.hd.cloud.mqtt.message.MqttMessageHeader;
import com.evotech.hd.cloud.mqtt.message.processor.MqttRequestExchangeProcessor;
import com.evotech.hd.cloud.mqtt.message.processor.impl.state.MqttStateChargingDataExchangeProcessor;
import com.evotech.hd.cloud.mqtt.message.processor.strategy.MqttStrategyExchangeProcessor;
import com.evotech.hd.cloud.mqtt.message.processor.strategy.impl.state.MqttStateChargingDataExchangeProcessor;
import com.evotech.hd.cloud.utils.components.SwapOrderBasicFeeComponent;
import com.evotech.hd.common.core.entity.Result;
import com.evotech.hd.common.core.entity.cloud.BatteryStation;
@ -81,8 +81,8 @@ public class TestController {
header.setFunction(json.getString("function"));
cn.hutool.json.JSONObject dataBody = JSONUtil.parseObj(json.getJSONObject("dataBoy"));
Map<String, MqttRequestExchangeProcessor> mqttMessageRequestExchangeProcessorMap = applicationContext.getBeansOfType(MqttRequestExchangeProcessor.class);
for (MqttRequestExchangeProcessor processor : mqttMessageRequestExchangeProcessorMap.values()) {
Map<String, MqttStrategyExchangeProcessor> mqttMessageRequestExchangeProcessorMap = applicationContext.getBeansOfType(MqttStrategyExchangeProcessor.class);
for (MqttStrategyExchangeProcessor processor : mqttMessageRequestExchangeProcessorMap.values()) {
if(processor.accept(header.getFunction())){
processor.exchange(topic, header, dataBody);
}

View File

@ -0,0 +1,45 @@
package com.evotech.hd.cloud.entity.vo;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 首页报警信息类
*
* @ClassName:HomeAlarmData
* @date: 2025年05月08日 14:41
* @author: andy.shi
* @contact: 17330188597
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
@Data
@Schema(name = "报警信息")
public class HomeAlarmData {
// @Schema(description = "设备名称")
// String deviceName;
//
// @Schema(description = "设备类型")
// String deviceType;
@Schema(description = "站点名称")
String stationName;
@JsonIgnore
String stationCode;
@Schema(description = "报警类型")
String alarmType;
@Schema(description = "报警时间")
String alarmTime;
public HomeAlarmData() {
}
public HomeAlarmData(String stationName, String stationCode) {
this.stationName = stationName;
this.stationCode = stationCode;
}
}

View File

@ -0,0 +1,36 @@
package com.evotech.hd.cloud.entity.vo;
import com.evotech.hd.common.core.Dto.result.home.HomeOrderInfo;
import com.evotech.hd.common.core.utils.Collections;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
/**
* 公司首页类
* @ClassName:HomeCompanyData
* @date: 2025年05月08日 17:31
* @author: andy.shi
* @contact: 17330188597
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
@Data
@Schema(name = "公司首页")
public class HomeCompanyData {
@Schema(description = "车辆")
private Long carNum;
@Schema(description = "员工")
private Long userNum;
@Schema(description = "待结算订单")
private Long PendingOrderNum;
@Schema(description = "待结算金额")
private Double PendingOrderAmount;
@Schema(description = "换电订单信息")
private List<HomeOrderInfo> orderList = Collections.emptyList();
}

View File

@ -0,0 +1,32 @@
package com.evotech.hd.cloud.entity.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 平台首页信息统计类类
*
* @ClassName:HomePlatformData1
* @date: 2025年05月08日 8:54
* @author: andy.shi
* @contact: 17330188597
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
@Data
@Schema(name = "运营商,换电站,公司, 机器人, 电池")
public class HomePlatformData1 extends HomePoxyData{
@Schema(description = "代理商数")
private Long proxyNum;
@Schema(description = "公司数")
private Long totalCompanyNum;
@Schema(description = "用户数")
private Long totalUserNum;
@Schema(description = "车辆数")
private Long totalCarNum;
}

View File

@ -0,0 +1,44 @@
package com.evotech.hd.cloud.entity.vo;
import com.evotech.hd.common.core.Dto.result.home.HomeOrderSwapBatteryHalfYearAmountDto;
import com.evotech.hd.common.core.utils.Collections;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
/**
* 订单相关类
* @ClassName:HomePlatformData2
* @date: 2025年05月08日 11:53
* @author: andy.shi
* @contact: 17330188597
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
@Data
@Schema(name = "近半年订单金额, 占比, 运营情况")
public class HomePlatformData2 {
@Schema(description = "完成订单数量")
private Long totalFinishOrderNum;
@Schema(description = "完成金额")
private Double totalFinishAmount;
@Schema(description = "待结算订单数量")
private Long totalPendingOrderNum;
@Schema(description = "待结算金额")
private Double totalPendingOrderAmount;
@Schema(description = "订单总数")
private Long totalOrderNum;
@Schema(description = "各运营商近半年订单占比")
List<HomePlatformDataDetailDto> countList = Collections.emptyList();
@Schema(description = "近半年订单走势")
List<HomeOrderSwapBatteryHalfYearAmountDto> trendList = Collections.emptyList();
}

View File

@ -0,0 +1,23 @@
package com.evotech.hd.cloud.entity.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 换电站订单占比类
*
* @ClassName:HomeOrderSwapBatteryDto
* @date: 2025年04月24日 10:06
* @author: andy.shi
* @contact: 17330188597
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
@Data
@Schema(name = "首页占比相关数据")
public class HomePlatformDataDetailDto {
@Schema(description = "运营商 or 站点 名称")
String proxyName;
@Schema(description = "运营商 or 站点 订单数量")
Long quantity;
}

View File

@ -0,0 +1,43 @@
package com.evotech.hd.cloud.entity.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 运营商首页信息统计类类
*
* @ClassName:HomePlatformData1
* @date: 2025年05月08日 8:54
* @author: andy.shi
* @contact: 17330188597
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
@Data
@Schema(name = "换电站, 机器人, 电池")
public class HomePoxyData {
@Schema(description = "总换电站数")
private Long totalStation;
@Schema(description = "营业换电站数")
private Long workStation;
@Schema(description = "总机器人数")
private Long totalRobot;
@Schema(description = "可用机器人数")
private Long availableRobot;
@Schema(description = "总电池数")
private Long totalDC;
@Schema(description = "充电电池数")
private Long chargeDC;
@Schema(description = "可用电池数")
private Long availableDC;
}

View File

@ -0,0 +1,48 @@
package com.evotech.hd.cloud.entity.vo;
import com.evotech.hd.common.core.Dto.result.home.HomeOrderSwapBatteryHalfYearAmountDto;
import com.evotech.hd.common.core.Dto.result.home.HomeOrderSwapBatteryProportionDto;
import com.evotech.hd.common.core.utils.Collections;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
/**
* 订单相关类
* @ClassName:HomePlatformData2
* @date: 2025年05月08日 11:53
* @author: andy.shi
* @contact: 17330188597
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
@Data
@Schema(name = "订单情况, 近半年订单金额, 占比, 运营情况")
public class HomePoxyData2 {
@Schema(description = "当月完成订单数量")
private Long currentTotalFinishOrderNum;
@Schema(description = "当月完成金额")
private Double currentTotalFinishAmount;
@Schema(description = "当月待结算订单数量")
private Long currentTotalPendingOrderNum;
@Schema(description = "当月待结算金额")
private Double currentTotalPendingOrderAmount;
@Schema(description = "当月订单总数")
private Long currentTotalOrderNum;
@Schema(description = "近半年订单总数")
private Long halfYearTotalOrderNum;
@Schema(description = "各站点近半年订单占比")
List<HomeOrderSwapBatteryProportionDto> countList = Collections.emptyList();
@Schema(description = "近半年订单走势")
List<HomeOrderSwapBatteryHalfYearAmountDto> trendList = Collections.emptyList();
}

View File

@ -0,0 +1,50 @@
package com.evotech.hd.cloud.entity.vo;
import com.evotech.hd.common.core.Dto.result.home.HomeOrderSwapBatteryHalfYearAmountDto;
import com.evotech.hd.common.core.utils.Collections;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
/**
*
*
* @ClassName:HomeStationData
* @date: 2025年05月08日 16:51
* @author: andy.shi
* @contact: 17330188597
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
@Data
@Schema(name = "站端首页占比相关数据")
public class HomeStationData {
@Schema(description = "总机器人数")
private Long totalRobot;
@Schema(description = "可用机器人数")
private Long availableRobot;
@Schema(description = "总电池数")
private Long totalDC;
@Schema(description = "充电电池数")
private Long chargeDC;
@Schema(description = "可用电池数")
private Long availableDC;
@Schema(description = "总订单数")
private Long totalOrderNum;
@Schema(description = "已结算订单数")
private Long totalFinishOrderNum = 0l;
@Schema(description = "带结算订单数")
private Long totalPendingOrderNum = 0l;
@Schema(description = "近半年订单走势")
List<HomeOrderSwapBatteryHalfYearAmountDto> trendList = Collections.emptyList();
}

View File

@ -12,14 +12,13 @@ import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;
@Component
//@Component
@Order(value = 20)
@Slf4j
public class MqttConnectInit implements ApplicationRunner {

View File

@ -22,7 +22,7 @@ import com.evotech.hd.cloud.mqtt.message.dto.newer.req.carinfo.CarInfoReq;
import com.evotech.hd.cloud.mqtt.message.dto.newer.req.carinfo.CarInfoResponse;
import com.evotech.hd.cloud.mqtt.message.dto.newer.req.carinfo.VehicleData;
import com.evotech.hd.cloud.mqtt.message.dto.newer.req.order.*;
import com.evotech.hd.cloud.mqtt.message.processor.MqttRequestExchangeProcessor;
import com.evotech.hd.cloud.mqtt.message.processor.strategy.MqttStrategyExchangeProcessor;
import com.evotech.hd.cloud.service.OrderSwapBatteryService;
import com.evotech.hd.cloud.service.WechatUserService;
import com.evotech.hd.cloud.utils.CommonUtil;
@ -102,11 +102,11 @@ public class RequestMessageService {
handlStartSwap(topic,header,battery);
break;
default:
Map<String, MqttRequestExchangeProcessor> mqttMessageRequestExchangeProcessorMap = applicationContext.getBeansOfType(MqttRequestExchangeProcessor.class);
Map<String, MqttStrategyExchangeProcessor> mqttMessageRequestExchangeProcessorMap = applicationContext.getBeansOfType(MqttStrategyExchangeProcessor.class);
if(CollectionUtils.isEmpty(mqttMessageRequestExchangeProcessorMap)){
log.error("mqttRequestExchangeProcessorMap is empty, 没有找到当前的请求信息, 请求接口{}, 请求参数{}", JSONUtil.toJsonStr(header), JSONUtil.toJsonStr(dataBody));
}
for (MqttRequestExchangeProcessor processor : mqttMessageRequestExchangeProcessorMap.values()) {
for (MqttStrategyExchangeProcessor processor : mqttMessageRequestExchangeProcessorMap.values()) {
if(processor.accept(header.getFunction())){
processor.exchange(topic, header, dataBody);
}
@ -258,6 +258,8 @@ public class RequestMessageService {
log.info("\r\n=====>>>生成订单信息--MQTT发送到消息主题{},订单编码:{}", topic,CommonUtil.swapBatteryOrderNo(orderByPlateNumReq.getStationCode()));
orderSwapBatteryService.add(osb);
}
//走到此处, 证明上面逻辑没有问题, 需要删除预约单过期标识
redisUtil.del("preorder:expire:"+osbp.getPkId());
// 返回数据
OrderData od = new OrderData();
BeanUtils.copyProperties(osb, od);

View File

@ -11,7 +11,7 @@ import com.evotech.hd.cloud.mqtt.message.MqttMessageHeader;
import com.evotech.hd.cloud.mqtt.message.dto.newer.state.OrderStatus;
import com.evotech.hd.cloud.mqtt.message.dto.newer.state.OrderStatusData;
import com.evotech.hd.cloud.mqtt.message.dto.newer.state.SwapStep;
import com.evotech.hd.cloud.mqtt.message.processor.MqttRequestExchangeProcessor;
import com.evotech.hd.cloud.mqtt.message.processor.strategy.MqttStrategyExchangeProcessor;
import com.evotech.hd.cloud.service.BatteryStationDcService;
import com.evotech.hd.cloud.utils.components.HDStepDictComponent;
import com.evotech.hd.common.core.dao.cloud.OrderSwapBatteryDao;
@ -78,11 +78,11 @@ public class StateMessageService {
case FUN_TEST:
break;
default:
Map<String, MqttRequestExchangeProcessor> mqttRequestExchangeProcessorMap = applicationContext.getBeansOfType(MqttRequestExchangeProcessor.class);
Map<String, MqttStrategyExchangeProcessor> mqttRequestExchangeProcessorMap = applicationContext.getBeansOfType(MqttStrategyExchangeProcessor.class);
if(CollectionUtils.isEmpty(mqttRequestExchangeProcessorMap)){
log.error("mqttRequestExchangeProcessorMap is empty, 没有找到当前的请求信息, 请求接口{}, 请求参数{}", JSONUtil.toJsonStr(header), JSONUtil.toJsonStr(dataBody));
}
for (MqttRequestExchangeProcessor processor : mqttRequestExchangeProcessorMap.values()) {
for (MqttStrategyExchangeProcessor processor : mqttRequestExchangeProcessorMap.values()) {
if(processor.accept(header.getFunction())){
processor.exchange(topic, header, dataBody);
}

View File

@ -0,0 +1,27 @@
package com.evotech.hd.cloud.mqtt.message.processor.observer.event;
import com.evotech.hd.common.core.entity.cloud.BatteryStation;
import org.springframework.context.ApplicationEvent;
/**
* 站点停止服务事件
* @ClassName:AlarmEvent
* @date: 2025年05月15日 13:51
* @author: andy.shi
* @contact: 17330188597
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
public class BatteryStationStopServerEvent extends ApplicationEvent {
private BatteryStation batteryStation;
public BatteryStationStopServerEvent(Object source, BatteryStation batteryStation) {
super(source);
this.batteryStation = batteryStation;
}
public BatteryStation getBatteryStation() {
return batteryStation;
}
}

View File

@ -0,0 +1,68 @@
package com.evotech.hd.cloud.mqtt.message.processor.observer.listener;
import com.evotech.hd.cloud.mqtt.message.processor.observer.event.BatteryStationStopServerEvent;
import com.evotech.hd.cloud.service.OrderSwapBatteryService;
import com.evotech.hd.cloud.service.newthread.GZHTemplateMessageService;
import com.evotech.hd.cloud.service.rpc.ResourceService;
import com.evotech.hd.common.core.Dto.ResultUtil;
import com.evotech.hd.common.core.Dto.request.template.StopServerTemplateDto;
import com.evotech.hd.common.core.entity.cloud.BatteryStation;
import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryPre;
import com.evotech.hd.common.core.utils.Collections;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 站点停止服务监听器
*
* @ClassName:AlarmListener
* @date: 2025年05月15日 13:58
* @author: andy.shi
* @contact: 17330188597
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
@Component
@Slf4j
public class BatteryStationStopServerListener {
@Resource
OrderSwapBatteryService orderSwapBatteryService;
@Resource
private GZHTemplateMessageService templateMessageService;
@Resource
private ResourceService resourceService;
@EventListener
public void handleStationStopEvent(BatteryStationStopServerEvent event){
BatteryStation batteryStation = event.getBatteryStation();
//监听站端运营状态状态, 如果不为运营状态
if(!Integer.valueOf(1).equals(batteryStation.getStatus())){
//不是营运状态, 获取当前站点是否存在预约单
List<OrderSwapBatteryPre> preList = orderSwapBatteryService.findOrderSwapBatteryPreList(batteryStation.getCode());
Map<String, String> plateNum = new LinkedHashMap<>();
//查询站点是否存在预约单, 存在的话. 通知客户,
if(Collections.isNotEmpty(preList)){
//直接关闭预约单
orderSwapBatteryService.clearOrderSwapBatteryPre(preList.stream().map(OrderSwapBatteryPre::getPkId).collect(Collectors.toList()));
plateNum = preList.stream().collect(Collectors.toMap(OrderSwapBatteryPre::getUcode, OrderSwapBatteryPre::getPlateNum, (k1, k2) -> k1));
}
StopServerTemplateDto stopServerTemplateDto = new StopServerTemplateDto();
stopServerTemplateDto.setStationName(batteryStation.getName());
stopServerTemplateDto.setPlateNum(plateNum);
//同步推送站管理员, 运营商
//站信息查找站管理员和运营商信息, 根据运营商信息, 查对应的负责人信息
stopServerTemplateDto.setAdminWuId(ResultUtil.getValue(resourceService.alarmUserList(batteryStation.getCode(), batteryStation.getProxyId())));
stopServerTemplateDto.setReason(String.format("因%s原因站点暂停运营请预约其他站点", (Integer.valueOf(2).equals(batteryStation.getStatus()) ? "调试" : "检修")));
templateMessageService.serviceStopMessageSend(stopServerTemplateDto);
}
}
}

View File

@ -0,0 +1,28 @@
package com.evotech.hd.cloud.mqtt.message.processor.observer.publisher;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
/**
* 公共事件发布类
* @ClassName:CommonEventPublisher
* @date: 2025年05月15日 13:59
* @author: andy.shi
* @contact: 17330188597
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
@Component
public class CommonEventPublisher {
private final ApplicationEventPublisher publisher;
public CommonEventPublisher(ApplicationEventPublisher publisher) {
this.publisher = publisher;
}
public <T extends ApplicationEvent> void publishEvent(T event) {
publisher.publishEvent(event); // 发布自定义事件
}
}

View File

@ -1,4 +1,4 @@
package com.evotech.hd.cloud.mqtt.message.processor;
package com.evotech.hd.cloud.mqtt.message.processor.strategy;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
@ -29,9 +29,9 @@ import java.util.Date;
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
public interface MqttRequestExchangeProcessor {
public interface MqttStrategyExchangeProcessor {
Logger logger = LoggerFactory.getLogger(MqttRequestExchangeProcessor.class);
Logger logger = LoggerFactory.getLogger(MqttStrategyExchangeProcessor.class);
boolean accept(String functionName);

View File

@ -1,4 +1,4 @@
package com.evotech.hd.cloud.mqtt.message.processor.impl.request;
package com.evotech.hd.cloud.mqtt.message.processor.strategy.impl.request;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
@ -6,7 +6,7 @@ import com.evotech.hd.cloud.mqtt.enums.RequestFunctionTypesEnum;
import com.evotech.hd.cloud.mqtt.message.MessageTopic;
import com.evotech.hd.cloud.mqtt.message.MqttMessageHeader;
import com.evotech.hd.cloud.mqtt.message.dto.newer.req.MqttResponse;
import com.evotech.hd.cloud.mqtt.message.processor.MqttRequestExchangeProcessor;
import com.evotech.hd.cloud.mqtt.message.processor.strategy.MqttStrategyExchangeProcessor;
import com.evotech.hd.cloud.service.OrderSwapBatteryService;
import com.evotech.hd.cloud.service.VehicleService;
import jakarta.annotation.Resource;
@ -27,7 +27,7 @@ import org.springframework.util.Assert;
@Slf4j
@Service
public class MqttRequestPushCarInfoExchangeProcessorImpl implements MqttRequestExchangeProcessor {
public class MqttRequestPushCarInfoExchangeProcessorImpl implements MqttStrategyExchangeProcessor {
@Resource
VehicleService vehicleService;

View File

@ -1,4 +1,4 @@
package com.evotech.hd.cloud.mqtt.message.processor.impl.request;
package com.evotech.hd.cloud.mqtt.message.processor.strategy.impl.request;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
@ -6,7 +6,7 @@ import com.evotech.hd.cloud.mqtt.enums.RequestFunctionTypesEnum;
import com.evotech.hd.cloud.mqtt.message.MessageTopic;
import com.evotech.hd.cloud.mqtt.message.MqttMessageHeader;
import com.evotech.hd.cloud.mqtt.message.dto.newer.req.MqttResponse;
import com.evotech.hd.cloud.mqtt.message.processor.MqttRequestExchangeProcessor;
import com.evotech.hd.cloud.mqtt.message.processor.strategy.MqttStrategyExchangeProcessor;
import com.evotech.hd.cloud.service.BatteryStationCdStrategyService;
import com.evotech.hd.common.core.entity.cloud.BatteryStationCdStrategy;
import jakarta.annotation.Resource;
@ -26,7 +26,7 @@ import java.util.List;
*/
@Slf4j
@Service
public class MqttRequestStrategyExchangeProcessorImpl implements MqttRequestExchangeProcessor {
public class MqttRequestStrategyExchangeProcessorImpl implements MqttStrategyExchangeProcessor {
@Resource
BatteryStationCdStrategyService batteryStationCdStrategyService;

View File

@ -1,11 +1,11 @@
package com.evotech.hd.cloud.mqtt.message.processor.impl.state;
package com.evotech.hd.cloud.mqtt.message.processor.strategy.impl.state;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.evotech.hd.cloud.mqtt.enums.StateFunctionTypesEnum;
import com.evotech.hd.cloud.mqtt.message.MessageTopic;
import com.evotech.hd.cloud.mqtt.message.MqttMessageHeader;
import com.evotech.hd.cloud.mqtt.message.processor.MqttRequestExchangeProcessor;
import com.evotech.hd.cloud.mqtt.message.processor.strategy.MqttStrategyExchangeProcessor;
import com.evotech.hd.common.constant.MongoConstant;
import com.evotech.hd.common.documnet.BatData;
import lombok.extern.slf4j.Slf4j;
@ -23,7 +23,7 @@ import org.springframework.util.StringUtils;
*/
@Slf4j
@Service
public class MqttStateBatDataDataExchangeProcessor implements MqttRequestExchangeProcessor {
public class MqttStateBatDataDataExchangeProcessor implements MqttStrategyExchangeProcessor {
@Override
public boolean accept(String functionName) {

View File

@ -1,11 +1,11 @@
package com.evotech.hd.cloud.mqtt.message.processor.impl.state;
package com.evotech.hd.cloud.mqtt.message.processor.strategy.impl.state;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.evotech.hd.cloud.mqtt.enums.StateFunctionTypesEnum;
import com.evotech.hd.cloud.mqtt.message.MessageTopic;
import com.evotech.hd.cloud.mqtt.message.MqttMessageHeader;
import com.evotech.hd.cloud.mqtt.message.processor.MqttRequestExchangeProcessor;
import com.evotech.hd.cloud.mqtt.message.processor.strategy.MqttStrategyExchangeProcessor;
import com.evotech.hd.common.constant.MongoConstant;
import com.evotech.hd.common.documnet.ChargingData;
import lombok.extern.slf4j.Slf4j;
@ -23,7 +23,7 @@ import org.springframework.util.StringUtils;
*/
@Slf4j
@Service
public class MqttStateChargingDataExchangeProcessor implements MqttRequestExchangeProcessor {
public class MqttStateChargingDataExchangeProcessor implements MqttStrategyExchangeProcessor {
@Override
public boolean accept(String functionName) {

View File

@ -1,11 +1,11 @@
package com.evotech.hd.cloud.mqtt.message.processor.impl.state;
package com.evotech.hd.cloud.mqtt.message.processor.strategy.impl.state;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.evotech.hd.cloud.mqtt.enums.StateFunctionTypesEnum;
import com.evotech.hd.cloud.mqtt.message.MessageTopic;
import com.evotech.hd.cloud.mqtt.message.MqttMessageHeader;
import com.evotech.hd.cloud.mqtt.message.processor.MqttRequestExchangeProcessor;
import com.evotech.hd.cloud.mqtt.message.processor.strategy.MqttStrategyExchangeProcessor;
import com.evotech.hd.cloud.service.BatteryStationService;
import com.evotech.hd.common.constant.MongoConstant;
import com.evotech.hd.common.documnet.StationState;
@ -24,7 +24,7 @@ import org.springframework.stereotype.Service;
*/
@Slf4j
@Service
public class MqttStateStationStateExchangeProcessor implements MqttRequestExchangeProcessor {
public class MqttStateStationStateExchangeProcessor implements MqttStrategyExchangeProcessor {
@Resource
BatteryStationService batteryStationService;

View File

@ -7,6 +7,42 @@ import com.evotech.hd.common.core.Dto.Result;
import java.util.List;
public interface HomeService {
/***
* 运营商, 换电站, 公司, 机器人 电池相关统计
* @return
*/
public Result<HomePlatformData1> platformData1();
/***
* 金额 占比, 交易情况
* @return
*/
public Result<HomePlatformData2> platformData2();
/***
* 换电站, 机器人 电池相关统计
* @return
*/
public Result<HomePoxyData> roxyData1();
/***
* 金额 占比, 交易情况
* @return
*/
public Result<HomePoxyData2> roxyData2();
public Result<HomeStationData> stationData1();
public Result<HomeCompanyData> company();
/***
* 报警信息
* @return
*/
Result<List<HomeAlarmData>> alarmData();
public Result<HomeData1> homeData1(HomeDataRequest hd);

View File

@ -16,16 +16,17 @@ import com.evotech.hd.cloud.device.dh.DHRequestUtil;
import com.evotech.hd.cloud.entity.BatteryStationSecretKey;
import com.evotech.hd.cloud.entity.request.PageListBatteryStationRequest;
import com.evotech.hd.cloud.exception.DHException;
import com.evotech.hd.cloud.mqtt.message.processor.observer.event.BatteryStationStopServerEvent;
import com.evotech.hd.cloud.mqtt.message.processor.observer.publisher.CommonEventPublisher;
import com.evotech.hd.cloud.service.BatteryStationService;
import com.evotech.hd.cloud.service.OrderSwapBatteryService;
import com.evotech.hd.cloud.service.newthread.GZHTemplateMessageService;
import com.evotech.hd.cloud.service.rpc.ResourceService;
import com.evotech.hd.cloud.service.rpc.WechatService;
import com.evotech.hd.common.constant.MongoConstant;
import com.evotech.hd.common.core.Dto.Result;
import com.evotech.hd.common.core.Dto.ResultUtil;
import com.evotech.hd.common.core.Dto.request.template.AlarmTemplateDto;
import com.evotech.hd.common.core.entity.cloud.BatteryStation;
import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryPre;
import com.evotech.hd.common.core.entity.cloud.VehicleInfo;
import com.evotech.hd.common.core.entity.cloud.vo.BatteryStationVO;
import com.evotech.hd.common.core.enums.CodeMsg;
@ -46,7 +47,6 @@ import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.KeyPair;
import java.util.*;
import java.util.stream.Collectors;
@Service
@Slf4j
@ -64,9 +64,9 @@ public class BatteryStationServiceImpl implements BatteryStationService {
private ResourceService resourceService;
@Resource
private GZHTemplateMessageService templateMessageService;
@Resource
OrderSwapBatteryService orderSwapBatteryService;
@Resource
CommonEventPublisher eventPublisher;
@Override
public com.evotech.hd.common.core.entity.Result<Integer> add(BatteryStation bs) {
bs.setCtime(new Date());
@ -131,6 +131,7 @@ public class BatteryStationServiceImpl implements BatteryStationService {
public com.evotech.hd.common.core.entity.Result<Integer> update(BatteryStation bs) {
int n = batteryStationDao.updateById(bs);
if (n == 1) {
eventPublisher.publishEvent(new BatteryStationStopServerEvent(this,bs));
return new com.evotech.hd.common.core.entity.Result<Integer>().success(n);
}
return new com.evotech.hd.common.core.entity.Result<Integer>().error("更新换电站失败!");
@ -348,7 +349,7 @@ public class BatteryStationServiceImpl implements BatteryStationService {
//报警信息
StringBuilder alarmMsg = new StringBuilder("");
//0-未知;1-正常;2-告警 沟通 只有2才算告警,未知不算告警
isAlarm = Integer.valueOf(2).equals(fire);
isAlarm = MongoConstant.ErrorCode.STATION_ALARM_CODE.equals(fire);
//如果消防告警存在信息
if(isAlarm){
alarmMsg.append("消防报警");
@ -356,7 +357,7 @@ public class BatteryStationServiceImpl implements BatteryStationService {
//如果消防没有报警, 检查烟感
if(!isAlarm){
//因为烟感有多个, 所以一个烟感报警,及存在报警信息
isAlarm = Collections.asList(smoke.split(",")).contains(Integer.valueOf(2));
isAlarm = Collections.asList(smoke.split(",")).contains(MongoConstant.ErrorCode.STATION_ALARM_CODE);
if(isAlarm){
alarmMsg.append("烟感报警");
}
@ -365,17 +366,8 @@ public class BatteryStationServiceImpl implements BatteryStationService {
batteryStation.setAlarm(isAlarm);
int n = 0;
if((n = batteryStationDao.updateById(batteryStation)) > 0){
//更新成功, 如果推送状态是运营状态, 则不需要做任何处理, 如果推送的状态非运营状态, 则需要同步推送预约单用户信息
if(!Integer.valueOf(1).equals(batteryStation.getStatus())){
//不是营运状态, 推送服务号通知
List<OrderSwapBatteryPre> preList = orderSwapBatteryService.findOrderSwapBatteryPreList(batteryStation.getCode());
if(Collections.isNotEmpty(preList)){
//直接关闭预约单
orderSwapBatteryService.clearOrderSwapBatteryPre(preList.stream().map(OrderSwapBatteryPre::getPkId).collect(Collectors.toList()));
//查询站点是否存在预约单, 存在的话. 通知客户,
templateMessageService.serviceStopMessageSend(preList.stream().map(OrderSwapBatteryPre::getUcode).collect(Collectors.toList()), (Integer.valueOf(2).equals(batteryStation.getStatus()) ? "调试" : "检修"));
}
}
//更新成功, 发布站端数据变更事件, 用于数据解耦
eventPublisher.publishEvent(new BatteryStationStopServerEvent(this,batteryStation));
//存在报警信息
if(batteryStation.getAlarm()){
//同步推送站管理员, 运营商

View File

@ -3,13 +3,18 @@ package com.evotech.hd.cloud.service.impl;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.evotech.hd.cloud.dao.*;
import com.evotech.hd.cloud.entity.request.HomeDataRequest;
import com.evotech.hd.cloud.entity.vo.*;
import com.evotech.hd.cloud.mqtt.enums.StateFunctionTypesEnum;
import com.evotech.hd.cloud.service.HomeService;
import com.evotech.hd.common.constant.MongoConstant;
import com.evotech.hd.common.core.Dto.Result;
import com.evotech.hd.common.core.Dto.ResultUtil;
import com.evotech.hd.common.core.Dto.request.HomeRequestDto;
import com.evotech.hd.common.core.Dto.result.home.HomeOrderInfo;
import com.evotech.hd.common.core.Dto.result.home.HomeOrderSwapBatteryAmountDto;
import com.evotech.hd.common.core.Dto.result.home.HomeOrderSwapBatteryHalfYearAmountDto;
import com.evotech.hd.common.core.Dto.result.home.HomeOrderSwapBatteryProportionDto;
@ -24,8 +29,10 @@ import com.evotech.hd.common.core.entity.resource.ProxyOperater;
import com.evotech.hd.common.core.entity.wechat.WechatUser;
import com.evotech.hd.common.core.enums.CodeMsg;
import com.evotech.hd.common.core.utils.Collections;
import com.evotech.hd.common.documnet.StationState;
import com.evotech.hd.common.permission.util.RedisPermissionUtils;
import com.evotech.hd.common.redis.utils.RedisUtil;
import com.evotech.hd.common.service.MongoDBService;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
@ -68,6 +75,233 @@ public class HomeServiceImpl implements HomeService {
@Resource
private RedisUtil redisUtil;
@Override
public Result<HomePlatformData1> platformData1() {
HomePlatformData1 data = new HomePlatformData1();
BeanUtils.copyProperties(ResultUtil.getValue(roxyData1()), data);
// 1. 运营商
data.setProxyNum(proxyOperaterDao.selectCount(new LambdaQueryWrapper<ProxyOperater>().eq(ProxyOperater::getDelFlag, 0).select(ProxyOperater::getPkId)));
// 1. 公司
data.setTotalCompanyNum(companyDao.selectCount(new LambdaQueryWrapper<Company>().eq(Company::getDelFlag, 0).select(Company::getPkId)));
// 2. 用户
data.setTotalUserNum(wechatUserDao.selectCount(new LambdaQueryWrapper<WechatUser>().select(WechatUser::getPkId)));
// 3. 车辆
data.setTotalCarNum(vehicleInfoDao.selectCount(new LambdaQueryWrapper<VehicleInfo>().eq(VehicleInfo::getDelFlag, 0).select(VehicleInfo::getPkId)));
return new Result<HomePlatformData1>().success(data);
}
@Override
public Result<HomePlatformData2> platformData2() {
HomePlatformData2 data = new HomePlatformData2();
Date d = new Date();
HomeRequestDto homeRequestDto = new HomeRequestDto(DateUtil.offsetMonth(d, -5), d);
//订单数量 or 订单金额
List<HomeOrderSwapBatteryAmountDto> orderAmountlist = orderSwapBatteryDao.homeFindAmountData(homeRequestDto);
if(Collections.isNotEmpty(orderAmountlist)){
HomeOrderSwapBatteryAmountDto totalFinishOrder = orderAmountlist.stream().filter(i -> Integer.valueOf(7).equals(i.getStatus())).findFirst().orElse(null);
if(totalFinishOrder != null){
data.setTotalFinishOrderNum(totalFinishOrder.getDataCount());
data.setTotalFinishAmount(totalFinishOrder.getAmount());
}
HomeOrderSwapBatteryAmountDto totalPendingOrder = orderAmountlist.stream().filter(i -> Integer.valueOf(6).equals(i.getStatus())).findFirst().orElse(null);
if(totalPendingOrder != null){
data.setTotalPendingOrderNum(totalPendingOrder.getDataCount());
data.setTotalPendingOrderAmount(totalPendingOrder.getAmount());
}
}
//计算占比
Map<String, Long> countMap = Collections.emptyMap();
List<HomeOrderSwapBatteryProportionDto> list = orderSwapBatteryDao.homeFindProportionData(homeRequestDto);
if(Collections.isNotEmpty(list)){
//总订单数
data.setTotalOrderNum(list.stream().collect(Collectors.summingLong(i -> i.getQuantity())));
countMap = list.stream().collect(Collectors.toMap(HomeOrderSwapBatteryProportionDto::getStationCode, HomeOrderSwapBatteryProportionDto::getQuantity, (k1,k2)-> k1));
}
Map<String, List<String>> batteryStationMap = batteryStationDao.selectList(new LambdaQueryWrapper<BatteryStation>().eq(BatteryStation::getDelFlag, 0).select(BatteryStation::getCode, BatteryStation::getProxyId)).stream().collect(Collectors.groupingBy(BatteryStation::getProxyId, Collectors.mapping(station -> station.getCode(), Collectors.toList())));
List<HomePlatformDataDetailDto> countList = Collections.emptyList();
Map<String, Long> finalCountMap = countMap;
proxyOperaterDao.selectList(new LambdaQueryWrapper<ProxyOperater>().eq(ProxyOperater::getDelFlag, 0).select(ProxyOperater::getPoname, ProxyOperater::getPocode))
.forEach(proxy ->{
HomePlatformDataDetailDto detailDto = new HomePlatformDataDetailDto();
detailDto.setProxyName(proxy.getPoname());
final Long[] totalCount = {0l};
batteryStationMap.get(proxy.getPocode()).forEach(stationCode ->{
Long stationQuantity = finalCountMap.get(stationCode);
totalCount[0] = defaultValue(totalCount[0],0l) + defaultValue(stationQuantity,0l);
});
detailDto.setQuantity(totalCount[0]);
countList.add(detailDto);
});
data.setCountList(countList);
//近半年走势情况
data.setTrendList(orderSwapBatteryDao.homeFindHalfYearAmountData(homeRequestDto).stream().sorted((o1,o2) ->{
return o1.getMonth().compareTo(o2.getMonth());
}).collect(Collectors.toList()));
return new Result<HomePlatformData2>().success(data);
}
@Override
public Result<HomePoxyData> roxyData1() {
HomePoxyData data = new HomePoxyData();
// 2. 换电站
data.setTotalStation(batteryStationDao.selectCount(new LambdaQueryWrapper<BatteryStation>().eq(BatteryStation::getDelFlag, 0).select(BatteryStation::getPkId)));
//可用换电站
data.setWorkStation(batteryStationDao.selectCount(new LambdaQueryWrapper<BatteryStation>().eq(BatteryStation::getDelFlag, 0).eq(BatteryStation::getStatus, 1).select(BatteryStation::getPkId)));
// 机器人
data.setTotalRobot(batteryStationRobotDao.selectCount(new LambdaQueryWrapper<BatteryStationRobot>().select(BatteryStationRobot::getPkId)));
//可用机器人
data.setAvailableRobot(batteryStationRobotDao.selectCount(new LambdaQueryWrapper<BatteryStationRobot>().eq(BatteryStationRobot::getStatus, 1).select(BatteryStationRobot::getPkId)));
// 电池
data.setTotalDC(batteryStationDcDao.selectCount(new LambdaQueryWrapper<BatteryStationDc>().eq(BatteryStationDc::getDelFlag, 0).select(BatteryStationDc::getPkId)));
//充电电池
data.setChargeDC(batteryStationDcDao.selectCount(new LambdaQueryWrapper<BatteryStationDc>().eq(BatteryStationDc::getDelFlag, 0).eq(BatteryStationDc::getStatus, 2).select(BatteryStationDc::getPkId)));
//可用电池
data.setAvailableDC(batteryStationDcDao.selectCount(new LambdaQueryWrapper<BatteryStationDc>().eq(BatteryStationDc::getDelFlag, 0).eq(BatteryStationDc::getStatus, 3).select(BatteryStationDc::getPkId)));
return new Result<HomePoxyData>().success(data);
}
@Override
public Result<HomePoxyData2> roxyData2() {
HomePoxyData2 data = new HomePoxyData2();
Date d = new Date();
HomeRequestDto homeRequestDto = new HomeRequestDto(DateUtil.beginOfMonth(d), d);
//订单数量 or 订单金额
List<HomeOrderSwapBatteryAmountDto> orderAmountlist = orderSwapBatteryDao.homeFindAmountData(homeRequestDto);
if(Collections.isNotEmpty(orderAmountlist)){
HomeOrderSwapBatteryAmountDto totalFinishOrder = orderAmountlist.stream().filter(i -> Integer.valueOf(7).equals(i.getStatus())).findFirst().orElse(null);
if(totalFinishOrder != null){
data.setCurrentTotalFinishOrderNum(totalFinishOrder.getDataCount());
data.setCurrentTotalFinishAmount(totalFinishOrder.getAmount());
}
HomeOrderSwapBatteryAmountDto totalPendingOrder = orderAmountlist.stream().filter(i -> Integer.valueOf(6).equals(i.getStatus())).findFirst().orElse(null);
if(totalPendingOrder != null){
data.setCurrentTotalPendingOrderNum(totalPendingOrder.getDataCount());
data.setCurrentTotalPendingOrderAmount(totalPendingOrder.getAmount());
}
data.setCurrentTotalOrderNum(defaultValue(data.getCurrentTotalFinishOrderNum(), 0l)+defaultValue(data.getCurrentTotalPendingOrderNum(), 0l));
}
homeRequestDto = new HomeRequestDto(DateUtil.offsetMonth(d, -5), d);
//订单数量 or 订单金额
//计算占比
List<HomeOrderSwapBatteryProportionDto> list = orderSwapBatteryDao.homeFindProportionData(homeRequestDto);
if(Collections.isNotEmpty(list)){
//总订单数
data.setHalfYearTotalOrderNum(list.stream().collect(Collectors.summingLong(i -> i.getQuantity())));
data.setCountList(list);
}
//近半年走势情况
data.setTrendList(orderSwapBatteryDao.homeFindHalfYearAmountData(homeRequestDto).stream().sorted((o1,o2) ->{
return o1.getMonth().compareTo(o2.getMonth());
}).collect(Collectors.toList()));
return new Result<HomePoxyData2>().success(data);
}
public <T> T defaultValue(T t, T defVal){
return ObjectUtils.isNotEmpty(t) ? t : defVal;
}
@Override
public Result<HomeStationData> stationData1() {
HomeStationData data = new HomeStationData();
// 机器人
data.setTotalRobot(batteryStationRobotDao.selectCount(new LambdaQueryWrapper<BatteryStationRobot>().select(BatteryStationRobot::getPkId)));
//可用机器人
data.setAvailableRobot(batteryStationRobotDao.selectCount(new LambdaQueryWrapper<BatteryStationRobot>().eq(BatteryStationRobot::getStatus, 1).select(BatteryStationRobot::getPkId)));
// 电池
data.setTotalDC(batteryStationDcDao.selectCount(new LambdaQueryWrapper<BatteryStationDc>().eq(BatteryStationDc::getDelFlag, 0).select(BatteryStationDc::getPkId)));
//充电电池
data.setChargeDC(batteryStationDcDao.selectCount(new LambdaQueryWrapper<BatteryStationDc>().eq(BatteryStationDc::getDelFlag, 0).eq(BatteryStationDc::getStatus, 2).select(BatteryStationDc::getPkId)));
//可用电池
data.setAvailableDC(batteryStationDcDao.selectCount(new LambdaQueryWrapper<BatteryStationDc>().eq(BatteryStationDc::getDelFlag, 0).eq(BatteryStationDc::getStatus, 3).select(BatteryStationDc::getPkId)));
//订单数量 or 订单金额
Date d = new Date();
List<HomeOrderSwapBatteryAmountDto> orderAmountlist = orderSwapBatteryDao.homeFindAmountData(new HomeRequestDto(DateUtil.beginOfMonth(d), d));
if(Collections.isNotEmpty(orderAmountlist)){
HomeOrderSwapBatteryAmountDto totalFinishOrder = orderAmountlist.stream().filter(i -> Integer.valueOf(7).equals(i.getStatus())).findFirst().orElse(null);
if(totalFinishOrder != null){
data.setTotalFinishOrderNum(totalFinishOrder.getDataCount());
}
HomeOrderSwapBatteryAmountDto totalPendingOrder = orderAmountlist.stream().filter(i -> Integer.valueOf(6).equals(i.getStatus())).findFirst().orElse(null);
if(totalPendingOrder != null){
data.setTotalPendingOrderNum(totalPendingOrder.getDataCount());
}
data.setTotalOrderNum(defaultValue(data.getTotalFinishOrderNum(),0l)+defaultValue(data.getTotalPendingOrderNum(), 0l));
}
//近半年走势情况
data.setTrendList(orderSwapBatteryDao.homeFindHalfYearStationAmountData(new HomeRequestDto(DateUtil.offsetMonth(d, -5), d)).stream().sorted((o1,o2) ->{
return o1.getMonth().compareTo(o2.getMonth());
}).collect(Collectors.toList()));
return new Result<HomeStationData>().success(data);
}
@Override
public Result<HomeCompanyData> company() {
HomeCompanyData data = new HomeCompanyData();
// 1. 车辆
data.setCarNum(vehicleInfoDao.selectCount(new LambdaQueryWrapper<VehicleInfo>().eq(VehicleInfo::getDelFlag, 0).select(VehicleInfo::getPkId)));
//2 人员
data.setUserNum(wechatUserDao.selectCount(new LambdaQueryWrapper<WechatUser>().select(WechatUser::getPkId)));
//获取待结算订单
List<HomeOrderInfo> orderInfo = orderSwapBatteryDao.findOrderListByStatus(6);
//待结算订单数量
data.setPendingOrderNum(Long.valueOf(orderInfo.size()));
//待结算订单金额
data.setPendingOrderAmount(orderInfo.stream().collect(Collectors.summingDouble( i-> i.getSwapAmount())));
//待结算订单信息
data.setOrderList(orderInfo);
return new Result<HomeCompanyData>().success(data);
}
@Resource
MongoDBService mongoDBService;
@Override
public Result<List<HomeAlarmData>> alarmData() {
List<HomeAlarmData> list = batteryStationDao.selectList(new LambdaQueryWrapper<BatteryStation>().eq(BatteryStation::getDelFlag, 0).eq(BatteryStation::getAlarm, true).select(BatteryStation::getCode, BatteryStation::getName)).stream().map(data -> new HomeAlarmData(data.getName(), data.getCode())).collect(Collectors.toList());
list.stream().forEach(alarm ->{
List<StationState> alarmList = mongoDBService.find(MongoConstant.STATION_INFO_BASE, StateFunctionTypesEnum.FUN_STATION_STATE.getFunction(), StationState.class, Collections.asMap(MongoConstant.EQ+ MongoConstant.SEPARATION+"stationCode",alarm.getStationCode(), MongoConstant.SORT+ MongoConstant.SEPARATION+MongoConstant.SORT_DESC, "id", MongoConstant.PAGE, "1"+MongoConstant.SEPARATION+"1"));
if(Collections.isNotEmpty(alarmList)){
StationState stationState= alarmList.get(0);
//报警信息
JSONObject alarmJSONObject = JSONObject.parseObject(alarmList.get(0).getValue());
Integer fire = alarmJSONObject.getInteger("fire");
if(MongoConstant.ErrorCode.STATION_ALARM_CODE.equals(fire)){
alarm.setAlarmType("消防告警");
}else{
String smoke = alarmJSONObject.getString("smoke");
if(Collections.asList(smoke.split(",")).contains(String.valueOf(MongoConstant.ErrorCode.STATION_ALARM_CODE))){
alarm.setAlarmType("烟感告警");
}
}
alarm.setAlarmTime(DateUtil.format(new Date(Long.valueOf(stationState.getId())), "yyyy-MM-dd HH:mm:ss"));
}
});
return new Result<List<HomeAlarmData>>().success(list);
}
@Override
public Result<HomeData1> homeData1(HomeDataRequest hd) {
// 1. 运营商
@ -190,24 +424,24 @@ public class HomeServiceImpl implements HomeService {
String month = it.next();
HomeData6 homeData6 = new HomeData6();
homeData6.setMonth(month);
List<HomeOrderSwapBatteryHalfYearAmountDto> values = mapList.get(month);
HomeOrderSwapBatteryHalfYearAmountDto wechat = values.stream().filter(f -> Integer.valueOf(7).equals(f.getStatus()) && Integer.valueOf(2).equals(f.getPayType())).findFirst().orElse(null);
if(ObjectUtils.isNotEmpty(wechat)){
homeData6.setInQuantity(wechat.getQuantity());
homeData6.setInMoney(wechat.getTotalMoney());
}
HomeOrderSwapBatteryHalfYearAmountDto account = values.stream().filter(f -> Integer.valueOf(7).equals(f.getStatus()) && Integer.valueOf(1).equals(f.getPayType())).findFirst().orElse(null);
if(ObjectUtils.isNotEmpty(account)){
homeData6.setWalletQuantity(account.getQuantity());
homeData6.setWalletMoney(account.getTotalMoney());
}
List<HomeOrderSwapBatteryHalfYearAmountDto> refund = values.stream().filter(f -> Integer.valueOf(-1).equals(f.getStatus())).collect(Collectors.toList());
if(Collections.isNotEmpty(refund)){
homeData6.setRefundQuantity(refund.stream().collect(Collectors.summingLong(i -> i.getQuantity())));
homeData6.setRefundMoney(refund.stream().collect(Collectors.summingDouble(i -> i.getTotalMoney())));
}
// List<HomeOrderSwapBatteryHalfYearAmountDto> values = mapList.get(month);
// HomeOrderSwapBatteryHalfYearAmountDto wechat = values.stream().filter(f -> Integer.valueOf(7).equals(f.getStatus()) && Integer.valueOf(2).equals(f.getPayType())).findFirst().orElse(null);
// if(ObjectUtils.isNotEmpty(wechat)){
// homeData6.setInQuantity(wechat.getQuantity());
// homeData6.setInMoney(wechat.getTotalMoney());
// }
//
// HomeOrderSwapBatteryHalfYearAmountDto account = values.stream().filter(f -> Integer.valueOf(7).equals(f.getStatus()) && Integer.valueOf(1).equals(f.getPayType())).findFirst().orElse(null);
// if(ObjectUtils.isNotEmpty(account)){
// homeData6.setWalletQuantity(account.getQuantity());
// homeData6.setWalletMoney(account.getTotalMoney());
// }
//
// List<HomeOrderSwapBatteryHalfYearAmountDto> refund = values.stream().filter(f -> Integer.valueOf(-1).equals(f.getStatus())).collect(Collectors.toList());
// if(Collections.isNotEmpty(refund)){
// homeData6.setRefundQuantity(refund.stream().collect(Collectors.summingLong(i -> i.getQuantity())));
// homeData6.setRefundMoney(refund.stream().collect(Collectors.summingDouble(i -> i.getTotalMoney())));
// }
list.add(homeData6);
}
list = list.stream().sorted((o1,o2) ->{

View File

@ -385,11 +385,11 @@ public class OrderSwapBatteryServiceImpl implements OrderSwapBatteryService {
fee = order.getServiceFee().add(order.getBasicFee().multiply(order.getElectAmount())).setScale(0, RoundingMode.HALF_UP);
} else if (order.getFeeType() == 2) {
// TODO 按SOC
if (order.getReturnBatRentSoc() == null || order.getRentBatSoc() == null) {
if (order.getReturnBatSoc() == null || order.getRentBatSoc() == null) {
return new Result<String>().error("充电订单 SOC 异常!");
}
// 计算 SOC
BigDecimal socDifference = new BigDecimal(order.getRentBatSoc() - order.getReturnBatRentSoc());
BigDecimal socDifference = new BigDecimal(order.getRentBatSoc() - order.getReturnBatSoc());
fee = order.getServiceFee().add(order.getBasicFee().multiply(socDifference)).setScale(0, RoundingMode.HALF_UP);
} else if (order.getFeeType() == 1) {
@ -713,10 +713,9 @@ public class OrderSwapBatteryServiceImpl implements OrderSwapBatteryService {
public List<OrderSwapBatteryPre> findOrderSwapBatteryPreList(String stationCode) {
return orderSwapBatteryPreDao.selectList(new LambdaQueryWrapper<OrderSwapBatteryPre>()
.eq(OrderSwapBatteryPre::getStationCode, stationCode)
.ne(OrderSwapBatteryPre::getUcode,"hp_station_push")
// .ne(OrderSwapBatteryPre::getUcode,"hp_station_push")
.eq(OrderSwapBatteryPre::getStatus, 1)
.select(OrderSwapBatteryPre::getUcode)
.select(OrderSwapBatteryPre::getPkId)
.select(OrderSwapBatteryPre::getUcode,OrderSwapBatteryPre::getPkId,OrderSwapBatteryPre::getPlateNum)
);
}

View File

@ -2,6 +2,7 @@ package com.evotech.hd.cloud.service.newthread;
import com.evotech.hd.cloud.service.rpc.WechatService;
import com.evotech.hd.common.core.Dto.request.template.AlarmTemplateDto;
import com.evotech.hd.common.core.Dto.request.template.StopServerTemplateDto;
import com.evotech.hd.common.core.entity.cloud.OrderSwapBattery;
import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryPre;
import com.evotech.hd.common.core.entity.cloud.TradeDetail;
@ -9,8 +10,6 @@ import jakarta.annotation.Resource;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class GZHTemplateMessageService {
@ -59,8 +58,8 @@ public class GZHTemplateMessageService {
* @param money
*/
@Async("taskExecutor")
public void serviceStopMessageSend(List<String>wuIds, String reason) {
wechatService.serviceStopMessageSend(wuIds, reason);
public void serviceStopMessageSend(StopServerTemplateDto stopServerTemplateDto) {
wechatService.serviceStopMessageSend(stopServerTemplateDto);
}
}

View File

@ -1,6 +1,12 @@
package com.evotech.hd.cloud.service.rpc;
import com.evotech.hd.cloud.entity.vo.NativePayVO;
import com.evotech.hd.common.core.Dto.request.template.AlarmTemplateDto;
import com.evotech.hd.common.core.Dto.request.template.StopServerTemplateDto;
import com.evotech.hd.common.core.entity.Result;
import com.evotech.hd.common.core.entity.cloud.OrderSwapBattery;
import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryPre;
import com.evotech.hd.common.core.entity.cloud.TradeDetail;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
@ -9,14 +15,6 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import com.evotech.hd.cloud.entity.vo.NativePayVO;
import com.evotech.hd.common.core.entity.Result;
import com.evotech.hd.common.core.entity.cloud.OrderSwapBattery;
import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryPre;
import com.evotech.hd.common.core.entity.cloud.TradeDetail;
import java.util.List;
@FeignClient(name = "${WECHAT-SERVER-API-NAME}", path = "${WECHAT-SERVER-API-PATH}")
public interface WechatService {
@ -61,6 +59,6 @@ public interface WechatService {
public com.evotech.hd.common.core.Dto.Result<String> alarmMessageSend(@RequestBody AlarmTemplateDto alarmTemplate);
@PostMapping(value = "/gzh/msg/send/service", consumes = {MediaType.APPLICATION_JSON_VALUE})
public com.evotech.hd.common.core.Dto.Result<String> serviceStopMessageSend(@RequestParam List<String> wuIds, @RequestParam String reason);
public com.evotech.hd.common.core.Dto.Result<String> serviceStopMessageSend(@RequestBody StopServerTemplateDto stopServerTemplateDto);
}

View File

@ -34,21 +34,20 @@ public class OrderCostCalculateTask {
public void calculateOrder() {
log.info("\r\n===>>>开始查找订单计算费用");
// 查询状态为5的订单
// Boolean flag = true;
Boolean flag = true;
int n = 0;
// while (flag) {
while (flag) {
List<OrderSwapBattery> list = orderSwapBatteryDao.selectList(new QueryWrapper<OrderSwapBattery>()
.eq("status", 5).ne("del_flag", 1)
.ge("order_time", DateUtil.beginOfYear(new Date()))
.last("limit 20"));
if (!list.isEmpty()) {
n = orderCalculate(n, list);
// flag = false;
}
// else {
// flag = false;
// }
// }
else {
flag = false;
}
}
log.info("\r\n===>>>订单计算费用完成:{} 条数据", n);
@ -63,6 +62,8 @@ public class OrderCostCalculateTask {
n += 1;
// 发送微信消息
gzhTemplateMessageService.orderMessageSend2(list.get(i).getPkId(), 2);
}else{
throw new RuntimeException(res.getMsg());
}
}
return n;

View File

@ -4,22 +4,16 @@ import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.evotech.hd.cloud.dao.OrderSwapBatteryPreDao;
import com.evotech.hd.cloud.service.OrderSwapBatteryService;
import com.evotech.hd.cloud.service.newthread.GZHTemplateMessageService;
import com.evotech.hd.common.core.dao.cloud.OrderSwapBatteryDao;
import com.evotech.hd.common.core.entity.cloud.OrderSwapBattery;
import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryPre;
import com.evotech.hd.common.redis.utils.RedisUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Set;
@ -119,19 +113,19 @@ public class OrderSwapBatteryTask {
}
for (String key : keys) {
try {
String id = key.substring(key.lastIndexOf(":") + 1);
OrderSwapBatteryPre order = orderSwapBatteryPreDao.selectById(id);
if (order != null && order.getStatus() == 1) { // 只处理状态为1的预约单
// 获取过期时间
Date expireTime = (Date) redisUtil.get(key);
// 如果当前时间接近过期时间(5分钟内)
if (expireTime != null && DateUtil.between(currentTime, expireTime, DateUnit.MINUTE) <= 5) {
// 发送微信公众号提醒
templateMessageService.preOrderMessageSend(order);
reminderCount++;
// 从Redis中删除该预约单
redisUtil.del(key);
log.info("发送微信公众号即将过期提醒,预约人:{}订单ID: {}", order.getUname(), order.getPkId());
// 获取过期时间
Date expireTime = (Date) redisUtil.get(key);
// 如果当前时间接近过期时间(5分钟内)
if (expireTime != null && DateUtil.between(currentTime, expireTime, DateUnit.MINUTE) <= 5) {
String id = key.substring(key.lastIndexOf(":") + 1);
OrderSwapBatteryPre order = orderSwapBatteryPreDao.selectById(id);
if (order != null && order.getStatus() == 1) { // 只处理状态为1的预约单
// 发送微信公众号提醒
templateMessageService.preOrderMessageSend(order);
reminderCount++;
// 从Redis中删除该预约单
redisUtil.del(key);
log.info("发送微信公众号即将过期提醒,预约人:{}订单ID: {}", order.getUname(), order.getPkId());
}
}
} catch (Exception e) {

View File

@ -7,10 +7,12 @@
<result column="name" property="stationName" />
<result column="code" property="stationCode" />
<result column="quantity" property="quantity" />
<result column="totalAmount" property="totalAmount" />
</resultMap>
<resultMap id="homeAmountResultMap" type="com.evotech.hd.common.core.Dto.result.home.HomeOrderSwapBatteryAmountDto">
<result column="amount" property="amount" />
<result column="dataCount" property="dataCount" />
<result column="status" property="status" />
</resultMap>
@ -28,6 +30,28 @@
<result column="payType" property="payType" />
</resultMap>
<resultMap id="findOrderListByStatusMap" type="com.evotech.hd.common.core.Dto.result.home.HomeOrderInfo">
<result column="order_time" property="swapTime" />
<result column="plate_num" property="swapCar" />
<result column="order_pre_uname" property="swapUserName" />
<result column="amount" property="swapAmount" />
</resultMap>
<select id="findOrderListByStatus" resultMap="findOrderListByStatusMap">
select order_time,
plate_num,
order_pre_uname,
amount
from hd_cloud_manage.yt_t_order_swap_battery osb
where del_Flag = 0
<if test="status!= null">
and status !=#{status}
</if>
order by order_time desc
</select>
<select id="homeFindProportionData" resultMap="homeProportionResultMap">
select ifnull(count(osb.pk_id),0) as quantity,
bs.code,
@ -40,12 +64,15 @@
</select>
<select id="homeFindAmountData" resultMap="homeAmountResultMap">
select osb.amount,
-- select osb.amount,
-- osb.status
select ifnull(sum(osb.amount),0) amount,ifnull(count(osb.pk_id),0) as dataCount,
osb.status
from hd_cloud_manage.yt_t_order_swap_battery osb
where DATE_FORMAT(osb.order_time,"%Y-%m-%d") >= DATE_FORMAT(#{params.begin},"%Y-%m-%d")
and DATE_FORMAT(#{params.end},"%Y-%m-%d") >= DATE_FORMAT(osb.order_time,"%Y-%m-%d")
and osb.amount is not null
GROUP by osb.status
</select>
<select id="homeFindHalfYearOrderData" resultMap="homeHalfYearResultMap">
@ -62,6 +89,32 @@
</select>
<select id="homeFindHalfYearAmountData" resultMap="homeHalfYearAmountResultMap">
select
DATE_FORMAT(osb.order_time,"%Y-%m") as y_m,
ifnull(count(osb.pk_id), 0) as quantity,
sum(ifnull(osb.amount,0)) as totalMoney
from
hd_cloud_manage.yt_t_order_swap_battery osb
where DATE_FORMAT(osb.order_time,"%Y-%m") >= DATE_FORMAT(#{params.begin},"%Y-%m")
and DATE_FORMAT(#{params.end},"%Y-%m") >= DATE_FORMAT(osb.order_time,"%Y-%m")
and osb.amount is not null
and osb.status = 7
GROUP by y_m
</select>
<select id="homeFindHalfYearStationAmountData" resultMap="homeHalfYearAmountResultMap">
select
DATE_FORMAT(osb.order_time,"%Y-%m") as y_m,
ifnull(count(osb.pk_id), 0) as quantity
from
hd_cloud_manage.yt_t_order_swap_battery osb
where DATE_FORMAT(osb.order_time,"%Y-%m") >= DATE_FORMAT(#{params.begin},"%Y-%m")
and DATE_FORMAT(#{params.end},"%Y-%m") >= DATE_FORMAT(osb.order_time,"%Y-%m")
and osb.amount is not null
and osb.status = 7
GROUP by y_m
</select>
<!--<select id="homeFindHalfYearAmountData" resultMap="homeHalfYearAmountResultMap">
select
DATE_FORMAT(osb.order_time,"%Y-%m") as y_m,
ifnull(count(osb.pk_id), 0) as quantity,
@ -78,7 +131,7 @@
and td.pay_type IS not null
and osb.status in (-1,7)
GROUP by y_m,osb.status,td.pay_type
</select>
</select>-->
<select id="homeFindOrderCountData" resultType="java.lang.Long" >

View File

@ -35,6 +35,8 @@ public class GZHProperties {
private String orderToPayTemplateId2;
private String WalletBackTemplateId;
//站点报警, 通知负责人
private String alarmTemplateId;
//暂停服务, 通知预约单客户通知
private String stopServerTemplateId;
}

View File

@ -1,29 +1,23 @@
package com.evotech.hd.wechat.controller;
import java.util.List;
import com.evotech.hd.common.core.entity.cloud.Company;
import com.evotech.hd.wechat.service.rpc.CloudService;
import jakarta.validation.Valid;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.evotech.hd.common.core.entity.BasePageRequest;
import com.evotech.hd.common.core.entity.Result;
import com.evotech.hd.common.core.entity.cloud.Company;
import com.evotech.hd.common.core.entity.cloud.WalletAccount;
import com.evotech.hd.common.core.entity.cloud.WalletAccountDetail;
import com.evotech.hd.common.core.entity.wechat.WechatUser;
import com.evotech.hd.wechat.service.WechatUserService;
import com.evotech.hd.wechat.service.rpc.CloudService;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Tag(name = "微信用户")
@RestController
@ -71,7 +65,7 @@ public class WechatUserController {
@Operation(summary = "查询钱包账户")
@PostMapping("/wallet/list")
@ApiOperationSupport(order = 5)
public Result<List<WalletAccount>> listWallet(String wuid, HttpServletRequest request) {
public Result<List<WalletAccount>> listWallet(@RequestParam(name = "wuid") String wuid, HttpServletRequest request) {
return wechatUserService.listWallet(wuid, request);
}

View File

@ -1,13 +1,7 @@
package com.evotech.hd.wechat.controller.gzh;
import com.evotech.hd.common.core.Dto.request.template.AlarmTemplateDto;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.evotech.hd.common.core.Dto.request.template.StopServerTemplateDto;
import com.evotech.hd.common.core.entity.Result;
import com.evotech.hd.common.core.entity.cloud.OrderSwapBattery;
import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryPre;
@ -15,13 +9,12 @@ import com.evotech.hd.common.core.entity.cloud.TradeDetail;
import com.evotech.hd.wechat.service.gzh.GZHMessageTemplateService;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import java.util.List;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.web.bind.annotation.*;
@Tag(name = "公众号发送消息")
@RestController
@ -88,8 +81,8 @@ public class GZHMessageSendController {
@Operation(summary = "站端停止服务, 推送客户")
@PostMapping("/service")
@ApiOperationSupport(order = 6)
public com.evotech.hd.common.core.Dto.Result<String> serviceStopMessageSend(@RequestParam List<String> wuIds, @RequestParam String reason) {
return gzhMessageTemplateService.sendTemplateServiceStop(wuIds, reason);
public com.evotech.hd.common.core.Dto.Result<String> serviceStopMessageSend(@RequestBody StopServerTemplateDto stopServerTemplateDto) {
return gzhMessageTemplateService.sendTemplateServiceStop(stopServerTemplateDto);
}
}

View File

@ -0,0 +1,34 @@
package com.evotech.hd.wechat.entity.gzh.templatemessage;
import cn.hutool.json.JSONObject;
import lombok.Data;
/**
*
* 站端报警通知类
* @ClassName:AlarmMessageTemplateData
* @date: 2025年05月05日 17:24
* @author: andy.shi
* @contact: 17330188597
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
@Data
public class StopServerMessageTemplateData {
/***
* 站点名称
*/
private JSONObject thing1;
/***
* 车牌号
*/
private JSONObject car_number2;
/***
* 取消原因
*/
private JSONObject const3;
/***
* 报警时间
*/
private JSONObject time4;
}

View File

@ -0,0 +1,30 @@
package com.evotech.hd.wechat.entity.gzh.templatemessage;
import cn.hutool.json.JSONObject;
import lombok.Data;
/**
*
* 站端报警通知类
* @ClassName:AlarmMessageTemplateData
* @date: 2025年05月05日 17:24
* @author: andy.shi
* @contact: 17330188597
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
@Data
public class StopServerSendAdminMessageTemplateData {
/***
* 站点名称
*/
private JSONObject thing1;
/***
* 温馨提示
*/
private JSONObject thing3;
/***
* 下线时间
*/
private JSONObject time4;
}

View File

@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.evotech.hd.common.core.Dto.ResultUtil;
import com.evotech.hd.common.core.Dto.request.template.AlarmTemplateDto;
import com.evotech.hd.common.core.Dto.request.template.StopServerTemplateDto;
import com.evotech.hd.common.core.dao.cloud.OrderSwapBatteryDao;
import com.evotech.hd.common.core.dao.wechat.WechatUserDao;
import com.evotech.hd.common.core.entity.Result;
@ -285,7 +286,6 @@ public class GZHMessageTemplateService {
* @return
*/
public com.evotech.hd.common.core.Dto.Result<String> sendTemplateMessageAlarm(AlarmTemplateDto alarmTemplateDto) {
Map<String, String> gzhOpenIdMap = wechatUserDao.selectList(new LambdaQueryWrapper<WechatUser>().in(WechatUser::getWuid, alarmTemplateDto.getWuid()).isNotNull(WechatUser::getGzhOpenid).select(WechatUser::getWuid, WechatUser::getGzhOpenid)).stream().collect(Collectors.toMap(WechatUser::getWuid,WechatUser::getGzhOpenid, (d1,d2) -> d1));
if (Collections.isEmpty(gzhOpenIdMap)) {
return new com.evotech.hd.common.core.Dto.Result<String>().error(CodeMsg.PARAM_IS_NULL,"当前工作人员没有关注服务号");
@ -334,54 +334,101 @@ public class GZHMessageTemplateService {
* 告警信息推送公众号消息
* @return
*/
public com.evotech.hd.common.core.Dto.Result<String> sendTemplateServiceStop(List<String> wuIds, String reason) {
public com.evotech.hd.common.core.Dto.Result<String> sendTemplateServiceStop(StopServerTemplateDto stopServerTemplateDto) {
//因检修原因站点暂停运营请预约其他站点
//因调试原因站点暂停运营请预约其他站点
StringBuilder error = new StringBuilder("");
if(Collections.isNotEmpty(stopServerTemplateDto.getPlateNum())){
Map<String, String> gzhOpenIdMap = wechatUserDao.selectList(new LambdaQueryWrapper<WechatUser>().in(WechatUser::getWuid, stopServerTemplateDto.getPlateNum().keySet()).isNotNull(WechatUser::getGzhOpenid).select(WechatUser::getWuid, WechatUser::getGzhOpenid)).stream().collect(Collectors.toMap(WechatUser::getWuid,WechatUser::getGzhOpenid, (d1,d2) -> d1));
if (Collections.isNotEmpty(gzhOpenIdMap)) {
//组装数据
StopServerMessageTemplateData data = new StopServerMessageTemplateData();
data.setThing1(JSONUtil.parseObj(Collections.asMap("value", stopServerTemplateDto.getStationName())));
data.setConst3(JSONUtil.parseObj(Collections.asMap("value", stopServerTemplateDto.getReason())));
data.setTime4(JSONUtil.parseObj(Collections.asMap("value", DateUtil.format(new Date(),"yyy年MM月dd HH:mm"))));
return new com.evotech.hd.common.core.Dto.Result<String>().success("模版审核中, 暂时不做");
String templateId = gzhProperties.getStopServerTemplateId();
List<String> errorGzhOpenIdList = Collections.emptyList();
gzhOpenIdMap.keySet().forEach(wuId ->{
data.setCar_number2(JSONUtil.parseObj(Collections.asMap("value", stopServerTemplateDto.getPlateNum().get(wuId))));//动态跟换车牌号
String result = ResultUtil.getValue(sendTemplateMessage(gzhOpenIdMap.get(wuId),templateId, JSONUtil.parseObj(data),true));
if(org.apache.commons.lang3.StringUtils.isEmpty(result)){
errorGzhOpenIdList.add(gzhOpenIdMap.get(wuId));
}
});
if(Collections.isNotEmpty(errorGzhOpenIdList)){
error.append("以下公众号ID推送取消预约单信息失败了").append(String.join(",", errorGzhOpenIdList)).append(";");
}
// Map<String, String> gzhOpenIdMap = wechatUserDao.selectList(new LambdaQueryWrapper<WechatUser>().in(WechatUser::getWuid, wuIds).isNotNull(WechatUser::getGzhOpenid).select(WechatUser::getWuid, WechatUser::getGzhOpenid)).stream().collect(Collectors.toMap(WechatUser::getWuid,WechatUser::getGzhOpenid, (d1,d2) -> d1));
// if (Collections.isEmpty(gzhOpenIdMap)) {
// return new com.evotech.hd.common.core.Dto.Result<String>().error(CodeMsg.PARAM_IS_NULL,"当前预约客户没有关注服务号");
// }
// StringBuilder error = new StringBuilder("");
// Iterator<String> iterator = wuIds.iterator();
// List<String> existsGzhOpenIdList = gzhOpenIdMap.keySet().stream().collect(Collectors.toList());
// while (iterator.hasNext()) {
// String key = iterator.next();
// if (existsGzhOpenIdList.contains(key)) {
// iterator.remove(); // 删除当前迭代的元素"b"
Iterator<String> iterator = stopServerTemplateDto.getPlateNum().keySet().iterator();
List<String> existsGzhOpenIdList = gzhOpenIdMap.keySet().stream().collect(Collectors.toList());
while (iterator.hasNext()) {
String key = iterator.next();
if (existsGzhOpenIdList.contains(key)) {
iterator.remove(); // 删除当前迭代的元素"b"
}
}
//去掉存在gzhopenid的wuid对象
List<String> oldWuIdList = StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.ORDERED), false)
.collect(Collectors.toList());
if(Collections.isNotEmpty(oldWuIdList)){
error.append("以下用户ID没有关注公众号").append(String.join(",", oldWuIdList)).append(";");
}
}
}
// if(Collections.isNotEmpty(stopServerTemplateDto.getAdminWuId())){
// Map<String, String> gzhOpenIdMap = wechatUserDao.selectList(new LambdaQueryWrapper<WechatUser>().in(WechatUser::getWuid, stopServerTemplateDto.getAdminWuId()).isNotNull(WechatUser::getOpenid).select(WechatUser::getWuid, WechatUser::getOpenid)).stream().collect(Collectors.toMap(WechatUser::getWuid,WechatUser::getOpenid, (d1,d2) -> d1));
// if (Collections.isNotEmpty(gzhOpenIdMap)) {
// //组装数据
// StopServerSendAdminMessageTemplateData data = new StopServerSendAdminMessageTemplateData();
// data.setThing1(JSONUtil.parseObj(Collections.asMap("value", stopServerTemplateDto.getStationName())));
// data.setThing3(JSONUtil.parseObj(Collections.asMap("value", stopServerTemplateDto.getReason())));
// data.setTime4(JSONUtil.parseObj(Collections.asMap("value", DateUtil.format(new Date(),"yyy年MM月dd HH:mm"))));
//
//// String templateId = gzhProperties.getStopServerTemplateId();
// List<String> errorGzhOpenIdList = Collections.emptyList();
// gzhOpenIdMap.keySet().forEach(wuId ->{
// String result = ResultUtil.getValue(sendTemplateMessage(false, gzhOpenIdMap.get(wuId),"HpPsQpeS5zlneMEaWyiB2k3m_tF8gpkzGuN5SkRV6rI", JSONUtil.parseObj(data),true));
// if(org.apache.commons.lang3.StringUtils.isEmpty(result)){
// errorGzhOpenIdList.add(gzhOpenIdMap.get(wuId));
// }
// });
// if(Collections.isNotEmpty(errorGzhOpenIdList)){
// error.append("以下工作人员推送站点关闭消息失败了").append(String.join(",", errorGzhOpenIdList)).append(";");
// }
//
// Iterator<String> iterator = stopServerTemplateDto.getAdminWuId().iterator();
// List<String> existsGzhOpenIdList = gzhOpenIdMap.keySet().stream().collect(Collectors.toList());
// while (iterator.hasNext()) {
// String key = iterator.next();
// if (existsGzhOpenIdList.contains(key)) {
// iterator.remove(); // 删除当前迭代的元素"b"
// }
// }
// //去掉存在gzhopenid的wuid对象
// List<String> oldWuIdList = StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.ORDERED), false)
// .collect(Collectors.toList());
// if(Collections.isNotEmpty(oldWuIdList)){
// error.append("以下工作人员没有关注公众号").append(String.join(",", oldWuIdList)).append(";");
// }
// }
// }
// //去掉存在gzhopenid的wuid对象
// List<String> oldWuIdList = StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.ORDERED), false)
// .collect(Collectors.toList());
// if(Collections.isNotEmpty(oldWuIdList)){
// error.append("以下用户ID没有关注公众号").append(String.join(",", oldWuIdList)).append(";");
// }
//
// AlarmMessageTemplateData data = new AlarmMessageTemplateData();
// String templateId = gzhProperties.getWalletBackTemplateId();
// List<String> errorGzhOpenIdList = Collections.emptyList();
// gzhOpenIdMap.values().forEach(gzhOpenId ->{
// String result = ResultUtil.getValue(sendTemplateMessage( gzhOpenId,templateId,JSONUtil.parseObj(data),true));
// if(org.apache.commons.lang3.StringUtils.isEmpty(result)){
// errorGzhOpenIdList.add(gzhOpenId);
// }
// });
// if(Collections.isNotEmpty(errorGzhOpenIdList)){
// error.append("以下公众号ID推送站端停止运营消息失败了").append(String.join(",", errorGzhOpenIdList)).append(";");
// }
//
// if(org.apache.commons.lang3.StringUtils.isNotEmpty(error)){
// return new com.evotech.hd.common.core.Dto.Result<String>().error(CodeMsg.PARAM_IS_NULL,error.toString());
// }
// return new com.evotech.hd.common.core.Dto.Result<String>().success("成功");
if(org.apache.commons.lang3.StringUtils.isNotEmpty(error)){
return new com.evotech.hd.common.core.Dto.Result<String>().error(CodeMsg.PARAM_IS_NULL,error.toString());
}
return new com.evotech.hd.common.core.Dto.Result<String>().success("成功");
}
private com.evotech.hd.common.core.Dto.Result<String> sendTemplateMessage(String gzhOpenId, String templateId, JSONObject templateData, Boolean isJumpApplet){
return sendTemplateMessage(true, gzhOpenId, templateId, templateData, isJumpApplet);
}
private com.evotech.hd.common.core.Dto.Result<String> sendTemplateMessage(Boolean isTemplate, String gzhOpenId, String templateId, JSONObject templateData, Boolean isJumpApplet){
MessageTemplateSendData sendData = new MessageTemplateSendData();
sendData.setTouser(gzhOpenId);
sendData.setTemplate_id(templateId);
@ -392,8 +439,13 @@ public class GZHMessageTemplateService {
miniprogram.setPath(orderPage);
sendData.setMiniprogram(miniprogram);
}
String res = null;
if(isTemplate){
res = TemplateMessageUtil.templateMessageSend(gzhAccessTokenService.gzhAccessToken(), sendData);
}else{
res = TemplateMessageUtil.templateMessageSendGZH(gzhAccessTokenService.gzhAccessToken(), sendData);
}
String res = TemplateMessageUtil.templateMessageSend(gzhAccessTokenService.gzhAccessToken(), sendData);
JSONObject jo = JSONUtil.parseObj(res);
if (jo.getInt("errcode") == 0) {
return new com.evotech.hd.common.core.Dto.Result<String>().success(jo.toString());

View File

@ -27,4 +27,22 @@ public class TemplateMessageUtil {
return res;
}
private static String templateGetcategorySendUrl = "https://api.weixin.qq.com/wxaapi/newtmpl/getcategory?access_token=";
/**
* 发送模板消息 POST
* @param accessToken
* @param templateData
* @return
*/
public static String templateMessageSendGZH(String accessToken, MessageTemplateSendData templateData) {
String body = JSONUtil.toJsonStr(templateData);
String res = HttpRequest.post(templateGetcategorySendUrl + accessToken)
.header("Content-Type", "application/json")
.body(body)
.execute()
.body();
return res;
}
}

View File

@ -126,4 +126,5 @@ hbyt:
wallet_recharge_template_id: 8JXsn_VkI0S0YZSbT2EKmV_zOxyudo4IsBLeU7V-SFk
order_to_pay_template_id2: K6cdaBOkxGJpah0vsz5rq5UBID04mk-eEWp2XM0KyA0
wallet_back_template_id: aO9GDhgIcYnCDCpsVSMB-CeXG3J4JzHlOUV2bhOAvVI
alarm_template_id: 8vW_gOzoOMzlJqvtSOF0fLeNm8Z6pttJG63oeFe1gq4
alarm_template_id: 8vW_gOzoOMzlJqvtSOF0fLeNm8Z6pttJG63oeFe1gq4
stop_server_template_id: RVrVqa9Y8-AjOCHxp9LWAnYejjphZhLoHJr0pU2nReo