diff --git a/backend/src/main/java/com/xly/erp/module/usr/controller/UserController.java b/backend/src/main/java/com/xly/erp/module/usr/controller/UserController.java index 2b03087..3d59c63 100644 --- a/backend/src/main/java/com/xly/erp/module/usr/controller/UserController.java +++ b/backend/src/main/java/com/xly/erp/module/usr/controller/UserController.java @@ -5,11 +5,13 @@ import com.xly.erp.module.usr.dto.CreateUserDTO; import com.xly.erp.module.usr.dto.UpdateUserDTO; import com.xly.erp.module.usr.service.UserService; import jakarta.validation.Valid; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.Map; @@ -35,4 +37,13 @@ public class UserController { Integer updated = userService.update(id, dto); return Result.ok(Map.of("iIncrement", updated)); } + + @GetMapping("/users") + public Result> list(@RequestParam(required = false) String field, + @RequestParam(required = false) String match, + @RequestParam(required = false) String value, + @RequestParam(required = false) Integer pageNum, + @RequestParam(required = false) Integer pageSize) { + return Result.ok(userService.list(field, match, value, pageNum, pageSize)); + } } diff --git a/backend/src/test/java/com/xly/erp/module/usr/controller/UserControllerIT.java b/backend/src/test/java/com/xly/erp/module/usr/controller/UserControllerIT.java index 41596b8..5ba255c 100644 --- a/backend/src/test/java/com/xly/erp/module/usr/controller/UserControllerIT.java +++ b/backend/src/test/java/com/xly/erp/module/usr/controller/UserControllerIT.java @@ -370,6 +370,115 @@ class UserControllerIT { assertThat(name).isEqualTo("原"); } + @Test + void getDefaults_with_jwt_returns200_andList() throws Exception { + insertUserWithPerms("sp_test_lst_1", "查询1", null, null); + insertUserWithPerms("sp_test_lst_2", "查询2", null, null); + String token = testJwtHelper.signFor("ADMIN001"); + HttpHeaders headers = jsonHeaders(); + headers.set("Authorization", "Bearer " + token); + + ResponseEntity resp = rest.exchange( + listUrl(""), HttpMethod.GET, new HttpEntity<>(headers), String.class); + + JsonNode jb = objectMapper.readTree(resp.getBody()); + assertThat(jb.get("code").asInt()).isZero(); + assertThat(jb.get("data").get("records").isArray()).isTrue(); + assertThat(jb.get("data").get("total").asInt()).isPositive(); + assertThat(jb.get("data").get("pageSize").asInt()).isEqualTo(20); + } + + @Test + void getKeywordContains_filtersByUsername() throws Exception { + insertUserWithPerms("sp_test_lst_kw1", "包含查询用户", null, null); + String token = testJwtHelper.signFor("ADMIN001"); + HttpHeaders headers = jsonHeaders(); + headers.set("Authorization", "Bearer " + token); + + ResponseEntity resp = rest.exchange( + listUrl("?field=用户名&match=包含&value=包含查询"), HttpMethod.GET, new HttpEntity<>(headers), String.class); + + JsonNode data = objectMapper.readTree(resp.getBody()).get("data"); + for (JsonNode node : data.get("records")) { + assertThat(node.get("sUserName").asText()).contains("包含查询"); + } + } + + @Test + void getKeywordEquals_filtersExact() throws Exception { + insertUserWithPerms("sp_test_lst_eq", "等于精确", null, null); + String token = testJwtHelper.signFor("ADMIN001"); + HttpHeaders headers = jsonHeaders(); + headers.set("Authorization", "Bearer " + token); + + ResponseEntity resp = rest.exchange( + listUrl("?field=用户号&match=等于&value=sp_test_lst_eq"), HttpMethod.GET, new HttpEntity<>(headers), String.class); + + JsonNode records = objectMapper.readTree(resp.getBody()).get("data").get("records"); + assertThat(records.size()).isEqualTo(1); + assertThat(records.get(0).get("sUserNo").asText()).isEqualTo("sp_test_lst_eq"); + } + + @Test + void getInvalidField_returns40001() throws Exception { + String token = testJwtHelper.signFor("ADMIN001"); + HttpHeaders headers = jsonHeaders(); + headers.set("Authorization", "Bearer " + token); + + ResponseEntity resp = rest.exchange( + listUrl("?field=未知"), HttpMethod.GET, new HttpEntity<>(headers), String.class); + + assertThat(objectMapper.readTree(resp.getBody()).get("code").asInt()).isEqualTo(40001); + } + + @Test + void getPageSizeExceeds100_returns40002() throws Exception { + String token = testJwtHelper.signFor("ADMIN001"); + HttpHeaders headers = jsonHeaders(); + headers.set("Authorization", "Bearer " + token); + + ResponseEntity resp = rest.exchange( + listUrl("?pageSize=200"), HttpMethod.GET, new HttpEntity<>(headers), String.class); + + assertThat(objectMapper.readTree(resp.getBody()).get("code").asInt()).isEqualTo(40002); + } + + @Test + void getNoMatch_returnsEmptyArray() throws Exception { + String token = testJwtHelper.signFor("ADMIN001"); + HttpHeaders headers = jsonHeaders(); + headers.set("Authorization", "Bearer " + token); + + ResponseEntity resp = rest.exchange( + listUrl("?field=用户号&match=等于&value=不存在的用户号XYZ"), HttpMethod.GET, new HttpEntity<>(headers), String.class); + + JsonNode data = objectMapper.readTree(resp.getBody()).get("data"); + assertThat(data.get("records").isArray()).isTrue(); + assertThat(data.get("records").size()).isZero(); + assertThat(data.get("total").asInt()).isZero(); + } + + @Test + void getWithoutJwt_permitAllStub_returns200() throws Exception { + HttpHeaders headers = jsonHeaders(); + ResponseEntity resp = rest.exchange( + listUrl(""), HttpMethod.GET, new HttpEntity<>(headers), String.class); + assertThat(objectMapper.readTree(resp.getBody()).get("code").asInt()).isZero(); + } + + @Test + void getTamperedJwt_returns20001() throws Exception { + HttpHeaders headers = jsonHeaders(); + headers.set("Authorization", "Bearer not.a.real.jwt"); + ResponseEntity resp = rest.exchange( + listUrl(""), HttpMethod.GET, new HttpEntity<>(headers), String.class); + assertThat(objectMapper.readTree(resp.getBody()).get("code").asInt()).isEqualTo(20001); + } + + private String listUrl(String querySuffix) { + return "http://localhost:" + port + "/api/usr/users" + querySuffix; + } + private String idUrl(Integer id) { return "http://localhost:" + port + "/api/usr/users/" + id; }