feat(backend): Improve authorization governance and video interactions
This commit is contained in:
+93
@@ -0,0 +1,93 @@
|
||||
package com.nuaa.video.admin.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.nuaa.video.admin.annotation.OperationLog;
|
||||
import com.nuaa.video.admin.dto.AdminRoleDTO;
|
||||
import com.nuaa.video.admin.service.AdminPermissionService;
|
||||
import com.nuaa.video.admin.service.AdminRoleService;
|
||||
import com.nuaa.video.admin.vo.AdminPermissionVO;
|
||||
import com.nuaa.video.admin.vo.AdminRoleVO;
|
||||
import com.nuaa.video.common.model.vo.Result;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 角色和权限管理控制器
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/admin/role")
|
||||
@RequiredArgsConstructor
|
||||
public class AdminRoleController {
|
||||
|
||||
private final AdminRoleService adminRoleService;
|
||||
private final AdminPermissionService adminPermissionService;
|
||||
|
||||
@PreAuthorize("hasAuthority('role:manage') or hasRole('ADMIN_SUPER')")
|
||||
@GetMapping("/list")
|
||||
public Result<Page<AdminRoleVO>> listRoles(
|
||||
@RequestParam(value = "page", defaultValue = "1") Integer page,
|
||||
@RequestParam(value = "size", defaultValue = "10") Integer size,
|
||||
@RequestParam(value = "keyword", required = false) String keyword) {
|
||||
return adminRoleService.listRoles(new Page<>(page, size), keyword);
|
||||
}
|
||||
|
||||
@PreAuthorize("hasAuthority('role:manage') or hasAuthority('user:manage') or hasRole('ADMIN_SUPER')")
|
||||
@GetMapping("/all")
|
||||
public Result<List<AdminRoleVO>> listAllRoles() {
|
||||
return adminRoleService.listAllRoles();
|
||||
}
|
||||
|
||||
@PreAuthorize("hasAuthority('role:manage') or hasRole('ADMIN_SUPER')")
|
||||
@GetMapping("/{id}")
|
||||
public Result<AdminRoleVO> getRoleDetail(@PathVariable Long id) {
|
||||
return adminRoleService.getRoleDetail(id);
|
||||
}
|
||||
|
||||
@OperationLog("新增角色")
|
||||
@PreAuthorize("hasAuthority('role:manage') or hasRole('ADMIN_SUPER')")
|
||||
@PostMapping
|
||||
public Result<Void> addRole(@RequestBody @Valid AdminRoleDTO roleDTO) {
|
||||
return adminRoleService.addRole(roleDTO, getCurrentUsername());
|
||||
}
|
||||
|
||||
@OperationLog("更新角色")
|
||||
@PreAuthorize("hasAuthority('role:manage') or hasRole('ADMIN_SUPER')")
|
||||
@PutMapping
|
||||
public Result<Void> updateRole(@RequestBody @Valid AdminRoleDTO roleDTO) {
|
||||
return adminRoleService.updateRole(roleDTO, getCurrentUsername());
|
||||
}
|
||||
|
||||
@OperationLog("角色授权")
|
||||
@PreAuthorize("hasAuthority('role:manage') or hasRole('ADMIN_SUPER')")
|
||||
@PutMapping("/{id}/permissions")
|
||||
public Result<Void> updateRolePermissions(@PathVariable Long id, @RequestBody List<Long> permissionIds) {
|
||||
return adminRoleService.updateRolePermissions(id, permissionIds, getCurrentUsername());
|
||||
}
|
||||
|
||||
@OperationLog("删除角色")
|
||||
@PreAuthorize("hasAuthority('role:manage') or hasRole('ADMIN_SUPER')")
|
||||
@DeleteMapping("/{id}")
|
||||
public Result<Void> deleteRole(@PathVariable Long id) {
|
||||
return adminRoleService.deleteRole(id);
|
||||
}
|
||||
|
||||
@PreAuthorize("hasAuthority('permission:manage') or hasAuthority('role:manage') or hasRole('ADMIN_SUPER')")
|
||||
@GetMapping("/permissions/list")
|
||||
public Result<List<AdminPermissionVO>> listPermissions() {
|
||||
return adminPermissionService.listPermissions();
|
||||
}
|
||||
|
||||
private String getCurrentUsername() {
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
if (authentication != null && authentication.isAuthenticated()) {
|
||||
return authentication.getName();
|
||||
}
|
||||
return "system";
|
||||
}
|
||||
}
|
||||
+8
-8
@@ -29,7 +29,7 @@ public class AdminUserController {
|
||||
/**
|
||||
* 获取管理员列表
|
||||
*/
|
||||
@PreAuthorize("hasAuthority('user:manage')")
|
||||
@PreAuthorize("hasAuthority('user:manage') or hasRole('ADMIN_SUPER')")
|
||||
@GetMapping("/list")
|
||||
public Result<Page<AdminUserVO>> listUsers(
|
||||
@RequestParam(value = "page", defaultValue = "1") Integer page,
|
||||
@@ -42,7 +42,7 @@ public class AdminUserController {
|
||||
/**
|
||||
* 获取管理员详情
|
||||
*/
|
||||
@PreAuthorize("hasAuthority('user:manage')")
|
||||
@PreAuthorize("hasAuthority('user:manage') or hasRole('ADMIN_SUPER')")
|
||||
@GetMapping("/{id}")
|
||||
public Result<AdminUserVO> getUser(@PathVariable Long id) {
|
||||
return adminUserService.getUserDetail(id);
|
||||
@@ -52,7 +52,7 @@ public class AdminUserController {
|
||||
* 添加管理员
|
||||
*/
|
||||
@OperationLog("添加管理员")
|
||||
@PreAuthorize("hasAuthority('user:manage')")
|
||||
@PreAuthorize("hasAuthority('user:manage') or hasRole('ADMIN_SUPER')")
|
||||
@PostMapping
|
||||
public Result<Void> addUser(@RequestBody @Valid AdminUserDTO adminUserDTO) {
|
||||
return adminUserService.addUser(adminUserDTO, getCurrentUsername());
|
||||
@@ -62,7 +62,7 @@ public class AdminUserController {
|
||||
* 更新管理员
|
||||
*/
|
||||
@OperationLog("更新管理员")
|
||||
@PreAuthorize("hasAuthority('user:manage')")
|
||||
@PreAuthorize("hasAuthority('user:manage') or hasRole('ADMIN_SUPER')")
|
||||
@PutMapping
|
||||
public Result<Void> updateUser(@RequestBody @Valid AdminUserDTO adminUserDTO) {
|
||||
return adminUserService.updateUser(adminUserDTO, getCurrentUsername());
|
||||
@@ -72,7 +72,7 @@ public class AdminUserController {
|
||||
* 删除管理员
|
||||
*/
|
||||
@OperationLog("删除管理员")
|
||||
@PreAuthorize("hasAuthority('user:manage')")
|
||||
@PreAuthorize("hasAuthority('user:manage') or hasRole('ADMIN_SUPER')")
|
||||
@DeleteMapping("/{id}")
|
||||
public Result<Void> deleteUser(@PathVariable Long id) {
|
||||
return adminUserService.deleteUser(id);
|
||||
@@ -82,7 +82,7 @@ public class AdminUserController {
|
||||
* 启用/禁用管理员
|
||||
*/
|
||||
@OperationLog("修改管理员状态")
|
||||
@PreAuthorize("hasAuthority('user:manage')")
|
||||
@PreAuthorize("hasAuthority('user:manage') or hasRole('ADMIN_SUPER')")
|
||||
@PutMapping("/{id}/status/{status}")
|
||||
public Result<Void> updateStatus(@PathVariable Long id, @PathVariable Integer status) {
|
||||
return adminUserService.updateStatus(id, status, getCurrentUsername());
|
||||
@@ -92,7 +92,7 @@ public class AdminUserController {
|
||||
* 重置密码
|
||||
*/
|
||||
@OperationLog("重置管理员密码")
|
||||
@PreAuthorize("hasAuthority('user:manage')")
|
||||
@PreAuthorize("hasAuthority('user:manage') or hasRole('ADMIN_SUPER')")
|
||||
@PutMapping("/{id}/reset-password")
|
||||
public Result<Void> resetPassword(@PathVariable Long id, @RequestParam String newPassword) {
|
||||
return adminUserService.resetPassword(id, newPassword, getCurrentUsername());
|
||||
@@ -108,4 +108,4 @@ public class AdminUserController {
|
||||
}
|
||||
return "system";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+12
-1
@@ -34,8 +34,9 @@ public class CommentManageController {
|
||||
@RequestParam(value = "size", defaultValue = "10") Integer size,
|
||||
@RequestParam(value = "videoId", required = false) Long videoId,
|
||||
@RequestParam(value = "userId", required = false) Long userId,
|
||||
@RequestParam(value = "status", required = false) Integer status,
|
||||
@RequestParam(value = "keyword", required = false) String keyword) {
|
||||
return commentFeignClient.getCommentList(page, size, videoId, userId, keyword, internalServiceToken);
|
||||
return commentFeignClient.getCommentList(page, size, videoId, userId, status, keyword, internalServiceToken);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,6 +58,16 @@ public class CommentManageController {
|
||||
return commentFeignClient.deleteComment(commentId, internalServiceToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复评论
|
||||
*/
|
||||
@OperationLog("恢复评论")
|
||||
@PreAuthorize("hasAuthority('comment:manage')")
|
||||
@PutMapping("/{commentId}/restore")
|
||||
public Result<Void> restoreComment(@PathVariable Long commentId) {
|
||||
return commentFeignClient.restoreComment(commentId, internalServiceToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取评论统计信息
|
||||
*/
|
||||
|
||||
+3
-2
@@ -32,8 +32,9 @@ public class UserManageController {
|
||||
public Result<Page<Object>> getUserList(
|
||||
@RequestParam(value = "page", defaultValue = "1") Integer page,
|
||||
@RequestParam(value = "size", defaultValue = "10") Integer size,
|
||||
@RequestParam(value = "keyword", required = false) String keyword) {
|
||||
return userFeignClient.getUserList(page, size, keyword, internalServiceToken);
|
||||
@RequestParam(value = "keyword", required = false) String keyword,
|
||||
@RequestParam(value = "status", required = false) Integer status) {
|
||||
return userFeignClient.getUserList(page, size, keyword, status, internalServiceToken);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.nuaa.video.admin.dto;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.Pattern;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
@@ -29,7 +28,6 @@ public class AdminRoleDTO implements Serializable {
|
||||
* 角色编码
|
||||
*/
|
||||
@NotBlank(message = "角色编码不能为空")
|
||||
@Pattern(regexp = "^ADMIN_[A-Z_]+$", message = "角色编码必须以ADMIN_开头")
|
||||
private String code;
|
||||
|
||||
/**
|
||||
@@ -38,7 +36,7 @@ public class AdminRoleDTO implements Serializable {
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 权限ID集合
|
||||
* 权限ID列表
|
||||
*/
|
||||
private List<Long> permissionIds;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ public interface CommentFeignClient {
|
||||
@RequestParam(value = "size", defaultValue = "10") Integer size,
|
||||
@RequestParam(value = "videoId", required = false) Long videoId,
|
||||
@RequestParam(value = "userId", required = false) Long userId,
|
||||
@RequestParam(value = "status", required = false) Integer status,
|
||||
@RequestParam(value = "keyword", required = false) String keyword,
|
||||
@RequestHeader("X-Internal-Token") String internalToken);
|
||||
|
||||
@@ -37,6 +38,13 @@ public interface CommentFeignClient {
|
||||
Result<Void> deleteComment(@PathVariable("commentId") Long commentId,
|
||||
@RequestHeader("X-Internal-Token") String internalToken);
|
||||
|
||||
/**
|
||||
* 恢复评论
|
||||
*/
|
||||
@PutMapping("/comment/admin/{commentId}/restore")
|
||||
Result<Void> restoreComment(@PathVariable("commentId") Long commentId,
|
||||
@RequestHeader("X-Internal-Token") String internalToken);
|
||||
|
||||
/**
|
||||
* 获取评论统计信息
|
||||
*/
|
||||
|
||||
+6
-1
@@ -19,7 +19,7 @@ public class CommentFeignClientFallbackFactory implements FallbackFactory<Commen
|
||||
|
||||
return new CommentFeignClient() {
|
||||
@Override
|
||||
public Result<Page<Object>> getCommentList(Integer page, Integer size, Long videoId, Long userId, String keyword, String internalToken) {
|
||||
public Result<Page<Object>> getCommentList(Integer page, Integer size, Long videoId, Long userId, Integer status, String keyword, String internalToken) {
|
||||
return Result.error("获取评论列表失败:服务不可用");
|
||||
}
|
||||
|
||||
@@ -33,6 +33,11 @@ public class CommentFeignClientFallbackFactory implements FallbackFactory<Commen
|
||||
return Result.error("删除评论失败:服务不可用");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Void> restoreComment(Long commentId, String internalToken) {
|
||||
return Result.error("恢复评论失败:服务不可用");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Object> getCommentStats(String internalToken) {
|
||||
return Result.error("获取评论统计信息失败:服务不可用");
|
||||
|
||||
@@ -19,6 +19,7 @@ public interface UserFeignClient {
|
||||
@RequestParam(value = "page", defaultValue = "1") Integer page,
|
||||
@RequestParam(value = "size", defaultValue = "10") Integer size,
|
||||
@RequestParam(value = "keyword", required = false) String keyword,
|
||||
@RequestParam(value = "status", required = false) Integer status,
|
||||
@RequestHeader("X-Internal-Token") String internalToken);
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ public class UserFeignClientFallbackFactory implements FallbackFactory<UserFeign
|
||||
log.error("用户服务调用失败:", cause);
|
||||
return new UserFeignClient() {
|
||||
@Override
|
||||
public Result<Page<Object>> getUserList(Integer page, Integer size, String keyword, String internalToken) {
|
||||
public Result<Page<Object>> getUserList(Integer page, Integer size, String keyword, Integer status, String internalToken) {
|
||||
log.error("获取用户列表失败");
|
||||
return Result.error("获取用户列表失败,用户服务不可用");
|
||||
}
|
||||
|
||||
+60
-1
@@ -1,5 +1,9 @@
|
||||
package com.nuaa.video.admin.security;
|
||||
|
||||
import com.nuaa.video.admin.entity.AdminPermission;
|
||||
import com.nuaa.video.admin.entity.AdminRole;
|
||||
import com.nuaa.video.admin.entity.AdminUser;
|
||||
import com.nuaa.video.admin.service.AdminUserService;
|
||||
import jakarta.servlet.FilterChain;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
@@ -14,7 +18,10 @@ import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@@ -25,7 +32,21 @@ import java.util.stream.Collectors;
|
||||
@RequiredArgsConstructor
|
||||
public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||
|
||||
private static final List<String> SUPER_ADMIN_AUTHORITIES = List.of(
|
||||
"user:manage",
|
||||
"role:manage",
|
||||
"permission:manage",
|
||||
"video:manage",
|
||||
"comment:manage",
|
||||
"tag:manage",
|
||||
"category:manage",
|
||||
"recommend:manage",
|
||||
"system:config",
|
||||
"operation:log"
|
||||
);
|
||||
|
||||
private final JwtTokenProvider jwtTokenProvider;
|
||||
private final AdminUserService adminUserService;
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
|
||||
@@ -39,7 +60,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||
// 从令牌中获取用户信息
|
||||
Long adminId = jwtTokenProvider.getAdminIdFromToken(token);
|
||||
String username = jwtTokenProvider.getUsernameFromToken(token);
|
||||
List<String> authorities = jwtTokenProvider.getAuthoritiesFromToken(token);
|
||||
List<String> authorities = resolveAuthorities(username, token);
|
||||
|
||||
// 转换为Spring Security的授权对象
|
||||
List<SimpleGrantedAuthority> simpleGrantedAuthorities = authorities.stream()
|
||||
@@ -72,6 +93,44 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||
filterChain.doFilter(request, response);
|
||||
}
|
||||
|
||||
private List<String> resolveAuthorities(String username, String token) {
|
||||
AdminUser adminUser = adminUserService.getByUsername(username);
|
||||
if (adminUser != null) {
|
||||
Set<String> authorities = new LinkedHashSet<>();
|
||||
if (adminUser.getRoles() != null) {
|
||||
for (AdminRole role : adminUser.getRoles()) {
|
||||
if (role == null || !StringUtils.hasText(role.getCode())) {
|
||||
continue;
|
||||
}
|
||||
authorities.add("ROLE_" + role.getCode());
|
||||
if ("ADMIN_SUPER".equals(role.getCode())) {
|
||||
authorities.addAll(SUPER_ADMIN_AUTHORITIES);
|
||||
}
|
||||
if (role.getPermissions() != null) {
|
||||
for (AdminPermission permission : role.getPermissions()) {
|
||||
if (permission != null && StringUtils.hasText(permission.getCode())) {
|
||||
authorities.add(permission.getCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!authorities.isEmpty()) {
|
||||
return new ArrayList<>(authorities);
|
||||
}
|
||||
}
|
||||
|
||||
List<String> tokenAuthorities = new ArrayList<>(jwtTokenProvider.getAuthoritiesFromToken(token));
|
||||
if (tokenAuthorities.contains("ROLE_ADMIN_SUPER")) {
|
||||
SUPER_ADMIN_AUTHORITIES.forEach(authority -> {
|
||||
if (!tokenAuthorities.contains(authority)) {
|
||||
tokenAuthorities.add(authority);
|
||||
}
|
||||
});
|
||||
}
|
||||
return tokenAuthorities;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从请求头中提取JWT令牌
|
||||
*/
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package com.nuaa.video.admin.service;
|
||||
|
||||
import com.nuaa.video.admin.vo.AdminPermissionVO;
|
||||
import com.nuaa.video.common.model.vo.Result;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 权限服务
|
||||
*/
|
||||
public interface AdminPermissionService {
|
||||
|
||||
Result<List<AdminPermissionVO>> listPermissions();
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.nuaa.video.admin.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.nuaa.video.admin.dto.AdminRoleDTO;
|
||||
import com.nuaa.video.admin.vo.AdminRoleVO;
|
||||
import com.nuaa.video.common.model.vo.Result;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 角色服务
|
||||
*/
|
||||
public interface AdminRoleService {
|
||||
|
||||
Result<Page<AdminRoleVO>> listRoles(Page<?> page, String keyword);
|
||||
|
||||
Result<List<AdminRoleVO>> listAllRoles();
|
||||
|
||||
Result<AdminRoleVO> getRoleDetail(Long id);
|
||||
|
||||
Result<Void> addRole(AdminRoleDTO roleDTO, String operator);
|
||||
|
||||
Result<Void> updateRole(AdminRoleDTO roleDTO, String operator);
|
||||
|
||||
Result<Void> updateRolePermissions(Long roleId, List<Long> permissionIds, String operator);
|
||||
|
||||
Result<Void> deleteRole(Long id);
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package com.nuaa.video.admin.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.nuaa.video.admin.entity.AdminPermission;
|
||||
import com.nuaa.video.admin.mapper.AdminPermissionMapper;
|
||||
import com.nuaa.video.admin.service.AdminPermissionService;
|
||||
import com.nuaa.video.admin.vo.AdminPermissionVO;
|
||||
import com.nuaa.video.common.model.vo.Result;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 权限服务实现
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class AdminPermissionServiceImpl implements AdminPermissionService {
|
||||
|
||||
private final AdminPermissionMapper adminPermissionMapper;
|
||||
|
||||
@Override
|
||||
public Result<List<AdminPermissionVO>> listPermissions() {
|
||||
List<AdminPermission> permissions = adminPermissionMapper.selectList(new LambdaQueryWrapper<AdminPermission>()
|
||||
.orderByAsc(AdminPermission::getId));
|
||||
return Result.success(permissions.stream().map(this::toPermissionVO).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
private AdminPermissionVO toPermissionVO(AdminPermission permission) {
|
||||
AdminPermissionVO permissionVO = new AdminPermissionVO();
|
||||
BeanUtils.copyProperties(permission, permissionVO);
|
||||
return permissionVO;
|
||||
}
|
||||
}
|
||||
+194
@@ -0,0 +1,194 @@
|
||||
package com.nuaa.video.admin.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.nuaa.video.admin.dto.AdminRoleDTO;
|
||||
import com.nuaa.video.admin.entity.AdminPermission;
|
||||
import com.nuaa.video.admin.entity.AdminRole;
|
||||
import com.nuaa.video.admin.entity.AdminRolePermission;
|
||||
import com.nuaa.video.admin.entity.AdminUserRole;
|
||||
import com.nuaa.video.admin.mapper.AdminRoleMapper;
|
||||
import com.nuaa.video.admin.mapper.AdminRolePermissionMapper;
|
||||
import com.nuaa.video.admin.mapper.AdminUserRoleMapper;
|
||||
import com.nuaa.video.admin.service.AdminRoleService;
|
||||
import com.nuaa.video.admin.vo.AdminPermissionVO;
|
||||
import com.nuaa.video.admin.vo.AdminRoleVO;
|
||||
import com.nuaa.video.common.model.vo.Result;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 角色服务实现
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class AdminRoleServiceImpl implements AdminRoleService {
|
||||
|
||||
private final AdminRoleMapper adminRoleMapper;
|
||||
private final AdminRolePermissionMapper adminRolePermissionMapper;
|
||||
private final AdminUserRoleMapper adminUserRoleMapper;
|
||||
|
||||
@Override
|
||||
public Result<Page<AdminRoleVO>> listRoles(Page<?> page, String keyword) {
|
||||
Page<AdminRole> rolePage = adminRoleMapper.selectRoleList(new Page<>(page.getCurrent(), page.getSize()), keyword);
|
||||
Page<AdminRoleVO> result = new Page<>();
|
||||
BeanUtils.copyProperties(rolePage, result, "records");
|
||||
result.setRecords(rolePage.getRecords().stream().map(this::toRoleVO).collect(Collectors.toList()));
|
||||
return Result.success(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<AdminRoleVO>> listAllRoles() {
|
||||
List<AdminRole> roles = adminRoleMapper.selectRoleList(new Page<>(1, 200), null).getRecords();
|
||||
return Result.success(roles.stream().map(this::toRoleVO).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<AdminRoleVO> getRoleDetail(Long id) {
|
||||
AdminRole role = adminRoleMapper.selectRoleDetail(id);
|
||||
if (role == null) {
|
||||
return Result.error("角色不存在");
|
||||
}
|
||||
return Result.success(toRoleVO(role));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Result<Void> addRole(AdminRoleDTO roleDTO, String operator) {
|
||||
if (existsRoleName(roleDTO.getName(), null)) {
|
||||
return Result.error("角色名称已存在");
|
||||
}
|
||||
if (existsRoleCode(roleDTO.getCode(), null)) {
|
||||
return Result.error("角色编码已存在");
|
||||
}
|
||||
|
||||
AdminRole role = new AdminRole();
|
||||
role.setName(roleDTO.getName());
|
||||
role.setCode(roleDTO.getCode());
|
||||
role.setDescription(roleDTO.getDescription());
|
||||
role.setCreatedBy(operator);
|
||||
role.setUpdatedBy(operator);
|
||||
role.setCreateTime(LocalDateTime.now());
|
||||
role.setUpdateTime(LocalDateTime.now());
|
||||
adminRoleMapper.insert(role);
|
||||
|
||||
saveRolePermissions(role.getId(), roleDTO.getPermissionIds(), operator);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Result<Void> updateRole(AdminRoleDTO roleDTO, String operator) {
|
||||
AdminRole existing = adminRoleMapper.selectById(roleDTO.getId());
|
||||
if (existing == null) {
|
||||
return Result.error("角色不存在");
|
||||
}
|
||||
if (existsRoleName(roleDTO.getName(), roleDTO.getId())) {
|
||||
return Result.error("角色名称已存在");
|
||||
}
|
||||
if (existsRoleCode(roleDTO.getCode(), roleDTO.getId())) {
|
||||
return Result.error("角色编码已存在");
|
||||
}
|
||||
|
||||
AdminRole role = new AdminRole();
|
||||
role.setId(roleDTO.getId());
|
||||
role.setName(roleDTO.getName());
|
||||
role.setCode(roleDTO.getCode());
|
||||
role.setDescription(roleDTO.getDescription());
|
||||
role.setUpdatedBy(operator);
|
||||
role.setUpdateTime(LocalDateTime.now());
|
||||
adminRoleMapper.updateById(role);
|
||||
|
||||
if (roleDTO.getPermissionIds() != null) {
|
||||
replaceRolePermissions(roleDTO.getId(), roleDTO.getPermissionIds(), operator);
|
||||
}
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Result<Void> updateRolePermissions(Long roleId, List<Long> permissionIds, String operator) {
|
||||
AdminRole existing = adminRoleMapper.selectById(roleId);
|
||||
if (existing == null) {
|
||||
return Result.error("角色不存在");
|
||||
}
|
||||
replaceRolePermissions(roleId, permissionIds, operator);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Result<Void> deleteRole(Long id) {
|
||||
AdminRole existing = adminRoleMapper.selectById(id);
|
||||
if (existing == null) {
|
||||
return Result.error("角色不存在");
|
||||
}
|
||||
|
||||
long bindCount = adminUserRoleMapper.selectCount(new LambdaQueryWrapper<AdminUserRole>()
|
||||
.eq(AdminUserRole::getRoleId, id));
|
||||
if (bindCount > 0) {
|
||||
return Result.error("该角色已分配给管理员,无法删除");
|
||||
}
|
||||
|
||||
adminRolePermissionMapper.delete(new LambdaQueryWrapper<AdminRolePermission>()
|
||||
.eq(AdminRolePermission::getRoleId, id));
|
||||
adminRoleMapper.deleteById(id);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
private boolean existsRoleName(String name, Long excludeId) {
|
||||
return adminRoleMapper.selectCount(new LambdaQueryWrapper<AdminRole>()
|
||||
.eq(AdminRole::getName, name)
|
||||
.ne(excludeId != null, AdminRole::getId, excludeId)) > 0;
|
||||
}
|
||||
|
||||
private boolean existsRoleCode(String code, Long excludeId) {
|
||||
return adminRoleMapper.selectCount(new LambdaQueryWrapper<AdminRole>()
|
||||
.eq(AdminRole::getCode, code)
|
||||
.ne(excludeId != null, AdminRole::getId, excludeId)) > 0;
|
||||
}
|
||||
|
||||
private void replaceRolePermissions(Long roleId, List<Long> permissionIds, String operator) {
|
||||
adminRolePermissionMapper.delete(new LambdaQueryWrapper<AdminRolePermission>()
|
||||
.eq(AdminRolePermission::getRoleId, roleId));
|
||||
saveRolePermissions(roleId, permissionIds, operator);
|
||||
}
|
||||
|
||||
private void saveRolePermissions(Long roleId, List<Long> permissionIds, String operator) {
|
||||
if (permissionIds == null || permissionIds.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<Long> validPermissionIds = permissionIds.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
if (!validPermissionIds.isEmpty()) {
|
||||
adminRolePermissionMapper.batchInsert(roleId, validPermissionIds, operator);
|
||||
}
|
||||
}
|
||||
|
||||
private AdminRoleVO toRoleVO(AdminRole role) {
|
||||
AdminRoleVO roleVO = new AdminRoleVO();
|
||||
BeanUtils.copyProperties(role, roleVO);
|
||||
List<AdminPermission> permissions = role.getPermissions() == null ? Collections.emptyList() :
|
||||
role.getPermissions().stream().filter(item -> item.getId() != null).collect(Collectors.toList());
|
||||
roleVO.setPermissions(permissions.stream().map(this::toPermissionVO).collect(Collectors.toList()));
|
||||
roleVO.setPermissionIds(permissions.stream().map(AdminPermission::getId).collect(Collectors.toList()));
|
||||
return roleVO;
|
||||
}
|
||||
|
||||
private AdminPermissionVO toPermissionVO(AdminPermission permission) {
|
||||
AdminPermissionVO permissionVO = new AdminPermissionVO();
|
||||
BeanUtils.copyProperties(permission, permissionVO);
|
||||
return permissionVO;
|
||||
}
|
||||
}
|
||||
+19
-2
@@ -53,14 +53,31 @@ public class AdminUserServiceImpl extends ServiceImpl<AdminUserMapper, AdminUser
|
||||
|
||||
@Override
|
||||
public Result<Page<AdminUserVO>> listUsers(Page<AdminUser> page, String keyword) {
|
||||
Page<AdminUser> userPage = adminUserMapper.selectUserList(page, keyword);
|
||||
LambdaQueryWrapper<AdminUser> queryWrapper = new LambdaQueryWrapper<>();
|
||||
if (StringUtils.hasText(keyword)) {
|
||||
queryWrapper.and(wrapper -> wrapper
|
||||
.like(AdminUser::getUsername, keyword)
|
||||
.or()
|
||||
.like(AdminUser::getRealName, keyword)
|
||||
.or()
|
||||
.like(AdminUser::getEmail, keyword)
|
||||
.or()
|
||||
.like(AdminUser::getPhone, keyword));
|
||||
}
|
||||
queryWrapper.orderByAsc(AdminUser::getId);
|
||||
|
||||
Page<AdminUser> userPage = page(page, queryWrapper);
|
||||
|
||||
// 转换为VO
|
||||
Page<AdminUserVO> voPage = new Page<>();
|
||||
BeanUtils.copyProperties(userPage, voPage, "records");
|
||||
|
||||
List<AdminUserVO> userVOList = new ArrayList<>();
|
||||
for (AdminUser user : userPage.getRecords()) {
|
||||
for (AdminUser baseUser : userPage.getRecords()) {
|
||||
AdminUser user = adminUserMapper.selectUserDetail(baseUser.getId());
|
||||
if (user == null) {
|
||||
user = baseUser;
|
||||
}
|
||||
AdminUserVO vo = new AdminUserVO();
|
||||
BeanUtils.copyProperties(user, vo);
|
||||
|
||||
|
||||
+3
-1
@@ -7,6 +7,7 @@ import com.nuaa.video.admin.dto.LoginDTO;
|
||||
import com.nuaa.video.admin.entity.AdminPermission;
|
||||
import com.nuaa.video.admin.entity.AdminRole;
|
||||
import com.nuaa.video.admin.entity.AdminUser;
|
||||
import com.nuaa.video.admin.mapper.AdminUserMapper;
|
||||
import com.nuaa.video.admin.security.AdminUserDetails;
|
||||
import com.nuaa.video.admin.security.JwtTokenProvider;
|
||||
import com.nuaa.video.admin.service.AdminUserService;
|
||||
@@ -44,6 +45,7 @@ public class AuthServiceImpl implements AuthService {
|
||||
private final AuthenticationManager authenticationManager;
|
||||
private final JwtTokenProvider jwtTokenProvider;
|
||||
private final AdminUserService adminUserService;
|
||||
private final AdminUserMapper adminUserMapper;
|
||||
private final RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
@Value("${login.retry-count:5}")
|
||||
@@ -169,7 +171,7 @@ public class AuthServiceImpl implements AuthService {
|
||||
@Override
|
||||
public Result<LoginVO> getCurrentUser(AdminUserDetails adminUserDetails) {
|
||||
// 获取用户信息
|
||||
AdminUser adminUser = adminUserService.getById(adminUserDetails.getId());
|
||||
AdminUser adminUser = adminUserMapper.selectUserDetail(adminUserDetails.getId());
|
||||
if (adminUser == null) {
|
||||
return Result.error("用户不存在");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user