fix: 统一账号角色校验与默认首页

- 创建与导入账号时强制校验启用角色

- 按启用角色返回默认首页并过滤禁用角色
This commit is contained in:
2026-08-03 14:48:39 +08:00
parent 219e4f7eff
commit 866688b92f
9 changed files with 697 additions and 42 deletions

View File

@@ -8,6 +8,7 @@ import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -16,6 +17,7 @@ import org.springframework.web.multipart.MultipartFile;
import tech.easyflow.auth.entity.EncryptedCredentialDTO;
import tech.easyflow.auth.service.AuthCredentialKeyService;
import tech.easyflow.auth.service.AuthService;
import tech.easyflow.common.constant.Constants;
import tech.easyflow.common.constant.enums.EnumAccountType;
import tech.easyflow.common.constant.enums.EnumDataStatus;
import tech.easyflow.common.domain.Result;
@@ -25,10 +27,13 @@ import tech.easyflow.common.util.StringUtil;
import tech.easyflow.common.web.controller.BaseCurdController;
import tech.easyflow.common.web.jsonbody.JsonBody;
import tech.easyflow.log.annotation.LogRecord;
import tech.easyflow.admin.controller.system.vo.SysAccountProfileVo;
import tech.easyflow.system.entity.SysAccount;
import tech.easyflow.system.entity.SysRole;
import tech.easyflow.system.entity.vo.SysAccountBatchActionResultVo;
import tech.easyflow.system.entity.vo.SysAccountImportResultVo;
import tech.easyflow.system.service.SysAccountService;
import tech.easyflow.system.service.SysRoleService;
import tech.easyflow.system.util.SysPasswordPolicy;
import javax.annotation.Resource;
@@ -36,9 +41,13 @@ import java.io.Serializable;
import java.math.BigInteger;
import java.net.URLEncoder;
import java.util.Collection;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 用户表 控制层。
@@ -49,13 +58,27 @@ import java.util.Map;
@RestController("sysAccountController")
@RequestMapping("/api/v1/sysAccount")
public class SysAccountController extends BaseCurdController<SysAccountService, SysAccount> {
private static final String SUPER_ADMIN_HOME_PATH = "/dashboard/workspace";
private static final String USER_HOME_PATH = "/ai/agent-chat";
private final AuthCredentialKeyService credentialKeyService;
private final SysRoleService sysRoleService;
@Resource
private AuthService authService;
public SysAccountController(SysAccountService service, AuthCredentialKeyService credentialKeyService) {
/**
* 创建用户管理控制器。
*
* @param service 用户服务
* @param credentialKeyService 凭证密钥服务
* @param sysRoleService 角色服务
*/
public SysAccountController(SysAccountService service,
AuthCredentialKeyService credentialKeyService,
SysRoleService sysRoleService) {
super(service);
this.credentialKeyService = credentialKeyService;
this.sysRoleService = sysRoleService;
}
@Override
@@ -76,6 +99,10 @@ public class SysAccountController extends BaseCurdController<SysAccountService,
if (count > 0) {
return Result.fail(1, "用户名已存在");
}
Result<?> roleValidation = validateCreateRoles(entity);
if (roleValidation != null) {
return roleValidation;
}
String password = decryptInitialPassword(entity.getPasswordCredential());
if (!StringUtil.hasText(password)) {
return Result.fail(1, "密码不能为空");
@@ -144,11 +171,24 @@ public class SysAccountController extends BaseCurdController<SysAccountService,
return super.onRemoveBefore(ids);
}
/**
* 获取当前账号资料、角色标识与默认首页。
*
* @return 当前账号资料视图
*/
@GetMapping("/myProfile")
public Result<SysAccount> myProfile() {
public Result<SysAccountProfileVo> myProfile() {
LoginAccount account = SaTokenUtil.getLoginAccount();
SysAccount sysAccount = service.getById(account.getId());
return Result.ok(sysAccount);
List<String> roles = sysRoleService.getRolesByAccountId(account.getId()).stream()
.map(SysRole::getRoleKey)
.filter(StringUtil::hasText)
.distinct()
.collect(Collectors.toList());
String homePath = roles.contains(Constants.SUPER_ADMIN_ROLE_CODE)
? SUPER_ADMIN_HOME_PATH
: USER_HOME_PATH;
return Result.ok(SysAccountProfileVo.from(sysAccount, roles, homePath));
}
@PostMapping("/updateProfile")
@@ -262,8 +302,12 @@ public class SysAccountController extends BaseCurdController<SysAccountService,
service.writeImportTemplate(response.getOutputStream());
}
/**
* {@inheritDoc}
*/
@Override
@PostMapping("save")
@Transactional(rollbackFor = Exception.class)
public Result<?> save(@JsonBody SysAccount entity) {
try {
return super.save(entity);
@@ -271,4 +315,33 @@ public class SysAccountController extends BaseCurdController<SysAccountService,
return Result.fail(1, "用户名已存在");
}
}
/**
* 校验创建账号时提交的角色,并归一化角色 ID。
*
* @param entity 待创建账号
* @return 校验失败结果,校验通过返回 null
*/
private Result<?> validateCreateRoles(SysAccount entity) {
List<BigInteger> roleIds = entity == null ? null : entity.getRoleIds();
Set<BigInteger> uniqueRoleIds = new LinkedHashSet<>();
if (roleIds != null) {
roleIds.stream()
.filter(java.util.Objects::nonNull)
.forEach(uniqueRoleIds::add);
}
if (uniqueRoleIds.isEmpty()) {
return Result.fail(1, "角色不能为空");
}
List<SysRole> roles = sysRoleService.listByIds(uniqueRoleIds);
boolean valid = roles.size() == uniqueRoleIds.size()
&& roles.stream().allMatch(role ->
EnumDataStatus.AVAILABLE.getCode().equals(role.getStatus()));
if (!valid) {
return Result.fail(1, "角色不存在或已禁用");
}
entity.setRoleIds(new ArrayList<>(uniqueRoleIds));
return null;
}
}

View File

@@ -0,0 +1,76 @@
package tech.easyflow.admin.controller.system.vo;
import cn.hutool.core.bean.BeanUtil;
import tech.easyflow.system.entity.SysAccount;
import java.util.ArrayList;
import java.util.List;
/**
* 管理端当前账号资料视图。
*/
public class SysAccountProfileVo extends SysAccount {
private String homePath;
private List<String> roles = new ArrayList<>();
/**
* 创建空的当前账号资料视图。
*/
public SysAccountProfileVo() {
}
/**
* 根据账号实体和角色信息创建资料视图。
*
* @param account 账号实体
* @param roles 角色标识列表
* @param homePath 默认首页
* @return 当前账号资料视图
*/
public static SysAccountProfileVo from(SysAccount account, List<String> roles, String homePath) {
SysAccountProfileVo profile = new SysAccountProfileVo();
if (account != null) {
BeanUtil.copyProperties(account, profile);
}
profile.setRoles(roles);
profile.setHomePath(homePath);
return profile;
}
/**
* 获取默认首页。
*
* @return 默认首页
*/
public String getHomePath() {
return homePath;
}
/**
* 设置默认首页。
*
* @param homePath 默认首页
*/
public void setHomePath(String homePath) {
this.homePath = homePath;
}
/**
* 获取角色标识列表。
*
* @return 角色标识列表
*/
public List<String> getRoles() {
return roles;
}
/**
* 设置角色标识列表。
*
* @param roles 角色标识列表
*/
public void setRoles(List<String> roles) {
this.roles = roles == null ? new ArrayList<>() : new ArrayList<>(roles);
}
}