/**
 * Copyright &copy; 2021-2026 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
 */
package com.jeeplus.sys.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jeeplus.center.enums.ServiceAliasEnum;
import com.jeeplus.centerservice.utils.RestTemplateService;
import com.jeeplus.sys.domain.*;
import com.jeeplus.sys.mapper.OfficeMapper;
import com.jeeplus.sys.service.dto.CertDTO;
import com.jeeplus.sys.service.dto.LoginUserOnlineDTO;
import com.jeeplus.sys.service.mapstruct.CertWrapper;
import com.jeeplus.sys.utils.ServletUtils;
import com.jeeplus.sys.utils.ip.AddressUtils;
import com.jeeplus.sys.utils.ip.IpUtils;
import eu.bitwalker.useragentutils.UserAgent;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jeeplus.common.redis.RedisUtils;
import com.jeeplus.common.utils.RequestUtils;
import com.jeeplus.sys.constant.CacheNames;
import com.jeeplus.sys.mapper.UserMapper;
import com.jeeplus.sys.service.dto.OfficeDTO;
import com.jeeplus.sys.service.dto.UserDTO;
import com.jeeplus.sys.service.mapstruct.UserWrapper;
import com.jeeplus.sys.utils.UserUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

/**
 * 用户管理
 * @author jeeplus
 * @version 2021-09-05
 */
@Service
@Transactional
public class UserService  extends ServiceImpl<UserMapper, User> {

	@Autowired
	private UserWrapper userWrapper;

	@Autowired
	private RedisUtils redisUtils;

	@Autowired
	private SysConfigService sysConfigService;

	@Autowired
	private UserMapper userMapper;

	@Autowired
	private OfficeMapper officeMapper;

	@Autowired
	private CertService certService;

	@Autowired
	private SerialnumTplCService serialnumTplCService;

	@Autowired
	private RosterBaseCService rosterBaseCService;

	@Autowired
	private SysUserFailedLogService sysUserFailedLogService;

	@Autowired
	private RestTemplateService restTemplateService;

	/**
	 * 单一登录判断，是否允许登录
	 * @return
	 */
	public boolean isEnableLogin (String loginName) {
		SysConfig sysConfig = sysConfigService.getById ( "1");
		if(sysConfig.getMultiAccountLogin ().equals ( "0" )){ // 不允许一个账号多个客户端登录
			if(sysConfig.getSingleLoginType ().equals ( "1" )){ // 后登陆踢出先登录
				Set <String> keys = RedisUtils.getInstance ( ).keys ( CacheNames.USER_CACHE_TOKEN + loginName+ "*");
				keys.forEach ( key->{
					String token = RedisUtils.getInstance ().get ( key ).toString ();
//					RedisUtils.getInstance ().delete ( CacheNames.USER_CACHE_TOKEN + loginName + ":" + token );
					RedisUtils.getInstance ().set ( CacheNames.USER_CACHE_TOKEN + loginName + ":" + token, "kickOut" );
				} );
			}else{ // 已经登陆禁止再登录
				if(redisUtils.keys (CacheNames.USER_CACHE_TOKEN+ loginName+"*"   ).size () >0){
					return  false;
				};
			}
		}
		return true;
	}


	/**
	 * 获取用户
	 * @param id
	 * @return
	 */
	public UserDTO get(String id) {
		QueryWrapper queryWrapper = new QueryWrapper ();
		queryWrapper.eq ("a.id", id);
		return baseMapper.get (queryWrapper);
	}

	/**
	 * 根据登录名获取用户
	 * @param loginName
	 * @return
	 */
	@Cacheable(cacheNames = CacheNames.USER_CACHE_LOGIN_NAME, key = "#loginName")
	public UserDTO getUserByLoginName(String loginName) {
		QueryWrapper queryWrapper = new QueryWrapper ();
		queryWrapper.eq ("a.login_name", loginName);
		queryWrapper.eq("a.del_flag","0");
		UserDTO userDTO = baseMapper.get(queryWrapper);

		final UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
		//获取登录ip
		final String ip = IpUtils.getIpAddr(ServletUtils.getRequest());

		// 获取客户端操作系统
		String os = userAgent.getOperatingSystem().getName();
		// 获取客户端浏览器
		String browser = userAgent.getBrowser().getName();
		// 登录地址
		String address = AddressUtils.getRealAddressByIP(ip);

		userDTO.setLoginTime(new Date());

		userDTO.setLoginIp(ip);
		userDTO.setLoginLocation(address);
		userDTO.setOs(os);
		userDTO.setBrowser(browser);

		return userDTO;
	}

	/**
	 * 根据登录名获取用户
	 * @param name
	 * @return
	 */
	public UserDTO getUserByName(String name) {
		UserDTO userDTO = userMapper.getUserByName(name);

		return userDTO;
	}

	/**
	 * 根据登录名获取用户,不使用缓存
	 * @param loginName
	 * @return
	 */
	public UserDTO getUserByLoginNameNoCache(String loginName) {
		QueryWrapper queryWrapper = new QueryWrapper ();
		queryWrapper.eq ("a.login_name", loginName);
		return baseMapper.get (queryWrapper);
	}

	/**
	 * 根据登录名获取用户id
	 * @param loginName
	 * @return
	 */
	public String getUserIdByLogin(String loginName) {
		return userMapper.getUserIdByLogin (loginName);
	}

	/**
	 * 根据登录名或手机号获取用户信息
	 * @param loginName
	 * @return
	 */
	public List<UserDTO> getUserIdByLoginOrMobile(String loginName) {
		return userMapper.getUserIdByLoginOrMobile (loginName);
	}

	/**
	 * 根据用户name获取用户id
	 * @param name
	 * @return
	 */
	public String getUserIdByName(String name) {
		return userMapper.getUserIdByName (name);
	}


	/**
	 * 自定义分页检索
	 * @param page
	 * @param queryWrapper
	 * @return
	 */
	public IPage <UserDTO> findPage(Page <UserDTO> page, QueryWrapper queryWrapper) {
		queryWrapper.eq ("a.del_flag", 0 ); // 排除已经删除
		IPage<UserDTO> list = baseMapper.findList(page, queryWrapper);
		if(CollectionUtil.isNotEmpty(list.getRecords())){
			list.getRecords().stream().forEach(item->{
				// 查询是否有需要手动推送到子系统的数据
				Map<String,Object> checkResp = rosterBaseCService.checkIsSyncFailed(item.getId());
				item.setPushFailed((Boolean)checkResp.get("success"));
			});
		}
		return list;
	}

	/**
	 * 查询角色下关联的用户
	 * @param page
	 * @param queryWrapper
	 * @return
	 */
	public IPage <UserDTO> findPageByRole(Page <UserDTO> page, QueryWrapper queryWrapper) {
		queryWrapper.eq ("a.del_flag", 0 ); //排除已经删除
		return  baseMapper.findListByRole (page, queryWrapper);


	}

	/**
	 * 查询角色下关联的用户
	 * @param roleId
	 * @return
	 */
	public List <UserDTO> findListByRoleId(String roleId) {
		QueryWrapper queryWrapper = new QueryWrapper (  );
		queryWrapper.eq ("a.del_flag", 0 ); //排除已经删除
		queryWrapper.eq ( "r.id", roleId );

		Page <UserDTO> page = new Page <> (  );
		page.setSize ( -1 );
		return  baseMapper.findListByRole ( page, queryWrapper ).getRecords ();
	}

	/**
	 * 查询岗位下关联的用户
	 * @param postId
	 * @return
	 */
	public List <UserDTO> findListByPostId(String postId) {
		return  baseMapper.findListByPostId ( postId );


	}

	public void saveUserRole(String userId,String roleId){
		if(StrUtil.isNotEmpty(userId)&&StrUtil.isNotEmpty(roleId)){
			baseMapper.insertUserRole ( userId, roleId );
		}
	}

	/**
	 * 保存或者更新用户
	 * @param userDTO
	 */
	public void saveOrUpdate(UserDTO userDTO) throws Exception {
		// 获取修改前的所属部门id
		String oldOffice = "";
		if (ObjectUtil.isNotEmpty(userDTO) && StringUtils.isNotBlank(userDTO.getId())) {
			User byIdUser = baseMapper.selectById(userDTO.getId());
			if (ObjectUtil.isNotEmpty(byIdUser) && StringUtils.isNotBlank(byIdUser.getOfficeId())) {
				oldOffice = byIdUser.getOfficeId();
			}
		}
		User user = userWrapper.toEntity (userDTO);
		super.saveOrUpdate ( user );
		if( StrUtil.isBlank ( userDTO.getId () ) ){
			userDTO.setId ( user.getId () );
		}
		// 更新用户与角色关联
		baseMapper.deleteUserRole(userDTO.getId ());
		if (userDTO.getRoleDTOList () != null){
			userDTO.getRoleDTOList ().forEach ( roleDTO -> {
				baseMapper.insertUserRole ( userDTO.getId (), roleDTO.getId () );
			} );
		}else{
			throw new RuntimeException (userDTO.getLoginName() + "没有设置角色！");
		}
		// 更新用户与岗位联系
		baseMapper.deleteUserPost ( userDTO.getId () );
		if(userDTO.getPostDTOList () != null) {
			userDTO.getPostDTOList ().forEach ( postDTO -> {
				baseMapper.insertUserPost ( userDTO.getId (), postDTO.getId () );
			} );
		}
		// 更新用户的管理部门
		List<String> officeIdList = new ArrayList<>();
		if(StringUtils.isNotBlank(userDTO.getManageOfficeIds())){
			List<String> officeIds = Arrays.asList(userDTO.getManageOfficeIds().split(","));
			officeIdList.addAll(officeIds);
		}
		this.updateUserManageOffice(officeIdList, userDTO);

		// 新增/修改关联花名册数据
		this.saveOrUpdateRoster(user, oldOffice);

		UserUtils.deleteCache ( userDTO );
	}


	public Map<String,Object> deleteUser(UserDTO userDTO) {
		Map<String,Object> responseMap = new HashMap<>();
		if (ObjectUtil.isNotEmpty(userDTO) && StringUtils.isNotBlank(userDTO.getRosterId())) {
			String rosterId = userDTO.getRosterId();
			AtomicBoolean runSuccess = new AtomicBoolean(true);
			// 先删除子系统花名册以及用户数据
			Map<String,Object> paramMap = new HashMap<>();
			paramMap.put("rosterId",rosterId);
			User u = this.getOne(new QueryWrapper<User>().lambda().eq(User::getRosterId, rosterId));
			paramMap.put("userId",u.getId());
			String officeCode = rosterBaseCService.getServiceByOffice(u.getOfficeId());  // 根据这个部门id获取二级部门的别名code来获取所属哪个子系统
			if (StringUtils.isNotBlank(officeCode)) {
				// 评估
				if (ServiceAliasEnum.CPA_EVALUATION.getValue().equals(officeCode) || ServiceAliasEnum.CPA_PUBLIC.getValue().equals(officeCode)) {
					// 首先将数据记录为清除失败，待获取到其他系统执行成功的回值后再将此记录删掉
					boolean succ = false;
					String dataId_evaluation = sysUserFailedLogService.removeFailedLog(u.getId(), ServiceAliasEnum.CPA_EVALUATION.getValue());
					Object res_evaluation = restTemplateService.getCPA_EVALUATION("/roster/base/removeByRosterId",null,paramMap);
					if (ObjectUtil.isNotEmpty(res_evaluation)) {
						Map<String,Object> resMap = JSONObject.parseObject(JSON.toJSONString(res_evaluation), Map.class);
						if ((Boolean) resMap.get("success")) {
							// 删除成功，将刚才记录的数据删除
							sysUserFailedLogService.removeById(dataId_evaluation);
							succ = true;
						}
					}
					if (!succ) { // succ的值为false，那么说明数据删除失败
						runSuccess.set(false);
					}
				}
				// 财务
				if (ServiceAliasEnum.CPA_FINANCE.getValue().equals(officeCode) || ServiceAliasEnum.CPA_PUBLIC.getValue().equals(officeCode)) {
					// 首先将数据记录为清除失败，待获取到其他系统执行成功的回值后再将此记录删掉
					boolean succ = false;
					String dataId_finance = sysUserFailedLogService.removeFailedLog(u.getId(), ServiceAliasEnum.CPA_FINANCE.getValue());
					Object res_finance = restTemplateService.getCPA_FINANCE("/roster/base/removeByRosterId",null,paramMap);
					if (ObjectUtil.isNotEmpty(res_finance)) {
						Map<String,Object> resMap = JSONObject.parseObject(JSON.toJSONString(res_finance), Map.class);
						if ((Boolean) resMap.get("success")) {
							// 删除成功，将刚才记录的数据删除
							sysUserFailedLogService.removeById(dataId_finance);
							succ = true;
						}
					}
					if (!succ) { // succ的值为false，那么说明数据删除失败
						runSuccess.set(false);
					}
				}
				// 中审
				if (ServiceAliasEnum.CPA_AUDIT.getValue().equals(officeCode) || ServiceAliasEnum.CPA_PUBLIC.getValue().equals(officeCode)) {
					// 首先将数据记录为清除失败，待获取到其他系统执行成功的回值后再将此记录删掉
					boolean succ = false;
					String dataId_audit = sysUserFailedLogService.removeFailedLog(u.getId(), ServiceAliasEnum.CPA_AUDIT.getValue());
					Object res_audit = restTemplateService.getCPA_AUDIT("/roster/base/removeByRosterId",null,paramMap);
					if (ObjectUtil.isNotEmpty(res_audit)) {
						Map<String,Object> resMap = JSONObject.parseObject(JSON.toJSONString(res_audit), Map.class);
						if ((Boolean) resMap.get("success")) {
							// 删除成功，将刚才记录的数据删除
							sysUserFailedLogService.removeById(dataId_audit);
							succ = true;
						}
					}
					if (!succ) { // succ的值为false，那么说明数据删除失败
						runSuccess.set(false);
					}
				}
			}
			if (runSuccess.get()) { // runSuccess的值为true，则说明子系统的操作都执行成功
				// 删除花名册数据
				rosterBaseCService.removeById(rosterId);
				// 删除用户关联的管理部门信息
				this.deleteUserManageOffice(userDTO);  //  根据用户id删除用户的管理部门信息
				// 删除用户关联的岗位信息
				this.deleteUserPost(userDTO.getId());
				// 删除用户关联的角色信息
				this.deleteUserRole(userDTO.getId());
				// 删除用户
				this.removeById(userDTO.getId());
				// 清除redis缓存
				UserUtils.deleteCache ( userDTO );
				responseMap.put("success", true);
				responseMap.put("message", "删除成功");
			} else {
				responseMap.put("success", false);
				responseMap.put("message", "删除失败，子系统删除数据未成功");
			}
		} else {
			responseMap.put("success", false);
			responseMap.put("message", "删除失败，未找到用户或关联花名册数据");
		}
		return responseMap;
	}

	public void updateUserLoginInfo(UserDTO userDTO) {
		User user = new User ( userDTO.getId () );
		// 更新本次登录信息
		HttpServletRequest request = RequestUtils.getRequest ();
		if ( request != null ) {
			user.setLoginIp( request.getRemoteHost () );
		}

		user.setLoginDate(new Date());
		super.updateById (user);
	}

	//查询所有人员信息
	public List<OfficeDTO> disposeUserOffice(List<OfficeDTO> officeDTOList, String type){
		return userMapper.findListByCompanyId(UserUtils.getCurrentUserDTO().getCompanyDTO().getId(),type);
	}

	//根据部门查询用户信息
	public List<OfficeDTO> getUserByOffice(List<String> officeIds,String type){
		return userMapper.getUserByOffice(officeIds,type);
	}

	/**
	 * 根据部门id查询部门下所有有效用户信息
	 * @param officeIds
	 * @return
	 */
	public List<UserDTO> getUserByOfficeIds(List<String> officeIds){
		return userMapper.getUserByOfficeIds(officeIds);
	}


	public LoginUserOnlineDTO selectOnlineByInfo(String ip, String userName, UserDTO user){
		if (StringUtils.equals(ip, user.getIp()) && StringUtils.equals(userName, user.getName())) {
			return loginUserToUserOnline(user);
		}
		return null;
	}

	public LoginUserOnlineDTO selectOnlineByIp(String ip,  UserDTO user){
		if (StringUtils.equals(ip, user.getIp())) {
			return loginUserToUserOnline(user);
		}
		return null;
	}

	public LoginUserOnlineDTO selectOnlineByName(String userName, UserDTO user){
		if (StringUtils.equals(userName, user.getName())) {
			return loginUserToUserOnline(user);
		}
		return null;
	}

	/**
	 * 设置在线用户信息
	 *
	 * @param user 用户信息
	 * @return 在线用户
	 */
	public LoginUserOnlineDTO loginUserToUserOnline(UserDTO user)
	{
		if (null == user ) {
			return null;
		}
		LoginUserOnlineDTO sysUserOnline = new LoginUserOnlineDTO();
		sysUserOnline.setTokenId(user.getToken());
		sysUserOnline.setUserName(user.getName());
		sysUserOnline.setIp(user.getIp());
		sysUserOnline.setLoginLocation(user.getLoginLocation());
		sysUserOnline.setBrowser(user.getBrowser());
		sysUserOnline.setOs(user.getOs());
		sysUserOnline.setLoginTime(user.getLoginTime());
		sysUserOnline.setLoginName(user.getLoginName());
		if(null != user.getOfficeDTO() && StringUtils.isNotBlank(user.getOfficeDTO().getName())){
			sysUserOnline.setOfficeName(user.getOfficeDTO().getName());
		}
		return sysUserOnline;
	}

	/**
	 * 根据部门id获取 部门 以及 子部门 下的所有用户信息
	 * @param officeId
	 * @return
	 */
	public List<User> getUserByOfficeAll(String officeId){
		List<Office> officeList = officeMapper.selectList(new QueryWrapper<Office>().lambda().eq(Office::getParentId, officeId));
		List<String> officeIdList = officeList.stream().distinct().map(Office::getId).collect(Collectors.toList());
		while(true) {
			List<String> ids = new ArrayList<>();
			officeIdList.stream().forEach(item->{
				List<Office> officeList1 = officeMapper.selectList(new QueryWrapper<Office>().lambda().eq(Office::getParentId, item));
				officeList1.stream().forEach(i->{
					officeList.add(i);
					ids.add(i.getId());
				});
			});
			if (CollectionUtil.isNotEmpty(ids)) {
				officeIdList = ids;
			} else {
				break;
			}
		}
		List<String> officeIds = officeList.stream().distinct().filter(item -> {
			if (StringUtils.isNotBlank(item.getId())) {
				return true;
			}
			return false;
		}).map(Office::getId).collect(Collectors.toList());
		officeIds.add(officeId);
		return userMapper.selectList(new QueryWrapper<User>().lambda().in(User::getOfficeId,officeIds));
	}


	/**
	 * 根据用户手机号和当前人id查询非当前登录人的信息
	 * @param userDTO
	 */
	public List<UserDTO> getUserInfoByMobile(UserDTO userDTO) {
		return userMapper.getUserInfoByMobile(userDTO);
	}

//	保存人员执业资质
	public void saveCertList(UserDTO userDTO) {
		if (ObjectUtil.isNotEmpty(userDTO)) {
			if (CollectionUtil.isNotEmpty(userDTO.getCertDTOList())) {
				List<String> ids = userDTO.getCertDTOList().stream().filter(item -> {
					if (com.jeeplus.sys.utils.StringUtils.isNotBlank(item.getId())) {
						return true;
					}
					return false;
				}).map(CertDTO::getId).collect(Collectors.toList());
				if (CollectionUtil.isNotEmpty(ids)) {
					certService.remove(new QueryWrapper<Cert>().lambda().eq(Cert::getUserId,userDTO.getId()).notIn(Cert::getId,ids));
				}else{
					certService.remove(new QueryWrapper<Cert>().lambda().eq(Cert::getUserId,userDTO.getId()));
				}
				userDTO.getCertDTOList().stream().forEach(item->{
					Cert cert = CertWrapper.INSTANCE.toEntity(item);
					cert.setUserId(userDTO.getId());
					certService.saveOrUpdate(cert);
				});
			} else {
				certService.remove(new QueryWrapper<Cert>().lambda().eq(Cert::getUserId,userDTO.getId()));
			}
		}
	}


	/**
	 * 根据角色名称查询角色下人员信息
	 * @param roleName 角色名称
	 * @return
	 */
	public List<UserDTO> getUserInfoByRoleName(String roleName){
		return userMapper.getUserInfoByRoleName(roleName);
	}

	/**
	 * 根据角色英文名称查询角色下人员信息
	 * @param enName 角色英文名称
	 * @return
	 */
	public List<UserDTO> getUserInfoByEnName(String enName){
		return userMapper.getUserInfoByEnName(enName);
	}

	public Boolean isUpdatePassword(String userId) {
		String updatePassword = userMapper.isUpdatePassword(userId);
		if (StringUtils.isNotBlank(updatePassword)) {
			if ("1".equals(updatePassword)) {
				// 密码已经修改过
				return true;
			}
		}
		return false;
	}


	/**
	 * 修改用户修改密码状态信息
	 * @param userDTO
	 */
	public void updateUserUpPassword(UserDTO userDTO) {
		userMapper.updateUserUpPassword (userDTO);
	}

	public void updateUserManageOffice(List<String> officeIdList, UserDTO userDTO) {
		//根据用户id删除原有用户管理的部门信息
		userMapper.deleteUserManageOffice(userDTO);
		//遍历将新的用户管理的部门信息信息添加进去
		if(officeIdList.size()>0){
			for (String officeId : officeIdList) {
				userMapper.insertUserManageOffice(officeId,userDTO.getId());
			}
		}
	}

	// 新增/修改花名册数据
	public void saveOrUpdateRoster (User user, String oldOfficeId) throws Exception {
		RosterBaseC r = new RosterBaseC();
		r.setName(user.getName());  // 姓名
		r.setOfficeId("");  // 部门
		r.setMobile("");  // 电话号码
		r.setEmail("");  // 邮箱
		if (StringUtils.isNotBlank(user.getOfficeId())) {
			r.setOfficeId(user.getOfficeId());  // 部门
		}
		if (StringUtils.isNotBlank(user.getMobile())) {
			r.setMobile(user.getMobile());  // 电话号码
		}
		if (StringUtils.isNotBlank(user.getEmail())) {
			r.setEmail(user.getEmail());  // 邮箱
		}
		User u = this.getById(user.getId());
		if (StringUtils.isNotBlank(u.getRosterId())) {
			r.setId(u.getRosterId()); // 花名册id
			r.setWorkerType("1");  //  员工类型： 全职
			RosterBaseC roster = rosterBaseCService.getById(u.getRosterId());
			if (ObjectUtil.isNotEmpty(roster)) {
				if (StringUtils.isNotBlank(roster.getWorkerType())) {
					r.setWorkerType(roster.getWorkerType());  //  如果花名册的员工类型有值，则不修改花名册的员工类型
				}
			}
		} else {
			UserDTO userDTO = UserUtils.getCurrentUserDTO();
			String serialNum = serialnumTplCService.genSerialNum(userDTO.getCompanyDTO().getId(), "3");
			r.setJobNo(serialNum); // 花名册工号
			user.setNo(serialNum); // 用户工号
			r.setPersonType("1");  //  人员类型： 员工
			r.setWorkerType("1");  //  员工类型： 全职
		}
		// 保存花名册数据
		rosterBaseCService.saveOrUpdate(r);
		user.setRosterId(r.getId());
		this.updateById(user);
		r.setUserId(u.getId());
		rosterBaseCService.syncPushSubsystem(r,oldOfficeId);
	}

	// 修改用户信息
	public ResponseEntity updateInfo(UserDTO userDTO) throws Exception {
		// 获取修改前的所属部门id
		String oldOffice = "";
		if (ObjectUtil.isNotEmpty(userDTO) && StringUtils.isNotBlank(userDTO.getId())) {
			User byIdUser = baseMapper.selectById(userDTO.getId());
			if (ObjectUtil.isNotEmpty(byIdUser) && StringUtils.isNotBlank(byIdUser.getOfficeId())) {
				oldOffice = byIdUser.getOfficeId();
			}
		}
		User user = UserWrapper.INSTANCE.toEntity(userDTO);
		// 根据用户id修改用户信息
		this.updateById (user);
		// 修改用户信息的同时更新花名册数据
		this.saveOrUpdateRoster(user, oldOffice);
		//更新缓存信息
		UserUtils.deleteCache ( UserUtils.getCurrentUserDTO ( ) );
		return ResponseEntity.ok ( "修改个人资料成功!" );
	}

	// 根据用户id查询资格证
	public List<Cert> getCertListByUserId(String userId) {
		return certService.list(new QueryWrapper<Cert>().lambda().eq(Cert::getUserId,userId));
	}

	// 根据岗位id查询用户
	public List<User> getUserIdByPost(String postId) {
		return userMapper.getUserByPost(postId);
	}

	public void deleteUserManageOffice(UserDTO userDTO) {
		userMapper.deleteUserManageOffice(userDTO);
	}

	public void deleteUserPost(String id) {
		userMapper.deleteUserPost(id);
	}

	public void deleteUserRole(String id) {
		userMapper.deleteUserRole(id);
	}

	/**
	 * 手动向子系统推送之前同步失败的数据
	 * @param userId
	 * @return
	 */
	public boolean pushUserSync(String userId) {
		AtomicBoolean respBool = new AtomicBoolean(true);
		User user = this.getById(userId);
		RosterBaseC rosterBase = rosterBaseCService.getById(user.getRosterId());
		rosterBase.setUserId(userId);
		Map<String,Object> bodyMap = JSONObject.parseObject(JSON.toJSONString(rosterBase), Map.class);
		// 查询日志表中未重新推送的”删除”推送
		List<SysUserFailedLog> deleteUserFailedLogList = sysUserFailedLogService.list(new LambdaQueryWrapper<SysUserFailedLog>()
				.eq(SysUserFailedLog::getUserId, user.getId())
				.eq(SysUserFailedLog::getIsSuccess, "2") // 查询删除操作
				.ne(SysUserFailedLog::getIsPush, "1") // isPush != 1说明未推送成功
				.orderByDesc(SysUserFailedLog::getCreateDate)
		);
		// 查询当前用户推送子系统是否成功， isPush != 1说明未推送成功
		List<SysUserFailedLog> sysUserFailedLogList = sysUserFailedLogService.list(new LambdaQueryWrapper<SysUserFailedLog>()
				.eq(SysUserFailedLog::getUserId, user.getId())
				.ne(SysUserFailedLog::getIsPush, "1")
				.orderByDesc(SysUserFailedLog::getCreateDate)
		);
		if (CollectionUtil.isNotEmpty(sysUserFailedLogList)) {
			sysUserFailedLogList.stream().forEach(sysUserFailedLog -> {
				switch (sysUserFailedLog.getIsSuccess()) {
					case "0": // 保存操作失败
						boolean succ = false;
						Object res = null;
						if (ServiceAliasEnum.CPA_EVALUATION.getValue().equals(sysUserFailedLog.getBelongService())) {
							// 调用评估系统的用户保存操作
							res = restTemplateService.postCPA_EVALUATION("/roster/base/saveOrUpdateUserRoster",null,null,bodyMap);

						} else if (ServiceAliasEnum.CPA_FINANCE.getValue().equals(sysUserFailedLog.getBelongService())) {
							// 调用财务系统的用户保存操作
							res = restTemplateService.postCPA_FINANCE("/roster/base/saveOrUpdateUserRoster",null,null,bodyMap);

						} else if (ServiceAliasEnum.CPA_AUDIT.getValue().equals(sysUserFailedLog.getBelongService())) {
							// 调用财务系统的用户保存操作
							res = restTemplateService.postCPA_AUDIT("/roster/base/saveOrUpdateUserRoster",null,null,bodyMap);

						}
						if (ObjectUtil.isNotEmpty(res)) {
							Map<String,Object> resMap = JSONObject.parseObject(JSON.toJSONString(res), Map.class);
							if ((Boolean) resMap.get("success")) {
								// 保存成功，将推送日志表中的数据修改为推送完成
								sysUserFailedLogService.finishById(sysUserFailedLog.getId());
								succ = true;
							}
						}
						if (!succ) { // succ的值为false，说明此次手动推送失败
							respBool.set(false);
						}
						break;
					case "1": case "2": // 1:清除操作失败（这里指的是切换所属系统，要清除原系统中的人员信息）   2:删除操作失败
						boolean succ1 = false;
						Object res1 = null;
						if (ServiceAliasEnum.CPA_EVALUATION.getValue().equals(sysUserFailedLog.getBelongService())) {
							// 调用评估系统的用户清除操作
							res1 = restTemplateService.postCPA_EVALUATION("/roster/base/deleteUserRoster",null,null,bodyMap);
						} else if (ServiceAliasEnum.CPA_FINANCE.getValue().equals(sysUserFailedLog.getBelongService())) {
							// 调用财务系统的用户清除操作
							res1 = restTemplateService.postCPA_FINANCE("/roster/base/deleteUserRoster",null,null,bodyMap);
						} else if (ServiceAliasEnum.CPA_AUDIT.getValue().equals(sysUserFailedLog.getBelongService())) {
							// 调用财务系统的用户清除操作
							res1 = restTemplateService.postCPA_AUDIT("/roster/base/deleteUserRoster",null,null,bodyMap);
						}
						if (ObjectUtil.isNotEmpty(res1)) {
							Map<String,Object> resMap = JSONObject.parseObject(JSON.toJSONString(res1), Map.class);
							if ((Boolean) resMap.get("success")) {
								// 清除成功，将推送日志表中的数据修改为推送完成
								sysUserFailedLogService.finishById(sysUserFailedLog.getId());
								succ1 = true;
							}
						}
						if (!succ1) { // succ的值为false，说明此次手动推送失败
							respBool.set(false);
						}
						break;
				}
			});
			// respBool值为true 说明推送失败的操作现已全部重新推送
			if (respBool.get()) {
				if (CollectionUtil.isNotEmpty(deleteUserFailedLogList)) { // deleteUserFailedLogList不是空，说明有删除操作
					// 删除花名册数据
					rosterBaseCService.removeById(rosterBase.getId());
					// 删除用户
					this.removeById(userId);
					UserDTO userDTO = new UserDTO();
					userDTO.setId(userId);
					// 删除用户关联的管理部门信息
					this.deleteUserManageOffice(userDTO);  //  根据用户id删除用户的管理部门信息
					// 删除用户关联的岗位信息
					this.deleteUserPost(userId);
					// 删除用户关联的角色信息
					this.deleteUserRole(userId);
				}
			}
		}
		return respBool.get();
	}
}
