package com.oying.modules.system.service.impl; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.oying.modules.system.domain.Dept; import com.oying.modules.system.domain.User; import com.oying.modules.system.domain.dto.DeptQueryCriteria; import com.oying.modules.system.mapper.DeptMapper; import com.oying.modules.system.mapper.RoleMapper; import com.oying.modules.system.mapper.UserMapper; import com.oying.modules.system.service.DeptService; import com.oying.utils.*; import lombok.RequiredArgsConstructor; import com.oying.exception.BadRequestException; import com.oying.utils.enums.DataScopeEnum; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.lang.reflect.Field; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; /** * @author Z * @date 2019-03-25 */ @Service @RequiredArgsConstructor public class DeptServiceImpl extends ServiceImpl implements DeptService { private final DeptMapper deptMapper; private final UserMapper userMapper; private final RedisUtils redisUtils; private final RoleMapper roleMapper; @Override public List queryAll(DeptQueryCriteria criteria, Boolean isQuery) throws Exception { String dataScopeType = SecurityUtils.getDataScopeType(); if (isQuery) { if(dataScopeType.equals(DataScopeEnum.ALL.getValue())){ criteria.setPidIsNull(true); } List fields = StringUtils.getAllFields(criteria.getClass(), new ArrayList<>()); List fieldNames = new ArrayList(){{ add("pidIsNull");add("enabled");}}; for (Field field : fields) { //设置对象的访问权限,保证对private的属性的访问 field.setAccessible(true); Object val = field.get(criteria); if(fieldNames.contains(field.getName())){ continue; } if (ObjectUtil.isNotNull(val)) { criteria.setPidIsNull(null); break; } } } // 数据权限 criteria.setIds(SecurityUtils.getCurrentUserDataScope()); List list = deptMapper.findAll(criteria); // 如果为空,就代表为自定义权限或者本级权限,就需要去重,不理解可以注释掉,看查询结果 if(StringUtils.isBlank(dataScopeType)){ return deduplication(list); } return list; } @Override public Dept findById(Long id) { String key = CacheKey.DEPT_ID + id; Dept dept = redisUtils.get(key, Dept.class); if(dept == null){ dept = deptMapper.selectById(id); redisUtils.set(key, dept, 1, TimeUnit.DAYS); } return dept; } @Override public List findByPid(long pid) { return deptMapper.findByPid(pid); } @Override public Set findByRoleId(Long id) { return deptMapper.findByRoleId(id); } @Override @Transactional(rollbackFor = Exception.class) public void create(Dept resources) { save(resources); // 清理缓存 updateSubCnt(resources.getPid()); // 清理自定义角色权限的datascope缓存 delCaches(resources.getPid()); } @Override @Transactional(rollbackFor = Exception.class) public void update(Dept resources) { // 旧的机构 Long oldPid = findById(resources.getId()).getPid(); Long newPid = resources.getPid(); if(resources.getPid() != null && resources.getId().equals(resources.getPid())) { throw new BadRequestException("上级不能为自己"); } Dept dept = getById(resources.getId()); resources.setId(dept.getId()); saveOrUpdate(resources); // 更新父节点中子节点数目 updateSubCnt(oldPid); updateSubCnt(newPid); // 清理缓存 delCaches(resources.getId()); } @Override @Transactional(rollbackFor = Exception.class) public void delete(Set depts) { for (Dept dept : depts) { // 清理缓存 delCaches(dept.getId()); deptMapper.deleteById(dept.getId()); updateSubCnt(dept.getPid()); } } @Override public void download(List depts, HttpServletResponse response) throws IOException { List> list = new ArrayList<>(); for (Dept dept : depts) { Map map = new LinkedHashMap<>(); map.put("机构名称", dept.getName()); map.put("机构状态", dept.getEnabled() ? "启用" : "停用"); map.put("创建日期", dept.getCreateTime()); list.add(map); } FileUtil.downloadExcel(list, response); } @Override public Set getDeleteDepts(List menuList, Set deptSet) { for (Dept dept : menuList) { deptSet.add(dept); List depts = deptMapper.findByPid(dept.getId()); if(CollUtil.isNotEmpty(depts)){ getDeleteDepts(depts, deptSet); } } return deptSet; } @Override public List getDeptChildren(List deptList) { List list = new ArrayList<>(); deptList.forEach(dept -> { if (dept!=null && dept.getEnabled()) { List depts = deptMapper.findByPid(dept.getId()); if (CollUtil.isNotEmpty(depts)) { list.addAll(getDeptChildren(depts)); } list.add(dept.getId()); } } ); return list; } @Override public List getSuperior(Dept dept, List depts) { if(dept.getPid() == null){ depts.addAll(deptMapper.findByPidIsNull()); return depts; } depts.addAll(deptMapper.findByPid(dept.getPid())); return getSuperior(findById(dept.getPid()), depts); } @Override public Object buildTree(List deptList) { Set trees = new LinkedHashSet<>(); Set depts= new LinkedHashSet<>(); List deptNames = deptList.stream().map(Dept::getName).collect(Collectors.toList()); boolean isChild; for (Dept dept : deptList) { isChild = false; if (dept.getPid() == null) { trees.add(dept); } for (Dept it : deptList) { if (it.getPid() != null && dept.getId().equals(it.getPid())) { isChild = true; if (dept.getChildren() == null) { dept.setChildren(new ArrayList<>()); } dept.getChildren().add(it); } } if(isChild) { depts.add(dept); } else if(dept.getPid() != null && !deptNames.contains(findById(dept.getPid()).getName())) { depts.add(dept); } } if (CollectionUtil.isEmpty(trees)) { trees = depts; } Map map = new HashMap<>(2); map.put("totalElements",depts.size()); map.put("content",CollectionUtil.isEmpty(trees)? depts :trees); return map; } @Override public void verification(Set depts) { Set deptIds = depts.stream().map(Dept::getId).collect(Collectors.toSet()); if(userMapper.countByDepts(deptIds) > 0){ throw new BadRequestException("所选机构存在用户关联,请解除后再试!"); } if(roleMapper.countByDepts(deptIds) > 0){ throw new BadRequestException("所选机构存在角色关联,请解除后再试!"); } } private void updateSubCnt(Long deptId){ if(deptId != null){ int count = deptMapper.countByPid(deptId); deptMapper.updateSubCntById(count, deptId); } } private List deduplication(List list) { List depts = new ArrayList<>(); for (Dept dept : list) { boolean flag = true; for (Dept dept1 : list) { if (dept1.getId().equals(dept.getPid())) { flag = false; break; } } if (flag){ depts.add(dept); } } return depts; } /** * 清理缓存 * @param id / */ public void delCaches(Long id){ List users = userMapper.findByRoleDeptId(id); // 删除数据权限 redisUtils.delByKeys(CacheKey.DATA_USER, users.stream().map(User::getId).collect(Collectors.toSet())); redisUtils.del(CacheKey.DEPT_ID + id); } }