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的路径。直接关联取