Browse Source

feat(online): 完善数据权限规则与角色绑定功能

- 新增IRolePermissionSchemaService接口及其实现类,管理角色与数据规则方案关联关系
- 添加RolePermissionSchema实体模型,定义角色-数据规则方案关联表结构
- 修改PermissionDataRuleSchema模型,将formId字段更名为formHeadId,新增formIdList字段
- 实现根据当前用户角色查询启用数据规则的功能,支持按表单匹配规则
- 在角色管理控制器中新增数据规则绑定参数,支持角色创建和更新时绑定数据规则方案
- 实现数据规则详情接口回显功能,填充绑定的在线表单列表
- 重构在线表单列表数据ORM服务中的权限规则查询逻辑
- 移除角色删除时的数据规则绑定清理逻辑
- 更新系统角色VO,将部门列表替换为数据规则方案ID列表
feature/2026-07-ccc-dev
chenchuchuan 3 days ago
parent
commit
25f7f8f7c7
  1. 75
      application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/upms/controller/SysRoleController.java
  2. 8
      application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/upms/service/SysRoleService.java
  3. 21
      application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/upms/service/impl/SysRoleServiceImpl.java
  4. 7
      application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/upms/vo/SysRoleVo.java
  5. 51
      common/common-online/src/main/java/apelet/common/online/abstractplugin/ListDataOrmService.java
  6. 2
      common/common-online/src/main/java/apelet/common/online/abstractplugin/ListDataService.java
  7. 2
      common/common-online/src/main/java/apelet/common/online/controller/PermissionDataRuleSchemaController.java
  8. 13
      common/common-online/src/main/java/apelet/common/online/dao/RolePermissionSchemaMapper.java
  9. 1
      common/common-online/src/main/java/apelet/common/online/model/OnlineForm.java
  10. 22
      common/common-online/src/main/java/apelet/common/online/model/PermissionDataRuleSchema.java
  11. 28
      common/common-online/src/main/java/apelet/common/online/model/RolePermissionSchema.java
  12. 16
      common/common-online/src/main/java/apelet/common/online/service/IPermissionDataRuleSchemaService.java
  13. 49
      common/common-online/src/main/java/apelet/common/online/service/IRolePermissionSchemaService.java
  14. 59
      common/common-online/src/main/java/apelet/common/online/service/impl/PermissionDataRuleSchemaServiceImpl.java
  15. 89
      common/common-online/src/main/java/apelet/common/online/service/impl/RolePermissionSchemaServiceImpl.java

75
application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/upms/controller/SysRoleController.java

@ -10,7 +10,9 @@ import apelet.common.core.validator.UpdateGroup;
import apelet.common.log.annotation.OperationLog; import apelet.common.log.annotation.OperationLog;
import apelet.common.log.model.constant.SysOperationLogType; import apelet.common.log.model.constant.SysOperationLogType;
import apelet.common.online.dto.RoleFormButtonDto; import apelet.common.online.dto.RoleFormButtonDto;
import apelet.common.online.model.RolePermissionSchema;
import apelet.common.online.service.IRoleFormButtonService; import apelet.common.online.service.IRoleFormButtonService;
import apelet.common.online.service.IRolePermissionSchemaService;
import apelet.tenantadmin.upms.dto.SysRoleDto; import apelet.tenantadmin.upms.dto.SysRoleDto;
import apelet.tenantadmin.upms.dto.SysUserDto; import apelet.tenantadmin.upms.dto.SysUserDto;
import apelet.tenantadmin.upms.model.SysRole; import apelet.tenantadmin.upms.model.SysRole;
@ -18,9 +20,9 @@ import apelet.tenantadmin.upms.model.SysUser;
import apelet.tenantadmin.upms.model.SysUserRole; import apelet.tenantadmin.upms.model.SysUserRole;
import apelet.tenantadmin.upms.service.SysRoleService; import apelet.tenantadmin.upms.service.SysRoleService;
import apelet.tenantadmin.upms.service.SysUserService; import apelet.tenantadmin.upms.service.SysUserService;
import apelet.tenantadmin.upms.vo.SysDeptVo;
import apelet.tenantadmin.upms.vo.SysRoleVo; import apelet.tenantadmin.upms.vo.SysRoleVo;
import apelet.tenantadmin.upms.vo.SysUserVo; import apelet.tenantadmin.upms.vo.SysUserVo;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.TypeReference; import com.alibaba.fastjson.TypeReference;
import com.github.pagehelper.Page; import com.github.pagehelper.Page;
import com.github.pagehelper.page.PageMethod; import com.github.pagehelper.page.PageMethod;
@ -53,13 +55,16 @@ public class SysRoleController {
private SysUserService sysUserService; private SysUserService sysUserService;
@Autowired @Autowired
private IRoleFormButtonService roleFormButtonService; private IRoleFormButtonService roleFormButtonService;
@Autowired
private IRolePermissionSchemaService rolePermissionSchemaService;
/** /**
* 新增角色操作 * 新增角色操作
* *
* @param sysRoleDto 新增角色对象 * @param sysRoleDto 新增角色对象
* @param menuIdListString 与当前角色Id绑定的menuId列表多个menuId之间逗号分隔 * @param menuIdListString 与当前角色Id绑定的menuId列表多个menuId之间逗号分隔
* @param buttonConfigList 按钮权限配置列表可选不传不影响原有逻辑 * @param buttonConfigList 按钮权限配置列表可选不传不影响原有逻辑
* @param permissionDataRuleIdList 绑定的数据规则方案ID列表可选有值则校验并写入关联表
* @return 应答结果对象包含新增角色的主键Id * @return 应答结果对象包含新增角色的主键Id
*/ */
@ApiOperationSupport(ignoreParameters = {"sysRoleDto.roleId", "sysRoleDto.createTimeStart", "sysRoleDto.createTimeEnd"}) @ApiOperationSupport(ignoreParameters = {"sysRoleDto.roleId", "sysRoleDto.createTimeStart", "sysRoleDto.createTimeEnd"})
@ -68,7 +73,8 @@ public class SysRoleController {
public ResponseResult<Long> add( public ResponseResult<Long> add(
@MyRequestBody SysRoleDto sysRoleDto, @MyRequestBody SysRoleDto sysRoleDto,
@MyRequestBody String menuIdListString, @MyRequestBody String menuIdListString,
@MyRequestBody List<RoleFormButtonDto> buttonConfigList) { @MyRequestBody List<RoleFormButtonDto> buttonConfigList,
@MyRequestBody List<Long> permissionDataRuleIdList) {
String errorMessage = MyCommonUtil.getModelValidationError(sysRoleDto); String errorMessage = MyCommonUtil.getModelValidationError(sysRoleDto);
if (errorMessage != null) { if (errorMessage != null) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage); return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
@ -88,15 +94,23 @@ public class SysRoleController {
buttonConfigList.forEach(dto -> dto.setRoleId(sysRole.getRoleId())); buttonConfigList.forEach(dto -> dto.setRoleId(sysRole.getRoleId()));
roleFormButtonService.batchSaveButtonConfig(buttonConfigList); roleFormButtonService.batchSaveButtonConfig(buttonConfigList);
} }
// 数据规则绑定(可选,不传不影响原有逻辑)
if (CollectionUtil.isNotEmpty(permissionDataRuleIdList)) {
CallResult bindResult = rolePermissionSchemaService.bindRoleSchemas(sysRole.getRoleId(), permissionDataRuleIdList);
if (!bindResult.isSuccess()) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, bindResult.getErrorMessage());
}
}
return ResponseResult.success(sysRole.getRoleId()); return ResponseResult.success(sysRole.getRoleId());
} }
/** /**
* 更新角色操作 * 更新角色操作
* *
* @param sysRoleDto 更新角色对象 * @param sysRoleDto 更新角色对象
* @param menuIdListString 与当前角色Id绑定的menuId列表多个menuId之间逗号分隔 * @param menuIdListString 与当前角色Id绑定的menuId列表多个menuId之间逗号分隔
* @param buttonConfigList 按钮权限配置列表可选不传不影响原有逻辑 * @param buttonConfigList 按钮权限配置列表可选不传不影响原有逻辑
* @param permissionDataRuleIdList 绑定的数据规则方案ID列表可选有值则校验后先删后增
* @return 应答结果对象 * @return 应答结果对象
*/ */
@OperationLog(type = SysOperationLogType.UPDATE) @OperationLog(type = SysOperationLogType.UPDATE)
@ -104,7 +118,8 @@ public class SysRoleController {
public ResponseResult<Void> update( public ResponseResult<Void> update(
@MyRequestBody SysRoleDto sysRoleDto, @MyRequestBody SysRoleDto sysRoleDto,
@MyRequestBody String menuIdListString, @MyRequestBody String menuIdListString,
@MyRequestBody List<RoleFormButtonDto> buttonConfigList) { @MyRequestBody List<RoleFormButtonDto> buttonConfigList,
@MyRequestBody List<Long> permissionDataRuleIdList) {
String errorMessage = MyCommonUtil.getModelValidationError(sysRoleDto, Default.class, UpdateGroup.class); String errorMessage = MyCommonUtil.getModelValidationError(sysRoleDto, Default.class, UpdateGroup.class);
if (errorMessage != null) { if (errorMessage != null) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage); return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
@ -132,6 +147,13 @@ public class SysRoleController {
buttonConfigList.forEach(dto -> dto.setRoleId(sysRole.getRoleId())); buttonConfigList.forEach(dto -> dto.setRoleId(sysRole.getRoleId()));
roleFormButtonService.batchSaveButtonConfig(buttonConfigList); roleFormButtonService.batchSaveButtonConfig(buttonConfigList);
} }
// 数据规则绑定(可选,不传不影响原有逻辑;传空列表则清空绑定)
if (permissionDataRuleIdList != null) {
CallResult bindResult = rolePermissionSchemaService.bindRoleSchemas(sysRole.getRoleId(), permissionDataRuleIdList);
if (!bindResult.isSuccess()) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, bindResult.getErrorMessage());
}
}
return ResponseResult.success(); return ResponseResult.success();
} }
@ -197,8 +219,11 @@ public class SysRoleController {
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST); return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
} }
SysRoleVo sysRoleVo = MyModelUtil.copyTo(sysRole, SysRoleVo.class); SysRoleVo sysRoleVo = MyModelUtil.copyTo(sysRole, SysRoleVo.class);
// 填充关联的组织列表(多对多,仅需要deptId和deptName) // 返回角色绑定的数据规则方案关联关系
sysRoleVo.setDeptList(sysRoleService.getRoleDept(roleId)); List<RolePermissionSchema> roleSchemaList = rolePermissionSchemaService.listByRoleId(roleId);
if (CollectionUtil.isNotEmpty(roleSchemaList)) {
sysRoleVo.setPermissionDataRuleIdList(roleSchemaList.stream().map(RolePermissionSchema::getSchemaId).collect(Collectors.toList()));
}
return ResponseResult.success(sysRoleVo); return ResponseResult.success(sysRoleVo);
} }
@ -373,20 +398,20 @@ public class SysRoleController {
return ResponseResult.success(sysRoleService.getSysPermCodeListWithDetail(roleId, permCode)); return ResponseResult.success(sysRoleService.getSysPermCodeListWithDetail(roleId, permCode));
} }
/** // /**
* 查询角色关联的组织列表用于编辑页回显多对多 // * 查询角色关联的组织列表(用于编辑页回显,多对多)。
* // *
* @param roleId 角色Id // * @param roleId 角色Id。
* @return 应答结果对象包含角色关联的组织信息列表 // * @return 应答结果对象,包含角色关联的组织信息列表。
*/ // */
@GetMapping("/getRoleDept") // @GetMapping("/getRoleDept")
public ResponseResult<List<SysDeptVo>> getRoleDept(@RequestParam Long roleId) { // public ResponseResult<List<SysDeptVo>> getRoleDept(@RequestParam Long roleId) {
if (MyCommonUtil.existBlankArgument(roleId)) { // if (MyCommonUtil.existBlankArgument(roleId)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST); // return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
} // }
List<SysDeptVo> deptVoList = sysRoleService.getRoleDept(roleId); // List<SysDeptVo> deptVoList = sysRoleService.getRoleDept(roleId);
return ResponseResult.success(deptVoList); // return ResponseResult.success(deptVoList);
} // }
/** /**
* 根据组织ID分页查询关联角色运行时使用 * 根据组织ID分页查询关联角色运行时使用

8
application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/upms/service/SysRoleService.java

@ -7,7 +7,6 @@ import apelet.common.core.object.MyPageData;
import apelet.common.core.object.MyPageParam; import apelet.common.core.object.MyPageParam;
import apelet.tenantadmin.upms.model.SysRole; import apelet.tenantadmin.upms.model.SysRole;
import apelet.tenantadmin.upms.model.SysUserRole; import apelet.tenantadmin.upms.model.SysUserRole;
import apelet.tenantadmin.upms.vo.SysDeptVo;
import apelet.tenantadmin.upms.vo.SysRoleVo; import apelet.tenantadmin.upms.vo.SysRoleVo;
import java.util.List; import java.util.List;
@ -110,13 +109,6 @@ public interface SysRoleService extends IBaseService<SysRole, Long> {
*/ */
List<Map<String, Object>> getSysPermCodeListWithDetail(Long roleId, String permCode); List<Map<String, Object>> getSysPermCodeListWithDetail(Long roleId, String permCode);
/**
* 查询角色关联的组织列表用于编辑页回显多对多
*
* @param roleId 角色Id
* @return 角色关联的组织Vo列表如果不存在返回空列表
*/
List<SysDeptVo> getRoleDept(Long roleId);
/** /**
* 根据组织ID分页查询关联角色 * 根据组织ID分页查询关联角色

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

@ -14,19 +14,18 @@ import apelet.common.ext.base.BizWidgetDatasource;
import apelet.common.ext.constant.BizWidgetDatasourceType; import apelet.common.ext.constant.BizWidgetDatasourceType;
import apelet.common.ext.util.BizWidgetDatasourceExtHelper; import apelet.common.ext.util.BizWidgetDatasourceExtHelper;
import apelet.common.online.service.IRoleFormButtonService; import apelet.common.online.service.IRoleFormButtonService;
import apelet.common.online.service.IRolePermissionSchemaService;
import apelet.common.sequence.wrapper.IdGeneratorWrapper; import apelet.common.sequence.wrapper.IdGeneratorWrapper;
import apelet.tenantadmin.config.DataSourceType; import apelet.tenantadmin.config.DataSourceType;
import apelet.tenantadmin.upms.dao.SysDeptMapper; import apelet.tenantadmin.upms.dao.SysDeptMapper;
import apelet.tenantadmin.upms.dao.SysRoleMapper; import apelet.tenantadmin.upms.dao.SysRoleMapper;
import apelet.tenantadmin.upms.dao.SysRoleMenuMapper; import apelet.tenantadmin.upms.dao.SysRoleMenuMapper;
import apelet.tenantadmin.upms.dao.SysUserRoleMapper; import apelet.tenantadmin.upms.dao.SysUserRoleMapper;
import apelet.tenantadmin.upms.model.SysDept;
import apelet.tenantadmin.upms.model.SysRole; import apelet.tenantadmin.upms.model.SysRole;
import apelet.tenantadmin.upms.model.SysRoleMenu; import apelet.tenantadmin.upms.model.SysRoleMenu;
import apelet.tenantadmin.upms.model.SysUserRole; import apelet.tenantadmin.upms.model.SysUserRole;
import apelet.tenantadmin.upms.service.SysMenuService; import apelet.tenantadmin.upms.service.SysMenuService;
import apelet.tenantadmin.upms.service.SysRoleService; import apelet.tenantadmin.upms.service.SysRoleService;
import apelet.tenantadmin.upms.vo.SysDeptVo;
import apelet.tenantadmin.upms.vo.SysRoleVo; import apelet.tenantadmin.upms.vo.SysRoleVo;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
@ -73,6 +72,8 @@ public class SysRoleServiceImpl extends BaseService<SysRole, Long> implements Sy
private BizWidgetDatasourceExtHelper bizWidgetDatasourceExtHelper; private BizWidgetDatasourceExtHelper bizWidgetDatasourceExtHelper;
@Autowired @Autowired
private IRoleFormButtonService roleFormButtonService; private IRoleFormButtonService roleFormButtonService;
@Autowired
private IRolePermissionSchemaService rolePermissionSchemaService;
@PostConstruct @PostConstruct
private void registerBizWidgetDatasource() { private void registerBizWidgetDatasource() {
@ -185,6 +186,7 @@ public class SysRoleServiceImpl extends BaseService<SysRole, Long> implements Sy
userRole.setRoleId(roleId); userRole.setRoleId(roleId);
sysUserRoleMapper.delete(new QueryWrapper<>(userRole)); sysUserRoleMapper.delete(new QueryWrapper<>(userRole));
roleFormButtonService.removeByRoleId(roleId); roleFormButtonService.removeByRoleId(roleId);
rolePermissionSchemaService.removeByRoleId(roleId);
return true; return true;
} }
@ -283,21 +285,6 @@ public class SysRoleServiceImpl extends BaseService<SysRole, Long> implements Sy
return sysRoleMapper.getSysPermCodeListWithDetail(roleId, permCode); return sysRoleMapper.getSysPermCodeListWithDetail(roleId, permCode);
} }
@Override
public List<SysDeptVo> getRoleDept(Long roleId) {
LambdaQueryWrapper<SysUserRole> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SysUserRole::getRoleId, roleId).isNotNull(SysUserRole::getDeptId);
List<SysUserRole> userRoleList = sysUserRoleMapper.selectList(queryWrapper);
if (CollUtil.isEmpty(userRoleList)) {
return Collections.emptyList();
}
Set<Long> deptIdSet = userRoleList.stream().map(SysUserRole::getDeptId).collect(Collectors.toSet());
List<SysDept> deptList = sysDeptMapper.selectBatchIds(deptIdSet);
if (CollUtil.isEmpty(deptList)) {
return Collections.emptyList();
}
return MyModelUtil.copyCollectionTo(deptList, SysDeptVo.class);
}
@Override @Override
public MyPageData<SysRoleVo> listRoleByDeptId(Long deptId, MyOrderParam orderParam, MyPageParam pageParam) { public MyPageData<SysRoleVo> listRoleByDeptId(Long deptId, MyOrderParam orderParam, MyPageParam pageParam) {

7
application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/upms/vo/SysRoleVo.java

@ -38,8 +38,9 @@ public class SysRoleVo extends BaseVo {
private List<Map<String, Object>> sysRoleMenuList; private List<Map<String, Object>> sysRoleMenuList;
/** /**
* 关联的组织列表仅返回deptId和deptName多对多 * 角色绑定的数据规则方案ID列表
*/ */
@Schema(description = "关联的组织列表") @Schema(description = "角色绑定的数据规则方案ID列表")
private List<SysDeptVo> deptList; private List<Long> permissionDataRuleIdList;
} }

51
common/common-online/src/main/java/apelet/common/online/abstractplugin/ListDataOrmService.java

@ -71,8 +71,8 @@ public class ListDataOrmService extends ListDataService {
List<Map<String, Object>> resList = new ArrayList<>(); List<Map<String, Object>> resList = new ArrayList<>();
OnlineTable masterTable = datasourceResult.getData().getMasterTable(); OnlineTable masterTable = datasourceResult.getData().getMasterTable();
OnlineForm onlineForm = onlineFormService.getOnlineFormFromCache(dto.getFormId()); OnlineForm onlineForm = onlineFormService.getOnlineFormFromCache(dto.getFormId());
// 根据 metaCode 过滤权限规则:非空→基础数据权限,为空→列表权限 // 根据当前用户角色 + 当前表单匹配权限规则:非空→基础数据权限,为空→列表权限
List<PermissionDataRuleSchema> ruleSchemaList = permissionDataRuleSchemaService.listByFormId(onlFormHead.getId()); List<PermissionDataRuleSchema> ruleSchemaList = this.getRuleSchemaListByCurrentRole();
String conditionExpression = null; String conditionExpression = null;
if (CollUtil.isNotEmpty(ruleSchemaList)) { if (CollUtil.isNotEmpty(ruleSchemaList)) {
List<PermissionDataRuleSchema> filtered = new ArrayList<>(); List<PermissionDataRuleSchema> filtered = new ArrayList<>();
@ -151,6 +151,53 @@ public class ListDataOrmService extends ListDataService {
return expression; return expression;
} }
/**
* 根据当前登录用户角色查询启用的数据规则并按当前表单匹配
* 兜底角色未绑定任何数据规则时返回空列表不做数据权限过滤
*/
private List<PermissionDataRuleSchema> getRuleSchemaListByCurrentRole() {
// 1. 当前用户角色ID集合
TokenData tokenData = TokenData.takeFromRequest();
if (tokenData == null || StrUtil.isBlank(tokenData.getRoleIds())) {
return Collections.emptyList();
}
Set<Long> roleIds = StrUtil.split(tokenData.getRoleIds(), ',').stream()
.map(Long::valueOf).collect(Collectors.toSet());
// 2. 查询角色绑定的数据规则方案
List<RolePermissionSchema> roleSchemaList = rolePermissionSchemaService.listByRoleIds(roleIds);
if (CollUtil.isEmpty(roleSchemaList)) {
return Collections.emptyList();
}
Set<Long> schemaIdSet = roleSchemaList.stream().map(RolePermissionSchema::getSchemaId).collect(Collectors.toSet());
List<PermissionDataRuleSchema> ruleList = permissionDataRuleSchemaService.listEnabledByIds(schemaIdSet);
if (CollUtil.isEmpty(ruleList)) {
return Collections.emptyList();
}
// 3. 按当前表单过滤:先按 form_head_id 匹配,命中后再按 form_id_list 筛选
return ruleList.stream().filter(this::matchRuleByForm).collect(Collectors.toList());
}
/**
* 判断数据规则是否匹配当前在线表单
* 先按 form_head_id 匹配规则所属主表命中后再按 form_id_list 筛选
* form_id_list 未配置则全部生效原先逻辑已配置时需包含当前表单id
*/
private boolean matchRuleByForm(PermissionDataRuleSchema rule) {
// 1. 先按 form_head_id 匹配(规则作用于其所属主表)
if (!Objects.equals(rule.getFormHeadId(), onlFormHead.getId())) {
return false;
}
// 2. 再按 form_id_list 筛选
if (StrUtil.isBlank(rule.getFormIdList())) {
return true;
}
Long currentFormId = dto.getFormId();
if (currentFormId == null) {
return false;
}
return StrUtil.split(rule.getFormIdList(), ',').stream().map(Long::valueOf).collect(Collectors.toSet()).contains(currentFormId);
}
public void getOrmSelector(JSONObject jsonObject, Set<String> selectorSet, OnlineTable masterTable, Map<String, Object> entryIdMap) { public void getOrmSelector(JSONObject jsonObject, Set<String> selectorSet, OnlineTable masterTable, Map<String, Object> entryIdMap) {
Map<Long, OnlineColumn> columnMap = masterTable.getColumnMap(); Map<Long, OnlineColumn> columnMap = masterTable.getColumnMap();
JSONArray array = jsonObject.getJSONArray("childWidgetList"); JSONArray array = jsonObject.getJSONArray("childWidgetList");

2
common/common-online/src/main/java/apelet/common/online/abstractplugin/ListDataService.java

@ -49,6 +49,7 @@ public abstract class ListDataService {
protected OnlineOperationService onlineOperationService; protected OnlineOperationService onlineOperationService;
protected OnlineTableService onlineTableService; protected OnlineTableService onlineTableService;
protected IPermissionDataRuleSchemaService permissionDataRuleSchemaService; protected IPermissionDataRuleSchemaService permissionDataRuleSchemaService;
protected IRolePermissionSchemaService rolePermissionSchemaService;
protected ResponseResult<OnlineDatasource> datasourceResult; protected ResponseResult<OnlineDatasource> datasourceResult;
@ -72,6 +73,7 @@ public abstract class ListDataService {
onlineTableService = ApplicationContextHolder.getBean("onlineTableService"); onlineTableService = ApplicationContextHolder.getBean("onlineTableService");
ormDataSourceUtil = ApplicationContextHolder.getBean("ormGenDataSourceUtil"); ormDataSourceUtil = ApplicationContextHolder.getBean("ormGenDataSourceUtil");
permissionDataRuleSchemaService = ApplicationContextHolder.getBean("permissionDataRuleSchemaService"); permissionDataRuleSchemaService = ApplicationContextHolder.getBean("permissionDataRuleSchemaService");
rolePermissionSchemaService = ApplicationContextHolder.getBean("rolePermissionSchemaService");
} }
@Setter @Setter

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

@ -179,6 +179,8 @@ public class PermissionDataRuleSchemaController {
if (schema == null) { if (schema == null) {
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST); return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
} }
// 根据配置的多个 formId 查询 zz_online_form,返回 formName
service.fillFormNameList(schema);
return ResponseResult.success(schema); return ResponseResult.success(schema);
} }
} }

13
common/common-online/src/main/java/apelet/common/online/dao/RolePermissionSchemaMapper.java

@ -0,0 +1,13 @@
package apelet.common.online.dao;
import apelet.common.core.base.dao.BaseDaoMapper;
import apelet.common.online.model.RolePermissionSchema;
/**
* 角色-数据规则方案关联表 Mapper 接口
*
* @author chenchuchuan
* @date 2026-08-05
*/
public interface RolePermissionSchemaMapper extends BaseDaoMapper<RolePermissionSchema> {
}

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

@ -72,6 +72,7 @@ public class OnlineForm {
/** /**
* 表单类型 * 表单类型
* @see FormType
*/ */
@TableField(value = "form_type") @TableField(value = "form_type")
private Integer formType; private Integer formType;

22
common/common-online/src/main/java/apelet/common/online/model/PermissionDataRuleSchema.java

@ -16,6 +16,8 @@ import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.Map;
/** /**
* 权限数据规则方案表 实体对象 * 权限数据规则方案表 实体对象
@ -38,11 +40,17 @@ public class PermissionDataRuleSchema extends BaseModel implements Serializable
private Long id; private Long id;
/** /**
* onl_form_head Id * onl_form_head Id数据规则所属主表
*/ */
@TableField(value = "form_id") @TableField(value = "form_head_id")
@NotNull(message = "数据验证失败,form_id不能为空!") @NotNull(message = "数据验证失败,form_head_id不能为空!")
private Long formId; private Long formHeadId;
/**
* 在线表单id集合zz_online_form.form_id多个逗号分隔为空表示对绑定的全部在线表单生效
*/
@TableField(value = "form_id_list")
private String formIdList;
/** /**
* 表单元数据编码 * 表单元数据编码
@ -127,6 +135,12 @@ public class PermissionDataRuleSchema extends BaseModel implements Serializable
@TableField(value = "update_user_id") @TableField(value = "update_user_id")
private Long updateUserId; private Long updateUserId;
/**
* 绑定的在线表单列表formId + formName详情接口返回用非持久化
*/
@TableField(exist = false)
private List<Map<String, Object>> formList;
// ========== MapStruct ========== // ========== MapStruct ==========
@Mapper @Mapper
public interface PermissionDataRuleSchemaModelMapper public interface PermissionDataRuleSchemaModelMapper

28
common/common-online/src/main/java/apelet/common/online/model/RolePermissionSchema.java

@ -0,0 +1,28 @@
package apelet.common.online.model;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
* 角色-数据规则方案关联实体对象role_id + schema_id 联合主键
*
* @author chenchuchuan
* @date 2026-08-05
*/
@Data
@TableName(value = "zz_role_permission_schema")
public class RolePermissionSchema {
/**
* 角色ID
*/
@TableField(value = "role_id")
private Long roleId;
/**
* 规则方案ID关联 zz_permission_data_rule_schema.id
*/
@TableField(value = "schema_id")
private Long schemaId;
}

16
common/common-online/src/main/java/apelet/common/online/service/IPermissionDataRuleSchemaService.java

@ -4,6 +4,7 @@ import apelet.common.core.base.service.IBaseService;
import apelet.common.core.object.CallResult; import apelet.common.core.object.CallResult;
import apelet.common.online.model.PermissionDataRuleSchema; import apelet.common.online.model.PermissionDataRuleSchema;
import java.util.Collection;
import java.util.List; import java.util.List;
/** /**
@ -46,4 +47,19 @@ public interface IPermissionDataRuleSchemaService extends IBaseService<Permissio
* @return 新增后的规则方案对象 * @return 新增后的规则方案对象
*/ */
PermissionDataRuleSchema saveNew(PermissionDataRuleSchema schema); PermissionDataRuleSchema saveNew(PermissionDataRuleSchema schema);
/**
* 根据规则方案ID集合查询启用状态的规则运行时用
*
* @param idSet 规则方案ID集合
* @return 启用状态的规则列表
*/
List<PermissionDataRuleSchema> listEnabledByIds(Collection<Long> idSet);
/**
* 填充绑定的在线表单列表formId + formName用于详情接口回显
*
* @param schema 规则方案对象
*/
void fillFormNameList(PermissionDataRuleSchema schema);
} }

49
common/common-online/src/main/java/apelet/common/online/service/IRolePermissionSchemaService.java

@ -0,0 +1,49 @@
package apelet.common.online.service;
import apelet.common.core.base.service.IBaseService;
import apelet.common.core.object.CallResult;
import apelet.common.online.model.RolePermissionSchema;
import java.util.Collection;
import java.util.List;
/**
* 角色-数据规则方案关联服务接口
*
* @author chenchuchuan
* @date 2026-08-05
*/
public interface IRolePermissionSchemaService extends IBaseService<RolePermissionSchema, Long> {
/**
* 查询指定角色绑定的所有数据规则方案
*
* @param roleId 角色ID
* @return 关联关系列表
*/
List<RolePermissionSchema> listByRoleId(Long roleId);
/**
* 根据多个角色ID查询绑定的数据规则方案运行时用
*
* @param roleIds 角色ID集合
* @return 关联关系列表
*/
List<RolePermissionSchema> listByRoleIds(Collection<Long> roleIds);
/**
* 绑定角色的数据规则方案先删后插schemaIdList 为空表示清空该角色的全部绑定
*
* @param roleId 角色ID
* @param schemaIdList 数据规则方案ID列表
* @return 绑定结果校验失败时返回错误信息
*/
CallResult bindRoleSchemas(Long roleId, List<Long> schemaIdList);
/**
* 删除角色下绑定的所有数据规则方案角色删除时调用
*
* @param roleId 角色ID
*/
void removeByRoleId(Long roleId);
}

59
common/common-online/src/main/java/apelet/common/online/service/impl/PermissionDataRuleSchemaServiceImpl.java

@ -6,16 +6,21 @@ import apelet.common.core.object.CallResult;
import apelet.common.generator.model.OnlFormHead; import apelet.common.generator.model.OnlFormHead;
import apelet.common.generator.service.IOnlFormHeadService; import apelet.common.generator.service.IOnlFormHeadService;
import apelet.common.online.dao.PermissionDataRuleSchemaMapper; import apelet.common.online.dao.PermissionDataRuleSchemaMapper;
import apelet.common.online.model.OnlineForm;
import apelet.common.online.model.PermissionDataRuleSchema; import apelet.common.online.model.PermissionDataRuleSchema;
import apelet.common.online.model.constant.DataRuleType; import apelet.common.online.model.constant.DataRuleType;
import apelet.common.online.service.IPermissionDataRuleSchemaService; import apelet.common.online.service.IPermissionDataRuleSchemaService;
import apelet.common.online.service.OnlineFormService;
import apelet.common.sequence.wrapper.IdGeneratorWrapper; import apelet.common.sequence.wrapper.IdGeneratorWrapper;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List; import java.util.*;
import java.util.stream.Collectors;
/** /**
* 权限数据规则方案表 服务实现类 * 权限数据规则方案表 服务实现类
@ -36,6 +41,9 @@ public class PermissionDataRuleSchemaServiceImpl extends BaseService<PermissionD
@Autowired @Autowired
private IOnlFormHeadService onlFormHeadService; private IOnlFormHeadService onlFormHeadService;
@Autowired
private OnlineFormService onlineFormService;
// ========== BaseService 要求重写 ========== // ========== BaseService 要求重写 ==========
@Override @Override
protected BaseDaoMapper<PermissionDataRuleSchema> mapper() { protected BaseDaoMapper<PermissionDataRuleSchema> mapper() {
@ -48,11 +56,11 @@ public class PermissionDataRuleSchemaServiceImpl extends BaseService<PermissionD
return mapper.getListByFilter(filter, orderBy); return mapper.getListByFilter(filter, orderBy);
} }
// ========== 按 formId 查询启用状态的规则 ========== // ========== 按 formHeadId 查询启用状态的规则 ==========
@Override @Override
public List<PermissionDataRuleSchema> listByFormId(Long formId) { public List<PermissionDataRuleSchema> listByFormId(Long formId) {
LambdaQueryWrapper<PermissionDataRuleSchema> qw = new LambdaQueryWrapper<>(); LambdaQueryWrapper<PermissionDataRuleSchema> qw = new LambdaQueryWrapper<>();
qw.eq(PermissionDataRuleSchema::getFormId, formId) qw.eq(PermissionDataRuleSchema::getFormHeadId, formId)
.eq(PermissionDataRuleSchema::getStatus, 1); .eq(PermissionDataRuleSchema::getStatus, 1);
return this.list(qw); return this.list(qw);
} }
@ -70,11 +78,50 @@ public class PermissionDataRuleSchemaServiceImpl extends BaseService<PermissionD
return schema; return schema;
} }
// ========== 核心校验: formId → 主表/单表,自动填充 tableType ========== // ========== 根据规则方案ID集合查询启用状态的规则(运行时用) ==========
@Override
public List<PermissionDataRuleSchema> listEnabledByIds(Collection<Long> idSet) {
if (CollUtil.isEmpty(idSet)) {
return Collections.emptyList();
}
LambdaQueryWrapper<PermissionDataRuleSchema> qw = new LambdaQueryWrapper<>();
qw.in(PermissionDataRuleSchema::getId, idSet)
.eq(PermissionDataRuleSchema::getStatus, 1);
return this.list(qw);
}
// ========== 填充绑定的在线表单列表(formId + formName),详情接口回显用 ==========
@Override
public void fillFormNameList(PermissionDataRuleSchema schema) {
if (schema == null ){
return;
}
List<Map<String, Object>> formList = new ArrayList<>();
if (StrUtil.isNotBlank(schema.getFormIdList())) {
List<Long> formIds = StrUtil.split(schema.getFormIdList(), ',')
.stream().filter(StrUtil::isNotBlank).map(Long::valueOf).collect(Collectors.toList());
if (CollUtil.isNotEmpty(formIds)) {
OnlineForm filter = new OnlineForm();
filter.setFormIdSet(new HashSet<>(formIds));
List<OnlineForm> formListData = onlineFormService.getOnlineFormList(filter, null);
if (CollUtil.isNotEmpty(formListData)) {
for (OnlineForm form : formListData) {
Map<String, Object> item = new HashMap<>();
item.put("formId", form.getFormId());
item.put("formName", form.getFormName());
formList.add(item);
}
}
}
}
schema.setFormList(formList);
}
// ========== 核心校验: formHeadId → 主表/单表,自动填充 tableType ==========
@Override @Override
public CallResult verifyRelatedData(PermissionDataRuleSchema schema) { public CallResult verifyRelatedData(PermissionDataRuleSchema schema) {
// 1. 通过 tableName 查询 onl_form_head 获取 tableType // 1. 通过 formHeadId 查询 onl_form_head 获取 tableType
OnlFormHead formHead = onlFormHeadService.getById(schema.getFormId()); OnlFormHead formHead = onlFormHeadService.getById(schema.getFormHeadId());
if (formHead == null) { if (formHead == null) {
return CallResult.error("数据验证失败,无法获取表类型信息,请检查表单配置!"); return CallResult.error("数据验证失败,无法获取表类型信息,请检查表单配置!");
} }

89
common/common-online/src/main/java/apelet/common/online/service/impl/RolePermissionSchemaServiceImpl.java

@ -0,0 +1,89 @@
package apelet.common.online.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.online.dao.RolePermissionSchemaMapper;
import apelet.common.online.model.RolePermissionSchema;
import apelet.common.online.service.IPermissionDataRuleSchemaService;
import apelet.common.online.service.IRolePermissionSchemaService;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
/**
* 角色-数据规则方案关联服务实现类
*
* @author chenchuchuan
* @date 2026-08-05
*/
@Service("rolePermissionSchemaService")
@Slf4j
public class RolePermissionSchemaServiceImpl extends BaseService<RolePermissionSchema, Long> implements IRolePermissionSchemaService {
@Autowired
private RolePermissionSchemaMapper mapper;
@Autowired
private IPermissionDataRuleSchemaService permissionDataRuleSchemaService;
@Override
protected BaseDaoMapper<RolePermissionSchema> mapper() {
return mapper;
}
@Override
public List<RolePermissionSchema> listByRoleId(Long roleId) {
LambdaQueryWrapper<RolePermissionSchema> qw = new LambdaQueryWrapper<>();
qw.eq(RolePermissionSchema::getRoleId, roleId);
return this.list(qw);
}
@Override
public List<RolePermissionSchema> listByRoleIds(Collection<Long> roleIds) {
if (CollUtil.isEmpty(roleIds)) {
return Collections.emptyList();
}
LambdaQueryWrapper<RolePermissionSchema> qw = new LambdaQueryWrapper<>();
qw.in(RolePermissionSchema::getRoleId, roleIds);
return this.list(qw);
}
@Transactional(rollbackFor = Exception.class)
@Override
public CallResult bindRoleSchemas(Long roleId, List<Long> schemaIdList) {
// 1. 校验数据规则方案是否存在
if (CollUtil.isNotEmpty(schemaIdList)) {
if (!permissionDataRuleSchemaService.existAllPrimaryKeys(new HashSet<>(schemaIdList))) {
return CallResult.error("数据验证失败,存在不合法的数据规则方案,请刷新后重试!");
}
}
// 2. 先删除该角色原有的绑定
this.removeByRoleId(roleId);
// 3. 再插入新的绑定
if (CollUtil.isNotEmpty(schemaIdList)) {
for (Long schemaId : schemaIdList) {
RolePermissionSchema roleSchema = new RolePermissionSchema();
roleSchema.setRoleId(roleId);
roleSchema.setSchemaId(schemaId);
this.save(roleSchema);
}
}
return CallResult.ok();
}
@Override
public void removeByRoleId(Long roleId) {
LambdaQueryWrapper<RolePermissionSchema> qw = new LambdaQueryWrapper<>();
qw.eq(RolePermissionSchema::getRoleId, roleId);
this.remove(qw);
}
}
Loading…
Cancel
Save