Kaynağa Gözat

老项目迁移

chejianzheng 4 ay önce
ebeveyn
işleme
24954687ca
72 değiştirilmiş dosya ile 2932 ekleme ve 111 silme
  1. 14 0
      pom.xml
  2. 11 4
      portal-service-application/src/main/java/com/hfln/portal/application/controller/TestController.java
  3. 28 10
      portal-service-application/src/main/java/com/hfln/portal/application/controller/wap/DeviceController.java
  4. 80 0
      portal-service-application/src/main/java/com/hfln/portal/application/controller/wap/RadarController.java
  5. 53 0
      portal-service-application/src/main/java/com/hfln/portal/application/controller/wap/RoomController.java
  6. 53 0
      portal-service-application/src/main/java/com/hfln/portal/application/controller/wap/ShareController.java
  7. 45 26
      portal-service-application/src/main/java/com/hfln/portal/application/controller/wap/UserController.java
  8. 45 0
      portal-service-application/src/main/java/com/hfln/portal/application/controller/wap/WechatController.java
  9. 16 0
      portal-service-common/src/main/java/com/hfln/portal/common/constant/mqtt/topic/TopicConstants.java
  10. 27 0
      portal-service-common/src/main/java/com/hfln/portal/common/dto/data/event/AlarmEventDTO.java
  11. 3 3
      portal-service-common/src/main/java/com/hfln/portal/common/dto/data/home/HomeInfoDTO.java
  12. 41 0
      portal-service-common/src/main/java/com/hfln/portal/common/dto/data/oss/OssFileDTO.java
  13. 36 0
      portal-service-common/src/main/java/com/hfln/portal/common/dto/data/room/RegionInfo.java
  14. 44 0
      portal-service-common/src/main/java/com/hfln/portal/common/dto/data/room/RoomDto.java
  15. 57 0
      portal-service-common/src/main/java/com/hfln/portal/common/dto/data/share/ShareDto.java
  16. 44 0
      portal-service-common/src/main/java/com/hfln/portal/common/request/share/ShareConfirmParam.java
  17. 46 0
      portal-service-common/src/main/java/com/hfln/portal/common/request/share/ShareParam.java
  18. 29 0
      portal-service-common/src/main/java/com/hfln/portal/common/request/user/PhoneLoginParams.java
  19. 4 0
      portal-service-common/src/main/java/com/hfln/portal/common/request/user/UserSignupParams.java
  20. 21 0
      portal-service-common/src/main/java/com/hfln/portal/common/response/device/WcTimesQueryRes.java
  21. 1 0
      portal-service-common/src/main/java/com/hfln/portal/common/response/package-info.java
  22. 23 0
      portal-service-common/src/main/java/com/hfln/portal/common/response/user/UserInfoWxRes.java
  23. 4 0
      portal-service-domain/pom.xml
  24. 38 0
      portal-service-domain/src/main/java/com/hfln/portal/domain/customer/OssBusiType.java
  25. 32 0
      portal-service-domain/src/main/java/com/hfln/portal/domain/customer/util/DevPosFixUtil.java
  26. 136 0
      portal-service-domain/src/main/java/com/hfln/portal/domain/customer/util/WxOfficeAccountClient.java
  27. 23 0
      portal-service-domain/src/main/java/com/hfln/portal/domain/exception/ErrorEnum.java
  28. 55 0
      portal-service-domain/src/main/java/com/hfln/portal/domain/gateway/DeviceGateway.java
  29. 11 4
      portal-service-domain/src/main/java/com/hfln/portal/domain/gateway/UserGateway.java
  30. 15 0
      portal-service-infrastructure/pom.xml
  31. 107 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/config/PushMsgWebSocket.java
  32. 16 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/config/WebSocketConfig.java
  33. 397 10
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/gateway/impl/DeviceGatewayImpl.java
  34. 108 14
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/gateway/impl/UserGatewayImpl.java
  35. 168 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/job/ScheduledTask.java
  36. 9 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/mapper/AlarmEventMapper.java
  37. 12 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/mapper/TblOssFileMapper.java
  38. 9 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/mapper/WxRelationMapper.java
  39. 377 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/mqtt/MqttSubHandle.java
  40. 108 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/oss/OssClient.java
  41. 38 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/oss/OssUtils.java
  42. 36 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/po/AlarmEvent.java
  43. 9 2
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/po/BasePO.java
  44. 5 5
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/po/DevInfo.java
  45. 13 6
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/po/DevRoom.java
  46. 5 4
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/po/DevShare.java
  47. 10 4
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/po/DevTarget.java
  48. 8 6
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/po/EventList.java
  49. 4 4
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/po/GroupDevMap.java
  50. 48 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/po/TblOssFile.java
  51. 6 1
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/po/UserInfo.java
  52. 36 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/po/WxRelation.java
  53. 9 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/AlarmEventService.java
  54. 3 1
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/DevInfoService.java
  55. 12 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/DevRoomService.java
  56. 8 1
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/DevShareService.java
  57. 9 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/DevTargetService.java
  58. 12 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/GroupDevMapService.java
  59. 15 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/OssFileService.java
  60. 11 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/UserService.java
  61. 12 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/WxRelationService.java
  62. 18 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/impl/AlarmEventServiceImpl.java
  63. 10 3
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/impl/DevInfoServiceImpl.java
  64. 55 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/impl/DevRoomServiceImpl.java
  65. 46 3
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/impl/DevShareServiceImpl.java
  66. 13 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/impl/DevTargetServiceImpl.java
  67. 22 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/impl/GroupDevMapServiceImpl.java
  68. 40 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/impl/OssFileServiceImpl.java
  69. 23 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/impl/UserServiceImpl.java
  70. 29 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/impl/WxRelationServiceImpl.java
  71. 18 0
      portal-service-server/src/main/resources/bootstrap-dev.yml
  72. 3 0
      portal-service-server/src/main/resources/bootstrap-prod.yml

+ 14 - 0
pom.xml

@@ -172,6 +172,20 @@
                 <version>1.0.0-SNAPSHOT</version>
             </dependency>
 
+            <!-- oss 存储 -->
+            <dependency>
+                <groupId>com.aliyun.oss</groupId>
+                <artifactId>aliyun-sdk-oss</artifactId>
+                <version>3.17.4</version>
+            </dependency>
+
+            <!-- 微信 -->
+            <dependency>
+                <groupId>com.github.binarywang</groupId>
+                <artifactId>weixin-java-mp</artifactId>
+                <version>4.5.0</version>
+            </dependency>
+
         </dependencies>
     </dependencyManagement>
 

+ 11 - 4
portal-service-application/src/main/java/com/hfln/portal/application/controller/TestController.java

@@ -3,21 +3,25 @@ package com.hfln.portal.application.controller;
 
 import cn.hfln.framework.catchlog.CatchAndLog;
 import cn.hfln.framework.dto.ApiResult;
+import cn.hfln.framework.mqtt.annotation.MqttSubscribe;
+import cn.hfln.framework.mqtt.template.MqttTemplate;
 import com.hfln.portal.infrastructure.service.UserService;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RestController;
 
 @RestController
 @CatchAndLog
+@Slf4j
 public class TestController {
     
 
     @Autowired
     private UserService userService;
 
-//    @Autowired
-//    private MqttPublisher mqttPublisher;
+    @Autowired
+    private MqttTemplate mqttPublisher;
 
     @GetMapping("/demo")
     public ApiResult<Boolean> get() {
@@ -27,12 +31,15 @@ public class TestController {
 //        userInfo.setGender(1);
 //        userInfo.setOpenid("wasdasd2212sada");
 //        userService.save(userInfo);
-//        mqttPublisher.send("test","asdasdsada");
+        mqttPublisher.send("test","asdasdsada");
 //        if (-1<0){
 //            throw new BizException(ErrorEnum.ERROR_BIZ_FAIL.getErrorCode(),ErrorEnum.ERROR_BIZ_FAIL.getErrorMessage());
 //        }
         return ApiResult.success(userService.checkOpenId("123456"));
     }
     
-    
+    @MqttSubscribe(topic = "test")
+    public void test(String topic , String payload){
+        log.info("topic :{},message:{}",topic,payload);
+    }
 }

+ 28 - 10
portal-service-application/src/main/java/com/hfln/portal/application/controller/wap/DeviceController.java

@@ -6,6 +6,7 @@ import com.hfln.portal.common.dto.data.device.DeviceDTO;
 import com.hfln.portal.common.request.device.DeviceBandingParams;
 import com.hfln.portal.common.request.device.DeviceListParams;
 import com.hfln.portal.common.request.device.DeviceLocationParams;
+import com.hfln.portal.common.response.device.WcTimesQueryRes;
 import com.hfln.portal.domain.gateway.DeviceGateway;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -16,7 +17,7 @@ import org.springframework.web.bind.annotation.*;
 import javax.validation.Valid;
 import java.util.List;
 
-@RestController
+@RestController("/wap/device")
 @CatchAndLog
 @Api(tags = "设备相关")
 @Slf4j
@@ -24,53 +25,70 @@ public class DeviceController {
     @Autowired
     private DeviceGateway deviceGateway;
 
-    @PostMapping("wap/device/deviceList")
-    @ApiOperation(value = "获取个人首页信息")
+
+//    @Autowired
+//    private MqttTemplate
+
+    @PostMapping("/deviceList")
+    @ApiOperation(value = "查询设备列表")
     public ApiResult<List<DeviceDTO>> deviceList(@RequestBody @Valid DeviceListParams request) {
         return ApiResult.success(deviceGateway.queryDeviceList(request));
     }
 
 
-    @GetMapping("/wap/device/deviceUnBind")
+    @GetMapping("/deviceUnBind")
     @ApiOperation(value = "解绑设备")
     public ApiResult<Boolean> deviceUnBind(@RequestParam("userId") Long userId, @RequestParam("deviceId") String deviceId) {
         return ApiResult.success(deviceGateway.deviceUnBind(userId, deviceId));
     }
 
-    @PostMapping("/wap/device/deviceBinding")
+    @PostMapping("/deviceBinding")
     @ApiOperation(value = "绑定设备")
     public ApiResult<Boolean> deviceBinding(@RequestBody @Valid DeviceBandingParams request) {
         return ApiResult.success(deviceGateway.deviceBind(request));
     }
 
 
-    @GetMapping("/wap/device/queryDeviceInfoById/{deviceId}")
+    @GetMapping("/queryDeviceInfoById/{deviceId}")
     @ApiOperation(value = "设备详情")
     public ApiResult<DeviceDTO> queryDeviceInfoById(@PathVariable("deviceId") String deviceId) {
         return ApiResult.success(deviceGateway.queryDeviceById(deviceId));
     }
 
-    @GetMapping("/wap/device/deviceRelations")
+    @GetMapping("/deviceRelations")
     @ApiOperation(value = "设备关系")
-    // todo
+    // todo web网页端接口,后续待定
     public ApiResult<DeviceDTO> deviceRelations() {
         return ApiResult.success();
     }
 
 
-    @PostMapping("/wap/device/updateDevice")
+    @PostMapping("/updateDevice")
     @ApiOperation(value = "设备信息修改")
     public ApiResult<Boolean> updateDevice(@RequestBody @Valid DeviceBandingParams request) {
         return ApiResult.success(deviceGateway.updateDevice(request));
     }
 
 
-    @GetMapping("/wap/device/updateDeviceLocation")
+    @GetMapping("/updateDeviceLocation")
     @ApiOperation(value = "更新设备位置")
     public ApiResult<Boolean> updateDeviceLocation(@RequestBody @Valid DeviceLocationParams params) {
         return ApiResult.success(deviceGateway.updateDeviceLocation(params));
     }
 
 
+    @GetMapping("/checkDevByUserId")
+    @ApiOperation(value = "检测用户是否拥有设备")
+    public ApiResult<Boolean> checkDevByUserId(@RequestParam("userId") Long userId, @RequestParam("devId") Long devId) {
+
+        deviceGateway.checkDevByUserId(userId, devId);
+        return ApiResult.success(true);
+    }
+
+    @GetMapping("/getWcTimes")
+    @ApiOperation(value = "查询前一天上厕所次数")
+    public ApiResult<WcTimesQueryRes> getWcTimes(@RequestParam("devId") Long devId, @RequestParam("time") String time) {
 
+        return ApiResult.success(deviceGateway.getWcTimes(devId, time));
+    }
 }

+ 80 - 0
portal-service-application/src/main/java/com/hfln/portal/application/controller/wap/RadarController.java

@@ -0,0 +1,80 @@
+package com.hfln.portal.application.controller.wap;
+
+
+import cn.hfln.framework.catchlog.CatchAndLog;
+import cn.hfln.framework.dto.ApiResult;
+import com.hfln.portal.common.dto.data.room.RoomDto;
+import com.hfln.portal.domain.gateway.DeviceGateway;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController("/wap/radar")
+@CatchAndLog
+@Api(tags = "雷达相关")
+@Slf4j
+public class RadarController {
+
+
+    @Autowired
+    private DeviceGateway deviceGateway;
+
+
+    @GetMapping("/getVersion")
+    @ApiOperation(value = "检查更新/获取版本")
+    public ApiResult<RoomDto> getVersion(@RequestParam String clientId) {
+
+        deviceGateway.getVersion(clientId);
+        return ApiResult.success();
+    }
+
+    @GetMapping("/reboot")
+    @ApiOperation(value = "设备软重启")
+    public ApiResult<Void> reboot(@RequestParam String clientId) {
+        deviceGateway.reboot(clientId);
+        return ApiResult.success();
+    }
+
+    @GetMapping("/updateOTA")
+    @ApiOperation(value = "OTA升级")
+    public ApiResult<Void> updateOTA(@RequestParam String clientId) {
+
+        deviceGateway.updateOTA(clientId);
+        return ApiResult.success();
+    }
+
+    @GetMapping("/fixPost")
+    @ApiOperation(value = "姿态修正")
+    public ApiResult<Void> fixPost(@RequestParam String clientId, @RequestParam int poseIndex) {
+
+        deviceGateway.fixPost(clientId, poseIndex);
+        return ApiResult.success();
+    }
+
+    @GetMapping("/stopFixPost")
+    @ApiOperation(value = "停止姿态修正")
+    public ApiResult<Void> stopFixPost(@RequestParam String clientId) {
+
+        deviceGateway.stopFixPost(clientId);
+        return ApiResult.success();
+    }
+
+
+    @GetMapping("/getInfo")
+    @ApiOperation(value = "获取设备信息")
+    public ApiResult<Void> getInfo(@RequestParam String clientId) {
+        deviceGateway.getInfo(clientId);
+        return ApiResult.success();
+    }
+
+    @GetMapping("/getParam")
+    @ApiOperation(value = "获取设备参数")
+    public ApiResult<Void> getParam(@RequestParam String clientId) {
+        deviceGateway.getParam(clientId);
+        return ApiResult.success();
+    }
+}

+ 53 - 0
portal-service-application/src/main/java/com/hfln/portal/application/controller/wap/RoomController.java

@@ -0,0 +1,53 @@
+package com.hfln.portal.application.controller.wap;
+
+
+import cn.hfln.framework.catchlog.CatchAndLog;
+import cn.hfln.framework.dto.ApiResult;
+import com.hfln.portal.common.dto.data.room.RoomDto;
+import com.hfln.portal.domain.gateway.DeviceGateway;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.validation.Valid;
+import java.io.IOException;
+
+@RestController("/wap/room")
+@CatchAndLog
+@Api(tags = "房间相关")
+@Slf4j
+public class RoomController {
+
+    @Autowired
+    private DeviceGateway deviceGateway;
+
+    @GetMapping("/readRoom")
+    @ApiOperation(value = "读取房间信息")
+    public ApiResult<RoomDto> readRoom(@RequestParam Long devId) {
+        return ApiResult.success(deviceGateway.readRoom(devId));
+    }
+
+    @PostMapping("/saveRoom")
+    @ApiOperation(value = "房间布局保存")
+    public ApiResult<Boolean> saveRoom(@Valid @RequestBody  RoomDto roomDto) {
+        return ApiResult.success(deviceGateway.saveRoom(roomDto));
+    }
+
+    @PostMapping("/uploadFloorPlan")
+    @ApiOperation(value = "上传户型图")
+    public ApiResult<Void> uploadFloorPlan(@Valid @RequestParam MultipartFile file, @RequestParam String groupUuid) throws IOException {
+
+
+        deviceGateway.uploadFloorPlan(file, groupUuid);
+        return ApiResult.success();
+    }
+
+    @GetMapping("/getFloorPlan")
+    @ApiOperation(value = "获取户型图")
+    public ApiResult<String> getFloorPlan(@Valid @RequestParam String groupUuid) {
+        return ApiResult.success(deviceGateway.getFloorPlan(groupUuid));
+    }
+}

+ 53 - 0
portal-service-application/src/main/java/com/hfln/portal/application/controller/wap/ShareController.java

@@ -0,0 +1,53 @@
+package com.hfln.portal.application.controller.wap;
+
+
+import cn.hfln.framework.catchlog.CatchAndLog;
+import cn.hfln.framework.dto.ApiResult;
+import com.hfln.portal.common.dto.data.share.ShareDto;
+import com.hfln.portal.common.request.share.ShareConfirmParam;
+import com.hfln.portal.common.request.share.ShareParam;
+import com.hfln.portal.domain.gateway.DeviceGateway;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.List;
+
+@RestController("/wap/share")
+@CatchAndLog
+@Api(tags = "设备分享")
+@Slf4j
+public class ShareController {
+
+    @Autowired
+    private DeviceGateway deviceGateway;
+
+    @PostMapping("/devShare")
+    @ApiOperation(value = "个人分享设备")
+    public ApiResult<Boolean> devShare(@Valid @RequestBody ShareParam shareParam) {
+        return ApiResult.success(deviceGateway.devShare(shareParam));
+    }
+
+    @GetMapping("/shareByUrl")
+    @ApiOperation(value = "通过链接分享设备")
+    public ApiResult<Void> shareByUrl(@Valid @RequestBody ShareParam shareParam) {
+        deviceGateway.shareByUrl(shareParam);
+        return ApiResult.success();
+    }
+
+    @GetMapping("/devShare")
+    @ApiOperation(value = "查看设备分享记录")
+    public ApiResult<List<ShareDto>> queryShare(@Valid @RequestParam Long userId) {
+        return ApiResult.success(deviceGateway.queryShare(userId));
+    }
+
+    @GetMapping("/shareConfirm")
+    @ApiOperation(value = "设备分享确认")
+    public ApiResult<Void> shareConfirm(@Valid @RequestBody ShareConfirmParam shareConfirmParam) {
+        deviceGateway.shareConfirm(shareConfirmParam);
+        return ApiResult.success();
+    }
+}

+ 45 - 26
portal-service-application/src/main/java/com/hfln/portal/application/controller/wap/UserController.java

@@ -3,10 +3,8 @@ package com.hfln.portal.application.controller.wap;
 import cn.hfln.framework.catchlog.CatchAndLog;
 import cn.hfln.framework.dto.ApiResult;
 import com.hfln.portal.common.dto.data.user.UserDto;
-import com.hfln.portal.common.request.user.LoginBySmsCodeParams;
-import com.hfln.portal.common.request.user.UserLoginParams;
-import com.hfln.portal.common.request.user.UserSignupParams;
-import com.hfln.portal.common.request.user.UserUpdatePasswordParams;
+import com.hfln.portal.common.request.user.*;
+import com.hfln.portal.common.response.user.UserInfoWxRes;
 import com.hfln.portal.domain.gateway.UserGateway;
 import com.hfln.portal.domain.gateway.sms.SmsGateway;
 import io.swagger.annotations.Api;
@@ -20,7 +18,7 @@ import javax.validation.Valid;
 import java.util.HashMap;
 import java.util.Map;
 
-@RestController
+@RestController("/wap/user")
 @CatchAndLog
 @Api(tags = "用户相关")
 @Slf4j
@@ -32,7 +30,7 @@ public class UserController {
     @Autowired
     private SmsGateway smsGateway;
 
-    @GetMapping("wap/user/queryForOpenId")
+    @GetMapping("/queryForOpenId")
     @ApiOperation(value = "登录获取openId")
     public ApiResult<String> queryForOpenId(@RequestParam String code) {
         String openId = userGateway.getOpenId(code);
@@ -42,8 +40,29 @@ public class UserController {
         return ApiResult.failed("获取openId失败!");
     }
 
+    @GetMapping("/loginWx")
+    @ApiOperation(value = "登录接口")
+    public ApiResult<UserInfoWxRes> loginWx(@RequestParam String code) {
+        UserInfoWxRes userInfoWxRes = userGateway.loginWx(code);
+        if (userInfoWxRes != null) {
+            return ApiResult.success(userInfoWxRes);
+        }
+        return ApiResult.failed("微信登录失败!");
+    }
+
+    @GetMapping("/loginByPhone")
+    @ApiOperation(value = "用户手机号码一键登录注册")
+    public ApiResult<String> loginByPhone(@Valid @RequestBody PhoneLoginParams params) {
+
+        if (userGateway.loginByPhone(params)) {
+            return ApiResult.success("登录成功");
+        }
+        return ApiResult.failed("登录失败");
+    }
+
+
 
-    @GetMapping("wap/user/getLoginSmsCode")
+    @GetMapping("/getLoginSmsCode")
     @ApiOperation(value = "获取登录短信验证码")
     public ApiResult<String> getLoginSmsCode(@RequestParam String phone) {
         if (smsGateway.sendLoginSmsCode(phone)) {
@@ -52,7 +71,7 @@ public class UserController {
         return ApiResult.failed("发送短信验证码失败!");
     }
 
-    @GetMapping("wap/user/getSignupSmsCode")
+    @GetMapping("/getSignupSmsCode")
     @ApiOperation(value = "获取注册短信验证码")
     public ApiResult<String> getSignupSmsCode(@RequestParam String phone) {
         if (smsGateway.sendSignupSmsCode(phone)) {
@@ -62,7 +81,7 @@ public class UserController {
     }
 
 
-    @PostMapping("wap/user/signup")
+    @PostMapping("/signup")
     @ApiOperation(value = "小程序用户注册")
     public ApiResult<String> signup(@Valid @RequestBody UserSignupParams request) {
         if (userGateway.signup(request)) {
@@ -72,26 +91,26 @@ public class UserController {
     }
 
 
-    @GetMapping("wap/user/checkOpenid")
+    @GetMapping("/checkOpenid")
     @ApiOperation(value = "校验用户是不是存在")
-    public ApiResult<String> checkOpenid(@RequestParam String openid) {
-        return ApiResult.success(userGateway.getOpenId(openid));
+    public ApiResult<Boolean> checkOpenid(@RequestParam String openid) {
+        return ApiResult.success(userGateway.checkOpenId(openid));
     }
 
 
-    @PostMapping("wap/user/loginBySmsCode")
+    @PostMapping("/loginBySmsCode")
     @ApiOperation(value = "短信验证码登录")
     public ApiResult<UserDto> loginBySmsCode(@Valid @RequestBody LoginBySmsCodeParams request) {
         return ApiResult.success(userGateway.loginBySmsCode(request));
     }
 
-    @PostMapping("wap/user/loginByPassword")
+    @PostMapping("/loginByPassword")
     @ApiOperation(value = "密码登录")
     public ApiResult<UserDto> loginByPassword(@Valid @RequestBody UserLoginParams request) {
         return ApiResult.success(userGateway.loginByPassword(request));
     }
 
-    @GetMapping("wap/user/getUserPhone")
+    @GetMapping("/getUserPhone")
     @ApiOperation(value = "获取用户手机号码")
     public ApiResult<Map<String, String>> getUserPhone(@RequestParam String code) {
         Map<String, String> result = new HashMap<>();
@@ -99,17 +118,17 @@ public class UserController {
         return ApiResult.success(result);
     }
 
-    /**
-     * todo
-     * 检测用户是否拥有设备
-     */
-    @GetMapping("wap/user/checkDevByOpenId")
-    @ApiOperation(value = "检测用户是否拥有设备")
-    public ApiResult<String> checkDevByOpenId(@RequestParam String openId) {
-        return ApiResult.success(openId);
-    }
-
-    @PostMapping("wap/user/updatePassword")
+//    /**
+//     * todo
+//     * 检测用户是否拥有设备
+//     */
+//    @GetMapping("wap/user/checkDevByOpenId")
+//    @ApiOperation(value = "检测用户是否拥有设备")
+//    public ApiResult<String> checkDevByOpenId(@RequestParam String openId) {
+//        return ApiResult.success(openId);
+//    }
+
+    @PostMapping("/updatePassword")
     @ApiOperation(value = "修改用户密码")
     public ApiResult<?> updatePassword(@RequestBody @Valid UserUpdatePasswordParams request) {
         userGateway.updatePassword(request);

+ 45 - 0
portal-service-application/src/main/java/com/hfln/portal/application/controller/wap/WechatController.java

@@ -0,0 +1,45 @@
+package com.hfln.portal.application.controller.wap;
+
+
+import cn.hfln.framework.catchlog.CatchAndLog;
+import cn.hfln.framework.dto.ApiResult;
+import com.hfln.portal.domain.gateway.UserGateway;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+@RestController("/wap/wechat")
+@CatchAndLog
+@Api(tags = "微信相关")
+@Slf4j
+public class WechatController {
+
+    @Autowired
+    private UserGateway userGateway;
+
+    @GetMapping("/authUrl")
+    @ApiOperation(value = "自动跳转微信授权")
+    public ApiResult<Void> authUrl(HttpServletResponse response) throws IOException {
+
+        log.info("自动跳转微信授权");
+        String url = userGateway.authUrl();
+        response.sendRedirect(url);
+        return ApiResult.success();
+    }
+
+    @GetMapping("/callback")
+    @ApiOperation(value = "微信回调接口")
+    public ApiResult<Void> callback(@RequestParam String code, @RequestParam String state, HttpServletResponse response) throws IOException {
+
+        String welcomeUrl = userGateway.callback(code);
+        response.sendRedirect(welcomeUrl);
+        return ApiResult.success();
+    }
+}

+ 16 - 0
portal-service-common/src/main/java/com/hfln/portal/common/constant/mqtt/topic/TopicConstants.java

@@ -2,6 +2,22 @@ package com.hfln.portal.common.constant.mqtt.topic;
 
 public interface TopicConstants {
 
+    // 检查更新/获取版本
+    String TOPIC_DEV_GET_VERSION = "/dev/%s/get_device_info";
+
+    // 设备软重启
+    String TOPIC_DEV_REBOOT = "/dev/%s/reboot";
+
+    // OTA升级
+    String TOPIC_DEV_UPDATEOTA = "/dev/%s/update_firmware";
+
+    // 获取设备信息
+    String TOPIC_DEV_GET_INFO = "/mps/get_device_info";
+
+    // 获取设备参数
+    String TOPIC_DEV_GET_PARAM = "/mps/get_device_param";
+
+
     String TOPIC_DEV_UPDATE = "/dev/%s/set_device_param";
 
 

+ 27 - 0
portal-service-common/src/main/java/com/hfln/portal/common/dto/data/event/AlarmEventDTO.java

@@ -0,0 +1,27 @@
+package com.hfln.portal.common.dto.data.event;
+
+import com.hfln.portal.common.vo.BaseVO;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class AlarmEventDTO extends BaseVO {
+
+    private Long stayTimeId;
+
+    /**
+     * dev_info表id
+     */
+    private Long devId;
+
+    private Byte pose;
+
+    private String targetPoints;
+
+    private String event;
+
+    private String desc;
+
+    private Integer isHandle;
+} 

+ 3 - 3
portal-service-common/src/main/java/com/hfln/portal/common/dto/data/home/HomeInfoDTO.java

@@ -1,6 +1,7 @@
 package com.hfln.portal.common.dto.data.home;
 
 import com.hfln.portal.common.dto.data.device.DeviceDTO;
+import com.hfln.portal.common.dto.data.oss.OssFileDTO;
 import com.hfln.portal.common.vo.BaseVO;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
@@ -12,9 +13,8 @@ import java.util.List;
 @Data
 public class HomeInfoDTO extends BaseVO {
 
-
-    @ApiModelProperty("轮播图")
-    private String carouselImage;
+    @ApiModelProperty("轮播图列表")
+    private List<OssFileDTO> fileList;
 
     @ApiModelProperty("设备列表")
     private List<DeviceDTO> deviceList;

+ 41 - 0
portal-service-common/src/main/java/com/hfln/portal/common/dto/data/oss/OssFileDTO.java

@@ -0,0 +1,41 @@
+package com.hfln.portal.common.dto.data.oss;
+
+import com.hfln.portal.common.vo.BaseVO;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class OssFileDTO extends BaseVO {
+    /**
+     * 主键ID
+     */
+    @ApiModelProperty("主键ID")
+    private Long fileId;
+
+    /**
+     * 业务类型
+     */
+    @ApiModelProperty("业务类型")
+    private String busiType;
+
+    /**
+     * 业务主键
+     */
+    @ApiModelProperty("业务主键")
+    private Long busiId;
+
+    /**
+     * 文件名称
+     */
+    @ApiModelProperty("文件名称")
+    private String fileName;
+
+    /**
+     * 文件地址
+     */
+    @ApiModelProperty("文件地址")
+    private String fileUrl;
+
+}

+ 36 - 0
portal-service-common/src/main/java/com/hfln/portal/common/dto/data/room/RegionInfo.java

@@ -0,0 +1,36 @@
+package com.hfln.portal.common.dto.data.room;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class RegionInfo {
+
+    private String name;
+
+    private String type;
+
+    private BigDecimal width;
+
+    private BigDecimal height;
+
+    private BigDecimal top;
+
+    private BigDecimal left;
+
+    private Boolean rotate;
+
+    private BigDecimal yuanX;
+
+    private BigDecimal yuanY;
+
+    private String widthToM;
+
+    private String heightToM;
+
+    private BigDecimal x;
+
+    private BigDecimal y;
+
+}

+ 44 - 0
portal-service-common/src/main/java/com/hfln/portal/common/dto/data/room/RoomDto.java

@@ -0,0 +1,44 @@
+package com.hfln.portal.common.dto.data.room;
+
+
+import com.hfln.portal.common.vo.BaseVO;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.List;
+
+@EqualsAndHashCode(callSuper = true)
+@ApiModel(description = "设备房间")
+@Data
+public class RoomDto extends BaseVO {
+
+
+
+    /**
+     * 主键ID
+     */
+    @ApiModelProperty("主键ID")
+    private Long roomId;
+
+    /**
+     * 设备ID
+     */
+    @ApiModelProperty("设备ID")
+    private Long devId;
+
+
+    /**
+     * 子区域
+     */
+    @ApiModelProperty("子区域")
+    private List<RegionInfo> subRegions;
+
+    /**
+     * 家具
+     */
+    @ApiModelProperty("家具")
+    private List<RegionInfo> furnitures;
+
+}

+ 57 - 0
portal-service-common/src/main/java/com/hfln/portal/common/dto/data/share/ShareDto.java

@@ -0,0 +1,57 @@
+package com.hfln.portal.common.dto.data.share;
+
+
+import com.hfln.portal.common.vo.BaseVO;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@EqualsAndHashCode(callSuper = true)
+@ApiModel(description = "设备分享")
+@Data
+public class ShareDto extends BaseVO {
+
+    /**
+     * 主键ID
+     */
+    @ApiModelProperty("主键ID")
+    private Long shareId;
+
+    /**
+     * 设备ID
+     */
+    @ApiModelProperty("设备ID")
+    private Long devId;
+
+    /**
+     * 分享人userId
+     */
+    @ApiModelProperty("分享人userId")
+    private Long sharerUserId;
+
+    /**
+     * 分享人手机号
+     */
+    @ApiModelProperty("分享人手机号")
+    private String sharerPhone;
+
+    /**
+     * 被分享人userId
+     */
+    @ApiModelProperty("被分享人userId")
+    private Long sharedUserId;
+
+    /**
+     * 被分享人手机号
+     */
+    @ApiModelProperty("被分享人手机号")
+    private String sharedPhone;
+
+    /**
+     * 状态:0-待确认,1-已确认,2-已拒绝
+     */
+    @ApiModelProperty("状态:0-待确认,1-已确认,2-已拒绝")
+    private Integer state;
+
+}

+ 44 - 0
portal-service-common/src/main/java/com/hfln/portal/common/request/share/ShareConfirmParam.java

@@ -0,0 +1,44 @@
+package com.hfln.portal.common.request.share;
+
+
+import com.hfln.portal.common.vo.BaseVO;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import javax.validation.constraints.AssertTrue;
+import javax.validation.constraints.NotNull;
+
+@EqualsAndHashCode(callSuper = true)
+@ApiModel(description = "设备分享确认")
+@Data
+public class ShareConfirmParam extends BaseVO {
+
+
+    /**
+     * 设备ID
+     */
+    @ApiModelProperty("设备ID")
+    @NotNull(message = "设备ID不能为空")
+    private Long devId;
+
+    /**
+     * 被分享人userId
+     */
+    @ApiModelProperty("被分享人userId")
+    @NotNull(message = "被分享人userId")
+    private Long sharedUserId;
+
+    /**
+     * 确认状态 1-已确认,2-已拒绝
+     */
+    @ApiModelProperty("确认状态 1-已确认,2-已拒绝")
+    @NotNull(message = "确认状态不能为空")
+    private Integer state;
+
+    @AssertTrue(message = "确认状态有误")
+    private boolean isStateValid() {
+        return state != null && (state == 1 || state == 2);
+    }
+}

+ 46 - 0
portal-service-common/src/main/java/com/hfln/portal/common/request/share/ShareParam.java

@@ -0,0 +1,46 @@
+package com.hfln.portal.common.request.share;
+
+
+import com.hfln.portal.common.vo.BaseVO;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@EqualsAndHashCode(callSuper = true)
+@ApiModel(description = "设备分享")
+@Data
+public class ShareParam extends BaseVO {
+
+
+    /**
+     * 设备ID
+     */
+    @ApiModelProperty("设备ID")
+    private Long devId;
+
+    /**
+     * 分享人userId
+     */
+    @ApiModelProperty("分享人userId")
+    private Long sharerUserId;
+
+    /**
+     * 分享人手机号
+     */
+    @ApiModelProperty("分享人手机号")
+    private String sharerPhone;
+
+    /**
+     * 被分享人userId
+     */
+    @ApiModelProperty("被分享人userId")
+    private Long sharedUserId;
+
+    /**
+     * 被分享人手机号
+     */
+    @ApiModelProperty("被分享人手机号")
+    private String sharedPhone;
+
+}

+ 29 - 0
portal-service-common/src/main/java/com/hfln/portal/common/request/user/PhoneLoginParams.java

@@ -0,0 +1,29 @@
+package com.hfln.portal.common.request.user;
+
+
+import com.hfln.portal.common.vo.BaseVO;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import javax.validation.constraints.NotEmpty;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+@ApiModel(description = "电话登录入参")
+public class PhoneLoginParams extends BaseVO {
+
+    @NotEmpty(message = "手机号不能为空!")
+    @ApiModelProperty("手机号")
+    private String phone;
+
+    @NotEmpty(message = "openId不能为空!")
+    @ApiModelProperty("小程序openId")
+    private String openId;
+
+    @NotEmpty(message = "unionId不能为空!")
+    @ApiModelProperty("unionId")
+    private String unionId;
+
+}

+ 4 - 0
portal-service-common/src/main/java/com/hfln/portal/common/request/user/UserSignupParams.java

@@ -26,6 +26,10 @@ public class UserSignupParams extends BaseVO {
     @ApiModelProperty("小程序openId")
     private String openId;
 
+    @NotEmpty(message = "unionid不能为空!")
+    @ApiModelProperty("小程序unionid")
+    private String unionId;
+
     @NotEmpty(message = "密码不能为空!")
     @ApiModelProperty("密码")
     private String password;

+ 21 - 0
portal-service-common/src/main/java/com/hfln/portal/common/response/device/WcTimesQueryRes.java

@@ -0,0 +1,21 @@
+package com.hfln.portal.common.response.device;
+
+
+import com.hfln.portal.common.dto.data.event.AlarmEventDTO;
+import com.hfln.portal.common.vo.BaseVO;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.List;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+@ApiModel(description = "厕所使用查询结果")
+public class WcTimesQueryRes extends BaseVO {
+
+    private List<AlarmEventDTO> stayTimes;
+
+    private int count;
+
+}

+ 1 - 0
portal-service-common/src/main/java/com/hfln/portal/common/response/package-info.java

@@ -0,0 +1 @@
+package com.hfln.portal.common.response;

+ 23 - 0
portal-service-common/src/main/java/com/hfln/portal/common/response/user/UserInfoWxRes.java

@@ -0,0 +1,23 @@
+package com.hfln.portal.common.response.user;
+
+
+import com.hfln.portal.common.vo.BaseVO;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import javax.validation.constraints.NotEmpty;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+@ApiModel(description = "从微信查询用户信息")
+public class UserInfoWxRes extends BaseVO {
+
+    @ApiModelProperty("小程序openId")
+    private String openId;
+
+    @ApiModelProperty("小程序unionId")
+    private String unionId;
+
+}

+ 4 - 0
portal-service-domain/pom.xml

@@ -37,6 +37,10 @@
             <artifactId>mqtt-spring-boot-starter</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+        </dependency>
 
     </dependencies>
 

+ 38 - 0
portal-service-domain/src/main/java/com/hfln/portal/domain/customer/OssBusiType.java

@@ -0,0 +1,38 @@
+package com.hfln.portal.domain.customer;
+
+/**
+ * oss存储业务类型
+ *
+ * @author Frank Zhang
+ * @date 2018-01-08 11:09 AM
+ */
+public enum OssBusiType {
+
+    CAROUSEL("CAROUSEL", "轮播图"),
+    FLOORPLAN("FLOORPLAN", "户型图"),
+    ;
+
+    String code;
+    String desc;
+
+    OssBusiType(String code, String desc) {
+        this.code = code;
+        this.desc = desc;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public void setDesc(String desc) {
+        this.desc = desc;
+    }
+}

+ 32 - 0
portal-service-domain/src/main/java/com/hfln/portal/domain/customer/util/DevPosFixUtil.java

@@ -0,0 +1,32 @@
+package com.hfln.portal.domain.customer.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class DevPosFixUtil {
+
+    private static Map<String, Byte> poseFix = new HashMap<>();
+
+    public synchronized static void setFixPost(Byte pose, String clientId) {
+        if (pose == -1) {
+            return;
+        }
+        poseFix.put(clientId, pose);
+    }
+
+    public synchronized static void delFixPost(String clientId) {
+        if (poseFix.containsKey(clientId)) {
+            poseFix.remove(clientId);
+        }
+    }
+
+    public static boolean containsKey(String clientId) {
+
+        return poseFix.containsKey(clientId);
+    }
+
+    public static Byte get(String clientId) {
+
+        return poseFix.get(clientId);
+    }
+}

+ 136 - 0
portal-service-domain/src/main/java/com/hfln/portal/domain/customer/util/WxOfficeAccountClient.java

@@ -0,0 +1,136 @@
+package com.hfln.portal.domain.customer.util;
+
+import com.alibaba.fastjson2.JSON;
+import com.google.gson.Gson;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.HttpEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import javax.validation.constraints.NotBlank;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 微信公众号客户端
+ */
+@Slf4j
+@Component
+public class WxOfficeAccountClient {
+
+    private static final String APPID = "wx9b479fa3c2af4f21";
+    private static final String SECRET = "426effb7b58f9ba7c5f6dd1062db0074";
+
+    @NotBlank
+    @Value("${lnxx.wechat.office.account.appId}")
+    private String appId;
+
+    @NotBlank
+    @Value("${lnxx.wechat.office.account.secret}")
+    private String secret;
+
+    @NotBlank
+    @Value("${lnxx.wechat.office.account.templateId}")
+    private String templateId;
+
+    private static final Gson gson = new Gson();
+
+    public void sendMsg(String devId, String devName, String phoneNo, String fwhOpenId) {
+        // 1. 获取 access_token
+        String accessToken = getAccessToken();
+        if (accessToken == null) {
+
+            log.info("获取 access_token 失败");
+            return;
+        }
+
+        Map<String, Object> data = new HashMap<>();
+		// 1. 每个字段需要包装成包含 value 的 Map
+        Map<String, String> characterString1 = new HashMap<>();
+        characterString1.put("value", devId);
+        data.put("character_string1", characterString1);
+        Map<String, String> thing8 = new HashMap<>();
+
+        // 设备名称
+        thing8.put("value", devName);
+        data.put("thing8", thing8);
+        Map<String, String> thing10 = new HashMap<>();
+
+        // 用户手机号
+        thing10.put("value", phoneNo);
+        data.put("thing10", thing10);
+
+        Map<String, String> time3 = new HashMap<>();
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		String currentTime = sdf.format(new Date());
+        time3.put("value", currentTime);  // 时间字段需符合格式要求
+        data.put("time3", time3);
+
+        Map<String, String> const2 = new HashMap<>();
+        const2.put("value", "设备运行异常,给用户发送推送");
+        data.put("const2", const2);
+
+        log.info("mqttutil--sendmessage:{}", JSON.toJSONString(data));
+        boolean result = sendTemplateMessage(accessToken, fwhOpenId, data);
+        log.info("发送结果: " + (result ? "成功" : "失败"));
+    }
+
+    private String getAccessToken() {
+        String url = "https://api.weixin.qq.com/cgi-bin/token" +
+                "?grant_type=client_credential" +
+                "&appid=" + appId +
+                "&secret=" + secret;
+
+        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
+            HttpGet httpGet = new HttpGet(url);
+            try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
+                HttpEntity entity = response.getEntity();
+                String result = EntityUtils.toString(entity);
+                Map<String, Object> map = gson.fromJson(result, Map.class);
+                log.info("access_token:{}",map.get("access_token"));
+                return (String) map.get("access_token");
+            }
+        } catch (IOException e) {
+            log.error("获取accessToke失败", e);
+            return null;
+        }
+    }
+
+    private boolean sendTemplateMessage(String accessToken, String openid,
+                                        Map<String, Object> data) {
+        String url = "https://api.weixin.qq.com/cgi-bin/message/template/send" +
+                "?access_token=" + accessToken;
+
+        // 构建请求体
+        Map<String, Object> params = new HashMap<>();
+        params.put("touser", openid);
+        params.put("template_id", templateId);
+        params.put("data", data);
+
+        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
+            HttpPost httpPost = new HttpPost(url);
+            httpPost.setHeader("Content-Type", "application/json");
+            httpPost.setEntity(new StringEntity(gson.toJson(params), "UTF-8"));
+
+            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
+                String result = EntityUtils.toString(response.getEntity());
+                Map<String, Object> resultMap = gson.fromJson(result, Map.class);
+                System.out.println("打印结果: " + resultMap);
+                return resultMap.get("errmsg").equals("ok");
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+}

+ 23 - 0
portal-service-domain/src/main/java/com/hfln/portal/domain/exception/ErrorEnum.java

@@ -15,6 +15,7 @@ public enum ErrorEnum implements ErrorEnumInterface{
     ERROR_BIZ_FAIL( "10000", "业务失败"),
     USER_NOT_FOUND( "10001", "用户不存在"),
     MOBILE_EXISTS("10002", "手机号已存在"),
+    MOBILE_NOT_SIGN("10003", "手机号未注册"),
 
 
     /**
@@ -40,6 +41,7 @@ public enum ErrorEnum implements ErrorEnumInterface{
      * 三方系统调用相关
      */
     WECHAT_INTERFACE_CALL_EXCEPTION("40001", "微信接口调用异常"),
+    WECHAT_CODE_NOT_EXIST("40002", "code 不存在,可能不是微信回调"),
 
     /**
      * 设备相关
@@ -48,9 +50,30 @@ public enum ErrorEnum implements ErrorEnumInterface{
     DEVICE_IS_BINDING("50002", "当前设备已经被绑定!"),
 
 
+    /**
+     * 设备房间相关
+     */
+    ROOM_IS_NOT_EXIST("60001", "房间信息不存在!"),
 
 
+    /**
+     * 设备分享相关
+     */
+    SHARE_IS_NOT_REPEAT("70001", "请勿重复发送分享邀请!"),
+    SHARER_IS_NOT_EXIST("70002", "分享人不存在!"),
+    EXIST_NOT_DEAL_SHARE("70003", "存在未处理的邀请,请回主页查看!"),
+    SHARE_INFO_NOT_EXIST("70004", "分享邀请不存在!"),
+    SHARE_INFO_ALREADY_DEAL("70005", "分享邀请已处理!"),
 
+    /**
+     * 文件相关
+     */
+    FILE_IS_EMPTY("80001", "文件为空!"),
+    FILE_ONLY_PNG_JPG("80002", "仅支持PNG或JPG 格式!"),
+    FILE_ONLY_PNG_JPG02("80003", "文件实际格式与声明不符,仅支持 PNG/JPG!"),
+    FILE_NOT_COMPLETE("80004", "文件格式不完整!"),
+    FILE_DEL_OR_NOT_EXIST("80005", "文件已删除或不存在!"),
+    FILE_EXIST_MULTIPLE("80006", "存在多个文件!"),
     ;
 
     private final String errorCode;

+ 55 - 0
portal-service-domain/src/main/java/com/hfln/portal/domain/gateway/DeviceGateway.java

@@ -3,12 +3,19 @@ package com.hfln.portal.domain.gateway;
 import com.hfln.portal.common.dto.data.device.DeviceDTO;
 import com.hfln.portal.common.dto.data.event.EventListDTO;
 import com.hfln.portal.common.dto.data.home.HomeInfoDTO;
+import com.hfln.portal.common.dto.data.room.RoomDto;
+import com.hfln.portal.common.dto.data.share.ShareDto;
 import com.hfln.portal.common.request.device.DeviceBandingParams;
 import com.hfln.portal.common.request.device.DeviceListParams;
 import com.hfln.portal.common.request.device.DeviceLocationParams;
 import com.hfln.portal.common.request.event.EventListParams;
+import com.hfln.portal.common.request.share.ShareConfirmParam;
+import com.hfln.portal.common.request.share.ShareParam;
+import com.hfln.portal.common.response.device.WcTimesQueryRes;
 import com.hfln.portal.common.vo.PageRecord;
+import org.springframework.web.multipart.MultipartFile;
 
+import java.io.IOException;
 import java.util.List;
 
 public interface DeviceGateway {
@@ -32,4 +39,52 @@ public interface DeviceGateway {
 
     Boolean updateDeviceLocation(DeviceLocationParams params);
 
+    Boolean checkDevByUserId(Long userId, Long devId);
+
+
+    /**
+     * 房间布局
+     */
+
+    RoomDto readRoom(Long devId);
+
+    Boolean saveRoom(RoomDto roomDto);
+
+
+    /**
+     * 设备分享
+     */
+
+    Boolean devShare(ShareParam shareParam);
+
+    Boolean shareByUrl(ShareParam shareParam);
+
+    List<ShareDto> queryShare(Long userId);
+
+    void shareConfirm(ShareConfirmParam shareConfirmParam);
+
+
+    /**
+     *  mqtt 雷达
+     */
+
+    void getVersion(String clientId);
+
+    void reboot(String clientId);
+
+    void updateOTA(String clientId);
+
+    void fixPost(String clientId, int poseIndex);
+
+    void stopFixPost(String clientId);
+
+    void getInfo(String clientId);
+
+    void getParam(String clientId);
+
+    void uploadFloorPlan(MultipartFile file, String groupUuid) throws IOException;
+
+    String getFloorPlan(String groupUuid);
+
+    WcTimesQueryRes getWcTimes(Long devId, String time);
 }

+ 11 - 4
portal-service-domain/src/main/java/com/hfln/portal/domain/gateway/UserGateway.java

@@ -1,10 +1,8 @@
 package com.hfln.portal.domain.gateway;
 
 import com.hfln.portal.common.dto.data.user.UserDto;
-import com.hfln.portal.common.request.user.LoginBySmsCodeParams;
-import com.hfln.portal.common.request.user.UserLoginParams;
-import com.hfln.portal.common.request.user.UserSignupParams;
-import com.hfln.portal.common.request.user.UserUpdatePasswordParams;
+import com.hfln.portal.common.request.user.*;
+import com.hfln.portal.common.response.user.UserInfoWxRes;
 
 public interface UserGateway {
 
@@ -12,6 +10,12 @@ public interface UserGateway {
     String getOpenId(String code);
 
 
+    UserInfoWxRes loginWx(String code);
+
+
+    Boolean loginByPhone(PhoneLoginParams params);
+
+
     Boolean signup(UserSignupParams request);
 
 
@@ -32,4 +36,7 @@ public interface UserGateway {
 
     void updatePassword(UserUpdatePasswordParams request);
 
+    String authUrl();
+
+    String callback(String code);
 }

+ 15 - 0
portal-service-infrastructure/pom.xml

@@ -52,8 +52,23 @@
             <artifactId>sa-token-spring-boot-starter</artifactId>
         </dependency>
 
+        <!-- websocket -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-websocket</artifactId>
+        </dependency>
 
+        <!-- oss存储 -->
+        <dependency>
+            <groupId>com.aliyun.oss</groupId>
+            <artifactId>aliyun-sdk-oss</artifactId>
+        </dependency>
 
+        <!-- 微信 -->
+        <dependency>
+            <groupId>com.github.binarywang</groupId>
+            <artifactId>weixin-java-mp</artifactId>
+        </dependency>
 
 
     </dependencies>

+ 107 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/config/PushMsgWebSocket.java

@@ -0,0 +1,107 @@
+package com.hfln.portal.infrastructure.config;
+
+import com.hfln.portal.infrastructure.po.GroupDevMap;
+import com.hfln.portal.infrastructure.service.GroupDevMapService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import javax.websocket.OnClose;
+import javax.websocket.OnError;
+import javax.websocket.OnOpen;
+import javax.websocket.Session;
+import javax.websocket.server.PathParam;
+import javax.websocket.server.ServerEndpoint;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Slf4j
+@ServerEndpoint("/ws/PushMsgWebSocket/{key}")
+@Component
+public class PushMsgWebSocket {
+	
+//	private BaseDAO baseDAO =SpringContext.getContext().getBean(BaseDAO.class);
+
+	private static GroupDevMapService groupDevMapService;
+	
+	private static Map<String, PushMsgWebSocket> clients = new ConcurrentHashMap<String, PushMsgWebSocket>();
+	private static Map<String, List<String>> groups =new ConcurrentHashMap<String,List<String>>();
+	private Session session;
+	private String key;
+
+	@Autowired
+	private GroupDevMapService transfer;
+
+	@PostConstruct
+	public void init() {
+		groupDevMapService = transfer;
+	}
+
+	@OnOpen
+	public void onOpen(@PathParam("key") String key, Session session) throws IOException {
+		log.info("ws连接" + key);
+		this.session = session;
+		this.key = key;
+		clients.put(key, this);
+		
+		String groupUuid =key.split(":")[0];
+		List<GroupDevMap> maps = groupDevMapService.queryByGroupUuid(groupUuid);
+		if(maps != null && maps.size()>0) {
+			List<String> group =new ArrayList<String>();
+			for(int i =0;i<maps.size();i++) {
+				group.add(maps.get(i).getClientId());
+			}
+			groups.put(groupUuid, group);
+		}
+	}
+
+	@OnClose
+	public void onClose() throws IOException {
+		log.error("ws关闭"+key);
+		clients.remove(key);
+	}
+
+	@OnError
+	public void onError(Session session, Throwable error) {
+		log.error("ws异常", error);
+		clients.remove(key);
+	}
+
+	public static void sendMessageTo(String message, String code) {
+		Set<String> keys = clients.keySet();
+		for (String s : keys) {
+			// 单雷达建立连接
+			if (s.contains(code)) {
+				PushMsgWebSocket item = clients.get(s);
+				if (item != null) {
+					try {
+						item.session.getAsyncRemote().sendText(message);
+					} catch (Exception e) {
+						log.error("ws推送报错", e);
+						clients.remove(s);
+					}
+				}
+			}
+			// 数组建立连接
+			if (s.contains(":")) {
+				String group_uuid =s.split(":")[0];		
+				if(groups.containsKey(group_uuid) && groups.get(group_uuid).contains(code)) {
+					PushMsgWebSocket item = clients.get(s);
+					if (item != null) {
+						try {
+							item.session.getAsyncRemote().sendText(message);
+						} catch (Exception e) {
+							log.error("ws推送报错", e);
+							clients.remove(s);
+						}
+					}
+				}
+			}
+		}
+	}
+}

+ 16 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/config/WebSocketConfig.java

@@ -0,0 +1,16 @@
+package com.hfln.portal.infrastructure.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.config.annotation.EnableWebSocket;
+import org.springframework.web.socket.server.standard.ServerEndpointExporter;
+
+@EnableWebSocket
+@Configuration
+public class WebSocketConfig {
+
+    @Bean
+    public ServerEndpointExporter serverEndpointExporter() {
+        return new ServerEndpointExporter();
+    }
+}

+ 397 - 10
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/gateway/impl/DeviceGatewayImpl.java

@@ -1,35 +1,56 @@
 package com.hfln.portal.infrastructure.gateway.impl;
 
 import cn.hfln.framework.extension.BizException;
+import cn.hfln.framework.mqtt.template.MqttTemplate;
+import com.alibaba.fastjson2.JSONArray;
+import com.alibaba.fastjson2.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.hfln.portal.common.constant.mqtt.topic.TopicConstants;
 import com.hfln.portal.common.dto.data.device.DeviceDTO;
+import com.hfln.portal.common.dto.data.event.AlarmEventDTO;
 import com.hfln.portal.common.dto.data.event.EventListDTO;
 import com.hfln.portal.common.dto.data.home.HomeInfoDTO;
+import com.hfln.portal.common.dto.data.oss.OssFileDTO;
+import com.hfln.portal.common.dto.data.room.RegionInfo;
+import com.hfln.portal.common.dto.data.room.RoomDto;
+import com.hfln.portal.common.dto.data.share.ShareDto;
 import com.hfln.portal.common.request.device.DeviceBandingParams;
 import com.hfln.portal.common.request.device.DeviceListParams;
 import com.hfln.portal.common.request.device.DeviceLocationParams;
 import com.hfln.portal.common.request.event.EventListParams;
+import com.hfln.portal.common.request.share.ShareConfirmParam;
+import com.hfln.portal.common.request.share.ShareParam;
+import com.hfln.portal.common.response.device.WcTimesQueryRes;
 import com.hfln.portal.common.vo.PageRecord;
+import com.hfln.portal.domain.customer.OssBusiType;
+import com.hfln.portal.domain.customer.util.DevPosFixUtil;
 import com.hfln.portal.domain.exception.ErrorEnum;
 import com.hfln.portal.domain.gateway.DeviceGateway;
-import com.hfln.portal.infrastructure.po.DevGroup;
-import com.hfln.portal.infrastructure.po.DevInfo;
-import com.hfln.portal.infrastructure.po.DevShare;
-import com.hfln.portal.infrastructure.po.EventList;
+import com.hfln.portal.infrastructure.oss.OssClient;
+import com.hfln.portal.infrastructure.oss.OssUtils;
+import com.hfln.portal.infrastructure.po.*;
 import com.hfln.portal.infrastructure.service.*;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
+import org.springframework.web.multipart.MultipartFile;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
+import java.time.LocalDate;
 import java.util.*;
 import java.util.stream.Collectors;
 
+@Slf4j
 @Service
 public class DeviceGatewayImpl implements DeviceGateway {
 
@@ -48,17 +69,44 @@ public class DeviceGatewayImpl implements DeviceGateway {
     @Autowired
     private EventService eventService;
 
+    @Autowired
+    private OssFileService ossFileService;
+
+    @Autowired
+    private DevRoomService devRoomService;
+
+    @Autowired
+    private UserService userService;
+
+    @Autowired
+    private MqttTemplate mqttTemplate;
+
+    @Autowired
+    private OssClient ossClient;
+
+    @Autowired
+    private AlarmEventService alarmEventService;
+
 
     @Override
     public HomeInfoDTO queryHomeInfo(Long userId) {
         HomeInfoDTO homeInfoDTO = new HomeInfoDTO();
-        //todo 添加轮播图相关信息
-        homeInfoDTO.setCarouselImage(null);
+        // 添加轮播图相关信息
+        List<OssFileDTO> fileDTOS = new ArrayList<>();
+        List<TblOssFile> files = ossFileService.queryFile(OssBusiType.CAROUSEL.getCode(), null);
+        if (CollectionUtils.isNotEmpty(files)) {
+            for (TblOssFile file : files) {
+                OssFileDTO dto = new OssFileDTO();
+                BeanUtils.copyProperties(file, dto);
+                fileDTOS.add(dto);
+            }
+        }
+        homeInfoDTO.setFileList(fileDTOS);
         /*
           查询设备详情
          */
         // 查询当前OpenId被分享的设备
-        Optional<List<String>> sharedDevIds = devShareService.queryDeviceIdByUserId(userId);
+        Optional<List<Long>> sharedDevIds = devShareService.queryDeviceIdByUserId(userId);
 
         List<DeviceDTO> deviceDTOs = new ArrayList<>();
         List<DevInfo> devInfos = devInfoService.queryDeviceList(userId, null, null, sharedDevIds.orElse(Collections.emptyList()));
@@ -90,7 +138,7 @@ public class DeviceGatewayImpl implements DeviceGateway {
     @Override
     public List<DeviceDTO> queryDeviceList(DeviceListParams request) {
 
-        Optional<List<String>> sharedDevIds = devShareService.queryDeviceIdByUserId(request.getUserId());
+        Optional<List<Long>> sharedDevIds = devShareService.queryDeviceIdByUserId(request.getUserId());
 
         List<DeviceDTO> deviceDTOs = new ArrayList<>();
         List<DevInfo> devInfos = devInfoService.queryDeviceList(request.getUserId(), request.getKeyWord(),
@@ -152,7 +200,7 @@ public class DeviceGatewayImpl implements DeviceGateway {
         }
 
         // 3. 更新设备信息
-        return devInfoService.updateDevice(devInfo.getDevInfoId(), request);
+        return devInfoService.updateDevice(devInfo.getDevId(), request);
     }
 
 
@@ -247,7 +295,7 @@ public class DeviceGatewayImpl implements DeviceGateway {
                 .map(parts -> parts[0] + "." + parts[1])
                 .orElse("2.0");
 
-        //mqttHandler.handleDeviceUpdateMessage(result, request);
+        //todo mqttHandler.handleDeviceUpdateMessage(result, request);
         return flag;
     }
 
@@ -283,6 +331,345 @@ public class DeviceGatewayImpl implements DeviceGateway {
         if (params.getXValue() == null && params.getYValue() == null) {
             return false;
         }
+
+        updateWrapper.eq(DevInfo::getDevId, params.getDeviceId());
+        updateWrapper.eq(DevInfo::getIsDeleted, BasePO.DeleteFlag.NOT_DELETED);
+
         return devInfoService.update(updateWrapper);
     }
+
+    @Override
+    public Boolean checkDevByUserId(Long userId, Long devId) {
+
+        DevInfo devInfo = devInfoService.getOne(
+                Wrappers.<DevInfo>lambdaQuery()
+                        .eq(DevInfo::getDevId, devId)
+                        .eq(DevInfo::getUserId, userId)
+                        .eq(DevInfo::getIsDeleted, BasePO.DeleteFlag.NOT_DELETED)
+        );
+        if (Objects.nonNull(devInfo)) {
+            return true;
+        }
+
+        DevShare devShare = devShareService.queryByUserIdAndDevId(userId, devId);
+        if (devShare != null) {
+            return true;
+        }
+
+        return false;
+    }
+
+    @Override
+    public RoomDto readRoom(Long devId) {
+
+        DevRoom devRoom = devRoomService.queryByDevId(devId);
+        if (devRoom == null) {
+            throw new BizException(ErrorEnum.ROOM_IS_NOT_EXIST.getErrorCode(), ErrorEnum.ROOM_IS_NOT_EXIST.getErrorMessage());
+        }
+
+        RoomDto dto = new RoomDto();
+        dto.setRoomId(devRoom.getRoomId());
+        dto.setDevId(devRoom.getDevId());
+        if (StringUtils.hasText(devRoom.getFurnitures())) {
+            dto.setFurnitures(JSONArray.parseArray(devRoom.getFurnitures(), RegionInfo.class));
+        }
+        if (StringUtils.hasText(devRoom.getSubRegions())) {
+            dto.setSubRegions(JSONArray.parseArray(devRoom.getSubRegions(), RegionInfo.class));
+        }
+        return dto;
+    }
+
+    @Override
+    public Boolean saveRoom(RoomDto roomDto) {
+
+        // 更新dev_room表
+        devRoomService.saveOrUpdate(roomDto);
+
+        // todo  发送 屏蔽区域的数据到mqtt
+        if (CollectionUtils.isNotEmpty(roomDto.getSubRegions())) {
+            // todo 组装数据发送mqtt
+        }
+        return null;
+    }
+
+    @Override
+    public Boolean devShare(ShareParam shareParam) {
+
+
+        List<UserInfo> userInfos = userService.queryByPhone(shareParam.getSharedPhone());
+        if (userInfos == null || userInfos.size() < 1) {
+            throw new BizException(ErrorEnum.MOBILE_NOT_SIGN.getErrorCode(), ErrorEnum.MOBILE_NOT_SIGN.getErrorMessage());
+        }
+
+        LambdaQueryWrapper<DevShare> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(DevShare::getDevId, shareParam.getDevId());
+        queryWrapper.eq(DevShare::getSharerUserId, shareParam.getSharerUserId());
+        queryWrapper.eq(DevShare::getSharedUserId, userInfos.get(0).getUserId());
+        queryWrapper.in(DevShare::getState, Arrays.asList(0, 1));
+        List<DevShare> list = devShareService.list(queryWrapper);
+
+        if (list != null && list.size() > 1) {
+            throw new BizException(ErrorEnum.SHARE_IS_NOT_REPEAT.getErrorCode(), ErrorEnum.SHARE_IS_NOT_REPEAT.getErrorMessage());
+        }
+
+        DevShare devShare = new DevShare();
+
+        devShare.setDevId(shareParam.getDevId());
+        devShare.setSharerUserId(shareParam.getSharerUserId());
+        devShare.setSharerPhone(shareParam.getSharerPhone());
+        devShare.setSharedPhone(shareParam.getSharedPhone());
+        devShare.setSharedUserId(userInfos.get(0).getUserId());
+        devShare.setState(0);
+        devShareService.save(devShare);
+        return null;
+    }
+
+    @Override
+    public Boolean shareByUrl(ShareParam shareParam) {
+
+        DevShare notDealShare = devShareService.queryNotDeal(shareParam.getSharerUserId(), shareParam.getSharedUserId(), shareParam.getDevId());
+        if (notDealShare != null) {
+            throw new BizException(ErrorEnum.EXIST_NOT_DEAL_SHARE.getErrorCode(), ErrorEnum.EXIST_NOT_DEAL_SHARE.getErrorMessage());
+        }
+
+        DevShare devShare = new DevShare();
+        BeanUtils.copyProperties(shareParam, devShare);
+        if (StringUtils.isEmpty(shareParam.getSharerPhone())) {
+            UserInfo shareUser = userService.queryById(shareParam.getSharerUserId());
+            if (shareUser == null) {
+                throw new BizException(ErrorEnum.SHARER_IS_NOT_EXIST.getErrorCode(), ErrorEnum.SHARER_IS_NOT_EXIST.getErrorMessage());
+            }
+            devShare.setSharerPhone(shareUser.getPhone());
+        }
+
+        devShare.setState(1);
+        devShareService.save(devShare);
+        return true;
+    }
+
+    @Override
+    public List<ShareDto> queryShare(Long userId) {
+
+        List<DevShare> shares = devShareService.queryBySharedUserId(userId);
+        if (CollectionUtils.isEmpty(shares)) {
+            return null;
+        }
+
+        List<ShareDto> res = new ArrayList<>();
+        for (DevShare share : shares) {
+            ShareDto dto = new ShareDto();
+            BeanUtils.copyProperties(share, dto);
+            res.add(dto);
+        }
+        return res;
+    }
+
+    @Override
+    public void shareConfirm(ShareConfirmParam shareConfirmParam) {
+
+        DevShare devShare = devShareService.queryBySharedUserIdAndDevId(shareConfirmParam.getSharedUserId(), shareConfirmParam.getDevId());
+        if (devShare == null) {
+            throw new BizException(ErrorEnum.SHARE_INFO_NOT_EXIST.getErrorCode(), ErrorEnum.SHARE_INFO_NOT_EXIST.getErrorMessage());
+        }
+
+        if (devShare.getState() == null || devShare.getState() != 0) {
+            throw new BizException(ErrorEnum.SHARE_INFO_ALREADY_DEAL.getErrorCode(), ErrorEnum.SHARE_INFO_ALREADY_DEAL.getErrorMessage());
+        }
+
+        devShare.setState(shareConfirmParam.getState());
+        devShareService.updateById(devShare);
+    }
+
+    @Override
+    public void getVersion(String clientId) {
+
+        String topic = String.format(TopicConstants.TOPIC_DEV_GET_VERSION, clientId);
+        JSONObject msg = new JSONObject();
+        msg.put("dev_id", clientId);
+
+        mqttTemplate.send(topic, msg.toJSONString());
+    }
+
+    @Override
+    public void reboot(String clientId) {
+
+        String topic = String.format(TopicConstants.TOPIC_DEV_REBOOT, clientId);
+
+        mqttTemplate.send(topic, "1");
+    }
+
+    @Override
+    public void updateOTA(String clientId) {
+
+        String topic = String.format(TopicConstants.TOPIC_DEV_UPDATEOTA, clientId);
+
+        mqttTemplate.send(topic, "1");
+    }
+
+    @Override
+    public void fixPost(String clientId, int poseIndex) {
+
+        Byte pose;
+        switch (poseIndex) {
+            case 0:
+                pose = 4;
+                break;
+            case 1:
+                pose = 5;
+                break;
+            case 2:
+                pose = 0;
+                break;
+            case 3:
+                pose = 7;
+                break;
+            default:
+                pose = -1;
+                break;
+        }
+
+        DevPosFixUtil.setFixPost(pose, clientId);
+    }
+
+    @Override
+    public void stopFixPost(String clientId) {
+
+        DevPosFixUtil.delFixPost(clientId);
+    }
+
+    @Override
+    public void getInfo(String clientId) {
+
+        JSONObject msg = new JSONObject();
+        msg.put("dev_id", clientId);
+
+        mqttTemplate.send(TopicConstants.TOPIC_DEV_GET_INFO, msg.toJSONString());
+    }
+
+    @Override
+    public void getParam(String clientId) {
+
+        JSONObject msg = new JSONObject();
+        msg.put("dev_id", clientId);
+
+        mqttTemplate.send(TopicConstants.TOPIC_DEV_GET_PARAM, msg.toJSONString());
+    }
+
+    @Override
+    public void uploadFloorPlan(MultipartFile file, String groupUuid) throws IOException {
+
+        // 校验文件非空
+        if (file.isEmpty()) {
+            throw new BizException(ErrorEnum.FILE_IS_EMPTY.getErrorCode(), ErrorEnum.FILE_IS_EMPTY.getErrorMessage());
+        }
+
+        // 校验文件类型
+        String contentType = file.getContentType();
+        if (contentType == null || (!contentType.equalsIgnoreCase("image/png") && !contentType.equalsIgnoreCase("image/jpeg"))) {
+            throw new BizException(ErrorEnum.FILE_ONLY_PNG_JPG.getErrorCode(), ErrorEnum.FILE_ONLY_PNG_JPG.getErrorMessage());
+        }
+
+        // 校验文件头
+        byte[] fileHeader = new byte[8];
+        try (InputStream is = file.getInputStream()) {
+            int readBytes = is.read(fileHeader);
+            if (readBytes < 8) {
+                throw new BizException(ErrorEnum.FILE_NOT_COMPLETE.getErrorCode(), ErrorEnum.FILE_NOT_COMPLETE.getErrorMessage());
+            }
+        }
+        boolean isPng = checkPngMagicNumber(fileHeader);
+        boolean isJpeg = checkJpegMagicNumber(fileHeader);
+
+        if (!isPng && !isJpeg) {
+            throw new BizException(ErrorEnum.FILE_ONLY_PNG_JPG02.getErrorCode(), ErrorEnum.FILE_ONLY_PNG_JPG02.getErrorMessage());
+        }
+
+        String objectName = OssUtils.getObjectName(OssBusiType.FLOORPLAN.getCode(), file.getName());
+        ossClient.upload(file.getInputStream(), OssUtils.BUCKET_NAME, objectName);
+
+        TblOssFile ossFile = ossFileService.queryOneFile(OssBusiType.FLOORPLAN.getCode(), groupUuid);
+        if (ossFile == null) {
+            TblOssFile newFile = new TblOssFile();
+            newFile.setBusiType(OssBusiType.FLOORPLAN.getCode());
+            newFile.setBusiKey(groupUuid);
+            newFile.setFileName(file.getName());
+            newFile.setOssUrl(OssUtils.BUCKET_NAME+objectName);
+            ossFileService.save(newFile);
+        } else {
+            if (ossFile.getIsDeleted() == BasePO.DeleteFlag.NOT_DELETED) {
+                // 删除原文件
+                ossClient.delete(ossFile.getOssUrl());
+            }
+            ossFile.setBusiType(OssBusiType.FLOORPLAN.getCode());
+            ossFile.setBusiKey(groupUuid);
+            ossFile.setFileName(file.getName());
+            ossFile.setOssUrl(OssUtils.BUCKET_NAME+objectName);
+            ossFileService.updateById(ossFile);
+        }
+    }
+
+    @Override
+    public String getFloorPlan(String groupUuid) {
+
+        List<TblOssFile> tblOssFiles = ossFileService.queryFile(OssBusiType.FLOORPLAN.getCode(), groupUuid);
+        if (CollectionUtils.isEmpty(tblOssFiles)) {
+            throw new BizException(ErrorEnum.FILE_EXIST_MULTIPLE.getErrorCode(), ErrorEnum.FILE_EXIST_MULTIPLE.getErrorMessage());
+        }
+        TblOssFile tblOssFile = tblOssFiles.get(0);
+        if (tblOssFile == null || tblOssFile.getIsDeleted() == BasePO.DeleteFlag.DELETED) {
+            throw new BizException(ErrorEnum.FILE_DEL_OR_NOT_EXIST.getErrorCode(), ErrorEnum.FILE_DEL_OR_NOT_EXIST.getErrorMessage());
+        }
+
+        return ossClient.getDownloadUrl(tblOssFile.getOssUrl());
+    }
+
+    @Override
+    public WcTimesQueryRes getWcTimes(Long devId, String time) {
+
+        LocalDate inputDate = LocalDate.parse(time);
+        LocalDate previousDate = inputDate.minusDays(1);
+        List<AlarmEvent> list = alarmEventService.list(new LambdaQueryWrapper<AlarmEvent>().eq(AlarmEvent::getDevId, devId).ge(AlarmEvent::getCreateTime, previousDate).lt(AlarmEvent::getCreateTime, inputDate));
+        WcTimesQueryRes res = new WcTimesQueryRes();
+        if (CollectionUtils.isEmpty(list)) {
+
+            res.setStayTimes(null);
+            res.setCount(0);
+        } else {
+
+            List<AlarmEventDTO> dtoList = new ArrayList<>();
+            for (AlarmEvent alarmEvent : list) {
+                AlarmEventDTO dto = new AlarmEventDTO();
+                BeanUtils.copyProperties(alarmEvent, dto);
+                dtoList.add(dto);
+            }
+            res.setStayTimes(dtoList);
+            res.setCount(list.size());
+        }
+        return res;
+    }
+
+    // 校验 PNG 文件头(89 50 4E 47 0D 0A 1A 0A)
+    public static boolean checkPngMagicNumber(byte[] header) {
+        byte[] pngSignature = {(byte) 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A};
+        if (header.length < pngSignature.length) return false;
+        for (int i = 0; i < pngSignature.length; i++) {
+            if ((header[i] & 0xFF) != (pngSignature[i] & 0xFF)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    // 校验 JPEG 文件头(FF D8)
+    public static boolean checkJpegMagicNumber(byte[] header) {
+        return header.length >= 2 &&
+                (header[0] & 0xFF) == 0xFF &&
+                (header[1] & 0xFF) == 0xD8;
+    }
+
+    public static void main(String[] args) {
+
+    }
+
+
 }

+ 108 - 14
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/gateway/impl/UserGatewayImpl.java

@@ -5,20 +5,26 @@ import cn.dev33.satoken.stp.SaTokenInfo;
 import cn.dev33.satoken.stp.StpUtil;
 import cn.hfln.framework.common.redis.service.RedisService;
 import cn.hfln.framework.extension.BizException;
+import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONObject;
 import com.hfln.portal.common.constant.redis.RedisCacheConstant;
 import com.hfln.portal.common.dto.data.user.UserDto;
-import com.hfln.portal.common.request.user.LoginBySmsCodeParams;
-import com.hfln.portal.common.request.user.UserLoginParams;
-import com.hfln.portal.common.request.user.UserSignupParams;
-import com.hfln.portal.common.request.user.UserUpdatePasswordParams;
+import com.hfln.portal.common.request.user.*;
+import com.hfln.portal.common.response.user.UserInfoWxRes;
 import com.hfln.portal.domain.customer.util.PasswordUtil;
 import com.hfln.portal.domain.exception.ErrorEnum;
 import com.hfln.portal.domain.gateway.UserGateway;
-import com.hfln.portal.infrastructure.mapper.UserInfoMapper;
 import com.hfln.portal.infrastructure.po.UserInfo;
+import com.hfln.portal.infrastructure.po.WxRelation;
 import com.hfln.portal.infrastructure.service.UserService;
+import com.hfln.portal.infrastructure.service.WxRelationService;
+import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
+import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
+import me.chanjar.weixin.common.service.WxOAuth2Service;
+import me.chanjar.weixin.mp.api.WxMpService;
+import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -29,6 +35,7 @@ import org.springframework.http.MediaType;
 import org.springframework.stereotype.Service;
 import org.springframework.web.client.RestTemplate;
 
+import java.util.List;
 import java.util.Objects;
 
 @Service
@@ -42,9 +49,6 @@ public class UserGatewayImpl implements UserGateway {
     private RedisService redisService;
 
     @Autowired
-    private UserInfoMapper userInfoMapper;
-
-    @Autowired
     private UserService userService;
 
     @Value("${lnxx.wechat.appid}")
@@ -53,7 +57,14 @@ public class UserGatewayImpl implements UserGateway {
     @Value("${lnxx.wechat.secret}")
     private String secret;
 
+    @Value("${lnxx.wechat.bind.callbackUrl}")
+    private String callbackUrl;
+
+    @Autowired
+    private WxMpService wxMpService;
 
+    @Autowired
+    private WxRelationService wxRelationService;
 
 
     public static String WXX_CX_ACCESS_TOKEN = "";
@@ -75,6 +86,46 @@ public class UserGatewayImpl implements UserGateway {
     }
 
     @Override
+    public UserInfoWxRes loginWx(String code) {
+        if (StringUtils.isEmpty(code)) {
+            throw new BizException(ErrorEnum.WECHAT_CODE_ISNULL.getErrorCode(), ErrorEnum.WECHAT_CODE_ISNULL.getErrorMessage());
+        }
+        String url = String.format("https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code", appid, secret, code);
+        try {
+            String res = restTemplate.getForObject(url, String.class);
+            log.info("微信登录返回结果:{}", res);
+            JSONObject obj = JSONObject.parseObject(res);
+            String openId = Objects.requireNonNull(obj).getString("openid");
+            String unionId = Objects.requireNonNull(obj).getString("unionid");
+
+            UserInfoWxRes userInfoWxRes = new UserInfoWxRes();
+            userInfoWxRes.setOpenId(openId);
+            userInfoWxRes.setUnionId(unionId);
+            return userInfoWxRes;
+        } catch (Exception e) {
+            log.error("微信登录接口异常", e);
+            throw new BizException(ErrorEnum.WECHAT_INTERFACE_CALL_EXCEPTION.getErrorCode(), ErrorEnum.WECHAT_INTERFACE_CALL_EXCEPTION.getErrorMessage());
+        }
+    }
+
+    @Override
+    public Boolean loginByPhone(PhoneLoginParams params) {
+
+
+        if (userService.checkAvailableOpenId(params.getOpenId())) {
+            log.info("当前用户已登录:{}", params.getOpenId());
+            return true;
+        }
+
+        UserInfo userInfo = new UserInfo();
+        userInfo.setOpenid(params.getOpenId());
+        userInfo.setPhone(params.getPhone());
+        userInfo.setUnionId(params.getUnionId());
+        userService.save(userInfo);
+        return true;
+    }
+
+    @Override
     public Boolean signup(UserSignupParams request) {
         //校验验证码
         String cacheCode = redisService.getCacheObject(RedisCacheConstant.SMS_SIGNUP_CODE + request.getPhone());
@@ -95,14 +146,15 @@ public class UserGatewayImpl implements UserGateway {
         String encryptedPassword = PasswordUtil.encrypt(request.getPassword());
         user.setPassword(encryptedPassword);
         user.setOpenid(request.getOpenId());
-        userInfoMapper.insert(user);
+        user.setUnionId(request.getUnionId());
+        userService.save(user);
         return true;
     }
 
 
     @Override
     public Boolean checkOpenId(String openId) {
-        return userService.checkOpenId(openId);
+        return userService.checkAvailableOpenId(openId);
     }
 
     @Override
@@ -121,13 +173,13 @@ public class UserGatewayImpl implements UserGateway {
             redisService.deleteObject(RedisCacheConstant.SMS_LOGIN_CODE + phone);
         }
         BeanUtils.copyProperties(user, userDto);
-        userDto.setUserId(user.getUserInfoId()
+        userDto.setUserId(user.getUserId()
         );
 
         /*
         通过sa-token获取token
          */
-        StpUtil.login(user.getUserInfoId());
+        StpUtil.login(user.getUserId());
         SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
 
         return userDto;
@@ -142,7 +194,7 @@ public class UserGatewayImpl implements UserGateway {
             throw new BizException(ErrorEnum.USERNAME_OR_PASSWORD_ERROR.getErrorCode(), ErrorEnum.USERNAME_OR_PASSWORD_ERROR.getErrorMessage());
         }
         BeanUtils.copyProperties(user, userDto);
-        userDto.setUserId(user.getUserInfoId());
+        userDto.setUserId(user.getUserId());
         return userDto;
     }
 
@@ -201,8 +253,50 @@ public class UserGatewayImpl implements UserGateway {
             throw new BizException(ErrorEnum.OLD_PASSWORD_ERROR.getErrorCode(), ErrorEnum.OLD_PASSWORD_ERROR.getErrorMessage());
         }
         UserInfo info = new UserInfo();
-        info.setUserInfoId(request.getUserId());
+        info.setUserId(request.getUserId());
         info.setPassword(request.getNewPassword());
         userService.updateById(userInfo);
     }
+
+    @Override
+    public String authUrl() {
+        String redirectUrl =  callbackUrl + "/wx/callback"; // 微信后台配置的回调地址
+        return wxMpService.getOAuth2Service()
+                .buildAuthorizationUrl(redirectUrl, "snsapi_userinfo", "state123");
+    }
+
+    @SneakyThrows
+    @Override
+    public String callback(String code) {
+
+        if (code == null || code.isEmpty()) {
+            throw new BizException(ErrorEnum.WECHAT_CODE_NOT_EXIST.getErrorCode(), ErrorEnum.WECHAT_CODE_NOT_EXIST.getErrorMessage());
+        }
+
+        try {
+            WxOAuth2Service oauth2Service = wxMpService.getOAuth2Service();
+            WxOAuth2AccessToken accessToken = oauth2Service.getAccessToken(code);
+            WxOAuth2UserInfo userInfo = oauth2Service.getUserInfo(accessToken, null);
+            log.info("公众号绑定:userInfo:{}", JSON.toJSONString(userInfo));
+
+            List<WxRelation> wxRelations = wxRelationService.queryByUnionIdAndOpenId(userInfo.getUnionId(), userInfo.getOpenid());
+            if (CollectionUtils.isNotEmpty(wxRelations)) {
+                log.info("当前服务号公众号已经绑定过");
+                return "/welcome.html?nickname=" + userInfo.getNickname()
+                        + "&avatar=" + userInfo.getHeadImgUrl();
+            }
+
+            WxRelation wxRelation = new WxRelation();
+            wxRelation.setUnionId(userInfo.getUnionId());
+            wxRelation.setFwhOpenId(userInfo.getOpenid());
+            wxRelationService.save(wxRelation);
+
+            // 授权成功,跳转欢迎页面(带参数)
+            return "/welcome.html?nickname=" + userInfo.getNickname()
+                    + "&avatar=" + userInfo.getHeadImgUrl();
+        } catch (Exception e) {
+            log.error("公众号绑定异常", e);
+            throw e;
+        }
+    }
 }

+ 168 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/job/ScheduledTask.java

@@ -0,0 +1,168 @@
+//package com.hfln.portal.infrastructure.job;
+//
+//import com.alibaba.fastjson2.JSONObject;
+//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+//import com.fasterxml.jackson.databind.JsonNode;
+//import com.fasterxml.jackson.databind.ObjectMapper;
+//import com.google.common.collect.Lists;
+//import com.hfln.portal.infrastructure.po.DevTarget;
+//import com.hfln.portal.infrastructure.service.DevTargetService;
+//import lombok.extern.slf4j.Slf4j;
+//import org.apache.http.client.methods.CloseableHttpResponse;
+//import org.apache.http.client.methods.HttpGet;
+//import org.apache.http.client.utils.URIBuilder;
+//import org.apache.http.util.EntityUtils;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.scheduling.annotation.Scheduled;
+//import org.springframework.stereotype.Component;
+//
+//import java.io.ByteArrayInputStream;
+//import java.security.cert.CertificateExpiredException;
+//import java.security.cert.CertificateFactory;
+//import java.security.cert.CertificateNotYetValidException;
+//import java.security.cert.X509Certificate;
+//import java.sql.Timestamp;
+//import java.time.LocalDateTime;
+//import java.util.ArrayList;
+//import java.util.Date;
+//import java.util.List;
+//
+//@Slf4j
+//@Component
+//public class ScheduledTask {
+//
+//    @Autowired
+//    private DevTargetService devTargetService;
+//
+//    @Scheduled(cron = "0 0 1 * * ?")
+//    public void runAtOneAM() {
+//
+//        devTargetService.remove(new LambdaQueryWrapper<DevTarget>().lt(DevTarget::getCreateTime, LocalDateTime.now().plusDays(-3)));
+//        log.info("定时删除devTarget数据");
+//    }
+//
+//    @Scheduled(cron = "0 0 */6 * * ?")
+//    public void updateWxpayCert() {
+//        if(Environment.wxHttpClient != null) {
+//            CloseableHttpResponse res = null;
+//            try {
+//                List<X509Certificate> certs = new ArrayList<X509Certificate>();
+//                List<WxpaycertVO> wxcerts = baseDAO.queryByCondition(WxpaycertVO.class, null, "effective_time desc");
+//                URIBuilder uriBuilder = new URIBuilder("https://api.mch.weixin.qq.com/v3/certificates");
+//                HttpGet httpGet = new HttpGet(uriBuilder.build());
+//                httpGet.addHeader("Accept", "application/json");
+//                res = Environment.wxHttpClient.execute(httpGet);
+//                String body = EntityUtils.toString(res.getEntity());
+//                res.close();
+//                ObjectMapper mapper = new ObjectMapper();
+//                JsonNode dataNode = mapper.readTree(body).get("data");
+//                if (dataNode != null) {
+//                    for (int i = 0, count = dataNode.size(); i < count; i++) {
+//                        String serial_no = dataNode.get(i).get("serial_no").textValue();
+//                        boolean match = false;
+//                        for (WxpaycertVO c : wxcerts) {
+//                            if (serial_no.equals(c.getSerial_no())) {
+//                                match = true;
+//                                break;
+//                            }
+//                        }
+//                        if (!match) {
+//                            AesUtil decryptor = new AesUtil(Constants.WXMCHKEYV3.getBytes("UTF-8"));
+//                            JsonNode encryptCertificateNode = dataNode.get(i).get("encrypt_certificate");
+//                            String cert = decryptor.decryptToString(
+//                                    encryptCertificateNode.get("associated_data").toString().replaceAll("\"", "")
+//                                            .getBytes("utf-8"),
+//                                    encryptCertificateNode.get("nonce").toString().replaceAll("\"", "").getBytes("utf-8"),
+//                                    encryptCertificateNode.get("ciphertext").toString().replaceAll("\"", ""));
+//
+//                            CertificateFactory cf = CertificateFactory.getInstance("X509");
+//                            X509Certificate x509Cert = (X509Certificate) cf
+//                                    .generateCertificate(new ByteArrayInputStream(cert.getBytes("utf-8")));
+//                            try {
+//                                x509Cert.checkValidity();
+//                            } catch (CertificateExpiredException | CertificateNotYetValidException e) {
+//                                continue;
+//                            }
+//                            certs.add(x509Cert);
+//
+//                            WxpaycertVO c = new WxpaycertVO();
+//                            c.setSerial_no(dataNode.get(i).get("serial_no").textValue());
+//                            Date effective_time = DateUtil.parse("yyyy-MM-dd'T'HH:mm:ssX",
+//                                    dataNode.get(i).get("effective_time").textValue());
+//                            c.setEffective_time(new Timestamp(effective_time.getTime()));
+//                            Date expire_time = DateUtil.parse("yyyy-MM-dd'T'HH:mm:ssX",
+//                                    dataNode.get(i).get("expire_time").textValue());
+//                            c.setExpire_time(new Timestamp(expire_time.getTime()));
+//                            c.setCerttext(cert);
+//                            baseDAO.insert(c);
+//                        }
+//                    }
+//
+//                }
+//                if (certs.size() > 0) {
+//                    Log.info("新增证书:"+certs.size());
+//                    // 证书有变动重新加载
+//                    for (WxpaycertVO c : wxcerts) {
+//                        CertificateFactory cf = CertificateFactory.getInstance("X509");
+//                        X509Certificate x509Cert = (X509Certificate) cf
+//                                .generateCertificate(new ByteArrayInputStream(c.getCerttext().getBytes("utf-8")));
+//                        try {
+//                            x509Cert.checkValidity();
+//                        } catch (CertificateExpiredException | CertificateNotYetValidException e) {
+//                            continue;
+//                        }
+//                        certs.add(x509Cert);
+//                    }
+//                    Environment.wxHttpClient = WechatPayHttpClientBuilder.create()
+//                            .withMerchant(Constants.WXMCHID, Constants.WXMCHAPICERTNUM, Environment.wxPrivateKey)
+//                            .withWechatPay(certs).build();
+//                }
+//            } catch (Exception e) {
+//                e.printStackTrace();
+//            }
+//        }
+//
+//    }
+//
+//    @Scheduled(cron = "0 0 */1 * * ?")
+//    public void updateWxgzh() {
+//        if(StringUtils.isNotBlank(Constants.WXGZHAPPID) && StringUtils.isNotBlank(Constants.WXGZHAPPSECRET)) {
+//            String res = HttpUtil.request("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="
+//                    + Constants.WXGZHAPPID + "&secret=" + Constants.WXGZHAPPSECRET, null, false, null, null);
+//            if(StringUtils.isNotEmpty(res)) {
+//                Constants.WXGZHACCESS_TOKEN = (String) JSONObject.parseObject(res).get("access_token");
+//                Log.info("公众号更新ACCESS_TOKEN:" + Constants.WXGZHACCESS_TOKEN);
+//                String res_str = HttpUtil.request("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="
+//                        + Constants.WXGZHACCESS_TOKEN + "&type=jsapi", null, false, null, null);
+//                if(StringUtils.isNotEmpty(res_str)) {
+//                    Constants.WXGZHJS_TICKET = (String) JSONObject.parseObject(res_str).get("ticket");
+//                    Log.info("公众号更新JS_TICKET:" + Constants.WXGZHJS_TICKET);
+//                }
+//            }
+//        }
+//    }
+//
+//    @Scheduled(cron = "0 0 */1 * * ?")
+//    public void updateWxxcx() {
+//        if(StringUtils.isNotBlank(Constants.WXXCXAPPID) && StringUtils.isNotBlank(Constants.WXXCXAPPSECRET)) {
+//            String res = HttpUtil.request("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="
+//                    + Constants.WXXCXAPPID + "&secret=" + Constants.WXXCXAPPSECRET, null, false, null, null);
+//            if(StringUtils.isNotEmpty(res)) {
+//                Constants.WXXCXACCESS_TOKEN = (String) JSONObject.parseObject(res).get("access_token");
+//                Log.info("小程序更新ACCESS_TOKEN:" + Constants.WXXCXACCESS_TOKEN);
+//            }
+//        }
+//    }
+//
+//    @Scheduled(cron = "0 */1 * * * ?")
+//    public void processSblx() {
+//        List<String> sqls = Lists.newArrayList();
+//        List<SbVO> sbs = baseDAO.queryByCondition(SbVO.class, " and lx is null and UNIX_TIMESTAMP(now()) - UNIX_TIMESTAMP(sign_time)>120 ", null);
+//        for(SbVO v : sbs) {
+//            sqls.add("update tbl_sb set lx=1 where id='"+v.getId()+"' ");
+//        }
+//        if(sqls.size() > 0) {
+//            baseDAO.getJdbcTemplate().batchUpdate(sqls.toArray(new String[] {}));
+//        }
+//    }
+//}

+ 9 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/mapper/AlarmEventMapper.java

@@ -0,0 +1,9 @@
+package com.hfln.portal.infrastructure.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.hfln.portal.infrastructure.po.AlarmEvent;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface AlarmEventMapper extends BaseMapper<AlarmEvent> {
+} 

+ 12 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/mapper/TblOssFileMapper.java

@@ -0,0 +1,12 @@
+package com.hfln.portal.infrastructure.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.hfln.portal.infrastructure.po.TblOssFile;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * oss存储文件 Mapper 接口
+ */
+@Mapper
+public interface TblOssFileMapper extends BaseMapper<TblOssFile> {
+} 

+ 9 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/mapper/WxRelationMapper.java

@@ -0,0 +1,9 @@
+package com.hfln.portal.infrastructure.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.hfln.portal.infrastructure.po.WxRelation;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface WxRelationMapper extends BaseMapper<WxRelation> {
+}

+ 377 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/mqtt/MqttSubHandle.java

@@ -0,0 +1,377 @@
+package com.hfln.portal.infrastructure.mqtt;
+
+import cn.hfln.framework.mqtt.annotation.MqttSubscribe;
+import cn.hfln.framework.mqtt.template.MqttTemplate;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONArray;
+import com.alibaba.fastjson2.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.hfln.portal.domain.customer.util.DevPosFixUtil;
+import com.hfln.portal.domain.customer.util.MsgClient;
+import com.hfln.portal.domain.customer.util.WxOfficeAccountClient;
+import com.hfln.portal.infrastructure.po.*;
+import com.hfln.portal.infrastructure.service.*;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
+
+@Component
+@Slf4j
+public class MqttSubHandle {
+    // 常量定义
+    private static final double VERSION_THRESHOLD = 2.0; // 版本阈值,用于判断设备协议版本
+    private static final int QOS = 1;                  // MQTT服务质量等级
+    private static final boolean RETAIN = true;        // MQTT保留消息标志
+
+    @Autowired
+    private MqttTemplate mqttTemplate; // MQTT消息发布器
+
+    @Autowired
+    private DevInfoService devInfoService;
+
+    @Autowired
+    private EventService eventService;
+
+    @Autowired
+    private DevTargetService devTargetService;
+
+    @Autowired
+    private UserService userService;
+
+    @Autowired
+    private MsgClient msgClient;
+
+    @Autowired
+    private WxRelationService wxRelationService;
+
+    @Autowired
+    private WxOfficeAccountClient wxOfficeAccountClient;
+
+    @MqttSubscribe(topic = "/das/event", qos = 2)
+    public void subDasEvent(String payload) {
+
+        JSONObject obj = JSONObject.parseObject(payload);
+        String clientId = obj.getString("dev_id");
+        log.info("mqttsub, topic:{}, clientId:{}", "/das/event", clientId);
+        String event = obj.getString("event");
+        // 跌倒确认返回
+        if (event.equals("跌倒确认")) {
+            mqttTemplate.send("/mps/fall_event/ack", clientId);
+        }
+
+        byte messageType = obj.getByteValue("message_type");
+        byte pose = obj.getByteValue("pose");
+        JSONArray targetPointArray = obj.getJSONArray("target_point");
+        if (targetPointArray.isEmpty()) {
+            log.info("mqttsub target_point is Empty, do nothing");
+            return;
+        }
+
+        JSONArray targetPointOne = targetPointArray.getJSONArray(0);
+        BigDecimal x = targetPointOne.getBigDecimal(0);
+        BigDecimal y = targetPointOne.getBigDecimal(1);
+        BigDecimal z = targetPointOne.getBigDecimal(2);
+
+        BigDecimal[][] targetPoints = new BigDecimal[targetPointArray.size()][3];
+        for (int i = 0; i < targetPointArray.size(); i++) {
+
+            JSONArray targetPoint = targetPointArray.getJSONArray(i);
+            targetPoints[i] = new BigDecimal[]{targetPoint.getBigDecimal(0), targetPoint.getBigDecimal(1), targetPoint.getBigDecimal(2)};
+        }
+
+        String targetPointsStr = JSON.toJSONString(targetPoints);
+        List<DevInfo> devs = devInfoService.queryByClientId(clientId);
+        if (devs != null && devs.size() > 0) {
+            DevInfo dev = devs.get(0);
+            if (!targetPointsStr.equals(dev.getTargetPoints())) {
+                //  存储跌倒事件
+                if (messageType == 3) {
+
+                    event = obj.getString("event");
+                    if (event.equals("fall_confirmed")) {
+                        EventList eventListVO = new EventList();
+                        eventListVO.setDevId(dev.getDevId());
+                        eventListVO.setPose(pose);
+                        eventListVO.setIsHandle(0);
+                        eventListVO.setTargetPoints(targetPointsStr);
+                        eventListVO.setEvent(messageType);
+                        eventService.save(eventListVO);
+                    }
+                }
+
+                // target_points数据入库
+                DevTarget target = new DevTarget();
+                target.setDevId(dev.getDevId());
+                target.setPose(pose);
+                target.setIsHandle(false);
+                if (DevPosFixUtil.containsKey(clientId)) {
+                    target.setFixPose(DevPosFixUtil.get(clientId));
+                } else {
+                    target.setFixPose((byte) -1);
+                }
+                target.setTargetPoints(targetPointsStr);
+                target.setEvent(messageType);
+                devTargetService.save(target);
+
+                DevInfo devInfo = new DevInfo();
+                devInfo.setTargetPoints(targetPointsStr);
+                devInfo.setSignalTime(LocalDateTime.now());
+                devInfoService.update(devInfo, new LambdaUpdateWrapper<DevInfo>().eq(DevInfo::getClientId, clientId));
+            } else {
+                log.info("此次targetPoints与上次相同!");
+            }
+        }
+
+        //向前端发送数据
+        JSONObject msg = new JSONObject();
+        msg.put("target_points", targetPointArray);
+        msg.put("x", x);
+        msg.put("y", y);
+        msg.put("zt", pose);
+        msg.put("dev_id", clientId);
+        msg.put("event", event);
+        msg.put("msg_type", "event");
+
+        // todo 发送socket
+//        PushMsgWebSocket.sendMessageTo(msg.toString(), dev_id);
+
+        // 发送短信
+        if (event.equals("fall_confirmed")) {
+            log.info("mqttutil--有跌倒事件");
+            List<Long> userIds = new ArrayList<>();
+            StringBuffer devName = new StringBuffer("");
+            String devId = "";
+            // 设备拥有者openid
+            if (devs != null && devs.size() > 0) {
+                DevInfo dev = devs.get(0);
+                userIds.add(dev.getUserId());
+                devName.append(dev.getDevName());
+                devId = dev.getClientId();
+            }
+            // 被分享者openid
+//						List<ShareVO> shares = baseDAO.queryAllByCondition(ShareVO.class, " and dev_id ='"+dev_id+"' ", null);
+//						if(shares !=null && shares.size()>0) {
+//							for(int i=0;i<shares.size();i++) {
+//								ShareVO share =shares.get(i);
+//								openids.add(share.getShared());
+//							}
+//						}
+
+            if (userIds.size() > 0) {
+                // 拥有者和被分享者phone
+                List<UserInfo> userInfos = userService.listByIds(userIds);
+                for (int i = 0; i < userInfos.size(); i++) {
+                    UserInfo user = userInfos.get(i);
+                    // 发送跌倒短信
+                    log.info("mqttutil--开始发送跌倒消息");
+                    log.info("mqttutil--sendmsg:phone{}, dev_name:{}", user.getPhone(), devName.toString());
+                    msgClient.sendNotifyMsg(user.getPhone(), devName.toString());
+                    log.info("mqttUtil--消息发完了");
+
+                    // 发送微信公众号消息
+                    List<WxRelation> wxRelations = wxRelationService.queryByUnionId(user.getUnionId());
+                    String fwhOpenId = "";
+                    if (wxRelations != null && !wxRelations.isEmpty()) {
+                        fwhOpenId = wxRelations.get(0).getFwhOpenId();
+                    }
+                    log.info("mqttutil--当前useropenid=" + user.getOpenid() + ", fwhopenId=" + fwhOpenId);
+                    log.info("发送微信公众号信息:devName=" + devName.toString() + ", phoneNo=" + user.getPhone() + "fwhOpenId=" + fwhOpenId);
+                    // 发送微信公告号消息
+                    wxOfficeAccountClient.sendMsg(devId, devName.toString(), user.getPhone(), fwhOpenId);
+                    log.info("发送微信公众号消息发完了");
+                }
+
+            }
+        }
+
+    }
+
+    @MqttSubscribe(topic = "/das/realtime_pos")
+    public void subDasRealtimePos(String payload) {
+
+        JSONObject obj = JSONObject.parseObject(payload);
+        String clientId = obj.getString("dev_id");
+        log.info("mqttsub, topic:{}, clientId:{}", "/das/realtime_pos", clientId);
+        byte messageType = obj.getByteValue("message_type");
+        byte pose = obj.getByteValue("pose");
+        JSONArray targetPointArray = obj.getJSONArray("target_point");
+        if (targetPointArray.isEmpty()) {
+            log.info("mqttsub target_point is Empty, do nothing");
+            return;
+        }
+
+        JSONArray targetPointOne = targetPointArray.getJSONArray(0);
+        BigDecimal x = targetPointOne.getBigDecimal(0);
+        BigDecimal y = targetPointOne.getBigDecimal(1);
+        BigDecimal z = targetPointOne.getBigDecimal(2);
+
+        BigDecimal[][] targetPoints = new BigDecimal[targetPointArray.size()][3];
+        for (int i = 0; i < targetPointArray.size(); i++) {
+
+            JSONArray targetPoint = targetPointArray.getJSONArray(i);
+            targetPoints[i] = new BigDecimal[]{targetPoint.getBigDecimal(0), targetPoint.getBigDecimal(1), targetPoint.getBigDecimal(2)};
+        }
+
+        String targetPointsStr = JSON.toJSONString(targetPoints);
+        List<DevInfo> devs = devInfoService.queryByClientId(clientId);
+        if (devs != null && devs.size() > 0) {
+            DevInfo dev = devs.get(0);
+            if (!targetPointsStr.equals(dev.getTargetPoints())) {
+                //  存储跌倒事件
+                if (messageType == 3) {
+
+                    String event = obj.getString("event");
+                    if (event.equals("fall_confirmed")) {
+                        EventList eventListVO = new EventList();
+                        eventListVO.setDevId(dev.getDevId());
+                        eventListVO.setPose(pose);
+                        eventListVO.setIsHandle(0);
+                        eventListVO.setTargetPoints(targetPointsStr);
+                        eventListVO.setEvent(messageType);
+                        eventService.save(eventListVO);
+                    }
+                }
+
+                // target_points数据入库
+                DevTarget target = new DevTarget();
+                target.setDevId(dev.getDevId());
+                target.setPose(pose);
+                target.setIsHandle(false);
+                if (DevPosFixUtil.containsKey(clientId)) {
+                    target.setFixPose(DevPosFixUtil.get(clientId));
+                } else {
+                    target.setFixPose((byte) -1);
+                }
+                target.setTargetPoints(targetPointsStr);
+                target.setEvent(messageType);
+                devTargetService.save(target);
+
+                DevInfo devInfo = new DevInfo();
+                devInfo.setTargetPoints(targetPointsStr);
+                devInfo.setSignalTime(LocalDateTime.now());
+                devInfoService.update(devInfo, new LambdaUpdateWrapper<DevInfo>().eq(DevInfo::getClientId, clientId));
+            } else {
+                log.info("此次targetPoints与上次相同!");
+            }
+        }
+
+        //向前端发送数据
+        JSONObject msg = new JSONObject();
+        msg.put("target_points", targetPointArray);
+        msg.put("x", x);
+        msg.put("y", y);
+        msg.put("zt", pose);
+        msg.put("dev_id", clientId);
+        msg.put("msg_type", "target_point");
+//        if (topic.equals("/das/realtime_pos")) {
+//            msg.put("msg_type", "target_point");
+//        } else {
+//            msg.put("event", event);
+//            msg.put("msg_type", "event");
+//        }
+
+        // todo websocket 发送msg
+//            PushMsgWebSocket.sendMessageTo(msg.toString(), dev_id);
+    }
+
+    @MqttSubscribe(topic = "/das/dev_status")
+    public void subDasDevStatus(String payload) {
+
+        JSONObject obj = JSONObject.parseObject(payload);
+        String clientId = obj.getString("dev_id");
+        String devType = obj.getString("dev_type");
+        int online = obj.getIntValue("online");
+        String software = obj.getString("software");
+        String hardware = obj.getString("hardware");
+
+        String networkStr = obj.getString("network");
+        JSONObject network = JSONObject.parseObject(networkStr);
+        String ssid = network.getString("ssid");
+        String password = network.getString("password");
+        String ip = network.getString("ip");
+
+        String radarParamStr = obj.getString("radar_param");
+        JSONObject radarParam = JSONObject.parseObject(radarParamStr);
+        String mountPlain = radarParam.getString("mount_plain");
+        BigDecimal height = radarParam.getBigDecimal("height");
+
+        String trackingRegionStr = radarParam.getString("tracking_region");
+        JSONObject trackingRegion = JSONObject.parseObject(trackingRegionStr);
+        BigDecimal startX = trackingRegion.getBigDecimal("start_x");
+        BigDecimal startY = trackingRegion.getBigDecimal("start_y");
+        BigDecimal startZ = trackingRegion.getBigDecimal("start_z");
+        BigDecimal stopX = trackingRegion.getBigDecimal("stop_x");
+        BigDecimal stopY = trackingRegion.getBigDecimal("stop_y");
+        BigDecimal stopZ = trackingRegion.getBigDecimal("stop_z");
+        BigDecimal width = startX.subtract(stopX).abs();
+        BigDecimal length = startY.subtract(stopY).abs();
+
+        DevInfo vo = new DevInfo();
+        vo.setClientId(clientId);
+        vo.setDevType(devType);
+        vo.setOnline(online);
+        vo.setSoftware(software);
+        vo.setHardware(hardware);
+        vo.setWifiName(ssid);
+        vo.setWifiName(password);
+        vo.setIp(ip);
+        vo.setMountPlain(mountPlain);
+        vo.setStartX(startX);
+        vo.setStartY(startY);
+        vo.setStartZ(startZ);
+        vo.setStopX(stopX);
+        vo.setStopY(stopY);
+        vo.setStopZ(stopZ);
+        vo.setHeight(height);
+        vo.setWidth(width);
+        vo.setLength(length);
+
+        List<DevInfo> devs = devInfoService.queryByClientId(clientId);
+        if (devs.size() > 0) {
+
+            devInfoService.update(vo, new LambdaUpdateWrapper<DevInfo>().eq(DevInfo::getClientId, clientId));
+
+            // 向前端发送数据
+            JSONObject msg = new JSONObject();
+            msg.put("mount_plain", mountPlain);
+            msg.put("height", height);
+            msg.put("software", software);
+            msg.put("start_x", startX);
+            msg.put("stop_x", stopX);
+            msg.put("start_y", startY);
+            msg.put("stop_y", stopY);
+            msg.put("start_z", startZ);
+            msg.put("stop_z", stopZ);
+            msg.put("dev_type", devType);
+            msg.put("msg_type", "dev_status");
+
+            // todo websocket 发送
+//            PushMsgWebSocket.sendMessageTo(msg.toString(), clientId);
+        } else {
+
+            devInfoService.save(vo);
+
+        }
+    }
+
+    @MqttSubscribe(topic = "/das/exist")
+    public void subDasExist(String payload) {
+
+        JSONObject obj = JSONObject.parseObject(payload);
+        String dev_id = obj.getString("dev_id");
+        String event = obj.getString("event");
+        //向前端发送数据
+        JSONObject msg = new JSONObject();
+        msg.put("dev_id", dev_id);
+        msg.put("event", event);
+        msg.put("msg_type", "exist");
+
+        // todo websocketservice
+//        PushMsgWebSocket.sendMessageTo(msg.toString(), dev_id);
+    }
+}

+ 108 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/oss/OssClient.java

@@ -0,0 +1,108 @@
+package com.hfln.portal.infrastructure.oss;
+
+import com.aliyun.oss.ClientBuilderConfiguration;
+import com.aliyun.oss.OSS;
+import com.aliyun.oss.OSSClientBuilder;
+import com.aliyun.oss.common.auth.CredentialsProvider;
+import com.aliyun.oss.common.auth.DefaultCredentialProvider;
+import com.aliyun.oss.common.comm.SignVersion;
+import com.aliyun.oss.model.OSSObject;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Date;
+
+@Component
+@Slf4j
+public class OssClient {
+
+
+    @Value("${oss.endpoint}")
+    private String endpoint;
+
+    @Value("${oss.bucket}")
+    private String bucket;
+
+    @Value("${oss.region}")
+    private String region;
+
+    @Value("${oss.accessKey.secret}")
+    private String secret;
+
+    @Value("${oss.accessKey.id}")
+    private String id;
+
+    @Value("${oss.expire.seconds}")
+    private int expireSeconds;
+
+    private OSS oss;
+
+
+    @PostConstruct
+    private void init() {
+
+        // 使用DefaultCredentialProvider方法直接设置AK和SK
+        CredentialsProvider credentialsProvider = new DefaultCredentialProvider(id, secret);
+        // 使用credentialsProvider初始化客户端
+        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
+        // 显式声明使用 V4 签名算法
+        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
+
+        oss = OSSClientBuilder.create()
+                .endpoint(endpoint)
+                .region(region)
+                .clientConfiguration(clientBuilderConfiguration)
+                .credentialsProvider(credentialsProvider)
+                .build();
+    }
+
+
+    public void upload(InputStream inputStream, String bucketName, String objectName) {
+
+        log.info("oss上传,bucketName:{}, objectName:{}", bucketName, objectName);
+        try {
+            oss.putObject(bucketName, objectName, inputStream);
+        } catch (Exception e) {
+            log.error("oss上传失败," , e);
+            throw e;
+        }
+    }
+
+    public InputStream download(String bucketName, String objectName) {
+
+        OSSObject ossObject = oss.getObject(bucketName, objectName);
+        return ossObject.getObjectContent();
+    }
+
+    public String getDownloadUrl(String ossUrl) {
+        return getDownloadUrl(ossUrl.substring(0, ossUrl.indexOf("/")), ossUrl.substring(ossUrl.indexOf("/")));
+    }
+
+    public String getDownloadUrl(String bucketName, String objectName) {
+
+        URL url = oss.generatePresignedUrl(bucketName, objectName, new Date(new Date().getTime() + expireSeconds * 1000L));
+        return url.toString();
+    }
+
+    public void delete(String ossUrl) {
+        log.info("oss删除, ossUrl:{}", ossUrl);
+        try {
+            oss.deleteObject(ossUrl.substring(0, ossUrl.indexOf("/")), ossUrl.substring(ossUrl.indexOf("/")));
+        } catch (Exception e) {
+            log.error("文件删除失败", e);
+            throw e;
+        }
+    }
+
+    public static void main(String[] args) {
+        String ossUrl = "hfln/hxt/20200202/jljl.jpg";
+
+        System.out.println(ossUrl.substring(0, ossUrl.indexOf("/")));
+        System.out.println(ossUrl.substring(ossUrl.indexOf("/")));
+    }
+}
+

+ 38 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/oss/OssUtils.java

@@ -0,0 +1,38 @@
+package com.hfln.portal.infrastructure.oss;
+
+import org.springframework.util.StringUtils;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.UUID;
+
+public class OssUtils {
+
+    public static final String BUCKET_NAME = "hfln";
+
+    public static String getObjectName(String ossBusiType, String fileName) {
+
+        StringBuilder sb = new StringBuilder();
+        sb.append("/")
+                .append(ossBusiType)
+                .append("/")
+                .append(DateTimeFormatter.ofPattern("yyyyMMdd").format(LocalDate.now()))
+                .append("/")
+                .append(UUID.randomUUID().toString().replace("-", ""), 0, 8)
+                .append(getFileSuffix(fileName));
+
+        return sb.toString();
+    }
+
+    public static String getFileSuffix(String fileName) {
+        if (StringUtils.isEmpty(fileName)) {
+            return "";
+        }
+        return fileName.substring(fileName.lastIndexOf("."));
+    }
+
+    public static void main(String[] args) {
+
+        System.out.println(getFileSuffix("abc.jpg"));
+    }
+}

+ 36 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/po/AlarmEvent.java

@@ -0,0 +1,36 @@
+package com.hfln.portal.infrastructure.po;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 停留时间表
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("AlarmEvent")
+public class AlarmEvent extends BasePO {
+    /**
+     * 主键ID
+     */
+    @TableId(type = IdType.ASSIGN_ID)
+    private Long stayTimeId;
+
+    /**
+     * dev_info表id
+     */
+    private Long devId;
+
+    private Byte pose;
+
+    private String targetPoints;
+
+    private String event;
+
+    private String desc;
+
+    private Integer isHandle;
+} 

+ 9 - 2
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/po/BasePO.java

@@ -19,7 +19,7 @@ public class BasePO extends BaseVO {
      * 创建人
      */
     @TableField("create_id")
-    private String createId;
+    private Long createId;
 
 
     /**
@@ -27,7 +27,7 @@ public class BasePO extends BaseVO {
      */
 
     @TableField("update_id")
-    private String updateId;
+    private Long updateId;
     
     /**
      * 创建时间
@@ -47,6 +47,13 @@ public class BasePO extends BaseVO {
     @TableLogic
     @TableField("is_deleted")
     private Integer isDeleted;
+
+    /**
+     * 备注
+     */
+
+    @TableField("remark")
+    private String remark;
     
     /**
      * 删除标记常量

+ 5 - 5
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/po/DevInfo.java

@@ -17,14 +17,14 @@ public class DevInfo extends BasePO {
     /**
      * 主键ID
      */
-    @TableId(value = "dev_info_id", type = IdType.ASSIGN_ID)
-    private Long devInfoId;
+    @TableId(value = "dev_id", type = IdType.ASSIGN_ID)
+    private Long devId;
 
     /**
      * 设备ID
      */
-    @TableField("dev_id")
-    private String devId;
+    @TableField("client_id")
+    private String clientId;
 
     /**
      * 用户openid
@@ -149,7 +149,7 @@ public class DevInfo extends BasePO {
      * target数组
      */
     @TableField("target_points")
-    private Object targetPoints;
+    private String targetPoints;
 
     /**
      * 接收target时间

+ 13 - 6
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/po/DevRoom.java

@@ -15,19 +15,26 @@ public class DevRoom extends BasePO {
     /**
      * 主键ID
      */
-    @TableId(type = IdType.ASSIGN_ID)
-    private Long devRoomId;
+    @TableId(value = "room_id", type = IdType.ASSIGN_ID)
+    private Long roomId;
     
     /**
      * 设备ID
      */
     @TableField("dev_id")
-    private String devId;
-    
+    private Long devId;
+
+
+    /**
+     * 子区域
+     */
+    @TableField("sub_regions")
+    private String subRegions;
+
     /**
-     * 房间参数
+     * 家具
      */
     @TableField("room_params")
-    private String roomParams;
+    private String furnitures;
 
 } 

+ 5 - 4
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/po/DevShare.java

@@ -1,9 +1,10 @@
 package com.hfln.portal.infrastructure.po;
 
-import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
-import java.time.LocalDateTime;
 
 /**
  * 设备分享表
@@ -17,12 +18,12 @@ public class DevShare extends BasePO {
      * 主键ID
      */
     @TableId(type = IdType.ASSIGN_ID)
-    private Long devShareId;
+    private Long shareId;
 
     /**
      * 设备ID
      */
-    private String devId;
+    private Long devId;
 
     /**
      * 分享人userId

+ 10 - 4
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/po/DevTarget.java

@@ -1,9 +1,10 @@
 package com.hfln.portal.infrastructure.po;
 
-import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
-import java.math.BigDecimal;
 
 /**
  * 设备目标表
@@ -20,9 +21,9 @@ public class DevTarget extends BasePO {
     private Long devTargetId;
 
     /**
-     * 设备ID
+     * dev_info ID
      */
-    private String devId;
+    private Long devId;
 
     /**
      * 姿态
@@ -30,6 +31,11 @@ public class DevTarget extends BasePO {
     private Byte pose;
 
     /**
+     * 修正姿态
+     */
+    private Byte fixPose;
+
+    /**
      * target数组
      */
     private String targetPoints;

+ 8 - 6
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/po/EventList.java

@@ -1,9 +1,11 @@
 package com.hfln.portal.infrastructure.po;
 
-import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
-import java.time.LocalDateTime;
 
 /**
  * 事件列表表
@@ -20,14 +22,14 @@ public class EventList extends BasePO {
     private Long eventListId;
 
     /**
-     * 设备ID
+     * dev_info ID
      */
-    private String devId;
+    private Long devId;
 
     /**
      * 姿态
      */
-    private Integer pose;
+    private Byte pose;
 
     /**
      * target数组
@@ -37,7 +39,7 @@ public class EventList extends BasePO {
     /**
      * 事件类型
      */
-    private Integer event;
+    private Byte event;
 
     /**
      * 是否处理:0-未处理,1-已处理

+ 4 - 4
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/po/GroupDevMap.java

@@ -16,12 +16,12 @@ public class GroupDevMap extends BasePO {
      * 主键ID
      */
     @TableId(type = IdType.ASSIGN_ID)
-    private Long groupDevMapId;
+    private Long devMapId;
 
     /**
      * dev_group表id
      */
-    private Long devGroupId;
+    private Long groupId;
 
     /**
      * 组uuid
@@ -31,10 +31,10 @@ public class GroupDevMap extends BasePO {
     /**
      * dev_info表id
      */
-    private Long devInfoId;
+    private Long devId;
 
     /**
      * 设备id
      */
-    private String devId;
+    private String clientId;
 } 

+ 48 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/po/TblOssFile.java

@@ -0,0 +1,48 @@
+package com.hfln.portal.infrastructure.po;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * oss存储文件信息
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("tbl_oss_file")
+public class TblOssFile extends BasePO {
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "file_id", type = IdType.ASSIGN_ID)
+    private Long fileId;
+
+    /**
+     * 业务类型
+     */
+    @TableField("busi_type")
+    private String busiType;
+
+    /**
+     * 业务主键
+     */
+    @TableField("busi_key")
+    private String busiKey;
+
+    /**
+     * 文件名称
+     */
+    @TableField("file_name")
+    private String fileName;
+
+    /**
+     * 文件地址
+     */
+    @TableField("oss_url")
+    private String ossUrl;
+
+}

+ 6 - 1
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/po/UserInfo.java

@@ -16,7 +16,7 @@ public class UserInfo extends BasePO {
      * 主键ID,自增策略
      */
     @TableId(type = IdType.ASSIGN_ID)
-    private Long userInfoId;
+    private Long userId;
 
     /**
      * 用户openid,唯一标识
@@ -24,6 +24,11 @@ public class UserInfo extends BasePO {
     private String openid;
 
     /**
+     * 用户unionid,微信开发平台下唯一标识
+     */
+    private String unionId;
+
+    /**
      * 手机号
      */
     private String phone;

+ 36 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/po/WxRelation.java

@@ -0,0 +1,36 @@
+package com.hfln.portal.infrastructure.po;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 用户微信服务号关联表
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("wx_relation")
+public class WxRelation extends BasePO {
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "wx_rela_id", type = IdType.ASSIGN_ID)
+    private Long wxRelaId;
+
+    /**
+     * 小程序unionId
+     */
+    @TableField("小程序unionId")
+    private String unionId;
+
+    /**
+     * 用户微信服务号openId
+     */
+    @TableField("fwh_open_id")
+    private String fwhOpenId;
+
+}

+ 9 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/AlarmEventService.java

@@ -0,0 +1,9 @@
+package com.hfln.portal.infrastructure.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.hfln.portal.infrastructure.po.AlarmEvent;
+
+public interface AlarmEventService extends IService<AlarmEvent> {
+
+
+}

+ 3 - 1
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/DevInfoService.java

@@ -8,7 +8,7 @@ import java.util.List;
 
 public interface DevInfoService extends IService<DevInfo> {
 
-    List<DevInfo> queryDeviceList(Long userId, String keyWord,Integer status,List<String> sharedDevIds);
+    List<DevInfo> queryDeviceList(Long userId, String keyWord,Integer status,List<Long> sharedDevIds);
 
 
 
@@ -16,4 +16,6 @@ public interface DevInfoService extends IService<DevInfo> {
 
 
     Boolean updateDevice(Object identifier, DeviceBandingParams request);
+
+    List<DevInfo> queryByClientId(String clientId);
 }

+ 12 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/DevRoomService.java

@@ -0,0 +1,12 @@
+package com.hfln.portal.infrastructure.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.hfln.portal.common.dto.data.room.RoomDto;
+import com.hfln.portal.infrastructure.po.DevRoom;
+
+public interface DevRoomService extends IService<DevRoom> {
+
+    DevRoom queryByDevId(Long devId);
+
+    void saveOrUpdate(RoomDto roomDto);
+}

+ 8 - 1
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/DevShareService.java

@@ -8,8 +8,15 @@ import java.util.Optional;
 
 public interface DevShareService extends IService<DevShare> {
 
-    Optional<List<String>> queryDeviceIdByUserId(Long userId);
+    Optional<List<Long>> queryDeviceIdByUserId(Long userId);
 
+    DevShare queryByUserIdAndDevId(Long userId, Long devId);
+
+    DevShare queryBySharedUserIdAndDevId(Long sharedUserId, Long devId);
 
     List<DevShare> querySharedNumByUserId(Long userId);
+
+    DevShare queryNotDeal(Long sharerUserId, Long sharedUserId, Long devId);
+
+    List<DevShare> queryBySharedUserId(Long sharedUserId);
 }

+ 9 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/DevTargetService.java

@@ -0,0 +1,9 @@
+package com.hfln.portal.infrastructure.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.hfln.portal.infrastructure.po.DevTarget;
+
+public interface DevTargetService extends IService<DevTarget> {
+
+
+}

+ 12 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/GroupDevMapService.java

@@ -0,0 +1,12 @@
+package com.hfln.portal.infrastructure.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.hfln.portal.infrastructure.po.GroupDevMap;
+
+import java.util.List;
+
+public interface GroupDevMapService extends IService<GroupDevMap> {
+
+
+    List<GroupDevMap> queryByGroupUuid(String groupUuid);
+}

+ 15 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/OssFileService.java

@@ -0,0 +1,15 @@
+package com.hfln.portal.infrastructure.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.hfln.portal.infrastructure.po.TblOssFile;
+
+import java.util.List;
+
+public interface OssFileService extends IService<TblOssFile> {
+
+
+    List<TblOssFile> queryFile(String busiType, String busiKey);
+
+
+    TblOssFile queryOneFile(String busiType, String busiKey);
+}

+ 11 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/UserService.java

@@ -3,6 +3,8 @@ package com.hfln.portal.infrastructure.service;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.hfln.portal.infrastructure.po.UserInfo;
 
+import java.util.List;
+
 public interface UserService extends IService<UserInfo> {
 
     /**
@@ -11,7 +13,16 @@ public interface UserService extends IService<UserInfo> {
     Boolean checkOpenId(String openId);
 
     /**
+     * 根据openId查询用户是否存在可用用户
+     */
+    Boolean checkAvailableOpenId(String openId);
+
+    /**
      * 同手机号码和密码查询用户
      */
     UserInfo checkUserByPassword(String phone, String password);
+
+    List<UserInfo> queryByPhone(String sharedPhone);
+
+    UserInfo queryById(Long userId);
 }

+ 12 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/WxRelationService.java

@@ -0,0 +1,12 @@
+package com.hfln.portal.infrastructure.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.hfln.portal.infrastructure.po.WxRelation;
+
+import java.util.List;
+
+public interface WxRelationService extends IService<WxRelation> {
+
+    List<WxRelation> queryByUnionId(String unionId);
+    List<WxRelation> queryByUnionIdAndOpenId(String unionId, String fwhOpenId);
+}

+ 18 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/impl/AlarmEventServiceImpl.java

@@ -0,0 +1,18 @@
+package com.hfln.portal.infrastructure.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.hfln.portal.infrastructure.mapper.AlarmEventMapper;
+import com.hfln.portal.infrastructure.po.AlarmEvent;
+import com.hfln.portal.infrastructure.po.EventList;
+import com.hfln.portal.infrastructure.service.AlarmEventService;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+import java.util.Objects;
+
+@Service
+public class AlarmEventServiceImpl extends ServiceImpl<AlarmEventMapper, AlarmEvent> implements AlarmEventService {
+
+}

+ 10 - 3
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/impl/DevInfoServiceImpl.java

@@ -22,7 +22,7 @@ import java.util.Objects;
 public class DevInfoServiceImpl extends ServiceImpl<DevInfoMapper, DevInfo> implements DevInfoService {
 
     @Override
-    public List<DevInfo> queryDeviceList(Long userId, String keyWord, Integer status, List<String> sharedDevIds) {
+    public List<DevInfo> queryDeviceList(Long userId, String keyWord, Integer status, List<Long> sharedDevIds) {
         // 参数校验
         if (Objects.isNull(userId)) {
             return Collections.emptyList();
@@ -100,9 +100,9 @@ public class DevInfoServiceImpl extends ServiceImpl<DevInfoMapper, DevInfo> impl
 
         // 根据identifier类型决定使用哪个条件
         if (identifier instanceof Long) {
-            builder.eq(DevInfo::getDevInfoId, identifier);
-        } else if (identifier instanceof String) {
             builder.eq(DevInfo::getDevId, identifier);
+        } else if (identifier instanceof String) {
+            builder.eq(DevInfo::getClientId, identifier);
         } else {
             throw new IllegalArgumentException("不支持的设备标识类型");
         }
@@ -115,4 +115,11 @@ public class DevInfoServiceImpl extends ServiceImpl<DevInfoMapper, DevInfo> impl
 
         return this.update(updateWrapper);
     }
+
+    @Override
+    public List<DevInfo> queryByClientId(String clientId) {
+        LambdaQueryWrapper<DevInfo> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(DevInfo::getClientId, clientId);
+        return this.baseMapper.selectList(wrapper);
+    }
 }

+ 55 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/impl/DevRoomServiceImpl.java

@@ -0,0 +1,55 @@
+package com.hfln.portal.infrastructure.service.impl;
+
+import com.alibaba.fastjson2.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.hfln.portal.common.dto.data.room.RoomDto;
+import com.hfln.portal.domain.customer.util.UpdateWrapperBuilder;
+import com.hfln.portal.infrastructure.mapper.DevRoomMapper;
+import com.hfln.portal.infrastructure.po.BasePO;
+import com.hfln.portal.infrastructure.po.DevRoom;
+import com.hfln.portal.infrastructure.service.DevRoomService;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+@Service
+public class DevRoomServiceImpl extends ServiceImpl<DevRoomMapper, DevRoom> implements DevRoomService {
+
+    @Override
+    public DevRoom queryByDevId(Long devId) {
+
+        return this.baseMapper.selectOne(
+                new LambdaQueryWrapper<DevRoom>()
+                .select()
+                .eq(DevRoom::getIsDeleted, BasePO.DeleteFlag.NOT_DELETED)
+                .eq(DevRoom::getDevId, devId)
+        );
+    }
+
+    @Override
+    public void saveOrUpdate(RoomDto roomDto) {
+
+        // 先查询 不存在,则保存后更新
+        DevRoom devRoom = this.queryByDevId(roomDto.getDevId());
+        if (devRoom == null) {
+            DevRoom room = new DevRoom();
+            room.setDevId(roomDto.getDevId());
+            this.baseMapper.insert(room);
+        }
+
+        UpdateWrapperBuilder<DevRoom> builder = new UpdateWrapperBuilder<>();
+        if (CollectionUtils.isEmpty(roomDto.getFurnitures())) {
+            builder.set(DevRoom::getFurnitures, null);
+        } else {
+            builder.set(DevRoom::getFurnitures, JSON.toJSONString(roomDto.getFurnitures()));
+        }
+        if (CollectionUtils.isEmpty(roomDto.getSubRegions())) {
+            builder.set(DevRoom::getSubRegions, null);
+        } else {
+            builder.set(DevRoom::getSubRegions, JSON.toJSONString(roomDto.getSubRegions()));
+        }
+        builder.eq(DevRoom::getDevId, roomDto.getDevId());
+        builder.eq(DevRoom::getIsDeleted, BasePO.DeleteFlag.NOT_DELETED);
+        this.baseMapper.update(null, builder.build());
+    }
+}

+ 46 - 3
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/impl/DevShareServiceImpl.java

@@ -16,24 +16,50 @@ import java.util.stream.Collectors;
 public class DevShareServiceImpl extends ServiceImpl<DevShareMapper, DevShare> implements DevShareService {
 
     @Override
-    public Optional<List<String>> queryDeviceIdByUserId(Long userId) {
+    public Optional<List<Long>> queryDeviceIdByUserId(Long userId) {
         if (Objects.isNull(userId)) {
             return Optional.empty();
         }
-        List<String> deviceIds = this.baseMapper.selectObjs(
+        List<Long> deviceIds = this.baseMapper.selectObjs(
                         new LambdaQueryWrapper<DevShare>()
                                 .select(DevShare::getDevId)
                                 .eq(DevShare::getSharedUserId, userId)
                                 .eq(DevShare::getState, 1)
                                 .eq(DevShare::getIsDeleted, 0)
                 ).stream()
-                .map(obj -> (String) obj)
+                .map(obj -> (Long) obj)
                 .collect(Collectors.toList());
 
         return deviceIds.isEmpty() ? Optional.empty() : Optional.of(deviceIds);
     }
 
     @Override
+    public DevShare queryByUserIdAndDevId(Long userId, Long devId) {
+        if (Objects.isNull(userId) || Objects.isNull(devId)) {
+            return null;
+        }
+        return this.baseMapper.selectOne(
+                new LambdaQueryWrapper<DevShare>()
+                        .select()
+                        .eq(DevShare::getSharedUserId, userId)
+                        .eq(DevShare::getDevId, devId)
+                        .eq(DevShare::getState, 1)
+                        .eq(DevShare::getIsDeleted, 0)
+        );
+    }
+
+    @Override
+    public DevShare queryBySharedUserIdAndDevId(Long sharedUserId, Long devId) {
+        return this.baseMapper.selectOne(
+                new LambdaQueryWrapper<DevShare>()
+                        .select()
+                        .eq(DevShare::getSharedUserId, sharedUserId)
+                        .eq(DevShare::getDevId, devId)
+                        .eq(DevShare::getIsDeleted, 0)
+        );
+    }
+
+    @Override
     public List<DevShare> querySharedNumByUserId(Long userId) {
         LambdaQueryWrapper<DevShare> wrapper = new LambdaQueryWrapper<>();
         wrapper.eq(DevShare::getSharedUserId, userId);
@@ -42,5 +68,22 @@ public class DevShareServiceImpl extends ServiceImpl<DevShareMapper, DevShare> i
         return this.baseMapper.selectList(wrapper);
     }
 
+    @Override
+    public DevShare queryNotDeal(Long sharerUserId, Long sharedUserId, Long devId) {
+        LambdaQueryWrapper<DevShare> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(DevShare::getSharedUserId, sharedUserId);
+        wrapper.eq(DevShare::getSharerUserId, sharerUserId);
+        wrapper.eq(DevShare::getDevId, devId);
+        wrapper.eq(DevShare::getState, 0);
+        wrapper.eq(DevShare::getIsDeleted, 0);
+        return this.baseMapper.selectOne(wrapper);
+    }
 
+    @Override
+    public List<DevShare> queryBySharedUserId(Long sharedUserId) {
+        LambdaQueryWrapper<DevShare> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(DevShare::getSharedUserId, sharedUserId);
+        wrapper.eq(DevShare::getIsDeleted, 0);
+        return this.baseMapper.selectList(wrapper);
+    }
 }

+ 13 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/impl/DevTargetServiceImpl.java

@@ -0,0 +1,13 @@
+package com.hfln.portal.infrastructure.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.hfln.portal.infrastructure.mapper.DevTargetMapper;
+import com.hfln.portal.infrastructure.po.DevTarget;
+import com.hfln.portal.infrastructure.service.DevTargetService;
+import org.springframework.stereotype.Service;
+
+@Service
+public class DevTargetServiceImpl extends ServiceImpl<DevTargetMapper, DevTarget> implements DevTargetService {
+
+
+}

+ 22 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/impl/GroupDevMapServiceImpl.java

@@ -0,0 +1,22 @@
+package com.hfln.portal.infrastructure.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.hfln.portal.infrastructure.mapper.GroupDevMapMapper;
+import com.hfln.portal.infrastructure.po.BasePO;
+import com.hfln.portal.infrastructure.po.GroupDevMap;
+import com.hfln.portal.infrastructure.service.GroupDevMapService;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class GroupDevMapServiceImpl extends ServiceImpl<GroupDevMapMapper, GroupDevMap> implements GroupDevMapService {
+
+
+    @Override
+    public List<GroupDevMap> queryByGroupUuid(String groupUuid) {
+
+        return this.baseMapper.selectList(new LambdaQueryWrapper<GroupDevMap>().eq(GroupDevMap::getGroupUuid, groupUuid).eq(GroupDevMap::getIsDeleted, BasePO.DeleteFlag.NOT_DELETED));
+    }
+}

+ 40 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/impl/OssFileServiceImpl.java

@@ -0,0 +1,40 @@
+package com.hfln.portal.infrastructure.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.hfln.portal.infrastructure.mapper.TblOssFileMapper;
+import com.hfln.portal.infrastructure.po.BasePO;
+import com.hfln.portal.infrastructure.po.TblOssFile;
+import com.hfln.portal.infrastructure.service.OssFileService;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Objects;
+
+@Service
+public class OssFileServiceImpl extends ServiceImpl<TblOssFileMapper, TblOssFile> implements OssFileService {
+
+    @Override
+    public List<TblOssFile> queryFile(String busiType, String busiKey) {
+
+        LambdaQueryWrapper<TblOssFile> queryWrapper = new LambdaQueryWrapper<TblOssFile>()
+                .select()
+                .eq(TblOssFile::getIsDeleted, BasePO.DeleteFlag.NOT_DELETED)
+                .eq(TblOssFile::getBusiType, busiType);
+        if (Objects.nonNull(busiKey)) {
+            queryWrapper.eq(TblOssFile::getBusiKey, busiKey);
+        }
+        return this.baseMapper.selectList(queryWrapper);
+    }
+
+    @Override
+    public TblOssFile queryOneFile(String busiType, String busiKey) {
+        LambdaQueryWrapper<TblOssFile> queryWrapper = new LambdaQueryWrapper<TblOssFile>()
+                .select()
+                .eq(TblOssFile::getBusiType, busiType);
+        if (Objects.nonNull(busiKey)) {
+            queryWrapper.eq(TblOssFile::getBusiKey, busiKey);
+        }
+        return this.baseMapper.selectOne(queryWrapper);
+    }
+}

+ 23 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/impl/UserServiceImpl.java

@@ -4,11 +4,13 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.hfln.portal.domain.customer.util.PasswordUtil;
 import com.hfln.portal.infrastructure.mapper.UserInfoMapper;
+import com.hfln.portal.infrastructure.po.BasePO;
 import com.hfln.portal.infrastructure.po.UserInfo;
 import com.hfln.portal.infrastructure.service.UserService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 
+import java.util.List;
 import java.util.Objects;
 
 @Service
@@ -21,6 +23,13 @@ public class UserServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> imple
         return this.count(queryWrapper) > 0;
     }
 
+    public Boolean checkAvailableOpenId(String openId) {
+        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(UserInfo::getOpenid, openId);
+        queryWrapper.eq(UserInfo::getIsDeleted, 0);
+        return this.count(queryWrapper) > 0;
+    }
+
 
     public UserInfo checkUserByPassword(String phone, String password) {
         LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
@@ -35,5 +44,19 @@ public class UserServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> imple
         return null;
     }
 
+    @Override
+    public List<UserInfo> queryByPhone(String sharedPhone) {
+        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(UserInfo::getPhone, sharedPhone);
+        queryWrapper.eq(UserInfo::getIsDeleted, BasePO.DeleteFlag.NOT_DELETED);
+        return this.baseMapper.selectList(queryWrapper);
+    }
+
+    @Override
+    public UserInfo queryById(Long userId) {
+
+        return this.baseMapper.selectById(userId);
+    }
+
 
 }

+ 29 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/impl/WxRelationServiceImpl.java

@@ -0,0 +1,29 @@
+package com.hfln.portal.infrastructure.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.hfln.portal.infrastructure.mapper.WxRelationMapper;
+import com.hfln.portal.infrastructure.po.BasePO;
+import com.hfln.portal.infrastructure.po.WxRelation;
+import com.hfln.portal.infrastructure.service.WxRelationService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+@Slf4j
+public class WxRelationServiceImpl extends ServiceImpl<WxRelationMapper, WxRelation> implements WxRelationService {
+
+    @Override
+    public List<WxRelation> queryByUnionId(String unionId) {
+        return this.baseMapper.selectList(new LambdaQueryWrapper<WxRelation>().eq(WxRelation::getUnionId, unionId).eq(WxRelation::getIsDeleted, BasePO.DeleteFlag.NOT_DELETED));
+    }
+
+    @Override
+    public List<WxRelation> queryByUnionIdAndOpenId(String unionId, String fwhOpenId) {
+        return this.baseMapper.selectList(new LambdaQueryWrapper<WxRelation>().eq(WxRelation::getUnionId, unionId)
+                .eq(WxRelation::getFwhOpenId, fwhOpenId)
+                .eq(WxRelation::getIsDeleted, BasePO.DeleteFlag.NOT_DELETED));
+    }
+}

+ 18 - 0
portal-service-server/src/main/resources/bootstrap-dev.yml

@@ -53,6 +53,14 @@ lnxx:
   wechat:
     appid: wx60b2cd643b46d5eb
     secret: 15ebd7bed7b73d806eba2944f4e07592
+    #微信公众号
+    office:
+      account:
+        appId: wx9b479fa3c2af4f21
+        secret: 426effb7b58f9ba7c5f6dd1062db0074
+        templateId: -wNA7XW0_4hscmIUK-hmolNpccd-zMlyGnKUvpGdfZQ
+    bind:
+      callbackUrl: https://jkld.radar-power.cn
 # 短信验证码相关
   sms:
     tencent:
@@ -96,3 +104,13 @@ mqtt:
   max-message-size: 1048576
   ssl: false
 
+# oss 存储
+oss:
+  accessKey:
+    id: LTAI5t9ZjmmHVs7nseZx3xWT
+    secret: TbmTSDP9ztXrLa4gXBhAmjerQcKGj7
+  endpoint: oss-cn-shanghai.aliyuncs.com
+  bucket: lnxx.oss-cn-shanghai.aliyuncs.com
+  region: cn-shanghai
+  expire:
+    seconds: 300

+ 3 - 0
portal-service-server/src/main/resources/bootstrap-prod.yml

@@ -51,6 +51,9 @@ lnxx:
       basePackage: com.hfln.portal.application.controller
       title: TENANTRY-SERVICE-SERVER
       description: 业务服务
+  wechat:
+    bind:
+      callbackUrl: https://jkld.radar-power.cn
 wechat:
   appid: wx1a783618d97d999d
   secret: db43538fbd86e946c9798fed18a91df1