Jelajahi Sumber

添加单元测试

hxd 4 bulan lalu
induk
melakukan
598e32f9d3
22 mengubah file dengan 3016 tambahan dan 107 penghapusan
  1. 8 3
      portal-service-application/src/main/java/com/hfln/portal/application/controller/wap/DeviceController.java
  2. 1 9
      portal-service-application/src/main/java/com/hfln/portal/application/controller/wap/UserController.java
  3. 397 0
      portal-service-application/src/test/java/com/hfln/portal/application/controller/wap/DeviceControllerTest.java
  4. 142 0
      portal-service-application/src/test/java/com/hfln/portal/application/controller/wap/EventControllerTest.java
  5. 590 0
      portal-service-application/src/test/java/com/hfln/portal/application/controller/wap/GroupControllerTest.java
  6. 87 0
      portal-service-application/src/test/java/com/hfln/portal/application/controller/wap/HomeControllerTest.java
  7. 246 0
      portal-service-application/src/test/java/com/hfln/portal/application/controller/wap/RadarControllerTest.java
  8. 242 0
      portal-service-application/src/test/java/com/hfln/portal/application/controller/wap/RoomControllerTest.java
  9. 246 0
      portal-service-application/src/test/java/com/hfln/portal/application/controller/wap/ShareControllerTest.java
  10. 683 0
      portal-service-application/src/test/java/com/hfln/portal/application/controller/wap/UserControllerTest.java
  11. 137 0
      portal-service-application/src/test/java/com/hfln/portal/application/controller/wap/WechatControllerTest.java
  12. 1 1
      portal-service-common/src/main/java/com/hfln/portal/common/request/group/ShareGroupParams.java
  13. 2 1
      portal-service-domain/src/main/java/com/hfln/portal/domain/exception/ErrorEnum.java
  14. 2 0
      portal-service-domain/src/main/java/com/hfln/portal/domain/gateway/DeviceGateway.java
  15. 24 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/config/GlobalExceptionHandler.java
  16. 4 4
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/config/MybatisPlusConfig.java
  17. 90 76
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/config/MybatisPlusMetaObjectHandler.java
  18. 65 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/gateway/impl/DeviceGatewayImpl.java
  19. 28 10
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/gateway/impl/UserGatewayImpl.java
  20. 12 1
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/gateway/impl/sms/SmsGatewayImpl.java
  21. 2 1
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/po/UserInfo.java
  22. 7 1
      portal-service-server/pom.xml

+ 8 - 3
portal-service-application/src/main/java/com/hfln/portal/application/controller/wap/DeviceController.java

@@ -81,9 +81,7 @@ public class DeviceController {
     @GetMapping("/checkDevByUserId")
     @ApiOperation(value = "检测用户是否拥有设备")
     public ApiResult<Boolean> checkDevByUserId(@RequestParam("userId") Long userId, @RequestParam("devId") Long devId) {
-
-        deviceGateway.checkDevByUserId(userId, devId);
-        return ApiResult.success(true);
+        return ApiResult.success(deviceGateway.checkDevByUserId(userId, devId));
     }
 
     @GetMapping("/getWcTimes")
@@ -92,4 +90,11 @@ public class DeviceController {
 
         return ApiResult.success(deviceGateway.getWcTimes(devId, time));
     }
+/*
+
+    @GetMapping("/checkDevByOpenId")
+    @ApiOperation(value = "检测用户是否拥有设备")
+    public ApiResult<String> checkDevByOpenId(@RequestParam String openId , @RequestParam String clientId) {
+        return ApiResult.success(deviceGateway.checkDevByOpenId(openId, clientId));
+    }*/
 }

+ 1 - 9
portal-service-application/src/main/java/com/hfln/portal/application/controller/wap/UserController.java

@@ -119,15 +119,7 @@ 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("/updatePassword")
     @ApiOperation(value = "修改用户密码")

+ 397 - 0
portal-service-application/src/test/java/com/hfln/portal/application/controller/wap/DeviceControllerTest.java

@@ -0,0 +1,397 @@
+package com.hfln.portal.application.controller.wap;
+
+import cn.hfln.framework.dto.ApiResult;
+import com.hfln.portal.common.dto.data.device.DeviceDTO;
+import com.hfln.portal.common.request.device.DeviceListParams;
+import com.hfln.portal.common.request.device.DeviceBandingParams;
+import com.hfln.portal.common.request.device.DeviceLocationParams;
+import com.hfln.portal.common.response.device.WcTimesQueryRes;
+import com.hfln.portal.domain.gateway.DeviceGateway;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.test.util.ReflectionTestUtils;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.*;
+
+@ExtendWith(MockitoExtension.class)
+class DeviceControllerTest {
+    
+    // 常量定义
+    private static final String SUCCESS_CODE = "200";
+    private static final String TEST_OPEN_ID = "test_open_id";
+    private static final String TEST_CLIENT_ID = "test_client_id";
+    private static final String TEST_DEVICE_ID = "123456";
+    private static final Long TEST_USER_ID = 1L;
+    
+    @Mock
+    private DeviceGateway deviceGateway;
+    
+    @InjectMocks
+    private DeviceController deviceController;
+    
+    @Test
+    void deviceList_Success() {
+        // 准备测试数据
+        DeviceListParams request = new DeviceListParams();
+        request.setUserId(TEST_USER_ID);
+        request.setKeyWord("test");
+        request.setStatus(1);
+        
+        List<DeviceDTO> expectedDevices = new ArrayList<>();
+        DeviceDTO device = new DeviceDTO();
+        device.setDevId(TEST_DEVICE_ID);
+        device.setUserId(TEST_USER_ID);
+        expectedDevices.add(device);
+        
+        // 模拟Gateway行为
+        when(deviceGateway.queryDeviceList(request)).thenReturn(expectedDevices);
+        
+        // 执行测试
+        ApiResult<List<DeviceDTO>> result = deviceController.deviceList(request);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).queryDeviceList(request);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(expectedDevices, ReflectionTestUtils.getField(result, "data"));
+    }
+    
+    @Test
+    void deviceList_EmptyResult() {
+        // 准备测试数据
+        DeviceListParams request = new DeviceListParams();
+        request.setUserId(TEST_USER_ID);
+        
+        List<DeviceDTO> expectedDevices = new ArrayList<>();
+        
+        // 模拟Gateway行为
+        when(deviceGateway.queryDeviceList(request)).thenReturn(expectedDevices);
+        
+        // 执行测试
+        ApiResult<List<DeviceDTO>> result = deviceController.deviceList(request);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).queryDeviceList(request);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(expectedDevices, ReflectionTestUtils.getField(result, "data"));
+    }
+
+    @Test
+    void deviceUnBind_Success() {
+        // 准备测试数据
+        Long userId = TEST_USER_ID;
+        String clientId = TEST_CLIENT_ID;
+        
+        // 模拟Gateway行为
+        when(deviceGateway.deviceUnBind(userId, clientId)).thenReturn(true);
+        
+        // 执行测试
+        ApiResult<Boolean> result = deviceController.deviceUnBind(userId, clientId);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).deviceUnBind(userId, clientId);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(true, ReflectionTestUtils.getField(result, "data"));
+    }
+    
+    @Test
+    void deviceUnBind_Failed() {
+        // 准备测试数据
+        Long userId = TEST_USER_ID;
+        String clientId = TEST_CLIENT_ID;
+        
+        // 模拟Gateway行为
+        when(deviceGateway.deviceUnBind(userId, clientId)).thenReturn(false);
+        
+        // 执行测试
+        ApiResult<Boolean> result = deviceController.deviceUnBind(userId, clientId);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).deviceUnBind(userId, clientId);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(false, ReflectionTestUtils.getField(result, "data"));
+    }
+
+    @Test
+    void deviceBinding_Success() {
+        // 准备测试数据
+        DeviceBandingParams request = new DeviceBandingParams();
+        request.setUserId(TEST_USER_ID);
+        request.setClientId(TEST_CLIENT_ID);
+        request.setDevName("测试设备");
+        
+        // 模拟Gateway行为
+        when(deviceGateway.deviceBind(request)).thenReturn(true);
+        
+        // 执行测试
+        ApiResult<Boolean> result = deviceController.deviceBinding(request);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).deviceBind(request);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(true, ReflectionTestUtils.getField(result, "data"));
+    }
+    
+    @Test
+    void deviceBinding_Failed() {
+        // 准备测试数据
+        DeviceBandingParams request = new DeviceBandingParams();
+        request.setUserId(TEST_USER_ID);
+        request.setClientId(TEST_CLIENT_ID);
+        request.setDevName("测试设备");
+        
+        // 模拟Gateway行为
+        when(deviceGateway.deviceBind(request)).thenReturn(false);
+        
+        // 执行测试
+        ApiResult<Boolean> result = deviceController.deviceBinding(request);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).deviceBind(request);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(false, ReflectionTestUtils.getField(result, "data"));
+    }
+
+    @Test
+    void queryDeviceInfoById_Success() {
+        // 准备测试数据
+        String deviceId = TEST_DEVICE_ID;
+        DeviceDTO expectedDevice = new DeviceDTO();
+        expectedDevice.setDevId(deviceId);
+        expectedDevice.setDevName("测试设备");
+        expectedDevice.setUserId(TEST_USER_ID);
+        
+        // 模拟Gateway行为
+        when(deviceGateway.queryDeviceById(deviceId)).thenReturn(expectedDevice);
+        
+        // 执行测试
+        ApiResult<DeviceDTO> result = deviceController.queryDeviceInfoById(deviceId);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).queryDeviceById(deviceId);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(expectedDevice, ReflectionTestUtils.getField(result, "data"));
+    }
+    
+    @Test
+    void queryDeviceInfoById_NotFound() {
+        // 准备测试数据
+        String deviceId = TEST_DEVICE_ID;
+        
+        // 模拟Gateway行为
+        when(deviceGateway.queryDeviceById(deviceId)).thenReturn(null);
+        
+        // 执行测试
+        ApiResult<DeviceDTO> result = deviceController.queryDeviceInfoById(deviceId);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).queryDeviceById(deviceId);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(null, ReflectionTestUtils.getField(result, "data"));
+    }
+
+    @Test
+    void deviceRelations_Success() {
+        // 执行测试
+        ApiResult<DeviceDTO> result = deviceController.deviceRelations();
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(null, ReflectionTestUtils.getField(result, "data"));
+    }
+
+    @Test
+    void updateDevice_Success() {
+        // 准备测试数据
+        DeviceBandingParams request = new DeviceBandingParams();
+        request.setUserId(TEST_USER_ID);
+        request.setClientId(TEST_CLIENT_ID);
+        request.setDevName("更新后的设备名称");
+        
+        // 模拟Gateway行为
+        when(deviceGateway.updateDevice(request)).thenReturn(true);
+        
+        // 执行测试
+        ApiResult<Boolean> result = deviceController.updateDevice(request);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).updateDevice(request);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(true, ReflectionTestUtils.getField(result, "data"));
+    }
+    
+    @Test
+    void updateDevice_Failed() {
+        // 准备测试数据
+        DeviceBandingParams request = new DeviceBandingParams();
+        request.setUserId(TEST_USER_ID);
+        request.setClientId(TEST_CLIENT_ID);
+        request.setDevName("更新后的设备名称");
+        
+        // 模拟Gateway行为
+        when(deviceGateway.updateDevice(request)).thenReturn(false);
+        
+        // 执行测试
+        ApiResult<Boolean> result = deviceController.updateDevice(request);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).updateDevice(request);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(false, ReflectionTestUtils.getField(result, "data"));
+    }
+
+    @Test
+    void updateDeviceLocation_Success() {
+        // 准备测试数据
+        DeviceLocationParams params = new DeviceLocationParams();
+        params.setDeviceId(TEST_DEVICE_ID);
+        params.setXValue(new BigDecimal("100.5"));
+        params.setYValue(200L);
+        
+        // 模拟Gateway行为
+        when(deviceGateway.updateDeviceLocation(params)).thenReturn(true);
+        
+        // 执行测试
+        ApiResult<Boolean> result = deviceController.updateDeviceLocation(params);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).updateDeviceLocation(params);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(true, ReflectionTestUtils.getField(result, "data"));
+    }
+    
+    @Test
+    void updateDeviceLocation_Failed() {
+        // 准备测试数据
+        DeviceLocationParams params = new DeviceLocationParams();
+        params.setDeviceId(TEST_DEVICE_ID);
+        params.setXValue(new BigDecimal("100.5"));
+        params.setYValue(200L);
+        
+        // 模拟Gateway行为
+        when(deviceGateway.updateDeviceLocation(params)).thenReturn(false);
+        
+        // 执行测试
+        ApiResult<Boolean> result = deviceController.updateDeviceLocation(params);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).updateDeviceLocation(params);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(false, ReflectionTestUtils.getField(result, "data"));
+    }
+
+    @Test
+    void checkDevByUserId_Success() {
+        // 准备测试数据
+        Long userId = TEST_USER_ID;
+        Long devId = 1L;
+        
+        // 模拟Gateway行为
+        when(deviceGateway.checkDevByUserId(userId, devId)).thenReturn(true);
+        
+        // 执行测试
+        ApiResult<Boolean> result = deviceController.checkDevByUserId(userId, devId);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).checkDevByUserId(userId, devId);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(true, ReflectionTestUtils.getField(result, "data"));
+    }
+    
+    @Test
+    void checkDevByUserId_NotFound() {
+        // 准备测试数据
+        Long userId = TEST_USER_ID;
+        Long devId = 1L;
+        
+        // 模拟Gateway行为
+        when(deviceGateway.checkDevByUserId(userId, devId)).thenReturn(false);
+        
+        // 执行测试
+        ApiResult<Boolean> result = deviceController.checkDevByUserId(userId, devId);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).checkDevByUserId(userId, devId);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(false, ReflectionTestUtils.getField(result, "data"));
+    }
+
+    @Test
+    void getWcTimes_Success() {
+        // 准备测试数据
+        Long devId = 1L;
+        String time = "2024-03-20";
+        WcTimesQueryRes expectedResult = new WcTimesQueryRes();
+        expectedResult.setCount(5);
+        
+        // 模拟Gateway行为
+        when(deviceGateway.getWcTimes(devId, time)).thenReturn(expectedResult);
+        
+        // 执行测试
+        ApiResult<WcTimesQueryRes> result = deviceController.getWcTimes(devId, time);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).getWcTimes(devId, time);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(expectedResult, ReflectionTestUtils.getField(result, "data"));
+    }
+    
+    @Test
+    void getWcTimes_NoData() {
+        // 准备测试数据
+        Long devId = 1L;
+        String time = "2024-03-20";
+        
+        // 模拟Gateway行为
+        when(deviceGateway.getWcTimes(devId, time)).thenReturn(null);
+        
+        // 执行测试
+        ApiResult<WcTimesQueryRes> result = deviceController.getWcTimes(devId, time);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).getWcTimes(devId, time);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(null, ReflectionTestUtils.getField(result, "data"));
+    }
+    
+
+}

+ 142 - 0
portal-service-application/src/test/java/com/hfln/portal/application/controller/wap/EventControllerTest.java

@@ -0,0 +1,142 @@
+package com.hfln.portal.application.controller.wap;
+
+import cn.hfln.framework.dto.ApiResult;
+import com.hfln.portal.common.dto.data.event.EventListDTO;
+import com.hfln.portal.common.request.event.EventListParams;
+import com.hfln.portal.common.vo.PageRecord;
+import com.hfln.portal.domain.gateway.DeviceGateway;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.test.util.ReflectionTestUtils;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.*;
+
+@ExtendWith(MockitoExtension.class)
+class EventControllerTest {
+    
+    // 常量定义
+    private static final String SUCCESS_CODE = "200";
+    private static final String TEST_DEVICE_ID = "test_device_id";
+    private static final Long TEST_EVENT_ID = 1L;
+    
+    @Mock
+    private DeviceGateway deviceGateway;
+    
+    @InjectMocks
+    private EventController eventController;
+    
+    @Test
+    void deviceEventList_Success() {
+        // 准备测试数据
+        EventListParams request = new EventListParams();
+        request.setDeviceId(TEST_DEVICE_ID);
+        request.setStartTime(new Date());
+        request.setEndTime(new Date());
+        
+        List<EventListDTO> events = new ArrayList<>();
+        EventListDTO event = new EventListDTO();
+        event.setDevId(TEST_DEVICE_ID);
+        event.setEventListId(1L);
+        event.setPose(1);
+        event.setEvent(1);
+        event.setIsHandle(0);
+        events.add(event);
+        
+        PageRecord<EventListDTO> expectedPage = new PageRecord<>();
+        expectedPage.setRows(events);
+        expectedPage.setTotal(1L);
+        expectedPage.setPageNum(1);
+        expectedPage.setPageSize(10);
+        expectedPage.setTotalPageNum(1);
+        expectedPage.setOutTotalPageNum(false);
+        
+        // 模拟Gateway行为
+        when(deviceGateway.queryEventByPage(request)).thenReturn(expectedPage);
+        
+        // 执行测试
+        ApiResult<PageRecord<EventListDTO>> result = eventController.deviceEventList(request);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).queryEventByPage(request);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(expectedPage, ReflectionTestUtils.getField(result, "data"));
+    }
+    
+    @Test
+    void deviceEventList_EmptyResult() {
+        // 准备测试数据
+        EventListParams request = new EventListParams();
+        request.setDeviceId(TEST_DEVICE_ID);
+        request.setStartTime(new Date());
+        request.setEndTime(new Date());
+        
+        PageRecord<EventListDTO> expectedPage = new PageRecord<>();
+        expectedPage.setRows(new ArrayList<>());
+        expectedPage.setTotal(0L);
+        expectedPage.setPageNum(1);
+        expectedPage.setPageSize(10);
+        expectedPage.setTotalPageNum(0);
+        expectedPage.setOutTotalPageNum(false);
+        
+        // 模拟Gateway行为
+        when(deviceGateway.queryEventByPage(request)).thenReturn(expectedPage);
+        
+        // 执行测试
+        ApiResult<PageRecord<EventListDTO>> result = eventController.deviceEventList(request);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).queryEventByPage(request);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(expectedPage, ReflectionTestUtils.getField(result, "data"));
+    }
+    
+    @Test
+    void handleEvent_Success() {
+        // 准备测试数据
+        Long eventId = TEST_EVENT_ID;
+        
+        // 模拟Gateway行为
+        when(deviceGateway.handleEvent(eventId)).thenReturn(true);
+        
+        // 执行测试
+        ApiResult<Boolean> result = eventController.handleEvent(eventId);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).handleEvent(eventId);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(true, ReflectionTestUtils.getField(result, "data"));
+    }
+    
+    @Test
+    void handleEvent_Failed() {
+        // 准备测试数据
+        Long eventId = TEST_EVENT_ID;
+        
+        // 模拟Gateway行为
+        when(deviceGateway.handleEvent(eventId)).thenReturn(false);
+        
+        // 执行测试
+        ApiResult<Boolean> result = eventController.handleEvent(eventId);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).handleEvent(eventId);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(false, ReflectionTestUtils.getField(result, "data"));
+    }
+}

+ 590 - 0
portal-service-application/src/test/java/com/hfln/portal/application/controller/wap/GroupControllerTest.java

@@ -0,0 +1,590 @@
+package com.hfln.portal.application.controller.wap;
+
+import cn.hfln.framework.dto.ApiResult;
+import cn.hfln.framework.extension.BizException;
+import com.hfln.portal.common.dto.data.device.DeviceDTO;
+import com.hfln.portal.common.dto.data.group.GroupDTO;
+import com.hfln.portal.common.request.group.*;
+import com.hfln.portal.domain.exception.ErrorEnum;
+import com.hfln.portal.domain.gateway.GroupGateway;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.test.util.ReflectionTestUtils;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.*;
+
+@ExtendWith(MockitoExtension.class)
+class GroupControllerTest {
+    
+    // 常量定义
+    private static final String SUCCESS_CODE = "200";
+    private static final Long TEST_USER_ID = 1L;
+    private static final Long TEST_GROUP_ID = 1L;
+    private static final String TEST_GROUP_NAME = "测试群组";
+    private static final String TEST_GROUP_UUID = "test-group-uuid";
+    private static final Long TEST_DEVICE_ID = 1L;
+    
+    @Mock
+    private GroupGateway groupGateway;
+    
+    @InjectMocks
+    private GroupController groupController;
+
+    // ========== 添加群组相关测试 ==========
+    @Test
+    void addGroup_Success() {
+        // 准备测试数据
+        GroupAddParams request = new GroupAddParams();
+        request.setGroupName(TEST_GROUP_NAME);
+        request.setUserId(TEST_USER_ID);
+        
+        // 模拟Gateway行为
+        when(groupGateway.addGroup(request)).thenReturn(true);
+        
+        // 执行测试
+        ApiResult<Boolean> result = groupController.addGroup(request);
+        
+        // 验证交互
+        verify(groupGateway, times(1)).addGroup(request);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(true, ReflectionTestUtils.getField(result, "data"));
+    }
+
+    @Test
+    void addGroup_Failed() {
+        // 准备测试数据
+        GroupAddParams request = new GroupAddParams();
+        request.setGroupName(TEST_GROUP_NAME);
+        request.setUserId(TEST_USER_ID);
+        
+        // 模拟Gateway行为 - 返回失败
+        when(groupGateway.addGroup(request)).thenReturn(false);
+        
+        // 执行测试
+        ApiResult<Boolean> result = groupController.addGroup(request);
+        
+        // 验证交互
+        verify(groupGateway, times(1)).addGroup(request);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(false, ReflectionTestUtils.getField(result, "data"));
+    }
+
+    @Test
+    void addGroup_ThrowsException() {
+        // 准备测试数据
+        GroupAddParams request = new GroupAddParams();
+        request.setGroupName(TEST_GROUP_NAME);
+        request.setUserId(TEST_USER_ID);
+        
+        // 模拟Gateway行为 - 抛出异常
+        when(groupGateway.addGroup(request)).thenThrow(new BizException(ErrorEnum.USER_IS_NOT_EXIST.getErrorCode(), ErrorEnum.USER_IS_NOT_EXIST.getErrorMessage()));
+        
+        // 验证异常抛出
+        assertThrows(BizException.class, () -> groupController.addGroup(request));
+        
+        // 验证交互
+        verify(groupGateway, times(1)).addGroup(request);
+    }
+
+    // ========== 删除群组相关测试 ==========
+    @Test
+    void deleteGroup_Success() {
+        // 准备测试数据
+        Long groupId = TEST_GROUP_ID;
+        
+        // 模拟Gateway行为
+        when(groupGateway.deleteGroup(groupId)).thenReturn(true);
+        
+        // 执行测试
+        ApiResult<Boolean> result = groupController.deleteGroup(groupId);
+        
+        // 验证交互
+        verify(groupGateway, times(1)).deleteGroup(groupId);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(true, ReflectionTestUtils.getField(result, "data"));
+    }
+
+    @Test
+    void deleteGroup_Failed() {
+        // 准备测试数据
+        Long groupId = TEST_GROUP_ID;
+        
+        // 模拟Gateway行为 - 返回失败
+        when(groupGateway.deleteGroup(groupId)).thenReturn(false);
+        
+        // 执行测试
+        ApiResult<Boolean> result = groupController.deleteGroup(groupId);
+        
+        // 验证交互
+        verify(groupGateway, times(1)).deleteGroup(groupId);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(false, ReflectionTestUtils.getField(result, "data"));
+    }
+
+    @Test
+    void deleteGroup_ThrowsException() {
+        // 准备测试数据
+        Long groupId = TEST_GROUP_ID;
+        
+        // 模拟Gateway行为 - 抛出异常
+        when(groupGateway.deleteGroup(groupId)).thenThrow(new BizException(ErrorEnum.GROUP_IS_NOT_EXIST.getErrorCode(), ErrorEnum.GROUP_IS_NOT_EXIST.getErrorMessage()));
+        
+        // 验证异常抛出
+        assertThrows(BizException.class, () -> groupController.deleteGroup(groupId));
+        
+        // 验证交互
+        verify(groupGateway, times(1)).deleteGroup(groupId);
+    }
+
+    // ========== 更新群组相关测试 ==========
+    @Test
+    void updateGroup_Success() {
+        // 准备测试数据
+        GroupUpdateParams params = new GroupUpdateParams();
+        params.setGroupUuid(TEST_GROUP_UUID);
+        params.setGroupName(TEST_GROUP_NAME);
+        params.setLength(new BigDecimal("100"));
+        params.setWidth(new BigDecimal("50"));
+        params.setNorthAngle(new BigDecimal("45"));
+        
+        // 模拟Gateway行为
+        when(groupGateway.updateGroup(params)).thenReturn(true);
+        
+        // 执行测试
+        ApiResult<Boolean> result = groupController.updateGroup(params);
+        
+        // 验证交互
+        verify(groupGateway, times(1)).updateGroup(params);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(true, ReflectionTestUtils.getField(result, "data"));
+    }
+
+    @Test
+    void updateGroup_Failed() {
+        // 准备测试数据
+        GroupUpdateParams params = new GroupUpdateParams();
+        params.setGroupUuid(TEST_GROUP_UUID);
+        params.setGroupName(TEST_GROUP_NAME);
+        params.setLength(new BigDecimal("100"));
+        params.setWidth(new BigDecimal("50"));
+        params.setNorthAngle(new BigDecimal("45"));
+        
+        // 模拟Gateway行为 - 返回失败
+        when(groupGateway.updateGroup(params)).thenReturn(false);
+        
+        // 执行测试
+        ApiResult<Boolean> result = groupController.updateGroup(params);
+        
+        // 验证交互
+        verify(groupGateway, times(1)).updateGroup(params);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(false, ReflectionTestUtils.getField(result, "data"));
+    }
+
+    // ========== 查询群组列表相关测试 ==========
+    @Test
+    void groupList_Success() {
+        // 准备测试数据
+        GroupListParams request = new GroupListParams();
+        request.setUserId(TEST_USER_ID);
+        
+        List<GroupDTO> expectedGroups = new ArrayList<>();
+        GroupDTO group = new GroupDTO();
+        group.setDevGroupId(TEST_GROUP_ID);
+        group.setGroupUuid(TEST_GROUP_UUID);
+        group.setGroupName(TEST_GROUP_NAME);
+        group.setTotalDevice(5);
+        group.setOnlineDevice(3);
+        group.setWarningDevice(1);
+        expectedGroups.add(group);
+        
+        // 模拟Gateway行为
+        when(groupGateway.queryGroupList(request)).thenReturn(expectedGroups);
+        
+        // 执行测试
+        ApiResult<List<GroupDTO>> result = groupController.GroupList(request);
+        
+        // 验证交互
+        verify(groupGateway, times(1)).queryGroupList(request);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(expectedGroups, ReflectionTestUtils.getField(result, "data"));
+    }
+
+    @Test
+    void groupList_EmptyResult() {
+        // 准备测试数据
+        GroupListParams request = new GroupListParams();
+        request.setUserId(TEST_USER_ID);
+        
+        // 模拟Gateway行为 - 返回空列表
+        when(groupGateway.queryGroupList(request)).thenReturn(Collections.emptyList());
+        
+        // 执行测试
+        ApiResult<List<GroupDTO>> result = groupController.GroupList(request);
+        
+        // 验证交互
+        verify(groupGateway, times(1)).queryGroupList(request);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(Collections.emptyList(), ReflectionTestUtils.getField(result, "data"));
+    }
+
+    // ========== 查询群组设备列表相关测试 ==========
+    @Test
+    void queryGroupById_Success() {
+        // 准备测试数据
+        Long groupId = TEST_GROUP_ID;
+        
+        List<DeviceDTO> expectedDevices = new ArrayList<>();
+        DeviceDTO device = new DeviceDTO();
+        device.setDevId("1");
+        device.setDevName("测试设备");
+        expectedDevices.add(device);
+        
+        // 模拟Gateway行为
+        when(groupGateway.queryGroupDeviceInfoById(groupId)).thenReturn(expectedDevices);
+        
+        // 执行测试
+        ApiResult<List<DeviceDTO>> result = groupController.queryGroupById(groupId);
+        
+        // 验证交互
+        verify(groupGateway, times(1)).queryGroupDeviceInfoById(groupId);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(expectedDevices, ReflectionTestUtils.getField(result, "data"));
+    }
+
+    @Test
+    void queryGroupById_EmptyResult() {
+        // 准备测试数据
+        Long groupId = TEST_GROUP_ID;
+        
+        // 模拟Gateway行为 - 返回空列表
+        when(groupGateway.queryGroupDeviceInfoById(groupId)).thenReturn(Collections.emptyList());
+        
+        // 执行测试
+        ApiResult<List<DeviceDTO>> result = groupController.queryGroupById(groupId);
+        
+        // 验证交互
+        verify(groupGateway, times(1)).queryGroupDeviceInfoById(groupId);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(Collections.emptyList(), ReflectionTestUtils.getField(result, "data"));
+    }
+
+    // ========== 添加设备到群组相关测试 ==========
+    @Test
+    void addDeviceToGroup_Success() {
+        // 准备测试数据
+        AddDeviceToGroupParams request = new AddDeviceToGroupParams();
+        request.setDevId(TEST_DEVICE_ID);
+        request.setGroupId(TEST_GROUP_ID);
+        
+        // 模拟Gateway行为
+        when(groupGateway.addDeviceToGroup(request)).thenReturn(true);
+        
+        // 执行测试
+        ApiResult<Boolean> result = groupController.addDeviceToGroup(request);
+        
+        // 验证交互
+        verify(groupGateway, times(1)).addDeviceToGroup(request);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(true, ReflectionTestUtils.getField(result, "data"));
+    }
+
+    @Test
+    void addDeviceToGroup_Failed() {
+        // 准备测试数据
+        AddDeviceToGroupParams request = new AddDeviceToGroupParams();
+        request.setDevId(TEST_DEVICE_ID);
+        request.setGroupId(TEST_GROUP_ID);
+        
+        // 模拟Gateway行为 - 返回失败
+        when(groupGateway.addDeviceToGroup(request)).thenReturn(false);
+        
+        // 执行测试
+        ApiResult<Boolean> result = groupController.addDeviceToGroup(request);
+        
+        // 验证交互
+        verify(groupGateway, times(1)).addDeviceToGroup(request);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(false, ReflectionTestUtils.getField(result, "data"));
+    }
+
+    @Test
+    void addDeviceToGroup_ThrowsException() {
+        // 准备测试数据
+        AddDeviceToGroupParams request = new AddDeviceToGroupParams();
+        request.setDevId(TEST_DEVICE_ID);
+        request.setGroupId(TEST_GROUP_ID);
+        
+        // 模拟Gateway行为 - 抛出异常
+        when(groupGateway.addDeviceToGroup(request)).thenThrow(new BizException(ErrorEnum.DEVICE_IS_NOT_EXIST.getErrorCode(), ErrorEnum.DEVICE_IS_NOT_EXIST.getErrorMessage()));
+        
+        // 验证异常抛出
+        assertThrows(BizException.class, () -> groupController.addDeviceToGroup(request));
+        
+        // 验证交互
+        verify(groupGateway, times(1)).addDeviceToGroup(request);
+    }
+
+    // ========== 从群组删除设备相关测试 ==========
+    @Test
+    void deleteDeviceFromGroup_Success() {
+        // 准备测试数据
+        DeleteDeviceFromGroupParams request = new DeleteDeviceFromGroupParams();
+        request.setDevId(TEST_DEVICE_ID);
+        request.setGroupId(TEST_GROUP_ID);
+        
+        // 模拟Gateway行为
+        when(groupGateway.deleteDeviceFromGroup(request)).thenReturn(true);
+        
+        // 执行测试
+        ApiResult<Boolean> result = groupController.deleteDeviceFromGroup(request);
+        
+        // 验证交互
+        verify(groupGateway, times(1)).deleteDeviceFromGroup(request);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(true, ReflectionTestUtils.getField(result, "data"));
+    }
+
+    @Test
+    void deleteDeviceFromGroup_Failed() {
+        // 准备测试数据
+        DeleteDeviceFromGroupParams request = new DeleteDeviceFromGroupParams();
+        request.setDevId(TEST_DEVICE_ID);
+        request.setGroupId(TEST_GROUP_ID);
+        
+        // 模拟Gateway行为 - 返回失败
+        when(groupGateway.deleteDeviceFromGroup(request)).thenReturn(false);
+        
+        // 执行测试
+        ApiResult<Boolean> result = groupController.deleteDeviceFromGroup(request);
+        
+        // 验证交互
+        verify(groupGateway, times(1)).deleteDeviceFromGroup(request);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(false, ReflectionTestUtils.getField(result, "data"));
+    }
+
+    // ========== 分享群组相关测试 ==========
+    @Test
+    void shareGroup_Success() {
+        // 准备测试数据
+        ShareGroupParams request = new ShareGroupParams();
+        request.setGroupUuid(TEST_GROUP_UUID);
+        request.setSharerUserId(TEST_USER_ID);
+        request.setSharerPhone("13800138000");
+        
+        // 模拟Gateway行为
+        when(groupGateway.shareGroup(request)).thenReturn(true);
+        
+        // 执行测试
+        ApiResult<Boolean> result = groupController.shareGroup(request);
+        
+        // 验证交互
+        verify(groupGateway, times(1)).shareGroup(request);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(true, ReflectionTestUtils.getField(result, "data"));
+    }
+
+    @Test
+    void shareGroup_Failed() {
+        // 准备测试数据
+        ShareGroupParams request = new ShareGroupParams();
+        request.setGroupUuid(TEST_GROUP_UUID);
+        request.setSharerUserId(TEST_USER_ID);
+        request.setSharerPhone("13800138000");
+        
+        // 模拟Gateway行为 - 返回失败
+        when(groupGateway.shareGroup(request)).thenReturn(false);
+        
+        // 执行测试
+        ApiResult<Boolean> result = groupController.shareGroup(request);
+        
+        // 验证交互
+        verify(groupGateway, times(1)).shareGroup(request);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(false, ReflectionTestUtils.getField(result, "data"));
+    }
+
+    @Test
+    void shareGroup_ThrowsException() {
+        // 准备测试数据
+        ShareGroupParams request = new ShareGroupParams();
+        request.setGroupUuid(TEST_GROUP_UUID);
+        request.setSharerUserId(TEST_USER_ID);
+        request.setSharerPhone("13800138000");
+        
+        // 模拟Gateway行为 - 抛出异常
+        when(groupGateway.shareGroup(request)).thenThrow(new BizException(ErrorEnum.GROUP_IS_NOT_EXIST.getErrorCode(), ErrorEnum.GROUP_IS_NOT_EXIST.getErrorMessage()));
+        
+        // 验证异常抛出
+        assertThrows(BizException.class, () -> groupController.shareGroup(request));
+        
+        // 验证交互
+        verify(groupGateway, times(1)).shareGroup(request);
+    }
+
+    // ========== 群组分享确认相关测试 ==========
+    @Test
+    void groupShareConfirm_Success() {
+        // 准备测试数据
+        GroupShareConfirmParams request = new GroupShareConfirmParams();
+        request.setSharedUserId(TEST_USER_ID);
+        request.setSharedPhone("13800138000");
+        request.setUuid(TEST_GROUP_UUID);
+        
+        // 模拟Gateway行为
+        when(groupGateway.groupShareConfirm(request)).thenReturn(true);
+        
+        // 执行测试
+        ApiResult<Boolean> result = groupController.GroupShareConfirm(request);
+        
+        // 验证交互
+        verify(groupGateway, times(1)).groupShareConfirm(request);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(true, ReflectionTestUtils.getField(result, "data"));
+    }
+
+    @Test
+    void groupShareConfirm_Failed() {
+        // 准备测试数据
+        GroupShareConfirmParams request = new GroupShareConfirmParams();
+        request.setSharedUserId(TEST_USER_ID);
+        request.setSharedPhone("13800138000");
+        request.setUuid(TEST_GROUP_UUID);
+        
+        // 模拟Gateway行为 - 返回失败
+        when(groupGateway.groupShareConfirm(request)).thenReturn(false);
+        
+        // 执行测试
+        ApiResult<Boolean> result = groupController.GroupShareConfirm(request);
+        
+        // 验证交互
+        verify(groupGateway, times(1)).groupShareConfirm(request);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(false, ReflectionTestUtils.getField(result, "data"));
+    }
+
+    @Test
+    void groupShareConfirm_ThrowsException() {
+        // 准备测试数据
+        GroupShareConfirmParams request = new GroupShareConfirmParams();
+        request.setSharedUserId(TEST_USER_ID);
+        request.setSharedPhone("13800138000");
+        request.setUuid(TEST_GROUP_UUID);
+        
+        // 模拟Gateway行为 - 抛出异常
+        when(groupGateway.groupShareConfirm(request)).thenThrow(new BizException(ErrorEnum.SHARE_IS_EXPIRED.getErrorCode(), ErrorEnum.SHARE_IS_EXPIRED.getErrorMessage()));
+        
+        // 验证异常抛出
+        assertThrows(BizException.class, () -> groupController.GroupShareConfirm(request));
+        
+        // 验证交互
+        verify(groupGateway, times(1)).groupShareConfirm(request);
+    }
+
+    // ========== 群组分享处理相关测试 ==========
+    @Test
+    void groupShareHandle_Success() {
+        // 准备测试数据
+        GroupShareHandleParams request = new GroupShareHandleParams();
+        request.setState(1); // 接受状态
+        request.setUuid(TEST_GROUP_UUID);
+        
+        // 模拟Gateway行为
+        when(groupGateway.groupShareHandle(request)).thenReturn(true);
+        
+        // 执行测试
+        ApiResult<Boolean> result = groupController.groupShareHandle(request);
+        
+        // 验证交互
+        verify(groupGateway, times(1)).groupShareHandle(request);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(true, ReflectionTestUtils.getField(result, "data"));
+    }
+
+    @Test
+    void groupShareHandle_Failed() {
+        // 准备测试数据
+        GroupShareHandleParams request = new GroupShareHandleParams();
+        request.setState(2); // 拒绝状态
+        request.setUuid(TEST_GROUP_UUID);
+        
+        // 模拟Gateway行为 - 返回失败
+        when(groupGateway.groupShareHandle(request)).thenReturn(false);
+        
+        // 执行测试
+        ApiResult<Boolean> result = groupController.groupShareHandle(request);
+        
+        // 验证交互
+        verify(groupGateway, times(1)).groupShareHandle(request);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(false, ReflectionTestUtils.getField(result, "data"));
+    }
+
+    @Test
+    void groupShareHandle_ThrowsException() {
+        // 准备测试数据
+        GroupShareHandleParams request = new GroupShareHandleParams();
+        request.setState(2); // 拒绝状态
+        request.setUuid(TEST_GROUP_UUID);
+        
+        // 模拟Gateway行为 - 抛出异常
+        when(groupGateway.groupShareHandle(request)).thenThrow(new BizException(ErrorEnum.SHARE_GROUP_IS_NOT_EXIST.getErrorCode(), ErrorEnum.SHARE_GROUP_IS_NOT_EXIST.getErrorMessage()));
+        
+        // 验证异常抛出
+        assertThrows(BizException.class, () -> groupController.groupShareHandle(request));
+        
+        // 验证交互
+        verify(groupGateway, times(1)).groupShareHandle(request);
+    }
+}

+ 87 - 0
portal-service-application/src/test/java/com/hfln/portal/application/controller/wap/HomeControllerTest.java

@@ -0,0 +1,87 @@
+package com.hfln.portal.application.controller.wap;
+
+import cn.hfln.framework.dto.ApiResult;
+import cn.hfln.framework.extension.BizException;
+import com.hfln.portal.common.dto.data.home.HomeInfoDTO;
+import com.hfln.portal.domain.gateway.DeviceGateway;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.springframework.test.util.ReflectionTestUtils;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+class HomeControllerTest {
+
+    private static final Long TEST_USER_ID = 1L;
+    private static final String SUCCESS_CODE = "200";
+
+    @Mock
+    private DeviceGateway deviceGateway;
+
+    @InjectMocks
+    private HomeController homeController;
+
+    @BeforeEach
+    void setUp() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    void homeInfo_Success() {
+        // 准备测试数据
+        HomeInfoDTO expectedHomeInfo = new HomeInfoDTO();
+        expectedHomeInfo.setGroupNum(2);
+        expectedHomeInfo.setShareNum(3);
+        
+        // 模拟DeviceGateway的行为
+        when(deviceGateway.queryHomeInfo(TEST_USER_ID)).thenReturn(expectedHomeInfo);
+        
+        // 执行测试
+        ApiResult<HomeInfoDTO> result = homeController.homeInfo(TEST_USER_ID);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).queryHomeInfo(TEST_USER_ID);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(expectedHomeInfo, result.getData());
+    }
+
+    @Test
+    void homeInfo_EmptyResult() {
+        // 模拟DeviceGateway返回空结果
+        when(deviceGateway.queryHomeInfo(TEST_USER_ID)).thenReturn(null);
+        
+        // 执行测试
+        ApiResult<HomeInfoDTO> result = homeController.homeInfo(TEST_USER_ID);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).queryHomeInfo(TEST_USER_ID);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertNull(result.getData());
+    }
+
+    @Test
+    void homeInfo_Exception() {
+        // 模拟DeviceGateway抛出异常
+        when(deviceGateway.queryHomeInfo(TEST_USER_ID))
+            .thenThrow(new BizException("500", "查询首页信息失败"));
+        
+        // 执行测试 - 验证异常被正确传播
+        BizException exception = assertThrows(BizException.class, 
+            () -> homeController.homeInfo(TEST_USER_ID));
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).queryHomeInfo(TEST_USER_ID);
+        
+        // 验证异常信息
+        assertEquals("500", exception.getErrCode());
+        assertEquals("查询首页信息失败", exception.getMessage());
+    }
+}

+ 246 - 0
portal-service-application/src/test/java/com/hfln/portal/application/controller/wap/RadarControllerTest.java

@@ -0,0 +1,246 @@
+package com.hfln.portal.application.controller.wap;
+
+import cn.hfln.framework.dto.ApiResult;
+import cn.hfln.framework.extension.BizException;
+import com.hfln.portal.common.dto.data.room.RoomDto;
+import com.hfln.portal.domain.gateway.DeviceGateway;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.test.util.ReflectionTestUtils;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+@ExtendWith(MockitoExtension.class)
+class RadarControllerTest {
+
+    private static final String TEST_CLIENT_ID = "test_client_id";
+    private static final String SUCCESS_CODE = "200";
+    private static final int TEST_POSE_INDEX = 1;
+
+    @Mock
+    private DeviceGateway deviceGateway;
+
+    @InjectMocks
+    private RadarController radarController;
+
+    // ========== getVersion 测试 ==========
+    @Test
+    void getVersion_Success() {
+        // 执行测试
+        ApiResult<RoomDto> result = radarController.getVersion(TEST_CLIENT_ID);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).getVersion(TEST_CLIENT_ID);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+    }
+
+    @Test
+    void getVersion_Exception() {
+        // 模拟DeviceGateway抛出异常
+        doThrow(new BizException("500", "获取版本失败"))
+            .when(deviceGateway).getVersion(TEST_CLIENT_ID);
+        
+        // 执行测试 - 验证异常被正确传播
+        BizException exception = assertThrows(BizException.class, 
+            () -> radarController.getVersion(TEST_CLIENT_ID));
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).getVersion(TEST_CLIENT_ID);
+        
+        // 验证异常信息
+        assertEquals("500", exception.getErrCode());
+        assertEquals("获取版本失败", exception.getMessage());
+    }
+
+    // ========== reboot 测试 ==========
+    @Test
+    void reboot_Success() {
+        // 执行测试
+        ApiResult<Void> result = radarController.reboot(TEST_CLIENT_ID);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).reboot(TEST_CLIENT_ID);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+    }
+
+    @Test
+    void reboot_Exception() {
+        // 模拟DeviceGateway抛出异常
+        doThrow(new BizException("500", "设备重启失败"))
+            .when(deviceGateway).reboot(TEST_CLIENT_ID);
+        
+        // 执行测试 - 验证异常被正确传播
+        BizException exception = assertThrows(BizException.class, 
+            () -> radarController.reboot(TEST_CLIENT_ID));
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).reboot(TEST_CLIENT_ID);
+        
+        // 验证异常信息
+        assertEquals("500", exception.getErrCode());
+        assertEquals("设备重启失败", exception.getMessage());
+    }
+
+    // ========== updateOTA 测试 ==========
+    @Test
+    void updateOTA_Success() {
+        // 执行测试
+        ApiResult<Void> result = radarController.updateOTA(TEST_CLIENT_ID);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).updateOTA(TEST_CLIENT_ID);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+    }
+
+    @Test
+    void updateOTA_Exception() {
+        // 模拟DeviceGateway抛出异常
+        doThrow(new BizException("500", "OTA升级失败"))
+            .when(deviceGateway).updateOTA(TEST_CLIENT_ID);
+        
+        // 执行测试 - 验证异常被正确传播
+        BizException exception = assertThrows(BizException.class, 
+            () -> radarController.updateOTA(TEST_CLIENT_ID));
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).updateOTA(TEST_CLIENT_ID);
+        
+        // 验证异常信息
+        assertEquals("500", exception.getErrCode());
+        assertEquals("OTA升级失败", exception.getMessage());
+    }
+
+    // ========== fixPost 测试 ==========
+    @Test
+    void fixPost_Success() {
+        // 执行测试
+        ApiResult<Void> result = radarController.fixPost(TEST_CLIENT_ID, TEST_POSE_INDEX);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).fixPost(TEST_CLIENT_ID, TEST_POSE_INDEX);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+    }
+
+    @Test
+    void fixPost_Exception() {
+        // 模拟DeviceGateway抛出异常
+        doThrow(new BizException("500", "姿态修正失败"))
+            .when(deviceGateway).fixPost(TEST_CLIENT_ID, TEST_POSE_INDEX);
+        
+        // 执行测试 - 验证异常被正确传播
+        BizException exception = assertThrows(BizException.class, 
+            () -> radarController.fixPost(TEST_CLIENT_ID, TEST_POSE_INDEX));
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).fixPost(TEST_CLIENT_ID, TEST_POSE_INDEX);
+        
+        // 验证异常信息
+        assertEquals("500", exception.getErrCode());
+        assertEquals("姿态修正失败", exception.getMessage());
+    }
+
+    // ========== stopFixPost 测试 ==========
+    @Test
+    void stopFixPost_Success() {
+        // 执行测试
+        ApiResult<Void> result = radarController.stopFixPost(TEST_CLIENT_ID);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).stopFixPost(TEST_CLIENT_ID);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+    }
+
+    @Test
+    void stopFixPost_Exception() {
+        // 模拟DeviceGateway抛出异常
+        doThrow(new BizException("500", "停止姿态修正失败"))
+            .when(deviceGateway).stopFixPost(TEST_CLIENT_ID);
+        
+        // 执行测试 - 验证异常被正确传播
+        BizException exception = assertThrows(BizException.class, 
+            () -> radarController.stopFixPost(TEST_CLIENT_ID));
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).stopFixPost(TEST_CLIENT_ID);
+        
+        // 验证异常信息
+        assertEquals("500", exception.getErrCode());
+        assertEquals("停止姿态修正失败", exception.getMessage());
+    }
+
+    // ========== getInfo 测试 ==========
+    @Test
+    void getInfo_Success() {
+        // 执行测试
+        ApiResult<Void> result = radarController.getInfo(TEST_CLIENT_ID);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).getInfo(TEST_CLIENT_ID);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+    }
+
+    @Test
+    void getInfo_Exception() {
+        // 模拟DeviceGateway抛出异常
+        doThrow(new BizException("500", "获取设备信息失败"))
+            .when(deviceGateway).getInfo(TEST_CLIENT_ID);
+        
+        // 执行测试 - 验证异常被正确传播
+        BizException exception = assertThrows(BizException.class, 
+            () -> radarController.getInfo(TEST_CLIENT_ID));
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).getInfo(TEST_CLIENT_ID);
+        
+        // 验证异常信息
+        assertEquals("500", exception.getErrCode());
+        assertEquals("获取设备信息失败", exception.getMessage());
+    }
+
+    // ========== getParam 测试 ==========
+    @Test
+    void getParam_Success() {
+        // 执行测试
+        ApiResult<Void> result = radarController.getParam(TEST_CLIENT_ID);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).getParam(TEST_CLIENT_ID);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+    }
+
+    @Test
+    void getParam_Exception() {
+        // 模拟DeviceGateway抛出异常
+        doThrow(new BizException("500", "获取设备参数失败"))
+            .when(deviceGateway).getParam(TEST_CLIENT_ID);
+        
+        // 执行测试 - 验证异常被正确传播
+        BizException exception = assertThrows(BizException.class, 
+            () -> radarController.getParam(TEST_CLIENT_ID));
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).getParam(TEST_CLIENT_ID);
+        
+        // 验证异常信息
+        assertEquals("500", exception.getErrCode());
+        assertEquals("获取设备参数失败", exception.getMessage());
+    }
+}

+ 242 - 0
portal-service-application/src/test/java/com/hfln/portal/application/controller/wap/RoomControllerTest.java

@@ -0,0 +1,242 @@
+package com.hfln.portal.application.controller.wap;
+
+import cn.hfln.framework.dto.ApiResult;
+import cn.hfln.framework.extension.BizException;
+import com.hfln.portal.common.dto.data.room.RegionInfo;
+import com.hfln.portal.common.dto.data.room.RoomDto;
+import com.hfln.portal.domain.exception.ErrorEnum;
+import com.hfln.portal.domain.gateway.DeviceGateway;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.mock.web.MockMultipartFile;
+import org.springframework.test.util.ReflectionTestUtils;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+@ExtendWith(MockitoExtension.class)
+class RoomControllerTest {
+
+    private static final Long TEST_DEV_ID = 1L;
+    private static final Long TEST_ROOM_ID = 1L;
+    private static final String TEST_GROUP_UUID = "test-group-uuid";
+    private static final String SUCCESS_CODE = "200";
+
+    @Mock
+    private DeviceGateway deviceGateway;
+
+    @InjectMocks
+    private RoomController roomController;
+
+    // ========== readRoom 测试 ==========
+    @Test
+    void readRoom_Success() {
+        // 准备测试数据
+        RoomDto expectedRoom = new RoomDto();
+        expectedRoom.setRoomId(TEST_ROOM_ID);
+        expectedRoom.setDevId(TEST_DEV_ID);
+        List<RegionInfo> subRegions = new ArrayList<>();
+        List<RegionInfo> furnitures = new ArrayList<>();
+        expectedRoom.setSubRegions(subRegions);
+        expectedRoom.setFurnitures(furnitures);
+        
+        // 模拟DeviceGateway的行为
+        when(deviceGateway.readRoom(TEST_DEV_ID)).thenReturn(expectedRoom);
+        
+        // 执行测试
+        ApiResult<RoomDto> result = roomController.readRoom(TEST_DEV_ID);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).readRoom(TEST_DEV_ID);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(expectedRoom, result.getData());
+    }
+
+    @Test
+    void readRoom_NotFound() {
+        // 模拟DeviceGateway抛出异常
+        when(deviceGateway.readRoom(TEST_DEV_ID))
+            .thenThrow(new BizException(ErrorEnum.ROOM_IS_NOT_EXIST.getErrorCode(), 
+                ErrorEnum.ROOM_IS_NOT_EXIST.getErrorMessage()));
+        
+        // 执行测试 - 验证异常被正确传播
+        BizException exception = assertThrows(BizException.class, 
+            () -> roomController.readRoom(TEST_DEV_ID));
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).readRoom(TEST_DEV_ID);
+        
+        // 验证异常信息
+        assertEquals(ErrorEnum.ROOM_IS_NOT_EXIST.getErrorCode(), exception.getErrCode());
+        assertEquals(ErrorEnum.ROOM_IS_NOT_EXIST.getErrorMessage(), exception.getMessage());
+    }
+
+    // ========== saveRoom 测试 ==========
+    @Test
+    void saveRoom_Success() {
+        // 准备测试数据
+        RoomDto roomDto = new RoomDto();
+        roomDto.setDevId(TEST_DEV_ID);
+        roomDto.setRoomId(TEST_ROOM_ID);
+        
+        // 模拟DeviceGateway的行为
+        when(deviceGateway.saveRoom(roomDto)).thenReturn(true);
+        
+        // 执行测试
+        ApiResult<Boolean> result = roomController.saveRoom(roomDto);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).saveRoom(roomDto);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertTrue(result.getData());
+    }
+
+    @Test
+    void saveRoom_Failed() {
+        // 准备测试数据
+        RoomDto roomDto = new RoomDto();
+        roomDto.setDevId(TEST_DEV_ID);
+        roomDto.setRoomId(TEST_ROOM_ID);
+        
+        // 模拟DeviceGateway的行为
+        when(deviceGateway.saveRoom(roomDto)).thenReturn(false);
+        
+        // 执行测试
+        ApiResult<Boolean> result = roomController.saveRoom(roomDto);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).saveRoom(roomDto);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertFalse(result.getData());
+    }
+
+    @Test
+    void saveRoom_Exception() {
+        // 准备测试数据
+        RoomDto roomDto = new RoomDto();
+        roomDto.setDevId(TEST_DEV_ID);
+        roomDto.setRoomId(TEST_ROOM_ID);
+        
+        // 模拟DeviceGateway抛出异常
+        when(deviceGateway.saveRoom(roomDto))
+            .thenThrow(new BizException("500", "保存房间布局失败"));
+        
+        // 执行测试 - 验证异常被正确传播
+        BizException exception = assertThrows(BizException.class, 
+            () -> roomController.saveRoom(roomDto));
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).saveRoom(roomDto);
+        
+        // 验证异常信息
+        assertEquals("500", exception.getErrCode());
+        assertEquals("保存房间布局失败", exception.getMessage());
+    }
+
+    // ========== uploadFloorPlan 测试 ==========
+    @Test
+    void uploadFloorPlan_Success() throws IOException {
+        // 准备测试数据
+        MultipartFile file = new MockMultipartFile(
+            "file", "test.jpg", "image/jpeg", "test image content".getBytes());
+        
+        // 执行测试
+        ApiResult<Void> result = roomController.uploadFloorPlan(file, TEST_GROUP_UUID);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).uploadFloorPlan(file, TEST_GROUP_UUID);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+    }
+
+    @Test
+    void uploadFloorPlan_Exception() throws IOException {
+        // 准备测试数据
+        MultipartFile file = new MockMultipartFile(
+            "file", "test.jpg", "image/jpeg", "test image content".getBytes());
+        
+        // 模拟DeviceGateway抛出异常
+        doThrow(new BizException("500", "上传户型图失败"))
+            .when(deviceGateway).uploadFloorPlan(file, TEST_GROUP_UUID);
+        
+        // 执行测试 - 验证异常被正确传播
+        BizException exception = assertThrows(BizException.class, 
+            () -> roomController.uploadFloorPlan(file, TEST_GROUP_UUID));
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).uploadFloorPlan(file, TEST_GROUP_UUID);
+        
+        // 验证异常信息
+        assertEquals("500", exception.getErrCode());
+        assertEquals("上传户型图失败", exception.getMessage());
+    }
+
+    // ========== getFloorPlan 测试 ==========
+    @Test
+    void getFloorPlan_Success() {
+        // 准备测试数据
+        String expectedUrl = "http://example.com/floorplan.jpg";
+        
+        // 模拟DeviceGateway的行为
+        when(deviceGateway.getFloorPlan(TEST_GROUP_UUID)).thenReturn(expectedUrl);
+        
+        // 执行测试
+        ApiResult<String> result = roomController.getFloorPlan(TEST_GROUP_UUID);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).getFloorPlan(TEST_GROUP_UUID);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(expectedUrl, result.getData());
+    }
+
+    @Test
+    void getFloorPlan_NotFound() {
+        // 模拟DeviceGateway的行为
+        when(deviceGateway.getFloorPlan(TEST_GROUP_UUID)).thenReturn(null);
+        
+        // 执行测试
+        ApiResult<String> result = roomController.getFloorPlan(TEST_GROUP_UUID);
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).getFloorPlan(TEST_GROUP_UUID);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertNull(result.getData());
+    }
+
+    @Test
+    void getFloorPlan_Exception() {
+        // 模拟DeviceGateway抛出异常
+        when(deviceGateway.getFloorPlan(TEST_GROUP_UUID))
+            .thenThrow(new BizException("500", "获取户型图失败"));
+        
+        // 执行测试 - 验证异常被正确传播
+        BizException exception = assertThrows(BizException.class, 
+            () -> roomController.getFloorPlan(TEST_GROUP_UUID));
+        
+        // 验证交互
+        verify(deviceGateway, times(1)).getFloorPlan(TEST_GROUP_UUID);
+        
+        // 验证异常信息
+        assertEquals("500", exception.getErrCode());
+        assertEquals("获取户型图失败", exception.getMessage());
+    }
+}

+ 246 - 0
portal-service-application/src/test/java/com/hfln/portal/application/controller/wap/ShareControllerTest.java

@@ -0,0 +1,246 @@
+package com.hfln.portal.application.controller.wap;
+
+import cn.hfln.framework.dto.ApiResult;
+import cn.hfln.framework.extension.BizException;
+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.exception.ErrorEnum;
+import com.hfln.portal.domain.gateway.DeviceGateway;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+@ExtendWith(MockitoExtension.class)
+class ShareControllerTest {
+
+    private static final String SUCCESS_CODE = "200";
+    private static final Long TEST_USER_ID = 1L;
+    private static final Long TEST_DEVICE_ID = 100L;
+    private static final String TEST_PHONE = "13800138000";
+
+    @Mock
+    private DeviceGateway deviceGateway;
+
+    @InjectMocks
+    private ShareController shareController;
+
+    @BeforeEach
+    void setUp() {
+        // 初始化测试环境
+    }
+
+    // ========== devShare 测试用例 ==========
+
+    @Test
+    void devShare_Success() {
+        // 准备测试数据
+        ShareParam shareParam = new ShareParam();
+        shareParam.setDevId(TEST_DEVICE_ID);
+        shareParam.setSharerUserId(TEST_USER_ID);
+        shareParam.setSharerPhone(TEST_PHONE);
+        shareParam.setSharedPhone("13900139000");
+
+        // 模拟 Gateway 行为
+        when(deviceGateway.devShare(shareParam)).thenReturn(true);
+
+        // 执行测试
+        ApiResult<Boolean> result = shareController.devShare(shareParam);
+
+        // 验证结果
+        assertEquals(SUCCESS_CODE, result.getCode());
+        assertTrue(result.getData());
+        verify(deviceGateway, times(1)).devShare(shareParam);
+    }
+
+    @Test
+    void devShare_Failed() {
+        // 准备测试数据
+        ShareParam shareParam = new ShareParam();
+        shareParam.setDevId(TEST_DEVICE_ID);
+        shareParam.setSharerUserId(TEST_USER_ID);
+        shareParam.setSharerPhone(TEST_PHONE);
+        shareParam.setSharedPhone("13900139000");
+
+        // 模拟 Gateway 行为
+        when(deviceGateway.devShare(shareParam)).thenReturn(false);
+
+        // 执行测试
+        ApiResult<Boolean> result = shareController.devShare(shareParam);
+
+        // 验证结果
+        assertEquals(SUCCESS_CODE, result.getCode());
+        assertFalse(result.getData());
+        verify(deviceGateway, times(1)).devShare(shareParam);
+    }
+
+    @Test
+    void devShare_Exception() {
+        // 准备测试数据
+        ShareParam shareParam = new ShareParam();
+        shareParam.setDevId(TEST_DEVICE_ID);
+        shareParam.setSharerUserId(TEST_USER_ID);
+        shareParam.setSharerPhone(TEST_PHONE);
+        shareParam.setSharedPhone("13900139000");
+
+        // 模拟异常
+        when(deviceGateway.devShare(shareParam))
+            .thenThrow(new BizException(ErrorEnum.MOBILE_NOT_SIGN.getErrorCode(), 
+                ErrorEnum.MOBILE_NOT_SIGN.getErrorMessage()));
+
+        // 执行测试并验证异常
+        BizException exception = assertThrows(BizException.class, 
+            () -> shareController.devShare(shareParam));
+
+        // 验证异常信息
+        assertEquals(ErrorEnum.MOBILE_NOT_SIGN.getErrorCode(), exception.getErrCode());
+        verify(deviceGateway, times(1)).devShare(shareParam);
+    }
+
+    // ========== shareByUrl 测试用例 ==========
+
+    @Test
+    void shareByUrl_Success() {
+        // 准备测试数据
+        ShareParam shareParam = new ShareParam();
+        shareParam.setDevId(TEST_DEVICE_ID);
+        shareParam.setSharerUserId(TEST_USER_ID);
+        shareParam.setSharerPhone(TEST_PHONE);
+        shareParam.setSharedUserId(2L);
+        shareParam.setSharedPhone("13900139000");
+
+        // 模拟 Gateway 行为
+        when(deviceGateway.shareByUrl(shareParam)).thenReturn(true);
+
+        // 执行测试
+        ApiResult<Void> result = shareController.shareByUrl(shareParam);
+
+        // 验证结果
+        assertEquals(SUCCESS_CODE, result.getCode());
+        verify(deviceGateway, times(1)).shareByUrl(shareParam);
+    }
+
+    @Test
+    void shareByUrl_Exception() {
+        // 准备测试数据
+        ShareParam shareParam = new ShareParam();
+        shareParam.setDevId(TEST_DEVICE_ID);
+        shareParam.setSharerUserId(TEST_USER_ID);
+        shareParam.setSharerPhone(TEST_PHONE);
+        shareParam.setSharedUserId(2L);
+
+        // 模拟异常
+        doThrow(new BizException(ErrorEnum.EXIST_NOT_DEAL_SHARE.getErrorCode(), 
+            ErrorEnum.EXIST_NOT_DEAL_SHARE.getErrorMessage()))
+            .when(deviceGateway).shareByUrl(shareParam);
+
+        // 执行测试并验证异常
+        BizException exception = assertThrows(BizException.class, 
+            () -> shareController.shareByUrl(shareParam));
+
+        // 验证异常信息
+        assertEquals(ErrorEnum.EXIST_NOT_DEAL_SHARE.getErrorCode(), exception.getErrCode());
+        verify(deviceGateway, times(1)).shareByUrl(shareParam);
+    }
+
+    // ========== queryShare 测试用例 ==========
+
+    @Test
+    void queryShare_Success() {
+        // 准备测试数据
+        List<ShareDto> expectedShares = Arrays.asList(
+            createShareDto(1L, TEST_DEVICE_ID),
+            createShareDto(2L, TEST_DEVICE_ID + 1)
+        );
+
+        // 模拟 Gateway 行为
+        when(deviceGateway.queryShare(TEST_USER_ID)).thenReturn(expectedShares);
+
+        // 执行测试
+        ApiResult<List<ShareDto>> result = shareController.queryShare(TEST_USER_ID);
+
+        // 验证结果
+        assertEquals(SUCCESS_CODE, result.getCode());
+        assertEquals(2, result.getData().size());
+        assertEquals(expectedShares, result.getData());
+        verify(deviceGateway, times(1)).queryShare(TEST_USER_ID);
+    }
+
+    @Test
+    void queryShare_EmptyResult() {
+        // 模拟 Gateway 行为
+        when(deviceGateway.queryShare(TEST_USER_ID)).thenReturn(null);
+
+        // 执行测试
+        ApiResult<List<ShareDto>> result = shareController.queryShare(TEST_USER_ID);
+
+        // 验证结果
+        assertEquals(SUCCESS_CODE, result.getCode());
+        assertNull(result.getData());
+        verify(deviceGateway, times(1)).queryShare(TEST_USER_ID);
+    }
+
+    // ========== shareConfirm 测试用例 ==========
+
+    @Test
+    void shareConfirm_Success() {
+        // 准备测试数据
+        ShareConfirmParam confirmParam = new ShareConfirmParam();
+        confirmParam.setDevId(TEST_DEVICE_ID);
+        confirmParam.setSharedUserId(TEST_USER_ID);
+        confirmParam.setState(1);
+
+        // 模拟 Gateway 行为
+        doNothing().when(deviceGateway).shareConfirm(confirmParam);
+
+        // 执行测试
+        ApiResult<Void> result = shareController.shareConfirm(confirmParam);
+
+        // 验证结果
+        assertEquals(SUCCESS_CODE, result.getCode());
+        verify(deviceGateway, times(1)).shareConfirm(confirmParam);
+    }
+
+    @Test
+    void shareConfirm_Exception() {
+        // 准备测试数据
+        ShareConfirmParam confirmParam = new ShareConfirmParam();
+        confirmParam.setDevId(TEST_DEVICE_ID);
+        confirmParam.setSharedUserId(TEST_USER_ID);
+        confirmParam.setState(1);
+
+        // 模拟异常
+        doThrow(new BizException(ErrorEnum.SHARE_INFO_NOT_EXIST.getErrorCode(), 
+            ErrorEnum.SHARE_INFO_NOT_EXIST.getErrorMessage()))
+            .when(deviceGateway).shareConfirm(confirmParam);
+
+        // 执行测试并验证异常
+        BizException exception = assertThrows(BizException.class, 
+            () -> shareController.shareConfirm(confirmParam));
+
+        // 验证异常信息
+        assertEquals(ErrorEnum.SHARE_INFO_NOT_EXIST.getErrorCode(), exception.getErrCode());
+        verify(deviceGateway, times(1)).shareConfirm(confirmParam);
+    }
+
+    // ========== 辅助方法 ==========
+
+    private ShareDto createShareDto(Long shareId, Long devId) {
+        ShareDto dto = new ShareDto();
+        dto.setShareId(shareId);
+        dto.setDevId(devId);
+        dto.setSharerUserId(TEST_USER_ID);
+        dto.setSharerPhone(TEST_PHONE);
+        dto.setState(1);
+        return dto;
+    }
+}

+ 683 - 0
portal-service-application/src/test/java/com/hfln/portal/application/controller/wap/UserControllerTest.java

@@ -0,0 +1,683 @@
+package com.hfln.portal.application.controller.wap;
+
+import cn.hfln.framework.dto.ApiResult;
+import cn.hfln.framework.extension.BizException;
+import com.hfln.portal.common.dto.data.user.UserDto;
+import com.hfln.portal.common.request.user.*;
+import com.hfln.portal.common.response.user.UserInfoWxRes;
+import com.hfln.portal.domain.exception.ErrorEnum;
+import com.hfln.portal.domain.gateway.UserGateway;
+import com.hfln.portal.domain.gateway.sms.SmsGateway;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.test.util.ReflectionTestUtils;
+
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.*;
+
+@ExtendWith(MockitoExtension.class)
+class UserControllerTest {
+    
+    // 常量定义
+    private static final String SUCCESS_CODE = "200";
+    private static final String TEST_PHONE = "13800138000";
+    private static final String TEST_OPENID = "test_open_id";
+    private static final String TEST_UNIONID = "test_union_id";
+    private static final String TEST_PASSWORD = "password123";
+    private static final String TEST_SMS_CODE = "123456";
+    private static final String EXPECTED_OPENID_FAIL_MSG = "获取openId失败!";
+    private static final String EXPECTED_LOGIN_FAIL_MSG = "登录失败";
+    private static final String EXPECTED_SMS_SUCCESS_MSG = "发送短信验证码成功!";
+    private static final String EXPECTED_SMS_FAIL_MSG = "发送短信验证码失败!";
+    private static final String EXPECTED_SIGNUP_SUCCESS_MSG = "注册成功!";
+    private static final String EXPECTED_SIGNUP_FAIL_MSG = "注册失败!";
+    private static final String EXPECTED_WX_LOGIN_FAIL_MSG = "微信登录失败!";
+    private static final String EXPECTED_LOGIN_SUCCESS_MSG = "登录成功";
+
+    @Mock
+    private UserGateway userGateway;
+
+    @Mock
+    private SmsGateway smsGateway;
+
+    @InjectMocks
+    private UserController userController;
+
+    @Test
+    void queryForOpenId_Success() {
+        // 准备测试数据
+        String testCode = "testCode";
+        String expectedOpenId = TEST_OPENID;
+        
+        // 模拟UserGateway的行为
+        when(userGateway.getOpenId(testCode)).thenReturn(expectedOpenId);
+        
+        // 执行测试
+        ApiResult<String> result = userController.queryForOpenId(testCode);
+        
+        // 验证交互
+        verify(userGateway, times(1)).getOpenId(testCode);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(expectedOpenId, ReflectionTestUtils.getField(result, "data"));
+    }
+
+    @Test
+    void queryForOpenId_Failed() {
+        // 准备测试数据
+        String testCode = "invalidCode";
+        
+        // 模拟UserGateway的行为
+        when(userGateway.getOpenId(testCode)).thenReturn("");
+        
+        // 执行测试
+        ApiResult<String> result = userController.queryForOpenId(testCode);
+        
+        // 验证交互
+        verify(userGateway, times(1)).getOpenId(testCode);
+        
+        // 验证结果
+        assertNotEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(EXPECTED_OPENID_FAIL_MSG, ReflectionTestUtils.getField(result, "message"));
+    }
+
+    @Test
+    void queryForOpenId_Exception() {
+        // 准备测试数据
+        String testCode = "exceptionCode";
+        
+        // 模拟UserGateway抛出异常
+        when(userGateway.getOpenId(testCode)).thenThrow(new BizException(ErrorEnum.WECHAT_CODE_ISNULL.getErrorCode(), ErrorEnum.WECHAT_CODE_ISNULL.getErrorMessage()));
+        
+        // 执行测试 - 验证异常被正确传播
+        assertThrows(BizException.class, () -> userController.queryForOpenId(testCode));
+        
+        // 验证交互
+        verify(userGateway, times(1)).getOpenId(testCode);
+    }
+
+    @Test
+    void loginWx_Success() {
+        // 准备测试数据
+        String testCode = "validWxCode";
+        UserInfoWxRes expectedUserInfo = createTestUserInfoWxRes();
+        
+        // 模拟UserGateway的行为
+        when(userGateway.loginWx(testCode)).thenReturn(expectedUserInfo);
+        
+        // 执行测试
+        ApiResult<UserInfoWxRes> result = userController.loginWx(testCode);
+        
+        // 验证交互
+        verify(userGateway, times(1)).loginWx(testCode);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        
+        UserInfoWxRes resultData = (UserInfoWxRes) ReflectionTestUtils.getField(result, "data");
+        assertNotNull(resultData);
+        assertEquals(expectedUserInfo.getOpenId(), resultData.getOpenId());
+        assertEquals(expectedUserInfo.getUnionId(), resultData.getUnionId());
+    }
+    
+    @Test
+    void loginWx_Failed() {
+        // 准备测试数据
+        String testCode = "invalidWxCode";
+        
+        // 模拟UserGateway的行为
+        when(userGateway.loginWx(testCode)).thenReturn(null);
+        
+        // 执行测试
+        ApiResult<UserInfoWxRes> result = userController.loginWx(testCode);
+        
+        // 验证交互
+        verify(userGateway, times(1)).loginWx(testCode);
+        
+        // 验证结果
+        assertNotEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(EXPECTED_WX_LOGIN_FAIL_MSG, ReflectionTestUtils.getField(result, "message"));
+        assertNull(ReflectionTestUtils.getField(result, "data"));
+    }
+
+    @Test
+    void loginWx_Exception() {
+        // 准备测试数据
+        String testCode = "exceptionCode";
+        
+        // 模拟UserGateway抛出异常
+        when(userGateway.loginWx(testCode)).thenThrow(new BizException(ErrorEnum.WECHAT_INTERFACE_CALL_EXCEPTION.getErrorCode(), ErrorEnum.WECHAT_INTERFACE_CALL_EXCEPTION.getErrorMessage()));
+        
+        // 执行测试 - 验证异常被正确传播
+        assertThrows(BizException.class, () -> userController.loginWx(testCode));
+        
+        // 验证交互
+        verify(userGateway, times(1)).loginWx(testCode);
+    }
+
+    @Test
+    void loginByPhone_Success() {
+        // 准备测试数据
+        PhoneLoginParams params = createTestPhoneLoginParams(TEST_PHONE, TEST_OPENID, TEST_UNIONID);
+        
+        // 模拟UserGateway的行为
+        when(userGateway.loginByPhone(params)).thenReturn(true);
+        
+        // 执行测试
+        ApiResult<String> result = userController.loginByPhone(params);
+        
+        // 验证交互
+        verify(userGateway, times(1)).loginByPhone(params);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(EXPECTED_LOGIN_SUCCESS_MSG, ReflectionTestUtils.getField(result, "data"));
+    }
+    
+    @Test
+    void loginByPhone_Failed() {
+        // 准备测试数据
+        PhoneLoginParams params = createTestPhoneLoginParams(TEST_PHONE, "invalid_open_id", TEST_UNIONID);
+        
+        // 模拟UserGateway的行为
+        when(userGateway.loginByPhone(params)).thenReturn(false);
+        
+        // 执行测试
+        ApiResult<String> result = userController.loginByPhone(params);
+        
+        // 验证交互
+        verify(userGateway, times(1)).loginByPhone(params);
+        
+        // 验证结果
+        assertNotEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(EXPECTED_LOGIN_FAIL_MSG, ReflectionTestUtils.getField(result, "message"));
+    }
+
+    @Test
+    void loginByPhone_Exception() {
+        // 准备测试数据
+        PhoneLoginParams params = createTestPhoneLoginParams(TEST_PHONE, TEST_OPENID, TEST_UNIONID);
+        
+        // 模拟UserGateway抛出异常
+        when(userGateway.loginByPhone(params)).thenThrow(new RuntimeException("数据库连接失败"));
+        
+        // 执行测试 - 验证异常被正确传播
+        assertThrows(RuntimeException.class, () -> userController.loginByPhone(params));
+        
+        // 验证交互
+        verify(userGateway, times(1)).loginByPhone(params);
+    }
+
+    @Test
+    void getLoginSmsCode_Success() {
+        // 准备测试数据
+        String phone = TEST_PHONE;
+        
+        // 模拟SmsGateway的行为
+        when(smsGateway.sendLoginSmsCode(phone)).thenReturn(true);
+        
+        // 执行测试
+        ApiResult<String> result = userController.getLoginSmsCode(phone);
+        
+        // 验证交互
+        verify(smsGateway, times(1)).sendLoginSmsCode(phone);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(EXPECTED_SMS_SUCCESS_MSG, ReflectionTestUtils.getField(result, "data"));
+    }
+    
+    @Test
+    void getLoginSmsCode_Failed() {
+        // 准备测试数据
+        String phone = "invalid_phone";
+        
+        // 模拟SmsGateway的行为
+        when(smsGateway.sendLoginSmsCode(phone)).thenReturn(false);
+        
+        // 执行测试
+        ApiResult<String> result = userController.getLoginSmsCode(phone);
+        
+        // 验证交互
+        verify(smsGateway, times(1)).sendLoginSmsCode(phone);
+        
+        // 验证结果
+        assertNotEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(EXPECTED_SMS_FAIL_MSG, ReflectionTestUtils.getField(result, "message"));
+    }
+
+    @Test
+    void loginByPassword_Success() {
+        // 准备测试数据
+        UserLoginParams request = createTestUserLoginParams();
+        UserDto expectedUserDto = createTestUserDto();
+
+        // 模拟UserGateway的行为
+        when(userGateway.loginByPassword(request)).thenReturn(expectedUserDto);
+
+        // 执行测试
+        ApiResult<UserDto> result = userController.loginByPassword(request);
+
+        // 验证交互
+        verify(userGateway, times(1)).loginByPassword(request);
+
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+
+        UserDto resultData = (UserDto) ReflectionTestUtils.getField(result, "data");
+        assertNotNull(resultData);
+        assertEquals(expectedUserDto.getUserId(), resultData.getUserId());
+        assertEquals(expectedUserDto.getPhone(), resultData.getPhone());
+        assertEquals(expectedUserDto.getOpenid(), resultData.getOpenid());
+    }
+
+    @Test
+    void loginByPassword_Exception() {
+        // 准备测试数据
+        UserLoginParams request = createTestUserLoginParams();
+        
+        // 模拟UserGateway抛出异常
+        when(userGateway.loginByPassword(request)).thenThrow(new BizException(ErrorEnum.USERNAME_OR_PASSWORD_ERROR.getErrorCode(), ErrorEnum.USERNAME_OR_PASSWORD_ERROR.getErrorMessage()));
+        
+        // 执行测试 - 验证异常被正确传播
+        assertThrows(BizException.class, () -> userController.loginByPassword(request));
+        
+        // 验证交互
+        verify(userGateway, times(1)).loginByPassword(request);
+    }
+
+    @Test
+    void getSignupSmsCode_Success() {
+        // 准备测试数据
+        String phone = TEST_PHONE;
+        
+        // 模拟SmsGateway的行为
+        when(smsGateway.sendSignupSmsCode(phone)).thenReturn(true);
+        
+        // 执行测试
+        ApiResult<String> result = userController.getSignupSmsCode(phone);
+        
+        // 验证交互
+        verify(smsGateway, times(1)).sendSignupSmsCode(phone);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(EXPECTED_SMS_SUCCESS_MSG, ReflectionTestUtils.getField(result, "data"));
+    }
+    
+    @Test
+    void getSignupSmsCode_Failed() {
+        // 准备测试数据
+        String phone = "invalid_phone";
+        
+        // 模拟SmsGateway的行为
+        when(smsGateway.sendSignupSmsCode(phone)).thenReturn(false);
+        
+        // 执行测试
+        ApiResult<String> result = userController.getSignupSmsCode(phone);
+        
+        // 验证交互
+        verify(smsGateway, times(1)).sendSignupSmsCode(phone);
+        
+        // 验证结果
+        assertNotEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(EXPECTED_SMS_FAIL_MSG, ReflectionTestUtils.getField(result, "message"));
+    }
+
+    @Test
+    void signup_Success() {
+        // 准备测试数据
+        UserSignupParams request = createTestSignupParams();
+        
+        // 模拟UserGateway的行为
+        when(userGateway.signup(request)).thenReturn(true);
+        
+        // 执行测试
+        ApiResult<String> result = userController.signup(request);
+        
+        // 验证交互
+        verify(userGateway, times(1)).signup(request);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(EXPECTED_SIGNUP_SUCCESS_MSG, ReflectionTestUtils.getField(result, "data"));
+    }
+    
+    @Test
+    void signup_Failed() {
+        // 准备测试数据
+        UserSignupParams request = createTestSignupParams();
+        request.setPassword("invalid_password");
+        
+        // 模拟UserGateway的行为
+        when(userGateway.signup(request)).thenReturn(false);
+        
+        // 执行测试
+        ApiResult<String> result = userController.signup(request);
+        
+        // 验证交互
+        verify(userGateway, times(1)).signup(request);
+        
+        // 验证结果
+        assertNotEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(EXPECTED_SIGNUP_FAIL_MSG, ReflectionTestUtils.getField(result, "message"));
+    }
+
+    @Test
+    void signup_Exception() {
+        // 准备测试数据
+        UserSignupParams request = createTestSignupParams();
+        
+        // 模拟UserGateway抛出异常
+        when(userGateway.signup(request)).thenThrow(new BizException(ErrorEnum.SMS_CODE_ERROR.getErrorCode(), ErrorEnum.SMS_CODE_ERROR.getErrorMessage()));
+        
+        // 执行测试 - 验证异常被正确传播
+        assertThrows(BizException.class, () -> userController.signup(request));
+        
+        // 验证交互
+        verify(userGateway, times(1)).signup(request);
+    }
+
+    @Test
+    void checkOpenid_Success() {
+        // 准备测试数据
+        String openid = "valid_openid";
+        
+        // 模拟UserGateway的行为
+        when(userGateway.checkOpenId(openid)).thenReturn(true);
+        
+        // 执行测试
+        ApiResult<Boolean> result = userController.checkOpenid(openid);
+        
+        // 验证交互
+        verify(userGateway, times(1)).checkOpenId(openid);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(true, ReflectionTestUtils.getField(result, "data"));
+    }
+    
+    @Test
+    void checkOpenid_NotExist() {
+        // 准备测试数据
+        String openid = "non_existent_openid";
+        
+        // 模拟UserGateway的行为
+        when(userGateway.checkOpenId(openid)).thenReturn(false);
+        
+        // 执行测试
+        ApiResult<Boolean> result = userController.checkOpenid(openid);
+        
+        // 验证交互
+        verify(userGateway, times(1)).checkOpenId(openid);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(false, ReflectionTestUtils.getField(result, "data"));
+    }
+
+    @Test
+    void loginBySmsCode_Success() {
+        // 准备测试数据
+        LoginBySmsCodeParams request = createTestLoginBySmsCodeParams();
+        UserDto expectedUserDto = createTestUserDto();
+        
+        // 模拟UserGateway的行为
+        when(userGateway.loginBySmsCode(request)).thenReturn(expectedUserDto);
+        
+        // 执行测试
+        ApiResult<UserDto> result = userController.loginBySmsCode(request);
+        
+        // 验证交互
+        verify(userGateway, times(1)).loginBySmsCode(request);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        
+        UserDto resultData = (UserDto) ReflectionTestUtils.getField(result, "data");
+        assertNotNull(resultData);
+        assertEquals(expectedUserDto.getUserId(), resultData.getUserId());
+        assertEquals(expectedUserDto.getPhone(), resultData.getPhone());
+        assertEquals(expectedUserDto.getOpenid(), resultData.getOpenid());
+    }
+
+    @Test
+    void loginBySmsCode_Failed() {
+        // 准备测试数据
+        LoginBySmsCodeParams request = createTestLoginBySmsCodeParams();
+
+        // 模拟UserGateway的行为 - 抛出异常表示登录失败
+        when(userGateway.loginBySmsCode(request))
+                .thenThrow((new BizException(
+                        ErrorEnum.SMS_CODE_ERROR.getErrorCode(),
+                        ErrorEnum.SMS_CODE_ERROR.getErrorMessage())));
+
+        // 执行测试并验证应抛出异常
+        BizException exception = assertThrows(BizException.class, () -> userController.loginBySmsCode(request));
+
+        // 验证异常内容
+        assertEquals(ErrorEnum.SMS_CODE_ERROR.getErrorCode(), exception.getErrCode());
+        assertEquals(ErrorEnum.SMS_CODE_ERROR.getErrorMessage(), exception.getMessage());
+
+        // 验证交互
+        verify(userGateway, times(1)).loginBySmsCode(request);
+    }
+
+    @Test
+    void loginBySmsCode_Exception() {
+        // 准备测试数据
+        LoginBySmsCodeParams request = createTestLoginBySmsCodeParams();
+
+        // 模拟UserGateway抛出异常
+        when(userGateway.loginBySmsCode(request)).thenThrow(new BizException(ErrorEnum.SMS_CODE_EXPIRED.getErrorCode(), ErrorEnum.SMS_CODE_EXPIRED.getErrorMessage()));
+
+        // 执行测试 - 验证异常被正确传播
+        assertThrows(BizException.class, () -> userController.loginBySmsCode(request));
+
+        // 验证交互
+        verify(userGateway, times(1)).loginBySmsCode(request);
+    }
+
+
+
+    @Test
+    void getUserPhone_Success() {
+        // 准备测试数据
+        String code = "valid_code";
+        String expectedPhone = TEST_PHONE;
+        
+        // 模拟UserGateway的行为
+        when(userGateway.getUserPhone(code)).thenReturn(expectedPhone);
+        
+        // 执行测试
+        ApiResult<Map<String, String>> result = userController.getUserPhone(code);
+        
+        // 验证交互
+        verify(userGateway, times(1)).getUserPhone(code);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        
+        @SuppressWarnings("unchecked")
+        Map<String, String> resultData = (Map<String, String>) ReflectionTestUtils.getField(result, "data");
+        assertNotNull(resultData);
+        assertEquals(expectedPhone, resultData.get("phone"));
+    }
+
+    @Test
+    void getUserPhone_Failed() {
+        // 准备测试数据
+        String invalidCode = "invalid_code";
+
+        // 模拟UserGateway的行为 - 返回空字符串表示获取失败
+        when(userGateway.getUserPhone(invalidCode))
+                .thenThrow((new BizException(
+                        ErrorEnum.WECHAT_CODE_ISNULL.getErrorCode(),
+                        ErrorEnum.WECHAT_CODE_ISNULL.getErrorMessage())));
+
+        // 执行测试并验证应抛出异常
+       BizException exception = assertThrows(BizException.class, () -> userController.getUserPhone(invalidCode));
+
+        // 验证异常内容
+        assertEquals(ErrorEnum.WECHAT_CODE_ISNULL.getErrorCode(), exception.getErrCode());
+        assertEquals(ErrorEnum.WECHAT_CODE_ISNULL.getErrorMessage(), exception.getMessage());
+
+
+        // 验证交互
+        verify(userGateway, times(1)).getUserPhone(invalidCode);
+    }
+    @Test
+    void getUserPhone_Exception() {
+        // 准备测试数据
+        String code = "invalid_code";
+        
+        // 模拟UserGateway抛出异常
+        when(userGateway.getUserPhone(code)).thenThrow(new BizException(ErrorEnum.WECHAT_CODE_ISNULL.getErrorCode(), ErrorEnum.WECHAT_CODE_ISNULL.getErrorMessage()));
+        
+        // 执行测试 - 验证异常被正确传播
+        assertThrows(BizException.class, () -> userController.getUserPhone(code));
+        
+        // 验证交互
+        verify(userGateway, times(1)).getUserPhone(code);
+    }
+
+
+    @Test
+    void updatePassword_Success() {
+        // 准备测试数据
+        UserUpdatePasswordParams request = createTestUpdatePasswordParams();
+        
+        // 模拟UserGateway的行为
+        doNothing().when(userGateway).updatePassword(request);
+        
+        // 执行测试
+        ApiResult<?> result = userController.updatePassword(request);
+        
+        // 验证交互
+        verify(userGateway, times(1)).updatePassword(request);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+    }
+
+    @Test
+    void updatePassword_Exception() {
+        // 准备测试数据
+        UserUpdatePasswordParams request = createTestUpdatePasswordParams();
+        
+        // 模拟UserGateway抛出异常
+        doThrow(new BizException(ErrorEnum.USERNAME_OR_PASSWORD_ERROR.getErrorCode(), ErrorEnum.USERNAME_OR_PASSWORD_ERROR.getErrorMessage()))
+            .when(userGateway).updatePassword(request);
+        
+        // 执行测试 - 验证异常被正确传播
+        assertThrows(BizException.class, () -> userController.updatePassword(request));
+        
+        // 验证交互
+        verify(userGateway, times(1)).updatePassword(request);
+    }
+
+    @Test
+    void logout_Success() {
+        // 准备测试数据
+        UserLogoutParams request = createTestLogoutParams();
+        
+        // 模拟UserGateway的行为
+        doNothing().when(userGateway).logout(request);
+        
+        // 执行测试
+        ApiResult<?> result = userController.logout(request);
+        
+        // 验证交互
+        verify(userGateway, times(1)).logout(request);
+        
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+    }
+
+    @Test
+    void logout_Exception() {
+        // 准备测试数据
+        UserLogoutParams request = createTestLogoutParams();
+        
+        // 模拟UserGateway抛出异常
+        doThrow(new RuntimeException("用户注销失败")).when(userGateway).logout(request);
+        
+        // 执行测试 - 验证异常被正确传播
+        assertThrows(RuntimeException.class, () -> userController.logout(request));
+        
+        // 验证交互
+        verify(userGateway, times(1)).logout(request);
+    }
+
+
+
+    // 辅助方法
+    private PhoneLoginParams createTestPhoneLoginParams(String phone, String openId, String unionId) {
+        PhoneLoginParams params = new PhoneLoginParams();
+        params.setPhone(phone);
+        params.setOpenId(openId);
+        params.setUnionId(unionId);
+        return params;
+    }
+    
+    private UserInfoWxRes createTestUserInfoWxRes() {
+        UserInfoWxRes userInfo = new UserInfoWxRes();
+        userInfo.setOpenId(TEST_OPENID);
+        userInfo.setUnionId(TEST_UNIONID);
+        return userInfo;
+    }
+    
+    private UserSignupParams createTestSignupParams() {
+        UserSignupParams params = new UserSignupParams();
+        params.setPhone(TEST_PHONE);
+        params.setPassword(TEST_PASSWORD);
+        params.setCode(TEST_SMS_CODE);
+        params.setOpenId(TEST_OPENID);
+        params.setUnionId(TEST_UNIONID);
+        return params;
+    }
+    
+    private LoginBySmsCodeParams createTestLoginBySmsCodeParams() {
+        LoginBySmsCodeParams params = new LoginBySmsCodeParams();
+        params.setUserName(TEST_PHONE);
+        params.setSmsCode(TEST_SMS_CODE);
+        return params;
+    }
+    
+    private UserLoginParams createTestUserLoginParams() {
+        UserLoginParams params = new UserLoginParams();
+        params.setUserName(TEST_PHONE);
+        params.setPassword(TEST_PASSWORD);
+        return params;
+    }
+    
+    private UserDto createTestUserDto() {
+        UserDto userDto = new UserDto();
+        userDto.setUserId(1L);
+        userDto.setPhone(TEST_PHONE);
+        userDto.setOpenid(TEST_OPENID);
+        return userDto;
+    }
+    
+    private UserUpdatePasswordParams createTestUpdatePasswordParams() {
+        UserUpdatePasswordParams params = new UserUpdatePasswordParams();
+        params.setUserId(1L);
+        params.setOldPassword("old_password");
+        params.setNewPassword("new_password");
+        return params;
+    }
+    
+    private UserLogoutParams createTestLogoutParams() {
+        UserLogoutParams params = new UserLogoutParams();
+        params.setUserId(1L);
+        return params;
+    }
+}

+ 137 - 0
portal-service-application/src/test/java/com/hfln/portal/application/controller/wap/WechatControllerTest.java

@@ -0,0 +1,137 @@
+package com.hfln.portal.application.controller.wap;
+
+import cn.hfln.framework.dto.ApiResult;
+import cn.hfln.framework.extension.BizException;
+import com.hfln.portal.domain.exception.ErrorEnum;
+import com.hfln.portal.domain.gateway.UserGateway;
+import me.chanjar.weixin.mp.api.WxMpService;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.test.util.ReflectionTestUtils;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+@ExtendWith(MockitoExtension.class)
+class WechatControllerTest {
+
+    private static final String SUCCESS_CODE = "200";
+    private static final String TEST_AUTH_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=test";
+    private static final String TEST_WELCOME_URL = "/welcome.html?nickname=testUser&avatar=testAvatar";
+    private static final String TEST_CODE = "test_code";
+
+    @Mock
+    private UserGateway userGateway;
+
+    @InjectMocks
+    private WechatController wechatController;
+
+    @Test
+    void authUrl_Success() throws IOException {
+        // 准备测试数据
+        MockHttpServletResponse response = new MockHttpServletResponse();
+        when(userGateway.authUrl()).thenReturn(TEST_AUTH_URL);
+
+        // 执行测试
+        ApiResult<Void> result = wechatController.authUrl(response);
+
+        // 验证交互
+        verify(userGateway, times(1)).authUrl();
+
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(TEST_AUTH_URL, response.getRedirectedUrl());
+    }
+
+    @Test
+    void authUrl_Exception() throws IOException {
+        // 准备测试数据
+        MockHttpServletResponse response = new MockHttpServletResponse();
+        when(userGateway.authUrl()).thenThrow(new RuntimeException("Failed to get auth URL"));
+
+        // 执行测试并验证异常
+        assertThrows(RuntimeException.class, () -> wechatController.authUrl(response));
+
+        // 验证交互
+        verify(userGateway, times(1)).authUrl();
+    }
+
+    @Test
+    void callback_Success() throws IOException {
+        // 准备测试数据
+        MockHttpServletResponse response = new MockHttpServletResponse();
+        when(userGateway.callback(TEST_CODE)).thenReturn(TEST_WELCOME_URL);
+
+        // 执行测试
+        ApiResult<Void> result = wechatController.callback(TEST_CODE, "state123", response);
+
+        // 验证交互
+        verify(userGateway, times(1)).callback(TEST_CODE);
+
+        // 验证结果
+        assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
+        assertEquals(TEST_WELCOME_URL, response.getRedirectedUrl());
+    }
+
+    @Test
+    void callback_EmptyCode() throws IOException {
+        // 准备测试数据
+        MockHttpServletResponse response = new MockHttpServletResponse();
+        when(userGateway.callback("")).thenThrow(new BizException(
+            ErrorEnum.WECHAT_CODE_NOT_EXIST.getErrorCode(),
+            ErrorEnum.WECHAT_CODE_NOT_EXIST.getErrorMessage()
+        ));
+
+        // 执行测试并验证异常
+        BizException exception = assertThrows(BizException.class, 
+            () -> wechatController.callback("", "state123", response));
+
+        // 验证异常内容
+        assertEquals(ErrorEnum.WECHAT_CODE_NOT_EXIST.getErrorCode(), exception.getErrCode());
+        assertEquals(ErrorEnum.WECHAT_CODE_NOT_EXIST.getErrorMessage(), exception.getMessage());
+
+        // 验证交互
+        verify(userGateway, times(1)).callback("");
+    }
+
+    @Test
+    void callback_NullCode() throws IOException {
+        // 准备测试数据
+        MockHttpServletResponse response = new MockHttpServletResponse();
+        when(userGateway.callback(null)).thenThrow(new BizException(
+            ErrorEnum.WECHAT_CODE_NOT_EXIST.getErrorCode(),
+            ErrorEnum.WECHAT_CODE_NOT_EXIST.getErrorMessage()
+        ));
+
+        // 执行测试并验证异常
+        BizException exception = assertThrows(BizException.class, 
+            () -> wechatController.callback(null, "state123", response));
+
+        // 验证异常内容
+        assertEquals(ErrorEnum.WECHAT_CODE_NOT_EXIST.getErrorCode(), exception.getErrCode());
+        assertEquals(ErrorEnum.WECHAT_CODE_NOT_EXIST.getErrorMessage(), exception.getMessage());
+
+        // 验证交互
+        verify(userGateway, times(1)).callback(null);
+    }
+
+    @Test
+    void callback_Exception() throws IOException {
+        // 准备测试数据
+        MockHttpServletResponse response = new MockHttpServletResponse();
+        when(userGateway.callback(TEST_CODE)).thenThrow(new RuntimeException("Failed to process callback"));
+
+        // 执行测试并验证异常
+        assertThrows(RuntimeException.class, () -> wechatController.callback(TEST_CODE, "state123", response));
+
+        // 验证交互
+        verify(userGateway, times(1)).callback(TEST_CODE);
+    }
+}

+ 1 - 1
portal-service-common/src/main/java/com/hfln/portal/common/request/group/ShareGroupParams.java

@@ -16,7 +16,7 @@ public class ShareGroupParams extends BaseVO {
 
     @NotNull(message = "群组uuid不能为空")
     @ApiModelProperty(value = "群组uuid",required = true)
-    private Long groupUuid;
+    private String groupUuid;
 
     @NotNull(message = "分享人userid不能为空")
     @ApiModelProperty(value = "分享人userid",required = true)

+ 2 - 1
portal-service-domain/src/main/java/com/hfln/portal/domain/exception/ErrorEnum.java

@@ -35,7 +35,7 @@ public enum ErrorEnum implements ErrorEnumInterface{
     OLD_PASSWORD_ERROR("30004", "旧密码错误"),
     USER_IS_NOT_EXIST("30005", "用户不存在"),
     PASSWORD_IS_REPEAT("30006", "新密码与旧密码相同"),
-
+    USER_NAME_IS_NULL("30007", "用户名不能为空"),
 
     /**
      * 三方系统调用相关
@@ -48,6 +48,7 @@ public enum ErrorEnum implements ErrorEnumInterface{
      */
     DEVICE_IS_NOT_EXIST("50001", "设备不存在!"),
     DEVICE_IS_BINDING("50002", "当前设备已经被绑定!"),
+    CLIENT_ID_ID_NULL("50003", "设备ID不能为空!"),
 
     /**
      * 群组相关

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

@@ -89,4 +89,6 @@ public interface DeviceGateway {
     String getFloorPlan(String groupUuid);
 
     WcTimesQueryRes getWcTimes(Long devId, String time);
+
+    //String checkDevByOpenId(String openId, String clientId);
 }

+ 24 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/config/GlobalExceptionHandler.java

@@ -5,6 +5,7 @@ import cn.hfln.framework.extension.BizException;
 import com.alibaba.csp.sentinel.Tracer;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.http.HttpStatus;
+import org.springframework.http.converter.HttpMessageNotReadableException;
 import org.springframework.validation.BindException;
 import org.springframework.web.HttpRequestMethodNotSupportedException;
 import org.springframework.web.bind.MethodArgumentNotValidException;
@@ -39,6 +40,29 @@ public class GlobalExceptionHandler {
     }
 
     /**
+     * JSON解析异常
+     */
+    @ExceptionHandler(HttpMessageNotReadableException.class)
+    @ResponseStatus(HttpStatus.BAD_REQUEST)
+    public ApiResult<?> handleHttpMessageNotReadableException(HttpMessageNotReadableException e, HttpServletRequest request) {
+        String requestURI = request.getRequestURI();
+        log.error("请求地址'{}',JSON格式错误: {}", requestURI, e.getMessage());
+        Tracer.trace(e);
+        
+        String errorMessage = "请求参数格式错误";
+        if (e.getCause() != null && e.getCause().getMessage() != null) {
+            String causeMessage = e.getCause().getMessage();
+            if (causeMessage.contains("Unexpected character")) {
+                errorMessage = "JSON格式错误:存在意外字符,请检查JSON格式是否正确";
+            } else if (causeMessage.contains("was expecting comma")) {
+                errorMessage = "JSON格式错误:缺少逗号分隔符,请检查JSON格式";
+            }
+        }
+        
+        return ApiResult.failed("400", errorMessage);
+    }
+
+    /**
      * 业务异常
      */
     @ExceptionHandler(BizException.class)

+ 4 - 4
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/config/MybatisPlusConfig.java

@@ -31,8 +31,8 @@ public class MybatisPlusConfig {
      * 审计字段自动填充
      * @return {@link MetaObjectHandler}
      */
-//    @Bean
-//    public MybatisPlusMetaObjectHandler mybatisPlusMetaObjectHandler() {
-//        return new MybatisPlusMetaObjectHandler();
-//    }
+    @Bean
+    public MybatisPlusMetaObjectHandler mybatisPlusMetaObjectHandler() {
+        return new MybatisPlusMetaObjectHandler();
+    }
 }

+ 90 - 76
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/config/MybatisPlusMetaObjectHandler.java

@@ -1,76 +1,90 @@
-//package com.hfln.portal.infrastructure.config;
-//
-//import cn.hutool.core.util.StrUtil;
-//import cn.hfln.framework.common.security.LoginUser;
-//import cn.hfln.framework.common.security.utils.SecurityUtils;
-//import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
-//import lombok.extern.slf4j.Slf4j;
-//import org.apache.ibatis.reflection.MetaObject;
-//import org.springframework.util.ClassUtils;
-//
-//import java.nio.charset.Charset;
-//import java.util.Date;
-//
-///**
-// * MybatisPlus 自动填充配置
-// *
-// */
-//@Slf4j
-//public class MybatisPlusMetaObjectHandler implements MetaObjectHandler {
-//
-//	@Override
-//	public void insertFill(MetaObject metaObject) {
-//		log.debug("mybatis plus start insert fill ....");
-//		Date now = new Date();
-//
-//		fillValIfNullByName("createTime", now, metaObject, false);
-//		fillValIfNullByName("updateTime", now, metaObject, false);
-//		fillValIfNullByName("createBy", getUserName(), metaObject, false);
-//		fillValIfNullByName("updateBy", getUserName(), metaObject, false);
-//	}
-//
-//	@Override
-//	public void updateFill(MetaObject metaObject) {
-//		log.debug("mybatis plus start update fill ....");
-//		fillValIfNullByName("updateTime", new Date(), metaObject, true);
-//		fillValIfNullByName("updateBy", getUserName(), metaObject, true);
-//	}
-//
-//	/**
-//	 * 填充值,先判断是否有手动设置,优先手动设置的值,例如:job必须手动设置
-//	 * @param fieldName 属性名
-//	 * @param fieldVal 属性值
-//	 * @param metaObject MetaObject
-//	 * @param isCover 是否覆盖原有值,避免更新操作手动入参
-//	 */
-//	private static void fillValIfNullByName(String fieldName, Object fieldVal, MetaObject metaObject, boolean isCover) {
-//		// 1. 没有 set 方法
-//		if (!metaObject.hasSetter(fieldName)) {
-//			return;
-//		}
-//		// 2. 如果用户有手动设置的值
-//		Object userSetValue = metaObject.getValue(fieldName);
-//		String setValueStr = StrUtil.str(userSetValue, Charset.defaultCharset());
-//		if (StrUtil.isNotBlank(setValueStr) && !isCover) {
-//			return;
-//		}
-//		// 3. field 类型相同时设置
-//		Class<?> getterType = metaObject.getGetterType(fieldName);
-//		if (ClassUtils.isAssignableValue(getterType, fieldVal)) {
-//			metaObject.setValue(fieldName, fieldVal);
-//		}
-//	}
-//
-//	/**
-//	 * 获取 spring security 当前的用户名
-//	 * @return 当前用户名
-//	 */
-//	private String getUserName() {
-//		LoginUser loginUser = SecurityUtils.getLoginUser();
-//		if (loginUser == null){
-//			return "";
-//		}
-//		return loginUser.getUsername();
-//	}
-//
-//}
+package com.hfln.portal.infrastructure.config;
+
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.ibatis.reflection.MetaObject;
+import org.springframework.util.ClassUtils;
+
+import java.nio.charset.Charset;
+import java.time.LocalDateTime;
+
+/**
+ * MybatisPlus 自动填充配置
+ *
+ */
+@Slf4j
+public class MybatisPlusMetaObjectHandler implements MetaObjectHandler {
+
+	@Override
+	public void insertFill(MetaObject metaObject) {
+		log.debug("mybatis plus start insert fill ....");
+		LocalDateTime now = LocalDateTime.now();
+
+		fillValIfNullByName("createTime", now, metaObject, false);
+		fillValIfNullByName("updateTime", now, metaObject, false);
+		fillValIfNullByName("createId", getUserId(), metaObject, false);
+		fillValIfNullByName("updateId", getUserId(), metaObject, false);
+	}
+
+	@Override
+	public void updateFill(MetaObject metaObject) {
+		log.debug("mybatis plus start update fill ....");
+		fillValIfNullByName("updateTime", LocalDateTime.now(), metaObject, true);
+		fillValIfNullByName("updateId", getUserId(), metaObject, true);
+	}
+
+	/**
+	 * 填充值,先判断是否有手动设置,优先手动设置的值,例如:job必须手动设置
+	 * @param fieldName 属性名
+	 * @param fieldVal 属性值
+	 * @param metaObject MetaObject
+	 * @param isCover 是否覆盖原有值,避免更新操作手动入参
+	 */
+	private static void fillValIfNullByName(String fieldName, Object fieldVal, MetaObject metaObject, boolean isCover) {
+		// 1. 没有 set 方法
+		if (!metaObject.hasSetter(fieldName)) {
+			return;
+		}
+		// 2. 如果用户有手动设置的值
+		Object userSetValue = metaObject.getValue(fieldName);
+		String setValueStr = StrUtil.str(userSetValue, Charset.defaultCharset());
+		if (StrUtil.isNotBlank(setValueStr) && !isCover) {
+			return;
+		}
+		// 3. field 类型相同时设置
+		Class<?> getterType = metaObject.getGetterType(fieldName);
+		if (ClassUtils.isAssignableValue(getterType, fieldVal)) {
+			metaObject.setValue(fieldName, fieldVal);
+		}
+	}
+
+	/**
+	 * 获取当前用户ID
+	 * @return 当前用户ID
+	 */
+	private Long getUserId() {
+		try {
+			// 使用Sa-Token获取当前登录用户ID
+			if (StpUtil.isLogin()) {
+				Object loginId = StpUtil.getLoginId();
+				if (loginId != null) {
+					// 如果是字符串,尝试转换为Long
+					if (loginId instanceof String) {
+						return Long.valueOf((String) loginId);
+					} else if (loginId instanceof Long) {
+						return (Long) loginId;
+					} else if (loginId instanceof Number) {
+						return ((Number) loginId).longValue();
+					}
+				}
+			}
+			return null;
+		} catch (Exception e) {
+			log.warn("获取当前用户ID失败", e);
+			return null;
+		}
+	}
+
+}

+ 65 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/gateway/impl/DeviceGatewayImpl.java

@@ -668,6 +668,71 @@ public class DeviceGatewayImpl implements DeviceGateway {
         }
         return res;
     }
+/*    @Override
+    public String checkDevByOpenId(String openId, String clientId) {
+        // 1. 检查参数是否为空
+        if (StringUtils.isEmpty(openId)){
+            throw new BizException(ErrorEnum.USER_NAME_IS_NULL.getErrorCode(),
+                ErrorEnum.USER_NAME_IS_NULL.getErrorMessage());
+        }
+        if(StringUtils.isEmpty(clientId)){
+            throw new BizException(ErrorEnum.CLIENT_ID_ID_NULL.getErrorCode(),
+                    ErrorEnum.CLIENT_ID_ID_NULL.getErrorMessage());
+        }
+
+        // 2. 检查用户是否存在
+        UserInfo userInfo = userService.getOne(
+            new LambdaQueryWrapper<UserInfo>()
+                .eq(UserInfo::getOpenid, openId)
+                .eq(UserInfo::getIsDeleted, 0)
+        );
+
+        if (userInfo == null) {
+            throw new BizException(ErrorEnum.USER_IS_NOT_EXIST.getErrorCode(),
+                ErrorEnum.USER_IS_NOT_EXIST.getErrorMessage());
+        }
+
+        // 3. 检查设备是否存在且未删除
+        DevInfo devInfo = devInfoService.getOne(
+            new LambdaQueryWrapper<DevInfo>()
+                .eq(DevInfo::getDevId, clientId)
+                .eq(DevInfo::getIsDeleted, 0)
+        );
+
+        if (devInfo == null) {
+            throw new BizException(ErrorEnum.DEVICE_IS_NOT_EXIST.getErrorCode(),
+                ErrorEnum.DEVICE_IS_NOT_EXIST.getErrorMessage());
+        }
+
+        // 4. 检查是否是自持设备
+        boolean isOwnDevice = devInfoService.count(
+            new LambdaQueryWrapper<DevInfo>()
+                .eq(DevInfo::getDevId, clientId)
+                .eq(DevInfo::getUserId, userInfo.getUserId())
+                .eq(DevInfo::getIsDeleted, 0)
+        ) > 0;
+
+        if (isOwnDevice) {
+            return "false";
+        }
+
+        // 5. 检查设备是否被分享给该用户
+        boolean isSharedDevice = devShareService.count(
+            new LambdaQueryWrapper<DevShare>()
+                .eq(DevShare::getDevId, clientId)
+                .eq(DevShare::getSharedUserId, userInfo.getUserId())
+                .eq(DevShare::getIsDeleted, 0)
+        ) > 0;
+
+        if (isSharedDevice) {
+            return "false";
+        }
+
+        // 6. 如果既不是自持设备也不是分享设备,返回true
+        return "true";
+    }*/
+
+
 
     // 校验 PNG 文件头(89 50 4E 47 0D 0A 1A 0A)
     public static boolean checkPngMagicNumber(byte[] header) {

+ 28 - 10
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/gateway/impl/UserGatewayImpl.java

@@ -156,11 +156,21 @@ public class UserGatewayImpl implements UserGateway {
     @Override
     public Boolean signup(UserSignupParams request) {
         //校验验证码
-        String cacheCode = redisService.getCacheObject(RedisCacheConstant.SMS_SIGNUP_CODE + request.getPhone());
-        if (Objects.isNull(cacheCode)) {
+        String redisKey = RedisCacheConstant.SMS_SIGNUP_CODE + request.getPhone();
+        log.info("验证注册验证码:手机号={}, 输入验证码={}, Redis key={}", request.getPhone(), request.getCode(), redisKey);
+        
+        Object cacheCodeObj = redisService.getCacheObject(redisKey);
+        log.info("从Redis获取验证码:key={}, value={}", redisKey, cacheCodeObj);
+        
+        if (Objects.isNull(cacheCodeObj)) {
+            log.warn("验证码已过期或不存在:手机号={}, Redis key={}", request.getPhone(), redisKey);
             throw new BizException(ErrorEnum.SMS_CODE_EXPIRED.getErrorCode(), ErrorEnum.SMS_CODE_EXPIRED.getErrorMessage());
         }
+        String cacheCode = String.valueOf(cacheCodeObj);
+        log.info("验证码比较:输入={}, 缓存={}", request.getCode(), cacheCode);
+        
         if (!Objects.equals(cacheCode, request.getCode())) {
+            log.warn("验证码错误:手机号={}, 输入={}, 缓存={}", request.getPhone(), request.getCode(), cacheCode);
             throw new BizException(ErrorEnum.SMS_CODE_ERROR.getErrorCode(), ErrorEnum.SMS_CODE_ERROR.getErrorMessage());
 
         }
@@ -168,7 +178,7 @@ public class UserGatewayImpl implements UserGateway {
             throw new BizException(ErrorEnum.USER_ALREADY_EXISTS.getErrorCode(), ErrorEnum.USER_ALREADY_EXISTS.getErrorMessage());
         }
         // 验证通过 清除验证码入库
-        redisService.deleteObject(RedisCacheConstant.SMS_SIGNUP_CODE + request.getPhone());
+        redisService.deleteObject(redisKey);
         UserInfo user = new UserInfo();
         user.setPhone(request.getPhone());
         String encryptedPassword = PasswordUtil.encrypt(request.getPassword());
@@ -191,14 +201,24 @@ public class UserGatewayImpl implements UserGateway {
         String phone = request.getUserName();
         UserInfo user = userService.checkUserByPassword(phone, null);
         if (Objects.nonNull(user)) {
-            String cacheSmsCode = redisService.getCacheObject(RedisCacheConstant.SMS_LOGIN_CODE + phone);
-            if (Objects.isNull(cacheSmsCode)) {
+            String redisKey = RedisCacheConstant.SMS_LOGIN_CODE + phone;
+            log.info("验证登录验证码:手机号={}, 输入验证码={}, Redis key={}", phone, request.getSmsCode(), redisKey);
+            
+            Object cacheSmsCodeObj = redisService.getCacheObject(redisKey);
+            log.info("从Redis获取登录验证码:key={}, value={}", redisKey, cacheSmsCodeObj);
+            
+            if (Objects.isNull(cacheSmsCodeObj)) {
+                log.warn("登录验证码已过期或不存在:手机号={}, Redis key={}", phone, redisKey);
                 throw new BizException(ErrorEnum.SMS_CODE_EXPIRED.getErrorCode(), ErrorEnum.SMS_CODE_EXPIRED.getErrorMessage());
             }
+            String cacheSmsCode = String.valueOf(cacheSmsCodeObj);
+            log.info("登录验证码比较:输入={}, 缓存={}", request.getSmsCode(), cacheSmsCode);
+            
             if (!Objects.equals(request.getSmsCode(), cacheSmsCode)) {
+                log.warn("登录验证码错误:手机号={}, 输入={}, 缓存={}", phone, request.getSmsCode(), cacheSmsCode);
                 throw new BizException(ErrorEnum.SMS_CODE_ERROR.getErrorCode(), ErrorEnum.SMS_CODE_ERROR.getErrorMessage());
             }
-            redisService.deleteObject(RedisCacheConstant.SMS_LOGIN_CODE + phone);
+            redisService.deleteObject(redisKey);
         }
         BeanUtils.copyProperties(user, userDto);
         userDto.setUserId(user.getUserId()
@@ -340,10 +360,8 @@ public class UserGatewayImpl implements UserGateway {
         StpUtil.logout(request.getUserId());
 
         //3.修改用户信息表中的is_delete字段为1
-        UserInfo info = new UserInfo();
-        info.setUserId(request.getUserId());
-        info.setIsDeleted(1);
-        userService.updateById(info);
+        // 使用 MyBatis Plus 的逻辑删除功能
+        userService.removeById(request.getUserId());
 
         //4.批量更新其他相关表中的is_delete字段
         // 更新设备信息表

+ 12 - 1
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/gateway/impl/sms/SmsGatewayImpl.java

@@ -6,12 +6,14 @@ import com.hfln.portal.common.constant.redis.RedisCacheConstant;
 import com.hfln.portal.domain.customer.util.MsgClient;
 import com.hfln.portal.domain.exception.ErrorEnum;
 import com.hfln.portal.domain.gateway.sms.SmsGateway;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.util.Objects;
 import java.util.concurrent.TimeUnit;
 
+@Slf4j
 @Service
 public class SmsGatewayImpl implements SmsGateway {
 
@@ -51,12 +53,21 @@ public class SmsGatewayImpl implements SmsGateway {
             throw new BizException(ErrorEnum.FREQUENT_SMS_SENDING.getErrorCode(), ErrorEnum.FREQUENT_SMS_SENDING.getErrorMessage());
         }
         int captcha = (int) ((Math.random() * 9 + 1) * 1000);
+        log.info("生成注册验证码:手机号={}, 验证码={}", phone, captcha);
+        
         String sentLoginMsg = msgClient.sendRegisterMsg(phone, String.valueOf(captcha));
         if (Objects.nonNull(sentLoginMsg)) {
             // 存入redis  过期时间十分钟
-            redisService.setCacheObject(RedisCacheConstant.SMS_SIGNUP_CODE + phone, captcha,10L, TimeUnit.MINUTES);
+            String redisKey = RedisCacheConstant.SMS_SIGNUP_CODE + phone;
+            redisService.setCacheObject(redisKey, captcha, 10L, TimeUnit.MINUTES);
+            log.info("验证码已存入Redis:key={}, value={}, 过期时间=10分钟", redisKey, captcha);
+            
+            // 验证是否存储成功
+            Object storedValue = redisService.getCacheObject(redisKey);
+            log.info("验证存储结果:key={}, 存储的值={}", redisKey, storedValue);
             return true;
         }
+        log.warn("短信发送失败:手机号={}, 验证码={}", phone, captcha);
         return false;
     }
 

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

@@ -13,7 +13,7 @@ import lombok.EqualsAndHashCode;
 public class UserInfo extends BasePO {
 
     /**
-     * 主键ID,自增策略
+     * 主键ID,数据库自增策略
      */
     @TableId(type = IdType.ASSIGN_ID)
     private Long userId;
@@ -26,6 +26,7 @@ public class UserInfo extends BasePO {
     /**
      * 用户unionid,微信开发平台下唯一标识
      */
+    @TableField("unionid")
     private String unionId;
 
     /**

+ 7 - 1
portal-service-server/pom.xml

@@ -59,7 +59,13 @@
             <artifactId>spring-boot-starter-actuator</artifactId>
         </dependency>
 
-<!--        <dependency>-->
+        <dependency>
+            <groupId>org.eclipse.paho</groupId>
+            <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
+            <version>1.2.5</version>
+        </dependency>
+
+        <!--        <dependency>-->
 <!--            <groupId>org.springframework.cloud</groupId>-->
 <!--            <artifactId>spring-cloud-starter-bootstrap</artifactId>-->
 <!--        </dependency>-->