Files
AIGC/src/main/java/com/example/demo/controller/MemberApiController.java
blandarebiter 90b5118e45 perf(backend+frontend): 列表API响应体积优化 3.1MB→145KB (↓95.4%)
- 后端: JPQL构造器投影排除LONGTEXT大字段(uploadedImages/videoReferenceImages)
- 后端: DTO层过滤非分镜图类型的base64内联resultUrl
- 前端: 列表缩略图从video改为img loading=lazy,消除172并发请求
- 前端: download函数增加resultUrl懒加载(详情接口兜底)
- 文档: 新增性能优化报告 docs/performance-optimization-report.md
2026-04-10 18:46:37 +08:00

852 lines
40 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.example.demo.controller;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
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.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 com.example.demo.model.MembershipLevel;
import com.example.demo.model.User;
import com.example.demo.model.UserMembership;
import com.example.demo.repository.MembershipLevelRepository;
import com.example.demo.repository.PaymentRepository;
import com.example.demo.repository.UserMembershipRepository;
import com.example.demo.repository.UserRepository;
import com.example.demo.service.UserService;
import com.example.demo.util.JwtUtils;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.transaction.annotation.Transactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@RestController
@RequestMapping("/api/members")
@CrossOrigin(origins = "*")
public class MemberApiController {
private static final Logger logger = LoggerFactory.getLogger(MemberApiController.class);
@Autowired
private UserRepository userRepository;
@Autowired
private UserMembershipRepository userMembershipRepository;
@Autowired
private MembershipLevelRepository membershipLevelRepository;
@Autowired
private PaymentRepository paymentRepository;
@Autowired
private JwtUtils jwtUtils;
@Autowired
private UserService userService;
// 获取会员列表
@GetMapping
public ResponseEntity<Map<String, Object>> getMembers(
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "10") int pageSize,
@RequestParam(required = false) String level,
@RequestParam(required = false) String status) {
try {
Pageable pageable = PageRequest.of(page - 1, pageSize, Sort.by("createdAt").descending());
// 第一步:根据会员等级筛选(如果指定了等级)
List<Long> filteredUserIds = null;
if (level != null && !level.isEmpty() && !"all".equals(level)) {
// 根据等级名称查找会员等级ID
Optional<MembershipLevel> levelOpt = membershipLevelRepository.findByName(level);
if (levelOpt.isPresent()) {
Long levelId = levelOpt.get().getId();
// 查找具有该等级的所有活跃会员记录
List<UserMembership> memberships = userMembershipRepository.findAll().stream()
.filter(m -> "ACTIVE".equals(m.getStatus()) && levelId.equals(m.getMembershipLevelId()))
.toList();
// 提取用户ID列表
filteredUserIds = memberships.stream()
.map(UserMembership::getUserId)
.distinct()
.toList();
logger.info("会员等级筛选: level={}, levelId={}, 找到 {} 个用户", level, levelId, filteredUserIds.size());
} else {
logger.warn("未找到会员等级: level={}", level);
// 如果找不到等级,返回空列表
filteredUserIds = List.of();
}
}
// 第二步:根据 status 参数和等级筛选结果查询用户
Page<User> userPage;
if (filteredUserIds != null) {
// 如果有等级筛选,需要同时满足等级和状态条件
if (filteredUserIds.isEmpty()) {
// 如果等级筛选结果为空,直接返回空列表
userPage = Page.empty(pageable);
} else {
// 根据用户ID列表和状态筛选
if ("all".equals(status)) {
userPage = userRepository.findByIdIn(filteredUserIds, pageable);
} else if ("banned".equals(status)) {
userPage = userRepository.findByIdInAndIsActive(filteredUserIds, false, pageable);
} else {
userPage = userRepository.findByIdInAndIsActive(filteredUserIds, true, pageable);
}
}
} else {
// 如果没有等级筛选,只根据状态筛选
if ("all".equals(status)) {
userPage = userRepository.findAll(pageable);
} else if ("banned".equals(status)) {
userPage = userRepository.findByIsActive(false, pageable);
} else {
userPage = userRepository.findByIsActive(true, pageable);
}
}
List<Map<String, Object>> members = userPage.getContent().stream()
.map(user -> {
Map<String, Object> member = new HashMap<>();
member.put("id", user.getId());
member.put("username", user.getUsername());
member.put("email", user.getEmail());
member.put("phone", user.getPhone());
member.put("nickname", user.getNickname());
member.put("points", user.getPoints());
member.put("role", user.getRole());
member.put("isActive", user.getIsActive());
member.put("createdAt", user.getCreatedAt());
member.put("lastLoginAt", user.getLastLoginAt());
// 获取会员信息(按到期时间降序,返回最新的)
Optional<UserMembership> membership = userMembershipRepository
.findFirstByUserIdAndStatusOrderByEndDateDesc(user.getId(), "ACTIVE");
if (membership.isPresent()) {
UserMembership userMembership = membership.get();
Optional<MembershipLevel> membershipLevel = membershipLevelRepository
.findById(userMembership.getMembershipLevelId());
if (membershipLevel.isPresent()) {
Map<String, Object> membershipInfo = new HashMap<>();
MembershipLevel memberLevel = membershipLevel.get();
String displayName = memberLevel.getDisplayName();
// 🔥 仅对 free 等级进行特殊判定:根据充值金额区分"免费会员"和"入门会员"
// 其他等级standard/professional直接使用数据库中的 displayName
if ("free".equalsIgnoreCase(memberLevel.getName())) {
// 计算用户的总充值金额(而非充值次数)
java.math.BigDecimal totalPaid = paymentRepository.sumAmountByUserIdAndStatus(
user.getId(),
com.example.demo.model.PaymentStatus.SUCCESS
);
// 获取入门版的价格阈值
double freePrice = memberLevel.getPrice() != null ? memberLevel.getPrice() : 0.0;
double totalAmount = totalPaid != null ? totalPaid.doubleValue() : 0.0;
// 充值金额 >= 入门版价格 → 入门会员,否则 → 免费会员
if (totalAmount >= freePrice && freePrice > 0) {
displayName = "入门会员"; // 充值金额达到入门版价格
} else {
displayName = "免费会员"; // 未充值或充值金额不足
}
}
// 注:如果出现标准会员被判定为入门会员,请检查数据库 user_memberships 表中
// 该用户的 membership_level_id 是否正确指向 standard 等级(通常 id=2
membershipInfo.put("display_name", displayName);
membershipInfo.put("end_date", userMembership.getEndDate());
membershipInfo.put("status", userMembership.getStatus());
member.put("membership", membershipInfo);
}
}
return member;
})
.toList();
Map<String, Object> response = new HashMap<>();
response.put("list", members);
response.put("total", userPage.getTotalElements());
response.put("page", page);
response.put("pageSize", pageSize);
response.put("totalPages", userPage.getTotalPages());
return ResponseEntity.ok(response);
} catch (Exception e) {
Map<String, Object> error = new HashMap<>();
error.put("error", "获取会员列表失败");
error.put("message", e.getMessage());
return ResponseEntity.status(500).body(error);
}
}
// 获取会员详情
@GetMapping("/{id}")
public ResponseEntity<Map<String, Object>> getMemberDetail(@PathVariable Long id) {
try {
Optional<User> userOpt = userRepository.findById(id);
if (userOpt.isEmpty()) {
return ResponseEntity.notFound().build();
}
User user = userOpt.get();
Map<String, Object> member = new HashMap<>();
member.put("id", user.getId());
member.put("username", user.getUsername());
member.put("email", user.getEmail());
member.put("phone", user.getPhone());
member.put("nickname", user.getNickname());
member.put("points", user.getPoints());
member.put("role", user.getRole());
member.put("isActive", user.getIsActive());
member.put("createdAt", user.getCreatedAt());
member.put("lastLoginAt", user.getLastLoginAt());
// 获取会员信息(按到期时间降序,返回最新的)
Optional<UserMembership> membership = userMembershipRepository
.findFirstByUserIdAndStatusOrderByEndDateDesc(user.getId(), "ACTIVE");
if (membership.isPresent()) {
UserMembership userMembership = membership.get();
Optional<MembershipLevel> membershipLevel = membershipLevelRepository
.findById(userMembership.getMembershipLevelId());
if (membershipLevel.isPresent()) {
Map<String, Object> membershipInfo = new HashMap<>();
MembershipLevel memberLevel = membershipLevel.get();
String displayName = memberLevel.getDisplayName();
// 🔥 仅对 free 等级进行特殊判定:根据充值金额区分"免费会员"和"入门会员"
// 其他等级standard/professional直接使用数据库中的 displayName
if ("free".equalsIgnoreCase(memberLevel.getName())) {
// 计算用户的总充值金额(而非充值次数)
java.math.BigDecimal totalPaid = paymentRepository.sumAmountByUserIdAndStatus(
user.getId(),
com.example.demo.model.PaymentStatus.SUCCESS
);
// 获取入门版的价格阈值
double freePrice = memberLevel.getPrice() != null ? memberLevel.getPrice() : 0.0;
double totalAmount = totalPaid != null ? totalPaid.doubleValue() : 0.0;
// 充值金额 >= 入门版价格 → 入门会员,否则 → 免费会员
if (totalAmount >= freePrice && freePrice > 0) {
displayName = "入门会员"; // 充值金额达到入门版价格
} else {
displayName = "免费会员"; // 未充值或充值金额不足
}
}
// 注:如果出现标准会员被判定为入门会员,请检查数据库 user_memberships 表中
// 该用户的 membership_level_id 是否正确指向 standard 等级(通常 id=2
membershipInfo.put("display_name", displayName);
membershipInfo.put("end_date", userMembership.getEndDate());
membershipInfo.put("status", userMembership.getStatus());
member.put("membership", membershipInfo);
}
}
return ResponseEntity.ok(member);
} catch (Exception e) {
Map<String, Object> error = new HashMap<>();
error.put("error", "获取会员详情失败");
error.put("message", e.getMessage());
return ResponseEntity.status(500).body(error);
}
}
// 更新会员信息
@PutMapping("/{id}")
public ResponseEntity<Map<String, Object>> updateMember(
@PathVariable Long id,
@RequestBody Map<String, Object> updateData,
@RequestHeader("Authorization") String token) {
try {
// 验证管理员权限
String adminUsername = extractUsernameFromToken(token);
if (adminUsername == null) {
return ResponseEntity.status(401).body(Map.of("success", false, "message", "用户未登录"));
}
User admin = userRepository.findByUsername(adminUsername).orElse(null);
if (admin == null) {
return ResponseEntity.status(403).body(Map.of("success", false, "message", "需要管理员权限"));
}
boolean isSuperAdmin = "ROLE_SUPER_ADMIN".equals(admin.getRole());
boolean isAdmin = "ROLE_ADMIN".equals(admin.getRole());
if (!isSuperAdmin && !isAdmin) {
return ResponseEntity.status(403).body(Map.of("success", false, "message", "需要管理员权限"));
}
Optional<User> userOpt = userRepository.findById(id);
if (userOpt.isEmpty()) {
return ResponseEntity.notFound().build();
}
User user = userOpt.get();
// 普通管理员不能修改超级管理员的信息
if ("ROLE_SUPER_ADMIN".equals(user.getRole()) && !isSuperAdmin) {
return ResponseEntity.status(403).body(Map.of("success", false, "message", "只有超级管理员才能修改超级管理员的信息"));
}
// 更新用户基本信息
if (updateData.containsKey("username")) {
user.setUsername((String) updateData.get("username"));
}
if (updateData.containsKey("points")) {
Object pointsObj = updateData.get("points");
if (pointsObj instanceof Number) {
user.setPoints(((Number) pointsObj).intValue());
}
}
// 只有超级管理员可以修改角色,且不能修改超级管理员的角色
if (updateData.containsKey("role") && isSuperAdmin) {
String newRole = (String) updateData.get("role");
// 如果被编辑的用户是超级管理员,跳过角色修改
if ("ROLE_SUPER_ADMIN".equals(user.getRole())) {
// 不做任何操作,保持超级管理员角色
} else if ("ROLE_USER".equals(newRole) || "ROLE_ADMIN".equals(newRole)) {
// 只允许设置为普通用户或管理员
user.setRole(newRole);
}
// 如果 newRole 是 ROLE_SUPER_ADMIN忽略不允许通过此接口设置超级管理员
}
userService.save(user);
// 更新会员等级和到期时间
String levelName = (String) updateData.get("level");
String expiryDateStr = (String) updateData.get("expiryDate");
logger.info("更新会员等级: userId={}, levelName={}, expiryDate={}", id, levelName, expiryDateStr);
// 只要有会员等级或到期时间参数,就需要更新会员信息
if (levelName != null || (expiryDateStr != null && !expiryDateStr.isEmpty())) {
// 查找或创建会员信息(按到期时间降序,返回最新的)
Optional<UserMembership> membershipOpt = userMembershipRepository
.findFirstByUserIdAndStatusOrderByEndDateDesc(user.getId(), "ACTIVE");
UserMembership membership;
MembershipLevel level = null;
// 如果传入了会员等级,查找对应的等级
if (levelName != null) {
// 先尝试精确匹配 displayName
Optional<MembershipLevel> levelOpt = membershipLevelRepository.findByDisplayName(levelName);
// 如果找不到,尝试模糊匹配
if (!levelOpt.isPresent()) {
List<MembershipLevel> allLevels = membershipLevelRepository.findAll();
for (MembershipLevel lvl : allLevels) {
String name = lvl.getName();
String displayName = lvl.getDisplayName();
// 匹配 "专业会员" -> "professional" 或 "专业版"
if (levelName.contains("专业") && "professional".equalsIgnoreCase(name)) {
levelOpt = Optional.of(lvl);
break;
}
// 匹配 "标准会员" -> "standard" 或 "标准会员"
if (levelName.contains("标准") && "standard".equalsIgnoreCase(name)) {
levelOpt = Optional.of(lvl);
break;
}
// 匹配 "入门"/"免费" -> "free"(后端标记仍为 free
if ((levelName.contains("入门") || levelName.contains("免费")) && "free".equalsIgnoreCase(name)) {
levelOpt = Optional.of(lvl);
break;
}
}
}
logger.info("查找会员等级结果: levelName={}, found={}", levelName, levelOpt.isPresent());
if (levelOpt.isPresent()) {
level = levelOpt.get();
} else {
logger.warn("❌ 未找到会员等级: levelName={}", levelName);
}
}
if (membershipOpt.isPresent()) {
membership = membershipOpt.get();
logger.info("找到现有会员记录: membershipId={}, currentEndDate={}", membership.getId(), membership.getEndDate());
} else {
// 创建新的会员记录
membership = new UserMembership();
membership.setUserId(user.getId());
membership.setStatus("ACTIVE");
membership.setStartDate(java.time.LocalDateTime.now());
// 默认到期时间为1年后
membership.setEndDate(java.time.LocalDateTime.now().plusDays(365));
logger.info("创建新会员记录");
// 如果没有指定等级,默认使用标准会员
if (level == null) {
Optional<MembershipLevel> defaultLevel = membershipLevelRepository.findByName("standard");
if (defaultLevel.isPresent()) {
level = defaultLevel.get();
}
}
}
// 更新会员等级
if (level != null) {
membership.setMembershipLevelId(level.getId());
}
// 更新到期时间
if (expiryDateStr != null && !expiryDateStr.isEmpty()) {
try {
// 尝试解析带时间的格式 (如 2025-12-11T17:03:16)
java.time.LocalDateTime expiryDateTime = java.time.LocalDateTime.parse(expiryDateStr);
membership.setEndDate(expiryDateTime);
logger.info("设置到期时间(带时间格式): {}", expiryDateTime);
} catch (Exception e1) {
try {
// 尝试解析仅日期格式 (如 2025-12-11)
java.time.LocalDate expiryDate = java.time.LocalDate.parse(expiryDateStr);
membership.setEndDate(expiryDate.atTime(23, 59, 59));
logger.info("设置到期时间(日期格式): {}", expiryDate.atTime(23, 59, 59));
} catch (Exception e2) {
logger.warn("日期格式错误: {}", expiryDateStr);
}
}
}
membership.setUpdatedAt(java.time.LocalDateTime.now());
UserMembership saved = userMembershipRepository.save(membership);
logger.info("✅ 会员信息已保存: userId={}, membershipId={}, levelId={}, endDate={}",
user.getId(), saved.getId(), saved.getMembershipLevelId(), saved.getEndDate());
} else {
logger.info("未传入会员等级和到期时间参数,跳过会员信息更新");
}
Map<String, Object> response = new HashMap<>();
response.put("success", true);
response.put("message", "会员信息更新成功");
return ResponseEntity.ok(response);
} catch (Exception e) {
Map<String, Object> error = new HashMap<>();
error.put("error", "更新会员信息失败");
error.put("message", e.getMessage());
return ResponseEntity.status(500).body(error);
}
}
// 删除会员
@DeleteMapping("/{id}")
@Transactional
public ResponseEntity<Map<String, Object>> deleteMember(
@PathVariable Long id,
@RequestHeader("Authorization") String token) {
try {
// 验证管理员权限
String adminUsername = extractUsernameFromToken(token);
if (adminUsername == null) {
return ResponseEntity.status(401).body(Map.of("success", false, "message", "用户未登录"));
}
User admin = userRepository.findByUsername(adminUsername).orElse(null);
if (admin == null) {
return ResponseEntity.status(403).body(Map.of("success", false, "message", "需要管理员权限"));
}
boolean isSuperAdmin = "ROLE_SUPER_ADMIN".equals(admin.getRole());
boolean isAdmin = "ROLE_ADMIN".equals(admin.getRole());
if (!isSuperAdmin && !isAdmin) {
return ResponseEntity.status(403).body(Map.of("success", false, "message", "需要管理员权限"));
}
Optional<User> userOpt = userRepository.findById(id);
if (userOpt.isEmpty()) {
return ResponseEntity.notFound().build();
}
User user = userOpt.get();
// 不能删除自己
if (user.getUsername().equals(adminUsername)) {
return ResponseEntity.badRequest().body(Map.of("success", false, "message", "不能删除自己的账号"));
}
// 不能删除超级管理员
if ("ROLE_SUPER_ADMIN".equals(user.getRole())) {
return ResponseEntity.badRequest().body(Map.of("success", false, "message", "不能删除超级管理员账号"));
}
// 普通管理员不能删除其他管理员,只有超级管理员可以
if ("ROLE_ADMIN".equals(user.getRole()) && !isSuperAdmin) {
return ResponseEntity.badRequest().body(Map.of("success", false, "message", "只有超级管理员才能删除管理员账号"));
}
// 先删除关联的会员信息
userMembershipRepository.deleteByUserId(user.getId());
// 清除用户缓存
userService.evictUserCache(user.getUsername());
// 物理删除用户
userRepository.delete(user);
Map<String, Object> response = new HashMap<>();
response.put("success", true);
response.put("message", "会员删除成功");
return ResponseEntity.ok(response);
} catch (Exception e) {
Map<String, Object> error = new HashMap<>();
error.put("error", "删除会员失败");
error.put("message", e.getMessage());
return ResponseEntity.status(500).body(error);
}
}
// 批量删除会员
@DeleteMapping("/batch")
@Transactional
public ResponseEntity<Map<String, Object>> deleteMembers(
@RequestBody Map<String, List<Long>> request,
@RequestHeader("Authorization") String token) {
try {
// 验证管理员权限
String adminUsername = extractUsernameFromToken(token);
if (adminUsername == null) {
return ResponseEntity.status(401).body(Map.of("success", false, "message", "用户未登录"));
}
User admin = userRepository.findByUsername(adminUsername).orElse(null);
if (admin == null) {
return ResponseEntity.status(403).body(Map.of("success", false, "message", "需要管理员权限"));
}
boolean isSuperAdmin = "ROLE_SUPER_ADMIN".equals(admin.getRole());
boolean isAdmin = "ROLE_ADMIN".equals(admin.getRole());
if (!isSuperAdmin && !isAdmin) {
return ResponseEntity.status(403).body(Map.of("success", false, "message", "需要管理员权限"));
}
List<Long> ids = request.get("ids");
if (ids == null || ids.isEmpty()) {
return ResponseEntity.badRequest().body(Map.of("error", "请提供要删除的会员ID列表"));
}
List<User> users = userRepository.findAllById(ids);
// 过滤掉自己、超级管理员,普通管理员还需要过滤掉其他管理员
final boolean finalIsSuperAdmin = isSuperAdmin;
List<User> toDelete = users.stream()
.filter(user -> !user.getUsername().equals(adminUsername))
.filter(user -> !"ROLE_SUPER_ADMIN".equals(user.getRole()))
.filter(user -> finalIsSuperAdmin || !"ROLE_ADMIN".equals(user.getRole()))
.toList();
int skipped = users.size() - toDelete.size();
// 物理删除:先删除关联的会员信息,清除缓存,再删除用户
for (User user : toDelete) {
userMembershipRepository.deleteByUserId(user.getId());
userService.evictUserCache(user.getUsername()); // 清除缓存
}
userRepository.deleteAll(toDelete);
Map<String, Object> response = new HashMap<>();
response.put("success", true);
response.put("message", skipped > 0
? "批量删除成功,已跳过 " + skipped + " 个管理员账号"
: "批量删除成功");
response.put("deletedCount", toDelete.size());
response.put("skippedCount", skipped);
return ResponseEntity.ok(response);
} catch (Exception e) {
Map<String, Object> error = new HashMap<>();
error.put("error", "批量删除失败");
error.put("message", e.getMessage());
return ResponseEntity.status(500).body(error);
}
}
// 封禁/解封会员
@PutMapping("/{id}/ban")
public ResponseEntity<Map<String, Object>> toggleBanMember(
@PathVariable Long id,
@RequestBody Map<String, Boolean> request,
@RequestHeader("Authorization") String token) {
try {
// 验证管理员权限
String adminUsername = extractUsernameFromToken(token);
if (adminUsername == null) {
return ResponseEntity.status(401).body(Map.of("success", false, "message", "用户未登录"));
}
User admin = userRepository.findByUsername(adminUsername).orElse(null);
if (admin == null) {
return ResponseEntity.status(403).body(Map.of("success", false, "message", "需要管理员权限"));
}
boolean isSuperAdmin = "ROLE_SUPER_ADMIN".equals(admin.getRole());
boolean isAdmin = "ROLE_ADMIN".equals(admin.getRole());
if (!isSuperAdmin && !isAdmin) {
return ResponseEntity.status(403).body(Map.of("success", false, "message", "需要管理员权限"));
}
Optional<User> userOpt = userRepository.findById(id);
if (userOpt.isEmpty()) {
return ResponseEntity.notFound().build();
}
User user = userOpt.get();
// 不能封禁自己
if (user.getUsername().equals(adminUsername)) {
return ResponseEntity.badRequest().body(Map.of("success", false, "message", "不能封禁自己的账号"));
}
// 不能封禁超级管理员
if ("ROLE_SUPER_ADMIN".equals(user.getRole())) {
return ResponseEntity.badRequest().body(Map.of("success", false, "message", "不能封禁超级管理员账号"));
}
// 普通管理员不能封禁其他管理员,只有超级管理员可以
if ("ROLE_ADMIN".equals(user.getRole()) && !isSuperAdmin) {
return ResponseEntity.badRequest().body(Map.of("success", false, "message", "只有超级管理员才能封禁管理员账号"));
}
// 获取要设置的状态true=解封false=封禁)
Boolean isActive = request.get("isActive");
if (isActive == null) {
isActive = !user.getIsActive(); // 如果没传,则切换状态
}
user.setIsActive(isActive);
userService.save(user);
Map<String, Object> response = new HashMap<>();
response.put("success", true);
response.put("message", isActive ? "解封成功" : "封禁成功");
response.put("isActive", isActive);
return ResponseEntity.ok(response);
} catch (Exception e) {
Map<String, Object> error = new HashMap<>();
error.put("error", "操作失败");
error.put("message", e.getMessage());
return ResponseEntity.status(500).body(error);
}
}
// 设置用户角色(仅超级管理员可操作)
@PutMapping("/{id}/role")
public ResponseEntity<Map<String, Object>> setUserRole(
@PathVariable Long id,
@RequestBody Map<String, String> request,
@RequestHeader("Authorization") String token) {
try {
// 验证超级管理员权限
String adminUsername = extractUsernameFromToken(token);
if (adminUsername == null) {
return ResponseEntity.status(401).body(Map.of("success", false, "message", "用户未登录"));
}
User admin = userRepository.findByUsername(adminUsername).orElse(null);
if (admin == null || !"ROLE_SUPER_ADMIN".equals(admin.getRole())) {
return ResponseEntity.status(403).body(Map.of("success", false, "message", "需要超级管理员权限"));
}
Optional<User> userOpt = userRepository.findById(id);
if (userOpt.isEmpty()) {
return ResponseEntity.notFound().build();
}
User user = userOpt.get();
// 不能修改自己的角色
if (user.getUsername().equals(adminUsername)) {
return ResponseEntity.badRequest().body(Map.of("success", false, "message", "不能修改自己的角色"));
}
// 不能修改其他超级管理员的角色
if ("ROLE_SUPER_ADMIN".equals(user.getRole())) {
return ResponseEntity.badRequest().body(Map.of("success", false, "message", "不能修改超级管理员的角色"));
}
String newRole = request.get("role");
if (newRole == null || newRole.isEmpty()) {
return ResponseEntity.badRequest().body(Map.of("success", false, "message", "请指定角色"));
}
// 验证角色有效性
if (!"ROLE_USER".equals(newRole) && !"ROLE_ADMIN".equals(newRole)) {
return ResponseEntity.badRequest().body(Map.of("success", false, "message", "无效的角色"));
}
String oldRole = user.getRole();
user.setRole(newRole);
userService.save(user);
String action = "ROLE_ADMIN".equals(newRole) ? "设置为管理员" : "取消管理员权限";
Map<String, Object> response = new HashMap<>();
response.put("success", true);
response.put("message", "用户 " + user.getUsername() + "" + action);
response.put("oldRole", oldRole);
response.put("newRole", newRole);
return ResponseEntity.ok(response);
} catch (Exception e) {
Map<String, Object> error = new HashMap<>();
error.put("error", "操作失败");
error.put("message", e.getMessage());
return ResponseEntity.status(500).body(error);
}
}
// 从Token中提取用户名
private String extractUsernameFromToken(String token) {
try {
if (token == null || !token.startsWith("Bearer ")) {
return null;
}
String actualToken = token.substring(7);
if (jwtUtils.isTokenExpired(actualToken)) {
return null;
}
return jwtUtils.getUsernameFromToken(actualToken);
} catch (Exception e) {
return null;
}
}
// 获取所有会员等级配置(用于系统设置和订阅页面)
@GetMapping("/levels")
public ResponseEntity<Map<String, Object>> getMembershipLevels() {
try {
List<MembershipLevel> levels = membershipLevelRepository.findAll();
List<Map<String, Object>> levelList = levels.stream()
.map(level -> {
Map<String, Object> levelMap = new HashMap<>();
levelMap.put("id", level.getId());
levelMap.put("name", level.getName());
levelMap.put("displayName", level.getDisplayName());
levelMap.put("description", level.getDescription());
levelMap.put("price", level.getPrice());
levelMap.put("durationDays", level.getDurationDays());
levelMap.put("pointsBonus", level.getPointsBonus());
levelMap.put("features", level.getFeatures());
levelMap.put("isActive", level.getIsActive());
return levelMap;
})
.toList();
Map<String, Object> response = new HashMap<>();
response.put("success", true);
response.put("data", levelList);
return ResponseEntity.ok(response);
} catch (Exception e) {
Map<String, Object> error = new HashMap<>();
error.put("error", "获取会员等级配置失败");
error.put("message", e.getMessage());
return ResponseEntity.status(500).body(error);
}
}
// 更新会员等级价格和配置
@PutMapping("/levels/{id}")
public ResponseEntity<Map<String, Object>> updateMembershipLevel(
@PathVariable Long id,
@RequestBody Map<String, Object> updateData) {
try {
Optional<MembershipLevel> levelOpt = membershipLevelRepository.findById(id);
if (levelOpt.isEmpty()) {
return ResponseEntity.notFound().build();
}
MembershipLevel level = levelOpt.get();
// 更新价格
if (updateData.containsKey("price")) {
Object priceObj = updateData.get("price");
if (priceObj instanceof Number) {
level.setPrice(((Number) priceObj).doubleValue());
} else if (priceObj instanceof String) {
level.setPrice(Double.parseDouble((String) priceObj));
}
}
// 更新资源点数量
if (updateData.containsKey("pointsBonus") || updateData.containsKey("resourcePoints")) {
Object pointsObj = updateData.get("pointsBonus") != null
? updateData.get("pointsBonus")
: updateData.get("resourcePoints");
if (pointsObj instanceof Number) {
level.setPointsBonus(((Number) pointsObj).intValue());
} else if (pointsObj instanceof String) {
level.setPointsBonus(Integer.parseInt((String) pointsObj));
}
}
// 更新描述
if (updateData.containsKey("description")) {
level.setDescription((String) updateData.get("description"));
}
level.setUpdatedAt(java.time.LocalDateTime.now());
membershipLevelRepository.save(level);
Map<String, Object> response = new HashMap<>();
response.put("success", true);
response.put("message", "会员等级配置更新成功");
return ResponseEntity.ok(response);
} catch (Exception e) {
Map<String, Object> error = new HashMap<>();
error.put("error", "更新会员等级配置失败");
error.put("message", e.getMessage());
return ResponseEntity.status(500).body(error);
}
}
}