package com.patzn.lims.sys.service.impl;

import com.baomidou.kisso.common.encrypt.TOTP;
import com.baomidou.kisso.enums.TokenOrigin;
import com.baomidou.kisso.security.token.SSOToken;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.patzn.lims.core.api.PtAssert;
import com.patzn.lims.core.toolkit.RegexUtils;
import com.patzn.lims.core.web.Account;
import com.patzn.lims.core.web.BaseServiceImpl;
import com.patzn.lims.core.web.LoginHelper;
import com.patzn.lims.sys.dto.SysUserDTO;
import com.patzn.lims.sys.dto.UserRegDTO;
import com.patzn.lims.sys.entity.SysCompany;
import com.patzn.lims.sys.entity.SysUser;
import com.patzn.lims.sys.entity.SysWxmpUser;
import com.patzn.lims.sys.enums.SysUserAccreditEnum;
import com.patzn.lims.sys.enums.VerificationCodeEnum;
import com.patzn.lims.sys.enums.WxTypeEnum;
import com.patzn.lims.sys.mapper.SysUserMapper;
import com.patzn.lims.sys.service.*;
import com.patzn.lims.sys.vo.SysUserVO;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.IdentityService;
import org.flowable.idm.api.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author patzn
 * @since 2017-07-10
 */
@Service
public class SysUserServiceImpl extends BaseServiceImpl<SysUserMapper, SysUser> implements ISysUserService {
    @Autowired
    private ISysCompanyService sysCompanyService;
    @Autowired
    private ISysRoleService sysRoleService;
    @Autowired
    private ISysOrgService sysOrgService;
    @Autowired
    private ISysUserRelOrgService sysUserRelOrgService;
    @Autowired
    private ISysUserRelRoleService sysUserRelRoleService;
    @Autowired
    private ISysWxmpUserService sysWxmpUserService;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private IdentityService identityService;

    @Override
    public boolean activation(SysUser user, String newPwd) {
        PtAssert.fail(!RegexUtils.isPassword(newPwd), "请输入字母数字混合6-20位长度的密码");
        return false;
    }


    @Override
    public boolean register(UserRegDTO dto, String ip) {
        int verifyMobile = 0;

        if (StringUtils.isNotEmpty(dto.getCode())) {
            // 验证短信验证码
            String code = redisTemplate.opsForValue().get(VerificationCodeEnum.REGISTER.getKey(
                    dto.getMobile(), dto.getCode()
            ));
            PtAssert.fail(null == code || !dto.getCode().equals(code), "验证码错误，请重新输入");
            verifyMobile = 1;
        }
        SysUser sysUser = dto.convert(SysUser.class);
        sysUser.setAdmin(0);
        sysUser.setStatus(1);
        sysUser.setVerifyMobile(verifyMobile);
        sysUser.setAccredit(SysUserAccreditEnum.NORMAL);
        sysUser.setRegip(ip);
        sysUser.setRegtime(new Date());
        return save(sysUser);
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean save(SysUser sysUser) {
        if (null == sysUser || StringUtils.isEmpty(sysUser.getUsername())
                || StringUtils.isEmpty(sysUser.getPassword())) {
            return false;
        }

        // 用户名验证码
        verifyUsername(sysUser.getUsername(), true);

        // 判断手机号码是否激活
        PtAssert.fail(RegexUtils.isMobile(sysUser.getMobile()) && isVerify(sysUser.getMobile()), "该手机号码已经注册，请更换其他手机号码");

        List<SysUser> sysUserList = listByUsername(sysUser.getUsername());
        if (CollectionUtils.isNotEmpty(sysUserList)) {
            PtAssert.fail("该账号名已经存在");
        }
        if (null == sysUser.getVerifyEmail()) {
            sysUser.setVerifyEmail(0);
        }
        if (null == sysUser.getVerifyMobile()) {
            sysUser.setVerifyMobile(0);
        }
        sysUser.setRegtime(new Date());
        sysUser.setStatus(2);
        sysUser.setPassword(passwordEncoder.encode(sysUser.getPassword()));
        sysUser.setId(IdWorker.getId());
        boolean result = super.save(sysUser);
        if (result) {
            // 保存用户信息至工作流
            Account account = LoginHelper.getAccount();
            if (null != account) {
                User user = identityService.newUser(String.valueOf(sysUser.getId()));
                user.setTenantId(account.getCompanyIdStr());
                identityService.saveUser(user);
            }
        }
        return result;
    }


    private List<SysUser> listByUsername(String username) {
        if (StringUtils.isNotEmpty(username)) {
            return list(Wrappers.<SysUser>query().eq("username", username));
        }
        return null;
    }

    @Override
    public boolean updateById(SysUser sysUser) {
        if (null == sysUser || StringUtils.isEmpty(sysUser.getUsername())
                || StringUtils.isEmpty(sysUser.getPassword())) {
            return false;
        }
        sysUser.setPassword(passwordEncoder.encode(sysUser.getPassword()));
        // 不允许更新登录账号
        sysUser.setUsername(null);
        return super.updateById(sysUser);
    }

    /**
     * <p>
     * 验证用户名是否合法
     * </p>
     */
    private void verifyUsername(String username, boolean existDb) {
        if (null != username) {
            PtAssert.fail((RegexUtils.isDigit(username) && username.length() == 11), "抱歉！用户名不能为11位纯数字，请重新输入。");
            PtAssert.fail(RegexUtils.isEmail(username), "抱歉！用户名不能为邮箱，请重新输入。");
            PtAssert.fail(existDb && null != getByUserName(username), "该账号名已存在，请改换其他用户名。");
        }
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveManager(SysUserDTO dto) {
        if (dto.getCompanyId().equals(0L)) {
            PtAssert.fail("非法的企业ID请联系管理员！");
        }
        SysUser sysUser = dto.convert(SysUser.class);
        verifyUsername(sysUser.getUsername(), false);
        SysCompany sysCompany = sysCompanyService.getById(sysUser.getCompanyId());
        if (null != sysCompany && StringUtils.isNotEmpty(sysCompany.getManager())) {
            SysUser manager = super.getOne(Wrappers.<SysUser>query().eq("username", sysCompany.getManager()));
            if (null == manager) {
                PtAssert.fail("用户异常，请联系管理员！");
            }
            // 存在关联管理员更新
            sysUser.setUsername(sysCompany.getManager());
            if (StringUtils.isNotEmpty(sysUser.getPassword())) {
                // 重置密码
                sysUser.setPassword(passwordEncoder.encode(sysUser.getPassword()));
            }
            sysUser.setId(manager.getId());
            // 角色关联
            if (CollectionUtils.isNotEmpty(dto.roleIdList())) {
                sysUserRelRoleService.saveRelRole(sysUser.getId(), dto.roleIdList());
            }
            return super.updateById(sysUser);
        }
        if (null == sysUser || StringUtils.isEmpty(sysUser.getUsername())
                || StringUtils.isEmpty(sysUser.getPassword())) {
            PtAssert.fail("数据异常请联系管理员！");
        }
        sysUser.setRealname(sysCompany.getName() + "【管理员】");
        // 设置为租户管理员
        sysUser.setAdmin(1);
        sysUser.setAccredit(SysUserAccreditEnum.ALLOW);
        if (save(sysUser)) {
            // 角色关联
            if (CollectionUtils.isNotEmpty(dto.roleIdList())) {
                sysUserRelRoleService.saveRelRole(sysUser.getId(), dto.roleIdList());
            }
            // 新增关联管理员，保存管理员更新公司管理员字段
            sysCompany = new SysCompany();
            sysCompany.setId(sysUser.getCompanyId());
            sysCompany.setManager(sysUser.getUsername());
            return sysCompanyService.updateById(sysCompany);
        }
        return false;
    }


    @Override
    public void otpQrCode(HttpServletResponse response, int width, int height, Long userId) {
        Account account = LoginHelper.getAccount();
        if (null == userId) {
            userId = account.getUserId();
        } else {
            PtAssert.fail(!account.getUserId().equals(userId) && 0 == account.getAdmin(),
                    "该账号非管理员无法操作执行该操作");
        }
        SysUser user = getById(userId);
        PtAssert.fail(StringUtils.isEmpty(user.getTotp()), "该账号不存或未开通二次认证");
        try {
            qrCode(TOTP.getOtpAuthUrl(user.getUsername(), "patzn", user.getTotp()),
                    width, height, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    @Override
    public boolean otpOnOff(Long userId, Integer code) {
        Account account = LoginHelper.getAccount();
        if (null == userId) {
            userId = account.getUserId();
        } else {
            PtAssert.fail(!account.getUserId().equals(userId) && 0 == account.getAdmin(),
                    "该账号非管理员无法操作执行该操作");
        }
        SysUser user = getById(userId);
        if (0 == user.getTwofactor()) {
            if (null == code) {
                try {
                    // 开通 TOTP 认证
                    SysUser su = new SysUser();
                    su.setId(user.getId());
                    su.setTotp(TOTP.getSecretKey());
                    su.setTwofactor(1);
                    return super.updateById(su);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } else if (null != code && TOTP.isValidCode(user.getTotp(), code)) {
            // 关闭 TOTP 认证
            SysUser su = new SysUser();
            su.setId(user.getId());
            su.setTwofactor(0);
            return retBool(baseMapper.updateById(su));
        }
        return false;
    }


    /**
     * <p>
     * 生成二维码
     * </p>
     */
    @Override
    public void qrCode(String contents, Integer width, Integer height, HttpServletResponse response) {
//        try {
//            Map<EncodeHintType, Object> hints = new Hashtable<>();
//            // 指定纠错等级
//            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
//            // 指定编码格式
//            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
//            //设置白边
//            hints.put(EncodeHintType.MARGIN, 3);
//            if (null == width || null == height) {
//                width = 282;
//                height = 282;
//            }
//            BitMatrix bitMatrix = new MultiFormatWriter().encode(contents,
//                    BarcodeFormat.QR_CODE, width, height, hints);
//
//            MatrixToImageWriter.writeToStream(bitMatrix, "png", response.getOutputStream());
//        } catch (Throwable e) {
//            logger.error("生成 qrCode 异常", e);
//        }
    }


    @Override
    public void exportUser(HttpServletResponse response, Long companyId, SysUserVO vo) {
        vo.setCompanyId(companyId);
//        new UserExportHandler(listVO(vo)).generater(response);
    }


    @Override
    public Map<String, Object> managerInfo(Long companyId) {
        if (null == companyId) {
            return null;
        }
        SysCompany sysCompany = sysCompanyService.getById(companyId);
        PtAssert.fail(null == sysCompany || StringUtils.isEmpty(sysCompany.getManager()), "管理员不存在，请先设置");

        SysUser sysUser = getByUserName(sysCompany.getManager());
        PtAssert.fail(null == sysUser, String.format("用户 %s 信息不存在，请联系管理员", sysCompany.getManager()));

        // 返回管理员信息及关联角色信息
        Map<String, Object> data = new HashMap<>(2);
        data.put("id", sysUser.getId());
        data.put("username", sysUser.getUsername());
        data.put("realname", sysUser.getRealname());
        data.put("roles", sysRoleService.listByUserId(sysUser.getId()));
        return data;
    }


    @Override
    public Page<SysUser> page(Page<SysUser> page, SysUserVO vo) {
        return page.setRecords(baseMapper.selectPageByVO(page, vo));
    }


    @Override
    public Page<SysUser> pageFlowMemberShip(Page<SysUser> page, String groupId, SysUserVO vo) {
        return page.setRecords(baseMapper.selectPageFlowMemberShip(page, groupId, vo));
    }


    @Override
    public Page<SysUser> pageNotSendMessage(Page<SysUser> page, Long messageId, SysUser sysUser) {
        return page.setRecords(baseMapper.selectPageNotSendMessage(page, messageId, sysUser));
    }


    @Override
    public Page<SysUser> pageFlowExcludeMemberShip(Page<SysUser> page, String groupId, SysUserVO vo) {
        page.setRecords(baseMapper.selectPageFlowExcludeMemberShip(page, groupId, vo));
        return page;
    }


    @Override
    public List<SysUser> list(SysUser sysUser) {
        if (null == sysUser.getStatus()) {
            sysUser.setStatus(1);
        }
        return list(Wrappers.<SysUser>query().last("LIMIT 20"));
    }

    @Override
    public List<SysUser> listByRoleName(Long companyId, String roleName) {
        return baseMapper.selectListByRoleName(companyId, roleName);
    }

    @Override
    public List<SysUserVO> listVO(SysUserVO vo) {
        return baseMapper.selectListByVO(vo);
    }

    @Override
    public SysUser login(String username, String password, boolean loginBack) {
        SysUser sysUser = login(username, password);
        if (loginBack && sysUser.getAccredit() != SysUserAccreditEnum.ALLOW) {
            PtAssert.fail("不允许登录");
        }
        return sysUser;
    }


    @Override
    public SysUser login(String username, String password) {
        QueryWrapper<SysUser> wrapper = Wrappers.query();
        if (RegexUtils.isMobile(username)) {
            // 手机号码登录
            wrapper.eq("mobile", username).eq("verify_mobile", 1);
        } else {
            wrapper.eq("username", username);
        }
        List<SysUser> sysUserList = list(wrapper);
        PtAssert.fail(null == sysUserList || sysUserList.size() != 1, "登录异常");

        // 系统用户判断
        SysUser sysUser = sysUserList.get(0);
        PtAssert.fail(sysUser.getStatus() == 0, "登录失败");
        if (null != sysUser.getCompanyId() && !Long.valueOf(0L).equals(sysUser.getCompanyId())) {
            // 非系统用户登录且企业禁用所属用户无法使用
            SysCompany sysCompany = sysCompanyService.getById(sysUser.getCompanyId());
            PtAssert.fail(sysCompany.getStatus() == 0, "禁止登录");
        }

        // 登录密码验证
        //PtAssert.fail(!PwdUtils.valid(sysUser.getSalt(), sysUser.getPassword(), password), ErrorCode.LOGIN_PASSWORD_ERROR);

        // 不允许暴露加密盐和登录密码
        sysUser.setPassword(null);
        return sysUser;
    }


    @Override
    public String loginToken(HttpServletRequest request, String username, String password,
                             String newPwd, String code) {
        boolean inactivate = false;
        if (StringUtils.isNotEmpty(newPwd)) {
            PtAssert.fail(newPwd.equals(password), "新旧密码不能一致");
            inactivate = true;
        }
        SysUser user;
        if (RegexUtils.isMobile(username) && StringUtils.isNotEmpty(code)) {
            user = loginByCode(username, code);
        } else {
            PtAssert.fail(StringUtils.isEmpty(password), "请输入登录密码");
            user = login(username, password);
        }
        if (inactivate) {
            PtAssert.fail(!activation(user, newPwd), "用户激活失败");
        } else {
            // 未激活状态
            PtAssert.fail(2 == user.getStatus(), "inactivate");
        }
        return getHtml5Token(request, user);
    }


    @Override
    public String loginToken(HttpServletRequest request, WxTypeEnum type, String openid, String username, String password) {
        SysUser sysUser = login(username, password);
        SysWxmpUser wxmpUser = new SysWxmpUser();
        wxmpUser.setUserId(sysUser.getId());
        wxmpUser.setType(type);
        wxmpUser.setOpenid(openid);
        wxmpUser.setSubscribe(0);
        wxmpUser.setSubscribeTime(new Date());
        PtAssert.fail(!sysWxmpUserService.save(wxmpUser), "绑定失败");
        return getHtml5Token(request, sysUser);
    }


    /**
     * <p>
     * 设置 HTML5 登录 Token
     * </p>
     *
     * @param request 当前请求
     * @param user    用户信息
     * @return
     */
    private String getHtml5Token(HttpServletRequest request, SysUser user) {
        if (null != validLogin(user)) {
            JwtBuilder jwtBuilder = Jwts.builder();
            if (null != user.getCompanyId()) {
                jwtBuilder.claim(LoginHelper.COMPANY_ID, user.getCompanyId());
            }
            if (null != user.getAdmin()) {
                jwtBuilder.claim(LoginHelper.ADMIN, user.getAdmin());
            }
            String username = user.getUsername();
            if (StringUtils.isNotEmpty(user.getRealname())) {
                username = user.getRealname();
            }
            return SSOToken.create(jwtBuilder).setOrigin(TokenOrigin.HTML5)
                    .setId(user.getId()).setIssuer(username)
                    .setUserAgent(request).getToken();
        }
        return null;
    }

    @Override
    public SysUser getByMobile(String mobile) {
        return super.getOne(Wrappers.<SysUser>query()
                .eq("mobile", mobile)
                .eq("verify_mobile", 1)
                .last("LIMIT 1"));
    }

    @Override
    public SysUser getByUserName(String username) {
        return super.getOne(Wrappers.<SysUser>query()
                .eq("username", username)
                .last("LIMIT 1"));
    }

    @Override
    public SysUser getByRealName(String realname) {
        return super.getOne(Wrappers.<SysUser>query()
                .eq("realname", realname)
                .last("LIMIT 1"));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateDtoById(SysUserDTO dto) {
        if (null == dto.getId()) {
            return false;
        }
        if (LoginHelper.ADMIN.equals(dto.getUsername())) {
            PtAssert.fail(!LoginHelper.isSysAdmin(), "抱歉！您无权编辑系统管理员信息。");
            // 超级管理员不允许变更为普通用户
            dto.setAccredit(SysUserAccreditEnum.ALLOW);
        }
        SysUser sysUser = super.getById(dto.getId());
        if (null == sysUser) {
            PtAssert.fail("该账号不存您无法编辑！");
        }
        if (Integer.valueOf(1).equals(dto.getNotifyWechat())) {
            // 验证是否允许设置为微信通知
            SysCompany sysCompany = sysCompanyService.getById(sysUser.getCompanyId());
            PtAssert.fail(null != sysCompany && 0 == sysCompany.getNotifyWechat(),
                    "抱歉！您所属的企业未启微信通知功能，请联系管理员。");
        }
        // 判断是否修改用户名
        if (null != dto.getUsername() && !dto.getUsername().equals(sysUser.getUsername())) {
            PtAssert.fail(super.count(Wrappers.<SysUser>query()
                            .eq("username", dto.getUsername())) > 0
                    , String.format("抱歉！账号: %s 已存在，请更换其它账号", dto.getUsername()));
        }
        // 临时修改对象
        SysUser tempUser = dto.convert(SysUser.class);
        // 不允许直接修改手机号码和邮箱地址
        tempUser.setMobile(null);
        tempUser.setEmail(null);
        if (StringUtils.isNotEmpty(dto.getPassword())) {
            //tempUser.setPassword(PwdUtils.generate(sysUser.getSalt(), dto.getPassword()));
        }
        // 置空防止更换为其他企业，其他账户
        tempUser.setCompanyId(null);

        // 企业管理员修改自己的名字，重置企业表管理员字段
        if (null != dto.getUsername() && 1 == sysUser.getAdmin()
                && !LoginHelper.isSysAdmin() && null != sysUser.getUsername()
                && !sysUser.getUsername().equals(dto.getUsername())) {
            sysCompanyService.updateManager(sysUser.getCompanyId(), dto.getUsername());
        }

        // 机构关联
        if (CollectionUtils.isNotEmpty(dto.orgIdList())) {
            sysUserRelOrgService.saveRelOrg(dto.getId(), dto.orgIdList());
        }
        // 角色关联
        if (CollectionUtils.isNotEmpty(dto.roleIdList())) {
            sysUserRelRoleService.saveRelRole(dto.getId(), dto.roleIdList());
        }
        // 更新用户信息
        return super.updateById(tempUser);
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveDto(SysUserDTO dto) {
        // 新增用户信息
        SysUser sysUser = dto.convert(SysUser.class);
        boolean result = save(sysUser);
        if (result) {
            // 机构关联
            sysUserRelOrgService.saveRelOrg(sysUser.getId(), dto.orgIdList());
            // 角色关联
            sysUserRelRoleService.saveRelRole(sysUser.getId(), dto.roleIdList());
        }
        return result;
    }

    @Override
    public SysUser getById(Serializable id) {
        SysUser sysUser = super.getById(id);
        if (null == sysUser) {
            PtAssert.fail("抱歉！你选择的用户不存在，刷新后重试。");
        }
        return sysUser;
    }


    @Override
    public boolean isVerify(String mobile) {
        // 存在 1 条激活手机号说明被验证码
        return super.count(Wrappers.<SysUser>query()
                .eq("mobile", mobile)
                .eq("verify_mobile", 1)) >= 1;
    }


    @Override
    public boolean changePassword(String mobile, String code, String password) {
        // 密码验证
        PtAssert.fail(!RegexUtils.isPassword(password), "登录密码必须为6-20位字母数字组合");

        // 验证短信验证码
        String mc = redisTemplate.opsForValue().get(VerificationCodeEnum.CHANGE_PASSWORD.getKey(mobile, code));
        PtAssert.fail(null == mc || !mc.equals(code), "验证码错误，请重新输入");

        // 用户逻辑判断
        SysUser sysUser = getByMobile(mobile);
        PtAssert.fail(null == sysUser, "该手机号码未绑定用户");

        // 修改密码
        SysUser tempUser = new SysUser();
        tempUser.setId(sysUser.getId());
        tempUser.setUsername(sysUser.getUsername());
        tempUser.setPassword(password);
        // 转换新密码、用户信息设置不更新
        tempUser.setPassword(passwordEncoder.encode(sysUser.getPassword()));
        tempUser.setUsername(null);
        return super.updateById(tempUser);
    }


    @Override
    public boolean changePassword(Long userId, String oldPwd, String newPwd) {
        SysUser sysUser = getById(userId);
        // 登录密码验证
        // PtAssert.fail(!PwdUtils.valid(sysUser.getSalt(), sysUser.getPassword(), oldPwd), ErrorCode.LOGIN_PASSWORD_ERROR);
        SysUser tempUser = new SysUser();
        tempUser.setId(userId);
        tempUser.setUsername(sysUser.getUsername());
        tempUser.setPassword(newPwd);
        tempUser.setPassword(passwordEncoder.encode(sysUser.getPassword()));
        return super.updateById(tempUser);
    }


    @Override
    public boolean validPassword(Long userId, String password) {
//        SysUser sysUser = getById(userId);
//        return PwdUtils.valid(sysUser.getSalt(), sysUser.getPassword(), password);
        return true;
    }


    @Override
    public SysUser loginByCode(String mobile, String code) {
        if (null == mobile || null == code) {
            return null;
        }
        // 手机号验证码登录校验
        String mc = redisTemplate.opsForValue().get(VerificationCodeEnum.LOGIN.getKey(mobile, code));
        PtAssert.fail(!code.equals(mc), "短信校验码错误，请重新输入");
        return validLogin(super.getOne(Wrappers.<SysUser>query().eq("mobile", mobile).eq("verify_mobile", 1)));
    }


    @Override
    public String loginWxMa(HttpServletRequest request, String openid) {
        return getHtml5Token(request, baseMapper.selectByWxOpenid(openid, WxTypeEnum.MA));
    }


    @Override
    public boolean bindEmailById(Long id, String email) {
        if (null == id || null == email) {
            return false;
        }
        SysUser sysUser = new SysUser();
        sysUser.setId(id);
        sysUser.setEmail(email);
        sysUser.setVerifyEmail(1);
        return super.updateById(sysUser);
    }


    @Override
    public boolean bindMobileById(Long id, String mobile) {
        if (null == id || null == mobile) {
            return false;
        }
        SysUser sysUser = new SysUser();
        sysUser.setId(id);
        sysUser.setMobile(mobile);
        sysUser.setVerifyMobile(1);
        return super.updateById(sysUser);
    }


    @Override
    public SysUserVO getAllowInfoById(Long id) {
        SysUser sysUser = getById(id);
        SysUserVO vo = new SysUserVO();
        vo.setId(sysUser.getId());
        vo.setUsername(sysUser.getUsername());
        vo.setRealname(sysUser.getRealname());
        vo.setEmail(sysUser.getEmail());
        vo.setVerifyEmail(sysUser.getVerifyEmail());
        vo.setAvatar(sysUser.getAvatar());
        vo.setMobile(sysUser.getMobile());
        vo.setVerifyMobile(sysUser.getVerifyMobile());
        vo.setQq(sysUser.getQq());
        vo.setSex(sysUser.getSex());
        vo.setAdmin(sysUser.getAdmin());
        if (null != sysUser.getCompanyId()) {
            SysCompany sysCompany = sysCompanyService.getById(sysUser.getCompanyId());
            PtAssert.fail(null == sysCompany, "该账号企业信息异常，请联系管理员");
            vo.setCompanyName(sysCompany.getName());
            vo.setLogo(sysCompany.getLogo());
        }
        vo.setOrgNames(sysOrgService.getNamesByUserId(id));
        vo.setRoleNames(sysRoleService.getNamesByUserId(id));
        return vo;
    }


    @Override
    public String saveAvatar(Long id, MultipartFile file) {
        PtAssert.fail(null == id || null == file, "用户 ID 或上传文件不存在");
//        OssFileResult result = ossClient.upload(file);
//        if (null != result) {
//            SysUser sysUser = new SysUser();
//            sysUser.setId(id);
//            sysUser.setAvatar(result.getObjectKey());
//            if (super.updateById(sysUser)) {
//                return sysUser.getAvatar();
//            }
//        }
        return null;
    }


    @Override
    public SysUser validLogin(SysUser sysUser) {
//        if (null != sysUser) {
//            PtAssert.fail(StatusEnum.DISABLED == sysUser.getStatus(), ErrorCode.LOGIN_DISABLED);
//            // 允许系统用户跳过使用
//            if (null != sysUser.getCompanyId() && !sysUser.getCompanyId().equals(0L)) {
//                SysCompany sysCompany = sysCompanyService.getById(sysUser.getCompanyId());
//                PtAssert.fail(null == sysCompany || 0 == sysCompany.getStatus(), ErrorCode.LOGIN_DISABLED);
//            }
//            return sysUser;
//        }
        return null;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean importUser(MultipartFile file, Account account) {
//        Collection<UserETO> users = ExcelUtils.readSheetAtOne(UserETO.class, file, "导入用户失败");
//        if (CollectionUtils.isEmpty(users)) {
//            return false;
//        }
//        Set<String> mobileSet = new HashSet<>();
//        Set<String> orgSet = new HashSet<>();
//        Set<String> roleSet = new HashSet<>();
//        users.forEach(e -> {
//            PtAssert.fail(StringUtils.isEmpty(e.getRealname()), "用户名不能为空");
//            PtAssert.fail(!RegexUtils.isMobile(e.getMobile()), "存在非正规手机号码：" + e.getMobile());
//            if (StringUtils.isNotEmpty(e.getMobile())) {
//                mobileSet.add(e.getMobile().trim());
//            }
//            if (StringUtils.isNotEmpty(e.getOrg())) {
//                orgSet.add(e.getOrg().trim());
//            }
//            if (StringUtils.isNotEmpty(e.getRole())) {
//                Collections.addAll(roleSet, e.getRole().trim().split("，|,"));
//            }
//        });
//        PtAssert.fail(null == mobileSet || users.size() != mobileSet.size(),
//                "手机号码不允许为空，并且不能重复");
//
//        PtAssert.fail(super.count(Wrappers.<>query().eq("verify_mobile", 1).in("mobile", mobileSet)) > 0,
//                "手机号存在数据库中已有数据，请无重复导入");
//
//        Map<String, Long> orgMap = null;
//        if (CollectionUtils.isNotEmpty(orgSet)) {
//            List<SysOrg> orgList = sysOrgService.lisByOrgNames(orgSet, account.getCompanyId());
//            PtAssert.fail(CollectionUtils.isEmpty(orgList), "导入未知组织，请核对后重试");
//            if (orgSet.size() != orgList.size()) {
//                Set<String> tempSet = new HashSet<>(orgList.stream().map(o -> o.getName()).collect(Collectors.toList()));
//                PtAssert.fail(tempSet.size() != orgList.size(), "导入组织名数据库中存在重复无法匹配，请核对修改后重试");
//                StringBuilder notFoundOrg = new StringBuilder();
//                orgSet.forEach(o -> {
//                    if (tempSet.add(o)) {
//                        notFoundOrg.append(",").append(o);
//                    }
//                });
//                PtAssert.fail("导入未知组织" + notFoundOrg.toString() + "请核对后重试");
//            }
//            orgMap = orgList.stream().collect(toMap(SysOrg::getName, v -> v.getId(), (k, v) -> k));
//        }
//
//        Map<String, Long> roleMap = null;
//        if (CollectionUtils.isNotEmpty(roleSet)) {
//            List<SysRole> roleList = sysRoleService.listByRoleNames(roleSet, account.getCompanyId());
//            PtAssert.fail(CollectionUtils.isEmpty(roleList), "导入未知角色，请核对后重试");
//            if (roleSet.size() != roleList.size()) {
//                Set<String> tempSet = new HashSet<>(roleList.stream().map(r -> r.getName()).collect(Collectors.toList()));
//                PtAssert.fail(tempSet.size() != roleList.size(), "导入角色数据库中存在重复无法匹配，请核对修改后重试");
//                StringBuilder notFoundRole = new StringBuilder();
//                roleSet.forEach(r -> {
//                    if (tempSet.add(r)) {
//                        notFoundRole.append(",").append(r);
//                    }
//                });
//                PtAssert.fail("导入未知角色" + notFoundRole.toString() + "请核对后重试");
//            }
//            roleMap = roleList.stream().collect(toMap(SysRole::getName, v -> v.getId(), (k, v) -> k));
//        }
//
//        for (UserETO e : users) {
//            SysUser su = new SysUser();
//            su.setRealname(e.getRealname());
//            su.setEmail(e.getEmail());
//            su.setMobile(e.getMobile());
//            // 随机用户名，初始化密码为手机号码
//            su.setUsername(Pinyin4jUtils.converterToSpell(e.getRealname()) + e.getMobile());
//            su.setSalt(MD5.toMD5(su.getUsername()));
//            su.setVerifyMobile(1);
//            su.setAccredit(SysUserAccreditEnum.ALLOW);
//            su.setPassword(PwdUtils.generate(su.getSalt(), e.getMobile()));
//            su.setStatus(2);
//            su.setCompanyId(account.getCompanyId());
//            if (super.save(su)) {
//                // 保存用户信息至工作流
//                User user = identityService.newUser(String.valueOf(su.getId()));
//                user.setTenantId(account.getCompanyIdStr());
//                identityService.saveUser(user);
//
//                if (null != orgMap && null != e.getOrg() && null != orgMap.get(e.getOrg())) {
//                    sysUserRelOrgService.saveRelOrg(su.getId(), orgMap.get(e.getOrg()));
//                }
//                if (null != roleMap && null != e.getRole()) {
//                    String[] roles = e.getRole().trim().split("，|,");
//                    for (String role : roles) {
//                        sysUserRelRoleService.saveRelRole(account.getCompanyId(), su.getId(), roleMap.get(role));
//                    }
//                }
//            }
//        }
        return true;
    }
}
