Browse Source

refactor(tenant): 重构按钮权限配置服务以支持多角色合并

- 移除 getButtonConfigVo 方法中的 roleId 参数,改为合并当前用户所有角色的权限
- 添加分页功能到 listAllFormButtons 方法,支持按角色ID过滤已配置的表单
- 新增 getCurrentUserRoleIds 辅助方法从 TokenData 解析用户角色ID集合
- 实现按钮权限的并集计算逻辑,遍历用户所有角色并合并勾选状态
- 更新数据访问层以支持新的查询参数和分页返回类型
- 在删除角色时同步清理相关按钮权限配置数据
feature/form-permission-control
chenchuchuan 2 weeks ago
parent
commit
b6e8b1914e
  1. 23
      application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/controller/RoleFormButtonController.java
  2. 14
      application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/service/IRoleFormButtonService.java
  3. 112
      application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/service/impl/RoleFormButtonServiceImpl.java
  4. 3
      application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/upms/service/impl/SysRoleServiceImpl.java
  5. 2
      common/common-online/src/main/java/apelet/common/online/controller/OnlineFormController.java
  6. 6
      common/common-online/src/main/java/apelet/common/online/dao/mapper/OnlineFormMapper.xml
  7. 6
      common/common-online/src/main/java/apelet/common/online/model/OnlineForm.java

23
application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/controller/RoleFormButtonController.java

@ -31,21 +31,19 @@ public class RoleFormButtonController { @@ -31,21 +31,19 @@ public class RoleFormButtonController {
private IRoleFormButtonService service;
/**
* 查询指定角色+表单的按钮权限配置
* 返回表单中所有开启的按钮 + 每个按钮是否已勾选
* 查询当前登录用户对指定表单的按钮权限合并所有角色
* 根据当前登录用户的所有角色查询各角色在该表单的按钮配置取并集返回
*
* @param roleId 角色ID必填
* @param formId 在线表单ID必填
* @return 包含 formId, roleId, id, buttonList[{name, checked}]
* @return 包含 formId, buttonList[{name, checked}]
*/
@GetMapping("/getButtonConfig")
public ResponseResult<Map<String, Object>> getButtonConfig(
@RequestParam Long roleId,
@RequestParam Long formId) {
if (MyCommonUtil.existBlankArgument(roleId, formId)) {
if (MyCommonUtil.existBlankArgument(formId)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
Map<String, Object> result = service.getButtonConfigVo(roleId, formId);
Map<String, Object> result = service.getButtonConfigVo(formId);
return ResponseResult.success(result);
}
@ -89,20 +87,19 @@ public class RoleFormButtonController { @@ -89,20 +87,19 @@ public class RoleFormButtonController {
/**
* 分页查询所有在线表单下的所有按钮
* 遍历全部在线表单从每个表单的 widgetJson 中提取已开启的按钮
* 如果传了 roleId则只返回该角色已配置的表单并合并已保存的勾选状态
*
* @param roleId 角色ID可选用于过滤已配置的表单
* @param orderParam 排序参数
* @param pageParam 分页参数
* @return 分页结果每个元素包含 formId, formName, buttonList[{name, checked}]
*/
@PostMapping("/listAllFormButtons")
public ResponseResult<MyPageData<?>> listAllFormButtons(
public ResponseResult<MyPageData<Map<String, Object>>> listAllFormButtons(
@MyRequestBody Long roleId,
@MyRequestBody MyOrderParam orderParam,
@MyRequestBody MyPageParam pageParam) {
if (pageParam != null) {
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
}
List<Map<String, Object>> result = service.listAllFormButtons(orderParam);
return ResponseResult.success(MyPageUtil.makeResponseData(result));
return ResponseResult.success(service.listAllFormButtons(roleId, orderParam, pageParam));
}
/**

14
application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/service/IRoleFormButtonService.java

@ -3,6 +3,8 @@ package apelet.tenantadmin.tenant.service; @@ -3,6 +3,8 @@ package apelet.tenantadmin.tenant.service;
import apelet.common.core.base.service.IBaseService;
import apelet.common.core.object.CallResult;
import apelet.common.core.object.MyOrderParam;
import apelet.common.core.object.MyPageData;
import apelet.common.core.object.MyPageParam;
import apelet.tenantadmin.tenant.dto.RoleFormButtonDto;
import apelet.tenantadmin.tenant.model.RoleFormButton;
@ -26,13 +28,12 @@ public interface IRoleFormButtonService @@ -26,13 +28,12 @@ public interface IRoleFormButtonService
// ========== 核心业务接口 ==========
/**
* 查询按钮权限配置的VO含表单所有按钮 + 勾选状态的合并结果
* 查询当前登录用户对指定表单的按钮权限合并所有角色的并集
*
* @param roleId 角色ID
* @param formId 在线表单ID
* @return 包含 formId, roleId, id(配置记录ID), buttonList(含name+checked的列表)
* @return 包含 formId, buttonList(含name+checked的列表)
*/
Map<String, Object> getButtonConfigVo(Long roleId, Long formId);
Map<String, Object> getButtonConfigVo(Long formId);
/**
* 批量保存按钮权限配置同一事务内全部成功或全部回滚
@ -71,9 +72,12 @@ public interface IRoleFormButtonService @@ -71,9 +72,12 @@ public interface IRoleFormButtonService
/**
* 分页查询所有在线表单下的所有按钮
* 遍历全部在线表单从每个表单的 widgetJson 中提取已开启的按钮
* 如果传了 roleId则只返回该角色已配置的表单并合并已保存的勾选状态
*
* @param roleId 角色ID可选用于过滤已配置的表单
* @param orderParam 排序参数
* @param pageParam 分页参数
* @return 分页结果每个元素包含 formId, formName, buttonList[{name, checked}]
*/
List<Map<String, Object>> listAllFormButtons(MyOrderParam orderParam);
MyPageData<Map<String, Object>> listAllFormButtons(Long roleId, MyOrderParam orderParam, MyPageParam pageParam);
}

112
application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/service/impl/RoleFormButtonServiceImpl.java

@ -2,8 +2,7 @@ package apelet.tenantadmin.tenant.service.impl; @@ -2,8 +2,7 @@ package apelet.tenantadmin.tenant.service.impl;
import apelet.common.core.base.dao.BaseDaoMapper;
import apelet.common.core.base.service.BaseService;
import apelet.common.core.object.CallResult;
import apelet.common.core.object.MyOrderParam;
import apelet.common.core.object.*;
import apelet.common.online.model.OnlineForm;
import apelet.common.online.model.OnlinePage;
import apelet.common.online.service.OnlineFormService;
@ -15,8 +14,11 @@ import apelet.tenantadmin.tenant.model.RoleFormButton; @@ -15,8 +14,11 @@ import apelet.tenantadmin.tenant.model.RoleFormButton;
import apelet.tenantadmin.tenant.service.IRoleFormButtonService;
import apelet.tenantadmin.tenant.util.WidgetJsonButtonParser;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.page.PageMethod;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
@ -60,11 +62,10 @@ public class RoleFormButtonServiceImpl extends BaseService<RoleFormButton, Long> @@ -60,11 +62,10 @@ public class RoleFormButtonServiceImpl extends BaseService<RoleFormButton, Long>
return mapper.getListByFilter(filter, orderBy);
}
// ========== 核心:查询按钮配置VO ==========
// ========== 核心:查询按钮配置VO(合并当前用户所有角色) ==========
@Override
public Map<String, Object> getButtonConfigVo(Long roleId, Long formId) {
public Map<String, Object> getButtonConfigVo(Long formId) {
Map<String, Object> result = new HashMap<>();
result.put("roleId", roleId);
result.put("formId", formId);
// 1. 获取 widgetJson,提取所有开启的按钮
@ -73,15 +74,16 @@ public class RoleFormButtonServiceImpl extends BaseService<RoleFormButton, Long> @@ -73,15 +74,16 @@ public class RoleFormButtonServiceImpl extends BaseService<RoleFormButton, Long>
result.put("buttonList", Collections.emptyList());
return result;
}
List<WidgetJsonButtonParser.ButtonInfo> enabledButtons = WidgetJsonButtonParser.extractEnabledButtons(onlineForm.getWidgetJson());
List<WidgetJsonButtonParser.ButtonInfo> enabledButtons =
WidgetJsonButtonParser.extractEnabledButtons(onlineForm.getWidgetJson());
// 2. 获取当前登录用户的所有角色
Set<Long> roleIds = getCurrentUserRoleIds();
// 2. 查询已存储的配置
RoleFormButton config = getByRoleIdAndFormId(roleId, formId);
// 3. 解析已勾选的按钮名称集合
// 3. 遍历所有角色,合并各角色在该表单的勾选按钮(取并集)
Set<String> checkedNames = new HashSet<>();
if (CollectionUtil.isNotEmpty(roleIds)) {
for (Long roleId : roleIds) {
RoleFormButton config = getByRoleIdAndFormId(roleId, formId);
if (config != null && config.getButtonConfig() != null) {
List<WidgetJsonButtonParser.ButtonInfo> savedButtons =
JSON.parseArray(config.getButtonConfig(),
@ -92,6 +94,8 @@ public class RoleFormButtonServiceImpl extends BaseService<RoleFormButton, Long> @@ -92,6 +94,8 @@ public class RoleFormButtonServiceImpl extends BaseService<RoleFormButton, Long>
}
}
}
}
}
// 4. 合并:表单所有开启的按钮 + 是否勾选
List<Map<String, Object>> buttonList = new ArrayList<>();
@ -102,11 +106,21 @@ public class RoleFormButtonServiceImpl extends BaseService<RoleFormButton, Long> @@ -102,11 +106,21 @@ public class RoleFormButtonServiceImpl extends BaseService<RoleFormButton, Long>
buttonList.add(item);
}
result.put("id", config != null ? config.getId() : null);
result.put("buttonList", buttonList);
return result;
}
/**
* 获取当前登录用户的所有角色ID集合 TokenData 中解析
*/
private Set<Long> getCurrentUserRoleIds() {
TokenData tokenData = TokenData.takeFromRequest();
if (tokenData == null || StrUtil.isBlank(tokenData.getRoleIds())) {
return Collections.emptySet();
}
return StrUtil.split(tokenData.getRoleIds(), ',').stream().map(Long::valueOf).collect(Collectors.toSet());
}
// ========== 核心:批量保存按钮配置(事务) ==========
@Override
@Transactional(rollbackFor = Exception.class)
@ -190,7 +204,7 @@ public class RoleFormButtonServiceImpl extends BaseService<RoleFormButton, Long> @@ -190,7 +204,7 @@ public class RoleFormButtonServiceImpl extends BaseService<RoleFormButton, Long>
private static @NotNull Map<String, Object> getButtonResult(OnlineForm form, List<WidgetJsonButtonParser.ButtonInfo> buttons) {
Map<String, Object> item = new HashMap<>();
item.put("formId", form.getFormId());
item.put("formId", form.getFormId().toString());
item.put("formName", form.getFormName());
List<Map<String, Object>> buttonList = new ArrayList<>();
if (!CollectionUtils.isEmpty(buttons)) {
@ -206,24 +220,82 @@ public class RoleFormButtonServiceImpl extends BaseService<RoleFormButton, Long> @@ -206,24 +220,82 @@ public class RoleFormButtonServiceImpl extends BaseService<RoleFormButton, Long>
}
@Override
public List<Map<String, Object>> listAllFormButtons(MyOrderParam orderParam) {
// 查询已发布的 page
public MyPageData<Map<String, Object>> listAllFormButtons(Long roleId, MyOrderParam orderParam, MyPageParam pageParam) {
// 1. 查询已发布的 page(不分页,获取全量)
List<OnlinePage> pageList = onlinePageService.queryByEnableList();
if (CollectionUtil.isEmpty(pageList)) {
return Collections.emptyList();
return new MyPageData<>(Collections.emptyList(), 0L);
}
Set<Long> pageIdSet = pageList.stream().map(OnlinePage::getPageId).collect(Collectors.toSet());
// 分页查询在线表单
// 2. 分页查询 OnlineForm
if (pageParam != null) {
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
}
String orderBy = MyOrderParam.buildOrderBy(orderParam, OnlineForm.class);
OnlineForm onlineForm = new OnlineForm();
onlineForm.setPageIdSet(pageIdSet);
List<OnlineForm> formList = onlineFormService.getOnlineFormList(null, orderBy);
List<OnlineForm> formList = onlineFormService.getOnlineFormList(onlineForm, orderBy);
long total = formList instanceof Page ? ((Page) formList).getTotal() : formList.size();
// 3. 如果传了 roleId,查询 RoleFormButton 获取勾选状态
Map<Long, Set<String>> formCheckedMap = Collections.emptyMap();
if (roleId != null) {
List<RoleFormButton> configList = this.listByRoleId(roleId);
if (CollectionUtil.isNotEmpty(configList)) {
formCheckedMap = new HashMap<>(configList.size());
for (RoleFormButton config : configList) {
formCheckedMap.put(config.getFormId(), extractCheckedNames(config));
}
}
}
// 4. 构建结果
List<Map<String, Object>> result = new ArrayList<>();
for (OnlineForm form : formList) {
List<WidgetJsonButtonParser.ButtonInfo> buttons =
WidgetJsonButtonParser.extractEnabledButtons(form.getWidgetJson());
result.add(getButtonResult(form, buttons));
Map<String, Object> item = getButtonResult(form, buttons);
if (roleId != null) {
Set<String> checkedNames = formCheckedMap.get(form.getFormId());
if (CollectionUtil.isNotEmpty(checkedNames)) {
applyCheckedStatus(item, checkedNames);
}
}
result.add(item);
}
return new MyPageData<>(result, total);
}
/**
* RoleFormButton.buttonConfig 中提取已勾选的按钮名称集合
*/
private Set<String> extractCheckedNames(RoleFormButton config) {
if (config.getButtonConfig() == null) {
return Collections.emptySet();
}
List<WidgetJsonButtonParser.ButtonInfo> savedButtons =
JSON.parseArray(config.getButtonConfig(), WidgetJsonButtonParser.ButtonInfo.class);
if (CollectionUtils.isEmpty(savedButtons)) {
return Collections.emptySet();
}
return savedButtons.stream()
.filter(b -> Boolean.TRUE.equals(b.getEnabled()))
.map(WidgetJsonButtonParser.ButtonInfo::getName)
.collect(Collectors.toSet());
}
/**
* 将已勾选的按钮名称集合应用到返回结果中
*/
private void applyCheckedStatus(Map<String, Object> item, Set<String> checkedNames) {
@SuppressWarnings("unchecked")
List<Map<String, Object>> buttonList =
(List<Map<String, Object>>) item.get("buttonList");
if (buttonList != null) {
for (Map<String, Object> btn : buttonList) {
btn.put("checked", checkedNames.contains(btn.get("name")));
}
}
return result;
}
}

3
application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/upms/service/impl/SysRoleServiceImpl.java

@ -69,6 +69,8 @@ public class SysRoleServiceImpl extends BaseService<SysRole, Long> implements Sy @@ -69,6 +69,8 @@ public class SysRoleServiceImpl extends BaseService<SysRole, Long> implements Sy
private IdGeneratorWrapper idGenerator;
@Autowired
private BizWidgetDatasourceExtHelper bizWidgetDatasourceExtHelper;
@Autowired
private apelet.tenantadmin.tenant.service.IRoleFormButtonService roleFormButtonService;
@PostConstruct
private void registerBizWidgetDatasource() {
@ -200,6 +202,7 @@ public class SysRoleServiceImpl extends BaseService<SysRole, Long> implements Sy @@ -200,6 +202,7 @@ public class SysRoleServiceImpl extends BaseService<SysRole, Long> implements Sy
SysRoleDept roleDept = new SysRoleDept();
roleDept.setRoleId(roleId);
sysRoleDeptMapper.delete(new QueryWrapper<>(roleDept));
roleFormButtonService.removeByRoleId(roleId);
return true;
}

2
common/common-online/src/main/java/apelet/common/online/controller/OnlineFormController.java

@ -598,7 +598,7 @@ public class OnlineFormController { @@ -598,7 +598,7 @@ public class OnlineFormController {
public ResponseResult<List<Object>> eventPluginExecute(
@MyRequestBody OnlineEventPluginExecuteDto onlineEventPluginExecuteDto) {
// //todo 暂时不开启 按钮权限校验
// // 按钮权限校验
// if (buttonPermissionChecker != null) {
// Long formId = onlineEventPluginExecuteDto.getFormId();
// String buttonName = onlineEventPluginExecuteDto.getEventWidgetVariableName();

6
common/common-online/src/main/java/apelet/common/online/dao/mapper/OnlineFormMapper.xml

@ -62,6 +62,12 @@ @@ -62,6 +62,12 @@
#{item}
</foreach>
</if>
<if test="onlineFormFilter.formIdSet != null">
AND zz_online_form.form_id IN
<foreach collection="onlineFormFilter.formIdSet" item="item" separator="," open="(" close=")">
#{item}
</foreach>
</if>
</if>
</sql>

6
common/common-online/src/main/java/apelet/common/online/model/OnlineForm.java

@ -146,6 +146,12 @@ public class OnlineForm { @@ -146,6 +146,12 @@ public class OnlineForm {
@TableField(exist = false)
private Set<Long> pageIdSet;
/**
* 表单id集合
*/
@TableField(exist = false)
private Set<Long> formIdSet;
@Mapper
public interface OnlineFormModelMapper extends BaseModelMapper<OnlineFormVo, OnlineForm> {
/**

Loading…
Cancel
Save