package com.vci.web.service.impl; import com.vci.dto.OrgDepartmentDTO; import com.vci.corba.common.PLException; import com.vci.corba.common.data.UserEntityInfo; import com.vci.corba.framework.data.DeptInfo; import com.vci.corba.omd.data.BusinessObject; import com.vci.web.service.OrgDeptQueryServiceI; import com.vci.lcstatuspck.FrameworkDataLCStatus; import com.vci.model.OrgDeptForPlatform1; import com.vci.po.OrgDeptPO; import com.vci.pagemodel.OrgDepartmentVO; import com.vci.omd.utils.ObjectTool; import com.vci.starter.poi.bo.ReadExcelOption; import com.vci.starter.poi.bo.WriteExcelData; import com.vci.starter.poi.bo.WriteExcelOption; import com.vci.starter.poi.constant.ExcelLangCodeConstant; import com.vci.starter.poi.util.ExcelUtil; import com.vci.starter.revision.bo.TreeWrapperOptions; import com.vci.starter.revision.service.RevisionModelUtil; import com.vci.starter.web.constant.QueryOptionConstant; import com.vci.starter.web.exception.VciBaseException; import com.vci.starter.web.pagemodel.*; import com.vci.starter.web.util.*; import com.vci.starter.web.wrapper.VciQueryWrapperForDO; import com.vci.web.service.WebBoServiceI; import com.vci.starter.web.util.Lcm.Func; import com.vci.web.util.PlatformClientUtil; import com.vci.web.util.WebUtil; import org.apache.commons.lang3.StringUtils; import org.apache.poi.hssf.util.HSSFColor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import java.io.File; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; /** * 部门的查询服务,兼容老平台 * @author 谢军 * @date 2020/3/10 */ @Service public class OrgDeptQueryServiceImpl implements OrgDeptQueryServiceI{ /** * 业务数据服务 */ @Autowired private WebBoServiceI boService; /** * 平台调用客户端 */ @Autowired private PlatformClientUtil platformClientUtil; /** * 对象操作工具类 */ @Autowired private RevisionModelUtil revisionModelUtil; /** * 必填列 */ private List ColumnNameisRed = new ArrayList(); /** * 日志 */ private Logger logger = LoggerFactory.getLogger(getClass()); /** * 根据部门主键获取部门的信息 * @param deptOid 部门主键 * @return 部门的显示对象,如果部门不存在则返回null,不会抛出异常 * @throws VciBaseException 参数为空或者数据库存在问题的时候会抛出异常 */ @Override public OrgDepartmentVO getDeptByDeptOid(String deptOid) throws VciBaseException { if(StringUtils.isBlank(deptOid)){ return null; } Map conditionMap = new HashMap<>(); conditionMap.put("pluid",deptOid); VciQueryWrapperForDO queryWrapper = new VciQueryWrapperForDO(conditionMap, OrgDeptForPlatform1.class); List deptForPlatform1s = boService.selectByQueryWrapper(queryWrapper, OrgDeptForPlatform1.class); if(Func.isEmpty(deptForPlatform1s)){ return null; } return deptDO2VO(deptForPlatform1s.get(0)); } /** * 根据父部门主键获取部门名称部门的信息 * @param parentDeptOid 父部门主键 * @param conditionMap 部门名称 * @return 部门的显示对象,如果部门不存在则返回null,不会抛出异常 * @throws VciBaseException 参数为空或者数据库存在问题的时候会抛出异常 */ @Override public List getDeptByDeptpOidAndCondition(String parentDeptOid,Map conditionMap) throws VciBaseException { if(Func.isEmpty(conditionMap)){ conditionMap = new HashMap(); } VciQueryWrapperForDO queryWrapper = new VciQueryWrapperForDO(conditionMap,OrgDeptForPlatform1.class); //父主键为空查顶层 if(Func.isBlank(parentDeptOid)){ queryWrapper.isNull("plparentuid"); }else{ queryWrapper.eq("plparentuid",parentDeptOid); } List roleForPlatform1s = boService.selectByQueryWrapper(queryWrapper, OrgDeptForPlatform1.class); if(Func.isEmpty(roleForPlatform1s)){ return null; } return deptDO2VOs(roleForPlatform1s); } /** * 根据父部门名称路径获取和部门名称部门的信息(主要用于导入时根据部门命令全路径和名称或编号查重) * @return 部门的显示对象,如果部门不存在则返回null,不会抛出异常 * @throws VciBaseException 参数为空或者数据库存在问题的时候会抛出异常 */ @Override public List getDeptAllFullName() throws VciBaseException { //查询部门信息,主要查询部门名称组成全路径 String sql = "SELECT PLUID, PLNAME, PLNUM, PLSTATUS, level, substr(sys_connect_by_path(PLNAME, '/'), 2) AS FULL_NAME_PATH " + "FROM PLDEPT " + "START WITH PLPARENTUID IS NULL " + "CONNECT BY PRIOR PLUID = PLPARENTUID"; List cbos = boService.queryByOnlySql(sql); List departmentVOList = new ArrayList<>(); if(!CollectionUtils.isEmpty(cbos)){ cbos.stream().forEach(cbo->{ //部门主键 String deptOid = ObjectTool.getNewBOAttributeValue(cbo,"PLUID"); //部门名称 String deptName = ObjectTool.getNewBOAttributeValue(cbo, "PLNAME"); //部门编号 String deptNum = ObjectTool.getNewBOAttributeValue(cbo, "PLNUM"); //部门层级 String deptLevel = ObjectTool.getNewBOAttributeValue(cbo, "level"); //部门名称全路径 String fullDeptNamePath = ObjectTool.getNewBOAttributeValue(cbo, "FULL_NAME_PATH"); //部门状态 String deptStatus = ObjectTool.getNewBOAttributeValue(cbo, "PLSTATUS"); OrgDepartmentVO orgDepartmentVO = new OrgDepartmentVO(deptNum,deptName,Short.valueOf(deptStatus),fullDeptNamePath,Integer.valueOf(deptLevel)); orgDepartmentVO.setOid(deptOid); departmentVOList.add(orgDepartmentVO); }); } return departmentVOList; } /** * 部门的数据对象转换为显示对象 * @param depts 数据对象 * @return 显示对象 */ public List deptDO2VOs(Collection depts){ List departmentVOS = new ArrayList<>(); Optional.ofNullable(depts).orElseGet(()->new ArrayList<>()).stream().forEach(dept->{ departmentVOS.add(deptDO2VO(dept)); }); return departmentVOS; } /** * 部门的数据对象转换为显示对象 * @param deptForPlatform1 数据对象 * @return 显示对象 */ public OrgDepartmentVO deptDO2VO(OrgDeptForPlatform1 deptForPlatform1){ OrgDepartmentVO departmentVO = new OrgDepartmentVO(); if(deptForPlatform1!=null){ departmentVO.setOid(deptForPlatform1.getPluid()); // 除部门主键外的唯一标识,长度为Dept:+8位可通过该参数反推回部门主键的hash编码 //departmentVO.setUniqueId("Dept:"+Func.oidEnHash(deptForPlatform1.getPluid())); departmentVO.setId(deptForPlatform1.getPlnum()); departmentVO.setName(deptForPlatform1.getPlname()); departmentVO.setStatus(deptForPlatform1.getPlstatus()); if(0 == deptForPlatform1.getPlstatus()){ departmentVO.setStatusText(FrameworkDataLCStatus.ENABLED.getValue()); }else{ departmentVO.setStatusText(FrameworkDataLCStatus.DISABLED.getValue()); } departmentVO.setSpecialties(deptForPlatform1.getPlspecialties()); departmentVO.setCode(deptForPlatform1.getPlcode()); departmentVO.setPkFatherDepartment(deptForPlatform1.getPlparentuid()); departmentVO.setDescription(deptForPlatform1.getPldesc()); departmentVO.setCreateTime(new Date(deptForPlatform1.getPlcreatetime())); departmentVO.setCreator(deptForPlatform1.getPlcreateuser()); departmentVO.setLastModifyTime(new Date(deptForPlatform1.getPlupdatetime())); departmentVO.setLastModifier(deptForPlatform1.getPlupdateuser()); } return departmentVO; } /** * 批量获取部门的信息 (根据部门主键) * @param deptOidCollections 部门主键的集合,可以超过1000个 * @return 部门的显示对象,如果部门不存在则返回空的列表,不会抛出异常 * @throws VciBaseException 参数为空或者数据库存在问题的时候会抛出异常 */ @Override public List listDeptByDeptOids( Collection deptOidCollections) throws VciBaseException { if(CollectionUtils.isEmpty(deptOidCollections)){ return new ArrayList<>(); } List depts = new ArrayList<>(); WebUtil.switchCollectionForOracleIn(deptOidCollections).stream().forEach(roleOids->{ Map conditionMap=new HashMap(); conditionMap.put("pluid", QueryOptionConstant.IN + VciBaseUtil.toInSql(roleOids.toArray(new String[0]))); VciQueryWrapperForDO queryWrapper = new VciQueryWrapperForDO(conditionMap,OrgDeptForPlatform1.class); List roleForPlatform1s = boService.selectByQueryWrapper(queryWrapper, OrgDeptForPlatform1.class); if(!CollectionUtils.isEmpty(roleForPlatform1s)){ depts.addAll(roleForPlatform1s); } }); return deptDO2VOs(depts); } /** * 获取部门的列表,默认会以部门名称升序排列,部门的编辑页面列表不要使用这个接口 * @param queryMap 查询条件 * @param pageHelper 分页和排序的信息,在兼容老平台的时候会自动兼容,如果属性不存在会自动忽略 * @return 部门的显示对象列表 * @throws VciBaseException 参数为空的时候会抛出异常 */ @Override public DataGrid gridDepts(Map queryMap, PageHelper pageHelper) throws VciBaseException { if(pageHelper == null){ pageHelper = new PageHelper(-1); } //根据部门编号排序 pageHelper.addDefaultAsc("plnum"); VciQueryWrapperForDO queryWrapper = new VciQueryWrapperForDO(queryMap,OrgDeptForPlatform1.class,pageHelper); List deptForPlatform1s = boService.selectByQueryWrapper(queryWrapper, OrgDeptForPlatform1.class); DataGrid dataGrid = new DataGrid<>(); if(!CollectionUtils.isEmpty(deptForPlatform1s)){ dataGrid.setData(deptDO2VOs(deptForPlatform1s)); dataGrid.setTotal(boService.countByQueryWrapper(queryWrapper,OrgDeptForPlatform1.class)); } return dataGrid; } /** * 根据部门主键获取部门的姓名 * @param deptOid 部门主键 * @return 部门姓名,如果不存在会返回null */ @Override public String getDeptNameByDeptOid(String deptOid) { WebUtil.alertNotNull(deptOid,"部门的主键"); return getDeptByDeptOid(deptOid).getName(); } /** * 使用用户主键查询部门 * @param userOid 用户主键 * @param queryMap 查询条件 * @param notIn 是否为不包含 * @return 角色的显示对象 */ private List listDeptByUserOid(String userOid,Map queryMap,boolean notIn){ if(StringUtils.isBlank(userOid)){ return new ArrayList<>(); } if(queryMap == null){ queryMap = new HashMap<>(); } List deptForPlatform1s = new ArrayList<>(); if(userOid.contains(",")){ Map finalQueryMap = queryMap; WebUtil.switchCollectionForOracleIn(WebUtil.str2List(userOid)).stream().forEach(userOids->{ Map conditionMap = new HashMap<>(); finalQueryMap.forEach((key,value)->{ conditionMap.put(key,value); }); conditionMap.put("pluid", notIn ? QueryOptionConstant.NOTIN : QueryOptionConstant.IN + "select pldeptuid from PLUSERDEPT where pluseruid in (" + WebUtil.toInSql(userOids.toArray(new String[0])) + ")"); VciQueryWrapperForDO queryWrapper = new VciQueryWrapperForDO(conditionMap,OrgDeptForPlatform1.class); List roleForPlatform1s = boService.selectByQueryWrapper(queryWrapper, OrgDeptForPlatform1.class); if(!CollectionUtils.isEmpty(roleForPlatform1s)){ deptForPlatform1s.addAll(roleForPlatform1s); } }); }else { queryMap.put("pluid", notIn ? QueryOptionConstant.NOTIN : QueryOptionConstant.IN + "select pldeptuid from PLUSERDEPT where pluseruid ='" + userOid.trim() + "'"); } VciQueryWrapperForDO queryWrapper = new VciQueryWrapperForDO(queryMap,OrgDeptForPlatform1.class); List roleForPlatform1s = boService.selectByQueryWrapper(queryWrapper, OrgDeptForPlatform1.class); if(!CollectionUtils.isEmpty(roleForPlatform1s)){ deptForPlatform1s.addAll(roleForPlatform1s); } return deptDO2VOs(deptForPlatform1s); } /** * 根据用户主键获取关联的部门 * @param userOid 用户主键 * @param queryMap 查询条件,如果需要使用用户的属性来查询可以使用pkUser.xxxx * @return 部门的显示对象 */ @Override public List listDeptByUserOid(String userOid, Map queryMap) { List departmentVOS = listDeptByUserOid(userOid, queryMap, false); if(CollectionUtils.isEmpty(departmentVOS)){ return new ArrayList<>(); } return departmentVOS; } /** * 获取未关联某个用户的部门 * @param userOid 用户主键 * @param queryMap 查询条件,如果需要使用用户的属性来查询可以使用pkUser.xxxx * @return 部门的显示对象 */ @Override public List listDeptUnInUserOid(String userOid, Map queryMap) { return listDeptByUserOid(userOid, queryMap, true); } /** * 获取未关联某个用户的部门 * @param userOid 用户主键 * @param queryMap 查询条件,如果需要使用用户的属性来查询可以使用pkUser.xxxx * @param pageHelper 分页和排序对象,老平台不支持使用部门编号来排序 * @return 部门的显示对象 */ @Override public DataGrid gridDeptUninUserOid(String userOid, Map queryMap, PageHelper pageHelper) { return gridDeptByUserOid(userOid,queryMap,pageHelper,true); } /** * 使用用户查询部门列表 * @param userOid 用户主键 * @param queryMap 查询条件 * @param pageHelper 分页对象 * @param notIn 不包含 * @return 列表数据 */ private DataGrid gridDeptByUserOid(String userOid,Map queryMap,PageHelper pageHelper,boolean notIn){ if(queryMap == null){ queryMap = new HashMap<>(); } if(StringUtils.isBlank(userOid)){ return new DataGrid<>(); } if(userOid.contains(",")){ String[] userOids = userOid.trim().split(","); if(userOids.length>1000){ //这个方法不支持超过1000个的用户查询 throw new VciBaseException("这个方法不支持超过1000个用户的主键来查询"); } queryMap.put("pluid", notIn ? QueryOptionConstant.NOTIN : QueryOptionConstant.IN + "select pldeptuid from PLUSERDEPT where pluseruid in (" + WebUtil.toInSql(userOids) + ")"); }else { queryMap.put("pluid", notIn ? QueryOptionConstant.NOTIN : QueryOptionConstant.IN + "select pldeptuid from PLUSERDEPT where pluseruid ='" + userOid.trim() + "'"); } return gridDepts(queryMap,pageHelper); } /** * 批量根据用户的主键来获取部门 * @param userOidCollection 用户主键集合 * @param queryMap 查询条件,如果需要使用用户的属性来查询可以使用pkUser.xxxx * @return 部门的显示对象,key是用户主键,value是关联的部门 */ @Override public Map> batchListDeptByUserOids( Collection userOidCollection, Map queryMap) { if(CollectionUtils.isEmpty(userOidCollection)){ return new HashMap<>(); } List deptVOList = new ArrayList<>(); Map> userDeptOidMap = new HashMap<>(); WebUtil.switchCollectionForOracleIn(userOidCollection).stream().forEach(userOids->{ List deptVOs = listDeptByUserOid(userOids.stream().collect(Collectors.joining(",")), queryMap, false); if(!CollectionUtils.isEmpty(deptVOs)){ deptVOList.addAll(deptVOs); String sql = "select pluseruid,pldeptuid from pluserdept where pluseruid in (" + WebUtil.toInSql(userOids.toArray(new String[0])) + ")"; List cbos = boService.queryBySql(sql, null); if(!CollectionUtils.isEmpty(cbos)){ cbos.stream().forEach(cbo->{ String userOid = ObjectTool.getNewBOAttributeValue(cbo,"pluseruid"); List deptOids = userDeptOidMap.getOrDefault(userOid,new ArrayList<>()); deptOids.add(ObjectTool.getNewBOAttributeValue(cbo,"pldeptuid")); userDeptOidMap.put(userOid,deptOids); }); } } }); if(!CollectionUtils.isEmpty(deptVOList)){ //这儿应该对deptVOList做一次去重处理,因为肯定会有重复的部门被查出来 Map deptVOMap = deptVOList.stream() .collect(Collectors.toMap(OrgDepartmentVO::getOid, Function.identity(), (existing, replacement) -> existing)); Map> userDeptVOMap = new HashMap<>(); userDeptOidMap.forEach((userOid,deptOids)->{ List deptVOS = new ArrayList<>(); deptOids.forEach(deptOid->{ if(deptVOMap.containsKey(deptOid)){ deptVOS.add(deptVOMap.get(deptOid)); } }); userDeptVOMap.put(userOid,deptVOS); }); return userDeptVOMap; } return new HashMap<>(); } /** * 批量根据用户的主键来获取部门名称(/间隔方式) * @param userOidCollection 用户主键集合 * @param queryMap 查询条件,如果需要使用用户的属性来查询可以使用pkUser.xxxx * @return 部门的显示对象,key是用户主键,value是关联的部门(包含父节点如当前部门为人力资源部则值为:550/人力资源部) */ @Override public Map> batchMapDeptNameByUserOids(Collection userOidCollection, Map queryMap) { if(CollectionUtils.isEmpty(userOidCollection)){ return new HashMap<>(); } Map> deptOidNameMap = new HashMap<>(); Map> userDeptOidMap = new HashMap<>(); WebUtil.switchCollectionForOracleIn(userOidCollection).stream().forEach(userOids->{ //1、要先根据用户主键获取到关联的部门主键 String sql = "select pluseruid,pldeptuid from pluserdept where pluseruid in (" + WebUtil.toInSql(userOids.toArray(new String[0])) + ")"; List cbos = boService.queryBySql(sql, null); if(!CollectionUtils.isEmpty(cbos)){ cbos.stream().forEach(cbo->{ //角色主键 String userOid = ObjectTool.getNewBOAttributeValue(cbo,"pluseruid"); //部门主键 String deptUid = ObjectTool.getNewBOAttributeValue(cbo, "pldeptuid"); //2、然后根据部门主键获取到由部门名称/组成的值 //避免多次查询,或者循环查询 if(deptOidNameMap.containsKey(deptUid)){ userDeptOidMap.put(userOid,deptOidNameMap.get(deptUid)); }else { if(Func.isNotEmpty(deptUid)){ //2.1、查询部门oid,当前部门包含父部门 String queryDeptSql = "select pluid,plname from pldept START with pluid = '" + deptUid + "' connect by prior plparentuid = pluid"; List cboDepts = boService.queryBySql(queryDeptSql, null); if(!CollectionUtils.isEmpty(cboDepts)){ StringBuilder sb = new StringBuilder(); for (int i = cboDepts.size()-1; i >=0; i--) { String deptName = ObjectTool.getNewBOAttributeValue(cboDepts.get(i),"plname"); sb.append(deptName); sb.append("/"); } //2.2、避免同一部门多次查询,这里存储在一个公共集合中,便于重复使用 //删除最后一个斜杠 sb.deleteCharAt(sb.length() - 1); Map tempMap = new HashMap<>(); tempMap.put(deptUid,sb.toString()); deptOidNameMap.put(deptUid,tempMap); userDeptOidMap.put(userOid,tempMap); } } } }); } }); return userDeptOidMap; } /** * 获取某个部门的直属下级部门 * @param pkFatherDepartmment 部门的主键 * @param queryMap 查询条件 * @return 部门显示对象 */ @Override public List listChildrenDeptByParentOid( String pkFatherDepartmment, Map queryMap) { VciQueryWrapperForDO queryWrapperForDO = new VciQueryWrapperForDO(queryMap,OrgDeptForPlatform1.class); if(StringUtils.isBlank(pkFatherDepartmment)){ queryWrapperForDO.isNull("plparentuid"); }else{ queryWrapperForDO.eq("plparentuid",pkFatherDepartmment.trim()); } List depts = boService.selectByQueryWrapper(queryWrapperForDO, OrgDeptForPlatform1.class); return deptDO2VOs(depts); } /** * 获取某个部门的所有层级的下级部门 * @param pkFatherDepartmment 部门的主键 * @param queryMap 查询条件 * @return 部门显示对象 */ @Override public List listAllLevelChildrenDeptByParentOid( String pkFatherDepartmment, Map queryMap) { VciQueryWrapperForDO queryWrapperForDO = new VciQueryWrapperForDO(queryMap,OrgDeptForPlatform1.class); queryWrapperForDO.in("pluid","select pluid from pldept start with " + (StringUtils.isBlank(pkFatherDepartmment)?" (plparentuid is null or plparentuid = '') ":"plparentuid = '" + pkFatherDepartmment.trim() + "'") + "connect by PRIOR pluid=plparentuid"); return deptDO2VOs(boService.selectByQueryWrapper(queryWrapperForDO, OrgDeptForPlatform1.class)); } /** * 参照树形数据的部门信息 * @param treeQueryObject 树形查询的条件 * @return 树节点 */ @Override public List refTreeDept(TreeQueryObject treeQueryObject) { String pkFatherDepartmment=treeQueryObject.getParentOid(); Map conditionMap = treeQueryObject.getConditionMap(); Map extandParamsMap = treeQueryObject.getExtandParamsMap(); if(conditionMap==null){ conditionMap=new HashMap(); } List orgDepartmentVOList=new ArrayList(); if(treeQueryObject.isQueryAllLevel()){ orgDepartmentVOList = listAllLevelChildrenDeptByParentOid(pkFatherDepartmment, conditionMap); }else{ conditionMap.put("plparentuid", pkFatherDepartmment); VciQueryWrapperForDO queryWrapperForDO = new VciQueryWrapperForDO(conditionMap,OrgDeptForPlatform1.class); orgDepartmentVOList = deptDO2VOs(boService.selectByQueryWrapper(queryWrapperForDO,OrgDeptForPlatform1.class)); } TreeWrapperOptions treeWrapperOptions = new TreeWrapperOptions(); BeanUtilForVCI.convert(treeQueryObject,treeWrapperOptions); treeWrapperOptions.setParentFieldName("pkFatherDepartment"); List trees = revisionModelUtil.doList2Trees(orgDepartmentVOList, treeWrapperOptions, dept -> { return dept.getId() + " " + dept.getName() + (FrameworkDataLCStatus.DISABLED.getValue().equals(dept.getLcStatus()) ? "【停用】" : ""); }); //extandParamsMap中添加"showAllDepartmentNode"为"true"时,并且parentOid为空,返回结果中会包含“所有部门”这个节点 if(Func.isBlank(pkFatherDepartmment) && (Func.isNotEmpty(extandParamsMap) && Boolean.parseBoolean(extandParamsMap.getOrDefault("showAllDepartmentNode","false")))){ List treeList = new ArrayList<>(); Tree tree = new Tree(); tree.setLeaf(false); tree.setParentId(null); //没有实际作用只是界面上渲染使用 tree.setOid(UUID.randomUUID().toString()); tree.setParentName(null); Map map = new HashMap<>(); map.put("name","所有部门"); map.put("ALLDept","ALLDept"); tree.setAttributes(map); tree.setChildren(trees); treeList.add(tree); return treeList; } return trees; } /** * 参照树形表格的部门信息,上级部门的是表格中的树形列 * @param treeQueryObject 树形查询的条件 * @return 部门的树表信息 */ @Override public DataGrid refTreeGridDept(TreeQueryObject treeQueryObject) { String pkFatherDepartmment=treeQueryObject.getParentOid(); Map conditionMap = treeQueryObject.getConditionMap(); if(conditionMap==null){ conditionMap=new HashMap(); } List orgDepartmentVOList=new ArrayList(); if(treeQueryObject.isQueryAllLevel()){ orgDepartmentVOList = listAllLevelChildrenDeptByParentOid(pkFatherDepartmment, conditionMap); }else{ conditionMap.put("plparentuid", pkFatherDepartmment); VciQueryWrapperForDO queryWrapperForDO = new VciQueryWrapperForDO(conditionMap,OrgDeptForPlatform1.class); orgDepartmentVOList = deptDO2VOs(boService.selectByQueryWrapper(queryWrapperForDO,OrgDeptForPlatform1.class)); } DataGrid dataGrid = new DataGrid(); dataGrid.setData(orgDepartmentVOList); if(!CollectionUtils.isEmpty(orgDepartmentVOList)){ dataGrid.setTotal(orgDepartmentVOList.size()); } return dataGrid; } /** * 保存部门用户关联信息,带查重功能 * @param userOIds 用户id * @param deptId 部门id * @return */ @Override public boolean saveUsersDept(String[] userOIds, String deptId) throws PLException { VciBaseUtil.alertNotNull(deptId,"部门主键"); //为空的话说明是清空当前这个部门下分配的成员 SessionInfo sessionInfo = WebThreadLocalUtil.getCurrentUserSessionInfoInThread(); UserEntityInfo userEntityInfo = new UserEntityInfo(sessionInfo.getUserId(), null); boolean resBoolean = platformClientUtil.getFrameworkService().saveRighForDept(deptId, userOIds, userEntityInfo); return resBoolean; } /** * 增加部门信息 * @param orgDepartmentDTO * @return */ @Override public boolean addDept(OrgDepartmentDTO orgDepartmentDTO) throws PLException { //判空 VciBaseUtil.alertNotNull( orgDepartmentDTO,"添加的部门对象", orgDepartmentDTO.getName(),"部门名"); //部门名和编号判重 Map conditionMap = new HashMap<>(); conditionMap.put("plname",QueryOptionConstant.OR + orgDepartmentDTO.getName()); if(Func.isNotBlank(orgDepartmentDTO.getId())){ conditionMap.put("plnum",QueryOptionConstant.OR + orgDepartmentDTO.getId()); } List departmentVOS = getDeptByDeptpOidAndCondition(orgDepartmentDTO.getPkFatherDepartment(), conditionMap); if(Func.isNotEmpty(departmentVOS)){ throw new VciBaseException("同一父节点下该部门名称或编号已经存在,请修改!"); } SessionInfo loginUser = WebThreadLocalUtil.getCurrentUserSessionInfoInThread(); String userId = loginUser.getUserId(); //生成存储的corba对象 orgDepartmentDTO.setCreateTime(new Date()); orgDepartmentDTO.setCreator(userId); orgDepartmentDTO.setLastModifier(userId); orgDepartmentDTO.setStatus((short) 0); DeptInfo deptInfo = changeOrgDeptDTOToDeptInfo(orgDepartmentDTO); UserEntityInfo userEntityInfo = new UserEntityInfo(userId, ""); String oid = platformClientUtil.getFrameworkService().saveDepartment(deptInfo, userEntityInfo); if (Func.isEmpty(oid)) { return false; } return true; } /** * 修改部门信息 * @param orgDepartmentDTO * @return */ @Override public boolean updateDept(OrgDepartmentDTO orgDepartmentDTO) throws PLException { //判空 VciBaseUtil.alertNotNull( orgDepartmentDTO,"修改的部门对象", orgDepartmentDTO.getOid(),"用户主键", orgDepartmentDTO.getId(),"用户名" ); //按oid查询数据库中已存在的,确保修改的部门存在 OrgDepartmentVO dbDepartmentVO = getDeptByDeptOid(orgDepartmentDTO.getOid()); if(Func.isEmpty(dbDepartmentVO)){ throw new VciBaseException("修改的部门不存在!"); } //部门名和编号判重,避免新家部门重复 Map conditionMap = new HashMap<>(); conditionMap.put("plname",QueryOptionConstant.OR + orgDepartmentDTO.getName()); if(Func.isNotBlank(orgDepartmentDTO.getId())){ conditionMap.put("plnum",QueryOptionConstant.OR + orgDepartmentDTO.getId()); } List repeatDepartmentVOS = getDeptByDeptpOidAndCondition(orgDepartmentDTO.getPkFatherDepartment(), conditionMap); repeatDepartmentVOS = repeatDepartmentVOS.stream().filter(item -> { if((item.getName().equals(orgDepartmentDTO.getName()) || item.getId().equals(orgDepartmentDTO.getId())) && !item.getOid().equals(orgDepartmentDTO.getOid())){ return true; } return false; }).collect(Collectors.toList()); if(Func.isNotEmpty(repeatDepartmentVOS) ){ throw new VciBaseException("同一父节点下该部门名称或编号已经存在,请修改!"); } OrgDepartmentDTO departmentDTO = new OrgDepartmentDTO(); BeanUtilForVCI.convert(dbDepartmentVO,departmentDTO); departmentDTO.setCode(orgDepartmentDTO.getCode()); departmentDTO.setId(orgDepartmentDTO.getId()); departmentDTO.setSpecialties(orgDepartmentDTO.getSpecialties()); departmentDTO.setDescription(orgDepartmentDTO.getDescription()); departmentDTO.setName(orgDepartmentDTO.getName()); String loginUserId = WebThreadLocalUtil.getCurrentUserSessionInfoInThread().getUserId(); orgDepartmentDTO.setLastModifier(loginUserId); DeptInfo deptInfo = changeOrgDeptDTOToDeptInfo(departmentDTO); boolean updateBoolean = platformClientUtil.getFrameworkService().updateDepartment(deptInfo, new UserEntityInfo(loginUserId, null)); return updateBoolean; } /** * Dto对象转corb对象 * @param orgDepartmentDTO * @return */ public DeptInfo changeOrgDeptDTOToDeptInfo(OrgDepartmentDTO orgDepartmentDTO) { DeptInfo departmentInfo = new DeptInfo(); departmentInfo.id = orgDepartmentDTO.getOid() == null ? "" : orgDepartmentDTO.getOid(); departmentInfo.name = orgDepartmentDTO.getName() == null ? "" : orgDepartmentDTO.getName(); departmentInfo.num = orgDepartmentDTO.getId() == null ? "" : orgDepartmentDTO.getId(); departmentInfo.code = orgDepartmentDTO.getCode() == null ? "" : orgDepartmentDTO.getCode(); departmentInfo.specialties = orgDepartmentDTO.getSpecialties() == null ? "" : orgDepartmentDTO.getSpecialties(); departmentInfo.status = orgDepartmentDTO.getStatus() == 0 ? 0 : orgDepartmentDTO.getStatus(); departmentInfo.description = orgDepartmentDTO.getDescription() == null ? "" : orgDepartmentDTO.getDescription(); departmentInfo.parentId = orgDepartmentDTO.getPkFatherDepartment() == null ? "" : orgDepartmentDTO.getPkFatherDepartment(); departmentInfo.createUser = orgDepartmentDTO.getCreator() == null ? "" : orgDepartmentDTO.getCreator(); departmentInfo.createTime = orgDepartmentDTO.getCreateTime().getTime(); departmentInfo.updateTime = System.currentTimeMillis(); departmentInfo.updateUser = orgDepartmentDTO.getLastModifier() == null ? "" : orgDepartmentDTO.getLastModifier(); //departmentInfo.grantor = orgDepartmentDTO.getGrantor() == null ? "" : orgDepartmentDTO.getGrantor(); return departmentInfo; } /** * 删除部门 * @param ids * @return */ @Override public boolean deleteDept(String[] ids) throws PLException { VciBaseUtil.alertNotNull(ids,"要删除的部门主键"); //TODO:考虑是否需要添加删除前判断部门下是否配置有用户,这种情况应该不允许删除 //TODO: 应该是不具备连带删除的功能,部门删除后用户关联的无用部门还在,考虑后期是否需要做,数据量不大可以不做连带删除 return platformClientUtil.getFrameworkService().deleteDepartment( ids, new UserEntityInfo(WebThreadLocalUtil.getCurrentUserSessionInfoInThread().getUserId(), null) ); } /** * 下载导入部门的excel模板。 * @param downloadFileName * @return */ @Override public String downloadImportTemplate(String downloadFileName) { //界面没传名称,使用默认名称 downloadFileName = Func.isBlank(downloadFileName) ? "部门导入模板_" + Func.format(new Date(),"yyyy-MM-dd HHmmss.sss"):downloadFileName; // 设置表单列名 List columns = new ArrayList<>(Arrays.asList("名称", "编号", "代号", "专业", "父部门名称全路径(/间隔)", "描述")); //设置必填列 ColumnNameisRed.clear(); ColumnNameisRed.add(0); ColumnNameisRed.add(1); //写excel String excelPath = LocalFileUtil.getDefaultTempFolder() + File.separator + downloadFileName + ".xls"; try { new File(excelPath).createNewFile(); } catch (Throwable e) { throw new VciBaseException(LangBaseUtil.getErrorMsg(e), new String[]{excelPath}, e); } //设置列 List excelDataList = new ArrayList<>(); for (int index = 0; index < columns.size(); index++) { //判断是否为必填列,给必填列设置颜色 if(ColumnNameisRed.contains(index)){ WriteExcelData excelData = new WriteExcelData(0, index, columns.get(index)); excelData.setFontColor(String.valueOf(HSSFColor.HSSFColorPredefined.RED.getIndex())); excelDataList.add(excelData); }else{ excelDataList.add(new WriteExcelData(0,index, columns.get(index))); } } WriteExcelOption excelOption = new WriteExcelOption(excelDataList); ExcelUtil.writeDataToFile(excelPath, excelOption); return excelPath; } /** * 导入部门 * @param file * @return * @throws VciBaseException */ @Override public BaseResult importDept(File file) throws Exception { VciBaseUtil.alertNotNull(file,"excel文件"); if(!file.exists()){ throw new VciBaseException("导入的excel文件不存在,{0}",new String[]{file.getPath()}); } try{ //1、读取excel中的数据,组成对象 ReadExcelOption excelOption = new ReadExcelOption(); //当前登录的用户账号 //String loginUserId = WebThreadLocalUtil.getCurrentUserSessionInfoInThread().getUserId(); String loginUserId = "developer"; UserEntityInfo userEntityInfo = new UserEntityInfo(loginUserId,null); List poList = ExcelUtil.readDataObjectFromExcel(file, OrgDeptPO.class,excelOption,(value, po, fieldName)->{}); //去除都是空的情况 if(CollectionUtils.isEmpty(poList)){ return BaseResult.fail(ExcelLangCodeConstant.IMPORT_CONTENT_NULL,new String[]{}); } //2、必填判空、判重(数据库判重和excel中判重),组装成保存用的数据对象 List deptInfoList = new ArrayList<>(); //2.1、用以存储excel中重复的数据,两个不可重复的字段)(Name不能为空,Name、Code同一父部门下唯一) Map repeatNameMap = new HashMap<>(); Map repeatNumMap = new HashMap<>(); Map indexMap = new HashMap<>(); //2.2、存储用户手输的oid和实际存储oid的映射关系 Map oidMap = new HashMap<>(); //查询系统中部门,其中包含了部门名称树属性 List dbOrgDepartmentVOList = this.getDeptAllFullName(); //遍历成map对象:key为DeptName的全路径:value为Dept对象(用户处理部门父组件) Map dbOrgDepartFullNameOidMap = dbOrgDepartmentVOList.stream().collect(Collectors.toMap(OrgDepartmentVO::getFullDeptNamePath, OrgDepartmentVO::getOid)); //用来判断处parentName既不在库中存在,又不在poNames存在的情况 List poNames = poList.stream().map(OrgDeptPO::getName).collect(Collectors.toList()); poList.stream().forEach(po->{ String parentFullNamePath = Func.isBlank(po.getParentFullNamePath()) ? "":po.getParentFullNamePath(); //部门名称判空,通常通过po中的注解就可实现 if(Func.isBlank(po.getName())){ throw new VciBaseException("第【"+po.getRowIndex()+"】行,depterror,Reason:Name cannot be empty"); }else if(parentFullNamePath.equals(repeatNameMap.getOrDefault(po.getName(), null))/*excel中同一部门下Name相等*/){ //同一部门下名称判重 throw new VciBaseException("第【"+po.getRowIndex()+"】行,deptnameerror,Reason: Names under the same department cannot be duplicated"); }else if(Func.isNotBlank(po.getNum()) && parentFullNamePath.equals(repeatNumMap.getOrDefault(po.getNum(),null))/*excel中同一部门下编号存在 */){ throw new VciBaseException("第【"+po.getRowIndex()+"】行,deptnumerror,Reason: The number cannot be duplicated"); }else{ //2.2、查询数据库中的数据(查重ID和NUM),比较麻烦需要根据ParentName全路径查询(所有只能单条查询进行判重) //同一部门下(parentName相等),name或者num相等 List repeatOrgDept = dbOrgDepartmentVOList.stream().filter(item -> { //同一部门名称全路径下,部门名称相等、部门编号不为空并且和系统中存在相等的编号 boolean isNameOrNumRepeat = po.getName().equals(item.getName()) || (Func.isNotBlank(po.getNum()) && po.getNum().equals(item.getId())); /*当parentFullNamePath为""时item.getFullDeptNamePath().contains(parentFullNamePath)永远为true, 所以需要特殊处理直接判断顶层的部门是否存在重复*/ if(((Func.isBlank(parentFullNamePath) && item.getTreelevel() == 1) || (Func.isNotBlank(parentFullNamePath) && item.getFullDeptNamePath().contains(parentFullNamePath))) && isNameOrNumRepeat) { return true; } return false; }).collect(Collectors.toList()); //只要不为空就说明当前行数据在系统中重复 if(Func.isNotEmpty(repeatOrgDept)){ throw new VciBaseException("第【"+po.getRowIndex()+"】行,deptname or deptnum error,Reason: The name or number already exists in the system"); } } //存储校验通过的数据,以便后续excel查重 repeatNameMap.put(po.getName(),parentFullNamePath); if(Func.isNotBlank(po.getNum())){ repeatNumMap.put(po.getNum(),parentFullNamePath); } indexMap.put(po.getName(),po.getRowIndex()); //校验数据就该组装成DTO数据对象了 OrgDepartmentDTO dto = new OrgDepartmentDTO(); BeanUtilForVCI.convert(po,dto); dto.setOid(po.getId()); dto.setId(po.getNum()); dto.setDescription(po.getDesc()); dto.setSpecialties(po.getSpecialties()); dto.setCreateTime(new Date()); dto.setCreator(loginUserId); dto.setLastModifier(loginUserId); dto.setStatus((short) 0); //给导入的数据设置的主键 String oid = VciBaseUtil.getPk().toUpperCase(Locale.ROOT); dto.setOid(oid); /*处理部门名称全路径转换为PkFatherDepartment(部门主键): 情况1、直属父部门是系统中已存在(判断方式:部门名称全路径在dbOrgDepartmentVOList中存在,fullDeptNamePath全等于parentFullNamePath)。 情况2、直属父部门不是系统中已存在的,但是直属父部门的的上级部门是系统中已存在的(涉及到oid和parentoid对应关系处理比较麻烦)。 情况3、直属父部门和其上级部门都是excel中新构建的。(涉及到oid和parentoid对应关系处理比较麻烦)*/ String dbDeptoid = dbOrgDepartFullNameOidMap.getOrDefault(parentFullNamePath, null); //情况1可以直接设置parentOid。 if(Func.isNotEmpty(dbDeptoid) || "".equals(parentFullNamePath)){ //设置父部门主键 dto.setPkFatherDepartment(dbDeptoid); }else{ //处理父路径名既不存在于数据库又不存在于当前excel String lastParentFullName = parentFullNamePath.substring(parentFullNamePath.lastIndexOf("/") + 1);//父路径名的最后一个部门名称 if(Func.isBlank(dbOrgDepartFullNameOidMap.getOrDefault(parentFullNamePath,null)) && !poNames.contains(lastParentFullName) ){ throw new VciBaseException("当前导入的部门数据中,第【" + indexMap.get(po.getName()) + "】行,父部门设置存在问题!"); } //情况2和3需要通过映射关系设置parentoid,所以这里先标记后续再做处理。 dto.setPkFatherDepartment("Pending:" + parentFullNamePath); } //存储parentOid:oid映射关系 String key = Func.isBlank(parentFullNamePath) ? po.getName():parentFullNamePath + "/"+po.getName(); oidMap.put(key,oid); DeptInfo deptInfo = this.changeOrgDeptDTOToDeptInfo(dto); deptInfoList.add(deptInfo); }); //3、处理oid和parentOid的映射关系:针对新加的数据是父部门 deptInfoList.stream().forEach(info -> { try { //parentId不为空并且没有Pending:相关的字符串,说明是需要处理oid映射parentOid的 if (info.parentId.contains("Pending:")){ //系统中已存在的父部门OID,需要移除掉Dept:标识 String key = info.parentId.replace("Pending:",""); String parentId = oidMap.get(key); info.parentId = parentId; } //4、保存操作 platformClientUtil.getFrameworkService().saveDepartment( info, userEntityInfo ); } catch (PLException e) { e.printStackTrace(); throw new VciBaseException("保存时出现错误!,原因:"+VciBaseUtil.getExceptionMessage(e)); } }); }catch (Exception e){ if(logger.isErrorEnabled()){ logger.error("读取excel内容时或保存部门时出现了错误,具体原因:",e.getMessage()); } e.printStackTrace(); return BaseResult.fail(LangBaseUtil.getErrorMsg(e),new String[]{},e); } return BaseResult.success("部门导入成功!"); } /** * 获取所有部门的信息 * @return key:部门由名称组成的路径(/间隔),value对应最小层级的部门信息 */ @Override public Map getDeptAllTreeMap() { List orgDepartmentVOList = listAllLevelChildrenDeptByParentOid(null, null); Map stringOrgDepartmentVOMap = convertToMap(orgDepartmentVOList); return stringOrgDepartmentVOMap; } /** * 获取部门由名称组成的路径(/间隔),value对应最小层级的部门信息 * @param orgDepartmentVOList * @return */ private Map convertToMap(List orgDepartmentVOList) { Map map = new HashMap<>(); for (OrgDepartmentVO orgDepartmentVO : orgDepartmentVOList) { String key = buildKey(orgDepartmentVO, orgDepartmentVOList); map.put(key, orgDepartmentVO); } return map; } private String buildKey(OrgDepartmentVO orgDepartmentVO, List orgDepartmentVOList) { StringBuilder keyBuilder = new StringBuilder(); OrgDepartmentVO current = orgDepartmentVO; while (current != null) { keyBuilder.insert(0, current.getName()); keyBuilder.insert(0, "/"); current = getParentDepartment(current.getPkFatherDepartment(), orgDepartmentVOList); } keyBuilder.deleteCharAt(0); return keyBuilder.toString(); } private OrgDepartmentVO getParentDepartment(String pkFatherDepartment, List orgDepartmentVOList) { for (OrgDepartmentVO orgDepartmentVO : orgDepartmentVOList) { if (pkFatherDepartment != null && pkFatherDepartment.equals(orgDepartmentVO.getOid())) { return orgDepartmentVO; } } return null; } }