Commit c5286961815b9002d9ea1004db0711109fd13be9

Authored by zichun
1 parent 0caab5b6

feat(usr): 查询用户 Controller GET /api/usr/users REQ-USR-003

backend/src/main/java/com/xly/erp/modules/usr/controller/UsrUserController.java
1 1 package com.xly.erp.modules.usr.controller;
2 2  
3 3 import com.xly.erp.common.exception.BusinessException;
  4 +import com.xly.erp.common.response.PageResult;
4 5 import com.xly.erp.common.response.Result;
5 6 import com.xly.erp.common.response.ResultCode;
6 7 import com.xly.erp.common.security.SecurityUtil;
7 8 import com.xly.erp.modules.usr.dto.CreateUserDTO;
8 9 import com.xly.erp.modules.usr.dto.UpdateUserDTO;
  10 +import com.xly.erp.modules.usr.dto.UserQueryDTO;
9 11 import com.xly.erp.modules.usr.service.UsrUserService;
  12 +import com.xly.erp.modules.usr.vo.UserVO;
10 13 import jakarta.validation.Valid;
11 14 import java.util.Map;
  15 +import org.springframework.web.bind.annotation.GetMapping;
12 16 import org.springframework.web.bind.annotation.PathVariable;
13 17 import org.springframework.web.bind.annotation.PostMapping;
14 18 import org.springframework.web.bind.annotation.PutMapping;
... ... @@ -58,4 +62,13 @@ public class UsrUserController {
58 62 Integer updatedId = usrUserService.updateUser(id, dto);
59 63 return Result.success(Map.of("id", updatedId));
60 64 }
  65 +
  66 + /**
  67 + * 查询用户(REQ-USR-003):任意已认证用户可调用(无管理员前置,spec § 8 D5)。
  68 + * query 参数自动绑定到 {@link UserQueryDTO}(非 @RequestBody);仅 @Valid + 委派 Service。
  69 + */
  70 + @GetMapping("/users")
  71 + public Result<PageResult<UserVO>> queryUsers(@Valid UserQueryDTO dto) {
  72 + return Result.success(usrUserService.queryUsers(dto));
  73 + }
61 74 }
... ...
backend/src/test/java/com/xly/erp/modules/usr/controller/UsrUserControllerTest.java
... ... @@ -5,6 +5,7 @@ import static org.mockito.Mockito.never;
5 5 import static org.mockito.Mockito.verify;
6 6 import static org.mockito.Mockito.when;
7 7 import static org.mockito.ArgumentMatchers.eq;
  8 +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
8 9 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
9 10 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
10 11 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
... ... @@ -13,11 +14,15 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
13 14 import com.fasterxml.jackson.databind.ObjectMapper;
14 15 import com.xly.erp.common.exception.BusinessException;
15 16 import com.xly.erp.common.exception.GlobalExceptionHandler;
  17 +import com.xly.erp.common.response.PageResult;
16 18 import com.xly.erp.common.response.ResultCode;
17 19 import com.xly.erp.common.security.SecurityUtil;
18 20 import com.xly.erp.modules.usr.dto.CreateUserDTO;
19 21 import com.xly.erp.modules.usr.dto.UpdateUserDTO;
  22 +import com.xly.erp.modules.usr.dto.UserQueryDTO;
20 23 import com.xly.erp.modules.usr.service.UsrUserService;
  24 +import com.xly.erp.modules.usr.vo.UserVO;
  25 +import java.util.List;
21 26 import org.junit.jupiter.api.AfterEach;
22 27 import org.junit.jupiter.api.BeforeEach;
23 28 import org.junit.jupiter.api.Test;
... ... @@ -168,4 +173,61 @@ class UsrUserControllerTest {
168 173 .andExpect(status().isOk())
169 174 .andExpect(jsonPath("$.code").value(40401));
170 175 }
  176 +
  177 + // ---------------- REQ-USR-003 T5:查询用户 Controller GET /api/usr/users(无管理员前置)----------------
  178 +
  179 + private PageResult<UserVO> onePageResult() {
  180 + UserVO vo = new UserVO();
  181 + vo.setId(1);
  182 + vo.setSUserName("alice");
  183 + vo.setSUserType("普通用户");
  184 + vo.setSLanguage("中文");
  185 + vo.setIIsVoid(0);
  186 + return PageResult.of(List.of(vo), 1L, 1L, 10L);
  187 + }
  188 +
  189 + @Test
  190 + void queryReturnsCodeZeroWithPageResult() throws Exception {
  191 + when(usrUserService.queryUsers(any(UserQueryDTO.class))).thenReturn(onePageResult());
  192 +
  193 + mockMvc.perform(get("/api/usr/users").param("pageNum", "1").param("pageSize", "10"))
  194 + .andExpect(status().isOk())
  195 + .andExpect(jsonPath("$.code").value(0))
  196 + .andExpect(jsonPath("$.data.total").value(1))
  197 + .andExpect(jsonPath("$.data.pageNum").value(1))
  198 + .andExpect(jsonPath("$.data.pageSize").value(10))
  199 + .andExpect(jsonPath("$.data.records[0].sUserName").value("alice"))
  200 + .andExpect(jsonPath("$.data.records[0].sPassword").doesNotExist())
  201 + .andExpect(jsonPath("$.data.records[0].password").doesNotExist());
  202 + }
  203 +
  204 + @Test
  205 + void queryAllowsNonAdmin() throws Exception {
  206 + // 无管理员前置(spec § 8 D5):普通用户即可调用,Service 被调用。
  207 + securityUtilMock.when(SecurityUtil::currentUserType).thenReturn("普通用户");
  208 + when(usrUserService.queryUsers(any(UserQueryDTO.class))).thenReturn(onePageResult());
  209 +
  210 + mockMvc.perform(get("/api/usr/users"))
  211 + .andExpect(status().isOk())
  212 + .andExpect(jsonPath("$.code").value(0));
  213 + verify(usrUserService).queryUsers(any(UserQueryDTO.class));
  214 + }
  215 +
  216 + @Test
  217 + void queryIllegalEnumReturns40001() throws Exception {
  218 + mockMvc.perform(get("/api/usr/users").param("queryField", "身份证"))
  219 + .andExpect(status().isOk())
  220 + .andExpect(jsonPath("$.code").value(40001));
  221 + verify(usrUserService, never()).queryUsers(any(UserQueryDTO.class));
  222 + }
  223 +
  224 + @Test
  225 + void queryPageParamInvalidReturns42201() throws Exception {
  226 + when(usrUserService.queryUsers(any(UserQueryDTO.class)))
  227 + .thenThrow(new BusinessException(ResultCode.PAGE_PARAM_INVALID));
  228 +
  229 + mockMvc.perform(get("/api/usr/users").param("pageNum", "0"))
  230 + .andExpect(status().isOk())
  231 + .andExpect(jsonPath("$.code").value(42201));
  232 + }
171 233 }
... ...