优化调整
This commit is contained in:
parent
6e3449a3bc
commit
2ffc8e79a8
@ -5,33 +5,42 @@
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="ec76006e-5a88-4766-9722-bc8eda172857" name="Changes" comment="">
|
||||
<change afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/config/mqtt/MqttConfigOld.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/commoms/mongodb/src/main/java/com/evotech/hd/config/ElectricityMeterBoxProperties.java" beforeDir="false" afterPath="$PROJECT_DIR$/commoms/mongodb/src/main/java/com/evotech/hd/config/ElectricityMeterBoxProperties.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/commoms/mongodb/src/main/resources/application-mongo.yml" beforeDir="false" afterPath="$PROJECT_DIR$/commoms/mongodb/src/main/resources/application-mongo.yml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/commoms/core/src/main/java/com/evotech/hd/core/dtos/business/AccessStrategyDTO.java" beforeDir="false" afterPath="$PROJECT_DIR$/commoms/core/src/main/java/com/evotech/hd/core/dtos/business/AccessStrategyDTO.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/commoms/core/src/main/java/com/evotech/hd/core/dtos/business/BatteryCompartmentDTO.java" beforeDir="false" afterPath="$PROJECT_DIR$/commoms/core/src/main/java/com/evotech/hd/core/dtos/business/BatteryCompartmentDTO.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/commoms/core/src/main/java/com/evotech/hd/core/dtos/system/ParamsDTO.java" beforeDir="false" afterPath="$PROJECT_DIR$/commoms/core/src/main/java/com/evotech/hd/core/dtos/system/ParamsDTO.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/commoms/core/src/main/java/com/evotech/hd/core/entity/system/AccessStrategy.java" beforeDir="false" afterPath="$PROJECT_DIR$/commoms/core/src/main/java/com/evotech/hd/core/entity/system/AccessStrategy.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/commoms/core/src/main/java/com/evotech/hd/core/entity/system/Params.java" beforeDir="false" afterPath="$PROJECT_DIR$/commoms/core/src/main/java/com/evotech/hd/core/entity/system/Params.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/commoms/mongodb/src/main/resources/application-mongoDev.yml" beforeDir="false" afterPath="$PROJECT_DIR$/commoms/mongodb/src/main/resources/application-mongoDev.yml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/WebServerApplication.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/WebServerApplication.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/config/mqtt/MessageTopic.java" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/config/mqtt/MqttConfig.java" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/cnstant/ParamSysConstants.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/cnstant/ParamSysConstants.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/config/handler/GlobalExceptionHandler.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/config/handler/GlobalExceptionHandler.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/config/mqtt/MqttMessageCallback.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/config/mqtt/MqttMessageCallback.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/config/mqtt/MqttProperties.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/config/mqtt/MqttProperties.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/config/mqtt/MqttPublishMessage.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/config/mqtt/MqttPublishMessage.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/controller/ManualOperationController.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/controller/ManualOperationController.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/controller/OrderSwapController.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/controller/OrderSwapController.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/controller/TestController.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/controller/TestController.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/job/job/BaseJob.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/job/job/BaseJob.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/job/JobConstant.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/job/JobConstant.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/job/job/CheckAlarmJob.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/job/job/CheckAlarmJob.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/job/job/charging/ChargingFullOfJob.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/job/job/charging/ChargingFullOfJob.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/job/service/ExecutionBatterySwapService.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/job/service/ExecutionBatterySwapService.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/mqtt/MessageTopic.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/mqtt/MessageTopic.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/mapper/BatteryCompartmentMapper.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/mapper/BatteryCompartmentMapper.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/mqtt/MessageUtilService.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/mqtt/MessageUtilService.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/mqtt/MqttMessageHeader.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/mqtt/MqttMessageHeader.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/service/OrderChargingService.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/service/OrderChargingService.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/service/impl/OrderChargingServiceImpl.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/service/impl/OrderChargingServiceImpl.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/mqtt/MqttMessageHandleService.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/mqtt/MqttMessageHandleService.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/mqtt/MqttPublishUtils.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/mqtt/MqttPublishUtils.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/service/BatteryCompartmentService.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/service/BatteryCompartmentService.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/service/OrderSwapService.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/service/OrderSwapService.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/service/ParamsService.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/service/ParamsService.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/service/impl/BatteryCompartmentServiceImpl.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/service/impl/BatteryCompartmentServiceImpl.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/service/impl/OrderReservationServiceImpl.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/service/impl/OrderReservationServiceImpl.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/service/impl/OrderSwapServiceImpl.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/service/impl/OrderSwapServiceImpl.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/service/impl/ParamsServiceImpl.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/service/impl/ParamsServiceImpl.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/utils/AccessStrategyUtil.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/utils/AccessStrategyUtil.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/utils/ParamUtils.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/utils/ParamUtils.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/utils/instruction/InstructionReadUtils.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/utils/instruction/InstructionReadUtils.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/utils/instruction/InstructionWriteUtils.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/utils/instruction/InstructionWriteUtils.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/utils/sendCloud/CloudSendInfoUtils.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/utils/sendCloud/CloudSendInfoUtils.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/utils/sendCloud/RsaEcbPkcsFullUtil.java" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/utils/sendCloud/RsaEcbPkcsFullUtil.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/resources/application-dev.yml" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/resources/application-dev.yml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/resources/application-pro.yml" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/resources/application-pro.yml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/resources/application.yml" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/resources/application.yml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/resources/mapper/AccessStrategyMapper.xml" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/resources/mapper/AccessStrategyMapper.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/resources/mapper/BatteryCompartmentMapper.xml" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/resources/mapper/BatteryCompartmentMapper.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web-server/src/main/resources/mapper/ParamsMapper.xml" beforeDir="false" afterPath="$PROJECT_DIR$/web-server/src/main/resources/mapper/ParamsMapper.xml" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
@ -81,6 +90,7 @@
|
||||
"Application.XmlRpcHttpDirectCall.executor": "Run",
|
||||
"Application.test111.executor": "Run",
|
||||
"Maven.commoms [clean].executor": "Run",
|
||||
"Maven.commoms [install].executor": "Run",
|
||||
"Maven.commoms [package].executor": "Run",
|
||||
"Maven.core [clean].executor": "Run",
|
||||
"Maven.core [install].executor": "Run",
|
||||
@ -97,7 +107,10 @@
|
||||
"Maven.web-server [clean].executor": "Run",
|
||||
"Maven.web-server [compile].executor": "Run",
|
||||
"Maven.web-server [dependency:resolve,-U].executor": "Run",
|
||||
"Maven.web-server [install].executor": "Run",
|
||||
"Maven.web-server [package].executor": "Run",
|
||||
"Maven.web-server [validate].executor": "Run",
|
||||
"Maven.web-server [verify].executor": "Run",
|
||||
"RequestMappingsPanelOrder0": "0",
|
||||
"RequestMappingsPanelOrder1": "1",
|
||||
"RequestMappingsPanelWidth0": "75",
|
||||
@ -107,7 +120,7 @@
|
||||
"Spring Boot.WebServerApplication.executor": "Debug",
|
||||
"git-widget-placeholder": "master",
|
||||
"kotlin-language-version-configured": "true",
|
||||
"last_opened_file_path": "D:/andy/ideaWorker/andy/blc/download/应用端/backend",
|
||||
"last_opened_file_path": "D:/andy/ideaWorker/station-control/web-server/src/main/resources/mapper",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.detected.package.tslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
@ -125,21 +138,21 @@
|
||||
</component>
|
||||
<component name="RecentsManager">
|
||||
<key name="CopyFile.RECENT_KEYS">
|
||||
<recent name="D:\andy\ideaWorker\station-control\web-server\src\main\resources\mapper" />
|
||||
<recent name="D:\andy\ideaWorker\station-control\commoms\core\src\main\resources" />
|
||||
<recent name="D:\andy\ideaWorker\station-control\commoms\mongodb\src\main\java\com\evotech\hd\config" />
|
||||
<recent name="D:\andy\ideaWorker\my\station-control\web-server\src\main\resources" />
|
||||
<recent name="D:\andy\ideaWorker\my\station-control\web-server\src\main\resources\mapper" />
|
||||
<recent name="D:\andy\ideaWorker\my\station-control\commoms\mongodb\src\main\resources" />
|
||||
<recent name="D:\andy\ideaWorker\my\station-control\web-server\src\main\java\com\evotech\hd\webserver\config\swagger" />
|
||||
</key>
|
||||
<key name="MoveFile.RECENT_KEYS">
|
||||
<recent name="D:\andy\ideaWorker\my\station-control\web-server\src\main\resources" />
|
||||
</key>
|
||||
<key name="CopyClassDialog.RECENTS_KEY">
|
||||
<recent name="com.evotech.hd.entity" />
|
||||
<recent name="com.evotech.hd.core.dtos.mqtt" />
|
||||
<recent name="com.evotech.hd.webserver.mqtt" />
|
||||
<recent name="com.evotech.hd.webserver.config.mqtt" />
|
||||
<recent name="com.evotech.hd.webserver.job.service" />
|
||||
<recent name="com.evotech.hd.webserver.mqtt.enums" />
|
||||
<recent name="com.evotech.hd.core.dtos.system" />
|
||||
<recent name="com.evotech.hd.webserver.mapper" />
|
||||
<recent name="com.evotech.hd.webserver.service.impl" />
|
||||
<recent name="com.evotech.hd.webserver.service" />
|
||||
</key>
|
||||
</component>
|
||||
<component name="RunAnythingCache">
|
||||
@ -391,7 +404,14 @@
|
||||
<workItem from="1765939118169" duration="98526000" />
|
||||
<workItem from="1766623919531" duration="18086000" />
|
||||
<workItem from="1766800226399" duration="599000" />
|
||||
<workItem from="1766810719772" duration="1371000" />
|
||||
<workItem from="1766810719772" duration="79701000" />
|
||||
<workItem from="1767582650417" duration="76709000" />
|
||||
<workItem from="1767939652097" duration="67647000" />
|
||||
<workItem from="1768356164082" duration="15456000" />
|
||||
<workItem from="1768809252266" duration="601000" />
|
||||
<workItem from="1768955894610" duration="4133000" />
|
||||
<workItem from="1768987212149" duration="43024000" />
|
||||
<workItem from="1769503255745" duration="74993000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
@ -399,6 +419,15 @@
|
||||
<option name="version" value="3" />
|
||||
</component>
|
||||
<component name="XDebuggerManager">
|
||||
<breakpoint-manager>
|
||||
<breakpoints>
|
||||
<line-breakpoint enabled="true" type="java-line">
|
||||
<url>file://$PROJECT_DIR$/web-server/src/main/java/com/evotech/hd/webserver/controller/TestController.java</url>
|
||||
<line>1480</line>
|
||||
<option name="timeStamp" value="3" />
|
||||
</line-breakpoint>
|
||||
</breakpoints>
|
||||
</breakpoint-manager>
|
||||
<watches-manager>
|
||||
<configuration name="SpringBootApplicationConfigurationType">
|
||||
<watch expression="import com.evotech.hd.entity.system.Params; " />
|
||||
|
||||
@ -46,7 +46,8 @@ public class AccessStrategyDTO extends BaseDTO<AccessStrategyDTO> {
|
||||
|
||||
@ApiModelProperty("生效的Rgv编号")
|
||||
String effectiveRgvNo;
|
||||
|
||||
@ApiModelProperty("电池预取, true是, false 否")
|
||||
Boolean batteryPrefetching;
|
||||
|
||||
@ApiModelProperty(value = "数据是否有效: valid有效 invalid 无效", hidden = true)
|
||||
String valid;
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package com.evotech.hd.core.dtos.business;
|
||||
|
||||
import com.evotech.hd.core.dtos.BaseDTO;
|
||||
import com.evotech.hd.query.Query;
|
||||
import com.evotech.hd.query.QueryType;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
@ -26,9 +28,11 @@ public class BatteryCompartmentDTO extends BaseDTO<BatteryCompartmentDTO> {
|
||||
String batteryCompartmentNo;
|
||||
|
||||
@ApiModelProperty("电池仓状态:1-正常,2-检修, 3-坏")
|
||||
@Query(javaField = "status", tableColumn = "a.status", type = QueryType.EQ)
|
||||
Integer status;
|
||||
|
||||
@ApiModelProperty("运行状态:1正常, 2-禁用")
|
||||
@Query(javaField = "state", tableColumn = "a.state", type = QueryType.EQ)
|
||||
Integer state;
|
||||
|
||||
@ApiModelProperty("排序")
|
||||
|
||||
@ -0,0 +1,59 @@
|
||||
package com.evotech.hd.core.dtos.system;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.evotech.hd.core.dtos.BaseDTO;
|
||||
import com.evotech.hd.query.Query;
|
||||
import com.evotech.hd.query.QueryType;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* mqtt消息
|
||||
*
|
||||
* @ClassName:Log
|
||||
* @date: 2025年08月18日 10:06
|
||||
* @author: andy.shi
|
||||
* @contact: 17330188597
|
||||
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
|
||||
*/
|
||||
@Data
|
||||
@ApiModel("mqtt消息")
|
||||
public class MessageMqttDTO extends BaseDTO<MessageMqttDTO> {
|
||||
|
||||
|
||||
@ApiModelProperty( "换电站")
|
||||
private String stationCode;
|
||||
|
||||
@ApiModelProperty("传送方向")
|
||||
private String direction;
|
||||
|
||||
@ApiModelProperty("消息ID")
|
||||
private String messageId;
|
||||
|
||||
@ApiModelProperty("qos")
|
||||
private Integer qos;
|
||||
|
||||
@ApiModelProperty( "消息类型: 状态信息类、事件记录类、请求与响应类")
|
||||
private String type;
|
||||
|
||||
@ApiModelProperty("方法 stationInfo")
|
||||
private String messageFunction;
|
||||
|
||||
@ApiModelProperty("消息的topic")
|
||||
private String topic;
|
||||
|
||||
@ApiModelProperty("内容,解密后的")
|
||||
private String content;
|
||||
|
||||
@ApiModelProperty("创建时间")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
|
||||
private Date ctime;
|
||||
|
||||
|
||||
}
|
||||
@ -30,6 +30,8 @@ public class ParamsDTO extends BaseDTO<ParamsDTO> {
|
||||
@ApiModelProperty("参数值")
|
||||
@Query(javaField = "paramValue", tableColumn = "a.param_value", type = QueryType.LIKE)
|
||||
String paramValue;
|
||||
@ApiModelProperty("是否影响换电, true 影响, false 不影响")
|
||||
Boolean effectBatterySwapping;
|
||||
|
||||
@ApiModelProperty("预期结果, 不满足预期返回错误信息")
|
||||
String expectedResults;
|
||||
|
||||
@ -50,6 +50,10 @@ public class AccessStrategy extends BaseEntity {
|
||||
*生效的RGV编号
|
||||
*/
|
||||
String effectiveRgvNo;
|
||||
/***
|
||||
*电池预取
|
||||
*/
|
||||
Boolean batteryPrefetching;
|
||||
/***
|
||||
* 数据是否有效: valid有效 invalid 无效
|
||||
*/
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
package com.evotech.hd.core.entity.system;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.evotech.hd.core.entity.BaseEntity;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @author zrb
|
||||
* @since 2024-11-06
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@TableName("sc_sys_message_mqtt")
|
||||
public class MessageMqtt extends BaseEntity {
|
||||
|
||||
private String stationCode;
|
||||
|
||||
private String direction;
|
||||
|
||||
private String messageId;
|
||||
|
||||
private Integer qos;
|
||||
|
||||
private String type;
|
||||
|
||||
private String messageFunction;
|
||||
|
||||
private String topic;
|
||||
|
||||
private String content;
|
||||
|
||||
|
||||
public MessageMqtt() {
|
||||
}
|
||||
|
||||
public MessageMqtt(String stationCode, String direction, String type, String messageFunction) {
|
||||
this.stationCode = stationCode;
|
||||
this.direction = direction;
|
||||
this.type = type;
|
||||
this.messageFunction = messageFunction;
|
||||
}
|
||||
}
|
||||
@ -32,6 +32,8 @@ public class Params extends BaseEntity {
|
||||
|
||||
String expectedResults;
|
||||
|
||||
Boolean effectBatterySwapping;
|
||||
|
||||
Boolean verifyResult;
|
||||
|
||||
String errMessage;
|
||||
|
||||
59
commoms/core/src/main/java/com/evotech/hd/utils/Global.java
Normal file
59
commoms/core/src/main/java/com/evotech/hd/utils/Global.java
Normal file
@ -0,0 +1,59 @@
|
||||
package com.evotech.hd.utils;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 全局属性配置
|
||||
* @author andy.shi
|
||||
* @ClassName:Global
|
||||
* @date: 2026年01月10日 10:16
|
||||
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
|
||||
*/
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "ythd", ignoreInvalidFields = true)
|
||||
@Data
|
||||
public class Global{
|
||||
/***
|
||||
* 云平台私钥
|
||||
*/
|
||||
@Value("${ythd.cloud-private-key}")
|
||||
public String cloudPrivateKey;
|
||||
/***
|
||||
* 云平台公钥
|
||||
*/
|
||||
@Value("${ythd.cloud-public-key}")
|
||||
public String cloudPublicKey;
|
||||
|
||||
@Value("${ythd.static-public-key}")
|
||||
public String staticPublicKey;
|
||||
//单例模式全局属性
|
||||
private static volatile Global global;
|
||||
|
||||
|
||||
public static Global newInstance() {
|
||||
if(global == null){
|
||||
synchronized (Global.class){
|
||||
if(global == null){
|
||||
global = SpringUtils.getBean(Global.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
return global;
|
||||
}
|
||||
|
||||
|
||||
public String getCloudPrivateKey() {
|
||||
return cloudPrivateKey;
|
||||
}
|
||||
|
||||
public String getCloudPublicKey() {
|
||||
return cloudPublicKey;
|
||||
}
|
||||
|
||||
public String getStaticPublicKey() {
|
||||
return staticPublicKey;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
package com.evotech.hd.utils;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* SpringUtils
|
||||
*
|
||||
* @author andy.shi
|
||||
* @ClassName:SpringUtils
|
||||
* @date: 2026年01月10日 11:11
|
||||
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
|
||||
*/
|
||||
@Component
|
||||
public class SpringUtils implements ApplicationContextAware {
|
||||
|
||||
|
||||
private static ApplicationContext applicationContext;
|
||||
|
||||
/**
|
||||
* Spring容器启动时,会自动调用这个方法,注入上下文对象
|
||||
*/
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext context) throws BeansException {
|
||||
// 将Spring上下文赋值给静态变量
|
||||
SpringUtils.applicationContext = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* 静态方法:根据Bean类型获取实例
|
||||
* @param clazz Bean的类型
|
||||
* @return 对应的Bean实例
|
||||
*/
|
||||
public static <T> T getBean(Class<T> clazz) {
|
||||
// 校验上下文是否初始化完成
|
||||
if (applicationContext == null) {
|
||||
throw new RuntimeException("Spring上下文未初始化,无法获取Bean");
|
||||
}
|
||||
return applicationContext.getBean(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* 静态方法:根据Bean名称获取实例(备用,优先用类型获取)
|
||||
* @param beanName Bean的名称
|
||||
* @return 对应的Bean实例
|
||||
*/
|
||||
public static Object getBean(String beanName) {
|
||||
if (applicationContext == null) {
|
||||
throw new RuntimeException("Spring上下文未初始化,无法获取Bean");
|
||||
}
|
||||
return applicationContext.getBean(beanName);
|
||||
}
|
||||
}
|
||||
5
commoms/core/src/main/resources/application-core.yml
Normal file
5
commoms/core/src/main/resources/application-core.yml
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
ythd:
|
||||
cloud-private-key: MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALEbx7j2XmAo3NiviJIk8/Mo1RF4yT/MYmZdZRnB9iSh4koIiu/KKCGSwvViFGfmP/q8TNLWsvpTVo3MxWBFJkWaALuo/iPu5RJ+tU1l0YXA35zZNxMuiDbmnI7wODRePUY1g5fa1ZNy5oDUQumfrXhDCoFC2AMUBn9KiMr+QQ97AgMBAAECgYAk/lF8X/Gckkx28ktLg251Nu0yZhFbQxy2lwF8HNiGFE5I+nnS1l4FjTstuBvdC+oHPHerfm8J/IhSvBfqIOd6PulJyuh5s31cdc+2SDWUzh8sBm48YHlDfjltZG2ijgM7h/+uvw1gHwXH8JQGF7ZjWguD3TJfqZ/jPFsuxoLKOQJBAOsp+f7kS5VXg6ziKzCMlWOAEfrsAO5ZhLJNMtoirbMQZYUfYxUc3KFWQMT9i9O2M752NXoeUed8a1DjmfyxaX8CQQDAzPs5EPNfpfuGsvJ79lGsH8mZcw7VdjDzmwNVVLLnSOaJxQIPTusjEJ2YmBs+ifCF30VIDpkRd/DGaj4yNgAFAkEAorh1B+6objoUHviQshNU+3iO+HV9X3AJ5eaNHWuJjbH2zVqekOlbsTehsa1Pp7sXqt7YuhtoySjKiTo0PynzuQJBAJsvovsBANQ5VubJ/NH4py6je3LPIN6Cvs4mNJ2nikUN8bps38aQoEVeJ2ve6vcAsqAe4bYpQd3ErAIZHCzwOD0CQF8hDwEGx1S4nJQpB9rmSQhoNzaEJuJKXgpAxNCQ9g4kLRZE+hpZk1kPw+VjGalyyZkY5ilXkWnqsvrprn+wW7Y=
|
||||
cloud-public-key: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCxG8e49l5gKNzYr4iSJPPzKNUReMk/zGJmXWUZwfYkoeJKCIrvyighksL1YhRn5j/6vEzS1rL6U1aNzMVgRSZFmgC7qP4j7uUSfrVNZdGFwN+c2TcTLog25pyO8Dg0Xj1GNYOX2tWTcuaA1ELpn614QwqBQtgDFAZ/SojK/kEPewIDAQAB
|
||||
static-public-key: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC32MZ8u1bK66Uj+Uh3eTfDLcGy4TosSLfksYvJBavX6fckS6vdV8VeYj9gQvTrB6b3VKIdsqf/uP4AjgiKlP34GVMfDr0bEPEccurEhs23QWSHGrVSJG5HPG0B1PBbRMMUwUkmQJxo65Ml6SSPyS/4ebdZ0qeY2/cWaK8laYj7sQIDAQAB
|
||||
@ -1,6 +1,6 @@
|
||||
yt:
|
||||
base_properties:
|
||||
host: 192.168.16.128
|
||||
host: 192.168.5.112
|
||||
port: 27017
|
||||
#用于账号密码验证的库
|
||||
authentication-database: admin
|
||||
|
||||
@ -11,10 +11,6 @@ package com.evotech.hd.webserver.cnstant;
|
||||
|
||||
public class ParamSysConstants {
|
||||
|
||||
/***
|
||||
* 检查电池仓是否存在电池
|
||||
*/
|
||||
public final static String EXISTS_BATTERY = "BSL_BatExist";
|
||||
/***
|
||||
* 设置最大功率
|
||||
*/
|
||||
|
||||
@ -13,8 +13,6 @@ import javax.servlet.ServletException;
|
||||
|
||||
/**
|
||||
* 全局异常处理器,将 Exception 翻译成 CommonResult + 对应的异常编号
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@RestControllerAdvice(basePackages = "com.evotech.hd")
|
||||
@AllArgsConstructor
|
||||
|
||||
@ -0,0 +1,127 @@
|
||||
package com.evotech.hd.webserver.config.mqtt;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.eclipse.paho.client.mqttv3.*;
|
||||
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PreDestroy;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* MqttClientManager
|
||||
*
|
||||
* @author andy.shi
|
||||
* @ClassName:MqttClientManager
|
||||
* @date: 2025年12月23日 15:59
|
||||
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
|
||||
*/
|
||||
@Configuration
|
||||
@Component
|
||||
@Slf4j
|
||||
public class MqttConfig implements CommandLineRunner {
|
||||
|
||||
@Resource
|
||||
MqttProperties mqttProperties;
|
||||
|
||||
static ConcurrentHashMap<String, MqttClient> mqttClientMap = new ConcurrentHashMap<>();
|
||||
// 已重试次数
|
||||
private final AtomicInteger retryCount = new AtomicInteger(0);
|
||||
// 重连执行器
|
||||
private final ScheduledExecutorService reconnectExecutor = Executors.newSingleThreadScheduledExecutor();
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
new Thread(this::connectMqtt, "mqtt-connect-thread").start();
|
||||
}
|
||||
|
||||
public MqttConnectOptions mqttConnectOptions() {
|
||||
MqttConnectOptions options = new MqttConnectOptions();
|
||||
// 设置服务器地址(支持多个,用数组)
|
||||
options.setServerURIs(new String[]{mqttProperties.getBroker()});
|
||||
// 配置认证信息(如果有)
|
||||
if (StringUtils.isNotEmpty(mqttProperties.getUsername())) {
|
||||
options.setUserName(mqttProperties.getUsername());
|
||||
}
|
||||
if (StringUtils.isNotEmpty(mqttProperties.getPassword())) {
|
||||
options.setPassword(mqttProperties.getPassword().toCharArray());
|
||||
}
|
||||
// 其他连接参数
|
||||
options.setKeepAliveInterval(mqttProperties.getKeepAlive()); // 心跳间隔
|
||||
options.setConnectionTimeout(10); // 连接超时时间(秒)
|
||||
options.setAutomaticReconnect(true); // 自动重连
|
||||
options.setCleanSession(true); // 断开后清除会话
|
||||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
* 建立 MQTT 连接
|
||||
*/
|
||||
private void connectMqtt() {
|
||||
try {
|
||||
// 1. 创建 MQTT 连接选项
|
||||
MqttConnectOptions connOpts = mqttConnectOptions();
|
||||
// 2. 创建 MQTT 客户端
|
||||
MqttClient client = new MqttClient(mqttProperties.getBroker(), mqttProperties.getClientId(), new MemoryPersistence());
|
||||
// 3. 设置回调(处理消息、连接断开等事件)
|
||||
client.setCallback(new MqttMessageCallback());
|
||||
// 4. 建立连接
|
||||
if (!client.isConnected()) {
|
||||
client.connect(connOpts);
|
||||
mqttClientMap.put("cloudClient", client);
|
||||
// 重置重试次数
|
||||
retryCount.set(0);
|
||||
}
|
||||
|
||||
} catch (MqttException e) {
|
||||
log.error("MQTT 连接失败,错误码:{},原因:{}", e.getReasonCode(), e.getMessage(), e);
|
||||
// 触发自定义重连逻辑
|
||||
startReconnect();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 启动自动重连
|
||||
*/
|
||||
private void startReconnect() {
|
||||
// 检查是否超过最大重试次数(0 表示无限重试)
|
||||
if (mqttProperties.getMaxRetry() > 0 && retryCount.get() >= mqttProperties.getMaxRetry()) {
|
||||
log.error("MQTT 重连次数已达上限({}次),停止重连", mqttProperties.getMaxRetry());
|
||||
reconnectExecutor.shutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
int currentRetry = retryCount.incrementAndGet();
|
||||
log.info("将在 {} 秒后进行第 {} 次 MQTT 重连", mqttProperties.getRetryInterval(), currentRetry);
|
||||
|
||||
// 延迟执行重连(避免频繁重试)
|
||||
reconnectExecutor.schedule(() -> {
|
||||
if (mqttClientMap.get("cloudClient") == null || !mqttClientMap.get("cloudClient").isConnected()) {
|
||||
connectMqtt();
|
||||
}
|
||||
}, mqttProperties.getRetryInterval(), TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void PreDestroyComplete() {
|
||||
log.info("===>>>程序要关闭了...");
|
||||
MqttClient cloudClient = mqttClientMap.get("cloudClient");
|
||||
try {
|
||||
cloudClient.disconnect();
|
||||
cloudClient.close();
|
||||
log.info("=====>>>关闭了MQTT");
|
||||
} catch (MqttException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -10,13 +10,22 @@ package com.evotech.hd.webserver.config.mqtt;
|
||||
*/
|
||||
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.evotech.hd.core.dtos.system.ParamsDTO;
|
||||
import com.evotech.hd.utils.Collections;
|
||||
import com.evotech.hd.utils.Global;
|
||||
import com.evotech.hd.webserver.job.JobConstant;
|
||||
import com.evotech.hd.webserver.job.service.QuartzJobService;
|
||||
import com.evotech.hd.webserver.mqtt.MessageTopic;
|
||||
import com.evotech.hd.webserver.mqtt.MqttMessageHandleService;
|
||||
import com.evotech.hd.webserver.mqtt.MqttPublishUtils;
|
||||
import com.evotech.hd.webserver.mqtt.enums.MqttMessageTypeEnum;
|
||||
import com.evotech.hd.webserver.service.ParamsService;
|
||||
import com.evotech.hd.webserver.utils.ParamUtils;
|
||||
import com.evotech.hd.webserver.websocket.controller.WebSocketUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.eclipse.paho.client.mqttv3.*;
|
||||
import org.quartz.SchedulerException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
@ -32,9 +41,11 @@ public class MqttMessageCallback implements MqttCallbackExtended, ApplicationCo
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
private MqttMessageHandleService mqttMessageHandleService;
|
||||
|
||||
private static String stationCode;
|
||||
|
||||
static String[] mqttMessageTypeArr = {"event","request", "state","keepalive"};
|
||||
static String[] mqttMessageTypeArr = {MqttMessageTypeEnum.EVENT.getType(),MqttMessageTypeEnum.REQUEST.getType(), MqttMessageTypeEnum.STATE.getType(), MqttMessageTypeEnum.ENCRYRESP.getType()};
|
||||
|
||||
/**
|
||||
* 建立连接后
|
||||
@ -60,6 +71,15 @@ public class MqttMessageCallback implements MqttCallbackExtended, ApplicationCo
|
||||
log.error("\r\n=====>>>MQTT订阅主题 {} 失败。。。", topic);
|
||||
}
|
||||
}
|
||||
//订阅完成之后, 获取秘钥信息
|
||||
MqttPublishUtils.sendEncryptKeyReq();
|
||||
//开启与服务端的心跳检查, 注意, 这里不是客户端和mq的心跳检查, 所以需要手动开启
|
||||
// try {
|
||||
// SpringUtil.getBean(QuartzJobService.class).resumeJob(JobConstant.KEEPALIVE_JOB, JobConstant.GroupEnum.BASE_GROUP.getType());
|
||||
// } catch (SchedulerException e) {
|
||||
// throw new RuntimeException(e);
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -70,6 +90,14 @@ public class MqttMessageCallback implements MqttCallbackExtended, ApplicationCo
|
||||
cause.printStackTrace();
|
||||
logger.error("MQTT连接已断开,原因:{}", cause.getMessage());
|
||||
// 自动重连由MqttConnectOptions的automaticReconnect控制
|
||||
//页面推送广播, 云平台连接丢失
|
||||
WebSocketUtils.broadCastMessage(JSONObject.toJSONString(Collections.asMap("method","alarm","data",JSONObject.toJSONString(Collections.asMap("MQTT服务", "连接丢失")))));
|
||||
//如果链接丢失, 关闭与服务端的心跳检查, 注意, 这里不是客户端和mq的心跳检查, 所以需要手动关闭
|
||||
// try {
|
||||
// SpringUtil.getBean(QuartzJobService.class).pauseJob(JobConstant.KEEPALIVE_JOB, JobConstant.GroupEnum.BASE_GROUP.getType());
|
||||
// } catch (SchedulerException e) {
|
||||
// throw new RuntimeException(e);
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
@ -95,13 +123,6 @@ public class MqttMessageCallback implements MqttCallbackExtended, ApplicationCo
|
||||
*/
|
||||
@Override
|
||||
public void deliveryComplete(IMqttDeliveryToken token) {
|
||||
// 消息成功发布后的回调(可选处理)
|
||||
// try {
|
||||
// logger.info("消息已成功发布到主题:{}", token.getMessageId());
|
||||
// } catch (Exception e) {
|
||||
// logger.error("消息发布确认失败", e);
|
||||
// }
|
||||
|
||||
try {
|
||||
// 核心:安全获取主题(优先用自定义 token 的主题,兼容原生 token)
|
||||
String publishTopic = "未知主题";
|
||||
|
||||
@ -1,17 +1,28 @@
|
||||
package com.evotech.hd.webserver.config.mqtt;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import cn.hutool.crypto.asymmetric.KeyType;
|
||||
import cn.hutool.crypto.asymmetric.RSA;
|
||||
import cn.hutool.crypto.symmetric.SymmetricCrypto;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.evotech.hd.core.dtos.Result;
|
||||
import com.evotech.hd.utils.Collections;
|
||||
import com.evotech.hd.utils.Global;
|
||||
import com.evotech.hd.webserver.mqtt.MessageTopic;
|
||||
import com.evotech.hd.webserver.mqtt.MessageUtilService;
|
||||
import com.evotech.hd.webserver.mqtt.MqttMessageHeader;
|
||||
import com.evotech.hd.webserver.mqtt.MyMqttMessage;
|
||||
import com.evotech.hd.webserver.mqtt.enums.MqttMessageTypeEnum;
|
||||
import com.evotech.hd.webserver.service.MessageMqttService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.eclipse.paho.client.mqttv3.*;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Date;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
@ -19,8 +30,10 @@ public class MqttPublishMessage {
|
||||
|
||||
@Resource
|
||||
MessageUtilService messageUtilService;
|
||||
@Resource
|
||||
MessageMqttService messageMqttService;
|
||||
|
||||
public MqttMessage publish(String message, String topic) {
|
||||
private MqttMessage publish(String message, String topic) {
|
||||
MqttClient cloudClient = MqttConfig.mqttClientMap.get("cloudClient");
|
||||
MqttMessage mqttMessage = new MqttMessage();
|
||||
/**
|
||||
@ -50,6 +63,53 @@ public class MqttPublishMessage {
|
||||
return mqttMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 心跳
|
||||
*/
|
||||
public void publishKeepaliveMessage() {
|
||||
log.info("MQTT->>>>>>>>>>>>>请求发送心跳;");
|
||||
MessageTopic topic = new MessageTopic();
|
||||
topic.setMessageType(MqttMessageTypeEnum.KEEPALIVE.getType());
|
||||
// 3. 发送MQTT消息
|
||||
try {
|
||||
MqttMessage mqttMessage = publish(DateUtil.formatDateTime(new Date()), topic.toString());
|
||||
try {
|
||||
messageMqttService.update(null, topic, mqttMessage.getId()+"", mqttMessage.getQos(), JSONUtil.parseObj(mqttMessage));
|
||||
} catch (Exception e) {
|
||||
log.error("MQTT->>>>>>>>>>>>>记录mqtt消息出现了错误{},topic:{}; message:{}",e.getMessage(),JSONUtil.toJsonStr(topic), JSONUtil.toJsonStr(mqttMessage));
|
||||
throw new RuntimeException("记录mqtt消息出现了错误"+e.getMessage());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("MQTT->>>>>>>>>>>>>发送站端mqtt消息出现异常{},topic:{};",e.getMessage(),JSONUtil.toJsonStr(topic));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 AES 加密消息
|
||||
* @param topic
|
||||
*/
|
||||
public void publishRSAMessage(MessageTopic topic) {
|
||||
log.info("MQTT->>>>>>>>>>>>>请求发送mqtt消息: topic:{};", JSONUtil.toJsonStr(topic));
|
||||
|
||||
RSA rsa = SecureUtil.rsa(null, Global.newInstance().getStaticPublicKey());
|
||||
Result<Integer> addResult = messageMqttService.addResultId(topic.getStationCode());
|
||||
Integer messageId = addResult.getData();
|
||||
//数据加密
|
||||
String encrypt = rsa.encryptBase64(JSON.toJSONString(Collections.asMap("messageId", messageId, "publicKey", Global.newInstance().getCloudPublicKey())), KeyType.PublicKey);
|
||||
// 3. 发送MQTT消息
|
||||
try {
|
||||
MqttMessage mqttMessage = publish(encrypt, topic.toString());
|
||||
try {
|
||||
messageMqttService.update(messageId, topic, mqttMessage.getId()+"", mqttMessage.getQos(), JSONUtil.parseObj(mqttMessage));
|
||||
} catch (Exception e) {
|
||||
log.error("MQTT->>>>>>>>>>>>>记录mqtt消息出现了错误{},topic:{}; message:{}",e.getMessage(),JSONUtil.toJsonStr(topic), JSONUtil.toJsonStr(mqttMessage));
|
||||
throw new RuntimeException("记录mqtt消息出现了错误"+e.getMessage());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("MQTT->>>>>>>>>>>>>发送站端mqtt消息出现异常{},topic:{};",e.getMessage(),JSONUtil.toJsonStr(topic));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 AES 加密消息
|
||||
* @param topic
|
||||
@ -70,8 +130,7 @@ public class MqttPublishMessage {
|
||||
try {
|
||||
MqttMessage mqttMessage = publish(encrypt, topic.toString());
|
||||
try {
|
||||
//dataBody.set("header", JSONUtil.toJsonStr(header));
|
||||
// addMqttMessage(topic, mqttMessage.getId()+"", mqttMessage.getQos(), JSONUtil.parseObj(message));
|
||||
messageMqttService.update(null, topic, mqttMessage.getId()+"", mqttMessage.getQos(), JSONUtil.parseObj(message));
|
||||
} catch (Exception e) {
|
||||
log.error("MQTT->>>>>>>>>>>>>记录mqtt消息出现了错误{},topic:{}; header:{}, data:{}; message:{}",e.getMessage(),JSONUtil.toJsonStr(topic),JSONUtil.toJsonStr(header),JSONUtil.toJsonStr(dataBody), JSONUtil.toJsonStr(mqttMessage));
|
||||
throw new RuntimeException("记录mqtt消息出现了错误"+e.getMessage());
|
||||
@ -80,47 +139,4 @@ public class MqttPublishMessage {
|
||||
log.error("MQTT->>>>>>>>>>>>>发送站端mqtt消息出现异常{},topic:{}; header:{}, data:{}",e.getMessage(),JSONUtil.toJsonStr(topic),JSONUtil.toJsonStr(header),JSONUtil.toJsonStr(dataBody));
|
||||
}
|
||||
}
|
||||
|
||||
// public SymmetricCrypto getAes(String stationCode) {
|
||||
// JSONObject aesJo = getAESKey(stationCode);
|
||||
// String aesSecretKey = aesJo.getStr("encryptKey");
|
||||
// String aesIv = aesJo.getStr("encryptVector");
|
||||
// SymmetricCrypto aes = new AES(Mode.CBC, Padding.PKCS5Padding, Base64.getDecoder().decode(aesSecretKey), aesIv.getBytes());
|
||||
// return aes;
|
||||
// }
|
||||
|
||||
// public JSONObject getAESKey(String stationCode) {
|
||||
// JSONObject jo = new JSONObject();
|
||||
// Object o1 = null;
|
||||
// try {
|
||||
// o1 = redisUtil.get(HDConstant.HD_STATION_SECRET_KEY_AES_PREFIX + stationCode + ":key");
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// Object o2 = null;
|
||||
// try {
|
||||
// o2 = redisUtil.get(HDConstant.HD_STATION_SECRET_KEY_AES_PREFIX + stationCode + ":iv");
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// if (!ObjectUtil.isEmpty(o1) && !ObjectUtil.isEmpty(o2)) {
|
||||
//// jo.set("aesSecretKey", o1.toString());
|
||||
//// jo.set("aesIv", o2.toString());
|
||||
// jo.set("encryptKey", o1.toString());
|
||||
// jo.set("encryptVector", o2.toString());
|
||||
// return jo;
|
||||
// }
|
||||
// BatteryStationSecretKey bssk = batteryStationSecretKeyDao.selectOne(new QueryWrapper<BatteryStationSecretKey>().eq("type", 2).eq("station_code", stationCode));
|
||||
// if (bssk == null) {
|
||||
// throw new RuntimeException("AES秘钥未获取到,请站端重新登陆!");
|
||||
//// return setAesKey(stationCode);
|
||||
// }
|
||||
// redisUtil.set(HDConstant.HD_STATION_SECRET_KEY_AES_PREFIX + stationCode + ":key", bssk.getPublicKey());
|
||||
// redisUtil.set(HDConstant.HD_STATION_SECRET_KEY_AES_PREFIX + stationCode + ":iv", bssk.getPrivateKey());
|
||||
//// jo.set("aesSecretKey", o1.toString());
|
||||
//// jo.set("aesIv", o2.toString());
|
||||
// jo.set("encryptKey", o1.toString());
|
||||
// jo.set("encryptVector", o2.toString());
|
||||
// return jo;
|
||||
// }
|
||||
}
|
||||
|
||||
@ -76,9 +76,20 @@ public class OrderSwapController {
|
||||
@ApiOperation("手动换电完成")
|
||||
@PostMapping("/manualBatterySwappingCompleted")
|
||||
@ApiLog(value = "手动换电完成", type=LogTypeEnum.OPERATION)
|
||||
public Result<Boolean> ManualBatterySwappingCompleted(@RequestBody OrderSwapDTO orderSwapDTO) throws Exception {
|
||||
public Result<Boolean> manualBatterySwappingCompleted(@RequestBody OrderSwapDTO orderSwapDTO) throws Exception {
|
||||
return orderSwapService.updateOrderSwapDTO(orderSwapDTO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动换电完成
|
||||
* @return
|
||||
*/
|
||||
@ApiOperation("订单关闭")
|
||||
@PostMapping("/close")
|
||||
@ApiLog(value = "订单关闭", type=LogTypeEnum.OPERATION)
|
||||
public Result<Boolean> close(@RequestBody OrderSwapDTO orderSwapDTO) throws Exception {
|
||||
return orderSwapService.close(orderSwapDTO);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -2,6 +2,7 @@ package com.evotech.hd.webserver.job;
|
||||
|
||||
import com.evotech.hd.core.enums.BaseEnum;
|
||||
import com.evotech.hd.webserver.job.job.ArrivalSignalJob;
|
||||
import com.evotech.hd.webserver.job.job.KeepaliveJob;
|
||||
import com.evotech.hd.webserver.job.job.LicensePlateMachineJob;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
@ -97,7 +98,10 @@ public class JobConstant {
|
||||
*/
|
||||
// public static String VEHICLE_ABDICATION_JOB = VehicleAbdicationJob.class.getSimpleName();
|
||||
|
||||
|
||||
/***
|
||||
* 客户端与服务端的心跳检查
|
||||
*/
|
||||
public static String KEEPALIVE_JOB = KeepaliveJob.class.getSimpleName();
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -1,18 +1,23 @@
|
||||
package com.evotech.hd.webserver.job.job;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.evotech.hd.core.dtos.Result;
|
||||
import com.evotech.hd.core.dtos.ResultUtil;
|
||||
import com.evotech.hd.core.dtos.business.AccessStrategyDTO;
|
||||
import com.evotech.hd.core.dtos.business.BatteryCompartmentDTO;
|
||||
import com.evotech.hd.core.dtos.business.RunningInstructionsDetailDTO;
|
||||
import com.evotech.hd.core.dtos.system.ParamsDTO;
|
||||
import com.evotech.hd.exception.InstructionException;
|
||||
import com.evotech.hd.utils.Collections;
|
||||
import com.evotech.hd.webserver.controller.TestController;
|
||||
import com.evotech.hd.webserver.mqtt.MqttPublishUtils;
|
||||
import com.evotech.hd.webserver.service.ParamsService;
|
||||
import com.evotech.hd.webserver.utils.AccessStrategyUtil;
|
||||
import com.evotech.hd.webserver.utils.ParamUtils;
|
||||
import com.evotech.hd.webserver.utils.instruction.InstructionReadUtils;
|
||||
import com.evotech.hd.webserver.utils.instruction.InstructionUtils;
|
||||
import com.evotech.hd.webserver.utils.query.QueryWrapperGenerator;
|
||||
import com.evotech.hd.webserver.utils.sendCloud.CloudSendInfoUtils;
|
||||
import com.evotech.hd.webserver.websocket.controller.WebSocketUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -21,6 +26,7 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 首页告警扫描
|
||||
@ -35,9 +41,11 @@ public class CheckAlarmJob implements BaseJob{
|
||||
|
||||
|
||||
// 任务执行方法(必须定义为public void run())
|
||||
public void run(Map<String, Object> params) throws InstructionException {
|
||||
public void run(Map<String, Object> params) throws Exception {
|
||||
log.info("===== 执行检查报警任务 =====");
|
||||
Map<String, String> alarmMessage = Collections.emptyMap();
|
||||
//默认不影响
|
||||
Boolean effectBatterySwapping = false;
|
||||
//获取所有的异常指令
|
||||
List<RunningInstructionsDetailDTO> instructions = getRunningInstructionsDetailService().findDictDetailDTOByTypeCode("check_alarm");
|
||||
if(Collections.isNotEmpty(instructions)){
|
||||
@ -51,20 +59,9 @@ public class CheckAlarmJob implements BaseJob{
|
||||
for (String rgvNo : rgvArrays){
|
||||
if(!InstructionUtils.getBoolean(paramsDTO, InstructionReadUtils.executionInteger(paramsDTO, rgvNo))){
|
||||
alarmMessage.put(paramsDTO.getName().replace(":num", rgvNo), paramsDTO.getErrMessage().replace(":num", rgvNo));
|
||||
}
|
||||
}
|
||||
}else{
|
||||
alarmMessage.put("RGV连接", "没有可用的RGV设备");
|
||||
}
|
||||
}if("RGV_RB_ErrorCode".equals(paramsDTO.getParamCode())){
|
||||
AccessStrategyDTO accessStrategyDTO = AccessStrategyUtil.getValidAccessStrategyDTO();
|
||||
if(StringUtils.isNotEmpty(accessStrategyDTO.getEffectiveRgvNo())){
|
||||
String[] rgvArrays = accessStrategyDTO.getEffectiveRgvNo().split(",");
|
||||
for (String rgvNo : rgvArrays){
|
||||
Map<String, Object> result = getExecutionBatterySwapService().executionErrorResult(rgvNo);
|
||||
if(Collections.isNotEmpty(result)){
|
||||
alarmMessage.put(paramsDTO.getName().replace(":num", rgvNo), String.valueOf(result.get("errorMsg")));
|
||||
TestController.getInstance().stopRgv(rgvNo, rgvNo, String.valueOf(result.get("errorMsg")));
|
||||
if(paramsDTO.getEffectBatterySwapping()){
|
||||
effectBatterySwapping = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
@ -73,9 +70,11 @@ public class CheckAlarmJob implements BaseJob{
|
||||
}else{
|
||||
if(!InstructionUtils.getBoolean(paramsDTO, InstructionReadUtils.executionInteger(paramsDTO, null))){
|
||||
alarmMessage.put(paramsDTO.getName(), paramsDTO.getErrMessage());
|
||||
if(paramsDTO.getEffectBatterySwapping()){
|
||||
effectBatterySwapping = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
//检查云平台链接
|
||||
@ -85,10 +84,12 @@ public class CheckAlarmJob implements BaseJob{
|
||||
alarmMessage.put("云平台", "连接丢失");
|
||||
}
|
||||
|
||||
//检查电池仓,电池信号
|
||||
alarmMessage = checkBatteryCompartmentSignal(alarmMessage);
|
||||
|
||||
//存在告警, 推送数据
|
||||
if(Collections.isNotEmpty(alarmMessage)){
|
||||
WebSocketUtils.broadCastMessage(JSONObject.toJSONString(Collections.asMap("method","alarm","data",JSONObject.toJSONString(alarmMessage))));
|
||||
|
||||
if(keepalive != null && keepalive){
|
||||
//推送数据
|
||||
Map<String, Object> alarmMap = Collections.emptyMap();
|
||||
@ -104,9 +105,47 @@ public class CheckAlarmJob implements BaseJob{
|
||||
if(alarmMessage.containsKey("急停")){
|
||||
alarmMap.put("stop", 2); //2为云平台现有的定义的站控的报警标识
|
||||
}
|
||||
CloudSendInfoUtils.sendAlarm(alarmMap);
|
||||
CloudSendInfoUtils.sendAlarm(alarmMap, effectBatterySwapping);
|
||||
}
|
||||
}
|
||||
log.info("检查报警任务执行完成");
|
||||
}
|
||||
|
||||
|
||||
BatteryCompartmentDTO params = new BatteryCompartmentDTO(){{
|
||||
setStatus(1);
|
||||
setState(1);
|
||||
}};
|
||||
//
|
||||
public Map<String, String> checkBatteryCompartmentSignal(Map<String, String> alarmMessage) throws Exception {
|
||||
//获取所有的仓位
|
||||
List<BatteryCompartmentDTO> list = getBatteryCompartmentService().findList(QueryWrapperGenerator.buildQueryCondition(params, BatteryCompartmentDTO.class));
|
||||
StringBuilder sb = new StringBuilder("");
|
||||
//有电池,无信号
|
||||
List<BatteryCompartmentDTO> existsBatteryList = list.stream().filter(BatteryCompartmentDTO::getExistsBattery).collect(Collectors.toList());
|
||||
if(Collections.isNotEmpty(existsBatteryList)){
|
||||
for (BatteryCompartmentDTO bc : existsBatteryList){
|
||||
//如果有电池, 返回的无电池信号, 直接锁定电池仓, 做电池仓禁用
|
||||
if(!InstructionReadUtils.checkExistsBattery(String.valueOf(bc.getId()))){
|
||||
getBatteryCompartmentService().settingState(bc.getId(), 2);
|
||||
sb.append("电池仓: ").append(bc.getId()).append("号, 电池信号丢失, 请确认;");
|
||||
}
|
||||
}
|
||||
}
|
||||
//没电池, 有信号
|
||||
List<BatteryCompartmentDTO> notExistsBatteryList = list.stream().filter(data -> !data.getExistsBattery()).collect(Collectors.toList());
|
||||
if(Collections.isNotEmpty(notExistsBatteryList)){
|
||||
for (BatteryCompartmentDTO bc : notExistsBatteryList){
|
||||
//如果有电池, 返回的无电池信号, 直接锁定电池仓, 做电池仓禁用
|
||||
if(InstructionReadUtils.checkExistsBattery(String.valueOf(bc.getId()))){
|
||||
getBatteryCompartmentService().settingState(bc.getId(), 2);
|
||||
sb.append("电池仓: ").append(bc.getId()).append("号, 出现未知电池信号, 请确认;");
|
||||
}
|
||||
}
|
||||
}
|
||||
if(sb.length() > 0){
|
||||
alarmMessage.put("电池仓", sb.toString());
|
||||
}
|
||||
return alarmMessage;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,26 @@
|
||||
package com.evotech.hd.webserver.job.job;
|
||||
|
||||
import com.evotech.hd.webserver.mqtt.MqttPublishUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* KeepaliveJob
|
||||
*
|
||||
* @author andy.shi
|
||||
* @ClassName:KeepaliveLob
|
||||
* @date: 2026年01月13日 11:34
|
||||
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class KeepaliveJob implements BaseJob{
|
||||
|
||||
|
||||
@Override
|
||||
public void run(Map<String, Object> params) throws Exception {
|
||||
MqttPublishUtils.sendKeepalive();
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
package com.evotech.hd.webserver.job.service;
|
||||
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.evotech.hd.core.dtos.Result;
|
||||
@ -109,6 +110,16 @@ public class ExecutionBatterySwapService {
|
||||
WebSocketUtils.broadCastMessage(JSONObject.toJSONString(Collections.asMap("method","order","data",JSONObject.toJSONString(ResultUtil.getValue(runningOrderResult)))));
|
||||
//下发物理接口, 抬杆放行 TODO
|
||||
InstructionWriteUtils.openRolling(ParamUtils.getDoorParams("入口"));
|
||||
//如果是双RGV, 并且开启了预取,
|
||||
AccessStrategyDTO accessStrategyDTO = AccessStrategyUtil.getValidAccessStrategyDTO();
|
||||
//如果开启了预存
|
||||
if(accessStrategyDTO.getBatteryPrefetching() && AccessStrategyUtil.getEffectiveRgvNoList(accessStrategyDTO).size() > 1){
|
||||
//获取仓位信息
|
||||
Map<String, String> resultMap = calculationPosition(accessStrategyDTO);
|
||||
RedisUtil.set("rgvInfo", JSONObject.toJSONString(resultMap));
|
||||
//执行取点数据
|
||||
buildTakeFuture(resultMap.get("loadingRgv"), Integer.valueOf(resultMap.get("takeNo")), runningOrderResult.getData().getId());
|
||||
}
|
||||
try {
|
||||
//开启车辆到位扫秒
|
||||
quartzJobService.resumeJob(new QuartzJobInfo(JobConstant.ARRIVAL_SIGNAL_JOB, JobConstant.GroupEnum.SWAP_GROUP.getType()));
|
||||
@ -143,7 +154,12 @@ public class ExecutionBatterySwapService {
|
||||
//打开开合门
|
||||
if(buildOpenFuture().get()){
|
||||
//获取仓位信息
|
||||
Map<String, String> result = calculationPosition(accessStrategyDTO);
|
||||
Map<String, String> result = Collections.emptyMap();
|
||||
if(accessStrategyDTO.getBatteryPrefetching() && AccessStrategyUtil.getEffectiveRgvNoList(accessStrategyDTO).size() > 1){
|
||||
result = JSON.to(Map.class, RedisUtil.get("rgvInfo"));
|
||||
}else{
|
||||
result = calculationPosition(accessStrategyDTO);
|
||||
}
|
||||
//查询当前运行订单
|
||||
Result<OrderSwapDTO> running = orderSwapService.runningOrder();
|
||||
OrderSwapDTO orderSwapDTO = running.getData();
|
||||
@ -284,7 +300,27 @@ public class ExecutionBatterySwapService {
|
||||
return false;
|
||||
});
|
||||
//取
|
||||
CompletableFuture<Boolean> takeFuture =buildTakeFuture(loadingRgv, takeNo, orderId);
|
||||
CompletableFuture<Boolean> takeFuture;
|
||||
if(AccessStrategyUtil.getValidAccessStrategyDTO().getBatteryPrefetching()){
|
||||
takeFuture = CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
Boolean result = false;
|
||||
//下发拆除命令
|
||||
do {
|
||||
if(result = Boolean.valueOf(String.valueOf(RedisUtil.get("buildTakeFuture")))){
|
||||
return true;
|
||||
}
|
||||
}while (!result);
|
||||
} catch (Exception e) {
|
||||
log.error("预取失败, {}", e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}else{
|
||||
//取
|
||||
takeFuture =buildTakeFuture(loadingRgv, takeNo, orderId);
|
||||
}
|
||||
//装. 依托于 拆, 取
|
||||
CompletableFuture<Boolean> loadingFuture = CompletableFuture.allOf(splitFuture, takeFuture).thenApplyAsync(voidResult->{
|
||||
Boolean split = splitFuture.join();
|
||||
@ -323,6 +359,7 @@ public class ExecutionBatterySwapService {
|
||||
});
|
||||
}
|
||||
//启动对中机构
|
||||
//对中机构启动速度过快, 无法短频查询, 所以取消sleep();
|
||||
public CompletableFuture<Boolean> buildCenOpenFuture(){
|
||||
return CompletableFuture.supplyAsync(()->{
|
||||
try {
|
||||
@ -333,12 +370,10 @@ public class ExecutionBatterySwapService {
|
||||
if(checkCenError()){
|
||||
return false;
|
||||
}
|
||||
sleep();
|
||||
if (openResult = checkCenOpenExecutionResult()) {
|
||||
log.info("对中机构正在运行, 当前时间为: "+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()));
|
||||
Boolean result = false;
|
||||
do {
|
||||
sleep();
|
||||
if(result = checkCenExecutionResult()){
|
||||
log.info("对中机构执行完成, 当前时间为: "+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()));
|
||||
// 推送云端, 并查询是否存在异常 没有异常, 开始启动换电
|
||||
@ -494,6 +529,7 @@ public class ExecutionBatterySwapService {
|
||||
public CompletableFuture<Boolean> buildTakeFuture(final String rgv, final Integer taskNo, final Integer orderId){
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
RedisUtil.set("buildTakeFuture", false);
|
||||
OrderSwap orderSwap = orderSwapService.getById(orderId);
|
||||
orderSwap.setRentBatNo(String.valueOf(taskNo));
|
||||
Battery battery = batteryService.getBatteryByCompartmentId(taskNo);
|
||||
@ -531,6 +567,7 @@ public class ExecutionBatterySwapService {
|
||||
log.error("取新电池后, BMS下电出现错误", e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
RedisUtil.set("buildTakeFuture", true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -795,9 +832,12 @@ public class ExecutionBatterySwapService {
|
||||
orderSwapService.updateById(orderSwapWrapper.toEntity(orderSwapDTO));//更新换电完成状态
|
||||
//执行换电完成
|
||||
executionResultPush(orderSwapDTO, SwapBatteryStepEnum.COMPLETED, false, Collections.emptyMap());
|
||||
//换电完成, 预取结果重置为false
|
||||
RedisUtil.set("buildTakeFuture", false);
|
||||
//重置rgv信息
|
||||
RedisUtil.set("rgvInfo", JSONObject.toJSONString(Collections.emptyMap()));
|
||||
//关闭开合门
|
||||
if(buildCloseFuture().get()){
|
||||
|
||||
//释放对中机构
|
||||
InstructionWriteUtils.closeCorrectInstitution();
|
||||
//推送空对象推送websocket, 刷新首页数据
|
||||
|
||||
@ -0,0 +1,12 @@
|
||||
package com.evotech.hd.webserver.mapper;
|
||||
|
||||
/**
|
||||
* BasicMapper
|
||||
*
|
||||
* @author andy.shi
|
||||
* @ClassName:BasicMapper
|
||||
* @date: 2026年01月12日 11:27
|
||||
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
|
||||
*/
|
||||
public interface BasicMapper {
|
||||
}
|
||||
@ -27,6 +27,8 @@ public interface BatteryCompartmentMapper extends BaseMapper<BatteryCompartment>
|
||||
*/
|
||||
IPage<BatteryCompartmentDTO> findPage(Page<BatteryCompartmentDTO> page, @Param(Constants.WRAPPER) QueryWrapper queryWrapper);
|
||||
|
||||
List<BatteryCompartmentDTO> findList( @Param(Constants.WRAPPER) QueryWrapper queryWrapper);
|
||||
|
||||
BatteryCompartmentDTO getInfo(@Param("id")Integer id);
|
||||
|
||||
List<Integer> findChargingPositionIds(@Param("notAllPower") Boolean isNotAllPower);
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
package com.evotech.hd.webserver.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Constants;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.evotech.hd.core.dtos.system.LogDTO;
|
||||
import com.evotech.hd.core.dtos.system.MessageMqttDTO;
|
||||
import com.evotech.hd.core.entity.system.Log;
|
||||
import com.evotech.hd.core.entity.system.MessageMqtt;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* 接口
|
||||
*
|
||||
* @ClassName:LogMapper
|
||||
* @date: 2025年08月18日 14:45
|
||||
* @author: andy.shi
|
||||
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
|
||||
*/
|
||||
public interface MessageMqttMapper extends BaseMapper<MessageMqtt> {
|
||||
/**
|
||||
* 获日志列表
|
||||
*
|
||||
* @param queryWrapper
|
||||
* @return
|
||||
*/
|
||||
IPage<MessageMqttDTO> findPage(Page<MessageMqttDTO> page, @Param(Constants.WRAPPER) QueryWrapper queryWrapper);
|
||||
}
|
||||
@ -2,10 +2,14 @@ package com.evotech.hd.webserver.mqtt;
|
||||
|
||||
import cn.hutool.crypto.Mode;
|
||||
import cn.hutool.crypto.Padding;
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import cn.hutool.crypto.asymmetric.KeyType;
|
||||
import cn.hutool.crypto.asymmetric.RSA;
|
||||
import cn.hutool.crypto.symmetric.AES;
|
||||
import cn.hutool.crypto.symmetric.SymmetricCrypto;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.evotech.hd.utils.Global;
|
||||
import com.evotech.hd.webserver.config.redis.utils.RedisUtil;
|
||||
import com.evotech.hd.webserver.utils.ParamUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -22,6 +26,13 @@ public class MessageUtilService {
|
||||
@Resource
|
||||
private RedisUtil redisUtil;
|
||||
|
||||
public JSONObject decryptEncryptKeyReqMessage(MqttMessage message) {
|
||||
byte[] payload = message.getPayload();
|
||||
RSA rsa = SecureUtil.rsa(Global.newInstance().getCloudPrivateKey(), null);
|
||||
byte[] decrypt = rsa.decrypt(new String(payload), KeyType.PrivateKey);
|
||||
return JSONUtil.parseObj(new String(decrypt));
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密AES类型的消息
|
||||
* @param topic
|
||||
|
||||
@ -3,8 +3,11 @@ package com.evotech.hd.webserver.mqtt;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.evotech.hd.webserver.job.service.ExecutionBatterySwapService;
|
||||
import com.evotech.hd.webserver.mqtt.enums.MqttMessageTypeEnum;
|
||||
import com.evotech.hd.webserver.service.BatteryStrategyService;
|
||||
import com.evotech.hd.webserver.service.MessageMqttService;
|
||||
import com.evotech.hd.webserver.service.OrderReservationService;
|
||||
import com.evotech.hd.webserver.utils.ParamUtils;
|
||||
import org.eclipse.paho.client.mqttv3.MqttMessage;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@ -24,25 +27,42 @@ public class MqttMessageHandleService {
|
||||
BatteryStrategyService batteryStrategyService;
|
||||
@Resource
|
||||
ExecutionBatterySwapService executionBatterySwapService;
|
||||
@Resource
|
||||
MessageMqttService messageMqttService;
|
||||
|
||||
public void handle(MessageTopic topic, MqttMessage message) throws Exception {
|
||||
//获取秘钥
|
||||
if (MqttMessageTypeEnum.ENCRYRESP.getType().equals(topic.getMessageType())) {
|
||||
ParamUtils.encryptKeyReq(messageUtilService.decryptEncryptKeyReqMessage(message));
|
||||
return;
|
||||
}
|
||||
// 2. keepalive不加密,单独处理
|
||||
if (MqttMessageTypeEnum.KEEPALIVE.getType().equals(topic.getMessageType())) {
|
||||
JSONObject jo = JSONUtil.parseObj(message);
|
||||
MqttMessageHeader header = new MqttMessageHeader();
|
||||
header.setFunction(MqttMessageTypeEnum.KEEPALIVE.getType());
|
||||
jo.set("header", JSONUtil.parseObj(header));
|
||||
messageMqttService.update(null, topic, null, 2, jo);
|
||||
return;
|
||||
}
|
||||
|
||||
JSONObject jo = messageUtilService.decryptAesMessage(topic, message);
|
||||
MqttMessageHeader header = JSONUtil.toBean(jo.getJSONObject("header"), MqttMessageHeader.class);
|
||||
com.alibaba.fastjson2.JSONObject dataBody = com.alibaba.fastjson2.JSONObject.parseObject(jo.getStr("dataBody"));
|
||||
//站端比较特殊, 只有2个mq消息, 1个是下发预约单, 一个是点击开始
|
||||
//不做特殊设计, 直接if-else 判定就好了
|
||||
if ("pushReservation".equalsIgnoreCase(header.getFunction())){
|
||||
//接收云端订单
|
||||
orderReservationService.acceptReservations(dataBody);
|
||||
}else if("BatterySwapReq".equalsIgnoreCase(header.getFunction())){
|
||||
//接收云端的开始换电, 启动对中机构
|
||||
try {
|
||||
executionBatterySwapService.activateAlignmentMechanism();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}else if("chargingStrategy".equalsIgnoreCase(header.getFunction())){
|
||||
batteryStrategyService.manageCloudData(dataBody);
|
||||
MqttMessageHeader header = JSONUtil.toBean(jo.getJSONObject("header"), MqttMessageHeader.class);
|
||||
com.alibaba.fastjson2.JSONObject dataBody = com.alibaba.fastjson2.JSONObject.parseObject(jo.getStr("dataBody"));
|
||||
//站端比较特殊, 只有2个mq消息, 1个是下发预约单, 一个是点击开始
|
||||
//不做特殊设计, 直接if-else 判定就好了
|
||||
if ("pushReservation".equalsIgnoreCase(header.getFunction())){
|
||||
//接收云端订单
|
||||
orderReservationService.acceptReservations(dataBody);
|
||||
}else if("BatterySwapReq".equalsIgnoreCase(header.getFunction())){
|
||||
//接收云端的开始换电, 启动对中机构
|
||||
try {
|
||||
executionBatterySwapService.activateAlignmentMechanism();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}else if("chargingStrategy".equalsIgnoreCase(header.getFunction())){
|
||||
batteryStrategyService.manageCloudData(dataBody);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package com.evotech.hd.webserver.mqtt;
|
||||
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.evotech.hd.webserver.config.mqtt.MqttPublishMessage;
|
||||
import com.evotech.hd.webserver.mqtt.enums.MqttMessageTypeEnum;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@ -23,12 +24,22 @@ public class MqttPublishUtils {
|
||||
this.mqttPublishMessage = mqttPublishMessage;
|
||||
}
|
||||
|
||||
public static void sendKeepalive(){
|
||||
mqttPublishMessage.publishKeepaliveMessage();
|
||||
}
|
||||
|
||||
public static void sendEncryptKeyReq(){
|
||||
MessageTopic topic = new MessageTopic();
|
||||
topic.setMessageType(MqttMessageTypeEnum.ENCRYREQ.getType());
|
||||
mqttPublishMessage.publishRSAMessage(topic);
|
||||
}
|
||||
|
||||
public static void sendState(String messageType, JSONObject dataBody){
|
||||
MessageTopic topic = new MessageTopic();
|
||||
topic.setMessageType("state");
|
||||
topic.setMessageType(MqttMessageTypeEnum.STATE.getType());
|
||||
MqttMessageHeader header = new MqttMessageHeader();
|
||||
header.setTimeStamp(String.valueOf(System.currentTimeMillis()));
|
||||
header.setIndex("1");
|
||||
header.setIndex(MqttMessageTypeEnum.STATE.getId());
|
||||
header.setFunction(messageType);
|
||||
mqttPublishMessage.publishAESMessage(topic,header, dataBody);
|
||||
}
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
package com.evotech.hd.webserver.mqtt.enums;
|
||||
|
||||
/**
|
||||
* 如下 8 种类型:
|
||||
1)state 换电站状态类信息,站控发送,支持变化实时上送、周期上送和查询上
|
||||
送三种方式,云平台无需回复。云平台可根据需要随时向站控系统召唤状态类信息。
|
||||
2)event 事件类信息,站控发送,包括故障告警事件记录、充换电事件记录等, 事件发生时上送,需接收者回复确认,站控 15 秒内收不到回复则要重复发送,直到收
|
||||
到云平台的回复。云平台可通过召唤历史事件流水号的方式,检查事件是否丢失。
|
||||
3)confirm 事件确认回复,云平台收到事件后的回复信息。
|
||||
4)request 主动请求,云平台、站控均可发起请求。
|
||||
5)response 收到请求后,接收者的回复。
|
||||
6)keepalive 心跳报文,站控周期发送,周期30秒,云平台收到后立即回复。报文内容为当前时标字符串:“yyyy-MM-dd hh:mm:ss”。云平台和站控连续 3 个周期收不到对方的任何报文,则认为通信中断。通信中断后,站控不发送心跳外的任何报文,直到收到心跳回复报文。
|
||||
7)encryptKeyReq 站控发送,请求密钥。
|
||||
8)encryptKeyResp 云平台回复站控的密钥请求。
|
||||
*
|
||||
*/
|
||||
public enum MqttMessageTypeEnum {
|
||||
|
||||
STATE("1", "state"),
|
||||
EVENT("2", "event"),
|
||||
CONFIRM("3", "confirm"),
|
||||
REQUEST("4", "request"),
|
||||
RESPONSE("5", "response"),
|
||||
KEEPALIVE("6", "keepalive"),
|
||||
ENCRYREQ("7", "encryptKeyReq"),
|
||||
ENCRYRESP("8", "encryptKeyResp");
|
||||
|
||||
|
||||
String id;
|
||||
String type;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
MqttMessageTypeEnum(String id, String type) {
|
||||
this.id = id;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
}
|
||||
@ -33,6 +33,8 @@ public interface BatteryCompartmentService extends IService<BatteryCompartment>
|
||||
* @return
|
||||
*/
|
||||
IPage<BatteryCompartmentDTO> findPageList(Page<BatteryCompartmentDTO> page, QueryWrapper queryWrapper);
|
||||
|
||||
List<BatteryCompartmentDTO> findList( QueryWrapper queryWrapper);
|
||||
/***
|
||||
* 获取非全额充电中的仓位信息
|
||||
* @return
|
||||
|
||||
@ -0,0 +1,15 @@
|
||||
package com.evotech.hd.webserver.service;
|
||||
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.evotech.hd.core.dtos.Result;
|
||||
import com.evotech.hd.core.entity.system.MessageMqtt;
|
||||
import com.evotech.hd.webserver.mqtt.MessageTopic;
|
||||
|
||||
public interface MessageMqttService extends IService<MessageMqtt> {
|
||||
|
||||
public Result<Integer> addResultId(String stationCode);
|
||||
|
||||
public Result<MessageMqtt> update(Integer id, MessageTopic topic, String messageId, int qos, JSONObject jo);
|
||||
|
||||
}
|
||||
@ -8,6 +8,7 @@ import com.evotech.hd.core.dtos.Result;
|
||||
import com.evotech.hd.core.dtos.business.OrderSwapDTO;
|
||||
import com.evotech.hd.core.entity.business.OrderReservation;
|
||||
import com.evotech.hd.core.entity.business.OrderSwap;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@ -35,4 +36,6 @@ public interface OrderSwapService extends IService<OrderSwap> {
|
||||
Result<Boolean> sendOrderCompleted(Serializable orderId);
|
||||
|
||||
Result<Boolean> updateOrderSwapDTO(OrderSwapDTO orderSwapDTO) throws Exception ;
|
||||
|
||||
Result<Boolean> close(OrderSwapDTO orderSwapDTO) throws Exception;
|
||||
}
|
||||
|
||||
@ -31,4 +31,6 @@ public interface ParamsService extends IService<Params> {
|
||||
ParamsDTO getParamsDTOByCode(String code);
|
||||
|
||||
ParamsDTO saveParamsDTO(ParamsDTO paramsDTO);
|
||||
|
||||
ParamsDTO getOrUpdateParamsDTO(String name, String code, String defVal, String des);
|
||||
}
|
||||
|
||||
@ -77,6 +77,12 @@ public class BatteryCompartmentServiceImpl extends ServiceImpl<BatteryCompartmen
|
||||
return getBaseMapper().findPage(page, queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BatteryCompartmentDTO> findList(QueryWrapper queryWrapper) {
|
||||
queryWrapper.orderByAsc("a.id");// 根据预约日期和预约时间段倒序排序
|
||||
return getBaseMapper().findList( queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Integer> findChargingPositionIds(Boolean isNotAllPower) {
|
||||
return getBaseMapper().findChargingPositionIds(isNotAllPower);
|
||||
@ -133,7 +139,7 @@ public class BatteryCompartmentServiceImpl extends ServiceImpl<BatteryCompartmen
|
||||
//检查电池是否已经充满电
|
||||
if (StringUtils.isEmpty(battery.getSoc()) || Integer.valueOf("100").compareTo(Integer.valueOf(battery.getSoc())) >0){
|
||||
//检查充电机 PS: 这种情况是不会出现的, 但是以防万一, 做个处理, 不做数据调整, 但是需要返回异常信息,需要站控人员调整
|
||||
if(!InstructionReadUtils.queryBatExist(id)){
|
||||
if(!InstructionReadUtils.checkExistsBattery(String.valueOf(id))){
|
||||
return Result.getInstance().build(Boolean.class).error("当前仓位返回没有电池, 请确认电池是否存在,或者是否对接到位", false);
|
||||
}
|
||||
//下发充电
|
||||
|
||||
@ -0,0 +1,64 @@
|
||||
package com.evotech.hd.webserver.service.impl;
|
||||
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.evotech.hd.core.dtos.Result;
|
||||
import com.evotech.hd.core.dtos.system.LogDTO;
|
||||
import com.evotech.hd.core.entity.system.Log;
|
||||
import com.evotech.hd.core.entity.system.MessageMqtt;
|
||||
import com.evotech.hd.webserver.mapper.LogMapper;
|
||||
import com.evotech.hd.webserver.mapper.MessageMqttMapper;
|
||||
import com.evotech.hd.webserver.mqtt.MessageTopic;
|
||||
import com.evotech.hd.webserver.mqtt.MqttMessageHeader;
|
||||
import com.evotech.hd.webserver.service.LogService;
|
||||
import com.evotech.hd.webserver.service.MessageMqttService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 类
|
||||
*
|
||||
* @ClassName:LogServiceImpl
|
||||
* @date: 2025年08月18日 14:44
|
||||
* @author: andy.shi
|
||||
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
|
||||
*/
|
||||
@Service
|
||||
public class MessageMqttServiceImpl extends ServiceImpl<MessageMqttMapper, MessageMqtt> implements MessageMqttService {
|
||||
|
||||
@Override
|
||||
public Result<Integer> addResultId(String stationCode) {
|
||||
MessageMqtt messageMqtt = new MessageMqtt();
|
||||
messageMqtt.setStationCode(stationCode);
|
||||
if(save(messageMqtt)){
|
||||
return Result.getInstance().build(Integer.class).success(messageMqtt.getId());
|
||||
}
|
||||
return Result.getInstance().build(Integer.class).error("保存失败");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<MessageMqtt> update(Integer id, MessageTopic topic, String messageId, int qos, JSONObject jo) {
|
||||
MqttMessageHeader header = JSONUtil.toBean(jo.getJSONObject("header"), MqttMessageHeader.class);
|
||||
MessageMqtt mm = getById(id);
|
||||
if(mm == null){
|
||||
mm = new MessageMqtt();
|
||||
}
|
||||
mm.setContent(jo.toJSONString(0));
|
||||
mm.setDirection(topic.getDataDirection());
|
||||
if(header != null){
|
||||
mm.setMessageFunction(header.getFunction());
|
||||
}
|
||||
mm.setMessageId(messageId);
|
||||
mm.setQos(qos);
|
||||
mm.setStationCode(topic.getStationCode());
|
||||
mm.setTopic(topic.toString());
|
||||
mm.setType(topic.getMessageType());
|
||||
if(saveOrUpdate(mm)){
|
||||
return Result.getInstance().build(MessageMqtt.class).success(mm);
|
||||
}
|
||||
return Result.getInstance().build(MessageMqtt.class).error("更改失败");
|
||||
}
|
||||
}
|
||||
@ -74,7 +74,8 @@ public class OrderReservationServiceImpl extends ServiceImpl<OrderReservationMap
|
||||
orderReservationDTO.setSwapDay(swapDay);
|
||||
orderReservationDTO.setSwapDuration(swapDuration);
|
||||
orderReservationDTO.setStatus(1);
|
||||
Result<JSONObject> result = CloudSendInfoUtils.sendOrderReservation(Collections.asMap("source",orderReservationDTO.getSource(),"stationCode",ParamUtils.findStationCode(),"stationName",ParamUtils.findStationName(),"reservationTime",orderReservationDTO.getReservationTime(),"swapDay",DateUtils.parseDateToStr("yyyyMMdd", reservationTime),"swapDuration",orderReservationDTO.getSwapDuration(),"uname",orderReservationDTO.getReservationName(),"phone",orderReservationDTO.getReservationPhone(),"plateNum",orderReservationDTO.getPlateNum()));
|
||||
//"stationCode",ParamUtils.findStationCode(),"stationName",ParamUtils.findStationName(),
|
||||
Result<JSONObject> result = CloudSendInfoUtils.sendOrderReservation(Collections.asMap("source",orderReservationDTO.getSource(),"reservationTime",orderReservationDTO.getReservationTime(),"swapDay",DateUtils.parseDateToStr("yyyyMMdd", reservationTime),"swapDuration",orderReservationDTO.getSwapDuration(),"uname",orderReservationDTO.getReservationName(),"phone",orderReservationDTO.getReservationPhone(),"plateNum",orderReservationDTO.getPlateNum()));
|
||||
JSONObject cloudResult = ResultUtil.getValue(result);
|
||||
if(cloudResult != null){
|
||||
//防止并发, 停止车牌机扫描,
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.evotech.hd.webserver.service.impl;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
@ -8,6 +9,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.evotech.hd.core.dtos.Result;
|
||||
import com.evotech.hd.core.dtos.ResultUtil;
|
||||
import com.evotech.hd.core.dtos.business.AccessStrategyDTO;
|
||||
import com.evotech.hd.core.dtos.business.BatterySwapStepDTO;
|
||||
import com.evotech.hd.core.dtos.business.OrderSwapDTO;
|
||||
import com.evotech.hd.core.entity.business.Battery;
|
||||
@ -16,9 +18,14 @@ import com.evotech.hd.core.entity.business.OrderSwap;
|
||||
import com.evotech.hd.core.enums.OrderStatusEnums;
|
||||
import com.evotech.hd.core.enums.SwapBatteryStepEnum;
|
||||
import com.evotech.hd.core.mapstruct.OrderSwapWrapper;
|
||||
import com.evotech.hd.exception.InstructionException;
|
||||
import com.evotech.hd.utils.Collections;
|
||||
import com.evotech.hd.utils.CommonUtil;
|
||||
import com.evotech.hd.webserver.config.redis.utils.RedisUtil;
|
||||
import com.evotech.hd.webserver.job.JobConstant;
|
||||
import com.evotech.hd.webserver.job.entity.QuartzJobInfo;
|
||||
import com.evotech.hd.webserver.job.service.ExecutionBatterySwapService;
|
||||
import com.evotech.hd.webserver.job.service.QuartzJobService;
|
||||
import com.evotech.hd.webserver.mapper.OrderSwapMapper;
|
||||
import com.evotech.hd.webserver.service.BatteryCompartmentService;
|
||||
import com.evotech.hd.webserver.service.BatteryService;
|
||||
@ -26,7 +33,10 @@ import com.evotech.hd.webserver.service.BatterySwapStepService;
|
||||
import com.evotech.hd.webserver.service.OrderSwapService;
|
||||
import com.evotech.hd.webserver.utils.AccessStrategyUtil;
|
||||
import com.evotech.hd.webserver.utils.ParamUtils;
|
||||
import com.evotech.hd.webserver.utils.instruction.InstructionReadUtils;
|
||||
import com.evotech.hd.webserver.utils.instruction.InstructionWriteUtils;
|
||||
import com.evotech.hd.webserver.utils.sendCloud.CloudSendInfoUtils;
|
||||
import com.evotech.hd.webserver.websocket.controller.WebSocketUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -35,8 +45,13 @@ import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@ -61,6 +76,8 @@ public class OrderSwapServiceImpl extends ServiceImpl<OrderSwapMapper, OrderSwap
|
||||
OrderSwapWrapper orderSwapWrapper;
|
||||
@Autowired
|
||||
ExecutionBatterySwapService executionBatterySwapService;
|
||||
@Autowired
|
||||
QuartzJobService quartzJobService;
|
||||
|
||||
@Override
|
||||
public IPage<OrderSwapDTO> findPageList(Page<OrderSwapDTO> page, QueryWrapper queryWrapper) {
|
||||
@ -195,6 +212,60 @@ public class OrderSwapServiceImpl extends ServiceImpl<OrderSwapMapper, OrderSwap
|
||||
return Result.getInstance().build(Boolean.class).success(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Boolean> close(OrderSwapDTO orderSwapDTO) throws Exception {
|
||||
AccessStrategyDTO accessStrategyDTO = AccessStrategyUtil.getValidAccessStrategyDTO();
|
||||
if(accessStrategyDTO.getBatteryPrefetching() && AccessStrategyUtil.getEffectiveRgvNoList(accessStrategyDTO).size() > 1){
|
||||
//重置预取标识
|
||||
RedisUtil.set("buildTakeFuture", false);
|
||||
//将电池送回仓位
|
||||
Map<String, String> resultMap = JSON.to(Map.class, RedisUtil.get("rgvInfo"));
|
||||
//获取格位信息
|
||||
if(executionBatterySwapService.buildPutFuture(resultMap.get("loadingRgv"), Integer.valueOf(resultMap.get("takeNo")), orderSwapDTO.getId()).join()){
|
||||
//存完之后, 关闭订单信息
|
||||
orderSwapDTO.setStatus(OrderStatusEnums.CANCLE.getCode());
|
||||
if(updateById(orderSwapWrapper.toEntity(orderSwapDTO))){
|
||||
//预取结果重置为false
|
||||
RedisUtil.set("buildTakeFuture", false);
|
||||
//重置rgv信息
|
||||
RedisUtil.set("rgvInfo", JSONObject.toJSONString(Collections.emptyMap()));
|
||||
//关闭车辆到位检查
|
||||
quartzJobService.pauseJob(new QuartzJobInfo(JobConstant.ARRIVAL_SIGNAL_JOB, JobConstant.GroupEnum.SWAP_GROUP.getType()));
|
||||
//打开出口闸门, 执行开门操作
|
||||
InstructionWriteUtils.openRolling(ParamUtils.getDoorParams("出口"));
|
||||
//打开车牌机扫描
|
||||
quartzJobService.resumeJob(JobConstant.LICENSE_PLATE_MACHINE_JOB, JobConstant.GroupEnum.SWAP_GROUP.getType());
|
||||
//推送云端, 订单关闭
|
||||
CloudSendInfoUtils.closeOrderStatus(Collections.asMap("pkId", orderSwapDTO.getCloudOrderId(), "status", orderSwapDTO.getStatus()));
|
||||
//推送空对象推送websocket, 刷新首页数据
|
||||
WebSocketUtils.broadCastMessage(JSONObject.toJSONString(Collections.asMap("method", "order", "data", JSONObject.toJSONString(new OrderSwapDTO((AccessStrategyUtil.getEffectiveRgvNoList(accessStrategyDTO).size()))))));
|
||||
//关门
|
||||
CompletableFuture.runAsync(
|
||||
() -> {
|
||||
//关闭进门栏杆
|
||||
try {
|
||||
InstructionWriteUtils.closeRolling(ParamUtils.getDoorParams("出口"));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
},
|
||||
// 延迟执行器:延迟 5 分钟
|
||||
CompletableFuture.delayedExecutor(ParamUtils.getVehicleAbdicationWaitingMilliseconds(), TimeUnit.MILLISECONDS)
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// else{
|
||||
// result = calculationPosition(accessStrategyDTO);
|
||||
// }
|
||||
|
||||
|
||||
return Result.getInstance().build(Boolean.class).success(true);
|
||||
}
|
||||
|
||||
// public static void sendCloud(final Integer id){
|
||||
// CompletableFuture.runAsync(() -> {
|
||||
// try {
|
||||
|
||||
@ -10,6 +10,7 @@ import com.evotech.hd.core.entity.system.Params;
|
||||
import com.evotech.hd.core.mapstruct.ParamsWrapper;
|
||||
import com.evotech.hd.core.enums.CacheNames;
|
||||
import com.evotech.hd.webserver.mapper.ParamsMapper;
|
||||
import com.evotech.hd.webserver.mqtt.MqttPublishUtils;
|
||||
import com.evotech.hd.webserver.service.ParamsService;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -64,7 +65,6 @@ public class ParamsServiceImpl extends ServiceImpl<ParamsMapper,Params> implemen
|
||||
|
||||
@Override
|
||||
@Cacheable(cacheNames = CacheNames.SYSTEM_RUNNING_PARAMS, key = "#code")
|
||||
// @CacheEvict(value = CacheNames.SYSTEM_RUNNING_PARAMS, key = "#code", allEntries = true)
|
||||
public ParamsDTO getParamsDTOByCode(String code) {
|
||||
Params param = getOne(new LambdaQueryWrapper<Params>().eq(Params::getParamCode, code), false);
|
||||
return paramsWrapper.toDTO(param);
|
||||
@ -75,12 +75,34 @@ public class ParamsServiceImpl extends ServiceImpl<ParamsMapper,Params> implemen
|
||||
}
|
||||
|
||||
@Override
|
||||
// @Cacheable(cacheNames = CacheNames.SYSTEM_RUNNING_PARAMS, key = "#paramsDTO.paramCode")
|
||||
@CacheEvict(value = CacheNames.SYSTEM_RUNNING_PARAMS, allEntries = true)
|
||||
public ParamsDTO saveParamsDTO(ParamsDTO paramsDTO) {
|
||||
saveOrUpdate(paramsWrapper.toEntity(paramsDTO));
|
||||
//如果当前是参数设置, 并且当前操作的是站点编码, 则更新秘钥
|
||||
if(Integer.valueOf(1).equals(paramsDTO.getGroupId()) && "station_code".equals(paramsDTO.getParamCode())){
|
||||
MqttPublishUtils.sendEncryptKeyReq();
|
||||
}
|
||||
return paramsDTO;
|
||||
}
|
||||
|
||||
@Override
|
||||
@CacheEvict(value = CacheNames.SYSTEM_RUNNING_PARAMS, allEntries = true)
|
||||
@Cacheable(cacheNames = CacheNames.SYSTEM_RUNNING_PARAMS, key = "#code")
|
||||
public ParamsDTO getOrUpdateParamsDTO(String name, String code, String defVal, String des) {
|
||||
Params param = getOne(new LambdaQueryWrapper<Params>().eq(Params::getParamCode, code), false);
|
||||
if(ObjectUtils.isEmpty(param)){
|
||||
param = new Params();
|
||||
param.setName(name);
|
||||
param.setParamCode(code);
|
||||
param.setParamValue(defVal);
|
||||
param.setDescription(des);
|
||||
save(param);
|
||||
}else{
|
||||
param.setParamValue(defVal);
|
||||
updateById(param);
|
||||
}
|
||||
return paramsWrapper.toDTO(param);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ import com.evotech.hd.webserver.service.AccessStrategyService;
|
||||
import com.evotech.hd.webserver.utils.sendCloud.CloudSendInfoUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@ -44,4 +45,11 @@ public class AccessStrategyUtil {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public static List<String> getEffectiveRgvNoList(@NotNull AccessStrategyDTO accessStrategyDTO){
|
||||
if(StringUtils.isNotEmpty(accessStrategyDTO.getEffectiveRgvNo())){
|
||||
return Collections.asList(accessStrategyDTO.getEffectiveRgvNo().split(","));
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -54,11 +54,6 @@ public class ParamUtils {
|
||||
* 站端私钥
|
||||
*/
|
||||
static final String STATION_SECRET_KEY = "station_secret_key";
|
||||
/***
|
||||
* 站端公钥
|
||||
*/
|
||||
static final String STATION_PUBLIC_KEY = "station_public_key";
|
||||
|
||||
/***
|
||||
* 站端AES私钥
|
||||
*/
|
||||
@ -149,15 +144,6 @@ public class ParamUtils {
|
||||
ParamsDTO param= paramService.getParamsDTO("站点私钥", ParamsConstant.STATION_SECRET_KEY,"MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAKXEG3/V8DUxpOzb8lJLkJaZGAHSfS+oHoPzZy+Xbr7mb8Jfc7tXRd+H1mmQOXz36HGdPiMP7nK1kPr+ddEJe+yofCkpr5y/Mavki9cLQ3Z/BHUH/t0E7mjyXKhlyn7pfudlW7rqNfQx3eboir+9ppgFe0knW6xHffFECIdfmrt9AgMBAAECgYARw9AMpbFeCgl6RuIT1rxSn2qWu2emJVbL3liHHawFMm30v0UIZUR8PbMJUicPEQRstKTVnh34ViQI+h9HPUR1/rmdI/jdM2n44ai+4AvT1iONgLS4JBBpc5a+ctV9uAgfSU65cRVAzKTzq3Etcqwgzrn8sWultKAyb3pHmjeYswJBANFHjh5LfGSSEpAOdfcNopNAGSaEhNKpm2/0f1VwEyM3/utpTMfHVo/M2OtdpU7JH0+BdtJfAEXtMOMAfzka6EcCQQDKxbuEeYit5zqTbsMLG9y016KjH6oySPnCL4RnA1eeCwK9j0LuYC+rhBg8Km2iLsDwoUDZUjaX/oipB1Ydc+QbAkEAjCG4tOpgucrhqRo1vR6hLK4v6Q21DoZJMXbqyF/KQLve8uzIX8FHYfSNj1ReO1oKoCcVVBoOycPgBzAvACLXQwJBAMCbyl8vwnDN74oT8BkhQihVnBsu/M//GZ8m27GuLw/kjZnZ903O9/kH5K1h7/naR1NLGPpVaZ4/HTjRyy724nkCQQDLEogix/P5ZwI6RmKKAkyyZkMPJIn9kA1j/zeFACdVBzar87GB4DNHiuwByzL4V/CLnQOEocpoq5PciXy2Nbi6","软件初始安装时, 直接初始化");
|
||||
return param.getParamValue();
|
||||
}
|
||||
/***
|
||||
* 站点公钥
|
||||
* @return
|
||||
*/
|
||||
public static String findStationPublicKey(){
|
||||
ParamsDTO param= paramService.getParamsDTO("站点公钥", ParamsConstant.STATION_PUBLIC_KEY,"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQClxBt/1fA1MaTs2/JSS5CWmRgB0n0vqB6D82cvl26+5m/CX3O7V0Xfh9ZpkDl89+hxnT4jD+5ytZD6/nXRCXvsqHwpKa+cvzGr5IvXC0N2fwR1B/7dBO5o8lyoZcp+6X7nZVu66jX0Md3m6Iq/vaaYBXtJJ1usR33xRAiHX5q7fQIDAQAB","软件初始安装时, 直接初始化");
|
||||
return param.getParamValue();
|
||||
}
|
||||
|
||||
/***
|
||||
* 站点对称AES私钥
|
||||
* @return
|
||||
@ -391,4 +377,20 @@ public class ParamUtils {
|
||||
return paramService.getParamsDTOByCode(code);
|
||||
}
|
||||
|
||||
public static void encryptKeyReq(cn.hutool.json.JSONObject jsonObject){
|
||||
try {
|
||||
String encryptVector = jsonObject.getStr("encryptVector");
|
||||
if(StringUtils.isNotEmpty(encryptVector)){
|
||||
paramService.getOrUpdateParamsDTO("站点AES私钥", ParamsConstant.STATION_AES_SECRET_KEY,encryptVector,"软件初始安装时, 直接初始化");
|
||||
}
|
||||
String encryptKey = jsonObject.getStr("encryptKey");
|
||||
if(StringUtils.isNotEmpty(encryptKey)){
|
||||
paramService.getOrUpdateParamsDTO("站点AES公钥", ParamsConstant.STATION_AES_PUBLIC_KEY,encryptKey,"软件初始安装时, 直接初始化");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
log.error("更新站控的AES秘钥出现异常", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -107,17 +107,6 @@ public class InstructionReadUtils {
|
||||
return InstructionUtils.getJson(execution(paramsDTO, String.valueOf(batteryCompartmentNo)));
|
||||
}
|
||||
|
||||
/*** 检查电池仓是否存在电池
|
||||
* @param: batteryCompartmentNo
|
||||
* @return true 存在 false 不存在
|
||||
*/
|
||||
public static Boolean queryBatExist(Integer batteryCompartmentNo) throws InstructionException {
|
||||
ParamsDTO paramsDTO = ParamUtils.getParamsDTO(ParamSysConstants.EXISTS_BATTERY);
|
||||
return InstructionUtils.getBoolean(paramsDTO, executionInteger(paramsDTO, String.valueOf(batteryCompartmentNo)));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*** 检查空调是否连接
|
||||
* @return true 连接 false 未连接
|
||||
*/
|
||||
@ -406,7 +395,9 @@ public class InstructionReadUtils {
|
||||
}
|
||||
|
||||
|
||||
/***消防设备是否连接
|
||||
/*** 检查电池仓是否存在电池
|
||||
* @param: batteryCompartmentNo
|
||||
* @return true 存在 false 不存在
|
||||
*/
|
||||
public static Boolean checkExistsBattery(String batteryCompartmentNo) throws InstructionException {
|
||||
ParamsDTO paramsDTO = ParamUtils.getParamsDTO(ParamSysConstants.BSL_BAT_EXIST);
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.evotech.hd.webserver.utils.sendCloud;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
@ -7,6 +8,7 @@ import com.evotech.hd.core.dtos.Result;
|
||||
import com.evotech.hd.utils.Collections;
|
||||
import com.evotech.hd.webserver.logging.AsyncLogService;
|
||||
import com.evotech.hd.webserver.logging.LogUtils;
|
||||
import com.evotech.hd.webserver.mqtt.MqttPublishUtils;
|
||||
import com.evotech.hd.webserver.utils.ParamUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.http.client.HttpClient;
|
||||
@ -86,16 +88,6 @@ public class CloudSendInfoUtils {
|
||||
return JSONObject.parseObject(result.toString(),Result.class);
|
||||
}
|
||||
|
||||
/***
|
||||
* 站端获取预约单数据
|
||||
* @param map
|
||||
* @return
|
||||
*/
|
||||
public static Result<JSONArray> findOrderReservationList(Map<String, Object> map){
|
||||
JSONObject result = send("获取云端预约单数据", JSONObject.parseObject(JSONObject.toJSONString(buildBaseInfo(map,"orderSwapBatteryPreProcessor","findOrderSwapBatteryPre"))));
|
||||
return JSONObject.parseObject(result.toString(),Result.class);
|
||||
}
|
||||
|
||||
/***
|
||||
* 站端推送预约单数据状态
|
||||
* @param map
|
||||
@ -121,19 +113,33 @@ public class CloudSendInfoUtils {
|
||||
* @param map
|
||||
* @return
|
||||
*/
|
||||
public static void sendAlarm(Map<String, Object> map){
|
||||
public static void sendAlarm(Map<String, Object> map, Boolean effectBatterySwapping){
|
||||
map.put("state", effectBatterySwapping ? 3 : (ParamUtils.findStationRunningStatus() ? 1 : 3));
|
||||
MqttPublishUtils.sendState("stationState", JSONUtil.parseObj(map));
|
||||
|
||||
//结合云端接口增加站端运行状态
|
||||
map.put("state", (ParamUtils.findStationRunningStatus() ? 1 : 3));
|
||||
send("推送告警信息", JSONObject.parseObject(JSONObject.toJSONString(buildBaseInfo(map,"alarmProcessor","alarmMessage"))));
|
||||
//如果影响换电, 直接给3 进入检修, 如果不影响, 则检查当前站端的运行状态
|
||||
// map.put("state", effectBatterySwapping ? 3 : (ParamUtils.findStationRunningStatus() ? 1 : 3));
|
||||
// send("推送告警信息", JSONObject.parseObject(JSONObject.toJSONString(buildBaseInfo(map,"alarmProcessor","alarmMessage"))));
|
||||
}
|
||||
|
||||
/***
|
||||
* 站端推送车辆到位信息
|
||||
* 站端推送换电步骤信息
|
||||
* @param map
|
||||
* @return
|
||||
*/
|
||||
public static Result<Boolean> sendArrivalSignal(Map<String, Object> map){
|
||||
JSONObject result = send("创建订单", JSONObject.parseObject(JSONObject.toJSONString(buildBaseInfo(map,"orderSwapProcessor","arrivalSignal"))));
|
||||
JSONObject result = send("换电步骤", JSONObject.parseObject(JSONObject.toJSONString(buildBaseInfo(map,"orderSwapProcessor","arrivalSignal"))));
|
||||
return JSONObject.parseObject(result.toString(),Result.class);
|
||||
}
|
||||
|
||||
/***
|
||||
* 订单关闭
|
||||
* @param map
|
||||
* @return
|
||||
*/
|
||||
public static Result<Boolean> closeOrderStatus(Map<String, Object> map){
|
||||
JSONObject result = send("订单关闭", JSONObject.parseObject(JSONObject.toJSONString(buildBaseInfo(map,"orderSwapProcessor","closeOrderStatus"))));
|
||||
return JSONObject.parseObject(result.toString(),Result.class);
|
||||
}
|
||||
|
||||
@ -190,7 +196,7 @@ public class CloudSendInfoUtils {
|
||||
}
|
||||
|
||||
public static void sendAlarmWx(Map<String, Object> map){
|
||||
JSONObject result = doPost("https://api.evo-techina.com/cloud/alarm/send/hq_web", map, Collections.asMap("Content-Type", "application/json","Accept-Language", "zh-CN"));
|
||||
doPost("https://api.evo-techina.com/cloud/alarm/send/hq_web", map, Collections.asMap("Content-Type", "application/json","Accept-Language", "zh-CN"));
|
||||
}
|
||||
|
||||
private static JSONObject doPost(String url, Map<String, Object> map, Map<String, String> headersMap) {
|
||||
|
||||
@ -1,18 +1,10 @@
|
||||
package com.evotech.hd.webserver.utils.sendCloud;
|
||||
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import cn.hutool.crypto.asymmetric.AsymmetricAlgorithm;
|
||||
import cn.hutool.crypto.asymmetric.Sign;
|
||||
import cn.hutool.crypto.asymmetric.SignAlgorithm;
|
||||
import com.evotech.hd.webserver.utils.ParamUtils;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.Signature;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
@ -25,23 +17,6 @@ import java.util.Base64;
|
||||
*/
|
||||
public class RsaEcbPkcsFullUtil {
|
||||
|
||||
// 签名算法:SHA256哈希 + RSA/ECB/PKCS1Padding
|
||||
private static final String SIGNATURE_ALGORITHM = "SHA256withRSA/ECB/PKCS1Padding";
|
||||
// RSA密钥算法
|
||||
private static final String KEY_ALGORITHM = "RSA";
|
||||
private static byte[] privateKeyStr = null;
|
||||
private static PrivateKey privateKey = null;
|
||||
private static PublicKey publicKey = null;
|
||||
// static{
|
||||
// try {
|
||||
// privateKeyStr = Base64.getDecoder().decode(ParamUtils.findStationSecretKey());
|
||||
// privateKey = base64ToPrivateKey();
|
||||
// publicKey = base64ToPublicKey();
|
||||
// } catch (Exception e) {
|
||||
// throw new RuntimeException(e);
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* 用私钥对消息签名(SHA256withRSA/ECB/PKCS1Padding)
|
||||
* @param message 原始消息
|
||||
@ -52,92 +27,4 @@ public class RsaEcbPkcsFullUtil {
|
||||
return Base64.getEncoder().encodeToString(sign.sign(message));
|
||||
}
|
||||
|
||||
/***
|
||||
* 私钥消息加密
|
||||
* @param message
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String encrypt(String message) throws Exception {
|
||||
// e.getBytes("UTF-8"));
|
||||
return Base64.getEncoder().encodeToString(SecureUtil.desede(privateKeyStr).encrypt(message));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 用公钥验证签名(SHA256withRSA/ECB/PKCS1Padding)
|
||||
* @param message 解密后的消息
|
||||
* @param signature 接收的签名(Base64编码)
|
||||
* @return 验证是否通过
|
||||
*/
|
||||
public static boolean verify(String message, String signature) throws Exception {
|
||||
Signature verifier = Signature.getInstance(AsymmetricAlgorithm.RSA_ECB_PKCS1.getValue());
|
||||
verifier.initVerify(publicKey); // 公钥验证模式
|
||||
verifier.update(message.getBytes("UTF-8"));
|
||||
byte[] signBytes = Base64.getDecoder().decode(signature);
|
||||
return verifier.verify(signBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用私钥解密消息(RSA/ECB/PKCS1Padding)
|
||||
* @param encryptedMessage 加密后的消息(Base64编码)
|
||||
* @return 解密后的原始消息
|
||||
*/
|
||||
public static String decrypt(String encryptedMessage) throws Exception {
|
||||
Cipher cipher = Cipher.getInstance(AsymmetricAlgorithm.RSA_ECB_PKCS1.getValue());
|
||||
cipher.init(Cipher.DECRYPT_MODE, privateKey); // 私钥解密模式
|
||||
byte[] encryptedBytes = Base64.getDecoder().decode(encryptedMessage);
|
||||
byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
|
||||
return new String(decryptedBytes, "UTF-8");
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
* 私钥消息加密
|
||||
* @param message
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String encryptWithPrivateKey(String message) throws Exception {
|
||||
// Cipher cipher = Cipher.getInstance(AsymmetricAlgorithm.RSA_ECB_PKCS1.getValue());
|
||||
// cipher.init(Cipher.ENCRYPT_MODE, privateKey); // 私钥加密模式
|
||||
// // 3. 加密并返回Base64结果
|
||||
// byte[] encryptedBytes = cipher.doFinal(message.getBytes("UTF-8"));
|
||||
return Base64.getEncoder().encodeToString(SecureUtil.desede(privateKeyStr).encrypt(message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 用公钥解密(私钥加密的数据必须用对应公钥解密)
|
||||
* @param encryptedMessage 加密后的消息(Base64)
|
||||
* @return 解密后的原始消息
|
||||
*/
|
||||
public static String decryptWithPublicKey(String encryptedMessage) throws Exception {
|
||||
Cipher cipher = Cipher.getInstance(AsymmetricAlgorithm.RSA_ECB_PKCS1.getValue());
|
||||
cipher.init(Cipher.DECRYPT_MODE, publicKey); // 公钥解密模式
|
||||
byte[] encryptedBytes = Base64.getDecoder().decode(encryptedMessage);
|
||||
byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
|
||||
return new String(decryptedBytes, "UTF-8");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Base64字符串私钥转为PrivateKey对象(PKCS#8格式)
|
||||
*/
|
||||
private static PrivateKey base64ToPrivateKey() throws Exception {
|
||||
byte[] keyBytes = Base64.getDecoder().decode(ParamUtils.findStationSecretKey());
|
||||
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); // 私钥用PKCS8规范
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
||||
return keyFactory.generatePrivate(keySpec);
|
||||
}
|
||||
|
||||
/**
|
||||
* Base64字符串转为PublicKey对象(X.509格式)
|
||||
*/
|
||||
private static PublicKey base64ToPublicKey() throws Exception {
|
||||
byte[] keyBytes = Base64.getDecoder().decode(ParamUtils.findStationPublicKey());
|
||||
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); // 公钥用X.509规范
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
||||
return keyFactory.generatePublic(keySpec);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
spring:
|
||||
redis:
|
||||
host: 192.168.16.128
|
||||
host: 192.168.5.112
|
||||
port: 6379
|
||||
database: 13
|
||||
password: hbyt2025
|
||||
@ -17,7 +17,7 @@ spring:
|
||||
# #连接池最大阻塞等待时间(使用负值表示没有限制)
|
||||
max-wait: -1ms
|
||||
mqtt:
|
||||
broker: tcp://192.168.16.128:1883 # MQTT服务器地址(如Mosquitto默认端口1883)
|
||||
broker: tcp://192.168.5.112:1883 # MQTT服务器地址(如Mosquitto默认端口1883)
|
||||
client-id: springboot-mqtt-${random.value} # 客户端ID(添加随机数确保唯一)
|
||||
username: admin # 可选,MQTT服务器认证用户名
|
||||
password: hbyt12345 # 可选,MQTT服务器认证密码
|
||||
|
||||
@ -27,7 +27,7 @@ spring:
|
||||
initialize-schema: always
|
||||
job-store-type: jdbc
|
||||
profiles:
|
||||
active: ${profiles.active:pro},mongo${profiles.active:},quartz #development
|
||||
active: ${profiles.active:pro},mongo${profiles.active:},quartz,core #development
|
||||
# 服务模块
|
||||
devtools:
|
||||
restart:
|
||||
@ -141,6 +141,8 @@ jwt:
|
||||
accessToken:
|
||||
expireTime: 1000000
|
||||
|
||||
cloudPublicKey:
|
||||
|
||||
#
|
||||
#mqtt:
|
||||
# broker: tcp://192.168.16.128:1883 # MQTT服务器地址(如Mosquitto默认端口1883)
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
id, `name`, create_time, extendeds,
|
||||
strategy,power_strategy, charging_strategy, instant_charge_power, minimum_safety_stock, effective_rgv_no, minimum_safety_stock,lowest_battery_swap_soc,full_of_limit_soc,
|
||||
strategy,power_strategy, charging_strategy, instant_charge_power, minimum_safety_stock, effective_rgv_no, minimum_safety_stock,lowest_battery_swap_soc,full_of_limit_soc,battery_prefetching,
|
||||
valid
|
||||
|
||||
</sql>
|
||||
|
||||
7
web-server/src/main/resources/mapper/BaseMapper.xml
Normal file
7
web-server/src/main/resources/mapper/BaseMapper.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.evotech.hd.webserver.mapper.BasicMapper">
|
||||
<sql id="Base_Column">
|
||||
a.id, a.`name`, a.create_time, a.extendeds
|
||||
</sql>
|
||||
</mapper>
|
||||
@ -72,6 +72,14 @@
|
||||
${ew.customSqlSegment}
|
||||
</select>
|
||||
|
||||
<select id="findList" resultMap="BatteryCompartmentResultMap">
|
||||
SELECT
|
||||
<include refid="Base_Column_List"/>
|
||||
from sc_battery_compartment a
|
||||
left join sc_battery b on b.battery_compartment_id = a.id and b.storage_Status = 1
|
||||
${ew.customSqlSegment}
|
||||
</select>
|
||||
|
||||
<select id="getInfo" resultMap="BatteryCompartmentResultMap">
|
||||
SELECT
|
||||
<include refid="Base_Column_List"/>
|
||||
|
||||
16
web-server/src/main/resources/mapper/MessageMqttMapper.xml
Normal file
16
web-server/src/main/resources/mapper/MessageMqttMapper.xml
Normal file
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.evotech.hd.webserver.mapper.MessageMqttMapper">
|
||||
<sql id="Base_Column_List">
|
||||
a.station_code,a.direction, a.message_id,a.qos,a.type,a.message_function,a.topic,a.content,
|
||||
<include refid="com.evotech.hd.webserver.mapper.BasicMapper.Base_Column"/>
|
||||
</sql>
|
||||
<!-- 通用查询结果列 -->
|
||||
<select id="findPage" resultType="com.evotech.hd.core.dtos.system.MessageMqttDTO">
|
||||
SELECT
|
||||
<include refid="Base_Column_List"/>
|
||||
from sc_sys_message_mqtt a
|
||||
${ew.customSqlSegment}
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@ -10,7 +10,8 @@ a.param_code,
|
||||
a.description,
|
||||
a.expected_results,
|
||||
a.verify_result,
|
||||
a.err_message
|
||||
a.err_message,
|
||||
a.effect_battery_swapping
|
||||
|
||||
</sql>
|
||||
<!-- 通用查询结果列 -->
|
||||
|
||||
Loading…
Reference in New Issue
Block a user