动态页面在前端自定义之后,目前是没办法通过权限去控制路由页面的权限的,本篇文章将介绍如何解决这个问题。
阅读本篇文章之前,应已经实现自定义页面渲染动态视图。参考文章:自定义视图内部渲染动态视图
实现思路:
- 通过自定义页面里设计的组件api名字,获取配置的路由页面名字。
- 解析路由页面包含的所有动作,拼接权限节点。
- 将路由页面的权限节点,拼到自定义视图所在菜单的权限管理上。
效果,路由页面的动作出现在自定义视图所在的菜单权限节点上
代码示例
package pro.shushi.pamirs.top.core.auth;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import pro.shushi.pamirs.auth.api.entity.node.ActionPermissionNode;
import pro.shushi.pamirs.auth.api.entity.node.PermissionNode;
import pro.shushi.pamirs.auth.api.extend.load.PermissionNodeLoadExtendApi;
import pro.shushi.pamirs.auth.api.loader.visitor.AuthCompileContext;
import pro.shushi.pamirs.auth.api.loader.visitor.AuthCompileVisitor;
import pro.shushi.pamirs.auth.api.loader.visitor.DslParser;
import pro.shushi.pamirs.auth.api.pmodel.AuthResourceAuthorization;
import pro.shushi.pamirs.auth.api.utils.AuthAuthorizationHelper;
import pro.shushi.pamirs.boot.base.model.Menu;
import pro.shushi.pamirs.boot.base.model.View;
import pro.shushi.pamirs.boot.base.model.ViewAction;
import pro.shushi.pamirs.boot.base.ux.model.UIView;
import pro.shushi.pamirs.boot.base.ux.model.UIWidget;
import pro.shushi.pamirs.boot.base.ux.model.view.UIField;
import pro.shushi.pamirs.boot.web.loader.path.AccessResourceInfo;
import pro.shushi.pamirs.boot.web.loader.path.ResourcePath;
import pro.shushi.pamirs.boot.web.manager.MetaCacheManager;
import pro.shushi.pamirs.meta.annotation.fun.extern.Slf4j;
import pro.shushi.pamirs.meta.common.spi.SPI;
import pro.shushi.pamirs.top.api.TopModule;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@Component
@Order(88)
@SPI.Service
@Slf4j
public class MyTestNodeLoadExtend implements PermissionNodeLoadExtendApi {
@Autowired
protected MetaCacheManager metaCacheManager;
@Override
public List<PermissionNode> buildNextPermissions(PermissionNode selected, List<PermissionNode> nodes) {
// 动态页面所属的菜单name
List<String> menuNames = new ArrayList<>();
menuNames.add("uiMenu3c094a75bd88461ba0ad780825069b32");
// 自定义组件api名称
List<String> apiNames = new ArrayList<>();
apiNames.add("dynamicView");
List<ActionPermissionNode> newNodes = new ArrayList<>();
for (String menuName : menuNames) {
List<ActionPermissionNode> actionPermissionNodes = buildActionPermissionNodes(selected, menuName, apiNames);
if (CollectionUtils.isNotEmpty(actionPermissionNodes)) {
newNodes.addAll(actionPermissionNodes);
}
}
nodes.addAll(newNodes);
return nodes;
}
private List<ActionPermissionNode> buildActionPermissionNodes(PermissionNode selected, String menuName, List<String> apiNames) {
String path = ResourcePath.generatorPath(TopModule.MODULE_MODULE, menuName);
if (!path.equals(selected.getPath())) {
return null;
}
Menu menu = metaCacheManager.fetchCloneMenus(TopModule.MODULE_MODULE).stream()
.filter(v -> v.getName().equals(menuName))
.findFirst()
.orElse(null);
if (menu == null) {
return null;
}
menu.fieldQuery(Menu::getViewAction);
View mainView = fetchMainView(menu.getViewAction());
if (mainView == null) {
return null;
}
UIView parser = new UIView();
try {
parser = DslParser.parser(mainView);
} catch (Throwable e) {
log.error("compile view error. model: {}, name: {}", mainView.getModel(), mainView.getName(), e);
}
List<ActionPermissionNode> dyNodes = new ArrayList<>();
for (String apiName : apiNames) {
List<ActionPermissionNode> viewPermissionNode = getViewPermissionNode(selected, parser, menu, apiName);
if (CollectionUtils.isNotEmpty(viewPermissionNode)) {
dyNodes.addAll(viewPermissionNode);
}
}
return dyNodes;
}
private List<ActionPermissionNode> getViewPermissionNode(PermissionNode selected, UIView parser, Menu menu, String apiName) {
String viewName = findLabelByApiName(parser.getWidgets(), apiName);
View view = new View().setName(viewName).queryOne();
if (view == null) {
log.info("incorrect view name, viewName: {}", viewName);
return null;
}
Long groupId = selected.getGroupId();
Map<String, AuthResourceAuthorization> authorizationMap = null;
if (groupId != null) {
authorizationMap = AuthAuthorizationHelper.fetchActionAuthorizationMap(groupId);
}
return compileByMenu(view, menu, menu.getViewAction(), authorizationMap);
}
private View fetchMainView(ViewAction viewAction) {
String resModel = Optional.ofNullable(viewAction.getResModel()).orElse(viewAction.getModel());
View resView = viewAction.getResView();
View mainView;
if (resView == null || resView.getTemplate() == null) {
mainView = metaCacheManager.fetchView(resModel, viewAction.getResViewName(), viewAction.getViewType(), false);
} else {
mainView = resView;
}
return mainView;
}
private List<ActionPermissionNode> compileByMenu(View mainView, Menu menu, ViewAction viewAction, Map<String, AuthResourceAuthorization> authorizationMap) {
AccessResourceInfo info = new AccessResourceInfo();
info.setModule(menu.getModule());
info.setModel(viewAction.getModel());
info.setActionName(viewAction.getName());
info.setMenu(menu.getName());
info.setViewAction(viewAction);
return compile(info, mainView, authorizationMap);
}
private List<ActionPermissionNode> compile(AccessResourceInfo info, View mainView, Map<String, AuthResourceAuthorization> authorizationMap) {
if (log.isDebugEnabled()) {
log.debug("auth compile view. model: {}, name: {}", mainView.getModel(), mainView.getName());
}
AuthCompileContext context = new AuthCompileContext(info, authorizationMap);
AuthCompileVisitor visitor = new AuthCompileVisitor(context);
try {
DslParser.visit(mainView, visitor);
} catch (Throwable e) {
log.error("compile view error. model: {}, name: {}", mainView.getModel(), mainView.getName(), e);
}
return visitor.getNodes();
}
private String findLabelByApiName(List<? extends UIWidget> elements, String apiName) {
if (elements == null || elements.isEmpty()) {
return null;
}
for (UIWidget element : elements) {
// 判断是否是指定组件。
if (element instanceof UIField) {
UIField field = (UIField) element;
if (apiName.equals(field.getWidget())) {
// 这里获取该组件的标题作为视图名字的配置,如业务有不同请自行修改。
return field.getLabel();
}
}
List<? extends UIWidget> subElements = element.getWidgets();
if (subElements != null && !subElements.isEmpty()) {
String label = findLabelByApiName(subElements, apiName);
if (label != null) {
return label;
}
}
}
return null;
}
}
Oinone社区 作者:yexiu原创文章,如若转载,请注明出处:https://doc.oinone.top/dai-ma-shi-jian/21714.html
访问Oinone官网:https://www.oinone.top获取数式Oinone低代码应用平台体验