Browse Source

feate: 修正处理

jackzhou 7 months ago
parent
commit
1b65f69592
29 changed files with 417 additions and 59 deletions
  1. 2 0
      snowy-plugin-api/snowy-plugin-auth-api/src/main/java/vip/xiaonuo/auth/api/SaBaseLoginUserApi.java
  2. 7 0
      snowy-plugin/snowy-plugin-auth/src/main/java/vip/xiaonuo/auth/modular/login/controller/AuthClientController.java
  3. 4 0
      snowy-plugin/snowy-plugin-auth/src/main/java/vip/xiaonuo/auth/modular/login/param/AuthAccountPasswordLoginParam.java
  4. 2 0
      snowy-plugin/snowy-plugin-auth/src/main/java/vip/xiaonuo/auth/modular/login/service/AuthService.java
  5. 10 0
      snowy-plugin/snowy-plugin-auth/src/main/java/vip/xiaonuo/auth/modular/login/service/impl/AuthServiceImpl.java
  6. 5 0
      snowy-plugin/snowy-plugin-client/src/main/java/vip/xiaonuo/client/modular/user/provider/ClientLoginUserApiProvider.java
  7. 36 0
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/event/MonitorDeviceHeartBeatEvent.java
  8. 37 0
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/event/MonitorDeviceHeartBeatEventListener.java
  9. 36 0
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/event/MonitorDeviceLoginEvent.java
  10. 37 0
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/event/MonitorDeviceLoginEventListener.java
  11. 6 0
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/renke/listener/JfcloudColdChainRenKeDefaultDataListener.java
  12. 10 0
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/dataclean/MonitorDataProcessor.java
  13. 37 6
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/dataclean/impl/AbsRenkeMonitorDataProcessor.java
  14. 8 0
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/handler/AbstractColdChainDataHandler.java
  15. 11 0
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/handler/ColdChainDataHandler.java
  16. 34 35
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/handler/impl/RenKeColdChainDataHandler.java
  17. 5 0
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/model/ColdChainMessageData.java
  18. 1 0
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/model/HaierColdChainMessageData.java
  19. 1 0
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/model/RenKeColdChainMessageData.java
  20. 32 6
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/app/param/AppDevice.java
  21. 18 5
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/app/param/AppDeviceData.java
  22. 3 3
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/app/service/AppDeviceService.java
  23. 5 0
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/monitordevice/service/MonitorDeviceService.java
  24. 39 0
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/monitordevice/service/impl/MonitorDeviceServiceImpl.java
  25. 5 0
      snowy-plugin/snowy-plugin-sys/src/main/java/vip/xiaonuo/sys/modular/user/provider/SysLoginUserApiProvider.java
  26. 2 0
      snowy-plugin/snowy-plugin-sys/src/main/java/vip/xiaonuo/sys/modular/user/service/SysUserService.java
  27. 10 0
      snowy-plugin/snowy-plugin-sys/src/main/java/vip/xiaonuo/sys/modular/user/service/impl/SysUserServiceImpl.java
  28. 1 0
      snowy-web-app/src/main/java/vip/xiaonuo/core/config/GlobalConfigure.java
  29. 13 4
      snowy-web-app/src/main/java/vip/xiaonuo/weixin/miniapp/controller/WxMaUserController.java

+ 2 - 0
snowy-plugin-api/snowy-plugin-auth-api/src/main/java/vip/xiaonuo/auth/api/SaBaseLoginUserApi.java

@@ -121,4 +121,6 @@ public interface SaBaseLoginUserApi {
      * @date 2022/4/27 22:57
      * @date 2022/4/27 22:57
      */
      */
     void updateUserLoginInfo(String userId, String device);
     void updateUserLoginInfo(String userId, String device);
+
+    boolean updateUserOpenId(String account, String openId);
 }
 }

+ 7 - 0
snowy-plugin/snowy-plugin-auth/src/main/java/vip/xiaonuo/auth/modular/login/controller/AuthClientController.java

@@ -82,6 +82,13 @@ public class AuthClientController {
         return CommonResult.data(authService.doLogin(authAccountPasswordLoginParam, SaClientTypeEnum.C.getValue()));
         return CommonResult.data(authService.doLogin(authAccountPasswordLoginParam, SaClientTypeEnum.C.getValue()));
     }
     }
 
 
+
+    @Operation(summary = "小程序密码登录")
+    @PostMapping("/auth/mini/doLogin")
+    public CommonResult<String> doMiniLogin(@RequestBody @Valid AuthAccountPasswordLoginParam authAccountPasswordLoginParam) {
+        return CommonResult.data(authService.doMiniLogin(authAccountPasswordLoginParam, SaClientTypeEnum.B.getValue()));
+    }
+
     /**
     /**
      * C端手机验证码登录
      * C端手机验证码登录
      *
      *

+ 4 - 0
snowy-plugin/snowy-plugin-auth/src/main/java/vip/xiaonuo/auth/modular/login/param/AuthAccountPasswordLoginParam.java

@@ -45,6 +45,10 @@ public class AuthAccountPasswordLoginParam {
     @Schema(description = "验证码")
     @Schema(description = "验证码")
     private String validCode;
     private String validCode;
 
 
+    /** openId */
+    @Schema(description = "openId")
+    private String openId;
+
     /** 验证码请求号 */
     /** 验证码请求号 */
     @Schema(description = "验证码请求号")
     @Schema(description = "验证码请求号")
     private String validCodeReqNo;
     private String validCodeReqNo;

+ 2 - 0
snowy-plugin/snowy-plugin-auth/src/main/java/vip/xiaonuo/auth/modular/login/service/AuthService.java

@@ -90,4 +90,6 @@ public interface AuthService {
      * @date 2022/7/9 14:44
      * @date 2022/7/9 14:44
      */
      */
     String doLoginById(String userId, String device, String type);
     String doLoginById(String userId, String device, String type);
+
+    String doMiniLogin(AuthAccountPasswordLoginParam authAccountPasswordLoginParam, String value);
 }
 }

+ 10 - 0
snowy-plugin/snowy-plugin-auth/src/main/java/vip/xiaonuo/auth/modular/login/service/impl/AuthServiceImpl.java

@@ -527,4 +527,14 @@ public class AuthServiceImpl implements AuthService {
             return execLoginC(saBaseClientLoginUser, device);
             return execLoginC(saBaseClientLoginUser, device);
         }
         }
     }
     }
+
+    @Override
+    public String doMiniLogin(AuthAccountPasswordLoginParam authAccountPasswordLoginParam, String value) {
+        String token = doLogin(authAccountPasswordLoginParam, value);
+        if (StrUtil.isNotBlank(token)) {
+            // 更新用户openid
+            loginUserApi.updateUserOpenId(authAccountPasswordLoginParam.getAccount(), authAccountPasswordLoginParam.getOpenId());
+        }
+        return token;
+    }
 }
 }

+ 5 - 0
snowy-plugin/snowy-plugin-client/src/main/java/vip/xiaonuo/client/modular/user/provider/ClientLoginUserApiProvider.java

@@ -173,4 +173,9 @@ public class ClientLoginUserApiProvider implements SaBaseLoginUserApi {
     public void updateUserLoginInfo(String userId, String device) {
     public void updateUserLoginInfo(String userId, String device) {
         clientUserService.updateUserLoginInfo(userId, device);
         clientUserService.updateUserLoginInfo(userId, device);
     }
     }
+
+    @Override
+    public boolean updateUserOpenId(String account, String openId) {
+        return false;
+    }
 }
 }

+ 36 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/event/MonitorDeviceHeartBeatEvent.java

@@ -0,0 +1,36 @@
+package vip.xiaonuo.coldchain.core.event;
+
+/**
+ * @author jackzhou
+ * @version 1.0
+ * @project jfcloud-coldchain
+ * @description 心跳机制
+ * @date 2024/11/12 15:31:05
+ */
+
+import lombok.Getter;
+import org.springframework.context.ApplicationEvent;
+
+import java.time.Clock;
+import java.util.Date;
+
+@Getter
+public class MonitorDeviceHeartBeatEvent extends ApplicationEvent {
+    private final Integer deviceId;
+    private final String ip;
+    private final Date timestamps;
+
+    public MonitorDeviceHeartBeatEvent(Object source, Integer deviceId, String ip, Date timestamps) {
+        super(source);
+        this.deviceId = deviceId;
+        this.ip = ip;
+        this.timestamps = timestamps;
+    }
+
+    public MonitorDeviceHeartBeatEvent(Object source, Clock clock, Integer deviceId, String ip, Date timestamps) {
+        super(source, clock);
+        this.deviceId = deviceId;
+        this.ip = ip;
+        this.timestamps = timestamps;
+    }
+}

+ 37 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/event/MonitorDeviceHeartBeatEventListener.java

@@ -0,0 +1,37 @@
+package vip.xiaonuo.coldchain.core.event;
+
+/**
+ * @author jackzhou
+ * @version 1.0
+ * @project jfcloud-coldchain
+ * @description
+ * @date 2024/11/12 15:31:43
+ */
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.event.EventListener;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+import vip.xiaonuo.coldchain.modular.monitordevice.service.MonitorDeviceService;
+
+import java.util.Date;
+
+@Slf4j
+@RequiredArgsConstructor
+@Component
+public class MonitorDeviceHeartBeatEventListener {
+    private final MonitorDeviceService monitorDeviceService;
+
+    @Async
+    @EventListener
+    public void handleMonitorDeviceHeartBeatEvent(MonitorDeviceHeartBeatEvent event) {
+        Integer deviceId = event.getDeviceId();
+        String ip = event.getIp();
+        Date timestamp = event.getTimestamps();
+        try {
+            boolean s = monitorDeviceService.updateLastHeartbeatTimeByDeviceId(deviceId, timestamp);
+        } catch (Exception e) {
+        }
+    }
+}

+ 36 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/event/MonitorDeviceLoginEvent.java

@@ -0,0 +1,36 @@
+package vip.xiaonuo.coldchain.core.event;
+
+/**
+ * @author jackzhou
+ * @version 1.0
+ * @project jfcloud-coldchain
+ * @description 登录事件
+ * @date 2024/11/12 15:31:05
+ */
+
+import lombok.Getter;
+import org.springframework.context.ApplicationEvent;
+
+import java.time.Clock;
+import java.util.Date;
+
+@Getter
+public class MonitorDeviceLoginEvent extends ApplicationEvent {
+    private final Integer deviceId;
+    private final String ip;
+    private final Date timestamps;
+
+    public MonitorDeviceLoginEvent(Object source, Integer deviceId, String ip, Date timestamps) {
+        super(source);
+        this.deviceId = deviceId;
+        this.ip = ip;
+        this.timestamps = timestamps;
+    }
+
+    public MonitorDeviceLoginEvent(Object source, Clock clock, Integer deviceId, String ip, Date timestamps) {
+        super(source, clock);
+        this.deviceId = deviceId;
+        this.ip = ip;
+        this.timestamps = timestamps;
+    }
+}

+ 37 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/event/MonitorDeviceLoginEventListener.java

@@ -0,0 +1,37 @@
+package vip.xiaonuo.coldchain.core.event;
+
+/**
+ * @author jackzhou
+ * @version 1.0
+ * @project jfcloud-coldchain
+ * @description
+ * @date 2024/11/12 15:31:43
+ */
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.event.EventListener;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+import vip.xiaonuo.coldchain.modular.monitordevice.service.MonitorDeviceService;
+
+import java.util.Date;
+
+@Slf4j
+@RequiredArgsConstructor
+@Component
+public class MonitorDeviceLoginEventListener {
+    private final MonitorDeviceService monitorDeviceService;
+
+    @Async
+    @EventListener
+    public void handleMonitorDeviceLoginEvent(MonitorDeviceLoginEvent event) {
+        Integer deviceId = event.getDeviceId();
+        String ip = event.getIp();
+        Date timestamps = event.getTimestamps();
+        try {
+            boolean s = monitorDeviceService.updateLastLoginTimeByDeviceId(deviceId, timestamps);
+        } catch (Exception e) {
+        }
+    }
+}

+ 6 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/renke/listener/JfcloudColdChainRenKeDefaultDataListener.java

@@ -57,6 +57,9 @@ public class JfcloudColdChainRenKeDefaultDataListener implements IDataListener {
     @Override
     @Override
     public void receiveLoginData(LoginData data) {
     public void receiveLoginData(LoginData data) {
         log.info("接收到设备登录信息: 设备ID = {}\n{}", data.getDeviceId(), JSONUtil.toJsonStr(data));
         log.info("接收到设备登录信息: 设备ID = {}\n{}", data.getDeviceId(), JSONUtil.toJsonStr(data));
+        RenKeColdChainMessageData renKeColdChainMessageData = new RenKeColdChainMessageData();
+        renKeColdChainMessageData.setDeviceId(data.getDeviceId());
+        renKeColdChainDataHandler.login(renKeColdChainMessageData);
     }
     }
 
 
     @Override
     @Override
@@ -86,5 +89,8 @@ public class JfcloudColdChainRenKeDefaultDataListener implements IDataListener {
     @Override
     @Override
     public void receiveHeartbeatData(HeartbeatData heartbeatData) {
     public void receiveHeartbeatData(HeartbeatData heartbeatData) {
         log.info("接收到心跳包: 设备ID = {}", heartbeatData.getDeviceId());
         log.info("接收到心跳包: 设备ID = {}", heartbeatData.getDeviceId());
+        RenKeColdChainMessageData renKeColdChainMessageData = new RenKeColdChainMessageData();
+        renKeColdChainMessageData.setDeviceId(heartbeatData.getDeviceId());
+        renKeColdChainDataHandler.login(renKeColdChainMessageData);
     }
     }
 }
 }

+ 10 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/dataclean/MonitorDataProcessor.java

@@ -14,4 +14,14 @@ public interface MonitorDataProcessor<T> {
     String RS_WS_WIFI5_C3_Y4 = "RS-WS-WIFI5-C3-Y4";
     String RS_WS_WIFI5_C3_Y4 = "RS-WS-WIFI5-C3-Y4";
 
 
     Boolean processData(T data);
     Boolean processData(T data);
+
+    /**
+     * 设备登录
+     */
+    void login(T data);
+
+    /**
+     * 处理心跳
+     */
+    void heartbeat(T data);
 }
 }

+ 37 - 6
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/dataclean/impl/AbsRenkeMonitorDataProcessor.java

@@ -1,14 +1,19 @@
 package vip.xiaonuo.coldchain.core.service.dataprocess.dataclean.impl;
 package vip.xiaonuo.coldchain.core.service.dataprocess.dataclean.impl;
 
 
+import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.context.ApplicationEventPublisher;
 import rk.netDevice.sdk.p2.RealTimeData;
 import rk.netDevice.sdk.p2.RealTimeData;
 import vip.xiaonuo.coldchain.core.bean.influxdb.SensorData;
 import vip.xiaonuo.coldchain.core.bean.influxdb.SensorData;
+import vip.xiaonuo.coldchain.core.event.MonitorDeviceHeartBeatEvent;
+import vip.xiaonuo.coldchain.core.event.MonitorDeviceLoginEvent;
 import vip.xiaonuo.coldchain.core.event.SensorDataEvent;
 import vip.xiaonuo.coldchain.core.event.SensorDataEvent;
 import vip.xiaonuo.coldchain.core.service.dataprocess.dataclean.MonitorDataProcessor;
 import vip.xiaonuo.coldchain.core.service.dataprocess.dataclean.MonitorDataProcessor;
+import vip.xiaonuo.coldchain.core.service.dataprocess.model.RenKeColdChainMessageData;
 import vip.xiaonuo.coldchain.modular.monitordevice.enums.DeviceModelEnum;
 import vip.xiaonuo.coldchain.modular.monitordevice.enums.DeviceModelEnum;
 
 
 import java.time.Instant;
 import java.time.Instant;
+import java.util.Date;
 import java.util.List;
 import java.util.List;
 import java.util.Objects;
 import java.util.Objects;
 
 
@@ -22,7 +27,7 @@ import java.util.Objects;
  * @date 2024/11/19
  * @date 2024/11/19
  */
  */
 @Slf4j  // 引入日志功能
 @Slf4j  // 引入日志功能
-public abstract class AbsRenkeMonitorDataProcessor implements MonitorDataProcessor<RealTimeData> {
+public abstract class AbsRenkeMonitorDataProcessor implements MonitorDataProcessor<RenKeColdChainMessageData> {
     // 设备型号
     // 设备型号
     protected String modelName;
     protected String modelName;
     // 事件发布器
     // 事件发布器
@@ -40,11 +45,12 @@ public abstract class AbsRenkeMonitorDataProcessor implements MonitorDataProcess
      * 3. 转换数据格式为传感器数据
      * 3. 转换数据格式为传感器数据
      * 4. 发布传感器数据事件
      * 4. 发布传感器数据事件
      *
      *
-     * @param data 实时数据
+     * @param renKeColdChainMessageData 实时数据
      * @return 处理是否成功
      * @return 处理是否成功
      */
      */
     @Override
     @Override
-    public Boolean processData(RealTimeData data) {
+    public Boolean processData(RenKeColdChainMessageData renKeColdChainMessageData) {
+        RealTimeData data = renKeColdChainMessageData.getRealTimeData();
         // 1. 确保实时数据不为空
         // 1. 确保实时数据不为空
         if (Objects.isNull(data) || Objects.isNull(data.getNodeList()) || data.getNodeList().isEmpty()) {
         if (Objects.isNull(data) || Objects.isNull(data.getNodeList()) || data.getNodeList().isEmpty()) {
             return false;
             return false;
@@ -54,7 +60,7 @@ public abstract class AbsRenkeMonitorDataProcessor implements MonitorDataProcess
         // 3. 获取设备ID,并从设备缓存中获取设备型号
         // 3. 获取设备ID,并从设备缓存中获取设备型号
         final String deviceId = String.valueOf(data.getDeviceId());
         final String deviceId = String.valueOf(data.getDeviceId());
         // 4. 日志记录:输出当前设备的型号信息
         // 4. 日志记录:输出当前设备的型号信息
-        log.info("开始处理设备数据,设备ID: {}, 设备型号: {}", deviceId, modelName);
+        log.info("开始处理设备数据,设备ID: {}, 设备型号: {}", deviceId, getModelName());
         // 5. 将实时数据转换为传感器数据列表
         // 5. 将实时数据转换为传感器数据列表
         List<SensorData> sensorDataList = transRealTimeData2SensorDatas(data);
         List<SensorData> sensorDataList = transRealTimeData2SensorDatas(data);
         // 6. 发布传感器数据事件
         // 6. 发布传感器数据事件
@@ -62,9 +68,8 @@ public abstract class AbsRenkeMonitorDataProcessor implements MonitorDataProcess
         // 7. 日志记录:输出处理结果
         // 7. 日志记录:输出处理结果
         if (result) {
         if (result) {
             postProcess(sensorDataList);
             postProcess(sensorDataList);
-            log.info("处理设备数据结束,设备ID: {}, 设备型号: {}", deviceId, modelName);
         } else {
         } else {
-            log.error("处理设备数据结束,但保存失败,设备ID: {}, 设备型号: {}", deviceId, modelName);
+            log.error("处理设备数据结束,但保存失败,设备ID: {}, 设备型号: {}", deviceId, getModelName());
         }
         }
         return result;
         return result;
     }
     }
@@ -165,4 +170,30 @@ public abstract class AbsRenkeMonitorDataProcessor implements MonitorDataProcess
         sensorData.setDeviceId(deviceId);
         sensorData.setDeviceId(deviceId);
         return sensorData;
         return sensorData;
     }
     }
+
+    // 公共的事件发布方法
+    @SneakyThrows
+    private void publishDeviceEvent(Integer deviceId, Date timestamp, Class<?> eventType) {
+        if (timestamp == null) {
+            // 默认使用当前时间
+            timestamp = new Date();
+        }
+        applicationEventPublisher.publishEvent(eventType.getConstructor(Object.class, Integer.class, String.class, Date.class)
+                .newInstance(this, deviceId, null, timestamp));
+    }
+
+    @Override
+    public void login(RenKeColdChainMessageData data) {
+        Integer deviceId = data.getDeviceId();
+        Date timestamp = new Date();
+        publishDeviceEvent(deviceId, timestamp, MonitorDeviceLoginEvent.class);
+    }
+
+    @Override
+    public void heartbeat(RenKeColdChainMessageData data) {
+        Integer deviceId = data.getDeviceId();
+        Date timestamp = new Date();
+        publishDeviceEvent(deviceId, timestamp, MonitorDeviceHeartBeatEvent.class);
+    }
+
 }
 }

+ 8 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/handler/AbstractColdChainDataHandler.java

@@ -41,4 +41,12 @@ public abstract class AbstractColdChainDataHandler<T extends ColdChainMessageDat
             throw new IllegalStateException("无法解析泛型类型");
             throw new IllegalStateException("无法解析泛型类型");
         }
         }
     }
     }
+
+    @Override
+    public void login(T data) {
+    }
+
+    @Override
+    public void heartbeat(T data) {
+    }
 }
 }

+ 11 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/handler/ColdChainDataHandler.java

@@ -27,4 +27,15 @@ public interface ColdChainDataHandler<T extends ColdChainMessageData> {
      * 获取处理的数据类型,使用泛型反射来获取实际类型
      * 获取处理的数据类型,使用泛型反射来获取实际类型
      */
      */
     Class<T> getDataClass();
     Class<T> getDataClass();
+
+
+    /**
+     * 设备登录
+     */
+    void login(T data);
+
+    /**
+     * 处理心跳
+     */
+    void heartbeat(T data);
 }
 }

+ 34 - 35
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/handler/impl/RenKeColdChainDataHandler.java

@@ -25,7 +25,6 @@ import java.util.Map;
 @RequiredArgsConstructor
 @RequiredArgsConstructor
 public class RenKeColdChainDataHandler extends AbstractColdChainDataHandler<RenKeColdChainMessageData> {
 public class RenKeColdChainDataHandler extends AbstractColdChainDataHandler<RenKeColdChainMessageData> {
     private final Map<String, MonitorDataProcessor<?>> monitorDataProcessorMap;
     private final Map<String, MonitorDataProcessor<?>> monitorDataProcessorMap;
-    //    private final ApplicationEventPublisher eventPublisher;
     private final MonitorDeviceCache monitorDeviceCache;
     private final MonitorDeviceCache monitorDeviceCache;
 
 
     @Override
     @Override
@@ -35,43 +34,43 @@ public class RenKeColdChainDataHandler extends AbstractColdChainDataHandler<RenK
         final String modelName = monitorDeviceCache.getDeviceModel(deviceId);
         final String modelName = monitorDeviceCache.getDeviceModel(deviceId);
         if (StrUtil.isNotBlank(modelName)) {
         if (StrUtil.isNotBlank(modelName)) {
             AbsRenkeMonitorDataProcessor monitorDataProcessor = (AbsRenkeMonitorDataProcessor) monitorDataProcessorMap.get(modelName);
             AbsRenkeMonitorDataProcessor monitorDataProcessor = (AbsRenkeMonitorDataProcessor) monitorDataProcessorMap.get(modelName);
-            monitorDataProcessor.processData(data);
+            monitorDataProcessor.processData(renKeColdChainMessageData);
         }
         }
-         /*data.getNodeList().forEach(nodeData -> {
-            SensorData sensorData = new SensorData();
-            // 如果记录时间为空,使用当前时间
-            if (nodeData.getRecordTime() == null) {
-                Instant defaultTime = Instant.now();
-                sensorData.setTime(defaultTime);
-            } else {
-                sensorData.setTime(nodeData.getRecordTime().toInstant());
-            }
-            //设置模型型号
-            sensorData.setModelName(modelName);
-            // 只处理有效数据:温度和湿度不为0
-            if (nodeData.getTem() != 0.0 || nodeData.getHum() != 0.0) {
-                log.info("记录ID: {}, 记录时间: {}, 温度: {}, 湿度: {}", deviceId + " : " + nodeData.getNodeId(), nodeData.getRecordTime(), nodeData.getTem(), nodeData.getHum());
-                sensorData.setTemperature(nodeData.getTem());
-                sensorData.setHumidity(nodeData.getHum());
-                sensorData.setLat(nodeData.getLat());
-                sensorData.setLng(nodeData.getLng());
-                sensorData.setDeviceId(deviceId);
-                sensorData.putTag("name", "周小杰");
-
-                writeData(sensorData);
-            }
-        });*/
+        return Boolean.TRUE;
+    }
 
 
+    @Override
+    public void login(RenKeColdChainMessageData data) {
+        processMonitorData(data, "login");
+    }
 
 
-        return Boolean.TRUE;
+    @Override
+    public void heartbeat(RenKeColdChainMessageData data) {
+        processMonitorData(data, "heartbeat");
+    }
+    // 公共的处理方法
+    private void processMonitorData(RenKeColdChainMessageData data, String action) {
+        if (!monitorDataProcessorMap.isEmpty()) {
+            AbsRenkeMonitorDataProcessor monitorDataProcessor = (AbsRenkeMonitorDataProcessor) monitorDataProcessorMap.get(0);
+            if (monitorDataProcessor != null) {
+                // 根据 action 调用相应的方法
+                switch (action) {
+                    case "login":
+                        monitorDataProcessor.login(data);
+                        break;
+                    case "heartbeat":
+                        monitorDataProcessor.heartbeat(data);
+                        break;
+                    default:
+                        log.error("Unsupported action: {}", action);
+                        break;
+                }
+            } else {
+                log.error("No valid processor found.");
+            }
+        } else {
+            log.warn("Monitor data processor map is empty.");
+        }
     }
     }
 
 
-    /**
-     * 异步将处理后的数据写入 InfluxDB
-     *
-     * @param sensorData 传感器数据
-     */
-//    public void writeData(SensorData sensorData) {
-//        eventPublisher.publishEvent(new SensorDataEvent(this, sensorData));
-//    }
 }
 }

+ 5 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/model/ColdChainMessageData.java

@@ -1,5 +1,6 @@
 package vip.xiaonuo.coldchain.core.service.dataprocess.model;
 package vip.xiaonuo.coldchain.core.service.dataprocess.model;
 
 
+import java.io.Serializable;
 import java.time.LocalDateTime;
 import java.time.LocalDateTime;
 
 
 /**
 /**
@@ -10,8 +11,12 @@ import java.time.LocalDateTime;
  * @date 2024/11/12 13:00:25
  * @date 2024/11/12 13:00:25
  */
  */
 public interface ColdChainMessageData extends java.io.Serializable {
 public interface ColdChainMessageData extends java.io.Serializable {
+
+
     // 默认的时间字段,返回当前时间
     // 默认的时间字段,返回当前时间
     default LocalDateTime getTimestamp() {
     default LocalDateTime getTimestamp() {
         return LocalDateTime.now();
         return LocalDateTime.now();
     }
     }
+
+    Serializable getDeviceId();
 }
 }

+ 1 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/model/HaierColdChainMessageData.java

@@ -11,4 +11,5 @@ import lombok.Data;
  */
  */
 @Data
 @Data
 public class HaierColdChainMessageData implements ColdChainMessageData {
 public class HaierColdChainMessageData implements ColdChainMessageData {
+    private String deviceId;
 }
 }

+ 1 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/model/RenKeColdChainMessageData.java

@@ -12,5 +12,6 @@ import rk.netDevice.sdk.p2.RealTimeData;
  */
  */
 @Data
 @Data
 public class RenKeColdChainMessageData implements ColdChainMessageData {
 public class RenKeColdChainMessageData implements ColdChainMessageData {
+    private Integer deviceId;
     private RealTimeData realTimeData;
     private RealTimeData realTimeData;
 }
 }

+ 32 - 6
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/app/param/AppDevice.java

@@ -15,6 +15,7 @@ import lombok.NoArgsConstructor;
 import java.time.LocalDateTime;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatter;
 import java.time.temporal.ChronoUnit;
 import java.time.temporal.ChronoUnit;
+import java.util.List;
 import java.util.Locale;
 import java.util.Locale;
 
 
 @Data
 @Data
@@ -22,10 +23,38 @@ import java.util.Locale;
 @NoArgsConstructor
 @NoArgsConstructor
 public class AppDevice {
 public class AppDevice {
     private String deviceName;
     private String deviceName;
+    private String deviceCode;
+    /**
+     * 电池电量 (%)
+     */
     private double batteryPercentage;
     private double batteryPercentage;
-    private double temperature;
-    private LocalDateTime lastUpdated; // 使用 LocalDateTime 存储日期时间
-    private int batteryHealthPercentage;
+    /**
+     * 最近更新时间
+     */
+    private LocalDateTime lastUpdated;
+
+    /**
+     * 是否插电
+     *
+     * @return
+     */
+    private boolean plugIn = false;
+
+    /**
+     * 上次一次登录时间
+     *
+     * @return
+     */
+    private LocalDateTime lastLoginTime;
+
+    /**
+     * 关键的设备探头
+     *
+     * @return
+     */
+
+    private List<AppDeviceData> children;
+
 
 
     // 格式化 lastUpdated 的显示方法
     // 格式化 lastUpdated 的显示方法
     public String getFormattedLastUpdated() {
     public String getFormattedLastUpdated() {
@@ -33,13 +62,10 @@ public class AppDevice {
         if (lastUpdated == null) {
         if (lastUpdated == null) {
             return "暂不可用";  // 可以返回适当的默认值
             return "暂不可用";  // 可以返回适当的默认值
         }
         }
-
         // 获取当前时间
         // 获取当前时间
         LocalDateTime now = LocalDateTime.now();
         LocalDateTime now = LocalDateTime.now();
-
         // 计算两个日期的差值(以天为单位)
         // 计算两个日期的差值(以天为单位)
         long daysDiff = ChronoUnit.DAYS.between(lastUpdated, now);
         long daysDiff = ChronoUnit.DAYS.between(lastUpdated, now);
-
         // 如果日期在 7 天之内,显示中文星期几
         // 如果日期在 7 天之内,显示中文星期几
         if (daysDiff <= 7) {
         if (daysDiff <= 7) {
             // 使用 Locale.CHINESE 进行格式化,显示中文星期几
             // 使用 Locale.CHINESE 进行格式化,显示中文星期几

+ 18 - 5
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/app/param/AppDeviceData.java

@@ -8,21 +8,34 @@ package vip.xiaonuo.coldchain.modular.app.param;
  * @date 2024/11/17 22:39:49
  * @date 2024/11/17 22:39:49
  */
  */
 
 
-import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.Data;
-import lombok.NoArgsConstructor;
 
 
 import java.time.LocalDateTime;
 import java.time.LocalDateTime;
 
 
 @Data
 @Data
-@AllArgsConstructor
-@NoArgsConstructor
 public class AppDeviceData {
 public class AppDeviceData {
     private String deviceCode;          // 设备唯一标识符
     private String deviceCode;          // 设备唯一标识符
+    private String deviceName;          // 设备名称
     private LocalDateTime timestamp;    // 数据记录的时间
     private LocalDateTime timestamp;    // 数据记录的时间
     private Double temperature;         // 设备温度 (℃)
     private Double temperature;         // 设备温度 (℃)
     private Double humidity;            // 设备湿度 (%)
     private Double humidity;            // 设备湿度 (%)
     private Double co2Level;            // 二氧化碳浓度 (ppm)
     private Double co2Level;            // 二氧化碳浓度 (ppm)
     private Double batteryPercentage;   // 电池电量 (%)
     private Double batteryPercentage;   // 电池电量 (%)
-    private String deviceName;          // 设备名称
+    /**
+     * 路数,默认路数1
+     */
+    private Integer roads = 1;
+
+    public AppDeviceData() {
+    }
+
+    public AppDeviceData(String deviceCode, LocalDateTime timestamp, Double temperature, Double humidity, Double co2Level, Double batteryPercentage, String deviceName) {
+        this.deviceCode = deviceCode;
+        this.timestamp = timestamp;
+        this.temperature = temperature;
+        this.humidity = humidity;
+        this.co2Level = co2Level;
+        this.batteryPercentage = batteryPercentage;
+        this.deviceName = deviceName;
+    }
 }
 }

+ 3 - 3
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/app/service/AppDeviceService.java

@@ -24,9 +24,9 @@ public class AppDeviceService {
     public List<AppDevice> getAllDevices() {
     public List<AppDevice> getAllDevices() {
         List<AppDevice> appDevices = new ArrayList<>();
         List<AppDevice> appDevices = new ArrayList<>();
         // 示例设备数据
         // 示例设备数据
-        appDevices.add(new AppDevice("Device A", 80.5, 31.4, LocalDateTime.now().minusDays(1), 75)); // 1天前
-        appDevices.add(new AppDevice("Device B", 90.2, 25.0, LocalDateTime.now().minusDays(5), 85)); // 5天前
-        appDevices.add(new AppDevice("Device C", 65.75, 28.5, LocalDateTime.now().minusDays(10), 70)); // 10天前
+//        appDevices.add(new AppDevice("Device A", 80.5, 31.4, LocalDateTime.now().minusDays(1), 75)); // 1天前
+//        appDevices.add(new AppDevice("Device B", 90.2, 25.0, LocalDateTime.now().minusDays(5), 85)); // 5天前
+//        appDevices.add(new AppDevice("Device C", 65.75, 28.5, LocalDateTime.now().minusDays(10), 70)); // 10天前
         return appDevices;
         return appDevices;
     }
     }
 
 

+ 5 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/monitordevice/service/MonitorDeviceService.java

@@ -22,6 +22,7 @@ import vip.xiaonuo.coldchain.modular.monitordevice.param.MonitorDeviceEditParam;
 import vip.xiaonuo.coldchain.modular.monitordevice.param.MonitorDeviceIdParam;
 import vip.xiaonuo.coldchain.modular.monitordevice.param.MonitorDeviceIdParam;
 import vip.xiaonuo.coldchain.modular.monitordevice.param.MonitorDevicePageParam;
 import vip.xiaonuo.coldchain.modular.monitordevice.param.MonitorDevicePageParam;
 
 
+import java.util.Date;
 import java.util.List;
 import java.util.List;
 
 
 /**
 /**
@@ -84,4 +85,8 @@ public interface MonitorDeviceService extends IService<MonitorDevice> {
 
 
 
 
     boolean updateParameters(ParamData data);
     boolean updateParameters(ParamData data);
+
+    boolean updateLastHeartbeatTimeByDeviceId(Integer deviceId, Date timestamp);
+
+    boolean updateLastLoginTimeByDeviceId(Integer deviceId, Date timestamp);
 }
 }

+ 39 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/monitordevice/service/impl/MonitorDeviceServiceImpl.java

@@ -21,6 +21,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.annotation.Transactional;
 import rk.netDevice.sdk.p2.ParamData;
 import rk.netDevice.sdk.p2.ParamData;
@@ -38,6 +39,7 @@ import vip.xiaonuo.common.enums.CommonSortOrderEnum;
 import vip.xiaonuo.common.exception.CommonException;
 import vip.xiaonuo.common.exception.CommonException;
 import vip.xiaonuo.common.page.CommonPageRequest;
 import vip.xiaonuo.common.page.CommonPageRequest;
 
 
+import java.util.Date;
 import java.util.List;
 import java.util.List;
 
 
 /**
 /**
@@ -48,6 +50,7 @@ import java.util.List;
  **/
  **/
 @Service
 @Service
 @RequiredArgsConstructor
 @RequiredArgsConstructor
+@Slf4j
 public class MonitorDeviceServiceImpl extends ServiceImpl<MonitorDeviceMapper, MonitorDevice> implements MonitorDeviceService {
 public class MonitorDeviceServiceImpl extends ServiceImpl<MonitorDeviceMapper, MonitorDevice> implements MonitorDeviceService {
     private final RenKeService renKeService;
     private final RenKeService renKeService;
     private final MonitorDeviceCache monitorDeviceCache;
     private final MonitorDeviceCache monitorDeviceCache;
@@ -157,4 +160,40 @@ public class MonitorDeviceServiceImpl extends ServiceImpl<MonitorDeviceMapper, M
         }
         }
         return this.updateById(device);
         return this.updateById(device);
     }
     }
+
+    @Override
+    public boolean updateLastHeartbeatTimeByDeviceId(Integer deviceId, Date timestamp) {
+        return updateDeviceTimeByDeviceId(deviceId, timestamp, "lastHeartbeatTime");
+    }
+
+    @Override
+    public boolean updateLastLoginTimeByDeviceId(Integer deviceId, Date timestamp) {
+        return updateDeviceTimeByDeviceId(deviceId, timestamp, "lastLoginTime");
+    }
+
+    // 通用更新方法,避免代码重复,并处理 timestamp 为空的情况
+    private boolean updateDeviceTimeByDeviceId(Integer deviceId, Date timestamp, String timeField) {
+        if (timestamp == null) {
+            // 如果 timestamp 为空,使用当前系统时间
+            timestamp = new Date();  // 或者 new Date(System.currentTimeMillis());
+        }
+        MonitorDevice device = this.getOne(new QueryWrapper<MonitorDevice>().eq("device_code", deviceId));
+        if (device == null) {
+            // 设备未找到,记录日志
+            log.warn("Device with deviceId {} not found", deviceId);
+            return false;
+        }
+        // 根据传入的字段名动态设置时间
+        if ("lastHeartbeatTime".equals(timeField)) {
+            device.setLastHeartbeatTime(timestamp);
+        } else if ("lastLoginTime".equals(timeField)) {
+            device.setLastLoginTime(timestamp);
+        } else {
+            log.error("Invalid time field: {}", timeField);
+            return false;
+        }
+        // 更新设备信息
+        return this.updateById(device);
+    }
+
 }
 }

+ 5 - 0
snowy-plugin/snowy-plugin-sys/src/main/java/vip/xiaonuo/sys/modular/user/provider/SysLoginUserApiProvider.java

@@ -168,4 +168,9 @@ public class SysLoginUserApiProvider implements SaBaseLoginUserApi {
     public void updateUserLoginInfo(String userId, String device) {
     public void updateUserLoginInfo(String userId, String device) {
         sysUserService.updateUserLoginInfo(userId, device);
         sysUserService.updateUserLoginInfo(userId, device);
     }
     }
+
+    @Override
+    public boolean updateUserOpenId(String account, String openId) {
+        return sysUserService.updateUserOpenId(account, openId);
+    }
 }
 }

+ 2 - 0
snowy-plugin/snowy-plugin-sys/src/main/java/vip/xiaonuo/sys/modular/user/service/SysUserService.java

@@ -480,4 +480,6 @@ public interface SysUserService extends IService<SysUser> {
      * @date 2023/6/25 11:03
      * @date 2023/6/25 11:03
      **/
      **/
     List<SysRole> getRoleListByIdList(SysUserIdListParam sysUserIdListParam);
     List<SysRole> getRoleListByIdList(SysUserIdListParam sysUserIdListParam);
+
+    boolean updateUserOpenId(String account, String openId);
 }
 }

+ 10 - 0
snowy-plugin/snowy-plugin-sys/src/main/java/vip/xiaonuo/sys/modular/user/service/impl/SysUserServiceImpl.java

@@ -1576,4 +1576,14 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
                 .in(SysRole::getId, sysUserIdListParam.getIdList()).orderByAsc(SysRole::getSortCode);
                 .in(SysRole::getId, sysUserIdListParam.getIdList()).orderByAsc(SysRole::getSortCode);
         return sysRoleService.list(lambdaQueryWrapper);
         return sysRoleService.list(lambdaQueryWrapper);
     }
     }
+
+    @Override
+    public boolean updateUserOpenId(String account, String openId) {
+        SysUser sysUser = this.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getAccount, account));
+        if (ObjectUtil.isNotEmpty(sysUser) && StrUtil.isNotBlank(openId)) {
+            sysUser.setOpenId(openId);
+            return this.updateById(sysUser);
+        }
+        return false;
+    }
 }
 }

+ 1 - 0
snowy-web-app/src/main/java/vip/xiaonuo/core/config/GlobalConfigure.java

@@ -124,6 +124,7 @@ public class GlobalConfigure implements WebMvcConfigurer {
             "/auth/b/getPicCaptcha",
             "/auth/b/getPicCaptcha",
             "/auth/b/getPhoneValidCode",
             "/auth/b/getPhoneValidCode",
             "/auth/b/doLogin",
             "/auth/b/doLogin",
+            "/auth/mini/doLogin",
             "/auth/b/doLoginByPhone",
             "/auth/b/doLoginByPhone",
 
 
             /* 三方登录相关 */
             /* 三方登录相关 */

+ 13 - 4
snowy-web-app/src/main/java/vip/xiaonuo/weixin/miniapp/controller/WxMaUserController.java

@@ -5,16 +5,18 @@ import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
 import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
 import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
 import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
 import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
 import cn.binarywang.wx.miniapp.util.WxMaConfigHolder;
 import cn.binarywang.wx.miniapp.util.WxMaConfigHolder;
+import io.swagger.v3.oas.annotations.Operation;
 import jakarta.annotation.Resource;
 import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
 import lombok.AllArgsConstructor;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import me.chanjar.weixin.common.error.WxErrorException;
 import me.chanjar.weixin.common.error.WxErrorException;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
+import vip.xiaonuo.auth.core.enums.SaClientTypeEnum;
+import vip.xiaonuo.auth.modular.login.param.AuthAccountPasswordLoginParam;
 import vip.xiaonuo.auth.modular.login.service.AuthService;
 import vip.xiaonuo.auth.modular.login.service.AuthService;
+import vip.xiaonuo.common.pojo.CommonResult;
 import vip.xiaonuo.sys.modular.user.result.SysLoginUser;
 import vip.xiaonuo.sys.modular.user.result.SysLoginUser;
 import vip.xiaonuo.sys.modular.user.service.SysUserService;
 import vip.xiaonuo.sys.modular.user.service.SysUserService;
 import vip.xiaonuo.weixin.miniapp.model.JfcloudWxMaJscode2SessionResult;
 import vip.xiaonuo.weixin.miniapp.model.JfcloudWxMaJscode2SessionResult;
@@ -73,6 +75,13 @@ public class WxMaUserController {
         }
         }
     }
     }
 
 
+    @Operation(summary = "小程序密码登录")
+    @PostMapping("/mini/login")
+    public CommonResult<String> doMiniLogin(@RequestBody @Valid AuthAccountPasswordLoginParam authAccountPasswordLoginParam) {
+        return CommonResult.data(authService.doMiniLogin(authAccountPasswordLoginParam, SaClientTypeEnum.B.getValue()));
+    }
+
+
     /**
     /**
      * <pre>
      * <pre>
      * 获取用户信息接口
      * 获取用户信息接口