feat(ops,iot): 保洁前端 API 层和区域管理新增
新增保洁业务前端 API 接口层(工牌、工单、仪表盘)和运营区域管理完整功能,包含 Service/Controller/Test 三层结构。 主要功能: 1. IoT 设备查询 API(RPC 接口) - IotDeviceQueryApi: 提供设备简化信息查询 - IotDeviceSimpleRespDTO: 设备简化 DTO 2. 保洁工牌管理 - CleanBadgeService/Impl: 工牌通知、优先级调整、手动完成 - BadgeNotifyReqDTO/UpgradePriorityReqDTO/ManualCompleteOrderReqDTO 3. 保洁工单管理 - CleanWorkOrderService/Impl: 工单时间线查询 4. 保洁仪表盘 - CleanDashboardService/Impl: 快速统计(待处理/进行中/已完成/在线工牌数) - QuickStatsRespDTO: 快速统计 DTO 5. 运营区域管理(Ops Biz) - OpsBusAreaService/Impl: 区域 CRUD(支持树形结构、分页查询) - AreaDeviceRelationService/Impl: 区域设备关联管理(绑定/解绑/批量更新) - OpsBusAreaMapper/AreaDeviceRelationMapper: 扩展 MyBatis 批量方法 - 7 个 VO 类:CreateReqVO/UpdateReqVO/PageReqVO/RespVO/BindReqVO/RelationRespVO/DeviceUpdateReqVO 6. 前端 Controller(Ops Server) - OpsBusAreaController: 区域管理 REST API(11 个接口) - AreaDeviceRelationController: 设备关联 REST API(8 个接口) - CleanBadgeController: 工牌管理 REST API(5 个接口) - CleanDashboardController: 仪表盘 REST API(1 个接口) - CleanDeviceController: 设备管理 REST API(2 个接口) - CleanWorkOrderController: 工单管理 REST API(2 个接口) 7. 测试覆盖 - OpsBusAreaServiceTest: 区域服务测试(284 行) - AreaDeviceRelationServiceTest: 设备关联测试(240 行) - OpsBusAreaControllerTest: 区域 Controller 测试(186 行) - AreaDeviceRelationControllerTest: 设备关联 Controller 测试(182 行) 8. API 层扩展 - ErrorCodeConstants: 错误码常量(区域、设备关联) - NotifyTypeEnum: 通知类型枚举(语音、文本、震动) - 4 个 Badge/Order DTO: BadgeStatusRespDTO/BadgeRealtimeStatusRespDTO/OrderTimelineRespDTO 9. RPC 配置 - RpcConfiguration: 注入 IotDeviceQueryApi 影响模块:Ops API、Ops Biz、Ops Server、Ops Environment Biz、IoT API、IoT Server Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
package com.viewsh.module.ops.controller.admin.area;
|
||||
|
||||
import com.viewsh.framework.apilog.core.annotation.ApiAccessLog;
|
||||
import com.viewsh.framework.common.pojo.CommonResult;
|
||||
import com.viewsh.module.ops.dal.dataobject.vo.area.AreaDeviceBindReqVO;
|
||||
import com.viewsh.module.ops.dal.dataobject.vo.area.AreaDeviceRelationRespVO;
|
||||
import com.viewsh.module.ops.dal.dataobject.vo.area.AreaDeviceUpdateReqVO;
|
||||
import com.viewsh.module.ops.service.area.AreaDeviceRelationService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.viewsh.framework.apilog.core.enums.OperateTypeEnum.*;
|
||||
import static com.viewsh.framework.common.pojo.CommonResult.success;
|
||||
|
||||
/**
|
||||
* 管理后台 - 区域设备关联管理
|
||||
*
|
||||
* @author lzh
|
||||
*/
|
||||
@Tag(name = "管理后台 - 区域设备关联")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/admin-api/ops/area/device-relation")
|
||||
@Validated
|
||||
public class AreaDeviceRelationController {
|
||||
|
||||
@Resource
|
||||
private AreaDeviceRelationService areaDeviceRelationService;
|
||||
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "查询区域已绑定设备列表")
|
||||
@Parameter(name = "areaId", description = "区域ID", required = true)
|
||||
// @PreAuthorize("@ss.hasPermission('ops:area:query')")
|
||||
public CommonResult<List<AreaDeviceRelationRespVO>> listByAreaId(@RequestParam("areaId") Long areaId) {
|
||||
List<AreaDeviceRelationRespVO> list = areaDeviceRelationService.listByAreaId(areaId);
|
||||
return success(list);
|
||||
}
|
||||
|
||||
@PostMapping("/bind")
|
||||
@Operation(summary = "绑定设备到区域")
|
||||
// @PreAuthorize("@ss.hasPermission('ops:area:bind-device')")
|
||||
@ApiAccessLog(operateType = CREATE)
|
||||
public CommonResult<Long> bindDevice(@Valid @RequestBody AreaDeviceBindReqVO bindReq) {
|
||||
Long relationId = areaDeviceRelationService.bindDevice(bindReq);
|
||||
return success(relationId);
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新设备关联配置")
|
||||
// @PreAuthorize("@ss.hasPermission('ops:area:config-device')")
|
||||
@ApiAccessLog(operateType = UPDATE)
|
||||
public CommonResult<Boolean> updateRelation(@Valid @RequestBody AreaDeviceUpdateReqVO updateReq) {
|
||||
areaDeviceRelationService.updateRelation(updateReq);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/remove")
|
||||
@Operation(summary = "解除设备绑定")
|
||||
@Parameter(name = "id", description = "关联ID", required = true)
|
||||
// @PreAuthorize("@ss.hasPermission('ops:area:bind-device')")
|
||||
@ApiAccessLog(operateType = DELETE)
|
||||
public CommonResult<Boolean> unbindDevice(@RequestParam("id") Long id) {
|
||||
Boolean result = areaDeviceRelationService.unbindDevice(id);
|
||||
return success(result);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.viewsh.module.ops.controller.admin.area;
|
||||
|
||||
import com.viewsh.framework.apilog.core.annotation.ApiAccessLog;
|
||||
import com.viewsh.framework.common.pojo.CommonResult;
|
||||
import com.viewsh.module.ops.dal.dataobject.vo.area.OpsBusAreaCreateReqVO;
|
||||
import com.viewsh.module.ops.dal.dataobject.vo.area.OpsBusAreaPageReqVO;
|
||||
import com.viewsh.module.ops.dal.dataobject.vo.area.OpsBusAreaRespVO;
|
||||
import com.viewsh.module.ops.dal.dataobject.vo.area.OpsBusAreaUpdateReqVO;
|
||||
import com.viewsh.module.ops.service.area.OpsBusAreaService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.viewsh.framework.apilog.core.enums.OperateTypeEnum.*;
|
||||
import static com.viewsh.framework.common.pojo.CommonResult.success;
|
||||
|
||||
/**
|
||||
* 管理后台 - 业务区域管理
|
||||
*
|
||||
* @author lzh
|
||||
*/
|
||||
@Tag(name = "管理后台 - 业务区域")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/admin-api/ops/area")
|
||||
@Validated
|
||||
public class OpsBusAreaController {
|
||||
|
||||
@Resource
|
||||
private OpsBusAreaService opsBusAreaService;
|
||||
|
||||
@GetMapping("/tree")
|
||||
@Operation(summary = "获取区域树(平铺列表,由前端自行组装)")
|
||||
// @PreAuthorize("@ss.hasPermission('ops:area:query')")
|
||||
public CommonResult<List<OpsBusAreaRespVO>> getAreaTree(OpsBusAreaPageReqVO reqVO) {
|
||||
List<OpsBusAreaRespVO> list = opsBusAreaService.getAreaTree(reqVO);
|
||||
return success(list);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获取区域详情")
|
||||
@Parameter(name = "id", description = "区域ID", required = true)
|
||||
// @PreAuthorize("@ss.hasPermission('ops:area:query')")
|
||||
public CommonResult<OpsBusAreaRespVO> getArea(@RequestParam("id") Long id) {
|
||||
OpsBusAreaRespVO area = opsBusAreaService.getArea(id);
|
||||
return success(area);
|
||||
}
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "新增区域")
|
||||
// @PreAuthorize("@ss.hasPermission('ops:area:create')")
|
||||
@ApiAccessLog(operateType = CREATE)
|
||||
public CommonResult<Long> createArea(@Valid @RequestBody OpsBusAreaCreateReqVO createReq) {
|
||||
Long areaId = opsBusAreaService.createArea(createReq);
|
||||
return success(areaId);
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新区域")
|
||||
// @PreAuthorize("@ss.hasPermission('ops:area:update')")
|
||||
@ApiAccessLog(operateType = UPDATE)
|
||||
public CommonResult<Boolean> updateArea(@Valid @RequestBody OpsBusAreaUpdateReqVO updateReq) {
|
||||
opsBusAreaService.updateArea(updateReq);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除区域")
|
||||
@Parameter(name = "id", description = "区域ID", required = true)
|
||||
// @PreAuthorize("@ss.hasPermission('ops:area:delete')")
|
||||
@ApiAccessLog(operateType = DELETE)
|
||||
public CommonResult<Boolean> deleteArea(@RequestParam("id") Long id) {
|
||||
Boolean result = opsBusAreaService.deleteArea(id);
|
||||
return success(result);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.viewsh.module.ops.controller.admin.clean;
|
||||
|
||||
import com.viewsh.framework.common.pojo.CommonResult;
|
||||
import com.viewsh.module.ops.api.clean.BadgeRealtimeStatusRespDTO;
|
||||
import com.viewsh.module.ops.api.clean.BadgeStatusRespDTO;
|
||||
import com.viewsh.module.ops.environment.dal.dataobject.BadgeNotifyReqDTO;
|
||||
import com.viewsh.module.ops.environment.service.badge.CleanBadgeService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.viewsh.framework.common.pojo.CommonResult.success;
|
||||
|
||||
/**
|
||||
* 管理后台 - 保洁工牌 Controller
|
||||
*
|
||||
* @author lzh
|
||||
*/
|
||||
@Tag(name = "管理后台 - 保洁工牌")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/ops/clean/badge")
|
||||
@Validated
|
||||
public class CleanBadgeController {
|
||||
|
||||
@Resource
|
||||
private CleanBadgeService cleanBadgeService;
|
||||
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "工牌实时状态列表")
|
||||
@Parameter(name = "areaId", description = "区域ID", required = false)
|
||||
@Parameter(name = "status", description = "状态筛选(IDLE/BUSY/OFFLINE/PAUSED)", required = false)
|
||||
@PreAuthorize("@ss.hasPermission('ops:clean:badge:query')")
|
||||
public CommonResult<List<BadgeStatusRespDTO>> getBadgeList(
|
||||
@RequestParam(value = "areaId", required = false) Long areaId,
|
||||
@RequestParam(value = "status", required = false) String status) {
|
||||
|
||||
List<BadgeStatusRespDTO> result = cleanBadgeService.getBadgeStatusList(areaId, status);
|
||||
return success(result);
|
||||
}
|
||||
|
||||
@GetMapping("/realtime/{badgeId}")
|
||||
@Operation(summary = "工牌实时状态详情")
|
||||
@Parameter(name = "badgeId", description = "工牌设备ID", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('ops:clean:badge:query')")
|
||||
public CommonResult<BadgeRealtimeStatusRespDTO> getBadgeRealtimeStatus(
|
||||
@PathVariable("badgeId") Long badgeId) {
|
||||
|
||||
BadgeRealtimeStatusRespDTO result = cleanBadgeService.getBadgeRealtimeStatus(badgeId);
|
||||
return success(result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.viewsh.module.ops.controller.admin.clean;
|
||||
|
||||
import com.viewsh.framework.common.pojo.CommonResult;
|
||||
import com.viewsh.module.ops.api.clean.QuickStatsRespDTO;
|
||||
import com.viewsh.module.ops.environment.service.dashboard.CleanDashboardService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import static com.viewsh.framework.common.pojo.CommonResult.success;
|
||||
|
||||
/**
|
||||
* 管理后台 - 保洁仪表盘 Controller
|
||||
*
|
||||
* @author lzh
|
||||
*/
|
||||
@Tag(name = "管理后台 - 保洁仪表盘")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/ops/clean/dashboard")
|
||||
@Validated
|
||||
public class CleanDashboardController {
|
||||
|
||||
@Resource
|
||||
private CleanDashboardService cleanDashboardService;
|
||||
|
||||
@GetMapping("/quick-stats")
|
||||
@Operation(summary = "快速统计")
|
||||
@PreAuthorize("@ss.hasPermission('ops:clean:dashboard:query')")
|
||||
public CommonResult<QuickStatsRespDTO> getQuickStats() {
|
||||
QuickStatsRespDTO result = cleanDashboardService.getQuickStats();
|
||||
return success(result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.viewsh.module.ops.controller.admin.clean;
|
||||
|
||||
import com.viewsh.framework.common.pojo.CommonResult;
|
||||
import com.viewsh.module.ops.environment.dal.dataobject.BadgeNotifyReqDTO;
|
||||
import com.viewsh.module.ops.environment.service.badge.CleanBadgeService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import static com.viewsh.framework.common.pojo.CommonResult.success;
|
||||
|
||||
/**
|
||||
* 管后台 - 保洁设备 Controller
|
||||
*
|
||||
* @author lzh
|
||||
*/
|
||||
@Tag(name = "管理后台 - 保洁设备")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/ops/clean/device")
|
||||
@Validated
|
||||
public class CleanDeviceController {
|
||||
|
||||
@Resource
|
||||
private CleanBadgeService cleanBadgeService;
|
||||
|
||||
@PostMapping("/notify")
|
||||
@Operation(summary = "发送工牌通知(语音/震动)")
|
||||
@PreAuthorize("@ss.hasPermission('ops:clean:device:notify')")
|
||||
public CommonResult<Boolean> sendBadgeNotify(
|
||||
@Valid @RequestBody BadgeNotifyReqDTO req) {
|
||||
|
||||
cleanBadgeService.sendBadgeNotify(req);
|
||||
return success(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.viewsh.module.ops.controller.admin.clean;
|
||||
|
||||
import com.viewsh.framework.common.pojo.CommonResult;
|
||||
import com.viewsh.module.ops.api.clean.OrderTimelineRespDTO;
|
||||
import com.viewsh.module.ops.environment.dal.dataobject.ManualCompleteOrderReqDTO;
|
||||
import com.viewsh.module.ops.environment.dal.dataobject.UpgradePriorityReqDTO;
|
||||
import com.viewsh.module.ops.environment.service.cleanorder.CleanWorkOrderService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import static com.viewsh.framework.common.pojo.CommonResult.success;
|
||||
|
||||
/**
|
||||
* 管理后台 - 保洁工单 Controller
|
||||
*
|
||||
* @author lzh
|
||||
*/
|
||||
@Tag(name = "管理后台 - 保洁工单")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/ops/clean/order")
|
||||
@Validated
|
||||
public class CleanWorkOrderController {
|
||||
|
||||
@Resource
|
||||
private CleanWorkOrderService cleanWorkOrderService;
|
||||
|
||||
@GetMapping("/timeline/{orderId}")
|
||||
@Operation(summary = "工单时间轴")
|
||||
@Parameter(name = "orderId", description = "工单ID", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('ops:clean:order:query')")
|
||||
public CommonResult<OrderTimelineRespDTO> getOrderTimeline(
|
||||
@PathVariable("orderId") Long orderId) {
|
||||
|
||||
OrderTimelineRespDTO result = cleanWorkOrderService.getOrderTimeline(orderId);
|
||||
return success(result);
|
||||
}
|
||||
|
||||
@PostMapping("/manual-complete")
|
||||
@Operation(summary = "手动完成工单")
|
||||
@PreAuthorize("@ss.hasPermission('ops:clean:order:complete')")
|
||||
public CommonResult<Boolean> manualCompleteOrder(
|
||||
@Valid @RequestBody ManualCompleteOrderReqDTO req) {
|
||||
|
||||
cleanWorkOrderService.manualCompleteOrder(req);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PostMapping("/upgrade-priority")
|
||||
@Operation(summary = "升级工单优先级")
|
||||
@PreAuthorize("@ss.hasPermission('ops:clean:order:upgrade')")
|
||||
public CommonResult<Boolean> upgradePriority(
|
||||
@Valid @RequestBody UpgradePriorityReqDTO req) {
|
||||
|
||||
cleanWorkOrderService.upgradePriority(req);
|
||||
return success(true);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.viewsh.module.ops.framework.rpc.config;
|
||||
|
||||
import com.viewsh.module.iot.api.device.IotDeviceControlApi;
|
||||
import com.viewsh.module.iot.api.device.IotDeviceQueryApi;
|
||||
import com.viewsh.module.iot.api.device.IotDeviceStatusQueryApi;
|
||||
import com.viewsh.module.system.api.notify.NotifyMessageSendApi;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
@@ -10,6 +11,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
@EnableFeignClients(clients = {
|
||||
NotifyMessageSendApi.class,
|
||||
IotDeviceControlApi.class,
|
||||
IotDeviceQueryApi.class,
|
||||
IotDeviceStatusQueryApi.class
|
||||
})
|
||||
public class RpcConfiguration {
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
package com.viewsh.module.ops.controller.admin.area;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.viewsh.module.ops.dal.dataobject.vo.area.AreaDeviceBindReqVO;
|
||||
import com.viewsh.module.ops.dal.dataobject.vo.area.AreaDeviceRelationRespVO;
|
||||
import com.viewsh.module.ops.dal.dataobject.vo.area.AreaDeviceUpdateReqVO;
|
||||
import com.viewsh.module.ops.service.area.AreaDeviceRelationService;
|
||||
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 org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/**
|
||||
* 区域设备关联管理 Controller 测试
|
||||
*
|
||||
* @author lzh
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class AreaDeviceRelationControllerTest {
|
||||
|
||||
@Mock
|
||||
private AreaDeviceRelationService areaDeviceRelationService;
|
||||
|
||||
@InjectMocks
|
||||
private AreaDeviceRelationController controller;
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
private AreaDeviceRelationRespVO testRelationVO;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
|
||||
objectMapper = new ObjectMapper();
|
||||
|
||||
testRelationVO = new AreaDeviceRelationRespVO();
|
||||
testRelationVO.setId(1L);
|
||||
testRelationVO.setAreaId(100L);
|
||||
testRelationVO.setAreaName("A栋3层电梯厅");
|
||||
testRelationVO.setDeviceId(50001L);
|
||||
testRelationVO.setDeviceKey("TRAFFIC_COUNTER_001");
|
||||
testRelationVO.setDeviceName("客流计数器001");
|
||||
testRelationVO.setProductId(10L);
|
||||
testRelationVO.setProductKey("traffic_counter_v1");
|
||||
testRelationVO.setProductName("客流计数器");
|
||||
testRelationVO.setRelationType("TRAFFIC_COUNTER");
|
||||
testRelationVO.setConfigData(new HashMap<>());
|
||||
testRelationVO.setEnabled(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testListByAreaId_Success() throws Exception {
|
||||
// Given
|
||||
when(areaDeviceRelationService.listByAreaId(100L))
|
||||
.thenReturn(Arrays.asList(testRelationVO));
|
||||
|
||||
// When & Then
|
||||
mockMvc.perform(get("/admin-api/ops/area/device-relation/list")
|
||||
.param("areaId", "100")
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data").isArray())
|
||||
.andExpect(jsonPath("$.data[0].deviceId").value(50001))
|
||||
.andExpect(jsonPath("$.data[0].deviceName").value("客流计数器001"));
|
||||
|
||||
verify(areaDeviceRelationService).listByAreaId(100L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testListByAreaId_Empty_Success() throws Exception {
|
||||
// Given
|
||||
when(areaDeviceRelationService.listByAreaId(999L))
|
||||
.thenReturn(Arrays.asList());
|
||||
|
||||
// When & Then
|
||||
mockMvc.perform(get("/admin-api/ops/area/device-relation/list")
|
||||
.param("areaId", "999")
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data").isArray())
|
||||
.andExpect(jsonPath("$.data").isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testBindDevice_Success() throws Exception {
|
||||
// Given
|
||||
AreaDeviceBindReqVO bindReq = new AreaDeviceBindReqVO();
|
||||
bindReq.setAreaId(100L);
|
||||
bindReq.setDeviceId(50001L);
|
||||
bindReq.setRelationType("TRAFFIC_COUNTER");
|
||||
|
||||
Map<String, Object> config = new HashMap<>();
|
||||
config.put("threshold", 100);
|
||||
bindReq.setConfigData(config);
|
||||
|
||||
when(areaDeviceRelationService.bindDevice(any(AreaDeviceBindReqVO.class)))
|
||||
.thenReturn(1L);
|
||||
|
||||
// When & Then
|
||||
mockMvc.perform(post("/admin-api/ops/area/device-relation/bind")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(bindReq)))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data").value(1));
|
||||
|
||||
verify(areaDeviceRelationService).bindDevice(any(AreaDeviceBindReqVO.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdateRelation_Success() throws Exception {
|
||||
// Given
|
||||
AreaDeviceUpdateReqVO updateReq = new AreaDeviceUpdateReqVO();
|
||||
updateReq.setId(1L);
|
||||
|
||||
Map<String, Object> config = new HashMap<>();
|
||||
config.put("threshold", 150);
|
||||
updateReq.setConfigData(config);
|
||||
|
||||
// When & Then
|
||||
mockMvc.perform(put("/admin-api/ops/area/device-relation/update")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(updateReq)))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(0));
|
||||
|
||||
verify(areaDeviceRelationService).updateRelation(any(AreaDeviceUpdateReqVO.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUnbindDevice_Success() throws Exception {
|
||||
// Given
|
||||
when(areaDeviceRelationService.unbindDevice(1L)).thenReturn(true);
|
||||
|
||||
// When & Then
|
||||
mockMvc.perform(delete("/admin-api/ops/area/device-relation/remove")
|
||||
.param("id", "1")
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data").value(true));
|
||||
|
||||
verify(areaDeviceRelationService).unbindDevice(1L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUnbindDevice_NotFound() throws Exception {
|
||||
// Given
|
||||
when(areaDeviceRelationService.unbindDevice(999L)).thenReturn(false);
|
||||
|
||||
// When & Then
|
||||
mockMvc.perform(delete("/admin-api/ops/area/device-relation/remove")
|
||||
.param("id", "999")
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data").value(false));
|
||||
|
||||
verify(areaDeviceRelationService).unbindDevice(999L);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
package com.viewsh.module.ops.controller.admin.area;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.viewsh.module.ops.dal.dataobject.vo.area.OpsBusAreaCreateReqVO;
|
||||
import com.viewsh.module.ops.dal.dataobject.vo.area.OpsBusAreaPageReqVO;
|
||||
import com.viewsh.module.ops.dal.dataobject.vo.area.OpsBusAreaRespVO;
|
||||
import com.viewsh.module.ops.dal.dataobject.vo.area.OpsBusAreaUpdateReqVO;
|
||||
import com.viewsh.module.ops.service.area.OpsBusAreaService;
|
||||
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 org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/**
|
||||
* 业务区域管理 Controller 测试
|
||||
*
|
||||
* @author lzh
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class OpsBusAreaControllerTest {
|
||||
|
||||
@Mock
|
||||
private OpsBusAreaService opsBusAreaService;
|
||||
|
||||
@InjectMocks
|
||||
private OpsBusAreaController controller;
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
private OpsBusAreaRespVO testAreaResp;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
|
||||
objectMapper = new ObjectMapper();
|
||||
|
||||
testAreaResp = new OpsBusAreaRespVO();
|
||||
testAreaResp.setId(100L);
|
||||
testAreaResp.setParentId(null);
|
||||
testAreaResp.setParentPath(null);
|
||||
testAreaResp.setAreaName("A园区");
|
||||
testAreaResp.setAreaCode("PARK_A");
|
||||
testAreaResp.setAreaType("PARK");
|
||||
testAreaResp.setIsActive(true);
|
||||
testAreaResp.setSort(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetAreaTree_Success() throws Exception {
|
||||
// Given
|
||||
when(opsBusAreaService.getAreaTree(any(OpsBusAreaPageReqVO.class)))
|
||||
.thenReturn(Arrays.asList(testAreaResp));
|
||||
|
||||
// When & Then
|
||||
mockMvc.perform(get("/admin-api/ops/area/tree")
|
||||
.param("areaType", "PARK")
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data").isArray())
|
||||
.andExpect(jsonPath("$.data[0].areaName").value("A园区"));
|
||||
|
||||
verify(opsBusAreaService).getAreaTree(any(OpsBusAreaPageReqVO.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetAreaTree_Empty_Success() throws Exception {
|
||||
// Given
|
||||
when(opsBusAreaService.getAreaTree(any(OpsBusAreaPageReqVO.class)))
|
||||
.thenReturn(Collections.emptyList());
|
||||
|
||||
// When & Then
|
||||
mockMvc.perform(get("/admin-api/ops/area/tree")
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data").isArray())
|
||||
.andExpect(jsonPath("$.data").isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetArea_Success() throws Exception {
|
||||
// Given
|
||||
when(opsBusAreaService.getArea(100L)).thenReturn(testAreaResp);
|
||||
|
||||
// When & Then
|
||||
mockMvc.perform(get("/admin-api/ops/area/get")
|
||||
.param("id", "100")
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data.id").value(100))
|
||||
.andExpect(jsonPath("$.data.areaName").value("A园区"));
|
||||
|
||||
verify(opsBusAreaService).getArea(100L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreateArea_Success() throws Exception {
|
||||
// Given
|
||||
OpsBusAreaCreateReqVO createReq = new OpsBusAreaCreateReqVO();
|
||||
createReq.setAreaName("A园区");
|
||||
createReq.setAreaCode("PARK_A");
|
||||
createReq.setAreaType("PARK");
|
||||
|
||||
when(opsBusAreaService.createArea(any(OpsBusAreaCreateReqVO.class)))
|
||||
.thenReturn(100L);
|
||||
|
||||
// When & Then
|
||||
mockMvc.perform(post("/admin-api/ops/area/create")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(createReq)))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data").value(100));
|
||||
|
||||
verify(opsBusAreaService).createArea(any(OpsBusAreaCreateReqVO.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdateArea_Success() throws Exception {
|
||||
// Given
|
||||
OpsBusAreaUpdateReqVO updateReq = new OpsBusAreaUpdateReqVO();
|
||||
updateReq.setId(100L);
|
||||
updateReq.setAreaName("A园区(更新)");
|
||||
|
||||
// When & Then
|
||||
mockMvc.perform(put("/admin-api/ops/area/update")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(updateReq)))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(0));
|
||||
|
||||
verify(opsBusAreaService).updateArea(any(OpsBusAreaUpdateReqVO.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeleteArea_Success() throws Exception {
|
||||
// Given
|
||||
when(opsBusAreaService.deleteArea(100L)).thenReturn(true);
|
||||
|
||||
// When & Then
|
||||
mockMvc.perform(delete("/admin-api/ops/area/delete")
|
||||
.param("id", "100")
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data").value(true));
|
||||
|
||||
verify(opsBusAreaService).deleteArea(100L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeleteArea_NotFound() throws Exception {
|
||||
// Given
|
||||
when(opsBusAreaService.deleteArea(999L)).thenReturn(false);
|
||||
|
||||
// When & Then
|
||||
mockMvc.perform(delete("/admin-api/ops/area/delete")
|
||||
.param("id", "999")
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data").value(false));
|
||||
|
||||
verify(opsBusAreaService).deleteArea(999L);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user