优化页面

This commit is contained in:
马宝龙
2026-07-28 11:35:34 +08:00
parent ea5071dc37
commit 52cbed63a8
7 changed files with 526 additions and 136 deletions

View File

@@ -9,6 +9,8 @@ import com.example.training.service.UserService;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.http.HttpStatus;
@@ -16,6 +18,7 @@ import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
@@ -38,15 +41,29 @@ public class UserController {
@GetMapping
public UserPage list(
@RequestParam(defaultValue = "") String keyword,
@RequestParam(defaultValue = "") String role,
@RequestParam(defaultValue = "") String status,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "50") int size) {
int safePage = Math.max(page, 0);
int safeSize = Math.min(Math.max(size, 1), 100);
Page<User> resultPage = userService.pageUsers(keyword, safePage, safeSize);
Page<User> resultPage = userService.pageUsers(keyword, role, status, safePage, safeSize);
return new UserPage(resultPage.getRecords().stream().map(UserResponse::from).toList(),
resultPage.getTotal(), (int) resultPage.getCurrent() - 1, (int) resultPage.getSize());
}
@GetMapping("/summary")
public UserSummary summary() {
UserService.UserSummary summary = userService.summarizeUsers();
return new UserSummary(summary.total(), summary.active(), summary.inactive(), summary.admins());
}
@PatchMapping("/status")
public BulkStatusResponse updateStatuses(@Valid @RequestBody BulkStatusRequest request) {
int updated = userService.updateStatuses(request.ids(), request.status());
return new BulkStatusResponse(updated, request.status());
}
@PostMapping
public ResponseEntity<UserResponse> create(@Valid @RequestBody UserRequest request) {
User user = userService.createUser(request.fullName(), request.email(),
@@ -59,7 +76,7 @@ public class UserController {
User user = userService.updateUser(id, request.fullName(), request.email(),
request.role(), request.status());
if (user == null) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "User not found");
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "用户不存在");
}
return UserResponse.from(user);
}
@@ -67,7 +84,7 @@ public class UserController {
@DeleteMapping("/{id}")
public ResponseEntity<Void> delete(@PathVariable Long id) {
if (!userService.deleteUser(id)) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "User not found");
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "用户不存在");
}
return ResponseEntity.noContent().build();
}
@@ -85,9 +102,20 @@ public class UserController {
@NotBlank @Size(max = 20) String status) {
}
public record BulkStatusRequest(
@NotEmpty @Size(max = 100) List<Long> ids,
@NotBlank @Pattern(regexp = "ACTIVE|INACTIVE") String status) {
}
public record UserPage(List<UserResponse> items, long total, int page, int size) {
}
public record UserSummary(long total, long active, long inactive, long admins) {
}
public record BulkStatusResponse(int updated, String status) {
}
public record UserResponse(Long id, String fullName, String email, String role,
String status, LocalDateTime createdAt, LocalDateTime updatedAt) {
static UserResponse from(User user) {

View File

@@ -3,13 +3,22 @@ package com.example.training.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.training.domain.User;
import java.util.List;
public interface UserService {
Page<User> pageUsers(String keyword, int page, int size);
Page<User> pageUsers(String keyword, String role, String status, int page, int size);
UserSummary summarizeUsers();
int updateStatuses(List<Long> ids, String status);
User createUser(String fullName, String email, String role, String status);
User updateUser(Long id, String fullName, String email, String role, String status);
boolean deleteUser(Long id);
record UserSummary(long total, long active, long inactive, long admins) {
}
}

View File

@@ -1,6 +1,7 @@
package com.example.training.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.training.domain.User;
import com.example.training.mapper.UserMapper;
@@ -8,6 +9,9 @@ import com.example.training.service.UserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
@@ -19,19 +23,51 @@ public class UserServiceImpl implements UserService {
@Override
@Transactional(readOnly = true)
public Page<User> pageUsers(String keyword, int page, int size) {
public Page<User> pageUsers(String keyword, String role, String status, int page, int size) {
Page<User> requestPage = new Page<>(page + 1L, size);
LambdaQueryWrapper<User> query = new LambdaQueryWrapper<>();
if (keyword != null && !keyword.isBlank()) {
String trimmedKeyword = keyword.trim();
query.like(User::getFullName, trimmedKeyword)
query.and(search -> search.like(User::getFullName, trimmedKeyword)
.or()
.like(User::getEmail, trimmedKeyword);
.like(User::getEmail, trimmedKeyword));
}
if (role != null && !role.isBlank()) {
query.eq(User::getRole, role.trim());
}
if (status != null && !status.isBlank()) {
query.eq(User::getStatus, status.trim());
}
query.orderByDesc(User::getCreatedAt);
return userMapper.selectPage(requestPage, query);
}
@Override
@Transactional(readOnly = true)
public UserSummary summarizeUsers() {
long total = userMapper.selectCount(new LambdaQueryWrapper<>());
long active = userMapper.selectCount(new LambdaQueryWrapper<User>()
.eq(User::getStatus, "ACTIVE"));
long inactive = userMapper.selectCount(new LambdaQueryWrapper<User>()
.eq(User::getStatus, "INACTIVE"));
long admins = userMapper.selectCount(new LambdaQueryWrapper<User>()
.eq(User::getRole, "Admin"));
return new UserSummary(total, active, inactive, admins);
}
@Override
@Transactional
public int updateStatuses(List<Long> ids, String status) {
if (ids == null || ids.isEmpty()) {
return 0;
}
LambdaUpdateWrapper<User> update = new LambdaUpdateWrapper<>();
update.in(User::getId, ids)
.set(User::getStatus, status)
.set(User::getUpdatedAt, LocalDateTime.now());
return userMapper.update(null, update);
}
@Override
@Transactional
public User createUser(String fullName, String email, String role, String status) {