package com.diagbot.facade;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.diagbot.client.AuthServiceClient;
import com.diagbot.dto.*;
import com.diagbot.entity.BasHospitalInfo;
import com.diagbot.entity.ImageCaptchaParams;
import com.diagbot.entity.JWT;
import com.diagbot.entity.JwtStore;
import com.diagbot.entity.SysHospitalSet;
import com.diagbot.entity.SysUser;
import com.diagbot.entity.SysUserDept;
import com.diagbot.entity.SysUserHospital;
import com.diagbot.entity.SysUserRole;
import com.diagbot.entity.wrapper.SysMenuWrapper;
import com.diagbot.enums.ConstantEnum;
import com.diagbot.enums.IsDeleteEnum;
import com.diagbot.enums.StatusEnum;
import com.diagbot.exception.CommonErrorCode;
import com.diagbot.exception.CommonException;
import com.diagbot.exception.ServiceErrorCode;
import com.diagbot.service.impl.SysUserDeptServiceImpl;
import com.diagbot.service.impl.SysUserRoleServiceImpl;
import com.diagbot.service.impl.SysUserServiceImpl;
import com.diagbot.util.BeanUtil;
import com.diagbot.util.DateUtil;
import com.diagbot.util.EntityUtil;
import com.diagbot.util.ImageCaptchaUtil;
import com.diagbot.util.ListUtil;
import com.diagbot.util.RedisUtils;
import com.diagbot.util.StringUtil;
import com.diagbot.util.SysUserUtils;
import com.diagbot.vo.BasDeptInfoVO;
import com.diagbot.vo.SysUserBaseVO;
import com.diagbot.vo.SysUserDeptVO;
import com.diagbot.vo.SysUserQueryVO;
import com.diagbot.vo.SysUserRoleVO;
import com.diagbot.vo.UserLoginVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 用户业务层
 * @author: gaodm
 * @time: 2018/8/6 9:00
 */
@Component
public class SysUserFacade extends SysUserServiceImpl {

    @Autowired
    private TokenFacade tokenFacade;

    @Autowired
    private AuthServiceClient authServiceClient;

    @Autowired
    private SysMenuFacade sysMenuFacade;

    @Autowired
    private BasHospitalInfoFacade basHospitalInfoFacade;

    @Autowired
    @Qualifier("sysUserRoleServiceImpl")
    private SysUserRoleServiceImpl sysUserRoleService;

    @Autowired
    @Qualifier("sysUserDeptServiceImpl")
    private SysUserDeptServiceImpl sysUserDeptService;

    @Autowired
    private BasDeptInfoFacade basDeptInfoFacade;

    @Autowired
    private SysRoleFacade sysRoleFacade;

    @Autowired
    private SysUserHospitalFacade sysUserHospitalFacade;
    @Autowired
    private SysUserRoleFacade sysUserRoleFacade;
    @Autowired
    private SysDictionaryFacade sysDictionaryFacade;
    @Autowired
    private SysHospitalSetFacade sysHospitalSetFacade;
    @Autowired
    private RedisUtils redisUtils;


    /**
     * 获取标识--选择登录页面
     *
     * @return java.lang.Long
     */
    public Long getHospitalMark() {
        Long mark = 0L;//0-默认通用医院 1-湘雅医院特殊登录页面
        SysHospitalSet sysHospitalSet = sysHospitalSetFacade.lambdaQuery()
                .eq(SysHospitalSet::getHospitalId, 35)
                .eq(SysHospitalSet::getIsDeleted, IsDeleteEnum.N.getKey())
                .eq(SysHospitalSet::getCode, "special_page_csxy").one();
        if (null != sysHospitalSet) {
            String val = sysHospitalSet.getValue();
            if (StringUtil.isNotBlank(val) && "1".equals(val)) {
                mark = Long.valueOf(val);
            }
        }
        return mark;
    }

    public void getCaptcha(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("image/png");
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        HttpSession session = request.getSession();
        String captchaId = session.getId();
        ServletOutputStream outputStream = response.getOutputStream();
        ImageCaptchaUtil imageCaptchaUtil = new ImageCaptchaUtil();
        BufferedImage image = imageCaptchaUtil.createRandom();
        String captcha = imageCaptchaUtil.getText();
        redisUtils.set("user:captchaIds:" + captchaId, captcha, 60 * 3);
        ImageIO.write(image, ImageCaptchaParams.DEFAULT_FORMAT, outputStream);
        outputStream.flush();
        outputStream.close();
    }

    /**
     * 获取jwt
     * <p>
     * userLoginVO
     *
     * @return jwt
     */
    public JwtDTO getJwt(HttpServletRequest request, UserLoginVO userLoginVO) {
        JwtDTO data = new JwtDTO();
        if (StringUtil.isBlank(userLoginVO.getUsername())) {
            throw new CommonException(CommonErrorCode.PARAM_IS_NULL,
                    "请输入用户名");
        }
        if (StringUtil.isBlank(userLoginVO.getPassword())) {
            throw new CommonException(CommonErrorCode.PARAM_IS_NULL,
                    "请输入密码");
        }
        //非湘雅医院执行
        String captchaId = "";
        if (0L == getHospitalMark()) {
            if (StringUtils.isEmpty(userLoginVO.getCaptcha())) {
                throw new CommonException(CommonErrorCode.PARAM_IS_NULL,
                        "请输入验证码");
            }
            // 验证码校验
            captchaId = request.getSession().getId();
            Object captchaObject = redisUtils.get("user:captchaIds:" + captchaId);
            if (null == captchaObject || StringUtil.isBlank(captchaObject.toString()) || !captchaObject.toString().trim().equalsIgnoreCase(userLoginVO.getCaptcha())) {
                throw new CommonException(CommonErrorCode.PARAM_IS_ERROR, "验证码错误");
            }
        }

        //使用MD5对密码进行加密
        String MD5Password = DigestUtils.md5DigestAsHex(userLoginVO.getPassword().getBytes());
        QueryWrapper<SysUser> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("username", userLoginVO.getUsername())
                .eq("status", StatusEnum.Enable.getKey())
                .eq("is_deleted", IsDeleteEnum.N.getKey());
        SysUser user = this.getOne(userQueryWrapper, false);
        if (null == user) {
            throw new CommonException(ServiceErrorCode.USER_NOT_FOUND);
        }
        PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
        if (!passwordEncoder.matches(MD5Password, user.getPassword())) {
            throw new CommonException(ServiceErrorCode.USER_PASSWORD_ERROR);
        }
        JWT jwt = authServiceClient.getToken("Basic dWFhLXNlcnZpY2U6MTIzNDU2",
                "password", userLoginVO.getUsername(), MD5Password);
        if (null == jwt) {
            throw new CommonException(ServiceErrorCode.GET_TOKEN_FAIL);
        }
        if (0L == getHospitalMark()) {
            redisUtils.del("user:captchaIds:" + captchaId);
        }
        data.setAccessToken(jwt.getAccess_token());
        data.setRefreshToken(jwt.getRefresh_token());
        data.setType(user.getType());
        data.setTypeCn(ConstantEnum.getName(user.getType()));//返回中文
        //获取用户角色
        try {
            SysUserBaseVO sysUserBaseVO = new SysUserBaseVO();
            sysUserBaseVO.setUserId(user.getId());
            List<SysRoleDTO> selRoles = getlocalUserRoles(sysUserBaseVO);
            if (selRoles != null && !selRoles.isEmpty()) {
                data.setSelRoles(selRoles);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        //token存入redis
        JwtStore jwtStore = new JwtStore();
        jwtStore.setAccessToken(jwt.getAccess_token());
        jwtStore.setRefreshToken(jwt.getRefresh_token());
        tokenFacade.createToken(jwtStore);

        //每次登录在redis缓存该用户登录成功的token；缓存时间为token有效时间
        long accessTokenTime = sysDictionaryFacade.getAccessTokenOutTime();
        redisUtils.set("user:refreshToken:outTime_" + user.getId(), accessTokenTime, accessTokenTime);
        /***
         * 未经过MD5加密密码复杂度判断
         */
        //   获取用户医院id
        //     String hospitalID = SysUserUtils.getCurrentHospitalID();
        Long id = user.getId();
        QueryWrapper<SysUserHospital> UserHospitalQueryWrapper = new QueryWrapper<>();
        UserHospitalQueryWrapper
                .eq("user_id", id)
                .eq("is_deleted", IsDeleteEnum.N.getKey());
        SysUserHospital userHospital = sysUserHospitalFacade.getOne(UserHospitalQueryWrapper, false);
        Long hospitalId = userHospital.getHospitalId();
        String idStr = String.valueOf(hospitalId);
        Boolean passwordRegular = passwordRegular(userLoginVO.getPassword(), idStr);
        if (!passwordRegular) {
            data.setPasswordComplexity("未修改初始密码，请及时修改密码");
        }
        return data;
    }

    /**
     * 外部获取jwt
     *
     * @param username 用户名
     * @return jwt
     */
    public JwtDTO getJwtNoPass(String username) {
        JwtDTO data = new JwtDTO();
        if (StringUtil.isBlank(username)) {
            throw new CommonException(CommonErrorCode.PARAM_IS_NULL,
                    "请输入用户名");
        }
        QueryWrapper<SysUser> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("username", username)
                .eq("status", StatusEnum.Enable.getKey())
                .eq("is_deleted", IsDeleteEnum.N.getKey());
        SysUser user = this.getOne(userQueryWrapper, false);
        if (null == user) {
            throw new CommonException(ServiceErrorCode.USER_NOT_FOUND);
        }
        JwtStore jwt = tokenFacade.getToken(user.getId().toString());
        if (null == jwt) {
            throw new CommonException(CommonErrorCode.NOT_EXISTS, "Token不存在，请重新登录");
        }
        data.setAccessToken(jwt.getAccessToken());
        data.setRefreshToken(jwt.getRefreshToken());
        data.setType(user.getType());
        data.setTypeCn(ConstantEnum.getName(user.getType()));//返回中文
        return data;
    }

    /**
     * 刷新jwt
     *
     * @param refreshToken
     * @return jwt
     */
    public JwtDTO refreshJwt(String refreshToken) {
        JwtDTO data = new JwtDTO();
        if (StringUtil.isBlank(refreshToken)) {
            throw new CommonException(CommonErrorCode.PARAM_IS_NULL,
                    "刷新令牌不能为空");
        }

        //验证刷新令牌有效性
        if (!tokenFacade.verifyToken(refreshToken, 2)) {
            throw new CommonException(CommonErrorCode.TOKEN_PAST);
        }

        JWT jwt = authServiceClient.refreshToken("Basic dWFhLXNlcnZpY2U6MTIzNDU2",
                "refresh_token", refreshToken);
        if (null == jwt) {
            throw new CommonException(ServiceErrorCode.GET_TOKEN_FAIL);
        }
        data.setAccessToken(jwt.getAccess_token());
        data.setRefreshToken(jwt.getRefresh_token());
        //token存入redis
        JwtStore jwtStore = new JwtStore();
        jwtStore.setAccessToken(jwt.getAccess_token());
        jwtStore.setRefreshToken(jwt.getRefresh_token());
        tokenFacade.createToken(jwtStore);
        return data;
    }


    /**
     * 验证jwt
     *
     * @param token
     * @return jwt
     */
    public OAuth2AccessToken checkToken(String token) {
        if (StringUtil.isBlank(token)) {
            throw new CommonException(CommonErrorCode.PARAM_IS_NULL,
                    "令牌不能为空");
        }

        OAuth2AccessToken jwt
                = authServiceClient.checkToken("Basic dWFhLXNlcnZpY2U6MTIzNDU2", token);
        if (null == jwt) {
            throw new CommonException(ServiceErrorCode.GET_TOKEN_FAIL, "该Token不正确！");
        }
        return jwt;
    }

    /**
     * 修改密码
     *
     * @param password       原密码
     * @param modifyPassword 新密码
     * @return 修改密码是否成功
     */
    public Boolean modifyPassword(String password, String modifyPassword) {
        //使用MD5对原密码和新密码进行加密
        String MD5Password = DigestUtils.md5DigestAsHex(password.getBytes());
        String MD5ModifyPassword = DigestUtils.md5DigestAsHex(modifyPassword.getBytes());
        if (StringUtil.isBlank(password)) {
            throw new CommonException(CommonErrorCode.PARAM_IS_NULL,
                    "请输入原密码");
        }
        if (StringUtil.isBlank(modifyPassword)) {
            throw new CommonException(CommonErrorCode.PARAM_IS_NULL,
                    "请输入新密码");
        }
        //对传入的密码进行格式验证
        String hospitalID = SysUserUtils.getCurrentHospitalID();
        Boolean regularBoolean = passwordRegular(modifyPassword, hospitalID);
        if (!regularBoolean) {
            throw new CommonException(CommonErrorCode.PARAM_IS_ERROR, "请输入正确格式的新密码");
        }
        String userId = SysUserUtils.getCurrentPrincipleID();
        SysUser user = this.getOne(new QueryWrapper<SysUser>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("status", StatusEnum.Enable.getKey())
                .eq("id", userId), false);
        if (null == user) {
            throw new CommonException(ServiceErrorCode.USER_NOT_FOUND);
        }
        PasswordEncoder passwordEncoder
                = PasswordEncoderFactories.createDelegatingPasswordEncoder();
        if (!passwordEncoder.matches(MD5Password, user.getPassword())) {
            throw new CommonException(CommonErrorCode.PARAM_IS_ERROR, "原密码错误");
        }
        if (password.equals(modifyPassword)) {
            throw new CommonException(CommonErrorCode.PARAM_IS_ERROR,
                    "原密码和新密码不能相同");
        }
        String entryPassword = passwordEncoder.encode(MD5ModifyPassword);
        user.setPassword(entryPassword);
        user.setGmtModified(DateUtil.now());
        user.setModifier(userId);
        this.updateById(user);
        return true;
    }

    /**
     * 未加密密文正则表达式  至少8个字符，1个大写字母，1个小写字母，1个数字和1个特殊字符：
     *
     * @param password
     * @return
     */
    public Boolean passwordRegular(String password, String hospitalId) {
        boolean check = true;
        Map<String, Map<String, String>> dictionaryWithKey = sysDictionaryFacade.getDictionaryWithKey();
        if (dictionaryWithKey != null) {
            Map<String, String> stringStringMap = dictionaryWithKey.get("30");
            if (stringStringMap != null) {
                String regular = stringStringMap.get(hospitalId);
                if (StringUtil.isNotEmpty(regular)) {
                    check = password.matches(regular);
                }
            }
        }
        return check;
    }

    /**
     * 登录
     *
     * @return 登录相关信息
     */
    public LoginDTO getUserOrgMenu() {
        LoginDTO data = new LoginDTO();
        Set<String> roleSet = new HashSet<>();
        Long userId = Long.parseLong(SysUserUtils.getCurrentPrincipleID());
        SysUser user = this.getOne(new QueryWrapper<SysUser>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("status", StatusEnum.Enable.getKey())
                .eq("id", userId), false);
        QueryWrapper<SysUserRole> sysUserRoleQueryWrapper = new QueryWrapper<>();
        sysUserRoleQueryWrapper.eq("user_id", userId);
        sysUserRoleQueryWrapper.eq("is_deleted", IsDeleteEnum.N.getKey());
        List<SysUserRole> sysUserRoleList = sysUserRoleFacade.list(sysUserRoleQueryWrapper);
        if (ListUtil.isNotEmpty(sysUserRoleList)) {
            sysUserRoleList.forEach(sysUserRole -> {
                roleSet.add(sysUserRole.getRoleId() + "");
            });
        }
        if (user == null) {
            throw new CommonException(CommonErrorCode.SERVER_IS_ERROR,
                    "用户不存在【" + userId + "】");
        }
        //添加用户
        UserLoginDTO userLoginDTO = new UserLoginDTO();
        BeanUtil.copyProperties(user, userLoginDTO);
        data.setUserLoginDTO(userLoginDTO);

        //添加医院信息
        if (user.getType().equals(ConstantEnum.OUTER_USER.getKey())) {
            QueryWrapper<BasHospitalInfo> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("is_deleted", IsDeleteEnum.N.getKey())
                    .eq("id", SysUserUtils.getCurrentHospitalID());
            BasHospitalInfo basHospitalInfo = basHospitalInfoFacade.getOne(queryWrapper, false);
            BasHospitalInfoDTO basHospitalInfoDTO = new BasHospitalInfoDTO();
            BeanUtil.copyProperties(basHospitalInfo, basHospitalInfoDTO);
            data.setBasHospitalInfoDTO(basHospitalInfoDTO);
        }

        //添加菜单信息
        List<SysMenuWrapper> menuList = sysMenuFacade.getByRole(user.getId(), roleSet);
        List<SysUserPermissionDTO> sysUserPermissionDTOList = sysMenuFacade.getByRolePermission(user.getId(), roleSet);
        Map<Long, List<SysMenuWrapper>> menuMap = EntityUtil.makeEntityListMap(menuList, "parentId");
        Map<Long, List<SysUserPermissionDTO>> menuPermissionMap = EntityUtil.makeEntityListMap(sysUserPermissionDTOList, "menuId");
        List<SysMenuWrapper> menuRes = menuMap.get(-1L);
        for (SysMenuWrapper bean : menuRes) {
            getSonMenu(bean, menuMap, menuPermissionMap);
        }
        data.setMenuWrappers(menuRes);
        return data;
    }


    /**
     * 递归获取菜单结构
     *
     * @param menu    当前菜单
     * @param menuMap 菜单集
     * @return 菜单结构
     */
    public List<SysMenuWrapper> getSonMenu(SysMenuWrapper menu,
                                           Map<Long, List<SysMenuWrapper>> menuMap,
                                           Map<Long, List<SysUserPermissionDTO>> menuPermissionMap) {
        List<SysMenuWrapper> res = new ArrayList<>();
        List<SysMenuWrapper> list = menuMap.get(menu.getId());
        List<SysUserPermissionDTO> listPermission = menuPermissionMap.get(menu.getId());
        if (ListUtil.isNotEmpty(listPermission)) {
            menu.setSysUserPermissionDTOList(listPermission);
        }
        if (ListUtil.isNotEmpty(list)) {
            menu.setSubMenuList(list);
            for (SysMenuWrapper bean : list) {
                getSonMenu(bean, menuMap, menuPermissionMap);
            }
        }
        return res;
    }

    /**
     * 递归获取菜单结构
     *
     * @param menuList 菜单参数
     */
    public void getMenuStruct(List<SysMenuWrapper> menuList) {
        for (SysMenuWrapper m : menuList) {
            m.setSubMenuList(recursion(m));
        }
    }


    /**
     * 递归查询菜单信息
     *
     * @param m 参数
     * @return 菜单信息
     */
    public List<SysMenuWrapper> recursion(SysMenuWrapper m) {
        List<SysMenuWrapper> subMenu = sysMenuFacade.getSubMenuById(m.getId());
        for (SysMenuWrapper sub : subMenu) {
            sub.setSubMenuList(recursion(sub));
        }
        return subMenu;
    }

    //-------------用户维护BEGAIN------------------------

    /**
     * 用户列表翻页信息查询
     *
     * @param sysUserQueryVO 用户列表翻页信息入参
     * @return 用户列表翻页信息
     */
    public IPage<SysUserQueryDTO> userPageFac(SysUserQueryVO sysUserQueryVO) {
        sysUserQueryVO.setHospitalId(Long.valueOf(SysUserUtils.getCurrentHospitalID()));
        return this.userPage(sysUserQueryVO);
    }

    /**
     * 获取用户科室
     *
     * @param sysUserBaseVO 获取用户科室入参
     * @return 用户科室信息
     */
    public SysUserDeptDTO getUserDepts(SysUserBaseVO sysUserBaseVO) {
        checkUser(sysUserBaseVO.getUserId());
        SysUserDeptDTO sysUserDeptDTO = new SysUserDeptDTO();
        sysUserDeptDTO.setUserId(sysUserBaseVO.getUserId());
        BasDeptInfoVO basDeptInfoVO = new BasDeptInfoVO();
        List<BasDeptInfoDTO> basDeptInfoDTOList = basDeptInfoFacade.listForUser(basDeptInfoVO);
        List<SysUserDept> sysUserDeptList
                = sysUserDeptService.list(new QueryWrapper<SysUserDept>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("user_id", sysUserBaseVO.getUserId())
        );

        if (ListUtil.isNotEmpty(sysUserDeptList)) {
            List<BasDeptInfoDTO> notSelDepts = new ArrayList<>();
            List<BasDeptInfoDTO> selDepts = new ArrayList<>();
            Set<String> selDeptIds = sysUserDeptList.stream()
                    .map(SysUserDept::getDeptId)
                    .collect(Collectors.toSet());
            for (BasDeptInfoDTO basDeptInfoDTO : basDeptInfoDTOList) {
                if (selDeptIds.contains(basDeptInfoDTO.getDeptId())) {
                    selDepts.add(basDeptInfoDTO);
                } else {
                    notSelDepts.add(basDeptInfoDTO);
                }
            }
            sysUserDeptDTO.setNotSelDepts(notSelDepts);
            sysUserDeptDTO.setSelDepts(selDepts);

        } else {
            sysUserDeptDTO.setNotSelDepts(basDeptInfoDTOList);
        }

        return sysUserDeptDTO;
    }

    /**
     * 获取用户角色
     *
     * @param sysUserBaseVO 获取用户角色入参
     * @return 用户角色信息
     */
    public SysUserRoleDTO getUserRoles(SysUserBaseVO sysUserBaseVO) {
        checkUser(sysUserBaseVO.getUserId());
        SysUserRoleDTO sysUserRoleDTO = new SysUserRoleDTO();
        sysUserRoleDTO.setUserId(sysUserBaseVO.getUserId());
        List<SysRoleDTO> sysRoleDTOList = sysRoleFacade.listFac();
        List<SysUserRole> sysUserRoleList
                = sysUserRoleService.list(new QueryWrapper<SysUserRole>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("user_id", sysUserBaseVO.getUserId())
        );

        if (ListUtil.isNotEmpty(sysUserRoleList)) {
            List<SysRoleDTO> notSelRoles = new ArrayList<>();
            List<SysRoleDTO> selRoles = new ArrayList<>();
            Set<Long> selRoleIds = sysUserRoleList.stream()
                    .map(SysUserRole::getRoleId)
                    .collect(Collectors.toSet());
            for (SysRoleDTO sysRoleDTO : sysRoleDTOList) {
                if (selRoleIds.contains(sysRoleDTO.getId())) {
                    selRoles.add(sysRoleDTO);
                } else {
                    notSelRoles.add(sysRoleDTO);
                }
            }
            sysUserRoleDTO.setNotSelRoles(notSelRoles);
            sysUserRoleDTO.setSelRoles(selRoles);

        } else {
            sysUserRoleDTO.setNotSelRoles(sysRoleDTOList);
        }

        return sysUserRoleDTO;
    }

    /**
     * 获取用户角色
     *
     * @param sysUserBaseVO 获取用户角色入参
     * @return 用户角色信息
     */
    private List<SysRoleDTO> getlocalUserRoles(SysUserBaseVO sysUserBaseVO) {
        SysUserRoleDTO sysUserRoleDTO = new SysUserRoleDTO();
        sysUserRoleDTO.setUserId(sysUserBaseVO.getUserId());
        List<SysRoleDTO> sysRoleDTOList = sysRoleFacade.listFac();
        List<SysUserRole> sysUserRoleList
                = sysUserRoleService.list(new QueryWrapper<SysUserRole>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("user_id", sysUserBaseVO.getUserId())
        );
        List<SysRoleDTO> selRoles = new ArrayList<>();
        if (ListUtil.isNotEmpty(sysUserRoleList)) {
            Set<Long> selRoleIds = sysUserRoleList.stream()
                    .map(SysUserRole::getRoleId)
                    .collect(Collectors.toSet());
            for (SysRoleDTO sysRoleDTO : sysRoleDTOList) {
                if (selRoleIds.contains(sysRoleDTO.getId())) {
                    selRoles.add(sysRoleDTO);
                }
            }
            sysUserRoleDTO.setSelRoles(selRoles);
        }

        return selRoles;
    }

    /**
     * 用户启用
     *
     * @param sysUserBaseVO 用户启用入参
     * @return 是否成功
     */
    public Boolean enable(SysUserBaseVO sysUserBaseVO) {
        checkUser(sysUserBaseVO.getUserId());
        Date now = DateUtil.now();
        String userId = SysUserUtils.getCurrentPrincipleID();
        return this.update(new UpdateWrapper<SysUser>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("id", sysUserBaseVO.getUserId())
                .eq("status", StatusEnum.Disable.getKey())
                .set("modifier", userId)
                .set("gmt_modified", now)
                .set("status", StatusEnum.Enable.getKey())
        );
    }

    /**
     * 用户停用
     *
     * @param sysUserBaseVO 用户停用入参
     * @return 是否成功
     */
    public Boolean disable(SysUserBaseVO sysUserBaseVO) {
        checkUser(sysUserBaseVO.getUserId());
        Date now = DateUtil.now();
        String userId = SysUserUtils.getCurrentPrincipleID();
        Boolean res = this.update(new UpdateWrapper<SysUser>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("id", sysUserBaseVO.getUserId())
                .eq("status", StatusEnum.Enable.getKey())
                .set("modifier", userId)
                .set("gmt_modified", now)
                .set("status", StatusEnum.Disable.getKey())
        );
        //删除Token
        if (res) {
            tokenFacade.deleteToken(sysUserBaseVO.getUserId().toString());
        }

        return res;
    }

    /**
     * 编辑用户科室
     *
     * @param sysUserDeptVO 编辑用户科室入参
     * @return 是否成功
     */
    public Boolean editUserDepts(SysUserDeptVO sysUserDeptVO) {
        checkUser(sysUserDeptVO.getUserId());
        Date now = DateUtil.now();
        String userId = SysUserUtils.getCurrentPrincipleID();
        //删除原科室
        sysUserDeptService.update(new UpdateWrapper<SysUserDept>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("user_id", sysUserDeptVO.getUserId())
                .set("is_deleted", IsDeleteEnum.Y.getKey())
                .set("modifier", userId)
                .set("gmt_modified", now)
        );
        //新增新科室
        if (ListUtil.isNotEmpty(sysUserDeptVO.getDeptIds())) {
            List<SysUserDept> sysUserDeptList = new ArrayList<>();
            for (String deptId : sysUserDeptVO.getDeptIds()) {
                SysUserDept sysUserDept = new SysUserDept();
                sysUserDept.setUserId(sysUserDeptVO.getUserId());
                sysUserDept.setHospitalId(Long.valueOf(SysUserUtils.getCurrentHospitalID()));
                sysUserDept.setDeptId(deptId);
                sysUserDept.setCreator(userId);
                sysUserDept.setModifier(userId);
                sysUserDept.setGmtCreate(now);
                sysUserDept.setGmtModified(now);
                sysUserDeptList.add(sysUserDept);
            }
            sysUserDeptService.saveBatch(sysUserDeptList);
        }
        //删除Token
        tokenFacade.deleteToken(sysUserDeptVO.getUserId().toString());
        //更新用户表
        return this.update(new UpdateWrapper<SysUser>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("id", sysUserDeptVO.getUserId())
                .set("modifier", userId)
                .set("gmt_modified", now)
        );
    }

    /**
     * 编辑用户角色
     *
     * @param sysUserRoleVO 编辑用户角色入参
     * @return 是否成功
     */
    public Boolean editUserRoles(SysUserRoleVO sysUserRoleVO) {
        checkUser(sysUserRoleVO.getUserId());
        Date now = DateUtil.now();
        String userId = SysUserUtils.getCurrentPrincipleID();
        //删除原角色
        sysUserRoleService.update(new UpdateWrapper<SysUserRole>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("user_id", sysUserRoleVO.getUserId())
                .set("is_deleted", IsDeleteEnum.Y.getKey())
                .set("modifier", userId)
                .set("gmt_modified", now)
        );
        //新增角色
        if (ListUtil.isNotEmpty(sysUserRoleVO.getRoleIds())) {
            List<SysUserRole> sysUserRoleList = new ArrayList<>();
            for (Long roleId : sysUserRoleVO.getRoleIds()) {
                SysUserRole sysUserRole = new SysUserRole();
                sysUserRole.setUserId(sysUserRoleVO.getUserId());
                sysUserRole.setRoleId(roleId);
                sysUserRole.setCreator(userId);
                sysUserRole.setModifier(userId);
                sysUserRole.setGmtCreate(now);
                sysUserRole.setGmtModified(now);
                sysUserRoleList.add(sysUserRole);
            }
            sysUserRoleService.saveBatch(sysUserRoleList);
        }
        //更新用户表
        this.update(new UpdateWrapper<SysUser>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("id", sysUserRoleVO.getUserId())
                .set("modifier", userId)
                .set("gmt_modified", now)
        );
        //删除Token
        tokenFacade.deleteToken(sysUserRoleVO.getUserId().toString());
        return true;
    }

    /**
     * 确认用户是否是管理员下的用户
     *
     * @param userId 用户Id
     */
    private void checkUser(Long userId) {
        //确认用户是否是管理员统一医院下的用户
        Integer cnt = sysUserHospitalFacade.count(new QueryWrapper<SysUserHospital>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("user_id", userId)
                .eq("hospital_id", SysUserUtils.getCurrentHospitalID())
        );
        if (cnt < 1) {
            throw new CommonException(CommonErrorCode.PARAM_IS_ERROR, "该医院下无该用户");
        }
    }

    public Long getUserId(String claimantId, Long hospitalId) {
        SysUser user = this.getBaseMapper().getUser(claimantId, hospitalId);
        if (user != null && user.getId() != null) {
            return user.getId();
        }
        return null;
    }
    //-------------用户维护END---------------------------

}
