xiejun
2024-09-13 b8d0022a3c40c59322661e8eee568643fdeb9c50
Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/frameworkcore/compatibility/impl/SmUserQueryServiceImpl.java
@@ -1,38 +1,57 @@
package com.vci.frameworkcore.compatibility.impl;
import com.vci.client.common.providers.ServiceProvider;
import com.vci.corba.framework.data.DeptInfo;
import com.vci.corba.framework.data.RoleInfo;
import com.vci.dto.SmUserDTO;
import com.vci.common.util.ThreeDES;
import com.vci.corba.common.PLException;
import com.vci.corba.common.data.UserEntityInfo;
import com.vci.corba.framework.data.UserInfo;
import com.vci.corba.omd.data.BusinessObject;
import com.vci.frameworkcore.compatibility.OrgDeptQueryServiceI;
import com.vci.frameworkcore.compatibility.SmPwdStrategyQueryServiceI;
import com.vci.frameworkcore.compatibility.SmRoleQueryServiceI;
import com.vci.frameworkcore.compatibility.SmUserQueryServiceI;
import com.vci.frameworkcore.pagemodel.SmPasswordStrategyVO;
import com.vci.frameworkcore.pagemodel.SmUserVO;
import com.vci.frameworkcore.enumpck.OrgTypeEnum;
import com.vci.model.SmUserDO;
import com.vci.pagemodel.SmUserVO;
import com.vci.po.SmUserPO;
import com.vci.pagemodel.OrgDepartmentVO;
import com.vci.pagemodel.SmPasswordStrategyVO;
import com.vci.pagemodel.SmRoleVO;
import com.vci.frameworkcore.properties.ConfigCorbaReader;
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.web.enumpck.BooleanEnum;
import com.vci.starter.web.enumpck.UserSecretEnum;
import com.vci.starter.web.exception.VciBaseException;
import com.vci.starter.web.pagemodel.DataGrid;
import com.vci.starter.web.pagemodel.PageHelper;
import com.vci.starter.web.pagemodel.Tree;
import com.vci.starter.web.pagemodel.TreeQueryObject;
import com.vci.starter.web.util.BeanUtil;
import com.vci.starter.web.util.VciBaseUtil;
import com.vci.starter.web.pagemodel.*;
import com.vci.starter.web.util.*;
import com.vci.starter.web.wrapper.VciQueryWrapperForDO;
import com.vci.web.model.SmPasswordStrategyDO;
import com.vci.web.model.SmUserDO;
import com.vci.web.enumpck.UserTypeEnum;
import com.vci.web.service.WebBoServiceI;
import com.vci.web.util.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.apache.poi.ss.formula.functions.T;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;
import static com.vci.frameworkcore.constant.FrameWorkBusLangCodeConstant.DATA_OID_NOT_EXIST;
import static com.vci.web.constant.CacheNameConstant.VCI_USER;
import static com.vci.web.util.WebUtil.arryAndSqlToClientBusinessObject;
import static com.vci.web.util.WebUtil.arryAndSqlToBusinessObject;
/**
 * 用户的查询相关的服务,可以兼容老平台和老的pdm
@@ -55,6 +74,24 @@
    */
   @Autowired
   private WebBoServiceI boService;
   /**
    * 部门服务
    */
   @Autowired
   private OrgDeptQueryServiceI orgDeptQueryService;
   /**
    * 角色服务
    */
   @Autowired
   private SmRoleQueryServiceI smRoleQueryService;
   /**
    * 密码策略查询服务
    */
   @Autowired
   private SmPwdStrategyQueryServiceI smPwdStrategyQueryService;
   /**
    * 使用角色的属性查询用户时
@@ -82,11 +119,49 @@
   public static final String QUERY_FIELD_ROLE = "roleUser.plroleuid";
   /**
    * 自引用
    * 必填列
    */
   @Autowired(required = false)
   @Lazy
   private SmUserQueryServiceI self;
   private List<Integer> ColumnNameisRed = new ArrayList<Integer>();
   /**
    * 用户分页查询时获取部门放到这里避免重复查询
    */
   private Map<String,Map<String,String>> orgDepartmentVOMap;
   /**
    * 用户分页查询时获取角色放到这里避免重复查询
    */
   private Map<String,List<SmRoleVO>> smRoleVOMap;
   /**
    * 用户分页查询时获取密码策略放到这里避免多次查询
    */
   private Map<String,SmPasswordStrategyVO> smPwdStrategyVOMap;
   /**
    * 日志
    */
   private Logger logger = LoggerFactory.getLogger(getClass());
   /**
    * 检查用户是否存在,可以根据用户名,也可以根据用户oid
    * @param userName  传null,即用oid作为检查条件
    * @param oid    传null,即用userName作为检查条件
    * @return true存在,false不存在
    */
   @Override
   public boolean checkUserExist(String userName, String oid) throws PLException {
      if(Func.isEmpty(userName) && Func.isEmpty(oid)){
         throw new PLException("500", new String[] { "检查用户是否存在时,传递的参数用户名和用户oid都为空!"});
      }
      UserInfo userInfo = null;
      if(Func.isNotEmpty(userName)) {
         userInfo = platformClientUtil.getFrameworkService().getUserObjectByUserName(userName);
      }else{
         userInfo = platformClientUtil.getFrameworkService().getUserObjectByoid(oid);
      }
      return Func.isNotEmpty(userInfo);
   }
   /**
     *  根据用户名获取用户的对象,不区分大小写
@@ -95,10 +170,14 @@
     * @throws VciBaseException 参数为空或者数据库存在问题的时候会抛出异常
     */
   @Override
   @Cacheable(value = VCI_USER,key = "#p0",unless = "#result == null")
   public SmUserVO getUserByUserId(String userId) throws VciBaseException {
      WebUtil.alertNotNull(userId,"用户名");
      return getUserByField("plusername",userId);
        try {
            UserInfo userInfo = platformClientUtil.getFrameworkService().getUserObjectByUserName(userId);
         return userInfo2VO(userInfo);
        } catch (PLException e) {
            throw new VciBaseException("登录时,获取用户信息失败:"+e.getMessage());
        }
   }
   /**
@@ -108,8 +187,8 @@
    * @return 用户的信息
    * @throws VciBaseException 查询出错的时候会抛出异常
    */
   private SmUserVO getUserByField(String queryField,String queryValue) throws VciBaseException{
      VciQueryWrapperForDO queryWrapper = new VciQueryWrapperForDO(null,SmUserDO.class,null,true);
   private SmUserVO getUserByField(String queryField, String queryValue) throws VciBaseException{
      VciQueryWrapperForDO queryWrapper = new VciQueryWrapperForDO(null, SmUserDO.class,null,true);
      queryWrapper.eq(queryWrapper.getTableNick() + "." +queryField,queryValue);
      queryWrapper.setDistinct(true);
      queryWrapper.wrapperSql();
@@ -120,9 +199,9 @@
            " left join PLUSERPASSWORDSTRATEGY pkUserPassword on  " +queryWrapper.getTableNick() + ".pluid = pkUserPassword.pluseruid " +
            queryWrapper.getLinkTableSql() + (StringUtils.isNotBlank(queryWrapper.getWhereSql())?(" where " + queryWrapper.getWhereSql()):"");
      try{
         String[][] sqlQueryResult = ServiceProvider.getBOFService().getSqlQueryResult(sql + fromSql, null);
         String[][] sqlQueryResult = platformClientUtil.getBOFService().getSqlQueryResult(sql + fromSql, null);
         if(sqlQueryResult.length>0){
            com.vci.client.bof.ClientBusinessObject cbo = arryAndSqlToClientBusinessObject(queryWrapper.getSelectFieldSql(),sqlQueryResult[0]);
            BusinessObject cbo = arryAndSqlToBusinessObject(queryWrapper.getSelectFieldSql(),sqlQueryResult[0]);
            return cbo2VO(cbo);
         }
      }catch (Exception e){
@@ -150,7 +229,7 @@
               + " left join pluserdept up on " + queryWrapper.getTableNick() + ".pluid = up.pluseruid left join pldept pkDepartment on  up.pldeptuid = pkDepartment.pluid " +
               " left join PLUSERPASSWORDSTRATEGY pkUserPassword on  " +queryWrapper.getTableNick() + ".pluid = pkUserPassword.pluseruid " +
               queryWrapper.getLinkTableSql() + (StringUtils.isNotBlank(queryWrapper.getWhereSql())?(" where " + queryWrapper.getWhereSql()):"");
         List<com.vci.client.bof.ClientBusinessObject> dataList = boService.queryBySql(sql + fromSql, null);
         List<BusinessObject> dataList = boService.queryBySql(sql + fromSql, null);
         if(!CollectionUtils.isEmpty(dataList)){
            dataList.stream().forEach(cbo->{
               userVOList.add(cbo2VO(cbo));
@@ -169,8 +248,14 @@
   @Override
   public List<SmUserVO> listUserByUserIds(Collection<String> userIdCollections)throws VciBaseException {
      WebUtil.alertNotNull(userIdCollections,"用户名集合");
      return listUserByField("plusername",userIdCollections);
      try {
         UserInfo[] userInfo = platformClientUtil.getFrameworkService().fetchUserInfoByNames(VciBaseUtil.collection2StrArr(userIdCollections));
         return userInfoArr2VO(userInfo);
      } catch (PLException e) {
         throw new VciBaseException("获取用户失败:"+e.getMessage());
      }
   }
   /**
     * 根据用户主键获取用户的信息
     * @param userOid 用户主键
@@ -180,8 +265,14 @@
   @Override
   public SmUserVO getUserByUserOid(String userOid) throws VciBaseException {
      WebUtil.alertNotNull(userOid,"用户主键");
      return getUserByField("pluid",userOid);
        try {
            UserInfo userInfo = platformClientUtil.getFrameworkService().getUserObjectByoid(userOid);
         return userInfo2VO(userInfo);
        } catch (PLException e) {
            throw new VciBaseException("获取用户失败:"+e.getMessage());
        }
   }
    /**
     * 批量获取用户的信息 (根据用户主键)
     * @param userOidCollections 用户主键的集合,可以超过1000个
@@ -189,10 +280,106 @@
     * @throws VciBaseException 参数为空或者数据库存在问题的时候会抛出异常
     */
   @Override
   public List<SmUserVO> listUserByUserOids(
         Collection<String> userOidCollections) throws VciBaseException {
   public List<SmUserVO> listUserByUserOids(Collection<String> userOidCollections) throws VciBaseException {
      WebUtil.alertNotNull(userOidCollections,"用户主键集合");
      return listUserByField("pluid",userOidCollections);
        try {
            UserInfo[] userInfoArr = platformClientUtil.getFrameworkService().getUserObjectByoids(VciBaseUtil.collection2StrArr(userOidCollections));
         return userInfoArr2VO(userInfoArr);
        } catch (PLException e) {
            throw new VciBaseException("获取用户信息失败:"+e.getMessage());
        }
   }
   /**
    * 业务数据数组转显示对象集合
    * @param userInfoArr 业务数据数组
    * @return 显示对象集合
    */
   private List<SmUserVO> userInfoArr2VO(UserInfo[] userInfoArr) throws PLException {
      List<SmUserVO> userVOList = new ArrayList<>();
      for(UserInfo userInfo : userInfoArr){
         userVOList.add(userInfo2VO(userInfo));
      }
      return userVOList;
   }
   /**
    * 业务数据转换为显示对象
    * @param userInfo 平台返回的业务数据
    * @return 用户显示对象
    */
   private SmUserVO userInfo2VO(UserInfo userInfo) throws PLException {
      if(Func.isBlank(userInfo.id)){
         return new SmUserVO();
      }
      SmUserVO smUserVO = new SmUserVO();
      smUserVO.setOid(userInfo.id);
      smUserVO.setId(userInfo.userName);
      smUserVO.setName(userInfo.trueName);
      smUserVO.setSecretGrade(userInfo.secretGrade);
      smUserVO.setSecretGradeText(UserSecretEnum.getSecretText(userInfo.secretGrade));
      smUserVO.setUserType(String.valueOf(userInfo.userType));
      smUserVO.setUserTypeText(UserTypeEnum.getTextByValue(String.valueOf(userInfo.userType)));
      smUserVO.setDescription(userInfo.desc);
      smUserVO.setEmail(userInfo.email);
      smUserVO.setStatus(userInfo.status);
      smUserVO.setPassword(userInfo.pwd);
      smUserVO.setConfirmPassword(userInfo.pwd);
      //用户所属部门的查询设置
      Map<String,String> orgDepartmentVOList;
      //查看全局变量中是否存在部门信息,存在的情况最主要是针对多条用户查询的时候避免重复查询的
      if(Func.isNotEmpty(orgDepartmentVOMap)){
         orgDepartmentVOList = Func.isNotEmpty(orgDepartmentVOMap.get(userInfo.id)) ?
               orgDepartmentVOMap.get(userInfo.id):new HashMap<>();
      }else {
         Map<String, Map<String, String>> tempDeptMap = orgDeptQueryService.batchMapDeptNameByUserOids(Arrays.asList(userInfo.id), null);
         orgDepartmentVOList = Func.isNotEmpty(tempDeptMap.get(userInfo.id)) ?
               tempDeptMap.get(userInfo.id):new HashMap<>();
      }
      //部门oid,正常情况下一个用户只会存在一个部门下
      smUserVO.setPkDepartment(orgDepartmentVOList.keySet().stream().collect(Collectors.joining(",")));
      smUserVO.setPkDepartmentName(orgDepartmentVOList.values().stream().collect(Collectors.joining(",")));
      //密码策略查询设置
      SmPasswordStrategyVO smPasswordStrategyVO;
      if(Func.isNotEmpty(smPwdStrategyVOMap)){
         smPasswordStrategyVO = smPwdStrategyVOMap.getOrDefault(userInfo.id,new SmPasswordStrategyVO());
      }else {
         smPasswordStrategyVO = smPwdStrategyQueryService.getPasswordStrategyVOByUserOid(userInfo.id);
         //如果不存在就获取默认的
         smPasswordStrategyVO = Func.isNotEmpty(smPasswordStrategyVO) ? smPasswordStrategyVO:smPwdStrategyQueryService.getPasswordStrategyVOByDefault();
      }
      smUserVO.setPkPasswordStrategy(smPasswordStrategyVO.getOid());
      smUserVO.setPkPasswordStrategyName(smPasswordStrategyVO.getName());
      //角色查询设置
      List<SmRoleVO> smRoleVOList;
      if (Func.isNotEmpty(smRoleVOMap)) {
         smRoleVOList = smRoleVOMap.get(userInfo.id);
      }else {
         smRoleVOList = smRoleQueryService.listRoleByUserOid(userInfo.id,null);
      }
      smUserVO.setPkPerson(
            Func.isEmpty(smRoleVOList) ?
                  null:smRoleVOList.stream().map(SmRoleVO::getOid).collect(Collectors.joining(","))
      );
      smUserVO.setPkPersonName(
            Func.isEmpty(smRoleVOList) ?
                  null:smRoleVOList.stream().map(SmRoleVO::getName).collect(Collectors.joining(","))
      );
      //是否部门领导
      smUserVO.setIsDeptLeader(userInfo.isDeptLeader.equals("0") ? "不是":"是");
      //专业
      smUserVO.setSpecialties(userInfo.specialties);
      if(userInfo.status == 0){
         smUserVO.setLockFlag(false);
      }else{
         smUserVO.setLockFlag(true);
      }
      smUserVO.setCreator(userInfo.createUser);
      smUserVO.setCreateTime(VciDateUtil.long2Date(userInfo.createTime));
      smUserVO.setLastModifier(userInfo.updateUser);
      smUserVO.setLastLoginTime(VciDateUtil.long2Date(userInfo.updateTime));
      smUserVO.setLastModifyPasswordTime(VciDateUtil.long2Date(userInfo.pwdUpdateTime));
      return smUserVO;
   }
   /**
@@ -203,11 +390,20 @@
   private List<SmUserVO> smUserDO2VOs(List<SmUserDO> userDOS){
      List<SmUserVO> userVOList = new ArrayList<>();
      Optional.ofNullable(userDOS).orElseGet(()->new ArrayList<>()).stream().forEach(userDO->{
         SmUserVO userVO = new SmUserVO();
         BeanUtil.convert(userDO,userVO);
         userVOList.add(userVO);
         userVOList.add(smUserDO2VO(userDO));
      });
      return userVOList;
   }
   /**
    * 用户的数据对象转换为显示对象
    * @param smUserDO
    * @return
    */
   private SmUserVO smUserDO2VO(SmUserDO smUserDO){
      SmUserVO smUserVO = new SmUserVO();
      BeanUtil.convert(smUserDO,smUserVO);
      return smUserVO;
   }
   /**
@@ -231,7 +427,7 @@
            + " left join pluserdept up on " + queryWrapper.getTableNick() + ".pluid = up.pluseruid left join pldept pkDepartment on  up.pldeptuid = pkDepartment.pluid " +
            " left join PLUSERPASSWORDSTRATEGY pkUserPassword on  " +queryWrapper.getTableNick() + ".pluid = pkUserPassword.pluseruid " + (QUERY_FIELD_ROLE.equalsIgnoreCase(queryField)?roleSql:"") +
            queryWrapper.getLinkTableSql() + (StringUtils.isNotBlank(queryWrapper.getWhereSql())?(" where " + queryWrapper.getWhereSql()):"");
      List<com.vci.client.bof.ClientBusinessObject> dataList = boService.queryBySql(sql + fromSql, null);
      List<BusinessObject> dataList = boService.queryBySql(sql + fromSql, null);
      if(!CollectionUtils.isEmpty(dataList)){
         dataList.stream().forEach(cbo->{
            userVOList.add(cbo2VO(cbo));
@@ -245,7 +441,7 @@
    * @param cbo 业务数据
    * @return 显示对象
    */
   private SmUserVO cbo2VO(com.vci.client.bof.ClientBusinessObject cbo){
   private SmUserVO cbo2VO(BusinessObject cbo){
      SmUserDO userDO = new SmUserDO();
      SmUserVO userVO = new SmUserVO();
      WebUtil.copyValueToObjectFromCbos(cbo,userDO);
@@ -268,9 +464,9 @@
    * @return 用户的显示对象的列表
    */
   private DataGrid<SmUserVO> gridUserByQueryField(String queryField,String queryValue, Map<String, String> queryMap, PageHelper pageHelper,boolean notIn){
      if(StringUtils.isBlank(queryValue)){
      /*if(StringUtils.isBlank(queryValue)){
         return new DataGrid<>();
      }
      }*/
      PageHelper newPageHelper = new PageHelper(-1);
      newPageHelper.setSort(pageHelper.getSort());
      newPageHelper.setOrder(pageHelper.getOrder());
@@ -299,7 +495,7 @@
            }
         }
      }
      List<com.vci.client.bof.ClientBusinessObject> dataList = boService.queryBySql((isPage?("select " + pageSelectList.stream().collect(Collectors.joining(","))+ " from (select A.*,rownum RN from ( "):"") + sql + fromSql + (isPage?pageSubfix:""), null);
      List<BusinessObject> dataList = boService.queryBySql((isPage?("select " + pageSelectList.stream().collect(Collectors.joining(","))+ " from (select A.*,rownum RN from ( "):"") + sql + fromSql + (isPage?pageSubfix:""), null);
      if(!CollectionUtils.isEmpty(dataList)){
         dataList.stream().forEach(cbo->{
            userVOList.add(cbo2VO(cbo));
@@ -313,17 +509,50 @@
      }
      return dataGrid;
   }
   /**
     * 获取用户的列表,默认会以用户名升序排列,用户的编辑页面列表不要使用这个接口
     * @param queryMap 查询条件
     * @param pageHelper 分页和排序的信息,在兼容老平台的时候会自动兼容,如果属性不存在会自动忽略
     * @return 用户的显示对象列表
     * @throws VciBaseException 参数为空的时候会抛出异常
     */
    * 用户管理界面分页查询
    * @param conditionMap 查询条件
    * @param pageHelper 分页参数
    * @return
    */
   @Override
   public DataGrid<SmUserVO> gridUsers(Map<String, String> queryMap,
                              PageHelper pageHelper) throws VciBaseException {
      return gridUserByQueryField(null,null,queryMap,pageHelper,false);
   public DataGrid<SmUserVO> getDataGridUsers(Map<String, String> conditionMap, PageHelper pageHelper) throws PLException {
      if(pageHelper == null){
         pageHelper = new PageHelper(-1);
      }
      pageHelper.addDefaultAsc("PLTRUENAME");
      String loginUserId = WebThreadLocalUtil.getCurrentUserSessionInfoInThread().getUserId();
      //String loginUserId = "Ludc";
      //分页查询
      UserInfo[] userInfos = platformClientUtil.getFrameworkService().fetchUserInfoByCondition(
            conditionMap.get("name"),
            conditionMap.get("id"),
            conditionMap.get("pkDepartment"),
            conditionMap.get("pkPerson"),
            loginUserId,  //当前登录的用户名
            pageHelper.getPage(),
            pageHelper.getLimit()
      );
      DataGrid<SmUserVO> dataGrid = new DataGrid<>();
      if(Func.isNotEmpty(userInfos)){
         List<String> idList = Arrays.stream(userInfos).map(item -> item.id).collect(Collectors.toList());
         orgDepartmentVOMap = orgDeptQueryService.batchMapDeptNameByUserOids(idList, null);
         smRoleVOMap = smRoleQueryService.batchListRoleByUserOids(idList,null);
         smPwdStrategyVOMap = smPwdStrategyQueryService.batchSmPwdStrategyByUserOids(idList);
         dataGrid.setData(userInfoArr2VO(userInfos));
         //TODO: 这个统计总数有问题,带过去的参数不能像上面那个fetchUserInfoByCondition查询一样统计增却的总数
         dataGrid.setTotal(
               platformClientUtil.getFrameworkService().getUserTotalByCondition(
                  conditionMap.get("name"),
                  conditionMap.get("id"),
                  conditionMap.get("pkDepartment"),
                  conditionMap.get("pkPerson"),
                  loginUserId  //当前登录的用户名
               )
         );
      }
      return dataGrid;
   }
   /**
@@ -354,9 +583,10 @@
     */
   @Override
   public String getUserNameByUserId(String userId) {
      SmUserVO userVO = self.getUserByUserId(userId);
      SmUserVO userVO = getUserByUserId(userId);
      return userVO == null?"":userVO.getName();
   }
    /**
     * 根据用户主键获取用户的姓名
     * @param userOid 用户主键
@@ -364,30 +594,132 @@
     */
   @Override
   public String getUserNameByUserOid(String userOid) {
      SmUserVO userVO = self.getUserByUserOid(userOid);
      SmUserVO userVO = getUserByUserOid(userOid);
      return userVO.getName();
   }
   /**
    * 统计部门下的用户:包含子部门下的用户
    * @param deptOid
    * @param queryMap
    * @return
    * @throws VciBaseException
    */
   @Override
   public List<SmUserVO> countSmUserByDeptOid(String deptOid, Map<String, String> queryMap) throws VciBaseException {
      //是否查询子部门下关联的用户
      List<OrgDepartmentVO> orgDepartmentVOList = orgDeptQueryService.listAllLevelChildrenDeptByParentOid(deptOid, null);
      List<String> deptOidCollection = orgDepartmentVOList.stream().map(OrgDepartmentVO::getOid).collect(Collectors.toList());
      deptOidCollection.add(deptOid);//将当前层的oid也放进去
      List<SmUserVO> smUserVOList = listUserVOByDeptOid(queryMap, deptOidCollection, false);
      if(Func.isEmpty(smUserVOList)){
         return new ArrayList<>();
      }
      Map<String, List<SmRoleVO>> smRoleVOMap = smRoleQueryService.batchListRoleByUserOids(smUserVOList.stream().map(SmUserVO::getOid).collect(Collectors.toSet()), null);
      smUserVOList = smUserVOList.stream().map(vo->{
         List<SmRoleVO> smRoleVOS = smRoleVOMap.get(vo.getOid());
         vo.setPkPerson(
               Func.isEmpty(smRoleVOS) ?
                     null:smRoleVOS.stream().map(SmRoleVO::getOid).collect(Collectors.joining(","))
         );
         vo.setPkPersonName(
               Func.isEmpty(smRoleVOS) ?
                     null:smRoleVOS.stream().map(SmRoleVO::getName).collect(Collectors.joining(","))
         );
         return vo;
      }).collect(Collectors.toList());
      return smUserVOList;
   }
    /**
     * 查询某个部门下的用户对象
     * 查询在某个部门下的用户对象
     * @param deptOid 部门的主键
     * @param queryMap 查询条件,如果是部门的某个属性作为查询条件,则可以使用pkDepartment.xxx这样的方式
     * @return 用户的显示对象列表
     * @throws VciBaseException 参数为空或者查询出错的时候会抛出异常
     */
   @Override
   public List<SmUserVO> listUserByDeptOid(String deptOid,
         Map<String, String> queryMap) throws VciBaseException {
      if(StringUtils.isBlank(deptOid)){
         return new ArrayList<>();
      }
      return listUserByQueryField(QUERY_FIELD_DEPARTMENT,deptOid,queryMap,false);
   public List<SmUserVO> listUserByDeptOid(String deptOid, Map<String, String> queryMap) throws VciBaseException {
      //查询当前选中的部门下的用户
      return listUserVOByDeptOid(queryMap,Arrays.asList(deptOid),false );
   }
   /**
    * 获取
    * 查询不在某个部门下的用户对象列表
    * @param deptOid 部门的主键
    * @param queryMap 查询条件,如果是部门的某个属性作为查询条件,则可以使用pkDepartment.xxx这样的方式
    * @return 用户的显示对象列表,默认使用用户名升序排列
    * @throws VciBaseException 参数为空或者查询出错的时候会抛出异常
    */
   @Override
   public List<SmUserVO> listUserUnInDeptOid(String deptOid, Map<String, String> queryMap) throws VciBaseException {
      // TODO:根据当前登录的用户决定能查那些用户
      String userType = "0";//WebThreadLocalUtil.getCurrentUserSessionInfoInThread().getUsertype();
      //根据当前登录的用户类型不同,查询不同的用户
      if(UserTypeEnum.SUPPER_ADMIN.getValue().equals(userType)){
         //超管用户只能查管理员用户
         queryMap.put("plusertype", "1");
      }else{
         //除了超管都只能查普通用户
         queryMap.put("plusertype", "2");
      }
      return listUserVOByDeptOid(queryMap,Arrays.asList(deptOid),true);
   }
   /**
    * 用户根据部门查询的统一方法
    * @param conditionMap 查询条件
    * @param deptOidList 部门主键
    * @param notIn true待选,false已选
    * @return
    */
   private List<SmUserVO> listUserVOByDeptOid(Map<String,String> conditionMap/*放置查询条件*/,List<String> deptOidList,boolean notIn){
      //先查询已选人员oid
      List<String> userOidList = new ArrayList<>();
      WebUtil.switchCollectionForOracleIn(deptOidList).stream().forEach(deptOids->{
         String sql = "select pluseruid,pldeptuid from pluserdept where pldeptuid in (" + WebUtil.toInSql(deptOids.toArray(new String[0])) + ")";
         List<BusinessObject> cbos = boService.queryBySql(sql, null);
         //遍历出用户主键
         cbos.stream().forEach(cbo->{
            userOidList.add(ObjectTool.getNewBOAttributeValue(cbo,"pluseruid"));
         });
      });
      //根据用户oid查询用户
      VciQueryWrapperForDO queryWrapperForDO = new VciQueryWrapperForDO(conditionMap, SmUserDO.class);
      //添加连表查询条件
      queryWrapperForDO.setLinkTableSql(" left join pluserdept up on " + queryWrapperForDO.getTableNick() + ".pluid = up.pluseruid" +
            " left join pldept pkDepartment on  up.pldeptuid = pkDepartment.pluid " +
            " left join PLUSERPASSWORDSTRATEGY pkUserPassword on  " +queryWrapperForDO.getTableNick() + ".pluid = pkUserPassword.pluseruid ");
      queryWrapperForDO.setOrderSql("order by " + queryWrapperForDO.getTableNick() + ".pltrueName");
      List<SmUserDO> smUserDOList = new ArrayList<>();
      //userOidList为空时的两种情况
      if(Func.isEmpty(userOidList)){
         //如果是已选查询说明已选为空直接返回空
         if(!notIn){
            return new ArrayList<>();
         }
         //不是已选查询说明待选为空,直接查询用户
         smUserDOList.addAll(boService.selectByQueryWrapper(queryWrapperForDO, SmUserDO.class));
      }else{
         //已选查询,或待选查询,但是该部门存在相关配置
         WebUtil.switchCollectionForOracleIn(userOidList).stream().forEach(userOids->{
            //查询不在范围内的:待选人员
            if(notIn){
               queryWrapperForDO.notIn(queryWrapperForDO.getTableNick()+".pluid",WebUtil.toInSql(userOids.toArray(new String[0])));
            }else{
               //已选人员和统计
               queryWrapperForDO.in(queryWrapperForDO.getTableNick()+".pluid",WebUtil.toInSql(userOids.toArray(new String[0])));
            }
            smUserDOList.addAll(boService.selectByQueryWrapper(queryWrapperForDO, SmUserDO.class));
         });
      }
      return smUserDO2VOs(smUserDOList);
   }
   /**
    * 获取查询封装器,默认只查了plstatus=0和plusertype=2(改成根据当前登录的用户来决定查什么类型的用户),
    * 排序默认plusername
    * @param queryField 查询属性
    * @param queryValue 查询的值
    * @param queryMap  查询条件,如果是角色的属性,需要使用pkrole.xxx
@@ -418,24 +750,19 @@
      }
      addRoleQuerySql(queryMap,queryWrapperForDO);
      queryWrapperForDO.eq("plstatus", "0");
      queryWrapperForDO.eq("plusertype", "2");
      queryWrapperForDO.setDistinct(true);
      // TODO:根据当前登录的用户决定能查那些用户
      SessionInfo loginUser = WebThreadLocalUtil.getCurrentUserSessionInfoInThread();
      //根据当前登录的用户类型不同,查询不同的用户
      if(UserTypeEnum.SUPPER_ADMIN.getValue().equals(loginUser.getUsertype())){
         //超管用户只能查管理员用户
         queryMap.put("plusertype", "1");
      }else{
         //除了超管都只能查普通用户
         queryMap.put("plusertype", "2");
      }
      return queryWrapperForDO;
   }
   /**
     * 查询某个部门下的用户对象列表
     * @param deptOid 部门的主键
     * @param queryMap 查询条件,如果是部门的某个属性作为查询条件,则可以使用pkDepartment.xxx这样的方式
     * @param pageHelper 分页和排序信息,默认使用用户名升序排列
     * @return 用户的显示对象列表,默认使用用户名升序排列
     * @throws VciBaseException 参数为空或者查询出错的时候会抛出异常
     */
   @Override
   public DataGrid<SmUserVO> gridUserByDeptOid(String deptOid,
         Map<String, String> queryMap, PageHelper pageHelper)
         throws VciBaseException {
      return gridUserByQueryField(QUERY_FIELD_DEPARTMENT,deptOid,queryMap,pageHelper,false);
   }
    /**
     * 批量根据部门的主键获取用户
     * @param deptOidCollection 部门的主键集合
@@ -454,36 +781,8 @@
      }
      return new HashMap<>();
   }
   /**
     * 查询不在某个部门下的用户对象列表
     * @param deptOid 部门的主键
     * @param queryMap 查询条件,如果是部门的某个属性作为查询条件,则可以使用pkDepartment.xxx这样的方式
     * @return 用户的显示对象列表,默认使用用户名升序排列
     * @throws VciBaseException 参数为空或者查询出错的时候会抛出异常
     */
   @Override
   public List<SmUserVO> listUserUnInDeptOid(String deptOid,
         Map<String, String> queryMap) throws VciBaseException {
      if(StringUtils.isBlank(deptOid)){
         return new ArrayList<>();
      }
      return listUserByQueryField(QUERY_FIELD_DEPARTMENT,deptOid,queryMap,true);
   }
   /**
     * 查询不在某个部门下的用户对象列表
     * @param deptOid 部门的主键
     * @param queryMap 查询条件,如果是部门的某个属性作为查询条件,则可以使用pkDepartment.xxx这样的方式
     * @param pageHelper 分页和排序信息,默认使用用户名升序排列
     * @return 用户的显示对象列表,默认使用用户名升序排列
     * @throws VciBaseException 参数为空或者查询出错的时候会抛出异常
     */
   @Override
   public DataGrid<SmUserVO> gridUserUnInDeptOid(String deptOid,
         Map<String, String> queryMap, PageHelper pageHelper)
         throws VciBaseException {
      return gridUserByQueryField(QUERY_FIELD_DEPARTMENT,deptOid,queryMap,pageHelper,true);
   }
    /**
     * 查询某个角色下的用户对象
     * @param roleOid 角色的主键
     * @param queryMap 查询条件,如果是角色的某个属性作为查询条件,则可以使用pkRole.xxx这样的方式
@@ -493,26 +792,9 @@
   @Override
   public List<SmUserVO> listUserByRoleOid(String roleOid,
         Map<String, String> queryMap) throws VciBaseException {
      if(StringUtils.isBlank(roleOid)){
         return new ArrayList<>();
      }
      return listUserByQueryField(QUERY_FIELD_ROLE,roleOid,queryMap,false);
      return listUserVOByRoleOid(queryMap,roleOid,false);
   }
   }
   /**
     * 查询某个角色下的用户对象列表
     * @param roleOid 角色的主键
     * @param queryMap 查询条件,如果是角色的某个属性作为查询条件,则可以使用pkRole.xxx这样的方式
     * @param pageHelper 分页和排序信息,默认使用用户名升序排列
     * @return 用户的显示对象列表,默认使用用户名升序排列
     * @throws VciBaseException 参数为空或者查询出错的时候会抛出异常
     */
   @Override
   public DataGrid<SmUserVO> gridUserByRoleOid(String roleOid,
         Map<String, String> queryMap, PageHelper pageHelper)
         throws VciBaseException {
      return gridUserByQueryField(QUERY_FIELD_ROLE,roleOid,queryMap,pageHelper,false);
   }
   /**
     * 查询不在某个角色下的用户对象列表
     * @param roleOid 角色的主键
@@ -523,25 +805,56 @@
   @Override
   public List<SmUserVO> listUserUnInRoleOid(String roleOid,
         Map<String, String> queryMap) throws VciBaseException {
      if(StringUtils.isBlank(roleOid)){
      // TODO:根据当前登录的用户决定能查那些用户
      String usertype = WebThreadLocalUtil.getCurrentUserSessionInfoInThread().getUsertype();
      //根据当前登录的用户类型不同,查询不同的用户
      if(UserTypeEnum.SUPPER_ADMIN.getValue().equals(usertype)){
         //超管用户只能查管理员用户
         queryMap.put("plusertype", "1");
      }else{
         //除了超管都只能查普通用户
         queryMap.put("plusertype", "2");
      }
      return listUserVOByRoleOid(queryMap,roleOid,true);
   }
   /**
    * 用户根据角色查询的统一方法
    * @param conditionMap 查询条件
    * @param roleOid 角色主键
    * @param notIn true不在范围内,false再范围内
    * @return
    */
   private List<SmUserVO> listUserVOByRoleOid(Map<String,String> conditionMap,String roleOid,boolean notIn){
      //listUserByQueryField这个方法暂时不能满足我现在的查询需求,并且引用的地方较多,所以不太好改动
      //1、先查询与当前角色存在关联关系的用户
      String sql = "select pluseruid,plroleuid from pluserrole where plroleuid = '" + roleOid +"'";
      List<BusinessObject> cbos = boService.queryBySql(sql, null);
      List<String> userOidList = new ArrayList<>();
      if(CollectionUtils.isEmpty(cbos)){
         return new ArrayList<>();
      }
      return listUserByQueryField(QUERY_FIELD_ROLE,roleOid,queryMap,true);
      //遍历出用户主键
      cbos.stream().forEach(cbo->{
         userOidList.add(ObjectTool.getNewBOAttributeValue(cbo,"pluseruid"));
      });
      //2、再查询用户
      VciQueryWrapperForDO queryWrapperForDO = new VciQueryWrapperForDO(conditionMap, SmUserDO.class);
      List<SmUserDO> smUserDOS = new ArrayList<>();
      queryWrapperForDO.setLinkTableSql(" left join pluserdept up on " + queryWrapperForDO.getTableNick() + ".pluid = up.pluseruid" +
            " left join pldept pkDepartment on  up.pldeptuid = pkDepartment.pluid " +
            " left join PLUSERPASSWORDSTRATEGY pkUserPassword on  " +queryWrapperForDO.getTableNick() + ".pluid = pkUserPassword.pluseruid ");
      WebUtil.switchCollectionForOracleIn(userOidList).stream().forEach(userOids->{
         if(notIn){
            queryWrapperForDO.notIn("pluid",WebUtil.toInSql(userOids.toArray(new String[0])));
         }else{
            queryWrapperForDO.in("pluid",WebUtil.toInSql(userOids.toArray(new String[0])));
         }
         smUserDOS.addAll(boService.selectByQueryWrapper(queryWrapperForDO, SmUserDO.class));
      });
      return smUserDO2VOs(smUserDOS);
   }
    /**
     * 查询不在某个角色下的用户对象列表
     * @param roleOid 角色的主键
     * @param queryMap 查询条件,如果是角色的某个属性作为查询条件,则可以使用pkRole.xxx这样的方式
     * @param pageHelper 分页和排序信息,默认使用用户名升序排列
     * @return 用户的显示对象列表,默认使用用户名升序排列
     * @throws VciBaseException 参数为空或者查询出错的时候会抛出异常
     */
   @Override
   public DataGrid<SmUserVO> gridUserUnInRoleOid(String roleOid,
         Map<String, String> queryMap, PageHelper pageHelper)
         throws VciBaseException {
      return gridUserByQueryField(QUERY_FIELD_ROLE,roleOid,queryMap,pageHelper,true);
   }
   /**
     * 批量根据角色的主键获取用户
     * @param roleOidCollection 角色的主键集合
@@ -599,6 +912,7 @@
         PageHelper pageHelper) throws VciBaseException {
      return gridUserByQueryField(null,null,queryMap,pageHelper,false);
   }
   /**
     * 参照用户的树形显示
     * @param treeQueryObject 树型接口查询对象
@@ -615,13 +929,13 @@
            + " left join pluserdept up on " + queryWrapper.getTableNick() + ".pluid = up.pluseruid left join pldept pkDepartment on  up.pldeptuid = pkDepartment.pluid " +
            " left join PLUSERPASSWORDSTRATEGY pkUserPassword on  " +queryWrapper.getTableNick() + ".pluid = pkUserPassword.pluseruid " +
            queryWrapper.getLinkTableSql() + (StringUtils.isNotBlank(queryWrapper.getWhereSql())?(" where " + queryWrapper.getWhereSql()):"");
      List<com.vci.client.bof.ClientBusinessObject> dataList = boService.queryBySql(sql + fromSql, null);
      List<BusinessObject> dataList = boService.queryBySql(sql + fromSql, null);
      List<Tree> treeList = new ArrayList<>();
      if(!CollectionUtils.isEmpty(dataList)){
         dataList.stream().forEach(cbo->{
            Tree tree = new Tree();
            tree.setOid(cbo.getOid());
            tree.setText(cbo.getId() + " " + cbo.getName());
            tree.setOid(cbo.oid);
            tree.setText(cbo.id + " " + cbo.name);
            Map<String,String> attributeMap = new HashMap<>();
            WebUtil.copyValueToCboFromMap(cbo,attributeMap);
            tree.setAttributes(attributeMap);
@@ -631,7 +945,169 @@
      }
      return treeList;
   }
    /**
   /**
    * 获取角色数据
    * @param treeQueryObject
    * @return
    * @throws VciBaseException
    */
   @Override
   public List<Tree> refPersonOrgTree(TreeQueryObject treeQueryObject) throws VciBaseException {
      List<Tree> rootTreeList=new ArrayList<>();
       Map<String,String> conditionMap=treeQueryObject.getConditionMap();
       if(CollectionUtils.isEmpty(conditionMap)) {
          conditionMap = new HashMap<>();
       }
      String dataType=StringUtils.isNotBlank(conditionMap.get("dataType"))?conditionMap.get("dataType"):"";//数据类型
      String parentId=StringUtils.isNotBlank(conditionMap.get("parentId"))?conditionMap.get("parentId"):"";//父节点
      String orgType=StringUtils.isNotBlank(conditionMap.get("orgType"))?conditionMap.get("orgType"):"";//接口查询包含的类型
      try {
         initChildTree(dataType,orgType,parentId,rootTreeList);
      } catch (PLException e) {
         throw new  VciBaseException("用户权限选择树加载失败:"+e.getMessage());
      }
      return rootTreeList;
   }
   /***
    *
    * @param dataType
    * @param orgType
    * @param parentId
    */
   private void initChildTree(String dataType,String orgType, String  parentId, List<Tree>rootTreeList) throws PLException {
      if(StringUtils.isBlank(parentId)){
         Tree rootTree=new Tree("root","人员组织","root");
         rootTree.setParentBtmName("root");
         rootTree.setExpanded(true);
         List<Tree> childList=new ArrayList<>();
         if(OrgTypeEnum.ORG_TYPE_USER.getValue().equals(orgType)){//如果是人员
            Tree userTree=initDataTreeNode(OrgTypeEnum.ORG_TYPE_USER.getValue(),"用户",OrgTypeEnum.ORG_TYPE_USER.getValue(),OrgTypeEnum.ORG_TYPE_USER.getValue(),rootTree);
            childList.add(userTree);
         }else if(OrgTypeEnum.ORG_TYPE_DEPT.getValue().equals(orgType)){//如果是部门
            Tree departmentTree=initDataTreeNode(OrgTypeEnum.ORG_TYPE_DEPT.getValue(),"部门",OrgTypeEnum.ORG_TYPE_DEPT.getValue(),OrgTypeEnum.ORG_TYPE_DEPT.getValue(),rootTree);
            childList.add(departmentTree);
         }else if(OrgTypeEnum.ORG_TYPE_ROLE.getValue().equals(orgType)){//如果是角色
            Tree roleTree=initDataTreeNode(OrgTypeEnum.ORG_TYPE_ROLE.getValue(),"角色",OrgTypeEnum.ORG_TYPE_ROLE.getValue(),OrgTypeEnum.ORG_TYPE_ROLE.getValue(),rootTree);
            childList.add(roleTree);
         }else{
            Tree userTree=initDataTreeNode(OrgTypeEnum.ORG_TYPE_USER.getValue(),"用户",OrgTypeEnum.ORG_TYPE_USER.getValue(),OrgTypeEnum.ORG_TYPE_USER.getValue(),rootTree);
            childList.add(userTree);
            Tree departmentTree=initDataTreeNode(OrgTypeEnum.ORG_TYPE_DEPT.getValue(),"部门",OrgTypeEnum.ORG_TYPE_DEPT.getValue(),OrgTypeEnum.ORG_TYPE_DEPT.getValue(),rootTree);
            childList.add(departmentTree);
            Tree roleTree=initDataTreeNode(OrgTypeEnum.ORG_TYPE_ROLE.getValue(),"角色",OrgTypeEnum.ORG_TYPE_ROLE.getValue(),OrgTypeEnum.ORG_TYPE_ROLE.getValue(),rootTree);
            childList.add(roleTree);
         }
         if(childList.size()>0){
            rootTree.setExpanded(true);
            rootTree.setChildren(childList);
         }
         rootTreeList.add(rootTree);
      }else{
         if(OrgTypeEnum.ORG_TYPE_ROOT.getValue().equals(dataType)){//如果父节点有值,则需要判断是加载什么节点
            Tree rootTree=new Tree("root","人员组织","root");
            rootTree.setParentBtmName("root");
            rootTree.setExpanded(true);
            if(OrgTypeEnum.ORG_TYPE_USER.getValue().equals(orgType)){//如果是人员
               Tree userTree=initDataTreeNode(OrgTypeEnum.ORG_TYPE_USER.getValue(),"用户",OrgTypeEnum.ORG_TYPE_USER.getValue(),OrgTypeEnum.ORG_TYPE_USER.getValue(),rootTree);
               rootTreeList.add(userTree);
            }else if(OrgTypeEnum.ORG_TYPE_DEPT.getValue().equals(orgType)){//如果是部门
               Tree departmentTree=initDataTreeNode(OrgTypeEnum.ORG_TYPE_DEPT.getValue(),"部门",OrgTypeEnum.ORG_TYPE_DEPT.getValue(),OrgTypeEnum.ORG_TYPE_DEPT.getValue(),rootTree);
               rootTreeList.add(departmentTree);
            }else if(OrgTypeEnum.ORG_TYPE_ROLE.getValue().equals(orgType)){//如果是角色
               Tree roleTree=initDataTreeNode(OrgTypeEnum.ORG_TYPE_ROLE.getValue(),"角色",OrgTypeEnum.ORG_TYPE_ROLE.getValue(),OrgTypeEnum.ORG_TYPE_ROLE.getValue(),rootTree);
               rootTreeList.add(roleTree);
            }else{
               Tree userTree=initDataTreeNode(OrgTypeEnum.ORG_TYPE_USER.getValue(),"用户",OrgTypeEnum.ORG_TYPE_USER.getValue(),OrgTypeEnum.ORG_TYPE_USER.getValue(),rootTree);
               rootTreeList.add(userTree);
               Tree departmentTree=initDataTreeNode(OrgTypeEnum.ORG_TYPE_DEPT.getValue(),"部门",OrgTypeEnum.ORG_TYPE_DEPT.getValue(),OrgTypeEnum.ORG_TYPE_DEPT.getValue(),rootTree);
               rootTreeList.add(departmentTree);
               Tree roleTree=initDataTreeNode(OrgTypeEnum.ORG_TYPE_ROLE.getValue(),"角色",OrgTypeEnum.ORG_TYPE_ROLE.getValue(),OrgTypeEnum.ORG_TYPE_ROLE.getValue(),rootTree);
               rootTreeList.add(roleTree);
            }
         }else if(OrgTypeEnum.ORG_TYPE_USER.getValue().equals(dataType)) {//如果传进来的是user节点
            if(OrgTypeEnum.ORG_TYPE_USER.getValue().equals(parentId)) {
               Tree userTree = initDataTreeNode(OrgTypeEnum.ORG_TYPE_USER.getValue(), "用户", OrgTypeEnum.ORG_TYPE_USER.getValue(), OrgTypeEnum.ORG_TYPE_USER.getValue(), null);
               UserInfo[] infos = platformClientUtil.getFrameworkService().fetchUserInfo();
               Arrays.stream(infos).forEach(info -> {
                  Tree childTree = initDataTreeNode(info.id, info.trueName + "(" + info.userName + ")", info, OrgTypeEnum.ORG_TYPE_USER.getValue(), userTree);
                  rootTreeList.add(childTree);
               });
            }
         }else   if(OrgTypeEnum.ORG_TYPE_DEPT.getValue().equals(dataType)) {//如果是部门
            DeptInfo[] deptInfos=new DeptInfo[]{};
            Tree departmentTree=new Tree();
            if(OrgTypeEnum.ORG_TYPE_DEPT.getValue().equals(parentId)) {
               departmentTree=initDataTreeNode(OrgTypeEnum.ORG_TYPE_DEPT.getValue(),"部门",OrgTypeEnum.ORG_TYPE_DEPT.getValue(),OrgTypeEnum.ORG_TYPE_DEPT.getValue(),null);
               deptInfos = platformClientUtil.getFrameworkService().fetchDepartmentInfo();
            }else{
               deptInfos=platformClientUtil.getFrameworkService().fetchDepartmentInfoByParentId(parentId);
               DeptInfo deptInfo=platformClientUtil.getFrameworkService().fetchDepartmentInfoById(parentId);
               departmentTree=initDataTreeNode(deptInfo.id,deptInfo.name,deptInfo,OrgTypeEnum.ORG_TYPE_DEPT.getValue(),null);
            }
            if(!CollectionUtils.isEmpty(Arrays.asList(deptInfos))){
               Tree finalDepartmentTree = departmentTree;
               Arrays.stream(deptInfos).forEach(deptInfo -> {
                  Tree childTree=initDataTreeNode(deptInfo.id,deptInfo.name,deptInfo,OrgTypeEnum.ORG_TYPE_DEPT.getValue(), finalDepartmentTree);
                  rootTreeList.add(childTree);
               });
            }
            if(!OrgTypeEnum.ORG_TYPE_DEPT.getValue().equals(parentId)) {
               UserInfo[] infos = platformClientUtil.getFrameworkService().getUserByDeptId(parentId);
               if (infos != null && infos.length > 0) {
                  Tree finalDepartmentTree = departmentTree;
                  Arrays.stream(infos).forEach(info -> {
                     Tree childTree = initDataTreeNode(info.id, info.trueName + "(" + info.userName + ")", info, OrgTypeEnum.ORG_TYPE_USER.getValue(), finalDepartmentTree);
                     rootTreeList.add(childTree);
                  });
               }
            }
         }else  if(OrgTypeEnum.ORG_TYPE_ROLE.getValue().equals(dataType)) {//如果是角色
            if(OrgTypeEnum.ORG_TYPE_ROLE.getValue().equals(parentId)){
               Tree roleTree=initDataTreeNode(OrgTypeEnum.ORG_TYPE_ROLE.getValue(),"角色",OrgTypeEnum.ORG_TYPE_ROLE.getValue(),OrgTypeEnum.ORG_TYPE_ROLE.getValue(),null);
               RoleInfo[] roleInfos=platformClientUtil.getFrameworkService().fetchRoleInfo();
               if(roleInfos!=null&&roleInfos.length>0) {
                  Arrays.stream(roleInfos).forEach(info -> {
                     Tree childTree = initDataTreeNode(info.id, info.name, info, OrgTypeEnum.ORG_TYPE_ROLE.getValue(), roleTree);
                     rootTreeList.add(childTree);
                  });
               }
            }else{
               RoleInfo roleInfo=platformClientUtil.getFrameworkService().fetchRoleInfoById(parentId);
               Tree roleTree=initDataTreeNode(roleInfo.id,roleInfo.name,roleInfo,OrgTypeEnum.ORG_TYPE_ROLE.getValue(),null);
               UserInfo[] infos=platformClientUtil.getFrameworkService().fetchUserInfoByRoleId(roleInfo.id,roleInfo.type);
               if(infos!=null&&infos.length>0) {
                  Arrays.stream(infos).forEach(info -> {
                     Tree childTree = initDataTreeNode(info.id, info.trueName + "(" + info.userName + ")", info, OrgTypeEnum.ORG_TYPE_USER.getValue(), roleTree);
                     rootTreeList.add(childTree);
                  });
               }
            }
         }
      }
   }
   /***
    *
    * @param oid
    * @param text
    * @param o
    * @param type
    * @param parentTree
    * @return
    */
   private Tree initDataTreeNode(String oid,String text,Object o,String type,Tree parentTree){
      Tree ObjectTreeNode=new Tree(oid,text,o);
      ObjectTreeNode.setParentBtmName(type);
      if(parentTree!=null) {
         ObjectTreeNode.setParentId(parentTree.getParentId());
         ObjectTreeNode.setParentName(parentTree.getParentName());
      }
      return ObjectTreeNode;
   }
   /**
     * 校验密码是否相同,在新平台中存储的密码是两次md5
     * @param userOid 用户主键
     * @param md5Password 已经md5加密一次的密码--老的平台里不能加密
@@ -645,19 +1121,20 @@
      String sql = " select plpassword from pluser where pluid = :userOid";
      Map<String,String> conditionMap = new HashMap<>();
      conditionMap.put("userOid",userOid.trim());
      List<com.vci.client.bof.ClientBusinessObject> clientBusinessObjectList = boService.queryBySql(sql, conditionMap);
      if(CollectionUtils.isEmpty(clientBusinessObjectList)){
      List<BusinessObject> BusinessObjectList = boService.queryBySql(sql, conditionMap);
      if(CollectionUtils.isEmpty(BusinessObjectList)){
         return  false;
      }
      ThreeDES des = new ThreeDES();// 实例化一个对�?
      des.getKey("daliantan0v0");// 生成密匙
      md5Password = des.getEncString(md5Password);
      if(md5Password.equals(clientBusinessObjectList.get(0).getAttributeValue("plpassword"))){
      if(md5Password.equals(ObjectTool.getNewBOAttributeValue(BusinessObjectList.get(0),"plpassword"))){
         return true;
      }
      return false;
   }
   /**
     * 校验用户是否锁定
     * @param smUserVO 用户对象
@@ -670,7 +1147,9 @@
         return smUserVO.isLockFlag();
      }
      //查询密码策略
      SmPasswordStrategyVO passwordStrategyVO = getPasswordStrategyVOByOid(smUserVO.getPkPasswordStrategy());
      SmPasswordStrategyVO passwordStrategyVO = smPwdStrategyQueryService.getPasswordStrategyVOByOid(
            smUserVO.getPkPasswordStrategy()
      );
      if(passwordStrategyVO == null){
         throw new VciBaseException("系统里没有密码安全策略");
      }
@@ -678,58 +1157,6 @@
         return  true;
      }
      return false;
   }
   /**
    * 使用主键获取密码策略
    * @param oid 主键
    * @return 密码策略显示对象
    */
   public SmPasswordStrategyVO getPasswordStrategyVOByOid(String oid){
      VciQueryWrapperForDO queryWrapperForDO = new VciQueryWrapperForDO(null, SmPasswordStrategyDO.class);
      queryWrapperForDO.eq("oid",oid.trim());
      List<com.vci.client.bof.ClientBusinessObject> cboList = boService.queryBySql(queryWrapperForDO.getSelectFieldSql() + " from plpasswordstrategy " +
            queryWrapperForDO.getTableNick() + queryWrapperForDO.getLinkTableSql() +
            (StringUtils.isBlank(queryWrapperForDO.getWhereSql()) ? "" : (" where " + queryWrapperForDO.getWhereSql())), null);
      if(!CollectionUtils.isEmpty(cboList)){
         SmPasswordStrategyDO passwordStrategyDO = new SmPasswordStrategyDO();
         WebUtil.copyValueToObjectFromCbos(cboList.get(0),passwordStrategyDO);
         SmPasswordStrategyVO passwordStrategyVO = new SmPasswordStrategyVO();
         BeanUtil.convert(passwordStrategyDO,passwordStrategyVO);
         return passwordStrategyVO;
      }else{
         //获取默认的
         queryWrapperForDO = new VciQueryWrapperForDO(null, SmPasswordStrategyDO.class);
         queryWrapperForDO.eq("plisdefault","1");
         cboList = boService.queryBySql(queryWrapperForDO.getSelectFieldSql() + " from plpasswordstrategy " +
               queryWrapperForDO.getTableNick() + queryWrapperForDO.getLinkTableSql() +
               (StringUtils.isBlank(queryWrapperForDO.getWhereSql()) ? "" : (" where " + queryWrapperForDO.getWhereSql())), null);
         if(!CollectionUtils.isEmpty(cboList)){
            SmPasswordStrategyDO passwordStrategyDO = new SmPasswordStrategyDO();
            WebUtil.copyValueToObjectFromCbos(cboList.get(0),passwordStrategyDO);
            SmPasswordStrategyVO passwordStrategyVO = new SmPasswordStrategyVO();
            BeanUtil.convert(passwordStrategyDO,passwordStrategyVO);
            return passwordStrategyVO;
         }
      }
      return null;
   }
    /**
     * 根据用户的主键,获取用户的密码安全策略
     * @param userOid 用户的主键
     * @return 密码安全策略的显示对象,如果不存在则会返回Null
     * @throws VciBaseException 参数为空或者数据库查询出错的时候会抛出异常
     */
   @Override
   public SmPasswordStrategyVO getPasswordStrategyVOByUserOid(String userOid)
         throws VciBaseException {
      WebUtil.alertNotNull(userOid,"用户的主键");
      SmUserVO userVO = getUserByUserOid(userOid);
      if(userVO == null || StringUtils.isBlank(userVO.getOid())){
         throw new VciBaseException(DATA_OID_NOT_EXIST);
      }
      return getPasswordStrategyVOByOid(userVO.getPkPasswordStrategy());
   }
    /**
@@ -740,6 +1167,7 @@
   public void lockUser(String userId) {
      //老的这个平台,是依靠锁定次数来判断的,所以这里没办法直接设置
   }
    /**
     * 设置某个用户不是锁定状态
     * @param userId 用户名
@@ -754,29 +1182,61 @@
         throw WebUtil.getVciBaseException(vciError);
      }
   }
    /**
     * 修改密码
     * @param userOid 用户主键
     * @param oldPassword 旧的密码
     * @param password 新的密码
     * @param confirmPassword 确认密码
     */
   @Override
   public void changePassword(String userOid, String password,
         String confirmPassword) throws VciBaseException {
      WebUtil.alertNotNull(userOid,"用户主键",password,"密码",confirmPassword,"确认密码");
   @Transactional(rollbackFor = Exception.class)
   public boolean changePassword(String userOid,String oldPassword, String password,
         String confirmPassword) throws Exception {
      WebUtil.alertNotNull(userOid,"用户主键",oldPassword,"登录密码",password,"密码",confirmPassword,"确认密码");
      if(!password.equals(confirmPassword)){
         throw new VciBaseException("密码和确认密码不相等");
      }
      //对旧密码和密码进行解密,便于比对密码用
      oldPassword = Func.decryptAes(oldPassword,"daliantan0v0vcip");
      password = Func.decryptAes(password,"daliantan0v0vcip");
      //对比旧密码
      boolean b = this.checkPasswordEqual(oldPassword, userOid);
      if(!b){
         throw new PLException("500", new String[] { "您输入的密码与登录密码不一致,请重新输入!"});
      }
      SmUserVO smUserVO = getUserByUserOid(userOid);
      if(Func.isEmpty(smUserVO)){
         throw new VciBaseException("当前修改的用户不存在!");
      }
      //TODO:校验密码是否符合策略
      String error = platformClientUtil.getFrameworkService().checkPasswordStrategyByUserId(smUserVO.getId(), password,null);
      if (!StringUtils.isBlank(error)) {
         throw new VciBaseException("当前设置的密码,密码策略校验未通过!");
      }
      //TODO:考虑是否需要将修改方式改成直接调用平台的接口,因为现在的修改方式没能正确的更新缓存
      /*UserInfo userInfo = new UserInfo();
      userInfo.id = userOid.trim();
      userInfo.pwd = password;
      userInfo.pwdUpdateTime = System.currentTimeMillis();
      boolean updateBoolean = platformClientUtil.getFrameworkService().updateUser(userInfo, new UserEntityInfo(WebThreadLocalUtil.getCurrentUserSessionInfoInThread().getUserId(), null));
      return updateBoolean;*/
      ThreeDES des = new ThreeDES();// 实例化一个对�?
      des.getKey("daliantan0v0");// 生成密匙
      String encPassword = des.getEncString(password);
      String sql = "update pluser set plpassword = '" + encPassword + "' where pluid = '" + userOid.trim() + "'";
      //修改密码的同时需要将密码修改时间也更新
      String sql = "update pluser set plpassword = '" + encPassword + "', plpwdupdatetime = TO_DATE('"
            + Func.format(new Date(),"yyyy-MM-dd HH:mm:ss") +"','yyyy-MM-dd hh24:mi:ss') where pluid = '" + userOid.trim() + "'";
      try {
         platformClientUtil.getBOFactoryService().executeUpdateSql(sql);
         return platformClientUtil.getBOFactoryService().executeUpdateSql(sql);
      } catch (PLException vciError) {
         throw WebUtil.getVciBaseException(vciError);
      }
   }
   /**
     * 更新用户的密码错误次数
     * @param userOid 用户的主键
@@ -794,6 +1254,7 @@
         throw WebUtil.getVciBaseException(vciError);
      }
   }
    /**
     * 更新用户的最后登录时间
     * @param userOid 用户的主键
@@ -809,4 +1270,363 @@
         throw WebUtil.getVciBaseException(vciError);
      }
   }
   /**
    * 添加用户
    * @param smUserDTO
    * @return
    */
   @Override
   @Transactional(rollbackFor = Exception.class)
   public boolean addUser(SmUserDTO smUserDTO) throws PLException {
      //判空
      VciBaseUtil.alertNotNull(
            smUserDTO,"添加的用户对象",
            smUserDTO.getId(),"用户名",
            smUserDTO.getPassword(),"密码",
            smUserDTO.getConfirmPassword(),"确认密码",
            smUserDTO.getName(),"姓名"
      );
      //校验
      check(smUserDTO,true,false);
      //生成存储的DO对象
      Date date = new Date();
      smUserDTO.setPwdUpdateTime(date);
      smUserDTO.setStatus((short) 0);
      smUserDTO.setCreateTime(date);
      SessionInfo loginUser = WebThreadLocalUtil.getCurrentUserSessionInfoInThread();
      String loginUserId = loginUser.getUserId();
      //用户类型,现在按照当前登录的用户决定他所添加的用户级别
      //超管添加的就是管理员
      if(UserTypeEnum.SUPPER_ADMIN.getValue().equals(loginUser.getUsertype())){
         smUserDTO.setUserType(Short.parseShort(UserTypeEnum.ADMIN.getValue()));
      }else {
         //管理员添加的就是普通用户
         smUserDTO.setUserType(Short.parseShort(UserTypeEnum.USER.getValue()));
      }
      smUserDTO.setCreator(loginUserId);
      smUserDTO.setLastModifier(loginUserId);
      UserInfo userInfo = changeSmUserDTOToUserInfo(smUserDTO);
      UserEntityInfo userEntityInfo = new UserEntityInfo(loginUserId, "");
      String oid = platformClientUtil.getFrameworkService().saveUser(userInfo, userEntityInfo);
      if (Func.isEmpty(oid)) {
         return false;
      }
      if(Func.isNotBlank(smUserDTO.getPkDepartment())){
         //执行保存用户部门关联关系
         orgDeptQueryService.saveUsersDept(new String[]{oid},smUserDTO.getPkDepartment());
      }
      return true;
   }
   /**
    * 修改用户
    * @param smUserDTO
    * @return
    */
   @Override
   @Transactional(rollbackFor = Exception.class)
   public boolean updateUser(SmUserDTO smUserDTO) throws PLException {
      //判空
      VciBaseUtil.alertNotNull(
            smUserDTO,"修改的用户对象",
            smUserDTO.getOid(),"用户主键",
            smUserDTO.getId(),"用户名",
            smUserDTO.getPassword(),"密码",
            smUserDTO.getConfirmPassword(),"确认密码",
            smUserDTO.getName(),"姓名"
      );
      //校验
      check(smUserDTO,false,false);
      //查询数据库中的
      SmUserVO dbSmUserVO = getUserByUserOid(smUserDTO.getOid());
      //根据主键没查询到了用户
      if(Func.isEmpty(dbSmUserVO) || Func.isBlank(dbSmUserVO.getOid())){
         throw new PLException("500", new String[] { "当前修改的用户不存在"});
      }
      SessionInfo loginUser = WebThreadLocalUtil.getCurrentUserSessionInfoInThread();
      String loginUserName = loginUser.getUserId();
      smUserDTO.setLastModifier(loginUserName);
      smUserDTO.setUserType(Short.parseShort(dbSmUserVO.getUserType()));
      smUserDTO.setPwdUpdateTime(dbSmUserVO.getLastModifyPasswordTime());
      smUserDTO.setIsDeptLeader(smUserDTO.getIsDeptLeader().equals("不是") ? "0":"1");
      UserInfo userInfo = changeSmUserDTOToUserInfo(smUserDTO);
      boolean updateBoolean = platformClientUtil.getFrameworkService().updateUser(userInfo, new UserEntityInfo(loginUserName, null));
      //修改成功,并且用户关联部门有所更改
      if(updateBoolean && !smUserDTO.getPkDepartment().equals(dbSmUserVO.getPkDepartment())){
         //执行保存用户部门关联关系
         orgDeptQueryService.saveUsersDept(new String[]{dbSmUserVO.getOid()},smUserDTO.getPkDepartment());
      }
      return updateBoolean;
   }
   /**
    * 检查用户信息是否符合规范
    * @param smUserDTO
    * @param isAdd 是否新增
    * @param isImport 是否导入
    */
   private void check(SmUserDTO smUserDTO, boolean isAdd,boolean isImport){
      //导入的没有确认密码
      if(!isImport && !smUserDTO.getPassword().equals(smUserDTO.getConfirmPassword())){
         throw new VciBaseException("密码和确认密码不相等");
      }
      if(smUserDTO.getId().getBytes().length > 128){
         throw new VciBaseException("用户名长度超过上限");
      }
      if(smUserDTO.getPassword().getBytes().length > 128){
         throw new VciBaseException("密码长度超过上限");
      }
      if(smUserDTO.getName().getBytes().length > 64){
         throw new VciBaseException("姓名长度超过上限");
      }
      if (Func.isNotBlank(smUserDTO.getSpecialties()) && smUserDTO.getSpecialties().getBytes().length > 255){
         throw new VciBaseException("专业长度超过上限");
      }
      if (Func.isNotBlank(smUserDTO.getEmail()) && smUserDTO.getEmail().getBytes().length > 128){
         throw new VciBaseException("电子邮箱长度超过上限");
      }
      if (Func.isNotBlank(smUserDTO.getDescription()) && smUserDTO.getDescription().getBytes().length > 255 ){
         throw new VciBaseException("描述长度超过上限");
      }
      if (!smUserDTO.getId().matches("^[A-Za-z0-9_]+$")) {
         throw new VciBaseException("用户名必须是由A-Z a-z 0-9 _组成");
      }
      if (Func.isNotBlank(smUserDTO.getEmail()) && !smUserDTO.getEmail().matches("^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$")){
         throw new VciBaseException("电子邮箱格式错误");
      }
      /*是新增才做用户名查重处理,修改不需要查重(一经创建不允许修改用户名),
         导入的也不需要在这儿查重,因为在导入逻辑里面需要返回重复的行
       */
      if(isAdd && !isImport){
         //根据用户名(账号)查重
         SmUserVO dbSmUserVO = getUserByUserId(smUserDTO.getId());
         if(Func.isNotEmpty(dbSmUserVO) && Func.isNotBlank(dbSmUserVO.getOid())){
            throw new VciBaseException("该用户名在系统中已经存在,请修改!");
         }
      }
      //根据当前创建这个用户的人所绑定密码策略来进行密码校验
      try {
         String userId = WebThreadLocalUtil.getCurrentUserSessionInfoInThread().getUserId();
         String error = platformClientUtil.getFrameworkService().checkPasswordStrategyByUserId(userId, smUserDTO.getPassword(),null);
         if (!StringUtils.isBlank(error)) {
            throw new VciBaseException("当前设置的密码,密码策略校验未通过");
         }
      } catch (PLException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
         throw new VciBaseException("检查密码策略符合情况失败!2");
      }
   }
   /***
    * 用户从DTO对象到corba对象
    * @param user
    * @return
    */
   public UserInfo changeSmUserDTOToUserInfo(SmUserDTO user) {
      UserInfo userInfo = new UserInfo();
      userInfo.id = user.getOid() == null ? "" : user.getOid();
      userInfo.userName = user.getId() == null ? "" : user.getId();
      userInfo.pwd = user.getPassword() == null ? "" : user.getPassword();
      userInfo.trueName = user.getName() == null ? "" : user.getName();
      userInfo.specialties = user.getSpecialties() == null ? "" : user.getSpecialties();
      userInfo.email = user.getEmail() == null ? "" : user.getEmail();
      userInfo.desc = user.getDescription() == null ? "" : user.getDescription();
      userInfo.userType = user.getUserType();
      userInfo.status = user.getStatus();
      userInfo.createTime = user.getCreateTime().getTime();
      userInfo.createUser = user.getCreator() == null ? "" : user.getCreator();
      userInfo.updateTime = System.currentTimeMillis();
      userInfo.updateUser = user.getLastModifier() == null ? "" : user.getLastModifier();
      userInfo.pwdUpdateTime = user.getPwdUpdateTime().getTime();
      userInfo.grantor = user.getGrantor() == null ? "" : user.getGrantor();
      userInfo.isDeptLeader = user.getIsDeptLeader() == null ? "0" : user.getIsDeptLeader();
      return userInfo;
   }
   /**
    * 删除用户
    * @param ids
    * @return
    */
   @Override
   @Transactional(rollbackFor = Exception.class)
   public boolean deleteUser(String[] ids) throws PLException {
      VciBaseUtil.alertNotNull(ids,"要删除的用户主键");
      //调用platformClientUtil的删除用户的方法,会一起删除掉具备关联关系的一些信息,如部门
      return platformClientUtil.getFrameworkService().deleteUser(
            ids,
            new UserEntityInfo(WebThreadLocalUtil.getCurrentUserSessionInfoInThread().getUserId(),null)
      );
   }
   /**
    * 用户停用/启用
    * @param ids
    * @param flag
    * @return
    */
   @Override
   @Transactional(rollbackFor = Exception.class)
   public boolean stopUsers(String[] ids, boolean flag) throws PLException {
      VciBaseUtil.alertNotNull(ids,"停用/启用的用户id列表");
      return platformClientUtil.getFrameworkService().stopUsers(ids, flag,null);
   }
   /**
    * 下载导入人员的excel模板。
    * @param downloadFileName 下载时界面传过来指定文件名的
    * @return 文件在本地的全路径
    * @throws VciBaseException 参数为空或者文件出错的时候会抛出异常
    */
   @Override
   public String downloadImportTemplate(String downloadFileName) {
      //界面没传名称,使用默认名称
      downloadFileName = Func.isBlank(downloadFileName) ?  "用户导入模板_" + Func.format(new Date(),"yyyy-MM-dd HHmmss.sss"):downloadFileName;
      // 设置表单列名
      List<String> columns = new ArrayList<>(Arrays.asList("账号", "密码", "姓名", "电子邮箱", "专业", "描述", "部门(上下级部门之间以反斜杠隔开(/))"));
      //获取是否导出密级配置项
      String flag = ConfigCorbaReader.getConfigValue("exportSecretGrade");
      if (flag != null && flag.equalsIgnoreCase("true")) {
         columns = new ArrayList<>(Arrays.asList("账号", "密码", "姓名", "电子邮箱", "专业", "描述", "部门(上下级部门之间以反斜杠隔开(/))" ,"密级"));
      }
      //设置必填列
      ColumnNameisRed.clear();
      ColumnNameisRed.add(0);
      ColumnNameisRed.add(1);
      ColumnNameisRed.add(2);
      //写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<WriteExcelData> 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 importUser(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();
         UserEntityInfo userEntityInfo = new UserEntityInfo(loginUserId,null);
         //是否导入密级配置
         boolean exportSecretGrade = Boolean.parseBoolean(ConfigCorbaReader.getConfigValue("exportSecretGrade"));
         List<SmUserPO> poList = ExcelUtil.readDataObjectFromExcel(file, SmUserPO.class,excelOption,(value, po, fieldName)->{
            Integer secretValue = UserSecretEnum.getSecretValueByText(po.getSecretGradeText());
            //是否必须导入密级
            if(exportSecretGrade){
               if(secretValue == null){
                  throw new VciBaseException("传入的密级不符合规则!");
               }
               po.setSecretGrade(secretValue);
            }
         });
         //去除都是空的情况
         if(CollectionUtils.isEmpty(poList)){
            return BaseResult.fail(ExcelLangCodeConstant.IMPORT_CONTENT_NULL,new String[]{});
         }
         //数据库查询是否有已存在的用户,方便后续做判重处理
         List<SmUserVO> smUserVOList = this.listUserByUserIds(poList.stream().map(SmUserPO::getId).collect(Collectors.toSet()));
         List<String> repeatUserId = new ArrayList<>();
         if(Func.isNotEmpty(smUserVOList)){
            repeatUserId = smUserVOList.stream().map(SmUserVO::getId).collect(Collectors.toList());
         }
         //当前excel中是否重复用的判重Map:(key:账号,value:行号)
         Map<String, String> excelReapeat = new HashMap<>();
         //先获取全部部门名称的父子对应关系:key为部门子父级名称路径,value为部门信息
         List<OrgDepartmentVO> orgDepartmentVOList = orgDeptQueryService.getDeptAllFullName();
         Map<String, OrgDepartmentVO> deptVOMap = orgDepartmentVOList.stream().collect(Collectors.toMap(OrgDepartmentVO::getFullDeptNamePath, s->s));
         //Map<String,OrgDepartmentVO> deptVOMap = orgDeptQueryService.getDeptAllTreeMap();
         //判断必填属性是否为空,用户是否已存在,以及部门是否填错等校验逻辑
         List<String> finalRepeatUserId = repeatUserId;
         poList.stream().forEach(smUserPO -> {
            //先对必填属性判空处理
            if(Func.isBlank(smUserPO.getId())){
               throw new VciBaseException("第【"+smUserPO.getRowIndex()+"】行,usernameerror");
            }else if(Func.isBlank(smUserPO.getName())){
               throw new VciBaseException("第【"+smUserPO.getRowIndex()+"】行,nameerror");
            }else if(Func.isBlank(smUserPO.getPassword())){
               throw new VciBaseException("第【"+smUserPO.getRowIndex()+"】行,passworderror");
            }else if (Func.isNotEmpty(smUserVOList) && finalRepeatUserId.contains(smUserPO.getId())){//2、判断用户名是否重复
               throw new VciBaseException("第【"+smUserPO.getRowIndex()+"】行,用户名在系统中已经存在,请修改!");
            }else if(Func.isNotBlank(smUserPO.getPkDepartmentName())){//处理填写了部门的数据行
               OrgDepartmentVO orgDepartmentVO = deptVOMap.get(smUserPO.getPkDepartmentName());
               //部门为空就说明用户填写错误
               if(Func.isEmpty(orgDepartmentVO) && Func.isBlank(orgDepartmentVO.getOid())){
                  throw new VciBaseException("第【"+smUserPO.getRowIndex()+"】行数据,部门设置错误,原因:未查询到该路径下的部门");
               }
            }else if(excelReapeat.containsKey(smUserPO.getId())){//表格中判重
               throw new VciBaseException("第【"+excelReapeat.get(smUserPO.getId())+"】行和第【"+smUserPO.getRowIndex()+"】行数据,账号重复");
            }
            excelReapeat.put(smUserPO.getId(),smUserPO.getRowIndex());
         });
         //保存逻辑
         poList.stream().forEach(smUserPO->{
            SmUserDTO smUserDTO = new SmUserDTO();
            BeanUtil.convert(smUserPO,smUserDTO);
            //用户信息是否规范检查
            this.check(smUserDTO,true,true);
            //生成存储的DO对象
            Date date = new Date();
            smUserDTO.setPwdUpdateTime(date);
            smUserDTO.setStatus((short) 0);
            smUserDTO.setCreateTime(date);
            smUserDTO.setCreator(loginUserId);
            smUserDTO.setLastModifier(loginUserId);
            //保存用户
            String oid = null;
            try {
               //保存用户获取到用户oid
               oid = platformClientUtil.getFrameworkService().saveUser(changeSmUserDTOToUserInfo(smUserDTO), userEntityInfo);
               //保存用户部门关联关系
               if(Func.isNotBlank(oid) && Func.isNotBlank(smUserDTO.getPkDepartmentName())){
                  orgDeptQueryService.saveUsersDept(
                        new String[]{oid},
                        deptVOMap.get(smUserDTO.getPkDepartmentName()).getOid()
                  );
               }
            } catch (PLException e) {
               e.printStackTrace();
               throw new VciBaseException("执行到第【"+smUserPO.getRowIndex()+"】行保存逻辑时出现错误,原因:" + 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("用户导入成功!");
   }
}