层级变动权限问题:层级发布后变动“再发布”时,权限同步

This commit is contained in:
s2042968 2025-02-18 14:09:35 +08:00
parent c0995be7e7
commit 957769f2d1
9 changed files with 275 additions and 9 deletions

View File

@ -4,6 +4,7 @@ import com.electromagnetic.industry.software.common.resp.ElectromagneticResult;
import com.electromagnetic.industry.software.manage.pojo.req.FolderResortDTO; import com.electromagnetic.industry.software.manage.pojo.req.FolderResortDTO;
import com.electromagnetic.industry.software.manage.pojo.req.QueryPublishStatus; import com.electromagnetic.industry.software.manage.pojo.req.QueryPublishStatus;
import com.electromagnetic.industry.software.manage.service.EdPrjService; import com.electromagnetic.industry.software.manage.service.EdPrjService;
import com.electromagnetic.industry.software.manage.service.PermissionService;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
@ -19,6 +20,8 @@ public class ProjectController {
@Resource @Resource
private EdPrjService edPrjService; private EdPrjService edPrjService;
@Resource
private PermissionService permissionService;
@RequestMapping("create") @RequestMapping("create")
public ElectromagneticResult<?> create(@RequestParam String prjName) { public ElectromagneticResult<?> create(@RequestParam String prjName) {
@ -62,7 +65,10 @@ public class ProjectController {
@RequestMapping("publish") @RequestMapping("publish")
public ElectromagneticResult<?> publish(@RequestParam String prjId) { public ElectromagneticResult<?> publish(@RequestParam String prjId) {
return edPrjService.publish(prjId); ElectromagneticResult<?> result = edPrjService.publish(prjId);
// 更新项目权限
permissionService.syncPermissions(prjId);
return result;
} }
@RequestMapping("follow") @RequestMapping("follow")

View File

@ -2,9 +2,14 @@ package com.electromagnetic.industry.software.manage.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.electromagnetic.industry.software.manage.pojo.models.RolePermission; import com.electromagnetic.industry.software.manage.pojo.models.RolePermission;
import com.electromagnetic.industry.software.manage.pojo.req.PublishedFileDTO;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper @Mapper
public interface RolePermissionMapper extends BaseMapper<RolePermission> { public interface RolePermissionMapper extends BaseMapper<RolePermission> {
List<RolePermission> getCurrentPermission(PublishedFileDTO publishedFileDTO);
} }

View File

@ -10,6 +10,12 @@ import lombok.Data;
@AllArgsConstructor @AllArgsConstructor
public class RolePermission { public class RolePermission {
/**
* 主键id
*/
@TableField(value = "id")
private Long id;
/** /**
* 角色编码 * 角色编码
*/ */
@ -27,4 +33,11 @@ public class RolePermission {
*/ */
@TableField(value = "permission_code") @TableField(value = "permission_code")
private String permissionCode; private String permissionCode;
public RolePermission(String roleId, String fileId, String permissionCode) {
this.roleId = roleId;
this.fileId = fileId;
this.permissionCode = permissionCode;
}
} }

View File

@ -0,0 +1,25 @@
package com.electromagnetic.industry.software.manage.pojo.req;
import com.electromagnetic.industry.software.common.enums.EffectFlagEnum;
import com.electromagnetic.industry.software.common.enums.PublishEnum;
import lombok.Data;
@Data
public class PublishedFileDTO {
private String fileId;
private Integer dataStatus;
private Integer effectFlag;
private Boolean prjDir;
public void newInit() {
this.setPrjDir(Boolean.TRUE);
this.setDataStatus(PublishEnum.PUBLISHED.getCode());
this.setEffectFlag(EffectFlagEnum.EFFECT.code);
}
}

View File

@ -44,4 +44,9 @@ public interface PermissionService {
*/ */
Map<String, Boolean> filterExportIds(String[] ids); Map<String, Boolean> filterExportIds(String[] ids);
/**
* 同步权限
*/
void syncPermissions (String prjId);
} }

View File

@ -1,7 +1,33 @@
package com.electromagnetic.industry.software.manage.service; package com.electromagnetic.industry.software.manage.service;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.electromagnetic.industry.software.manage.pojo.models.EdFileInfo;
import com.electromagnetic.industry.software.manage.pojo.models.RolePermission; import com.electromagnetic.industry.software.manage.pojo.models.RolePermission;
import com.electromagnetic.industry.software.manage.pojo.req.PublishedFileDTO;
import org.apache.ibatis.annotations.Param;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
public interface RolePermissionService extends IService<RolePermission> { public interface RolePermissionService extends IService<RolePermission> {
/**
* 同步新权限
* @param currentPermission
* @param infoId
*/
void syncPermissions (List<RolePermission> currentPermission, String infoId);
/**
* 获取新权限
* @param publishedFileDTO
* @return
*/
List<RolePermission> getCurrentPermission(PublishedFileDTO publishedFileDTO);
/**
* 在树形结构变动后同步权限
* @param prjId
*/
void syncPermissionsAfterTreeUpdate (List<EdFileInfo> files, String prjId);
} }

View File

@ -1,17 +1,19 @@
package com.electromagnetic.industry.software.manage.service.serviceimpl; package com.electromagnetic.industry.software.manage.service.serviceimpl;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.electromagnetic.industry.software.common.enums.FilePermission; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.electromagnetic.industry.software.common.enums.*;
import com.electromagnetic.industry.software.common.util.EleLog;
import com.electromagnetic.industry.software.common.util.UserThreadLocal; import com.electromagnetic.industry.software.common.util.UserThreadLocal;
import com.electromagnetic.industry.software.manage.mapper.EdFileInfoMapper; import com.electromagnetic.industry.software.manage.mapper.EdFileInfoMapper;
import com.electromagnetic.industry.software.manage.mapper.RolePermissionMapper;
import com.electromagnetic.industry.software.manage.mapper.UserRoleMapper; import com.electromagnetic.industry.software.manage.mapper.UserRoleMapper;
import com.electromagnetic.industry.software.manage.pojo.models.EdFileInfo; import com.electromagnetic.industry.software.manage.pojo.models.EdFileInfo;
import com.electromagnetic.industry.software.manage.pojo.models.RolePermission; import com.electromagnetic.industry.software.manage.pojo.models.RolePermission;
import com.electromagnetic.industry.software.manage.pojo.models.UserRole; import com.electromagnetic.industry.software.manage.pojo.models.UserRole;
import com.electromagnetic.industry.software.manage.pojo.req.PublishedFileDTO;
import com.electromagnetic.industry.software.manage.service.PermissionService; import com.electromagnetic.industry.software.manage.service.PermissionService;
import com.electromagnetic.industry.software.manage.service.RolePermissionService; import com.electromagnetic.industry.software.manage.service.RolePermissionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -19,13 +21,14 @@ import javax.annotation.Resource;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Slf4j
@Service @Service
public class PermissionServiceImpl implements PermissionService { public class PermissionServiceImpl implements PermissionService {
@Resource @Resource
UserRoleMapper userRoleMapper; UserRoleMapper userRoleMapper;
@Resource @Resource
RolePermissionMapper rolePermissionMapper; RolePermissionService rolePermissionService;
@Resource @Resource
EdFileInfoMapper edFileInfoMapper; EdFileInfoMapper edFileInfoMapper;
@ -49,7 +52,7 @@ public class PermissionServiceImpl implements PermissionService {
queryWrapper1.select(RolePermission::getPermissionCode) queryWrapper1.select(RolePermission::getPermissionCode)
.eq(RolePermission::getFileId, id) .eq(RolePermission::getFileId, id)
.in(RolePermission::getRoleId, roleIds); .in(RolePermission::getRoleId, roleIds);
List<String> permissionCodes = rolePermissionMapper.selectObjs(queryWrapper1).stream().map(Object::toString).collect(Collectors.toList()); List<String> permissionCodes = rolePermissionService.listObjs(queryWrapper1).stream().map(Object::toString).collect(Collectors.toList());
return transToMap(permissionCodes, includeView); return transToMap(permissionCodes, includeView);
} }
@ -72,7 +75,7 @@ public class PermissionServiceImpl implements PermissionService {
queryWrapper1.select(RolePermission::getFileId) queryWrapper1.select(RolePermission::getFileId)
.in(RolePermission::getRoleId, roleIds) .in(RolePermission::getRoleId, roleIds)
.eq(RolePermission::getPermissionCode, FilePermission.VIEW); .eq(RolePermission::getPermissionCode, FilePermission.VIEW);
List<String> ids = rolePermissionMapper.selectObjs(queryWrapper1).stream().map(Object::toString).collect(Collectors.toList()); List<String> ids = rolePermissionService.listObjs(queryWrapper1).stream().map(Object::toString).collect(Collectors.toList());
Set<String> result = new HashSet<>(); Set<String> result = new HashSet<>();
// 把父亲节点加上 // 把父亲节点加上
@ -109,7 +112,7 @@ public class PermissionServiceImpl implements PermissionService {
queryWrapper.select(RolePermission::getPermissionCode) queryWrapper.select(RolePermission::getPermissionCode)
.eq(RolePermission::getFileId, fileId) .eq(RolePermission::getFileId, fileId)
.eq(RolePermission::getRoleId, roleId); .eq(RolePermission::getRoleId, roleId);
return rolePermissionMapper.selectObjs(queryWrapper).stream().map(Object::toString).collect(Collectors.toList()); return rolePermissionService.listObjs(queryWrapper).stream().map(Object::toString).collect(Collectors.toList());
} }
/** /**
@ -155,7 +158,7 @@ public class PermissionServiceImpl implements PermissionService {
queryWrapper.eq(RolePermission::getFileId, id) queryWrapper.eq(RolePermission::getFileId, id)
.eq(RolePermission::getPermissionCode, FilePermission.EXPORT.getCode()) .eq(RolePermission::getPermissionCode, FilePermission.EXPORT.getCode())
.in(RolePermission::getRoleId, roleIds); .in(RolePermission::getRoleId, roleIds);
long count = rolePermissionMapper.selectCount(queryWrapper); long count = rolePermissionService.count(queryWrapper);
map.put(id, count>0); map.put(id, count>0);
// 添加父节点 // 添加父节点
@ -169,4 +172,35 @@ public class PermissionServiceImpl implements PermissionService {
} }
return map; return map;
} }
/**
* 同步权限
*/
@Override
public void syncPermissions (String prjId) {
// 获取当前项目所有已逻辑删除的节点删除其权限
LambdaQueryWrapper<EdFileInfo> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(EdFileInfo::getDataStatus, EleDataStatusEnum.DELETED.code)
.eq(EdFileInfo::getEffectFlag, EffectFlagEnum.NOT_EFFECTIVE.code)
.likeRight(EdFileInfo::getFilePath, prjId);
List<String> deletedIds = edFileInfoMapper.selectList(queryWrapper).stream().map(EdFileInfo::getId).collect(Collectors.toList());
LambdaQueryWrapper<RolePermission> deleteWrapper = new LambdaQueryWrapper<>();
deleteWrapper.in(RolePermission::getFileId, deletedIds);
rolePermissionService.remove(deleteWrapper);
// 获取当前项目所有已发布的节点
LambdaQueryWrapper<EdFileInfo> infoWrapper = new LambdaQueryWrapper<>();
infoWrapper.likeRight(EdFileInfo::getFilePath, prjId)
.eq(EdFileInfo::getEffectFlag, EffectFlagEnum.EFFECT.code)
.eq(EdFileInfo::getDataStatus, EleDataStatusEnum.PUBLISHED.code)
.eq(EdFileInfo::getPrjDir, true);
List<EdFileInfo> files = edFileInfoMapper.selectList(infoWrapper);
// 同步权限
rolePermissionService.syncPermissionsAfterTreeUpdate(files, prjId);
}
} }

View File

@ -1,11 +1,132 @@
package com.electromagnetic.industry.software.manage.service.serviceimpl; package com.electromagnetic.industry.software.manage.service.serviceimpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.electromagnetic.industry.software.common.enums.EffectFlagEnum;
import com.electromagnetic.industry.software.common.enums.EleDataStatusEnum;
import com.electromagnetic.industry.software.manage.mapper.RolePermissionMapper; import com.electromagnetic.industry.software.manage.mapper.RolePermissionMapper;
import com.electromagnetic.industry.software.manage.pojo.models.EdFileInfo;
import com.electromagnetic.industry.software.manage.pojo.models.RolePermission; import com.electromagnetic.industry.software.manage.pojo.models.RolePermission;
import com.electromagnetic.industry.software.manage.pojo.req.PublishedFileDTO;
import com.electromagnetic.industry.software.manage.service.RolePermissionService; import com.electromagnetic.industry.software.manage.service.RolePermissionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeMap;
import java.util.stream.Collectors;
@Slf4j
@Service @Service
public class RolePermissionServiceImpl extends ServiceImpl<RolePermissionMapper, RolePermission> implements RolePermissionService { public class RolePermissionServiceImpl extends ServiceImpl<RolePermissionMapper, RolePermission> implements RolePermissionService {
@Resource
private RolePermissionMapper rolePermissionMapper;
/**
* 同步新权限
* @param currentPermission
* @param infoId
*/
@Override
@Transactional
public void syncPermissions (List<RolePermission> currentPermission, String infoId) {
if (currentPermission == null) {
throw new IllegalArgumentException("currentPermission must not be null");
}
LambdaQueryWrapper<RolePermission> deleteWrapper = new LambdaQueryWrapper<>();
deleteWrapper.eq(RolePermission::getFileId, infoId);
List<RolePermission> oldPermissions = this.list(deleteWrapper);
Set<String> newPermissionSet = currentPermission.stream()
.map(p -> p.getRoleId() + "_" + p.getPermissionCode())
.collect(Collectors.toSet());
List<RolePermission> permissionsToDelete = oldPermissions.stream()
.filter(p -> !newPermissionSet.contains(p.getRoleId() + "_" + p.getPermissionCode()))
.collect(Collectors.toList());
log.info ("删除旧权限: {}", permissionsToDelete);
// 删除不需要的权限
if (!permissionsToDelete.isEmpty()) {
List<Long> idsToDelete = permissionsToDelete.stream()
.map(RolePermission::getId)
.collect(Collectors.toList());
this.removeBatchByIds(idsToDelete);
}
// 批量插入/更新新权限使用 ON DUPLICATE KEY UPDATE 机制
if (!currentPermission.isEmpty()) {
for (RolePermission rp : currentPermission) {
RolePermission exist = this.getOne(new LambdaQueryWrapper<RolePermission>()
.eq(RolePermission::getFileId, rp.getFileId())
.eq(RolePermission::getRoleId, rp.getRoleId())
.eq(RolePermission::getPermissionCode, rp.getPermissionCode()));
if (exist != null) {
rp.setId(exist.getId()); // 赋值已有 ID避免重复插入
}
}
this.saveOrUpdateBatch(currentPermission);
}
}
/**
* 获取新权限
* @param publishedFileDTO
* @return
*/
@Override
public List<RolePermission> getCurrentPermission(PublishedFileDTO publishedFileDTO) {
return rolePermissionMapper.getCurrentPermission(publishedFileDTO);
}
/**
* 在树形结构变动后同步权限
* @param prjId
*/
@Transactional
@Override
public void syncPermissionsAfterTreeUpdate (List<EdFileInfo> files, String prjId) {
log.info("开始同步项目权限:{}", prjId);
// 对files分层
TreeMap<Integer, List<EdFileInfo>> levelMap = new TreeMap<>();
for (EdFileInfo file : files) {
int len = file.getFilePath().split("_").length;
levelMap.computeIfAbsent(len, k -> new ArrayList<>()).add(file);
}
// 获取叶子节点
int maxLen = levelMap.lastKey();
// 从最底层的叶子节点的上级节点开始遍历,更新权限
for (int i=maxLen-1; i>0;i--) {
for (EdFileInfo fileInfo : levelMap.get(i)) {
String infoId = fileInfo.getId();
if (isLeafNode(infoId, files)) {
continue;
}
PublishedFileDTO publishedFileDTO = new PublishedFileDTO();
publishedFileDTO.newInit();
publishedFileDTO.setFileId(infoId);
List<RolePermission> currentPermission = getCurrentPermission(publishedFileDTO);
syncPermissions(currentPermission, infoId);
}
log.info("同步项目权限结束:{}", prjId);
}
}
private boolean isLeafNode(String id, List<EdFileInfo> files) {
Set<String> parentIdSet = files.stream()
.map(EdFileInfo::getParentId)
.collect(Collectors.toSet());
return !parentIdSet.contains(id);
}
} }

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.electromagnetic.industry.software.manage.mapper.RolePermissionMapper">
<resultMap id="RolePermissionMap" type="com.electromagnetic.industry.software.manage.pojo.models.RolePermission">
<id column="id" jdbcType="BIGINT" property="id"/>
<result column="file_id" jdbcType="VARCHAR" property="fileId"/>
<result column="permission_code" jdbcType="VARCHAR" property="permissionCode"/>
<result column="role_id" jdbcType="VARCHAR" property="roleId"/>
</resultMap>
<select id="getCurrentPermission" parameterType="com.electromagnetic.industry.software.manage.pojo.req.PublishedFileDTO" resultMap="RolePermissionMap">
SELECT f.parent_id as file_id , rp.permission_code, rp.role_id
FROM ed_role_permission rp
JOIN ed_file_info f ON rp.file_id = f.id
WHERE f.parent_id = #{fileId}
AND f.prj_dir = #{prjDir}
AND f.data_status = #{dataStatus}
AND f.effect_flag = #{effectFlag}
GROUP BY rp.role_id, rp.permission_code
HAVING COUNT(f.id) = (
SELECT COUNT(f2.id)
FROM ed_file_info f2
WHERE f2.parent_id = #{fileId}
AND f2.prj_dir = #{prjDir}
AND f2.data_status = #{dataStatus}
AND f2.effect_flag = #{effectFlag}
)
</select>
</mapper>