20251204,职级权限,开发实践分享

1、所遇问题&需求

一个职位的树结构,根节点为公司,下边分为部门,取某个子节点下,勾选的职位集合(勾选上级,意味着下级也有权限,需要返回)

比如:

知年公司

销售

运营

华北

华南

华东

江苏

南京

上海

检测

技术

车商基本信息

城市:职位树(包括下级)对应的城市列表

市场:职位树(包括下级)对应的城市,过滤出市场(有城市属性,t_car_market)列表

车商归属信息(培训师/运维职位城市)

大区:职位树(包括下级)的大区

小区:职位树(包括下级)的小区

城市:职位树(包括下级)对应的城市列表

培训师、运维:职位树(包括下级)关联的人员列表,按照角色过滤

2、如何实现

  • 获取该产品运营负责人下的全部节点ID,为集合A
  • 根据用户,获取用户关联的职位(可以一个或多个,也可以是其他其他部门的节点)。集合B
  • 找到B集合里边,全部子节点。记录为集合C
  • 集合A和集合C,相交。即在部门小有权限的职位树。集合D
  • 集合D中,指定层级为大区、小区
  • 集合D中,会关联城市,获取城市列表
  • 集合D中,会关联人员,按照角色进行过滤。获取到人员列表
  • 在城市列表的基础上,根据城市查询市场
java 复制代码
/**
 * @author QUAN XIN
 * 新的职级相关接口
 * @date 2025/12/3 13:36
 */
public interface OwnPositionV2Service {

    /**
     * 获取全部职级ID。(仅培训系统)
     * 即产品运营负责人节点下
     * @return
     */
    List<Long> getTrainer();

    /**
     * 获取全部职级列表。(仅培训系统)
     * 即产品运营负责人节点下,全部职位信息
     * @return
     */
    List<OwnPositionVO> getTrainerAllPositionIds();

    /**
     * 获取用户有权限的职级。(含全部子节点、仅培训系统)
     * @param ownUserId
     * @return
     */
    List<Long> getSubTreeByUser(Long ownUserId);

    /**
     * 获取城市id列表(仅培训系统)
     * @param ownUserId
     * @return
     */
    List<Long> getCityIds(Long ownUserId);

    /**
     * 获取城市列表。(仅培训系统)
     * @param ownUserId
     * @return
     */
    List<CommonSelectVO> getCityList(Long ownUserId);

    /**
     * 获取大区列表。(仅培训系统)
     * @param ownUserId
     * @return
     */
    List<OwnPositionVO> getAreaList(Long ownUserId);

    /**
     * 获取小区列表(仅培训系统)
     * @param ownUserId
     * @return
     */
    List<OwnPositionVO> getSmallAreaList(Long ownUserId);

    /**
     * 获取市场列表(仅培训系统)
     * @param ownUserId
     * @return
     */
    List<CommonSelectVO> getMarketList(Long ownUserId);

    /**
     * 获取用户列表(仅培训系统)
     * 职位树(包括下级)关联的人员列表,按照角色过滤
     * @param ownUserId
     * @param roleId
     * @return
     */
    List<CommonSelectVO> getOwnUserList(Long ownUserId, Integer roleId);

}

递归查询getRecursionIds,一次自循环,一个根据父节点获取全部子节点getSubTreeByParent。

而根据父节点获取子节点,一次是获取集合A;一次是获取集合C;这两处,都走了缓存来减少跟数据库的交互。如下

java 复制代码
@Override
    public List<Long> getTrainer() {
        String key = TRAINER_SYS_REDIS_KEY + TRAINER_CLASS_REDIS_KEY + "getTrainer";
        List<Long> subTree = RedisClient.get(key, () -> getTrainerAct(),
                RedisClient.hour(2));
        return subTree;
    }
java 复制代码
  @Override
    public List<Long> getSubTreeByUser(Long ownUserId) {
        String key = TRAINER_SYS_REDIS_KEY + TRAINER_CLASS_REDIS_KEY + "getSubTreeByUser." + ownUserId;
        List<Long> filterTrainer = RedisClient.get(key, () -> getSubTreeByUserAct(ownUserId),
                RedisClient.hour(2));
        return filterTrainer;
    }

3、效果如何

4、优化、建议、思考

形成文档,利人利己

递归取子节点,总不太好

是否可以通过设计上来优化,比如冗余一个字段,是path的路径。直接关联取

相关推荐
代码什么用7 小时前
Spring基础使用
java·后端·spring
Su米苏8 小时前
Spring AI 中MCP 与普通 @Tool的区别
java·人工智能·spring
码云数智-园园8 小时前
unique_ptr 还是 shared_ptr?C++ 智能指针选型与内存泄漏实战分析
java·开发语言
老板一杯拿铁8 小时前
Java 异常体系详解:从字节码原理到最佳实践
java
蜗牛互联网8 小时前
Java 17 HttpClient调用文件转写API的超时与失败回退
java·人工智能·后端
禾小西9 小时前
07丨Redis 哨兵机制:主库故障后,如何恢复服务?
java·开发语言·redis
我不是阵雨9 小时前
JDK 21虚拟线程Pinning陷阱:一文拔钉解困
java·开发语言
小卡车5559 小时前
java反射、自定义注解的应用(自定义分页)
java
BLUcoding10 小时前
接口服务公网超时排查记录:SecureRandom 阻塞问题分析与解决
java·linux·springboot·aes·securerandom
yuniko-n10 小时前
【JUC】Lock 和 synchronzied 锁
java