自定义用户中心菜单

使用扩展点实现用户中心菜单替换

1. 工程中引起pamirs-user-api

<dependency>
    <groupId>pro.shushi.pamirs.core</groupId>
    <artifactId>pamirs-user-api</artifactId>
</dependency>

2. 实现TopBarUserBlockAction的后置扩展

  • 实现HookAfter后置扩展接口
  • @Hook(model = {TopBarUserBlock.MODEL_MODEL}, fun = {"construct"})添加Hook注解注明是TopBarUserBlock模型的construct函数的后置扩展。

增加用户中心菜单

@Component
@Order(1)
@SPI.Service
public class MyTopBarActionExt implements TopBarActionExtendApi {

    public void edit(List<TopBarAction> list) {
        list.add(new TopBarAction("top_demo", "top.Teacher", "uiView9a0caf1d574a42c9847a057a0c4a4ad1", ActionTypeEnum.VIEW, 1)
                .setDisplayName("商品管理")
                .setIcon("oinone-gongzuotai")
        );
    }

}

实现效果

自定义用户中心菜单

替换原有的用户中心菜单

  1. 替换原有的菜单跳转

    @Component
    public class DemoTopBarUserBlockDataHookAfter implements HookAfter {
    
    @Override
    @Hook(model = {TopBarUserBlock.MODEL_MODEL}, fun = {"construct"})
    public Object run(Function function, Object ret) {
        if (ret == null) {
            return null;
        }
        TopBarUserBlock result = null;
        if (ret instanceof Object[]) {
            Object[] rets = (Object[]) ((Object[]) ret);
            if (rets.length == 1) {
                result = (TopBarUserBlock) rets[0];
              //例:替换用户中心:修改密码菜单
              //使用name和model查询出模型的ViewAction替换修改密码ViewAction
                ViewAction demoViewAction = PamirsSession.getContext().getExtendCache(ActionCacheApi.class).get(Dog.MODEL_MODEL, "changePassword");
                //设置菜单的icon
                Map<String, Object> attributes = Optional.ofNullable(demoViewAction.getAttributes()).orElse(new HashMap<>());
                attributes.put("icon", "oinone-xiugaimima");
                demoViewAction.setAttributes(attributes);
                //UserViewAction第0个是修改密码ViewAction,使用自定义的ViewAction就可以实现替换
                result.getUserViewAction().set(0, demoViewAction);
            }
        } else {
            result = (TopBarUserBlock) ret;
        }
        return result;
    }
    }
  2. 使用@UxRouteButton方式新增ViewAction,更多新增Action方式详见:Action的类型

    @Model.model(Dog.MODEL_MODEL)
    @Component
    @UxRouteButton(
        action = @UxAction(name = "changePassword", displayName = "修改密码"),
        value = @UxRoute(model = Dog.MODEL_MODEL, openType = ActionTargetEnum.DIALOG))
    public class DogAction {
    }

替换原有的个人设置头像跳转

  1. 修改点击头像绑定的跳转逻辑

    @Order(10)
    @Component
    @SPI.Service
    public class DemoTopBarUserBlockDataApi implements TopBarUserBlockDataApi {
    
    @Override
    public TopBarUserBlock extendData(TopBarUserBlock data) {
        //例如增加一个菜单, PamirsDemo.MODEL_MODEL: 模型。 MenuuiMenu31f22466735a4abe8e0544b428ed88ac:viewAction的name。
        Action demoViewAction = PamirsSession.getContext().getExtendCache(ActionCacheApi.class).get(PamirsDemo.MODEL_MODEL, "MenuuiMenu31f22466735a4abe8e0544b428ed88ac");
        if (demoViewAction != null){
            AccessResourceInfo info = PageLoadHelper.generatorAccessResourceInfo(TopModule.MODULE_MODULE, demoViewAction);
            AccessResourceInfoSession.setInfo(info);
            String path = ResourcePath.generatorPath(demoViewAction.getModel(), demoViewAction.getName());
            demoViewAction.setSessionPath(path);
            data.setUserAvatarAction(demoViewAction);
        }
        return data;
    }
    }
  2. 添加权限节点,用于控制权限。

    @Component
    @Order(88)
    @SPI.Service
    public class MyTestNodeLoadExtend implements PermissionNodeLoadExtendApi {
    
    @Override
    public List<PermissionNode> buildRootPermissions(PermissionLoadContext loadContext, List<PermissionNode> nodes) {
        PermissionNode root = AuthNodeHelper.createNodeWithTranslate("CustomNode", "自定义节点");
        List<PermissionNode> newNodes = new ArrayList<>();
        newNodes.add(root);
        Action demoViewAction = PamirsSession.getContext().getExtendCache(ActionCacheApi.class).get(PamirsDemo.MODEL_MODEL, "MenuuiMenu31f22466735a4abe8e0544b428ed88ac");
    
        if (demoViewAction != null) {
            //将该Action放入权限树
            //权限鉴权的path路径是根据【cacheAction.getModel() + cacheAction.getName()】拼接的。和MODULE没有关系,这里MODULE可以自定义。
            AuthNodeHelper.addNode(newNodes, root, AuthNodeHelper.createActionNode(TopModule.MODULE_MODULE, demoViewAction, root));
        }
        nodes.add(0, root);
        return newNodes;
    }
    }
  3. 管理中心控制个人设置头像权限
    自定义用户中心菜单

Oinone社区 作者:yexiu原创文章,如若转载,请注明出处:https://doc.oinone.top/backend/14399.html

访问Oinone官网:https://www.oinone.top获取数式Oinone低代码应用平台体验

Like (0)
yexiu's avataryexiu数式员工
Previous 2024年7月2日 pm7:42
Next 2024年7月4日 pm10:10

相关推荐

  • OSS(CDN)配置和文件系统的一些操作

    目前Oinone支持的OSS类型 类型 服务 OSS 阿里云OSS UPYUN 又拍云 MINIO MinIO HUAWEI_OBS 华为云OBS LOCAL 本地NGINX文件存储 TENCENT_COS 腾讯云COS CTYUN_ZOS 天翼云ZOS OSS通用yaml配置 cdn: oss: name: # 名称 type: # 类型 bucket: uploadUrl: # 上传URL downloadUrl: # 下载URL accessKeyId: accessKeySecret: mainDir: # 主目录 validTime: 3600000 timeout: 600000 active: true referer: localFolderUrl: others: [key]: name: # 名称 type: # 类型 bucket: uploadUrl: # 上传URL downloadUrl: # 下载URL accessKeyId: accessKeySecret: mainDir: # 主目录 validTime: 3600000 timeout: 600000 active: true referer: localFolderUrl: PS:others中使用自定义key来指定OSS服务进行文件上传/下载功能。上传/下载必须匹配,否则无法正常使用。 OSS配置示例 阿里云OSS cdn: oss: name: 阿里云 type: OSS bucket: pamirs(根据实际情况修改) uploadUrl: oss-cn-hangzhou.aliyuncs.com downloadUrl: oss-cn-hangzhou.aliyuncs.com accessKeyId: 你的accessKeyId accessKeySecret: 你的accessKeySecret # 根据实际情况修改 mainDir: upload/ validTime: 3600000 timeout: 600000 active: true imageResizeParameter: referer: 华为云OBS cdn: oss: name: 华为云 type: HUAWEI_OBS bucket: pamirs(根据实际情况修改) uploadUrl: obs.cn-east-2.myhuaweicloud.com downloadUrl: obs.cn-east-2.myhuaweicloud.com accessKeyId: 你的accessKeyId accessKeySecret: 你的accessKeySecret # 根据实际情况修改 mainDir: upload/ validTime: 3600000 timeout: 600000 active: true allowedOrigin: http://192.168.95.31:8888,https://xxxx.xxxxx.com referer: 华为云OBS需要在启动工程增加以下依赖 <okhttp3.version>4.9.3</okhttp3.version> <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>${okhttp3.version}</version> </dependency> 注意事项华为云OBS的防盗链配置,仅允许携带特定referer的才可以,而excel导入后端处理的逻辑匿名读的时候是不带referer的,所以会被拒绝 MINIO 文件系统,mino的配置: cdn: oss: name: minio type: MINIO bucket: pamirs(根据实际情况修改) uploadUrl: http://192.168.243.6:32190(根据实际情况修改) downloadUrl: http://192.168.243.6:9000(根据实际情况修改) accessKeyId: 你的accessKeyId accessKeySecret: 你的accessKeySecret # 根据实际情况修改 mainDir: upload/ validTime: 3600000 timeout: 600000 active: true referer: localFolderUrl: MINIO无公网访问地址下OSS的配置方式: https://doc.oinone.top/yun-wei-shi-jian/7112.html 又拍云 cdn: oss: name: 又拍云…

    后端 2023年11月1日
    2.2K00
  • 【OpenGauss】后端部署使用OpenGauss高斯数据库

    Gauss数据库配置 适配版本 4.7.8.3之后的版本 配置步骤 Maven配置 去华为官网下周驱动包:gsjdbc4.jar;https://support.huaweicloud.com/mgtg-dws/dws_01_0032.html <dependency> <groupId>org.postgresql</groupId> <artifactId>gsjdbc</artifactId> <version>4</version> <scope>system</scope> <!– 下面两种方式都可以–> <systemPath>${pom.basedir}/libs/gsjdbc4.jar</systemPath> <!–<systemPath>/Users/wangxian/java-tools/guassdb/gsjdbc4.jar</systemPath>–> </dependency> 导入 scope 为 system 的包,spring 编译插件需要增加 includeSystemScope: true 配置。 <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <includeSystemScope>true</includeSystemScope> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> JDBC连接配置 pamirs: datasource: pamirs: type: com.alibaba.druid.pool.DruidDataSource driverClassName: org.postgresql.Driver url: jdbc:postgresql://127.0.0.1:5432/pamirs?currentSchema=demo username: XXXXXX password: XXXXXX initialSize: 5 maxActive: 200 minIdle: 5 maxWait: 60000 timeBetweenEvictionRunsMillis: 60000 testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: true asyncInit: true base: type: com.alibaba.druid.pool.DruidDataSource driverClassName: org.postgresql.Driver url: jdbc:postgresql://127.0.0.1:5432/pamirs?currentSchema=demo_base username: XXXXXX password: XXXXXX initialSize: 5 maxActive: 200 minIdle: 5 maxWait: 60000 timeBetweenEvictionRunsMillis: 60000 testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: true asyncInit: true 连接url配置 点击查看官方文档:官方文档 url格式 jdbc:postgresql://${host}:${port}/${database}?currentSchema=${schema} 在pamirs连接配置时,${database}和${schema}必须完整配置,不可缺省。 其他连接参数如需配置,可自行查阅相关资料进行调优。 方言配置 pamirs方言配置 pamirs: dialect: ds: base: type: GaussDB version: 5 majorVersion: 5.0.1 pamirs: type: GaussDB version: 5 majorVersion: 5.0.1 数据库版本 type version majorVersion 5.x GaussDB 5 5.0.1 PS:由于方言开发环境为5.0.1版本,其他类似版本(5.x)原则上不会出现太大差异,如出现其他版本无法正常支持的,可在文档下方留言。 schedule方言配置 pamirs: event: enabled: true schedule: enabled: true dialect: type: GaussDB version: 5 major-version: 5.0.1 type version majorVersion GaussDB 5 5.0.1 PS:由于schedule的方言在多个版本中并无明显差异,目前仅提供一种方言配置。 其他配置 逻辑删除的值配置 pamirs: mapper: global: table-info: logic-delete-value: (EXTRACT(epoch FROM CURRENT_TIMESTAMP) * 1000000 + EXTRACT(MICROSECONDS FROM CURRENT_TIMESTAMP))::bigint Gauss数据库用户初始化及授权 — init root…

    2024年3月27日
    2.8K00
  • 自定义数据权限拦截处理

    业务场景 公司给员工对哪些模块有访问权限,这个时候就需要在员工访问模块表的时候做数据过滤, 解决方案 我们可以通过平台提供的数据过滤占位符解决这个问题,新建一条数据行权限,过滤语句条件是占位符,再编写占位符的解析逻辑 1.初始化权限基础数据 package pro.shushi.pamirs.demo.core.init; import com.google.common.collect.Lists; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import pro.shushi.pamirs.auth.api.constants.AuthConstants; import pro.shushi.pamirs.auth.api.enmu.AuthGroupTypeEnum; import pro.shushi.pamirs.auth.api.enmu.PermissionDataSourceEnum; import pro.shushi.pamirs.auth.api.enmu.PermissionTypeEnum; import pro.shushi.pamirs.auth.api.model.AuthGroup; import pro.shushi.pamirs.auth.api.model.AuthRole; import pro.shushi.pamirs.auth.api.model.ResourcePermission; import pro.shushi.pamirs.boot.base.model.UeModule; import pro.shushi.pamirs.boot.common.api.command.AppLifecycleCommand; import pro.shushi.pamirs.boot.common.api.init.InstallDataInit; import pro.shushi.pamirs.boot.common.api.init.UpgradeDataInit; import pro.shushi.pamirs.demo.api.DemoModule; import pro.shushi.pamirs.demo.core.placeholder.EmployeeModulePlaceholder; import pro.shushi.pamirs.framework.common.utils.ObjectUtils; import pro.shushi.pamirs.meta.annotation.fun.extern.Slf4j; import pro.shushi.pamirs.meta.domain.module.ModuleDefinition; import java.util.Collections; import java.util.List; @Slf4j @Component @Order(0) public class DemoModuleBizInit implements InstallDataInit, UpgradeDataInit { @Override public List<String> modules() { return Collections.singletonList(DemoModule.MODULE_MODULE); } @Override public int priority() { return 0; } @Override public boolean init(AppLifecycleCommand command, String version) { this.initAuth(); return true; } @Override public boolean upgrade(AppLifecycleCommand command, String version, String existVersion) { this.initAuth(); return true; } private void initAuth() { AuthGroup authGroup = new AuthGroup(); authGroup.setName("测试权限组") .setDisplayName("测试权限组") .setType(AuthGroupTypeEnum.RUNTIME) .setActive(true); authGroup.createOrUpdate(); AuthRole authRole = new AuthRole(); authRole.setCode("TEST_ROLE_1") .setName("测试角色") .setRoleTypeCode(AuthConstants.ROLE_SYSTEM_TYPE_CODE) .setPermissionDataSource(PermissionDataSourceEnum.CUSTOM) .setActive(true); authRole.createOrUpdate(); authRole.setGroups(Lists.newArrayList(authGroup)); authRole.fieldSave(AuthRole::getGroups); ResourcePermission authPermission = new ResourcePermission(); authPermission.setName("测试模块权限过滤") .setDomainExp(EmployeeModulePlaceholder.PLACEHOLDER) .setModel(ModuleDefinition.MODEL_MODEL) .setPermRead(true) .setPermRun(true) .setPermissionType(PermissionTypeEnum.ROW) .setPermissionDataSource(PermissionDataSourceEnum.CUSTOM) .setCanShow(true) .setActive(true); ResourcePermission authPermission2 = ObjectUtils.clone(authPermission); authPermission2.setName("测试ue模块权限过滤").setModel(UeModule.MODEL_MODEL); authGroup.setPermissions(Lists.newArrayList(authPermission, authPermission2)); authGroup.fieldSave(AuthGroup::getPermissions); } } 这里演示的module表比较特殊,需要同时设置ModuleDefinition和UeModule这2个模型做数据过滤 2.编写占位符拦截替换逻辑 package pro.shushi.pamirs.demo.core.placeholder; import org.springframework.stereotype.Component; import pro.shushi.pamirs.user.api.AbstractPlaceHolderParser; @Component public class EmployeeModulePlaceholder extends AbstractPlaceHolderParser { public static final String PLACEHOLDER = "${employeeModulePlaceholder}"; protected String value() { // TODO…

    2023年11月24日
    1.3K00
  • Oinone设计器部署参数说明

    概述 Oinone提供两种设计器部署方式,合作伙伴可以自行选择适合自己的部署方式。 Docker配置参数 环境变量 ARG_ENV:指定spring.profiles.active(默认:dev) ARG_LIFECYCLE:指定-Plifecycle(默认:INSTALL) JVM_OPTIONS:jvm参数 PROGRAM_ARGS:程序参数 JVM_OPTIONS和PROGRAM_ARGS参数说明 java [JVM_OPTIONS?] -jar boot.jar [PROGRAM_ARGS?] 端口说明 PS:以下为目前设计器镜像的全部端口,不同类型镜像的端口由于内置服务不同,使用的端口数量不同,但端口号是完全一致的。 80:前端服务端口(设计器访问入口) 8091:后端服务端口 8093:后端EIP服务端口 20880:Dubbo端口 3306:内置MySQL端口 2181:内置Zookeeper端口 6379:内置Redis端口 9876/10991:内置RocketMQ端口 9999:内置本地OSS默认端口 挂载目录说明(挂载虚拟卷) /opt/pamirs为镜像的工作目录,所有挂载目录均在该目录下。 /opt/pamirs/ext:应用配置文件目录;包含application.yml、logback.xml、license.lic等配置文件 /opt/pamirs/nginx/vhost:Nginx配置文件目录 /opt/pamirs/logs:后端服务日志目录 /opt/mq/conf/broker.conf:RocketMQ的broker配置文件 /opt/pamirs/outlib:非设计器内置包的外部加载目录(外部库),可以添加任何jar包集成到设计器中。 /opt/pamirs/dist:前端服务目录 /opt/pamirs/static:前端静态文件目录;LOCAL类型的OSS上传和下载目录; docker run启动常用参数 -e:指定环境变量 -p:指定端口映射 -v:指定挂载目录(挂载虚拟卷) docker run [OPTIONS] IMAGE [COMMAND] [ARG…] docker compose启动常用配置 services: container: image: $IMAGE container_name: $CONTAINER_NAME restart: always # docker run -e environment: KEY1: VALUE1 KEY2: VALUE2 … # docker run -p ports: – $machinePort1:$containerPort1 – $machinePort2:$containerPort2 … # docker run -v volumes: – $machinePath1:$containerPath1 – $machinePath2:$containerPath2 … docker compose常用命令 # 使用docker-compose.yaml启动 docker compose up -d # 使用docker-compose.yaml停止并删除容器 docker compose down -v # 指定配置文件启动 docker compose -f config.yaml up -d # 指定配置文件停止并删除容器 docker compose -f config.yaml down -v JAR包方式启动 下载Oinone专属启动器 oinone-boot-starter.zip 启动命令变化 # 原命令 java -jar boot.jar # 变更后命令 boot-starter java -jar boot.jar PS:更多命令可查看后端无代码设计器Jar包启动方法

    2024年11月4日
    1.7K00

Leave a Reply

Please Login to Comment