package com.tourguide.modules.system.service;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.tourguide.common.api.PageResponse;
|
import com.tourguide.common.exception.BusinessException;
|
import com.tourguide.modules.system.dto.PermissionActionResponse;
|
import com.tourguide.modules.system.dto.PermissionModuleResponse;
|
import com.tourguide.modules.system.dto.PermissionPageResponse;
|
import com.tourguide.modules.system.dto.RoleDetailResponse;
|
import com.tourguide.modules.system.dto.RoleResponse;
|
import com.tourguide.modules.system.dto.RoleSaveRequest;
|
import com.tourguide.modules.system.entity.SystemMenu;
|
import com.tourguide.modules.system.entity.SystemRole;
|
import com.tourguide.modules.system.entity.SystemRoleMenu;
|
import com.tourguide.modules.system.mapper.SystemMenuMapper;
|
import com.tourguide.modules.system.mapper.SystemRoleMapper;
|
import com.tourguide.modules.system.mapper.SystemRoleMenuMapper;
|
import com.tourguide.modules.user.entity.AdminUser;
|
import com.tourguide.modules.user.mapper.AdminUserMapper;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.util.StringUtils;
|
import java.util.ArrayList;
|
import java.util.Collections;
|
import java.util.HashMap;
|
import java.util.HashSet;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.Set;
|
import java.util.UUID;
|
import java.util.stream.Collectors;
|
|
@Service
|
public class SystemRoleService {
|
private final SystemRoleMapper roleMapper;
|
private final SystemMenuMapper menuMapper;
|
private final SystemRoleMenuMapper roleMenuMapper;
|
private final AdminUserMapper adminUserMapper;
|
|
public SystemRoleService(SystemRoleMapper roleMapper, SystemMenuMapper menuMapper,
|
SystemRoleMenuMapper roleMenuMapper, AdminUserMapper adminUserMapper) {
|
this.roleMapper = roleMapper;
|
this.menuMapper = menuMapper;
|
this.roleMenuMapper = roleMenuMapper;
|
this.adminUserMapper = adminUserMapper;
|
}
|
|
public PageResponse<RoleResponse> page(long page, long size, String keyword) {
|
LambdaQueryWrapper<SystemRole> query = new LambdaQueryWrapper<SystemRole>()
|
.like(StringUtils.hasText(keyword), SystemRole::getRoleName,
|
StringUtils.hasText(keyword) ? keyword.trim() : null)
|
.orderByAsc(SystemRole::getId);
|
Page<SystemRole> result = roleMapper.selectPage(new Page<SystemRole>(page, size), query);
|
List<RoleResponse> records = result.getRecords().stream()
|
.map(role -> new RoleResponse(role, countAccounts(role.getRoleCode())))
|
.collect(Collectors.toList());
|
return new PageResponse<RoleResponse>(records, result.getTotal(), result.getCurrent(), result.getSize());
|
}
|
|
public RoleDetailResponse detail(Long id) {
|
SystemRole role = findRole(id);
|
List<Long> relationMenuIds = roleMenuMapper.selectList(new LambdaQueryWrapper<SystemRoleMenu>()
|
.eq(SystemRoleMenu::getRoleId, id))
|
.stream().map(SystemRoleMenu::getMenuId).collect(Collectors.toList());
|
List<Long> menuIds = relationMenuIds.isEmpty() ? Collections.<Long>emptyList()
|
: menuMapper.selectList(new LambdaQueryWrapper<SystemMenu>()
|
.in(SystemMenu::getId, relationMenuIds).eq(SystemMenu::getStatus, 1))
|
.stream().map(SystemMenu::getId).collect(Collectors.toList());
|
return new RoleDetailResponse(role, menuIds);
|
}
|
|
public List<PermissionModuleResponse> permissions() {
|
List<SystemMenu> menus = menuMapper.selectList(new LambdaQueryWrapper<SystemMenu>()
|
.eq(SystemMenu::getStatus, 1).orderByAsc(SystemMenu::getSort, SystemMenu::getId));
|
Map<Long, List<SystemMenu>> children = new HashMap<Long, List<SystemMenu>>();
|
for (SystemMenu menu : menus) {
|
children.computeIfAbsent(menu.getParentId(), key -> new ArrayList<SystemMenu>()).add(menu);
|
}
|
List<PermissionModuleResponse> modules = new ArrayList<PermissionModuleResponse>();
|
for (SystemMenu module : children.getOrDefault(0L, Collections.<SystemMenu>emptyList())) {
|
if (!"DIRECTORY".equals(module.getMenuType())) continue;
|
List<PermissionPageResponse> pages = new ArrayList<PermissionPageResponse>();
|
for (SystemMenu page : children.getOrDefault(module.getId(), Collections.<SystemMenu>emptyList())) {
|
if (!"MENU".equals(page.getMenuType())) continue;
|
List<PermissionActionResponse> actions = children
|
.getOrDefault(page.getId(), Collections.<SystemMenu>emptyList()).stream()
|
.filter(menu -> "BUTTON".equals(menu.getMenuType()))
|
.map(PermissionActionResponse::new).collect(Collectors.toList());
|
pages.add(new PermissionPageResponse(page, actions));
|
}
|
if (!pages.isEmpty()) modules.add(new PermissionModuleResponse(module, pages));
|
}
|
return modules;
|
}
|
|
@Transactional
|
public RoleDetailResponse create(RoleSaveRequest request) {
|
validateRoleName(request.getRoleName(), null);
|
validateMenuIds(request.getMenuIds());
|
SystemRole role = new SystemRole();
|
role.setRoleCode("CUSTOM_" + UUID.randomUUID().toString().replace("-", "").substring(0, 12).toUpperCase());
|
role.setRoleName(request.getRoleName().trim());
|
role.setRemark(normalizeRemark(request.getRemark()));
|
role.setStatus(1);
|
roleMapper.insert(role);
|
replaceRoleMenus(role.getId(), request.getMenuIds());
|
return detail(role.getId());
|
}
|
|
@Transactional
|
public RoleDetailResponse update(Long id, RoleSaveRequest request) {
|
SystemRole role = findRole(id);
|
validateRoleName(request.getRoleName(), id);
|
validateMenuIds(request.getMenuIds());
|
role.setRoleName(request.getRoleName().trim());
|
role.setRemark(normalizeRemark(request.getRemark()));
|
roleMapper.updateById(role);
|
replaceRoleMenus(id, request.getMenuIds());
|
return detail(id);
|
}
|
|
@Transactional
|
public void delete(Long id) {
|
SystemRole role = findRole(id);
|
if ("ADMIN".equals(role.getRoleCode())) {
|
throw new BusinessException(409, "超级管理员角色不能删除");
|
}
|
if (countAccounts(role.getRoleCode()) > 0) {
|
throw new BusinessException(409, "该角色已关联后台账号,不能删除");
|
}
|
roleMenuMapper.markDeletedByRoleId(id);
|
roleMapper.deleteById(id);
|
}
|
|
private SystemRole findRole(Long id) {
|
SystemRole role = roleMapper.selectById(id);
|
if (role == null) throw new BusinessException(404, "角色不存在");
|
return role;
|
}
|
|
private long countAccounts(String roleCode) {
|
return adminUserMapper.selectCount(new LambdaQueryWrapper<AdminUser>().eq(AdminUser::getRoleCode, roleCode));
|
}
|
|
private void validateRoleName(String roleName, Long excludedId) {
|
LambdaQueryWrapper<SystemRole> query = new LambdaQueryWrapper<SystemRole>()
|
.eq(SystemRole::getRoleName, roleName.trim()).ne(excludedId != null, SystemRole::getId, excludedId);
|
if (roleMapper.selectCount(query) > 0) throw new BusinessException(409, "角色名称已存在");
|
}
|
|
private void validateMenuIds(List<Long> menuIds) {
|
Set<Long> uniqueIds = new HashSet<Long>(menuIds);
|
if (uniqueIds.isEmpty()) return;
|
long validCount = menuMapper.selectCount(new LambdaQueryWrapper<SystemMenu>()
|
.in(SystemMenu::getId, uniqueIds).eq(SystemMenu::getStatus, 1));
|
if (validCount != uniqueIds.size()) throw new BusinessException(400, "包含无效权限");
|
}
|
|
private void replaceRoleMenus(Long roleId, List<Long> menuIds) {
|
roleMenuMapper.markDeletedByRoleId(roleId);
|
for (Long menuId : new HashSet<Long>(menuIds)) {
|
SystemRoleMenu relation = new SystemRoleMenu();
|
relation.setRoleId(roleId);
|
relation.setMenuId(menuId);
|
roleMenuMapper.upsert(relation);
|
}
|
}
|
|
private String normalizeRemark(String remark) {
|
return StringUtils.hasText(remark) ? remark.trim() : null;
|
}
|
}
|