package com.jiayue.ssi.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.crypto.SmUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jiayue.ssi.annotation.AgainVerify;
import com.jiayue.ssi.annotation.OperateLog;
import com.jiayue.ssi.annotation.PreventReplay;
import com.jiayue.ssi.backenum.ApproveOperaterEnum;
import com.jiayue.ssi.backenum.ApproveStatusEnum;
import com.jiayue.ssi.backenum.AuditType;
import com.jiayue.ssi.backenum.BusinessType;
import com.jiayue.ssi.config.SendMailUtil;
import com.jiayue.ssi.constant.ApproveConstants;
import com.jiayue.ssi.constant.CacheConstants;
import com.jiayue.ssi.constant.CustomException;
import com.jiayue.ssi.constant.SecretKeyConstants;
import com.jiayue.ssi.dto.ActiveUserDto;
import com.jiayue.ssi.entity.*;
import com.jiayue.ssi.service.*;
import com.jiayue.ssi.service.impl.SysPermissionService;
import com.jiayue.ssi.util.*;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户信息接口
 *
 * @author xsl
 * @since 2023/03/13
 */
@RestController
@RequestMapping("/sysUserController")
@Slf4j
public class SysUserController {
    @Autowired
    SysUserService sysUserService;
    @Autowired
    SendMailUtil sendMailUtil;
    @Autowired
    SysPermissionService sysPermissionService;
    @Autowired
    SysUserRoleService sysUserRoleService;
    @Autowired
    SysApproveService sysApproveService;
    @Autowired
    SysRoleService sysRoleService;
    @Autowired
    SysPolicyService sysPolicyService;
    @Autowired
    JwtTokenUtil jwtTokenUtil;

    /**
     * 获取用户分页信息
     *
     * @return 用户信息
     */
    @GetMapping(value = "/getAll")
    @PreAuthorize("@ss.hasPermi('system:user:list')")
    @OperateLog(title = "用户管理", businessType = BusinessType.QUERY, auditType = AuditType.SYS,operdesc = "用户查询")
    @PreventReplay
    public ResponseVO getAll(String username, String phonenumber,
                             String status) throws CustomException {
        try {
            if (StringUtils.isNotEmpty(username)) {
                if (username.length() > 20) {
                    return ResponseVO.fail("用户账号长度不能超过20个字符！");
                }
            }
            if (StringUtils.isNotEmpty(phonenumber)) {
                if (phonenumber.length() > 11) {
                    return ResponseVO.fail("手机号码长度不能超过11个字符！");
                }
            }

            // 查询全部
            List<SysUser> sysUserList = sysUserService.queryAllUserByDecrypt();

            // 根据查询条件过滤结果
            if (StringUtils.isNotEmpty(username)) {
                sysUserList =  sysUserList.stream().filter(user -> username.equals(user.getUsername())).collect(Collectors.toList());
            }
            if (StringUtils.isNotEmpty(phonenumber)) {
                sysUserList =  sysUserList.stream().filter(user -> phonenumber.equals(user.getPhonenumber())).collect(Collectors.toList());
            }
            if (StringUtils.isNotEmpty(status)) {
                sysUserList =  sysUserList.stream().filter(user -> status.equals(user.getStatus())).collect(Collectors.toList());
            }

            SysRole sysRole = sysRoleService.selectRoleListByUserId();
            if ("YWGL".equals(sysRole.getRoleKey())){
                // 业务管理员员
                sysUserList =  sysUserList.stream().filter(user -> "1".equals(user.getUsertype())).collect(Collectors.toList());
            }

            return ResponseVO.success(sysUserList);
        } catch (Exception e) {
            throw new CustomException("获取所有用户异常", e);
        }
    }

    /**
     * 获取当前用户信息
     *
     * @return 用户信息
     */
    @GetMapping(value = "/getCurrentUser")
    public ResponseVO getCurrentUser() throws CustomException {
        try {
            SysUser sysUser = SecurityContextUtil.getSysUser();
            // 权限集合
            Set<String> permissions = sysPermissionService.getMenuPermission(sysUser.getId());
            Map<String, Object> map = new HashMap<>();
            sysUser.setMailbox(SM2CryptUtils.decrypt(sysUser.getMailbox(), SecretKeyConstants.SERVER_PRIVATE_KEY));
            sysUser.setPhonenumber(SM2CryptUtils.decrypt(sysUser.getPhonenumber(), SecretKeyConstants.SERVER_PRIVATE_KEY));
            sysUser.setNickname(SM2CryptUtils.decrypt(sysUser.getNickname(), SecretKeyConstants.SERVER_PRIVATE_KEY));
            sysUser.setIdcard(SM2CryptUtils.decrypt(sysUser.getIdcard(), SecretKeyConstants.SERVER_PRIVATE_KEY));
            map.put("sysUser", sysUser);
            map.put("permissions", permissions);
            return ResponseVO.success(map);
        } catch (Exception e) {
            throw new CustomException("获取当前用户异常", e);
        }
    }

    /**
     * 新增用户
     */
    @PostMapping(value = "/addUser")
    @AgainVerify
    @OperateLog(title = "用户管理", businessType = BusinessType.INSERT, auditType = AuditType.SYS,operdesc = "新增用户")
    @PreAuthorize("@ss.hasPermi('system:user:add')")
    @PreventReplay
    public ResponseVO addUser(@RequestBody SysUser user) throws CustomException {

        try {
            String username="";
            SysApprove sysApprove = new SysApprove();
            if (StringUtils.isEmpty(user.getUsername()) || StringUtils.isEmpty(user.getUsername().trim())) {
                return ResponseVO.fail("用户账号不能为空!");
            }
            else {
                username = user.getUsername();
                if (username.contains(" ")){
                    return ResponseVO.fail("账号中不能含有空格！");
                }

                String regExp = "^[^0-9][\\w_]{4,19}$";
                if (!username.matches(regExp)) {
                    return ResponseVO.fail("用户账号长度必须是5-20位，只能包含字母、数字和下划线，不能数字开头！");
                }
                sysApprove.setUsername(username);
            }

            if (!IdcardUtil.isValidCard(user.getIdcard())) {
                return ResponseVO.fail("身份证无效！");
            }
            // sm2加密身份证
            sysApprove.setIdcard(SM2CryptUtils.encrypt(user.getIdcard(), SecretKeyConstants.SERVER_PUBLIC_KEY));

            if (StringUtils.isEmpty(user.getPhonenumber())) {
                return ResponseVO.fail("手机号码不能为空！");
            } else if (!Validator.isMobile(user.getPhonenumber())) {
                return ResponseVO.fail("请输入正确的手机号码！");
            }
            // 加密手机号
            sysApprove.setPhonenumber(SM2CryptUtils.encrypt(user.getPhonenumber(), SecretKeyConstants.SERVER_PUBLIC_KEY));

            if (StringUtils.isEmpty(user.getNickname()) || StringUtils.isEmpty(user.getNickname().trim())) {
                return ResponseVO.fail("姓名不能为空！");
            } else {
                String nickName = user.getNickname().trim();
                if (nickName.length() > 30) {
                    return ResponseVO.fail("姓名长度不能超过30个字符！");
                }
                // 加密姓名
                sysApprove.setNickname(SM2CryptUtils.encrypt(nickName, SecretKeyConstants.SERVER_PUBLIC_KEY));
            }

            if (StringUtils.isEmpty(user.getMailbox())) {
                return ResponseVO.fail("邮箱不能为空!");
            } else if (!Validator.isEmail(user.getMailbox())) {
                return ResponseVO.fail("请输入正确的邮箱地址！");
            } else if (user.getMailbox().length() > 50) {
                return ResponseVO.fail("邮箱长度不能超过50个字符！");
            }
            // 加密邮箱
            sysApprove.setMailbox(SM2CryptUtils.encrypt(user.getMailbox(), SecretKeyConstants.SERVER_PUBLIC_KEY));

            if (user.getExpDate()!=null){
                // 判断临时账号有效期不能超过30天
                Calendar calendar = Calendar.getInstance();
                // 将当前日期增加30天
                calendar.add(Calendar.DAY_OF_MONTH, 29);
                // 获取增加30天后的日期
                Date endDate = calendar.getTime();
                if (!user.getExpDate().before(endDate)){
                    return ResponseVO.fail("账号有效期不能超过30天！");
                }
                sysApprove.setExpDate(user.getExpDate());
            }

            // 新增时先判断审批表里待审批-新增中是否存在相同账号、身份证
            QueryWrapper<SysApprove> wrapper = new QueryWrapper<>();
            // 新增操作类型
            wrapper.eq("operation", "0");
            // 待审批
            wrapper.eq("approve_status", "0");
            List<SysApprove> sysApproveList = sysApproveService.list(wrapper);
            for (SysApprove sysApprove1:sysApproveList){
                String approveUsername = sysApprove1.getUsername();
                String approveIdcard = SM2CryptUtils.decrypt(sysApprove1.getIdcard(), SecretKeyConstants.SERVER_PRIVATE_KEY);
                String approvePhonenumber = SM2CryptUtils.decrypt(sysApprove1.getPhonenumber(), SecretKeyConstants.SERVER_PRIVATE_KEY);
                String approveMailbox = SM2CryptUtils.decrypt(sysApprove1.getMailbox(), SecretKeyConstants.SERVER_PRIVATE_KEY);
                if (username.equals(approveUsername)){
                    return ResponseVO.fail("账号"+username + "在待审批，不能再次新增！");
                }
                if (user.getIdcard().equals(approveIdcard)){
                    return ResponseVO.fail("身份证"+user.getIdcard() + "在待审批中，不能再次新增！");
                }
                if (user.getPhonenumber().equals(approvePhonenumber)){
                    return ResponseVO.fail("手机号码"+user.getPhonenumber() + "在待审批中，不能再次新增！");
                }
                if (user.getMailbox().equals(approveMailbox)){
                    return ResponseVO.fail("用户邮箱"+user.getMailbox() + "在待审批中，不能再次新增！");
                }
            }

            List<SysUser> sysUserList = sysUserService.queryAllUserByDecrypt();
            for (SysUser sysUser:sysUserList){
                if (username.equals(sysUser.getUsername())){
                    return ResponseVO.fail("账号"+username + "存在，不能再次新增！");
                }
                if (user.getIdcard().equals(sysUser.getIdcard())){
                    return ResponseVO.fail("身份证"+user.getIdcard() + "存在，不能再次新增！");
                }
                if (user.getPhonenumber().equals(sysUser.getPhonenumber())){
                    return ResponseVO.fail("手机号码"+user.getPhonenumber() + "存在，不能再次新增！");
                }
                if (user.getMailbox().equals(sysUser.getMailbox())){
                    return ResponseVO.fail("用户邮箱"+user.getMailbox() + "存在，不能再次新增！");
                }
            }

            sysApprove.setUsertype(user.getUsertype());
            sysApprove.setStatus("0");

            // 用户新增插入审批表
            sysApprove.setModuleName(ApproveConstants.MODULE_NAME_USER);
            sysApprove.setOperation(String.valueOf(ApproveOperaterEnum.INSERT.getCode()));
            sysApprove.setApproveStatus(String.valueOf(ApproveStatusEnum.DSP.getCode()));
            sysApprove.setEntityName("SysUser");

            boolean bo = sysApproveService.save(sysApprove);
            if (bo) {
                return ResponseVO.success("添加用户信息成功,请联系审核管理员进行审核！");
            } else {
                log.error("添加用户信息失败");
                return ResponseVO.fail("添加用户信息失败");
            }
        } catch (Exception e) {
            throw new CustomException("添加用户信息异常", e);
        }
    }

    /**
     * 更新用户
     *
     * @param user 参数
     * @return 执行结果
     */
    @PostMapping(value = "/updateUser")
    @AgainVerify
    @OperateLog(title = "用户管理", businessType = BusinessType.UPDATE, auditType = AuditType.SYS,operdesc = "修改用户")
    @PreAuthorize("@ss.hasPermi('system:user:edit')")
    @PreventReplay
    public ResponseVO updateUser(@RequestBody SysUser user) throws CustomException {
        try {
            SysUser existUser = sysUserService.getById(user.getId());
            if (existUser == null) {
                return ResponseVO.fail("id为空不能修改!");
            }

            // 获取审批表是否存在此操作
            QueryWrapper<SysApprove> wrapper = new QueryWrapper<>();
            // 条件：待审批
            wrapper.eq("approve_status", ApproveStatusEnum.DSP.getCode());
            // 条件：删除操作
            wrapper.eq("master_id", user.getId());
            // 条件：实体名
            wrapper.eq("entity_name", "SysUser");
            List<SysApprove> list = sysApproveService.list(wrapper);
            if (list.size() > 0) {
                return ResponseVO.fail("此记录存在未审批的操作,不能进行修改！");
            }
            String username = "";
            SysApprove sysApprove = new SysApprove();
            if (StringUtils.isEmpty(user.getUsername()) || StringUtils.isEmpty(user.getUsername().trim())) {
                return ResponseVO.fail("用户账号不能为空!");
            } else{
                username = user.getUsername().trim();
                if (username.contains(" ")){
                    return ResponseVO.fail("账号中不能含有空格！");
                }
                String regExp = "^[^0-9][\\w_]{4,19}$";
                if (!username.matches(regExp)){
                    return ResponseVO.fail("用户账号长度必须是5-20位，只能包含字母、数字和下划线，不能数字开头！");
                }
                sysApprove.setUsername(username);
            }

            if (!IdcardUtil.isValidCard(user.getIdcard())) {
                return ResponseVO.fail("身份证无效！");
            }
            // sm2加密身份证
            sysApprove.setIdcard(SM2CryptUtils.encrypt(user.getIdcard(), SecretKeyConstants.SERVER_PUBLIC_KEY));

            if (StringUtils.isEmpty(user.getMailbox())) {
                return ResponseVO.fail("邮箱不能为空!");
            } else if (!Validator.isEmail(user.getMailbox())) {
                return ResponseVO.fail("请输入正确的邮箱地址！");
            } else if (user.getMailbox().length() > 50) {
                return ResponseVO.fail("邮箱长度不能超过50个字符！");
            }
            // 加密邮箱
            sysApprove.setMailbox(SM2CryptUtils.encrypt(user.getMailbox(), SecretKeyConstants.SERVER_PUBLIC_KEY));

            if (StringUtils.isEmpty(user.getPhonenumber())) {
                return ResponseVO.fail("手机号码不能为空！");
            } else if (!Validator.isMobile(user.getPhonenumber())) {
                return ResponseVO.fail("请输入正确的手机号码！");
            }
            // 加密手机号
            sysApprove.setPhonenumber(SM2CryptUtils.encrypt(user.getPhonenumber(), SecretKeyConstants.SERVER_PUBLIC_KEY));

            if (StringUtils.isEmpty(user.getNickname()) || StringUtils.isEmpty(user.getNickname().trim())) {
                return ResponseVO.fail("姓名不能为空！");
            } else {
                String nickName = user.getNickname().trim();
                if (nickName.length() > 30) {
                    return ResponseVO.fail("姓名长度不能超过30个字符！");
                }
                // 加密姓名
                sysApprove.setNickname(SM2CryptUtils.encrypt(nickName, SecretKeyConstants.SERVER_PUBLIC_KEY));
            }
            // 新增时先判断审批表里待审批
            QueryWrapper<SysApprove> wrapper1 = new QueryWrapper<>();
            // 新增操作类型
            wrapper1.eq("operation", "0");
            // 待审批
            wrapper1.eq("approve_status", "0");
            List<SysApprove> sysApproveList1 = sysApproveService.list(wrapper1);
            for (SysApprove sysApprove1:sysApproveList1){
                String approvePhonenumber = SM2CryptUtils.decrypt(sysApprove1.getPhonenumber(), SecretKeyConstants.SERVER_PRIVATE_KEY);
                String approveMailbox = SM2CryptUtils.decrypt(sysApprove1.getMailbox(), SecretKeyConstants.SERVER_PRIVATE_KEY);

                if (user.getPhonenumber().equals(approvePhonenumber)){
                    return ResponseVO.fail("手机号码"+user.getPhonenumber() + "在待审批新增操作中存在，不能修改！");
                }
                if (user.getMailbox().equals(approveMailbox)){
                    return ResponseVO.fail("用户邮箱"+user.getMailbox() + "在待审批新增操作中存在，不能修改！");
                }
            }

            List<SysUser> sysUserList = sysUserService.queryAllUserByDecrypt();
            for (SysUser sysUser:sysUserList){
                if (user.getPhonenumber().equals(sysUser.getPhonenumber()) && user.getId().longValue()!=sysUser.getId().longValue()){
                    return ResponseVO.fail("手机号码"+user.getPhonenumber() + "存在，不能修改！");
                }
                if (user.getMailbox().equals(sysUser.getMailbox()) && user.getId().longValue()!=sysUser.getId().longValue()){
                    return ResponseVO.fail("用户邮箱"+user.getMailbox() + "存在，不能修改！");
                }
            }
            if (user.getExpDate()==null) {
                user.setExpDate(null);
            }
            else{
                // 判断临时账号有效期不能超过30天
                Calendar calendar = Calendar.getInstance();
                // 将当前日期增加30天
                calendar.add(Calendar.DAY_OF_MONTH, 29);
                // 获取增加30天后的日期
                Date endDate = calendar.getTime();
                if (!user.getExpDate().before(endDate)){
                    return ResponseVO.fail("账号有效期不能超过30天！");
                }
                sysApprove.setExpDate(user.getExpDate());
            }

            sysApprove.setUsertype(user.getUsertype());
            sysApprove.setStatus(user.getStatus());
            sysApprove.setMasterId(String.valueOf(user.getId()));
            // 将修改前信息存入
            sysApprove.setParameterContent(JSONUtil.parse(existUser).toString());
            // 用户新增插入审批表
            sysApprove.setModuleName(ApproveConstants.MODULE_NAME_USER);
            sysApprove.setOperation(String.valueOf(ApproveOperaterEnum.UPDATE.getCode()));
            sysApprove.setApproveStatus(String.valueOf(ApproveStatusEnum.DSP.getCode()));
            sysApprove.setEntityName("SysUser");

            // 更改用户表signstr为1
            boolean bo = sysUserService.addUserByApprove(user.getId(),sysApprove);
            if (bo) {
                return ResponseVO.success("修改用户信息成功,等待审核管理员进行审核！");
            } else {
                log.error("修改用户信息失败");
                return ResponseVO.fail("修改用户信息失败");
            }
        } catch (Exception e) {
            throw new CustomException("修改用户信息异常", e);
        }
    }

    /**
     * 初始密码发送邮箱
     */
    @PostMapping(value = "/resetPassword")
    @AgainVerify
    @OperateLog(title = "用户管理", businessType = BusinessType.RESETPWD, auditType = AuditType.SYS,operdesc = "初始/重置密码发送邮箱")
    @PreAuthorize("@ss.hasPermi('system:user:send')")
    @PreventReplay
    public ResponseVO resetPassword(String id) {
        if (StringUtils.isEmpty(id)) {
            return ResponseVO.fail("重置密码缺失id!");
        }
        // 获取审批表是否存在此操作
        QueryWrapper<SysApprove> wrapper = new QueryWrapper<>();
        // 条件：待审批
        wrapper.eq("approve_status", ApproveStatusEnum.DSP.getCode());
        // 条件：删除操作
        wrapper.eq("master_id", id);
        // 条件：实体名
        wrapper.eq("entity_name", "SysUser");
        List<SysApprove> list = sysApproveService.list(wrapper);
        if (list.size() > 0) {
            return ResponseVO.fail("此记录存在未审批的操作,不能初始/重置密码！");
        }
        // id获取用户
        SysUser sysUser = sysUserService.getById(id);
        if (sysUser == null) {
            return ResponseVO.fail("重置密码失败！");
        }

        SysPolicy sysPolicy = sysPolicyService.getOne(new QueryWrapper<>());
        // 生成8位初始密码
        String randomPwd = RandomRulePwd.createPwd(sysPolicy.getPasswordRule(),8);
        log.info("发送邮箱初始/重置密码\r\n" +
                "↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓邮箱内容↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓"+
                "\r\n  账号："+sysUser.getUsername()+"  初始/重置密码："+randomPwd+" \r\n"     +
                "↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑邮箱内容↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑");
//        log.info("发送邮箱重置密码后台输出======> 用户名："+sysUser.getUsername()+" 初始/重置密码："+randomPwd);
        // SM3加密密码
        String sm3password = SmUtil.sm3(randomPwd).toUpperCase();
        // 再对密码sm2
        String sm2password = SM2CryptUtils.encrypt(sm3password,SecretKeyConstants.SERVER_PUBLIC_KEY);

        boolean bo = sysUserService.resetPassword(Integer.parseInt(id), sm2password,sm3password,sm2password);
        if (!bo) {
            return ResponseVO.fail("密码生成失败！");
        }
        try {
//            String[] mailArray = {AesUtils.decryptStr(sysUser.getMailbox())};
//            sendMailUtil.executeSendMail(mailArray, "系统登录密码", "密码：" + randomPwd);
        } catch (Exception e) {
//            log.error("用户名："+sysUser.getUsername()+",邮箱验证码发送失败！",e);
            return ResponseVO.fail("发送邮箱失败");
        }
        return ResponseVO.success();
    }

    /**
     * 删除用户信息
     */
    @PostMapping(value = "/delUser")
    @AgainVerify
    @OperateLog(title = "用户管理", businessType = BusinessType.DELETE, auditType = AuditType.SYS,operdesc = "删除用户")
    @PreAuthorize("@ss.hasPermi('system:user:remove')")
    @PreventReplay
    public ResponseVO delete(String id) throws CustomException {
        try {
            if (StringUtils.isEmpty(id)) {
                return ResponseVO.fail("id不能为空!");
            }
            // id获取用户
            SysUser sysUser = sysUserService.getById(id);
            if (sysUser == null) {
                return ResponseVO.fail("id为空不能删除用户！");
            }

            // 获取审批表是否存在此操作
            QueryWrapper<SysApprove> wrapper = new QueryWrapper<>();
            // 条件：待审批
            wrapper.eq("approve_status", ApproveStatusEnum.DSP.getCode());
            // 条件：删除操作
            wrapper.eq("master_id", id);
            // 条件：实体名
            wrapper.eq("entity_name", "SysUser");
            List<SysApprove> list = sysApproveService.list(wrapper);
            if (list.size() > 0) {
                return ResponseVO.fail("此记录存在未审批的操作,不能进行删除！");
            }

            boolean bo = sysUserService.removeUserById(sysUser);
            if (bo) {
                return ResponseVO.success("【删除用户】已进入审批，审批通过后实现真正删除！");
            } else {
                log.error("删除用户信息失败");
                return ResponseVO.fail("删除用户信息失败");
            }
        } catch (Exception e) {
            throw new CustomException("删除用户信息异常", e);
        }
    }

    /**
     * 修改密码
     */
    @PostMapping(value = "/updatePassword")
    @OperateLog(title = "用户管理", businessType = BusinessType.PWDUPDATE, auditType = AuditType.SYS,operdesc = "修改个人密码")
    @PreventReplay
    public ResponseVO updatePassword(String id, String oldPassword, String newPassword, String confirmPassword) throws CustomException {
        try {
            oldPassword = oldPassword.trim();
            newPassword = newPassword.trim();
            confirmPassword = confirmPassword.trim();

            if (StringUtils.isEmpty(id)) {
                return ResponseVO.fail("修改密码缺失id!");
            }
            // 获取审批表是否存在此操作
            QueryWrapper<SysApprove> wrapper = new QueryWrapper<>();
            // 条件：待审批
            wrapper.eq("approve_status", ApproveStatusEnum.DSP.getCode());
            // 条件：删除操作
            wrapper.eq("master_id", id);
            // 条件：实体名
            wrapper.eq("entity_name", "SysUser");
            List<SysApprove> list = sysApproveService.list(wrapper);
            if (list.size() > 0) {
                return ResponseVO.fail("此记录存在未审批的操作,不能进行修改！");
            }
            // id获取用户
            SysUser sysUser = sysUserService.getById(id);
            if (sysUser == null) {
                return ResponseVO.fail("找不到用户,修改密码失败！");
            }

            if (newPassword == null) {
                // 返回密码长度问题
                return ResponseVO.fail("密码长度需要8~20位之间！");
            }

            if (StringUtils.isEmpty(oldPassword)) {
                return ResponseVO.fail("旧密码不能为空!");
            }

            if (StringUtils.isEmpty(newPassword)) {
                return ResponseVO.fail("新密码不能为空!");
            } else if (StringUtils.isEmpty(confirmPassword)) {
                return ResponseVO.fail("确认密码不能为空！");
            } else if (!newPassword.equals(confirmPassword)) {
                return ResponseVO.fail("新密码两次输入的密码不一致！");
            }

            if (newPassword.contains(" ")){
                return ResponseVO.fail("新密码中不能含有空格！");
            }

            // 对新密码规则验证
            if (newPassword.contains(sysUser.getUsername())) {
                return ResponseVO.fail("密码不能含有账号！");
            }
            String oldpwd = SM2CryptUtils.decrypt(sysUser.getPassword(),SecretKeyConstants.SERVER_PRIVATE_KEY);
            if (SmUtil.sm3(newPassword).toUpperCase().equals(oldpwd)) {
                return ResponseVO.fail("新密码不能与上次密码相同！");
            }

            SysPolicy sysPolicy = sysPolicyService.getOne(new QueryWrapper<>());
            String ruleInfo = PasswordRuleUtil.ruleRegx(sysPolicy.getPasswordRule(),newPassword);
            if (!"true".equals(ruleInfo)){
                return ResponseVO.fail(ruleInfo);
            }

            // 验证旧密码是否正确
            if (!oldpwd.equals(SmUtil.sm3(oldPassword).toUpperCase())){
                return ResponseVO.fail("旧密码不正确！");
            }

            // 新密码加密
            String sm3newpwd = SmUtil.sm3(newPassword).toUpperCase();
            // 再次sm2加密
            String sm2password = SM2CryptUtils.encrypt(sm3newpwd,SecretKeyConstants.SERVER_PUBLIC_KEY);
            sysUser.setPassword(sm2password);
            sysUser.setCheckPassword(sm3newpwd);
            sysUser.setBakPassword(sm2password);
            sysUser.setLastUpdatePwdTime(new Date());
            boolean bo = sysUserService.updateById(sysUser);
            if (!bo) {
                return ResponseVO.fail("修改密码失败！");
            }
            return ResponseVO.success();
        } catch (Exception e) {
            throw new CustomException("修改密码异常", e);
        }
    }

    /**
     * 解锁用户信息
     */
    @PostMapping(value = "/relockUser")
    @AgainVerify
    @OperateLog(title = "用户管理", businessType = BusinessType.UNLOCK, auditType = AuditType.SYS,operdesc = "用户账号解锁")
    @PreAuthorize("@ss.hasPermi('system:user:relock')")
    @PreventReplay
    public ResponseVO relockUser(String id,String expDate) throws CustomException {
        try {
            if (StringUtils.isEmpty(id)) {
                return ResponseVO.fail("id不能为空!");
            }
            // 获取审批表是否存在此操作
            QueryWrapper<SysApprove> wrapper = new QueryWrapper<>();
            // 条件：待审批
            wrapper.eq("approve_status", ApproveStatusEnum.DSP.getCode());
            // 条件：删除操作
            wrapper.eq("master_id", id);
            // 条件：实体名
            wrapper.eq("entity_name", "SysUser");
            List<SysApprove> list = sysApproveService.list(wrapper);
            if (list.size() > 0) {
                return ResponseVO.fail("此记录存在未审批的操作,不能进行解锁！");
            }
            // id获取用户
            SysUser sysUser = sysUserService.getById(id);
            if (sysUser == null) {
                return ResponseVO.fail("不能解锁用户！");
            }
            if (!"1".equals(sysUser.getStatus())) {
                return ResponseVO.fail("只能对【锁定】状态的进行解锁！");
            }

            if (StringUtils.isNotBlank(expDate)){
                Date eDate = DateUtil.parseDate(expDate);
                // 判断临时账号有效期不能超过30天
                Calendar calendar = Calendar.getInstance();
                // 将当前日期增加30天
                calendar.add(Calendar.DAY_OF_MONTH, 29);
                // 获取增加30天后的日期
                Date endDate = calendar.getTime();
                if (!eDate.before(endDate)){
                    return ResponseVO.fail("账号截止日期不能超过30天！");
                }
            }

            boolean bo = sysUserService.relockUserById(Integer.parseInt(id),expDate);
            if (bo) {
                return ResponseVO.success("解锁成功");
            } else {
                log.error("解锁失败");
                return ResponseVO.fail("解锁失败");
            }
        } catch (Exception e) {
            throw new CustomException("解锁异常", e);
        }
    }

    /**
     * 用户授权角色
     */
    @PostMapping("/authRole")
    @AgainVerify
    @PreAuthorize("@ss.hasPermi('system:user:role')")
    @OperateLog(title = "用户管理", businessType = BusinessType.GRANT, auditType = AuditType.SYS,operdesc = "用户授权角色")
    @PreventReplay
    public ResponseVO authRole(String userId, String roleId) throws CustomException {
        try {
            if (StringUtils.isEmpty(userId)) {
                return ResponseVO.fail("id不能为空!");
            }
            // id获取用户
            SysUser sysUser = sysUserService.getById(userId);
            if (sysUser == null) {
                return ResponseVO.fail("id为空不能授权用户！");
            }

            // id获取用户
            SysRole sysRole = sysRoleService.getById(roleId);
            if (sysRole == null) {
                return ResponseVO.fail("角色id为空不能授权用户！");
            }

            // 获取审批表是否存在此操作
            QueryWrapper<SysApprove> wrapper = new QueryWrapper<>();
            // 条件：待审批
            wrapper.eq("approve_status", ApproveStatusEnum.DSP.getCode());
            // 条件：删除操作
            wrapper.eq("master_id", userId);
            // 条件：实体名
            wrapper.eq("entity_name", "SysUser");
            List<SysApprove> list = sysApproveService.list(wrapper);
            if (list.size() > 0) {
                return ResponseVO.fail("此记录存在未审批的操作,不能进行修改！");
            }

            SysApprove sysApprove = new SysApprove();
            sysApprove.setMasterId(userId);
            sysApprove.setUsername(sysUser.getUsername());
            sysApprove.setRoleId(roleId);
            sysApprove.setParameterContent("授权用户账号："+sysUser.getUsername()+",分配角色："+sysRole.getRoleName());
            // 用户新增插入审批表
            sysApprove.setModuleName(ApproveConstants.MODULE_NAME_USER);
            sysApprove.setOperation(String.valueOf(ApproveOperaterEnum.APPROVE.getCode()));
            sysApprove.setApproveStatus(String.valueOf(ApproveStatusEnum.DSP.getCode()));
            sysApprove.setEntityName("SysUser");

            // 更改用户表signstr为1
            boolean bo = sysUserService.addUserByApprove(Long.parseLong(userId),sysApprove);
            if (bo) {
                return ResponseVO.success("授权用户信息成功,等待审核管理员进行审核！");
            } else {
                log.error("授权用户信息失败");
                return ResponseVO.fail("授权用户信息失败");
            }
        } catch (Exception e) {
            throw new CustomException("分配角色异常", e);
        }
//        return ResponseVO.success("分配角色成功");
    }

    /**
     * 根据用户ID获取角色
     *
     * @param userId
     * @return
     */
    @GetMapping("/getUserRole")
    @PreventReplay
    public ResponseVO getUserRole(Long userId) throws CustomException {
        try {
            if (userId == null) {
                return ResponseVO.fail("用户id不能为空!");
            }

            QueryWrapper<SysUserRole> wrapper = new QueryWrapper<>();
            wrapper.eq("user_id", userId);
            SysUserRole sysUserRole = sysUserRoleService.getOne(wrapper);
            return ResponseVO.success(sysUserRole);
        } catch (Exception e) {
            throw new CustomException("获取用户角色异常", e);
        }
    }

    /**
     * 检测用户密码是否符合规则
     *
     * @return 用户信息
     */
    @GetMapping(value = "/validatePasswordRule")
    public ResponseVO validatePasswordRule() throws CustomException {
        try {
            SysUser sysUser = SecurityContextUtil.getSysUser();
            String upwd = CacheConstants.usernamePasswordMap.get(sysUser.getUsername());
            SysPolicy sysPolicy = sysPolicyService.getOne(new QueryWrapper<>());
            String ruleInfo = PasswordRuleUtil.ruleRegx(sysPolicy.getPasswordRule(),upwd);
            return ResponseVO.success(ruleInfo);
        } catch (Exception e) {
            throw new CustomException("检测用户密码是否符合规则异常", e);
        }
    }
    /**
     * 注销用户信息
     */
    @PostMapping(value = "/logOffUser")
    @AgainVerify
    @OperateLog(title = "用户管理", businessType = BusinessType.DELETE, auditType = AuditType.SYS,operdesc = "注销用户账号")
    @PreAuthorize("@ss.hasPermi('system:user:logoff')")
    @PreventReplay
    public ResponseVO logOffUser(String id) throws CustomException {
        try {
            if (StringUtils.isEmpty(id)) {
                return ResponseVO.fail("id不能为空!");
            }
            // id获取用户
            SysUser sysUser = sysUserService.getById(id);
            if (sysUser == null) {
                return ResponseVO.fail("id为空不能删除用户！");
            }

            // 获取审批表是否存在此操作
            QueryWrapper<SysApprove> wrapper = new QueryWrapper<>();
            // 条件：待审批
            wrapper.eq("approve_status", ApproveStatusEnum.DSP.getCode());
            // 条件：删除操作
            wrapper.eq("master_id", id);
            // 条件：实体名
            wrapper.eq("entity_name", "SysUser");
            List<SysApprove> list = sysApproveService.list(wrapper);
            if (list.size() > 0) {
                return ResponseVO.fail("此记录存在未审批的操作,不能注销！");
            }

            // 根据id改变状态为注销，提交到审核
            SysApprove sysApprove = new SysApprove();
            sysApprove.setUsername(sysUser.getUsername());
            sysApprove.setNickname(sysUser.getNickname());
            sysApprove.setIdcard(sysUser.getIdcard());
            sysApprove.setMailbox(sysUser.getMailbox());
            sysApprove.setPhonenumber(sysUser.getPhonenumber());
            sysApprove.setUsertype(sysUser.getUsertype());
            sysApprove.setStatus(sysUser.getStatus());
            sysApprove.setMasterId(String.valueOf(sysUser.getId()));
            sysApprove.setParameterContent(JSONUtil.parse(sysUser).toString());
            // 用户新增插入审批表
            sysApprove.setModuleName(ApproveConstants.MODULE_NAME_USER);
            sysApprove.setOperation(String.valueOf(ApproveOperaterEnum.DELETE.getCode()));
            sysApprove.setApproveStatus(String.valueOf(ApproveStatusEnum.DSP.getCode()));
            sysApprove.setEntityName("SysUser");
            boolean bo = sysUserService.addUserByApprove(Long.parseLong(id),sysApprove);
            if (bo) {
                return ResponseVO.success("注销用户成功,等待审核管理员进行审核！");
            } else {
                log.error("注销用户失败");
                return ResponseVO.fail("注销用户失败");
            }
        } catch (Exception e) {
            throw new CustomException("注销用户异常", e);
        }
    }

    /**
     * 获取用户分页信息(查询在线用户使用 其中屏蔽了状态为注销的用户)
     *
     * @return 用户信息
     */
    @GetMapping(value = "/getUserByHealthy")
    @PreAuthorize("@ss.hasPermi('monitor:onLine:list')")
    @OperateLog(title = "在线用户管理", businessType = BusinessType.QUERY, auditType = AuditType.SYS,operdesc = "在线用户查询")
    @PreventReplay
    public ResponseVO getUserByHealthy(String currentPage, String pageSize, String onLineStatus) throws CustomException {
        try {
            Integer cp;
            if (StringUtils.isNotEmpty(currentPage)) {
                if (NumberUtil.isInteger(currentPage)) {
                    cp = Integer.parseInt(currentPage);
                } else {
                    return ResponseVO.fail("currentPage不是整数！");
                }
            } else {
                return ResponseVO.fail("currentPage不能是空！");
            }

            Integer ps;
            if (StringUtils.isNotEmpty(pageSize)) {
                if (NumberUtil.isInteger(pageSize)) {
                    ps = Integer.parseInt(pageSize);
                } else {
                    return ResponseVO.fail("pageSize不是整数！");
                }
            } else {
                return ResponseVO.fail("pageSize不能是空！");
            }
            QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
            wrapper.ne("status", "2");
            if (StringUtils.isNotEmpty(onLineStatus)) {
                wrapper.eq("online_status", onLineStatus);
            }
            Page<SysUser> result = sysUserService.page(new Page<>(cp, ps), wrapper);
            return ResponseVO.success(result);
        } catch (Exception e) {
            throw new CustomException("获取用户异常", e);
        }
    }

    /**
     * 验证心跳是否存活
     */
    @GetMapping(value = "/establishHeart")
    public ResponseVO establishHeart(HttpServletRequest request, HttpServletResponse response) throws CustomException {
        try {
            return ResponseVO.success();
        } catch (Exception e) {
            throw new CustomException("建立心跳异常", e);
        }
    }
}
