diff --git a/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/controller/RoleFormButtonController.java b/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/controller/RoleFormButtonController.java new file mode 100644 index 0000000..ebe891a --- /dev/null +++ b/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/controller/RoleFormButtonController.java @@ -0,0 +1,105 @@ +package apelet.tenantadmin.tenant.controller; + +import apelet.common.core.annotation.MyRequestBody; +import apelet.common.core.constant.ErrorCodeEnum; +import apelet.common.core.object.*; +import apelet.common.core.util.MyCommonUtil; +import apelet.common.core.util.MyPageUtil; +import apelet.common.log.annotation.OperationLog; +import apelet.common.log.model.constant.SysOperationLogType; +import apelet.tenantadmin.tenant.dto.RoleFormButtonDto; +import apelet.tenantadmin.tenant.model.RoleFormButton; +import apelet.tenantadmin.tenant.service.IRoleFormButtonService; +import com.github.pagehelper.page.PageMethod; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Map; + +/** + * 角色-表单按钮权限控制器。 + * + * @author chenchuchuan + * @date 2026-07-17 + */ +@RestController +@RequestMapping("/tenantadmin/tenant/roleFormButton") +public class RoleFormButtonController { + + @Autowired + private IRoleFormButtonService service; + + /** + * 查询指定角色+表单的按钮权限配置。 + * 返回表单中所有开启的按钮 + 每个按钮是否已勾选。 + * + * @param roleId 角色ID(必填)。 + * @param formId 在线表单ID(必填)。 + * @return 包含 formId, roleId, id, buttonList[{name, checked}]。 + */ + @GetMapping("/getButtonConfig") + public ResponseResult> getButtonConfig( + @RequestParam Long roleId, + @RequestParam Long formId) { + if (MyCommonUtil.existBlankArgument(roleId, formId)) { + return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST); + } + Map result = service.getButtonConfigVo(roleId, formId); + return ResponseResult.success(result); + } + + /** + * 批量保存角色+表单的按钮权限配置(新增或更新)。 + * + * @param dtoList 列表,每个元素包含 roleId(必填), formId(必填), id(编辑时传), buttonList。 + * @return 应答结果。 + */ + @OperationLog(type = SysOperationLogType.ADD) + @PostMapping("/saveButtonConfig") + public ResponseResult saveButtonConfig( + @MyRequestBody List dtoList) { + if (dtoList == null || dtoList.isEmpty()) { + return ResponseResult.error( + ErrorCodeEnum.ARGUMENT_NULL_EXIST, "数据验证失败,按钮配置列表不能为空!"); + } + CallResult result = service.batchSaveButtonConfig(dtoList); + if (!result.isSuccess()) { + return ResponseResult.error( + ErrorCodeEnum.DATA_VALIDATED_FAILED, result.getErrorMessage()); + } + return ResponseResult.success(); + } + + /** + * 根据角色ID查询该角色下所有绑定的按钮权限配置列表。 + * + * @param roleId 角色ID。 + * @return 按钮权限配置列表。 + */ + @GetMapping("/listByRoleId") + public ResponseResult> listByRoleId( + @RequestParam Long roleId) { + if (MyCommonUtil.existBlankArgument(roleId)) { + return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST); + } + return ResponseResult.success(service.listByRoleId(roleId)); + } + + /** + * 分页查询按钮权限配置列表。 + */ + @PostMapping("/list") + public ResponseResult> list( + @MyRequestBody RoleFormButton filter, + @MyRequestBody MyOrderParam orderParam, + @MyRequestBody MyPageParam pageParam) { + if (pageParam != null) { + PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize()); + } + List list = service.getListByFilter( + filter, MyOrderParam.buildOrderBy(orderParam, RoleFormButton.class)); + return ResponseResult.success( + MyPageUtil.makeResponseData(list, RoleFormButton.INSTANCE)); + } +} diff --git a/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/dao/RoleFormButtonMapper.java b/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/dao/RoleFormButtonMapper.java new file mode 100644 index 0000000..87c7669 --- /dev/null +++ b/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/dao/RoleFormButtonMapper.java @@ -0,0 +1,23 @@ +package apelet.tenantadmin.tenant.dao; + +import apelet.common.core.base.dao.BaseDaoMapper; +import apelet.tenantadmin.tenant.model.RoleFormButton; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 角色-表单按钮权限配置数据访问操作接口。 + * + * @author chenchuchuan + * @date 2026-07-17 + */ +public interface RoleFormButtonMapper extends BaseDaoMapper { + + /** + * 分页条件查询。 + */ + List getListByFilter( + @Param("filter") RoleFormButton filter, + @Param("orderBy") String orderBy); +} diff --git a/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/dao/mapper/RoleFormButtonMapper.xml b/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/dao/mapper/RoleFormButtonMapper.xml new file mode 100644 index 0000000..bc0d852 --- /dev/null +++ b/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/dao/mapper/RoleFormButtonMapper.xml @@ -0,0 +1,21 @@ + + + + + + + diff --git a/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/dto/RoleFormButtonDto.java b/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/dto/RoleFormButtonDto.java new file mode 100644 index 0000000..14ca2a6 --- /dev/null +++ b/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/dto/RoleFormButtonDto.java @@ -0,0 +1,35 @@ +package apelet.tenantadmin.tenant.dto; + +import lombok.Data; + +import java.util.List; + +/** + * 角色表单按钮权限保存入参。 + * + * @author chenchuchuan + * @date 2026-07-17 + */ +@Data +public class RoleFormButtonDto { + + /** 角色ID(必填) */ + private Long roleId; + + /** 表单ID(必填) */ + private Long formId; + + /** 主键ID(编辑时传,新增时不传) */ + private Long id; + + /** 按钮勾选列表 */ + private List buttonList; + + @Data + public static class ButtonItem { + /** 按钮名称 */ + private String name; + /** 是否勾选 */ + private Boolean checked; + } +} diff --git a/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/model/RoleFormButton.java b/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/model/RoleFormButton.java new file mode 100644 index 0000000..a58e55c --- /dev/null +++ b/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/model/RoleFormButton.java @@ -0,0 +1,69 @@ +package apelet.tenantadmin.tenant.model; + +import apelet.common.core.base.mapper.BaseModelMapper; +import apelet.common.core.base.model.BaseModel; +import apelet.common.core.validator.UpdateGroup; +import apelet.tenantadmin.tenant.vo.RoleFormButtonVo; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.Date; + +/** + * 角色-表单按钮权限配置实体对象。 + * + * @author chenchuchuan + * @date 2026-07-17 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("xy_sys_role_form_button") +public class RoleFormButton extends BaseModel implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "id") + @NotNull(message = "数据验证失败,id不能为空!", groups = {UpdateGroup.class}) + private Long id; + + /** 角色ID */ + @TableField(value = "role_id") + @NotNull(message = "数据验证失败,角色ID不能为空!") + private Long roleId; + + /** 在线表单ID */ + @TableField(value = "form_id") + @NotNull(message = "数据验证失败,表单ID不能为空!") + private Long formId; + + /** 按钮配置JSON */ + @TableField(value = "button_config") + private String buttonConfig; + + @TableField(value = "create_by") + private String createBy; + + @TableField(value = "create_time") + private Date createTime; + + @TableField(value = "update_by") + private String updateBy; + + @TableField(value = "update_time") + private Date updateTime; + + @Mapper + public interface RoleFormButtonModelMapper + extends BaseModelMapper { + } + + public static final RoleFormButtonModelMapper INSTANCE = + Mappers.getMapper(RoleFormButtonModelMapper.class); +} diff --git a/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/service/IRoleFormButtonService.java b/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/service/IRoleFormButtonService.java new file mode 100644 index 0000000..3f21b28 --- /dev/null +++ b/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/service/IRoleFormButtonService.java @@ -0,0 +1,69 @@ +package apelet.tenantadmin.tenant.service; + +import apelet.common.core.base.service.IBaseService; +import apelet.common.core.object.CallResult; +import apelet.tenantadmin.tenant.dto.RoleFormButtonDto; +import apelet.tenantadmin.tenant.model.RoleFormButton; + +import java.util.List; +import java.util.Map; + +/** + * 角色-表单按钮权限配置服务接口。 + * + * @author chenchuchuan + * @date 2026-07-17 + */ +public interface IRoleFormButtonService + extends IBaseService { + + /** + * 分页条件查询。 + */ + List getListByFilter(RoleFormButton filter, String orderBy); + + // ========== 核心业务接口 ========== + + /** + * 查询按钮权限配置的VO(含表单所有按钮 + 勾选状态的合并结果)。 + * + * @param roleId 角色ID。 + * @param formId 在线表单ID。 + * @return 包含 formId, roleId, id(配置记录ID), buttonList(含name+checked的列表)。 + */ + Map getButtonConfigVo(Long roleId, Long formId); + + /** + * 批量保存按钮权限配置(同一事务内全部成功或全部回滚)。 + * + * @param dtoList 保存入参列表。 + * @return 保存结果。 + */ + CallResult batchSaveButtonConfig(List dtoList); + + /** + * 保存单条按钮权限配置(仅供内部批量方法调用,不做事务注解)。 + * + * @param dto 保存入参。 + * @return 保存结果。 + */ + CallResult saveButtonConfig(RoleFormButtonDto dto); + + /** + * 根据角色ID查询该角色下所有绑定的按钮权限配置。 + * + * @param roleId 角色ID。 + * @return 按钮权限配置列表。 + */ + List listByRoleId(Long roleId); + + /** + * 根据角色ID和表单ID查询唯一配置记录。 + */ + RoleFormButton getByRoleIdAndFormId(Long roleId, Long formId); + + /** + * 删除角色下绑定的所有按钮权限配置(角色删除时调用)。 + */ + void removeByRoleId(Long roleId); +} diff --git a/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/service/impl/FormButtonPermissionCheckerImpl.java b/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/service/impl/FormButtonPermissionCheckerImpl.java new file mode 100644 index 0000000..0037d97 --- /dev/null +++ b/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/service/impl/FormButtonPermissionCheckerImpl.java @@ -0,0 +1,84 @@ +package apelet.tenantadmin.tenant.service.impl; + +import apelet.common.core.object.TokenData; +import apelet.common.online.service.FormButtonPermissionChecker; +import apelet.tenantadmin.tenant.model.RoleFormButton; +import apelet.tenantadmin.tenant.service.IRoleFormButtonService; +import apelet.tenantadmin.tenant.util.WidgetJsonButtonParser; +import apelet.tenantadmin.upms.dao.SysUserRoleMapper; +import apelet.tenantadmin.upms.model.SysUserRole; +import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * 按钮权限检查器实现。 + * 通过当前用户的所有角色,查询 xy_sys_role_form_button 表, + * 判断是否有指定表单-按钮的权限。 + * + * @author chenchuchuan + * @date 2026-07-17 + */ +@Slf4j +@Component +public class FormButtonPermissionCheckerImpl implements FormButtonPermissionChecker { + + @Autowired + private SysUserRoleMapper sysUserRoleMapper; + + @Autowired + private IRoleFormButtonService roleFormButtonService; + + @Override + public boolean hasPermission(Long formId, String buttonName) { + try { + // 1. 获取当前登录用户ID + TokenData tokenData = TokenData.takeFromRequest(); + if (tokenData == null) { + log.warn("TokenData 为空,无法校验按钮权限"); + return false; + } + Long userId = tokenData.getUserId(); + if (userId == null) { + return false; + } + + // 2. 获取用户的所有角色 + List userRoles = sysUserRoleMapper.selectList( + new LambdaQueryWrapper() + .eq(SysUserRole::getUserId, userId)); + if (userRoles.isEmpty()) { + return false; + } + + List roleIds = userRoles.stream() + .map(SysUserRole::getRoleId) + .collect(Collectors.toList()); + + // 3. 遍历角色,检查是否有任一角色授权了该表单的该按钮 + for (Long roleId : roleIds) { + RoleFormButton config = + roleFormButtonService.getByRoleIdAndFormId(roleId, formId); + if (config != null && config.getButtonConfig() != null) { + List buttons = + JSON.parseArray(config.getButtonConfig(), + WidgetJsonButtonParser.ButtonInfo.class); + for (WidgetJsonButtonParser.ButtonInfo btn : buttons) { + if (buttonName.equals(btn.getName()) + && Boolean.TRUE.equals(btn.getEnabled())) { + return true; + } + } + } + } + } catch (Exception e) { + log.error("校验按钮权限时发生异常", e); + } + return false; + } +} diff --git a/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/service/impl/RoleFormButtonServiceImpl.java b/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/service/impl/RoleFormButtonServiceImpl.java new file mode 100644 index 0000000..d7af08a --- /dev/null +++ b/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/service/impl/RoleFormButtonServiceImpl.java @@ -0,0 +1,182 @@ +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.online.model.OnlineForm; +import apelet.common.online.service.OnlineFormService; +import apelet.common.sequence.wrapper.IdGeneratorWrapper; +import apelet.tenantadmin.tenant.dao.RoleFormButtonMapper; +import apelet.tenantadmin.tenant.dto.RoleFormButtonDto; +import apelet.tenantadmin.tenant.model.RoleFormButton; +import apelet.tenantadmin.tenant.service.IRoleFormButtonService; +import apelet.tenantadmin.tenant.util.WidgetJsonButtonParser; +import com.alibaba.fastjson.JSON; +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.*; + +/** + * 角色-表单按钮权限配置服务实现。 + * + * @author chenchuchuan + * @date 2026-07-17 + */ +@Service +@Slf4j +public class RoleFormButtonServiceImpl + extends BaseService + implements IRoleFormButtonService { + + @Autowired + private RoleFormButtonMapper mapper; + + @Autowired + private IdGeneratorWrapper idGenerator; + + @Autowired + private OnlineFormService onlineFormService; + + @Override + protected BaseDaoMapper mapper() { + return mapper; + } + + @Override + public List getListByFilter( + RoleFormButton filter, String orderBy) { + return mapper.getListByFilter(filter, orderBy); + } + + // ========== 核心:查询按钮配置VO ========== + @Override + public Map getButtonConfigVo(Long roleId, Long formId) { + Map result = new HashMap<>(); + result.put("roleId", roleId); + result.put("formId", formId); + + // 1. 获取 widgetJson,提取所有开启的按钮 + OnlineForm onlineForm = onlineFormService.getById(formId); + if (onlineForm == null) { + result.put("buttonList", Collections.emptyList()); + return result; + } + + List enabledButtons = + WidgetJsonButtonParser.extractEnabledButtons(onlineForm.getWidgetJson()); + + // 2. 查询已存储的配置 + RoleFormButton config = getByRoleIdAndFormId(roleId, formId); + + // 3. 解析已勾选的按钮名称集合 + Set checkedNames = new HashSet<>(); + if (config != null && config.getButtonConfig() != null) { + List savedButtons = + JSON.parseArray(config.getButtonConfig(), + WidgetJsonButtonParser.ButtonInfo.class); + for (WidgetJsonButtonParser.ButtonInfo btn : savedButtons) { + if (Boolean.TRUE.equals(btn.getEnabled())) { + checkedNames.add(btn.getName()); + } + } + } + + // 4. 合并:表单所有开启的按钮 + 是否勾选 + List> buttonList = new ArrayList<>(); + for (WidgetJsonButtonParser.ButtonInfo btn : enabledButtons) { + Map item = new HashMap<>(); + item.put("name", btn.getName()); + item.put("checked", checkedNames.contains(btn.getName())); + buttonList.add(item); + } + + result.put("id", config != null ? config.getId() : null); + result.put("buttonList", buttonList); + return result; + } + + // ========== 核心:批量保存按钮配置(事务) ========== + @Override + @Transactional(rollbackFor = Exception.class) + public CallResult batchSaveButtonConfig(List dtoList) { + for (RoleFormButtonDto dto : dtoList) { + CallResult result = this.saveButtonConfig(dto); + if (!result.isSuccess()) { + return result; + } + } + return CallResult.ok(); + } + + // ========== 核心:保存单条按钮配置(无独立事务,由外层统一管理) ========== + @Override + public CallResult saveButtonConfig(RoleFormButtonDto dto) { + // 1. 必填校验 + if (dto.getRoleId() == null) { + return CallResult.error("数据验证失败,角色ID不能为空!"); + } + if (dto.getFormId() == null) { + return CallResult.error("数据验证失败,表单ID不能为空!"); + } + + // 2. 构建 button_config JSON + List> configList = new ArrayList<>(); + if (dto.getButtonList() != null) { + for (RoleFormButtonDto.ButtonItem item : dto.getButtonList()) { + Map configItem = new HashMap<>(); + configItem.put("name", item.getName()); + configItem.put("enabled", Objects.nonNull(item.getChecked()) && item.getChecked()); + configList.add(configItem); + } + } + String buttonConfigJson = JSON.toJSONString(configList); + + // 3. 查询是否已存在配置(role_id + form_id 唯一) + RoleFormButton existing = + getByRoleIdAndFormId(dto.getRoleId(), dto.getFormId()); + + if (existing != null) { + // 更新 + existing.setButtonConfig(buttonConfigJson); + existing.setUpdateTime(new Date()); + this.updateById(existing); + } else { + // 新增 + RoleFormButton entity = new RoleFormButton(); + entity.setRoleId(dto.getRoleId()); + entity.setFormId(dto.getFormId()); + entity.setButtonConfig(buttonConfigJson); + entity.setId(idGenerator.nextLongId()); + this.save(entity); + } + + return CallResult.ok(); + } + + @Override + public List listByRoleId(Long roleId) { + LambdaQueryWrapper qw = new LambdaQueryWrapper<>(); + qw.eq(RoleFormButton::getRoleId, roleId); + return this.list(qw); + } + + @Override + public RoleFormButton getByRoleIdAndFormId(Long roleId, Long formId) { + LambdaQueryWrapper qw = new LambdaQueryWrapper<>(); + qw.eq(RoleFormButton::getRoleId, roleId) + .eq(RoleFormButton::getFormId, formId); + return this.getOne(qw); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void removeByRoleId(Long roleId) { + LambdaQueryWrapper qw = new LambdaQueryWrapper<>(); + qw.eq(RoleFormButton::getRoleId, roleId); + this.remove(qw); + } +} diff --git a/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/util/WidgetJsonButtonParser.java b/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/util/WidgetJsonButtonParser.java new file mode 100644 index 0000000..8343200 --- /dev/null +++ b/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/util/WidgetJsonButtonParser.java @@ -0,0 +1,93 @@ +package apelet.tenantadmin.tenant.util; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * widgetJson 按钮解析工具类。 + * 从在线表单的 widgetJson 中提取所有 operationList 下的按钮。 + * + * @author chenchuchuan + * @date 2026-07-17 + */ +@Slf4j +public class WidgetJsonButtonParser { + + /** + * 按钮信息DTO(内部类,轻量)。 + */ + @Data + @AllArgsConstructor + @NoArgsConstructor + public static class ButtonInfo { + /** 按钮名称 */ + private String name; + /** 是否在设计器中开启 */ + private Boolean enabled; + } + + /** + * 从 widgetJson 中提取所有开启的按钮(去重,按name)。 + * + * @param widgetJson 在线表单的 widget_json 字段值。 + * @return 按钮列表(只包含 enabled=true 的按钮,按 name 去重)。 + */ + public static List extractEnabledButtons(String widgetJson) { + List allButtons = extractAllButtons(widgetJson); + List result = new ArrayList<>(); + Set seen = new HashSet<>(); + for (ButtonInfo btn : allButtons) { + if (Boolean.TRUE.equals(btn.getEnabled()) && seen.add(btn.getName())) { + result.add(btn); + } + } + return result; + } + + /** + * 从 widgetJson 中提取所有按钮(不去重,不过滤)。 + * 仅提取 pc.operationList 和 mobile.operationList 两个顶层数组, + * 不递归 tableWidget、widgetList、childWidgetList 等子节点下的 operationList。 + * + * @param widgetJson 在线表单的 widget_json 字段值。 + * @return 全部按钮列表。 + */ + public static List extractAllButtons(String widgetJson) { + List result = new ArrayList<>(); + if (widgetJson == null || widgetJson.isEmpty()) { + return result; + } + try { + JSONObject root = JSON.parseObject(widgetJson); + // 仅取 pc 和 mobile 两端的顶层 operationList + for (String device : new String[]{"pc", "mobile"}) { + JSONObject deviceJson = root.getJSONObject(device); + if (deviceJson == null) continue; + JSONArray operationList = deviceJson.getJSONArray("operationList"); + if (operationList != null) { + for (int i = 0; i < operationList.size(); i++) { + JSONObject btn = operationList.getJSONObject(i); + String name = btn.getString("name"); + Boolean enabled = btn.getBoolean("enabled"); + if (name != null) { + result.add(new ButtonInfo(name, enabled != null ? enabled : false)); + } + } + } + } + } catch (Exception e) { + log.error("解析 widgetJson 失败", e); + } + return result; + } +} diff --git a/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/vo/RoleFormButtonVo.java b/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/vo/RoleFormButtonVo.java new file mode 100644 index 0000000..2c29505 --- /dev/null +++ b/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/vo/RoleFormButtonVo.java @@ -0,0 +1,17 @@ +package apelet.tenantadmin.tenant.vo; + +import apelet.tenantadmin.tenant.model.RoleFormButton; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 角色-表单按钮权限配置VO对象。 + * + * @author chenchuchuan + * @date 2026-07-17 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class RoleFormButtonVo extends RoleFormButton { + private static final long serialVersionUID = 1L; +} diff --git a/common/common-online/src/main/java/apelet/common/online/service/FormButtonPermissionChecker.java b/common/common-online/src/main/java/apelet/common/online/service/FormButtonPermissionChecker.java new file mode 100644 index 0000000..342827f --- /dev/null +++ b/common/common-online/src/main/java/apelet/common/online/service/FormButtonPermissionChecker.java @@ -0,0 +1,20 @@ +package apelet.common.online.service; + +/** + * 在线表单按钮权限检查器接口。 + * 由 tenant-admin 模块实现并注册为 Spring Bean。 + * + * @author chenchuchuan + * @date 2026-07-17 + */ +public interface FormButtonPermissionChecker { + + /** + * 检查当前用户是否有指定表单上指定按钮的操作权限。 + * + * @param formId 在线表单ID (zz_online_form.form_id)。 + * @param buttonName 按钮名称(对应 operationList 中的 name 字段)。 + * @return true-有权限,false-无权限。 + */ + boolean hasPermission(Long formId, String buttonName); +}