package com.dms.api.v1; import com.dms.common.ApiResponse; import com.dms.common.Errors; import com.dms.common.Page; import com.dms.common.Payloads; import com.dms.mapper.UserMapper; import com.dms.model.UserEntity; import com.dms.security.AuthContext; import com.dms.security.AuthRequired; import com.dms.service.UserSummaryService; import com.dms.service.UserService; import jakarta.servlet.http.HttpServletRequest; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; 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; /** 用户接口,对齐 backend/dms/api/v1/users.py。 */ @RestController @RequestMapping("/api/v1/users") public class UsersController { private final UserMapper userMapper; private final UserSummaryService userSummaryService; private final UserService userService; public UsersController(UserMapper userMapper, UserSummaryService userSummaryService, UserService userService) { this.userMapper = userMapper; this.userSummaryService = userSummaryService; this.userService = userService; } /** 对齐 current_user(仅认证,不要求管理员)。 */ @AuthRequired @GetMapping("/me") public ApiResponse me() { UserEntity user = userMapper.findActiveById(AuthContext.get().userId()); if (user == null) { throw Errors.tokenInvalid(); } return ApiResponse.ok(userSummaryService.userSummary(user, userSummaryService.allowedModulesForUser(user))); } /** 对齐 update_ui_theme_route(契约1.20):本人主题偏好,无需管理权限。 */ @AuthRequired @PutMapping("/me/ui-theme") public ApiResponse updateUiTheme(@RequestBody Object body) { return ApiResponse.ok(userService.updateUiTheme(body)); } @AuthRequired(requireAdmin = true) @GetMapping public ApiResponse list(@RequestParam(required = false) String organizationId, @RequestParam(required = false) String includeDescendants, @RequestParam(required = false) String keyword, @RequestParam(required = false) String status, @RequestParam(required = false) String page, @RequestParam(required = false) String pageSize) { return ApiResponse.ok(userService.listUsers( Payloads.queryOptionalId(organizationId, "organizationId"), Payloads.booleanQuery(includeDescendants, "includeDescendants", false), keyword, status, Page.of(Payloads.integerQuery(page, "page", 1), Payloads.integerQuery(pageSize, "pageSize", 20)))); } @AuthRequired(requireAdmin = true) @PostMapping public ResponseEntity> create(@RequestBody Object body, HttpServletRequest request) { return ResponseEntity.status(HttpStatus.CREATED) .body(ApiResponse.ok(userService.create(body, request))); } /** 对齐 reorder_users_route(契约1.27):用户列表拖动重排。 */ @AuthRequired(requireAdmin = true) @PutMapping("/reorder") public ApiResponse reorder(@RequestBody Object body, HttpServletRequest request) { return ApiResponse.ok(userService.reorder(body, request)); } @AuthRequired(requireAdmin = true) @PutMapping("/{id}") public ApiResponse update(@PathVariable String id, @RequestBody Object body, HttpServletRequest request) { return ApiResponse.ok(userService.update(Payloads.pathId(id), body, request)); } @AuthRequired(requireAdmin = true) @DeleteMapping("/{id}") public ApiResponse delete(@PathVariable String id, @RequestParam(required = false) String rowVersion, HttpServletRequest request) { return ApiResponse.ok(userService.delete( Payloads.pathId(id), Payloads.deleteRowVersion(rowVersion), request)); } @AuthRequired(requireAdmin = true) @PostMapping("/{id}/reset-password") public ApiResponse resetPassword(@PathVariable String id, @RequestBody Object body, HttpServletRequest request) { return ApiResponse.ok(userService.resetPassword( Payloads.pathId(id), body, request)); } }