Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/frameworkcore/compatibility/impl/SmUserQueryServiceImpl.java
@@ -1,49 +1,52 @@
package com.vci.frameworkcore.compatibility.impl;
import com.vci.client.common.objects.UserObject;
import com.vci.client.common.providers.ClientServiceProvider;
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.dto.SmUserDTO;
import com.vci.frameworkcore.model.dto.SmUserDTO;
import com.vci.frameworkcore.model.SmUserDO;
import com.vci.frameworkcore.model.po.SmUserPO;
import com.vci.frameworkcore.pagemodel.OrgDepartmentVO;
import com.vci.frameworkcore.pagemodel.SmPasswordStrategyVO;
import com.vci.frameworkcore.pagemodel.SmRoleVO;
import com.vci.frameworkcore.pagemodel.SmUserVO;
import com.vci.frameworkcore.properties.ConfigReader;
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.util.VciDateUtil;
import com.vci.starter.web.util.WebThreadLocalUtil;
import com.vci.starter.web.pagemodel.*;
import com.vci.starter.web.util.*;
import com.vci.starter.web.wrapper.VciQueryWrapperForDO;
import com.vci.web.enumpck.UserTypeEnum;
import com.vci.web.model.SmPasswordStrategyDO;
import com.vci.web.model.SmUserDO;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
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.util.WebUtil.arryAndSqlToBusinessObject;
/**
@@ -112,6 +115,11 @@
   public static final String QUERY_FIELD_ROLE = "roleUser.plroleuid";
   /**
    * 必填列
    */
   private ArrayList<Integer> ColumnNameisRed = new ArrayList<Integer>();
   /**
    * 用户分页查询时获取部门放到这里避免重复查询
    */
   private Map<String,List<OrgDepartmentVO>> orgDepartmentVOMap;
@@ -127,6 +135,11 @@
   private Map<String,SmPasswordStrategyVO> smPwdStrategyVOMap;
   /**
    * 日志
    */
   private Logger logger = LoggerFactory.getLogger(getClass());
   /**
    * 检查用户是否存在,可以根据用户名,也可以根据用户oid
    * @param userName  传null,即用oid作为检查条件
    * @param oid    传null,即用userName作为检查条件
@@ -135,7 +148,7 @@
   @Override
   public boolean checkUserExist(String userName, String oid) throws PLException {
      if(Func.isEmpty(userName) && Func.isEmpty(oid)){
         throw new PLException("检查用户是否存在时,传递的参数用户名和用户oid都为空!",new String[0]);
         throw new PLException("500", new String[] { "检查用户是否存在时,传递的参数用户名和用户oid都为空!"});
      }
      UserInfo userInfo = null;
      if(Func.isNotEmpty(userName)) {
@@ -171,7 +184,7 @@
    * @throws VciBaseException 查询出错的时候会抛出异常
    */
   private SmUserVO getUserByField(String queryField,String queryValue) throws VciBaseException{
      VciQueryWrapperForDO queryWrapper = new VciQueryWrapperForDO(null,SmUserDO.class,null,true);
      VciQueryWrapperForDO queryWrapper = new VciQueryWrapperForDO(null, SmUserDO.class,null,true);
      queryWrapper.eq(queryWrapper.getTableNick() + "." +queryField,queryValue);
      queryWrapper.setDistinct(true);
      queryWrapper.wrapperSql();
@@ -238,6 +251,7 @@
         throw new VciBaseException("获取用户失败:"+e.getMessage());
      }
   }
   /**
     * 根据用户主键获取用户的信息
     * @param userOid 用户主键
@@ -277,7 +291,7 @@
    * @param userInfoArr 业务数据数组
    * @return 显示对象集合
    */
   private List<SmUserVO> userInfoArr2VO(UserInfo[] userInfoArr) {
   private List<SmUserVO> userInfoArr2VO(UserInfo[] userInfoArr) throws PLException {
      List<SmUserVO> userVOList = new ArrayList<>();
      for(UserInfo userInfo : userInfoArr){
         userVOList.add(userInfo2VO(userInfo));
@@ -290,19 +304,30 @@
    * @param userInfo 平台返回的业务数据
    * @return 用户显示对象
    */
   private SmUserVO userInfo2VO(UserInfo userInfo) {
   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(smUserVO.getSecretGrade()));
      smUserVO.setSecretGradeText(UserSecretEnum.getSecretText(userInfo.secretGrade));
      smUserVO.setUserType(String.valueOf(userInfo.userType));
      smUserVO.setUserTypeText(UserTypeEnum.getTextByValue(smUserVO.getUserType()));
      smUserVO.setUserTypeText(UserTypeEnum.getTextByValue(String.valueOf(userInfo.userType)));
      smUserVO.setDescription(userInfo.desc);
      smUserVO.setEmail(userInfo.email);
      smUserVO.setStatus(userInfo.status);
      smUserVO.setPassword(userInfo.pwd);
      //用户所属部门的查询设置
      List<OrgDepartmentVO> orgDepartmentVOList = orgDepartmentVOMap.get(userInfo.id);
      List<OrgDepartmentVO> orgDepartmentVOList;
      //查看全局变量中是否存在部门信息,存在的情况最主要是针对多条用户查询的时候避免重复查询的
      if(Func.isNotEmpty(orgDepartmentVOMap)){
         orgDepartmentVOList = orgDepartmentVOMap.get(userInfo.id);
      }else {
         orgDepartmentVOList = orgDeptQueryService.listDeptByUserOid(userInfo.id,null);
      }
      smUserVO.setPkDepartment(
            Func.isEmpty(orgDepartmentVOList) ?
                  null:orgDepartmentVOList.stream().map(OrgDepartmentVO::getOid).collect(Collectors.joining(","))
@@ -312,11 +337,23 @@
                  null:orgDepartmentVOList.stream().map(OrgDepartmentVO::getName).collect(Collectors.joining(","))
      );
      //密码策略查询设置
      SmPasswordStrategyVO smPasswordStrategyVO = smPwdStrategyVOMap.getOrDefault(userInfo.id,new SmPasswordStrategyVO());
      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 = smRoleVOMap.get(userInfo.id);
      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(","))
@@ -495,14 +532,15 @@
         pageHelper = new PageHelper(-1);
      }
      pageHelper.addDefaultAsc("PLTRUENAME");
      //String userName = WebThreadLocalUtil.getCurrentUserSessionInfoInThread().getUserName();
      //TODO:为了方便调试,所以这儿先注释写死后面记得更改
      String loginUserId = WebThreadLocalUtil.getCurrentUserSessionInfoInThread().getUserId();
      //分页查询
      UserInfo[] userInfos = platformClientUtil.getFrameworkService().fetchUserInfoByCondition(
            conditionMap.get("name"),
            conditionMap.get("userName"),
            conditionMap.get("deptId"),
            conditionMap.get("roleId"),
            "developer",  //当前登录的用户名
            conditionMap.get("id"),
            conditionMap.get("pkDepartment"),
            conditionMap.get("pkPerson"),
            loginUserId,  //当前登录的用户名
            pageHelper.getPage(),
            pageHelper.getLimit()
      );
@@ -516,10 +554,10 @@
         dataGrid.setTotal(
               platformClientUtil.getFrameworkService().getUserTotalByCondition(
                  conditionMap.get("name"),
                  conditionMap.get("userName"),
                  conditionMap.get("deptId"),
                  conditionMap.get("roleId"),
                  "developer"  //当前登录的用户名
                  conditionMap.get("id"),
                  conditionMap.get("pkDepartment"),
                  conditionMap.get("pkPerson"),
                  loginUserId  //当前登录的用户名
               )
         );
      }
@@ -557,6 +595,7 @@
      SmUserVO userVO = getUserByUserId(userId);
      return userVO == null?"":userVO.getName();
   }
    /**
     * 根据用户主键获取用户的姓名
     * @param userOid 用户主键
@@ -617,42 +656,6 @@
      addRoleQuerySql(queryMap,queryWrapperForDO);
      queryWrapperForDO.eq("plstatus", "0");
      queryWrapperForDO.eq("plusertype", "2");
      queryWrapperForDO.setDistinct(true);
      return queryWrapperForDO;
   }
   /**
    * 获取查询封装器,默认只查plusertype!=1的
    * @param queryField 查询属性
    * @param queryValue 查询的值
    * @param queryMap  查询条件,如果是角色的属性,需要使用pkrole.xxx
    * @param pageHelper 分页对象
    * @param notIn 是否为不包含
    * @return 查询封装器
    */
   private VciQueryWrapperForDO getQueryWrapper2(String queryField,String queryValue,Map<String,String> queryMap,PageHelper pageHelper,boolean notIn){
      if(pageHelper == null){
         pageHelper = new PageHelper(-1);
      }
      pageHelper.addDefaultAsc("plusername");
      VciQueryWrapperForDO queryWrapperForDO = new VciQueryWrapperForDO(queryMap,SmUserDO.class,pageHelper);
      if(StringUtils.isNotBlank(queryField)) {
         if (queryValue.contains(",")) {
            if (notIn) {
               queryWrapperForDO.notIn(queryField, VciBaseUtil.toInSql(VciBaseUtil.str2List(queryValue).toArray(new String[0])));
            } else {
               queryWrapperForDO.in(queryField, VciBaseUtil.toInSql(VciBaseUtil.str2List(queryValue).toArray(new String[0])));
            }
         } else {
            if (notIn) {
               queryWrapperForDO.neq(queryField, queryValue);
            } else {
               queryWrapperForDO.eq(queryField, queryValue);
            }
         }
      }
      addRoleQuerySql(queryMap,queryWrapperForDO);
      queryWrapperForDO.neq("plusertype", "2");
      queryWrapperForDO.setDistinct(true);
      return queryWrapperForDO;
   }
@@ -928,7 +931,6 @@
      return false;
   }
    /**
     * 设置某个用户是锁定状态
     * @param userId 用户名
@@ -960,6 +962,7 @@
     * @param confirmPassword 确认密码
     */
   @Override
   @Transactional(rollbackFor = Exception.class)
   public void changePassword(String userOid, String password,
         String confirmPassword) throws VciBaseException {
      WebUtil.alertNotNull(userOid,"用户主键",password,"密码",confirmPassword,"确认密码");
@@ -1017,40 +1020,41 @@
    * @return
    */
   @Override
   @Transactional(rollbackFor = Exception.class)
   public boolean addUser(SmUserDTO smUserDTO) throws PLException {
      //判空
      VciBaseUtil.alertNotNull(
            smUserDTO,"添加的用户对象",
            smUserDTO.getId(),"账号",
            smUserDTO.getId(),"用户名",
            smUserDTO.getPassword(),"密码",
            smUserDTO.getConfirmPassword(),"确认密码",
            smUserDTO.getName(),"姓名"
      );
      //确认密码
      String confirmPassword = smUserDTO.getConfirmPassword();
      //比对密码是是否一致
      if(!smUserDTO.getPassword().equals(confirmPassword)){
         throw new VciBaseException("两次密码不一致,请重新填写!");
      }
      //先用户名(账号)查重
      SmUserVO dbSmUserVO = getUserByUserId(smUserDTO.getId());
      if(Func.isNotEmpty(dbSmUserVO) && Func.isNotBlank(dbSmUserVO.getOid())){
         throw new VciBaseException("该用户名在系统中已经存在,请修改!");
      }
      //密码加密
      ThreeDES des = new ThreeDES();
      des.getKey("daliantan0v0");// 生成密匙
      //第二次MD5加密
      String md5Password2 = des.getEncString(smUserDTO.getPassword());
      //校验
      check(smUserDTO,true,false);
      //生成存储的DO对象
      smUserDTO.setOid(VciBaseUtil.getPk());
      smUserDTO.setPassword(md5Password2);
      smUserDTO.setLockFlag("0");
      BusinessObject user = ClientServiceProvider.getBOFService().initBusinessObject("user");
      SmUserDO smUserDO = new SmUserDO();
      BeanUtil.convert(user,smUserDO);
      UserInfo userInfo = new UserInfo();
      BeanUtil.convert(smUserDO,userInfo);
      return platformClientUtil.getFrameworkService().saveOrUpdateUser(userInfo, null);
      Date date = new Date();
      smUserDTO.setPwdUpdateTime(date);
      smUserDTO.setStatus((short) 0);
      smUserDTO.setCreateTime(date);
      smUserDTO.setLastModifyTime(date);
      String loginUserName = WebThreadLocalUtil.getCurrentUserSessionInfoInThread().getUserId();
      smUserDTO.setCreator(loginUserName);
      //smUserDTO.setCreator("developer");
      smUserDTO.setLastModifier(loginUserName);
      //smUserDTO.setLastModifier("developer");
      UserInfo userInfo = changeSmUserDTOToUserInfo(smUserDTO);
      UserEntityInfo userEntityInfo = new UserEntityInfo(loginUserName, "");
      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());
         //platformClientUtil.getFrameworkService().saveUserDept(new String[]{oid}, smUserDTO.getPkDepartment(), userEntityInfo);
      }
      return true;
   }
   /**
@@ -1059,34 +1063,121 @@
    * @return
    */
   @Override
   @Transactional(rollbackFor = Exception.class)
   public boolean updateUser(SmUserDTO smUserDTO) throws PLException {
      UserInfo userInfo = new UserInfo();
      BeanUtil.convert(smUserDTO,userInfo);
      return platformClientUtil.getFrameworkService().updateUser(userInfo, null);
      //判空
      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[] { "当前修改的用户不存在"});
      }
      smUserDTO.setLastModifyTime(new Date());
      String loginUserName = WebThreadLocalUtil.getCurrentUserSessionInfoInThread().getUserId();
      smUserDTO.setLastModifier(loginUserName);
      UserInfo userInfo = changeSmUserDTOToUserInfo(smUserDTO);
      boolean updateBoolean = platformClientUtil.getFrameworkService().updateUser(userInfo, new UserEntityInfo(loginUserName, null));
      //修改成功,并且用户关联部门有所更改
      if(updateBoolean && Func.isNotEmpty(smUserDTO.getPkDepartment()) && !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 {
         //TODO:为了方便调试,所以这儿先注释写死后面记得更改
         //String userName = WebThreadLocalUtil.getCurrentUserSessionInfoInThread().getUserId();
         String userName = "developer";
         String error = platformClientUtil.getFrameworkService().checkPasswordStrategyByUserId(userName, smUserDTO.getPassword(),null);
         if (!StringUtils.isBlank(error)) {
            throw new VciBaseException("当前设置的密码,密码策略校验未通过");
         }
      } catch (PLException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
         throw new VciBaseException("检查密码策略符合情况失败!2");
      }
   }
   /***
    * 用户从客户端对象到corba对象
    *
    * 用户从DTO对象到corba对象
    * @param user
    * @return
    */
   public UserInfo changeUserObjectToUserInfo(UserObject user) {
   public UserInfo changeSmUserDTOToUserInfo(SmUserDTO user) {
      UserInfo userInfo = new UserInfo();
      userInfo.id = user.getId() == null ? "" : user.getId();
      userInfo.userName = user.getUserName() == null ? "" : user.getUserName();
      userInfo.pwd = user.getPwd() == null ? "" : user.getPwd();
      userInfo.trueName = user.getTrueName() == null ? "" : user.getTrueName();
      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.getDesc() == null ? "" : user.getDesc();
      userInfo.desc = user.getDescription() == null ? "" : user.getDescription();
      userInfo.userType = user.getUserType();
      userInfo.status = user.getStatus();
      userInfo.createTime = user.getCreateTime();
      userInfo.createUser = user.getCreateUser() == null ? "" : user.getCreateUser();
      userInfo.updateTime = user.getUpdateTime();
      userInfo.updateUser = user.getUpdateUser() == null ? "" : user.getUpdateUser();
      userInfo.pwdUpdateTime = user.getPwdUpdateTime();
      userInfo.createTime = user.getCreateTime().getTime();
      userInfo.createUser = user.getCreator() == null ? "" : user.getCreator();
      userInfo.updateTime = user.getLastModifyTime().getTime();
      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;
@@ -1098,8 +1189,12 @@
    * @return
    */
   @Override
   @Transactional(rollbackFor = Exception.class)
   public boolean deleteUser(String[] ids) throws PLException {
      VciBaseUtil.alertNotNull(ids,"待删除的用户id列表不能为空!");
      if(Func.isEmpty(ids)){
         throw new VciBaseException("待删除的用户id列表不能为空!");
      }
      //调用platformClientUtil的删除用户的方法,会一起删除掉具备关联关系的一些信息,如部门
      return platformClientUtil.getFrameworkService().deleteUser(ids, null);
   }
@@ -1110,9 +1205,163 @@
    * @return
    */
   @Override
   public boolean disableOrEnableUsers(String[] ids, boolean flag) throws PLException {
   @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) {
      // 设置表单列名
      List<String> columns = new ArrayList<>(Arrays.asList("账号", "密码", "姓名", "电子邮箱", "专业", "描述", "部门(上下级部门之间以反斜杠隔开(/))"));
      //获取是否导出密级配置项
      String flag = ConfigReader.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 VciBaseException {
      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);
         //是否导入密级配置
         boolean exportSecretGrade = Boolean.parseBoolean(ConfigReader.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为部门信息
         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.setLastModifyTime(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("用户导入成功!");
   }
}