feat(admin): Implement admin module foundation

This commit is contained in:
2025-04-11 00:26:30 +08:00
parent 2f49bed861
commit 36380d50a7
71 changed files with 4682 additions and 15 deletions
@@ -0,0 +1,70 @@
package com.nuaa.video.user.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nuaa.video.common.model.vo.Result;
import com.nuaa.video.user.entity.UserInfo;
import com.nuaa.video.user.service.UserInfoService;
import com.nuaa.video.user.vo.UserProfileVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
/**
* 用户管理控制器 - 供管理后台调用
*/
@Slf4j
@RestController
@RequestMapping("/user/profile/admin")
@RequiredArgsConstructor
public class AdminUserController {
private final UserInfoService userInfoService;
/**
* 获取用户列表 - 管理接口
*/
@GetMapping("/list")
public Result<Page<UserProfileVO>> getUserList(
@RequestParam(value = "page", defaultValue = "1") Integer page,
@RequestParam(value = "size", defaultValue = "10") Integer size,
@RequestParam(value = "keyword", required = false) String keyword) {
Page<UserInfo> pageParam = new Page<>(page, size);
return userInfoService.getAdminUserList(pageParam, keyword);
}
/**
* 获取用户详情 - 管理接口
*/
@GetMapping("/{userId}")
public Result<UserProfileVO> getUserDetail(@PathVariable Long userId) {
return userInfoService.getAdminUserDetail(userId);
}
/**
* 禁用/启用用户 - 管理接口
*/
@PutMapping("/status/{userId}/{status}")
public Result<Void> updateUserStatus(
@PathVariable Long userId,
@PathVariable Integer status) {
return userInfoService.updateUserStatus(userId, status);
}
/**
* 重置用户密码 - 管理接口
*/
@PutMapping("/reset-password/{userId}")
public Result<Void> resetUserPassword(
@PathVariable Long userId,
@RequestParam String newPassword) {
return userInfoService.resetUserPassword(userId, newPassword);
}
/**
* 获取用户统计信息 - 管理接口
*/
@GetMapping("/stats")
public Result<Object> getUserStats() {
return userInfoService.getUserStats();
}
}
@@ -1,11 +1,8 @@
// com.nuaa.video.user.feign.AuthFeignClient.java
package com.nuaa.video.user.feign;
import com.nuaa.video.common.model.vo.Result;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.*;
/**
* 认证服务Feign客户端
@@ -30,4 +27,19 @@ public interface AuthFeignClient {
*/
@GetMapping("/username/{userId}")
String getUsernameById(@PathVariable("userId") Long userId);
/**
* 锁定/解锁用户账号 - 管理接口
*/
@PutMapping("/admin/lock/{userId}/{locked}")
Result<Void> lockUser(@PathVariable Long userId,
@PathVariable Boolean locked);
/**
* 管理员重置用户密码 - 管理接口
*/
@PutMapping("/admin/reset-password/{userId}")
Result<Void> resetPassword(
@PathVariable Long userId,
@RequestParam String newPassword);
}
@@ -92,4 +92,29 @@ public interface UserInfoService extends IService<UserInfo> {
* @return 结果
*/
Result<Void> increaseFavoriteCount(Long userId, Integer count);
/**
* 获取用户列表 - 管理接口
*/
Result<Page<UserProfileVO>> getAdminUserList(Page<UserInfo> page, String keyword);
/**
* 获取用户详情 - 管理接口
*/
Result<UserProfileVO> getAdminUserDetail(Long userId);
/**
* 更新用户状态 - 管理接口
*/
Result<Void> updateUserStatus(Long userId, Integer status);
/**
* 重置用户密码 - 管理接口
*/
Result<Void> resetUserPassword(Long userId, String newPassword);
/**
* 获取用户统计信息 - 管理接口
*/
Result<Object> getUserStats();
}
@@ -9,6 +9,7 @@ import com.nuaa.video.common.utils.MinioUtils;
import com.nuaa.video.user.dto.UserProfileDTO;
import com.nuaa.video.user.entity.UserInfo;
import com.nuaa.video.user.entity.UserStatDaily;
import com.nuaa.video.user.feign.AuthFeignClient;
import com.nuaa.video.user.mapper.UserFollowMapper;
import com.nuaa.video.user.mapper.UserInfoMapper;
import com.nuaa.video.user.mapper.UserStatDailyMapper;
@@ -20,10 +21,15 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 用户信息服务实现类
@@ -38,6 +44,7 @@ public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> i
private final UserSettingService userSettingService;
private final MinioUtils minioUtils;
private final UserStatDailyMapper userStatDailyMapper;
private final AuthFeignClient authFeignClient;
@Override
public Result<UserProfileVO> getUserProfile(Long userId, Long currentUserId) {
@@ -245,6 +252,133 @@ public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> i
return Result.success();
}
@Override
public Result<Page<UserProfileVO>> getAdminUserList(Page<UserInfo> page, String keyword) {
LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
// 添加关键词搜索条件
if (StringUtils.hasText(keyword)) {
queryWrapper.like(UserInfo::getNickname, keyword)
.or()
.like(UserInfo::getSignature, keyword);
}
// 按创建时间降序排序
queryWrapper.orderByDesc(UserInfo::getCreateTime);
// 分页查询
Page<UserInfo> userPage = page(page, queryWrapper);
// 转换为VO
Page<UserProfileVO> voPage = new Page<>();
BeanUtils.copyProperties(userPage, voPage, "records");
List<UserProfileVO> voList = userPage.getRecords().stream()
.map(user -> {
UserProfileVO vo = new UserProfileVO();
BeanUtils.copyProperties(user, vo);
return vo;
})
.collect(Collectors.toList());
voPage.setRecords(voList);
return Result.success(voPage);
}
@Override
public Result<UserProfileVO> getAdminUserDetail(Long userId) {
// 查询用户信息
UserInfo userInfo = getById(userId);
if (userInfo == null) {
return Result.error("用户不存在");
}
// 转换为VO
UserProfileVO vo = new UserProfileVO();
BeanUtils.copyProperties(userInfo, vo);
// 查询用户统计信息
// 例如:历史发布视频、历史评论等
return Result.success(vo);
}
@Override
@Transactional(rollbackFor = Exception.class)
public Result<Void> updateUserStatus(Long userId, Integer status) {
// 查询用户是否存在
UserInfo userInfo = getById(userId);
if (userInfo == null) {
return Result.error("用户不存在");
}
// 更新用户状态
UserInfo updateUser = new UserInfo();
updateUser.setId(userId);
updateUser.setUpdateTime(LocalDateTime.now());
updateUser.setUpdatedBy("admin");
updateById(updateUser);
// 当禁用用户,需要清除用户相关的登录态等
if (status == 0) {
// 发送事件通知auth服务禁用该用户账号
//TODO 可以优化为消息队列
authFeignClient.lockUser(userId, true);
}
return Result.success();
}
@Override
@Transactional(rollbackFor = Exception.class)
public Result<Void> resetUserPassword(Long userId, String newPassword) {
// 查询用户是否存在
UserInfo userInfo = getById(userId);
if (userInfo == null) {
return Result.error("用户不存在");
}
// 调用auth服务重置密码(实际项目中通过Feign或消息队列)
authFeignClient.resetPassword(userId, newPassword);
log.info("重置用户密码: userId={}, newPassword=***", userId);
return Result.success();
}
@Override
public Result<Object> getUserStats() {
// 收集用户统计数据
Map<String, Object> stats = new HashMap<>();
// 总用户数
long totalUsers = count();
stats.put("totalUsers", totalUsers);
// 今日新增用户
LocalDate today = LocalDate.now();
long todayNewUsers = count(new LambdaQueryWrapper<UserInfo>()
.ge(UserInfo::getCreateTime, today.atStartOfDay()));
stats.put("todayNewUsers", todayNewUsers);
// 活跃用户数(最近7天有登录记录的用户)
// 此处需要结合用户登录记录表查询,简化处理
stats.put("activeUsers", totalUsers * 0.3); // 示例数据
// 用户等级分布
// 假设level字段代表用户等级
Map<String, Object> levelDistribution = new HashMap<>();
for (int i = 1; i <= 6; i++) {
int level = i;
long count = count(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getLevel, level));
levelDistribution.put("level" + i, count);
}
stats.put("levelDistribution", levelDistribution);
return Result.success(stats);
}
/**
* 更新用户每日统计数据
*/