feat(admin): Implement admin module foundation
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
package com.nuaa.video.auth.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.nuaa.video.auth.entity.AuthUser;
|
||||
import com.nuaa.video.auth.service.AuthUserService;
|
||||
import com.nuaa.video.common.model.vo.Result;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* 认证管理控制器 - 供管理后台调用
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/auth/admin")
|
||||
@RequiredArgsConstructor
|
||||
public class AdminAuthController {
|
||||
|
||||
private final AuthUserService authUserService;
|
||||
|
||||
/**
|
||||
* 获取登录统计 - 管理接口
|
||||
*/
|
||||
@GetMapping("/login/stats")
|
||||
public Result<Object> getLoginStats() {
|
||||
return authUserService.getLoginStats();
|
||||
}
|
||||
|
||||
/**
|
||||
* 管理员重置用户密码 - 管理接口
|
||||
*/
|
||||
@PutMapping("/reset-password/{userId}")
|
||||
public Result<Void> resetPassword(
|
||||
@PathVariable Long userId,
|
||||
@RequestParam String newPassword) {
|
||||
return authUserService.adminResetPassword(userId, newPassword);
|
||||
}
|
||||
|
||||
/**
|
||||
* 锁定/解锁用户账号 - 管理接口
|
||||
*/
|
||||
@PutMapping("/lock/{userId}/{locked}")
|
||||
public Result<Void> lockUser(
|
||||
@PathVariable Long userId,
|
||||
@PathVariable Boolean locked) {
|
||||
return authUserService.lockUser(userId, locked);
|
||||
}
|
||||
}
|
||||
@@ -59,4 +59,19 @@ public interface AuthUserService extends IService<AuthUser> {
|
||||
* @return 用户信息
|
||||
*/
|
||||
Result<AuthUser> getCurrentUser(Long userId);
|
||||
|
||||
/**
|
||||
* 获取登录统计 - 管理接口
|
||||
*/
|
||||
Result<Object> getLoginStats();
|
||||
|
||||
/**
|
||||
* 管理员重置用户密码 - 管理接口
|
||||
*/
|
||||
Result<Void> adminResetPassword(Long userId, String newPassword);
|
||||
|
||||
/**
|
||||
* 锁定/解锁用户账号 - 管理接口
|
||||
*/
|
||||
Result<Void> lockUser(Long userId, Boolean locked);
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.nuaa.video.auth.service.impl;
|
||||
|
||||
import cn.hutool.core.lang.UUID;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
@@ -24,10 +25,14 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
import org.springframework.util.DigestUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 用户认证服务实现类
|
||||
@@ -283,6 +288,109 @@ public class AuthUserServiceImpl extends ServiceImpl<AuthUserMapper, AuthUser> i
|
||||
return Result.success(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Object> getLoginStats() {
|
||||
Map<String, Object> stats = new HashMap<>();
|
||||
|
||||
// 这里是模拟数据,实际项目中需要从数据库或缓存中获取
|
||||
|
||||
// 总用户数
|
||||
long totalUsers = count();
|
||||
stats.put("totalUsers", totalUsers);
|
||||
|
||||
// 今日登录用户数
|
||||
LocalDate today = LocalDate.now();
|
||||
long todayLoginUsers = 0; // 实际需要查询登录记录表
|
||||
stats.put("todayLoginUsers", todayLoginUsers);
|
||||
|
||||
// 当前在线用户数(可从Redis中获取)
|
||||
long onlineUsers = 0; // 实际需要从Redis或其他存储中获取
|
||||
stats.put("onlineUsers", onlineUsers);
|
||||
|
||||
// 最近7天每日登录用户数
|
||||
Map<String, Long> dailyLoginUsers = new HashMap<>();
|
||||
for (int i = 6; i >= 0; i--) {
|
||||
LocalDate date = today.minusDays(i);
|
||||
String dateStr = date.toString();
|
||||
long count = 0; // 实际需要查询登录记录表
|
||||
dailyLoginUsers.put(dateStr, count);
|
||||
}
|
||||
stats.put("dailyLoginUsers", dailyLoginUsers);
|
||||
|
||||
return Result.success(stats);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Result<Void> adminResetPassword(Long userId, String newPassword) {
|
||||
// 查询用户是否存在
|
||||
AuthUser user = getById(userId);
|
||||
if (user == null) {
|
||||
return Result.error("用户不存在");
|
||||
}
|
||||
|
||||
// 生成新的盐值
|
||||
String salt = generateSalt();
|
||||
// 加密密码
|
||||
String encryptedPassword = encryptPassword(newPassword, salt);
|
||||
|
||||
// 更新密码和盐值
|
||||
AuthUser updateUser = new AuthUser();
|
||||
updateUser.setId(userId);
|
||||
updateUser.setPassword(encryptedPassword);
|
||||
updateUser.setSalt(salt);
|
||||
updateUser.setUpdatedBy("admin");
|
||||
updateUser.setUpdateTime(LocalDateTime.now());
|
||||
updateById(updateUser);
|
||||
|
||||
// 清除用户token
|
||||
String tokenKey = "auth:token:" + userId;
|
||||
redisUtils.del(tokenKey);
|
||||
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Result<Void> lockUser(Long userId, Boolean locked) {
|
||||
// 查询用户是否存在
|
||||
AuthUser user = getById(userId);
|
||||
if (user == null) {
|
||||
return Result.error("用户不存在");
|
||||
}
|
||||
|
||||
// 更新用户状态
|
||||
AuthUser updateUser = new AuthUser();
|
||||
updateUser.setId(userId);
|
||||
updateUser.setStatus(locked ? 0 : 1); // 0-禁用,1-正常
|
||||
updateUser.setUpdatedBy("admin");
|
||||
updateUser.setUpdateTime(LocalDateTime.now());
|
||||
updateById(updateUser);
|
||||
|
||||
// 如果锁定用户,清除用户token
|
||||
if (locked) {
|
||||
String tokenKey = "auth:token:" + userId;
|
||||
redisUtils.del(tokenKey);
|
||||
}
|
||||
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成盐值
|
||||
*/
|
||||
private String generateSalt() {
|
||||
return UUID.randomUUID().toString().replace("-", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密密码
|
||||
*/
|
||||
private String encryptPassword(String password, String salt) {
|
||||
// 实际项目中应该使用加密算法如BCrypt
|
||||
return DigestUtils.md5DigestAsHex((password + salt).getBytes());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户角色
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user