/**
 * Copyright 2008-2009. Chongqing Communications Industry Services Co.,Ltd Information Technology Branch. All rights reserved. <a>http://www.crunii.com</a>
 */
package com.crunii.micro.service.sysmgr.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.crunii.micro.common.constants.CommonConstants;
import com.crunii.micro.common.constants.RedisKeys;
import com.crunii.micro.common.dto.PageReq;
import com.crunii.micro.common.dto.PageRsp;
import com.crunii.micro.common.dto.Result;
import com.crunii.micro.common.exception.BusinessException;
import com.crunii.micro.common.exception.MicroException;
import com.crunii.micro.common.utils.AESUtil;
import com.crunii.micro.common.utils.NumberUtil;
import com.crunii.micro.common.utils.RSAUtil;
import com.crunii.micro.common.utils.UUIDUtil;
import com.crunii.micro.core.annotation.InjectProperty;
import com.crunii.micro.core.cache.TsmPropertyCache;
import com.crunii.micro.domain.dto.Worker;
import com.crunii.micro.domain.dto.obs.ObsServiceCodeDto;
import com.crunii.micro.domain.entity.main.*;
import com.crunii.micro.domain.repo.main.*;
import com.crunii.micro.domain.util.CurrWorkerUtil;
import com.crunii.micro.feign.client.ObsService;
import com.crunii.micro.feign.client.dto.WorkerC;
import com.crunii.micro.feign.client.dto.WorkerCreateDTO;
import com.crunii.micro.service.sysmgr.api.domain.dto.OrgNode;
import com.crunii.micro.service.sysmgr.api.domain.dto.worker.WorkerRoleVo;
import com.crunii.micro.service.sysmgr.constants.SysmgrConstants;
import com.crunii.micro.service.sysmgr.dto.org.OrgIds;
import com.crunii.micro.service.sysmgr.dto.org.OrgSameLeveDto;
import com.crunii.micro.service.sysmgr.dto.org.TsmOrgDto;
import com.crunii.micro.service.sysmgr.dto.org.TsmWorkerOrgC;
import com.crunii.micro.service.sysmgr.dto.sysmgr.*;
import com.crunii.micro.service.sysmgr.enums.WorkerTypeEnum;
import com.crunii.micro.service.sysmgr.jdbc.OrgJdbcDao;
import com.crunii.micro.service.sysmgr.jdbc.WorkerJdbcDao;
import com.crunii.micro.service.sysmgr.service.AuthService;
import com.crunii.micro.service.sysmgr.service.LoginService;
import com.crunii.micro.service.sysmgr.service.WorkerService;
import com.crunii.micro.service.sysmgr.utils.RandomPasswdUtil;
import com.google.common.base.Joiner;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RMapCache;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.Base64Utils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static com.crunii.micro.common.dto.Result.DEFAULT_ERROR_CODE;
import static com.crunii.micro.service.sysmgr.constants.ErrorMsgConstants.*;
import static com.crunii.micro.service.sysmgr.constants.SysmgrConstants.registrationSystem;

/**
 * @author 田平 create 2018年10月31日下午4:40:16
 */
@Service(value = "workerService")
@Slf4j
public class WorkerServiceImpl implements WorkerService, InitializingBean {

    private static final Pattern pattern = Pattern
            .compile("^(?!.*\\s)(?=.*[a-z])(?=.*[0-9])(?=.*[!@#$%^&*()-+,.<>/?;':\"\\[\\]{}|_~=`]+).{8,16}$");

    private static final String SIGNURL="signUrl";
    private static final int TIMEOUT=120;//签名文件超时时间
    private static String propertyCode="workerDepartment";//所属部门

    @Resource
    private WorkerJdbcDao workerJdbcDao;

    @Resource
    private TsmWorkerRepo tsmWorkerRepo;

    @Resource
    private TsmWorkerRoleRepo tsmWorkerRoleRepo;

    @Resource
    private LoginService loginService;

    @Resource
    private AuthService authService;

    @Resource
    private ObsService obsService;

    @Resource
    private TsmPropertyCache tsmPropertyCache;

    @Resource
    private OrgJdbcDao orgJdbcDao;

    @Resource
    private TsmWorkerOrgAllRepo tsmWorkerOrgAllRepo;

    @Resource
    private TsmWorkerOrgRepo tsmWorkerOrgRepo;

    @Resource
    private TsmOrgRepo tsmOrgRepo;

    @Value("${upload.url}")
    private String urlPrefix;

    private List<String> directlyUnderAuthority = null;

    @Resource
    private TsmPostWorkerRepo tsmPostWorkerRepo;

    @Resource
    private TsmWorkerOrgTemporaryRepo tsmWorkerOrgTemporaryRepo;

    @Resource
    private TsmPostRoleRepo tsmPostRoleRepo;

    @Resource
    private TsmRoleRepo tsmRoleRepo;

    @Resource
    private TsmPropertyValueRepo tsmPropertyValueRepo;

    @Resource
    private TsmWorkerDeliveryAddressRepo tsmWorkerDeliveryAddressRepo;

    @Resource
    private RedissonClient redisson;

    @Override
    public void afterPropertiesSet() throws Exception {
        directlyUnderAuthority = workerJdbcDao.findSubordinateLeagueCodes(SysmgrConstants.DIRECTLY_UNDER_AUTHORITY_LEAGUE_CODE);
        if (Objects.isNull(directlyUnderAuthority)) {
            directlyUnderAuthority = new ArrayList<>();
        }
    }

    @Override
    public List<WorkerInfo> getTsmWorkers(List<Integer> ids) {
        return workerJdbcDao.getTsmWorkers(ids);
    }

    @Override
    public PageRsp<PageWorkerVo> pageOrgWorker(PageReq<PageOrgWorkerDto> req) {
        Worker currWorker = CurrWorkerUtil.getCurrWorker();
        return workerJdbcDao.pageOrgWorker(req, String.valueOf(currWorker.getLoginId()));
    }

    @Override
    public WorkerInfo getWorkerInfo(int loginId) {
        //主要为屏蔽密码关键信息返回前端，形成安全漏洞
        TsmWorker worker = tsmWorkerRepo.getOne(loginId);
        WorkerInfo info = new WorkerInfo();
        BeanUtils.copyProperties(worker, info);
        return info;
    }

    @Override
    public void unlockWebLoginLimit(int loginId) {
        loginService.clearPwdError(loginId);
    }

    @Override
    @InjectProperty
    public PageRsp<WorkerInfo> pageWorker(PageReq<WorkerReq> req) {
        PageRsp<WorkerInfo> workerInfoPageRsp = workerJdbcDao.pageWorker(req);
        List<WorkerInfo> result = workerInfoPageRsp.getResult();
        if (CollectionUtils.isEmpty(result)) {
            return workerInfoPageRsp;
        }

        Map<String, String> names = tsmPropertyValueRepo.findByPropCode(registrationSystem).stream()
                .collect(Collectors.toMap(TsmPropertyValue::getValueCode, TsmPropertyValue::getValueName));
        for (WorkerInfo workerInfo : result) {
            // 静态值可能为空,防止报错手动赋值
            if (Objects.nonNull(workerInfo.getIdentityCategory())) {
                List<TsmPropertyValue> values = tsmPropertyValueRepo.findByPropCodeAndValueCodeAndState("eventsTaskCityIdentityCategory", workerInfo.getIdentityCategory().toString(), 1);
                String value=null;
                if(values.size()>0){
                    TsmPropertyValue propertyValue = values.get(0);
                    if (ObjectUtil.isNotEmpty(propertyValue)){
                        value=propertyValue.getValueName();
                    }
                }
                if (!StringUtils.hasText(value)) {
                    List<TsmPropertyValue> valueList = tsmPropertyValueRepo.findByPropCodeAndValueCodeAndState("eventsTaskCountyIdentityType", workerInfo.getIdentityCategory().toString(), 1);
                    if (valueList.size()>0){
                        TsmPropertyValue tsmPropertyValue = valueList.get(0);
                        if (ObjectUtil.isNotEmpty(tsmPropertyValue)){
                            value=tsmPropertyValue.getValueName();
                        }
                    }
                }
                workerInfo.setIdentityCategoryTrans(value);
            }

            if (Objects.nonNull(workerInfo.getRegistrationSystem())) {
                List<TsmPropertyValue> values = tsmPropertyValueRepo.findByPropCodeAndValueCodeAndState("registrationSystem", workerInfo.getRegistrationSystem().toString(), 1);
                if (values.size() > 0) {
                    TsmPropertyValue propertyValue = values.get(0);
                    if (ObjectUtil.isNotEmpty(propertyValue)) {
                        String value = propertyValue.getValueName();
                        workerInfo.setRegistrationSystemTrans(value);
                    }
                }
            }
            //翻译直属系统
            if (workerInfo.getRegistrationSystem()!=null){
                String name = names.get(workerInfo.getRegistrationSystem().toString());
                workerInfo.setRegistrationSystemTrans(name);
            }
            // 设置头像地址
            if (StringUtils.hasText(workerInfo.getHeadPortraitPicKey())) {
                workerInfo.setFileUrl(urlPrefix + workerInfo.getHeadPortraitPicKey());
            }
            //查询用户职务
            List<WorkerPostVO> postByWorker = workerJdbcDao.findPostByWorker(workerInfo.getLoginId());
            //查询职务关联的角色
            for (WorkerPostVO workerPostVO : postByWorker) {
                List<Integer> roles = tsmPostRoleRepo.findByPostId(workerPostVO.getId()).stream().map(TsmPostRole::getRoleId).collect(Collectors.toList());
                workerPostVO.setRoleList(roles);
            }
            workerInfo.setPosts(postByWorker);
            // 查询角色
            List<TsmWorkerRole> workerRoles = tsmWorkerRoleRepo.findByLoginId((long) workerInfo.getLoginId());
            List<WorkerRoleListRspVo> authRoles=new ArrayList<>();
            getRoleByPost(postByWorker,authRoles);
            getRoleByWorker(workerRoles,authRoles);
            workerInfo.setRoles(authRoles);
            //查询挂职组织
            List<WorkerOrgVO> temporaryWorker = workerJdbcDao.findPostByTemporaryWorker(workerInfo.getLoginId());
            workerInfo.setTemporaryOrgs(temporaryWorker);
        }

        // 设置标签数据
        for (WorkerInfo workerInfo : result) {
            workerInfo.setLabels(workerJdbcDao.getLabelNames(workerInfo.getLoginId()));
        }
        return workerInfoPageRsp;
    }

    @Override
    public String doResetPwd(int loginId) {
        TsmWorker tsmWorker = tsmWorkerRepo.getOne(loginId);
        String passwd = RandomPasswdUtil.generateRandomString(11);
        tsmWorker.setLoginPwd(AESUtil.encrypt(passwd));
        tsmWorkerRepo.save(tsmWorker);
        return passwd;
    }

    @Override
    public Result<String> doModifyPwd(int loginId, String oldPwd, String newPwd) {
        String rOldPwd = RSAUtil.decryptHex(oldPwd);
        String rNewPwd = RSAUtil.decryptHex(newPwd);
        Result<String> result = new Result<>();
        //todo 使用单独的正则表达式无法满足任意3种组合
//        if (!pattern.matcher(rNewPwd).find()) {
//            throw new BusinessException("新密码复杂度检验失败！");
//        }
        if (!isStrongPassword(rNewPwd)) {
            throw new BusinessException("新密码复杂度检验失败！");
        }

        if (rNewPwd.equals(rOldPwd)) {
            throw new BusinessException("新旧密码不能相同！");
        }
        TsmWorker tsmWorker = tsmWorkerRepo.getOne(loginId);
        if (tsmWorker.getLoginPwd().equals(AESUtil.encrypt(rOldPwd))) {
            tsmWorker.setLoginPwd(AESUtil.encrypt(rNewPwd));
            tsmWorkerRepo.save(tsmWorker);
        } else {
            throw new BusinessException("原密码错误！");
        }
        return result;
    }

    @Override
    public WorkerCreateDTO createWorker(WorkerC workerC) {
        TsmWorker byMobile = tsmWorkerRepo.findByMobile(workerC.getMobile());
        if (Objects.nonNull(byMobile)) {
            throw new BusinessException("电话号码已存在！");
        }
        List<TsmWorker> byCodes= tsmWorkerRepo.findByLoginCode(workerC.getLoginCode());
        if (StringUtils.hasText(workerC.getLoginCode()) && !CollectionUtils.isEmpty(byCodes) && byCodes.size() > 0 ) {
            throw new BusinessException("账号: " + byCodes.get(0).getLoginCode() + " 已存在！");
        }
        TsmOrg org = tsmOrgRepo.findOrgById(workerC.getOrgId());
        if (ObjectUtil.isEmpty(org) || org.getState() == 0) {
            throw new BusinessException(ORG_CREATE_ORG_NOT_EXIST);
        }
        Date curr = new Date();
        TsmWorker tsmWorker = new TsmWorker();
        BeanUtils.copyProperties(workerC, tsmWorker);
        tsmWorker.setCreateTime(curr);
        tsmWorker.setLastChgPwdTime(curr);
        tsmWorker.setState(1);
        tsmWorker.setLoginNum(0);
        if (StringUtils.hasText(workerC.getHeadPortraitPicKey())) {
            tsmWorker.setHeadPortraitPicKey(workerC.getHeadPortraitPicKey());
        }
        tsmWorker.setLeagueCode(org.getOrgCode());
        tsmWorker.setOrgId(String.valueOf(org.getOrgId()));
        String passwd = RandomPasswdUtil.generateRandomString(11);
        tsmWorker.setLoginPwd(AESUtil.encrypt(passwd));
        // 如果赋值组织信息 则判断组织类别
        if (StringUtils.hasText(tsmWorker.getOrgId())) {
            Integer registrationSystem = 1;
            if (directlyUnderAuthority.contains(tsmWorker.getOrgId())) {
                registrationSystem = 2;
            }
            tsmWorker.setRegistrationSystem(registrationSystem);
        }
        tsmWorker.setWorkerType(WorkerTypeEnum.WEB.getType());
        tsmWorkerRepo.save(tsmWorker);
        tsmWorkerRepo.flush();
        int loginId = tsmWorker.getLoginId();
        // 添加标签
        workerJdbcDao.workerAddLabel(loginId, workerC.getLabelIds());
        // 赋值角色
        List<Integer> roleIds1 = workerC.getRoleIds();
        if (Objects.isNull(workerC.getRoleIds())) {
            roleIds1 = new ArrayList<>();
        }
        if (roleIds1.contains(SysmgrConstants.DEPARTMENT_AUDIT_PERSON) && roleIds1.contains(SysmgrConstants.SYS_AUDIT_PERSON)) {
            throw new BusinessException(WORKER_TWO_ROLE_EXIST);
        }

        List<TsmWorkerRole> workerRoles = new ArrayList<>();
        savePost(workerC.getTemporaryOrgs(), workerC.getPostIds(), loginId,workerRoles);
        List<Integer> ids = workerRoles.stream().map(TsmWorkerRole::getRoleId).collect(Collectors.toList());
        //过滤掉存在重复的角色
        List<Integer> roleIds = roleIds1.stream().filter(s->!ids.contains(s) && !CommonConstants.COMMON_ROLE_ID.equals(s)).collect(Collectors.toList());
        for (Integer integer : roleIds) {
            TsmWorkerRole workerRole = new TsmWorkerRole();
            workerRole.setLoginId(tsmWorker.getLoginId());
            workerRole.setRoleId(integer);
            workerRole.setSource(1);
            workerRoles.add(workerRole);
        }
        // 默认赋值公共权限
        TsmWorkerRole workerRole = new TsmWorkerRole();
        workerRole.setLoginId(loginId);
        workerRole.setRoleId(CommonConstants.COMMON_ROLE_ID);
        workerRoles.add(workerRole);
        tsmWorkerRoleRepo.saveAllAndFlush(workerRoles);
        // 保存obsCode
        if (Objects.nonNull(workerC.getFileId())) {
            saveObsCode(loginId, workerC.getFileId());
        }
        //固定的线程池（当前线程池大小为5）
       // ExecutorService executor = Executors.newFixedThreadPool(5);
        TsmWorkerOrgC tsmWorkerOrgC = new TsmWorkerOrgC();
        tsmWorkerOrgC.setWorkerId(tsmWorker.getLoginId());
        tsmWorkerOrgC.setOrgId(tsmWorker.getOrgId());
        saveTsmWorkerOrg(tsmWorkerOrgC);
      //  executor.shutdown();
        WorkerCreateDTO workerCreateDTO = new WorkerCreateDTO(loginId, passwd);
        return workerCreateDTO;
    }

    @Override
    public Integer appCreateWorker(WorkerC workerC) {
        TsmWorker byMobile = tsmWorkerRepo.findByMobile(workerC.getMobile());
        if (Objects.nonNull(byMobile)) {
            throw new BusinessException("电话号码已存在！");
        }
        Date curr = new Date();
        TsmWorker tsmWorker = new TsmWorker();
        BeanUtils.copyProperties(workerC, tsmWorker);
        tsmWorker.setCreateTime(curr);
        tsmWorker.setLastChgPwdTime(curr);
        tsmWorker.setState(1);
        tsmWorker.setLoginNum(0);
        if (StringUtils.hasText(workerC.getHeadPortraitPicKey())) {
            tsmWorker.setHeadPortraitPicKey(workerC.getHeadPortraitPicKey());
        }
        tsmWorker.setLeagueCode(null);
//        tsmWorker.setOrgId(null);
        //tsmWorker.setOrgIdNum(workerC.getOrgId());
        tsmWorker.setLoginPwd(AESUtil.encrypt(SysmgrConstants.DEFAULT_PWD));
        // 如果赋值组织信息 则判断组织类别
        if (StringUtils.hasText(tsmWorker.getOrgId())) {
            Integer registrationSystem = 1;
            if (directlyUnderAuthority.contains(tsmWorker.getOrgId())) {
                registrationSystem = 2;
            }
            tsmWorker.setRegistrationSystem(registrationSystem);
        }

        if ("PHONE".equalsIgnoreCase(workerC.getScope())) {
            tsmWorker.setWorkerType(WorkerTypeEnum.APP.getType());
        } else {
            tsmWorker.setWorkerType(WorkerTypeEnum.WEB.getType());
        }

        tsmWorkerRepo.save(tsmWorker);
        tsmWorkerRepo.flush();
        int loginId = tsmWorker.getLoginId();
        // 赋值角色
        List<Integer> roleIds1 = workerC.getRoleIds();
        if (Objects.isNull(workerC.getRoleIds())) {
            roleIds1 = new ArrayList<>();
        }
        if (roleIds1.contains(SysmgrConstants.DEPARTMENT_AUDIT_PERSON) && roleIds1.contains(SysmgrConstants.SYS_AUDIT_PERSON)) {
            throw new BusinessException(WORKER_TWO_ROLE_EXIST);
        }
        List<TsmWorkerRole> workerRoles = new ArrayList<>();
        savePost(workerC.getTemporaryOrgs(), workerC.getPostIds(), loginId,workerRoles);
        List<Integer> ids = workerRoles.stream().map(TsmWorkerRole::getRoleId).collect(Collectors.toList());
        //过滤掉存在重复的角色
        List<Integer> roleIds = roleIds1.stream().filter(s->!ids.contains(s) && !CommonConstants.COMMON_ROLE_ID.equals(s)).collect(Collectors.toList());
        for (Integer integer : roleIds) {
            TsmWorkerRole workerRole = new TsmWorkerRole();
            workerRole.setLoginId(tsmWorker.getLoginId());
            workerRole.setRoleId(integer);
            workerRole.setSource(1);
            workerRoles.add(workerRole);
        }
        // 默认赋值公共权限
        TsmWorkerRole workerRole = new TsmWorkerRole();
        workerRole.setLoginId(loginId);
        workerRole.setRoleId(CommonConstants.COMMON_ROLE_ID);
        workerRoles.add(workerRole);
        tsmWorkerRoleRepo.saveAllAndFlush(workerRoles);
        // 保存obsCode
        if (Objects.nonNull(workerC.getFileId())) {
            saveObsCode(loginId, workerC.getFileId());
        }
        if(StringUtils.hasText(tsmWorker.getOrgId())){
            TsmWorkerOrgC tsmWorkerOrgC = new TsmWorkerOrgC();
            tsmWorkerOrgC.setWorkerId(tsmWorker.getLoginId());
            tsmWorkerOrgC.setOrgId(tsmWorker.getOrgId());
            saveTsmWorkerOrg(tsmWorkerOrgC);
        }
        return loginId;
    }

    @Override
    public Integer createWorkerInfo(WorkerC workerC) {
        TsmWorker byMobile = tsmWorkerRepo.findByMobile(workerC.getMobile());
        if (Objects.nonNull(byMobile)) {
            return byMobile.getLoginId();
        } else {
            return createWorker(workerC).getLoginId();
        }
    }

    /**
     * 保存obs
     */
    private void saveObsCode(int loginId, Long fileId) {
        List<ObsServiceCodeDto> list = new ArrayList<>();
        ObsServiceCodeDto obsServiceCodeDto = new ObsServiceCodeDto();
        obsServiceCodeDto.setFileId(fileId);
        obsServiceCodeDto.setServiceId((long) loginId);
        obsServiceCodeDto.setServiceCode(CommonConstants.OBS_FILE_HEAD_PIC);
        list.add(obsServiceCodeDto);
        obsService.updateObsServiceCode(list);
    }

    @Override
    public void updateWorker(WorkerU workerU, String mobile, String token) {
        if (workerU.getMobile().equals(mobile)) {
            if (workerU.getState() == 0) {
                throw new BusinessException("状态不可更改！");
            }
        }
        Date date = new Date();
        Date birthday = workerU.getBirthday();
        int compare = DateUtil.compare(date, birthday);
        if (compare != 1) {
            throw new BusinessException("出生日期不能大于当前时间");
        }
        List<Integer> roleIds1 = workerU.getRoleIds();
        if (roleIds1.contains(SysmgrConstants.DEPARTMENT_AUDIT_PERSON) && roleIds1.contains(SysmgrConstants.SYS_AUDIT_PERSON)) {
            throw new BusinessException(WORKER_TWO_ROLE_EXIST);
        }
        TsmOrg org = tsmOrgRepo.findOrgById(workerU.getOrgId());
        if (ObjectUtil.isEmpty(org) || org.getState() == 0) {
            throw new BusinessException(ORG_CREATE_ORG_NOT_EXIST);
        }
        //校验手机号是否重复
        if (StringUtils.hasText(workerU.getMobile())){
            List<TsmWorker> workers = tsmWorkerRepo.findAllWorkerByMobile(workerU.getMobile(), workerU.getLoginId());
            if (workers.size()>0){
                throw new BusinessException(WORKER_MOBILE_ISEXISTS);
            }
        }
        //校验用户code是否重复
        List<TsmWorker> byCodes= tsmWorkerRepo.findByLoginCodeNotSelf(workerU.getLoginCode(),workerU.getLoginId());
        if (StringUtils.hasText(workerU.getLoginCode()) && !CollectionUtils.isEmpty(byCodes) && byCodes.size() > 0 ) {
            throw new BusinessException("账号: " + byCodes.get(0).getLoginCode() + " 已存在！");
        }
        TsmWorker tsmWorker = tsmWorkerRepo.getOne(workerU.getLoginId());
        String orgId = tsmWorker.getOrgId();
        BeanUtils.copyProperties(workerU, tsmWorker);
        tsmWorker.setLeagueCode(org.getOrgCode());
        tsmWorker.setOrgId(String.valueOf(org.getOrgId()));
        if (StringUtils.hasText(workerU.getHeadPortraitPicKey())) {
            tsmWorker.setHeadPortraitPicKey(workerU.getHeadPortraitPicKey());
        }
        tsmWorkerRepo.save(tsmWorker);
        // 修改标签
        workerJdbcDao.workerUpdateLabel(workerU.getLoginId(), workerU.getLabelIds());
        // 删除角色，除公共角色
        workerJdbcDao.delRoleByLoginId(workerU.getLoginId());
        List<TsmWorkerRole> workerRoles = new ArrayList<>();
        //保存用户与职务关联关系
        savePost(workerU.getTemporaryOrgs(), workerU.getPostIds(), workerU.getLoginId(),workerRoles);
        List<Integer> ids = workerRoles.stream().map(TsmWorkerRole::getRoleId).collect(Collectors.toList());
        //过滤掉存在重复的角色
        List<Integer> roleIds = workerU.getRoleIds().stream().filter(s->!ids.contains(s) && !CommonConstants.COMMON_ROLE_ID.equals(s)).collect(Collectors.toList());
        for (Integer integer : roleIds) {
            TsmWorkerRole workerRole = new TsmWorkerRole();
            workerRole.setLoginId(workerU.getLoginId());
            workerRole.setRoleId(integer);
            workerRole.setSource(1);
            workerRoles.add(workerRole);
        }
        tsmWorkerRoleRepo.saveAllAndFlush(workerRoles);
        if(StringUtils.hasText(orgId)){
            if (!orgId.equals(workerU.getOrgId())) {
                TsmWorkerOrgC tsmWorkerOrgC = new TsmWorkerOrgC();
                tsmWorkerOrgC.setWorkerId(workerU.getLoginId());
                tsmWorkerOrgC.setOrgId(workerU.getOrgId());
                saveTsmWorkerOrg(tsmWorkerOrgC);
            }
        } else {
            if(StringUtils.hasText(workerU.getOrgId())){
                TsmWorkerOrgC tsmWorkerOrgC = new TsmWorkerOrgC();
                tsmWorkerOrgC.setWorkerId(workerU.getLoginId());
                tsmWorkerOrgC.setOrgId(workerU.getOrgId());
                saveTsmWorkerOrg(tsmWorkerOrgC);
            }
        }
        // 保存obs
        saveObsCode(tsmWorker.getLoginId(), workerU.getFileId());
        // 前端需更新用户信息，删除token，跳入登录页
//        if (workerU.getMobile().equals(mobile)) {
//            loginService.doLogout(token);
//        }

    }

    private void saveTsmWorkerOrg(TsmWorkerOrgC tsmWorkerOrgC) {
        //先删除旧的权限组织
        orgJdbcDao.deleteWorkerOrgAllByUserId(Collections.singletonList(tsmWorkerOrgC.getWorkerId()), 1);
        /** 固定的线程池（当前线程池大小为5） */
        ExecutorService executor = Executors.newFixedThreadPool(5);
        //根据组织递归查询所有下级组织
        if (tsmWorkerOrgC.getOrgId() != null) {
            executor.submit(() -> {
                //插入下级递归组织
                orgJdbcDao.updateCreateTsmWorkerOrgAll(tsmWorkerOrgC.getOrgId(),tsmWorkerOrgC.getWorkerId(), tsmWorkerOrgC.getWorkerId());
                //先删除旧的权限组织
                orgJdbcDao.deleteWorkerOrgByUserId(Collections.singletonList(tsmWorkerOrgC.getWorkerId()), 1);
                TsmOrg org = tsmOrgRepo.getOne(Long.valueOf(tsmWorkerOrgC.getOrgId()));
                //初始化tsm_worker_org表
                TsmWorkerOrg tsmWorkerOrg = new TsmWorkerOrg();
                tsmWorkerOrg.setWorkerId(Long.valueOf(tsmWorkerOrgC.getWorkerId()));
                tsmWorkerOrg.setOrgId(org.getOrgId());
                tsmWorkerOrg.setOrgCode(org.getOrgCode());
                tsmWorkerOrg.setCreateUserId(Long.valueOf(tsmWorkerOrgC.getWorkerId()));
                tsmWorkerOrg.setCreateTime(new Date());
                tsmWorkerOrg.setRecursiveOrNot(1L);
                tsmWorkerOrgRepo.save(tsmWorkerOrg);
                tsmWorkerOrgRepo.flush();
            });
            executor.shutdown();
        }
    }

    /**
     * 查询数据权限下用户
     */
    @Override
    public Result<List<WorkerListRspDto>> getOrgManageWorker(WorkerManageReq req) {
        return new Result<>(workerJdbcDao.findWorkerByRestricted(req));
    }

    @Override
    public Result<String> createTsmWorkerOrgAll(Worker worker, TsmWorkerOrgAllReqDto workerAndOrgIdsDto) {
        if (org.apache.commons.collections.CollectionUtils.isEmpty(workerAndOrgIdsDto.getUserId())) {
            return new Result<>(false, Result.DEFAULT_ERROR_CODE, "用户不能为空！");
        }
        if (org.apache.commons.collections.CollectionUtils.isEmpty(workerAndOrgIdsDto.getOrgIdList())) {
            return new Result<>(false, Result.DEFAULT_ERROR_CODE, "组织不能为空！");
        }
        for (Integer userId : workerAndOrgIdsDto.getUserId()) {
            if (workerAndOrgIdsDto.getRecursiveOrNot() == 1) {
                //先删除旧的权限组织
                orgJdbcDao.deleteWorkerOrgByUserId(workerAndOrgIdsDto.getUserId(), 1);
                //先删除旧的权限组织
                orgJdbcDao.deleteWorkerOrgAllByUserId(workerAndOrgIdsDto.getUserId(), 1);
                List<TsmWorkerOrg> tsmWorkerOrgs = new ArrayList<>();
                for (Long orgId : workerAndOrgIdsDto.getOrgIdList()) {
                    TsmWorkerOrg tsmWorkerOrg = new TsmWorkerOrg();
                    TsmOrg org = WorkerServiceImpl.this.tsmOrgRepo.getOne(orgId);
                    if (null != org) {
                        tsmWorkerOrg.setWorkerId(Long.valueOf(userId));
                        tsmWorkerOrg.setOrgId(orgId);
                        tsmWorkerOrg.setOrgCode(org.getOrgCode());
                        tsmWorkerOrg.setCreateUserId(Long.valueOf(worker.getLoginId()));
                        tsmWorkerOrg.setCreateTime(new Date());
                        tsmWorkerOrg.setRecursiveOrNot(1L);
                        tsmWorkerOrgs.add(tsmWorkerOrg);
                    }
                }
                tsmWorkerOrgRepo.saveAll(tsmWorkerOrgs);
                tsmWorkerOrgRepo.flush();
                //插入下级递归组织
                orgJdbcDao.updateTsmWorkerOrgAll(workerAndOrgIdsDto.getOrgIdList(),worker.getLoginId(), userId);
            }
            //不递归
            else if (workerAndOrgIdsDto.getRecursiveOrNot() == 2) {
                //先删除旧的权限组织
                orgJdbcDao.deleteWorkerOrgByUserId(workerAndOrgIdsDto.getUserId(), 2);
                //先删除旧的权限组织
                orgJdbcDao.deleteWorkerOrgAllByUserId(workerAndOrgIdsDto.getUserId(), 2);
                List<TsmWorkerOrg> tsmWorkerOrgs = new ArrayList<>();
                for (Long orgId : workerAndOrgIdsDto.getOrgIdList()) {
                    TsmWorkerOrg tsmWorkerOrg = new TsmWorkerOrg();
                    TsmOrg org = WorkerServiceImpl.this.tsmOrgRepo.getOne(orgId);
                    if (null != org) {
                        tsmWorkerOrg.setWorkerId(Long.valueOf(userId));
                        tsmWorkerOrg.setOrgId(orgId);
                        tsmWorkerOrg.setOrgCode(org.getOrgCode());
                        tsmWorkerOrg.setCreateUserId(Long.valueOf(worker.getLoginId()));
                        tsmWorkerOrg.setCreateTime(new Date());
                        tsmWorkerOrg.setRecursiveOrNot(2L);
                        tsmWorkerOrgs.add(tsmWorkerOrg);
                    }
                }
                tsmWorkerOrgRepo.saveAll(tsmWorkerOrgs);
                tsmWorkerOrgRepo.flush();
                List<Long> orgList = workerAndOrgIdsDto.getOrgIdList();
                List<TsmOrg> allOrgList = orgJdbcDao.findByOrgIds(orgList);
                List<TsmWorkerOrgAll> tsmWorkerOrgAll = new ArrayList<>();
                for (TsmOrg tsmOrg : allOrgList) {
                    TsmWorkerOrgAll entity = new TsmWorkerOrgAll();
                    entity.setWorkerId(Long.valueOf(userId));
                    entity.setOrgId(tsmOrg.getOrgId());
                    entity.setOrgCode(tsmOrg.getOrgCode());
                    entity.setCreateUserId(Long.valueOf(worker.getLoginId()));
                    entity.setCreateTime(new Date());
                    entity.setRecursiveOrNot(2L);
                    tsmWorkerOrgAll.add(entity);
                }
                //保存新的权限组织到tsm_worker_org_all
                tsmWorkerOrgAllRepo.saveAll(tsmWorkerOrgAll);
                tsmWorkerOrgAllRepo.flush();
            }
        }
        return new Result<>("修改成功！", true);
    }

    /**
     * 递归查询组织机构的所有下级id
     *
     * @param orgList
     * @param orgId
     * @return
     */
    private void listChildOrg(List<Long> orgList, String orgId) {
        List<TsmOrg> orgs = orgJdbcDao.listByParentOrgIds(orgId);
        if (orgs.size() > 0) {
            List<Long> orgIds = orgs.stream().map(TsmOrg::getOrgId).collect(Collectors.toList());
            orgList.addAll(orgIds);
            String strOrgIds = Joiner.on(",").join(orgIds);
            this.listChildOrg(orgList, strOrgIds);
        }
    }

    @Override
    public Result<WorkerOrgAllDto> getTsmWorkerOrgAll(Worker worker, OrgIds req) {
        List<TsmOrgDto> orgManageList = orgJdbcDao.getOrgManageByUserId(req);
        List<TsmOrg> dtos = new ArrayList<>();
        dtos.addAll(orgManageList);
//        for (TsmOrg orgManage : orgManageList) {
//            // 递归查询所有下级组织
//            List<Long> orgList = new ArrayList<>();
//            orgList.add(orgManage.getOrgId());
//            listChildOrg(orgList, String.valueOf(orgManage.getOrgId()));
//        }
//        List<Long> halfOrgIds = new ArrayList<>();
//        orgJdbcDao.listParentOrg(halfOrgIds, dtos.stream().map(TsmOrg::getOrgId).collect(Collectors.toList()));
//        halfOrgIds = halfOrgIds.stream().distinct().collect(Collectors.toList()); // 去重
        dtos = dtos.stream().distinct().collect(Collectors.toList()); // 去重
        // 5、返回数据
        WorkerOrgAllDto result = new WorkerOrgAllDto();
        result.setCheckedOrg(dtos);
//        result.setHalfCheckedOrg(halfOrgIds);
        return new Result<>(result);
    }

    @Override
    public Result<List<TsmOrg>> getOrgByOrgId(Worker worker, OrgIds param) {
        List<Long> sameLeveDtos = getSuperstratumOrg(param.getOrgIds(), param.getUserId()); // 根据条件获取组织
        return new Result<>(this.orgJdbcDao.findByOrgIds(sameLeveDtos));
    }

    @Override
    public Result<List<WorkerRoleVo>> getRoleListByWorkerId(Long workerId) {
        List<WorkerRoleVo> list = new ArrayList<>();
        for (TsmWorkerRole tsmWorkerRole : tsmWorkerRoleRepo.findByLoginId(workerId)) {
            WorkerRoleVo workerRoleVo = new WorkerRoleVo();
            workerRoleVo.setRoleId((long) tsmWorkerRole.getRoleId());
            list.add(workerRoleVo);
        }
        return new Result<>(list);
    }

    private List<Long> getSuperstratumOrg(List<Long> orgIds, Integer userId) {
        // userId为空则是批量修改，不为空则为单个修改
//		if (userId != null) {
//			// 单个修改要把用户组织带进去
//			TsmWorker tsmWorker = this.tsmWorkerRepo.getOne(userId);
//			orgIds.add(Long.valueOf(tsmWorker.getOrgId()));
//			this.listChildOrg(orgIds, String.valueOf(tsmWorker.getOrgId()));
//		}
        List<OrgSameLeveDto> sameLeveDtos = orgJdbcDao.getSameLevelOrg(orgIds);
        List<TsmOrg> allOrg = new ArrayList<>();
        for (int i = 0; i < orgIds.size(); i++) {
            TsmOrg entity = tsmOrgRepo.getOne(orgIds.get(i));
            allOrg.add(entity);
        }
//		List<TsmOrg> allOrg = this.tsmOrgRepo.findAll(); // 先查询所有组织，防止每次查库降低效率
        List<Long> endOrg = new ArrayList<>();
        // 1、首先遍历前端传来的所有组织
        for (OrgSameLeveDto dto : sameLeveDtos) {
            List<Long> finalOrgIds = orgIds;
            // 1-1、所有下级组织id
            List<Long> sameOrgIds = Arrays.stream(dto.getSameLeveOrgIds().split(",")).map(Long::parseLong).collect(Collectors.toList());
            // 2、判断同级所有组织，前端是否传过来
            List<Long> diffOrgIds = sameOrgIds.stream().filter(item -> !finalOrgIds.contains(item)).collect(Collectors.toList());
            if (dto.getParentOrgId().equals(0)) { // 根级组织直接返回
                endOrg.add(dto.getOrgId());
            } else if (diffOrgIds.size() > 0) {// 至少有一个同级不存在
                endOrg.add(dto.getOrgId());
            } else { //所有同级都存在
                // 3、判断父级组织前端是否传来
                if (finalOrgIds.contains(dto.getParentOrgId())) { // 父级id存在则不需要返回父级id
                    List<Long> allSubOrg = new ArrayList<>(); // 同级已经判断，只需要判断所有下级
                    listChildOrg1(allOrg, allSubOrg, dto.getSameLeveOrgIds());// 递归查询
                    List<Long> allSubOrgIsExist = allSubOrg.stream().filter(item -> !finalOrgIds.contains(item)).collect(Collectors.toList());
                    // 3-1、父级传过来时只需要返回本身，并判断下级组织
                    if (allSubOrg.size() > 0 && allSubOrgIsExist.size() > 0) { // 所有下级至少有一个同级不存在
                        endOrg.add(dto.getOrgId());
                    }
                } else if (dto.getParentOrgId()==0){//如果处于最大级别的组织则返回当前选择组织
                    endOrg.add(dto.getOrgId());
                } else { // 父级id不存在
                    List<Long> allSubOrg = new ArrayList<>(); // 同级已经判断，只需要判断所有下级
                    listChildOrg1(allOrg, allSubOrg, dto.getSameLeveOrgIds());// 递归查询
                    List<Long> allSubOrgIsExist = allSubOrg.stream().filter(item -> !finalOrgIds.contains(item)).collect(Collectors.toList());
                    if (allSubOrg.size() == 0) { // 没有下级
                        endOrg.add(dto.getParentOrgId());
                    } else if (allSubOrgIsExist.size() > 0) { // 所有下级至少有一个同级不存在
                        endOrg.add(dto.getOrgId());
                    } else { //所有子集都包含于orgIds
                        endOrg.add(dto.getParentOrgId());
                    }
                }
            }
        }
        return endOrg;
    }

    /**
     * 关联职务
     *
     * @param postIds
     * @param loginId
     */
    private void savePost(List<Long> temporaryOrgs, List<Long> postIds, int loginId,List<TsmWorkerRole> workerRoles) {
        Set<Integer>allPostAndRoles=new HashSet<>();
        List<Integer> roleIds = workerRoles.stream().map(TsmWorkerRole::getRoleId).collect(Collectors.toList());
        //保存挂职组织
        tsmWorkerOrgTemporaryRepo.deletePostByWorker((long) loginId);
        if (ObjectUtil.isNotEmpty(temporaryOrgs)) {
            for (Long orgId : temporaryOrgs) {
                TsmWorkerOrgTemporary tsmWorkerOrgTemporary = new TsmWorkerOrgTemporary();
                tsmWorkerOrgTemporary.setLoginId(loginId);
                tsmWorkerOrgTemporary.setOrgId(orgId);
                tsmWorkerOrgTemporaryRepo.saveAndFlush(tsmWorkerOrgTemporary);
            }
        }

        //保存关联职务
        //先删除关联职务
        tsmPostWorkerRepo.deletePostByWorker((long) loginId);
        //关联职务
        if (ObjectUtil.isNotEmpty(postIds)) {
            for (Long postId : postIds) {
                TsmPostWorker tsmPostWorker = new TsmPostWorker();
                tsmPostWorker.setWorkerId((long) loginId);
                tsmPostWorker.setPostId((postId));
                tsmPostWorkerRepo.saveAndFlush(tsmPostWorker);
                //将职务关联的角色存入角色列表
                List<Integer> postAndRoles = tsmPostRoleRepo.findByPostId(postId).stream().map(TsmPostRole::getRoleId).filter(s->!roleIds.contains(s)).collect(Collectors.toList());
                allPostAndRoles.addAll(postAndRoles);
            }
            for (Integer postAndRole : allPostAndRoles) {
                TsmWorkerRole tsmWorkerRole=new TsmWorkerRole();
                tsmWorkerRole.setLoginId(loginId);
                tsmWorkerRole.setRoleId(postAndRole);
                tsmWorkerRole.setSource(2);
                workerRoles.add(tsmWorkerRole);
            }
        }
    }

    /**
     * 查询职务关联角色
     * @param postByWorker
     * @param workerRoles
     */
    private void getRoleByPost(List<WorkerPostVO> postByWorker, List<WorkerRoleListRspVo> workerRoles) {
        Set<Integer>allPostRoles=new HashSet<>();
        for (WorkerPostVO workerPostVO : postByWorker) {
            List<Integer> postRoles = tsmPostRoleRepo.findByPostId(workerPostVO.getId()).stream().map(TsmPostRole::getRoleId).collect(Collectors.toList());
            allPostRoles.addAll(postRoles);
        }
        for (Integer roleId : allPostRoles) {
            WorkerRoleListRspVo roleListRspVo = new WorkerRoleListRspVo();
            TsmRole role = tsmRoleRepo.getOne(roleId);
            if (ObjectUtil.isNotEmpty(role) && StringUtils.hasText(role.getRoleName()) && role.getState() == 1 && !CommonConstants.COMMON_ROLE_ID.equals(role.getRoleId())) {
                BeanUtils.copyProperties(role, roleListRspVo);
                roleListRspVo.setWhetherUpdate(false);
                workerRoles.add(roleListRspVo);
            }
        }
    }

    /**
     * 根据用户查询角色
     * @param workerRoles
     * @param authRoles
     */
    private void getRoleByWorker(List<TsmWorkerRole> workerRoles, List<WorkerRoleListRspVo> authRoles) {
        List<Integer> roleIds = authRoles.stream().map(WorkerRoleListRspVo::getRoleId).collect(Collectors.toList());
        for (TsmWorkerRole workerRole : workerRoles) {
            if (ObjectUtil.isNotEmpty(workerRole.getRoleId())){
                TsmRole role = tsmRoleRepo.getOne(workerRole.getRoleId());
                if (ObjectUtil.isNotEmpty(role) && StringUtils.hasText(role.getRoleName()) && role.getState()==1
                        && !roleIds.contains(role.getRoleId()) && !CommonConstants.COMMON_ROLE_ID.equals(role.getRoleId())){
                    WorkerRoleListRspVo workerRoleListRspVo=new WorkerRoleListRspVo();
                    BeanUtils.copyProperties(role,workerRoleListRspVo);
                    workerRoleListRspVo.setWhetherUpdate(true);
                    authRoles.add(workerRoleListRspVo);
                }
            }
        }
    }


    /**
     * 递归获取子集组织
     *
     * @param allOrg
     * @param orgList
     * @param strOrgId
     */
    private void listChildOrg1(List<TsmOrg> allOrg, List<Long> orgList, String strOrgId) {
        List<String> orgId = Arrays.asList(strOrgId.split(","));
        List<TsmOrg> orgs = allOrg.stream().filter(o -> orgId.contains(String.valueOf(o.getParentOrgId()))).collect(Collectors.toList());
        if (orgs.size() > 0) {
            List<Long> orgIds = orgs.stream().map(TsmOrg::getOrgId).collect(Collectors.toList());
            orgList.addAll(orgIds);
            this.listChildOrg1(allOrg, orgList, Joiner.on(",").join(orgIds));
        }
    }

    @Override
    public Result<List<OrgNode>> getOrgListByWorkerId(Long workerId) {
        if (workerId == null) {
            throw new MicroException(DEFAULT_ERROR_CODE, ORG_CREATE_REQUEST_NOT_NULL);
        }
        TsmWorker tsmWorker = tsmWorkerRepo.getOne(workerId.intValue());
        TsmOrg tsmOrg = tsmOrgRepo.findOrgById(tsmWorker.getOrgId());
        OrgNode orgNode = Convert.convert(OrgNode.class, tsmOrg);
        return new Result<>(Collections.singletonList(orgNode));
    }

    /**
     * 标签数据分页查询
     * @return
     */
    @Override
    public PageRsp<LabelResp> pageLabel(PageReq<LabelReq> req) {
        return workerJdbcDao.pageLabel(req);
    }

    /**
     *用户-保存签名
     * @param reqVo
     * @return
     */
    @Override
    public Boolean doSignature(Worker worker,WorkerSignatureReqVo reqVo) {
        TsmWorker user = tsmWorkerRepo.getOne(worker.getLoginId());
        if (!StringUtils.hasText(reqVo.getWorkerName())){
            throw new BusinessException(WORKER_SIGN_WORKER_NAME_IS_NULL);
        }
        if (!StringUtils.hasText(reqVo.getSignatureFileId())){
            throw new BusinessException(WORKER_SIGN_FILE_IS_NULL);
        }
        if (ObjectUtil.isNotEmpty(user)){
            user.setSignatureFileId(reqVo.getSignatureFileId());
            user.setSignatureUrl(reqVo.getSignatureUrl());
            user.setWorkerName(reqVo.getWorkerName());
            tsmWorkerRepo.save(user);
            return true;
        }
        return false;
    }

    /**
     * 生成签名二维码
     *
     * @param worker
     * @return
     */
    @Override
    public QrCodeRspVo getSignQrCode(Worker worker) {
        QrCodeRspVo qrCodeF = new QrCodeRspVo();
       //二维码内含链接
        String text = null;
        List<TsmPropertyValue> values = tsmPropertyValueRepo.findAllByPropCodeAndState(SIGNURL, 1);
        if (values.size()>0){
            TsmPropertyValue tsmPropertyValue = values.get(0);
            text =tsmPropertyValue.getValueCode()+"/#/signature?userId="+worker.getLoginId();
        }
        if (!StringUtils.hasText(text)){
            throw new BusinessException(WORKER_SIGN_SET_ERROR);
        }
        //二维码唯一标识
        String qrIdentifier = UUIDUtil.getUUID();
        QRCodeWriter qrCodeWriter = new QRCodeWriter();
        BitMatrix bitMatrix = null;
        Hashtable hints = new Hashtable();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);// H最高容错等级
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        ByteArrayOutputStream pngOutputStream = new ByteArrayOutputStream();
        // 设置对应参数,生成二维码,并转化为base64,qrCodeMsg是二维码包含的内容
        try {
            bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, 300, 300, hints);
            MatrixToImageWriter.writeToStream(bitMatrix, "PNG", pngOutputStream);
        } catch (WriterException | IOException e) {
            log.info("用户:{},生成签名二维码失败",worker);
            e.printStackTrace();
        }
        String qrCode = Base64Utils.encodeToString(pngOutputStream.toByteArray());
        qrCodeF.setQrCode(qrCode);
        qrCodeF.setQrIdentifier(qrIdentifier);
        qrCodeF.setCreateTime(new Date());
        return qrCodeF;
    }

    /**
     * 签名提交接口(App)
     * @param signSubmitReqVo
     * @return
     */
    @Override
    public void doSubmitSign(SignSubmitReqVo signSubmitReqVo) {
        if (!StringUtils.hasText(signSubmitReqVo.getFileId())){
            throw new BusinessException(WORKER_SIGN_FILE_APP_IS_NULL);
        }
        if (!StringUtils.hasText(signSubmitReqVo.getUserId())){
            throw new BusinessException(REQUEST_ERROR);
        }
        //写入缓存
        RMapCache<String, String> captchaMap = redisson.getMapCache(RedisKeys.SIGN_KEY);
        log.info("原始签名map:{}",captchaMap);
        captchaMap.put(signSubmitReqVo.getUserId(), signSubmitReqVo.getFileId(), TIMEOUT, TimeUnit.SECONDS);
        log.info("新增签名后map:{}",captchaMap);
    }

    /**
     * 保存邮寄地址
     * @param reqVo
     * @return
     */
    @Override
    public Boolean doSaveDeliveryAddress(Worker worker,DeliveryAddressReqVo reqVo) {
        TsmWorkerDeliveryAddress tsmWorkerDeliveryAddress=new TsmWorkerDeliveryAddress();
        //校验手机号
        if (!StringUtils.hasText(reqVo.getConsigneePhone())){
            throw new BusinessException(DELIVERY_PHONE_IS_NULL);
        }
        if (!NumberUtil.isMobile(reqVo.getConsigneePhone())){
            throw new BusinessException(DELIVERY_PHONE_ERROR);
        }
        //校验邮编
        if (StringUtils.hasText(reqVo.getPostalCode()) && !NumberUtil.isPostalCode(reqVo.getPostalCode())){
            throw new BusinessException(DELIVERY_POSTALCODE_ERROR);
        }
        TsmWorkerDeliveryAddress one = tsmWorkerDeliveryAddressRepo.findByWorkerId(worker.getLoginId());
        if (ObjectUtil.isNotEmpty(one)){
            BeanUtil.copyProperties(reqVo,one,"id");
            one.setUpdateBy(worker.getWorkerName());
            one.setUpdateId((long)worker.getLoginId());
            one.setUpdateTime(new Date());
            tsmWorkerDeliveryAddressRepo.saveAndFlush(one);
        }else {
            tsmWorkerDeliveryAddress.setWorkerId(worker.getLoginId());
            tsmWorkerDeliveryAddress.setConsigneeName(reqVo.getConsigneeName());
            tsmWorkerDeliveryAddress.setConsigneePhone(reqVo.getConsigneePhone());
            tsmWorkerDeliveryAddress.setConsigneeAddress(reqVo.getConsigneeAddress());
            tsmWorkerDeliveryAddress.setPostalCode(reqVo.getPostalCode());
            tsmWorkerDeliveryAddress.setCreateId((long)worker.getLoginId());
            tsmWorkerDeliveryAddress.setCreateTime(new Date());
            tsmWorkerDeliveryAddress.setCreateBy(worker.getWorkerName());
            tsmWorkerDeliveryAddressRepo.saveAndFlush(tsmWorkerDeliveryAddress);

        }
        return true;
    }

    /**
     * 查询邮寄地址
     * @param worker
     * @return
     */
    @Override
    public DeliveryAddressReqVo getDeliveryAddress(Worker worker) {
        DeliveryAddressReqVo deliveryAddressReqVo=new DeliveryAddressReqVo();
        TsmWorkerDeliveryAddress one = tsmWorkerDeliveryAddressRepo.findByWorkerId(worker.getLoginId());
        if (ObjectUtil.isNotEmpty(one)){
            deliveryAddressReqVo.setConsigneeAddress(one.getConsigneeAddress());
            deliveryAddressReqVo.setConsigneePhone(one.getConsigneePhone());
            deliveryAddressReqVo.setConsigneeName(one.getConsigneeName());
            deliveryAddressReqVo.setPostalCode(one.getPostalCode());
        }
        return deliveryAddressReqVo;
    }

    /**
     * 查询APP提交的签名文件(轮询)
     * @param worker
     * @return
     */
    @Override
    public String getSignFile(Worker worker) {
        if (redisson==null){
            throw new BusinessException("redis异常");
        }
        RMapCache<String, String> captchaMap = redisson.getMapCache(RedisKeys.SIGN_KEY);
        String file = captchaMap.get(String.valueOf(worker.getLoginId()));
        if (StringUtils.hasText(file)){
            captchaMap.remove(Integer.toString(worker.getLoginId()));
        }
        log.info("签名文件:{}",file);
        return file;
    }

    /**
     * 查询组织下用户
     * @param req
     * @return
     */
    @Override
    public Result<List<WorkerListRspDto>> getWorkerByOrgId(WorkerManageReq req) {
        TsmOrg tsmOrg = tsmOrgRepo.getOne(req.getOrgId());
        if (ObjectUtil.isEmpty(tsmOrg) || tsmOrg.getState()==0){
            throw new BusinessException(ORG_CREATE_ORG_NOT_EXIST);
        }
        if (tsmOrg.getParentOrgId()!=null){
            req.setParentOrgId(tsmOrg.getParentOrgId());
        }
        return Result.ofSuccess(workerJdbcDao.getWorkerByOrgId(req));
    }

    public static void main(String[] args) {
//        String rNewPwd = RSAUtil.decryptHex("6C5642624339772B3050334C704930363242486E34502F7377626B7243744C3079375451424A59562B7A497771303575734230467A73627743365979725251562F784662625958387959594C4F6D6F4D4D31544B7675667748572F47593873536C4E52677430676E43663161525735597874596F694963706D686151686E35636E4A633141593854794B4C356664535777474B632F47356C2F484B52656E6A6B785732664768744E6857383D&oldPwd=756C54766C67307A503555635073474F6F797559694C3774616E6D305447412B784856706E624332364D345463334C617A2B6B516A6A2F4F7038574C586F6469326F346551496A774943474D435455306373554B717A31516973564C5A314F4F6B5A5A7070346E302F355A4C414537416F4E61454A345871723033785668547735376C6B537668737462784136725945766B746577476B7A3045564D4F64774652714244316E68776335553D");
        if (!isStrongPassword("12l456123+")) {
            throw new BusinessException("新密码复杂度检验失败！");
        }
    }

    public static boolean isStrongPassword(String password) {
        int typesCount = 0;

        if (password.matches(".*[A-Z].*")) {
            typesCount++;
        }
        if (password.matches(".*[a-z].*")) {
            typesCount++;
        }
        if (password.matches(".*[0-9].*")) {
            typesCount++;
        }
        if (password.matches(".*[!@#$%^&*()-+,.<>/?;':\"\\[\\]{}|_~=`].*")) {
            typesCount++;
        }
        boolean containsChinese = false;
        for (char c : password.toCharArray()) {
            if (Character.UnicodeBlock.of(c) == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS) {
                containsChinese = true;
                break;
            }
        }

        if (!containsChinese) {
            typesCount++;
        }

        return typesCount >= 4 && password.length() >= 8 && password.length() <= 16;
    }
    
    @Override
    public Integer createWorkerCustomPwd(WorkerC workerC) {
        if (!StringUtils.hasText(workerC.getLoginCode())) {
            throw new BusinessException("用户名为空！");
        }
        if (!StringUtils.hasText(workerC.getOrgId())) {
            throw new BusinessException("组织为空！");
        }
        if (!StringUtils.hasText(workerC.getLoginPwd())) {
            throw new BusinessException("密码为空！");
        }
        List<TsmWorker> byCodes= tsmWorkerRepo.findByLoginCode(workerC.getLoginCode());
        if (!CollectionUtils.isEmpty(byCodes) && byCodes.size() > 0 ) {
            throw new BusinessException("用户名 " + byCodes.get(0).getLoginCode() + " 已存在！");
        }
        // 调用完此方法，会同步创建组织，故去掉此校验
       /* TsmOrg org = tsmOrgRepo.findOrgById(workerC.getOrgId());
        if (ObjectUtil.isEmpty(org) || org.getState() == 0) {
            throw new BusinessException(ORG_CREATE_ORG_NOT_EXIST);
        }*/
        Date curr = new Date();
        TsmWorker tsmWorker = new TsmWorker();
        BeanUtils.copyProperties(workerC, tsmWorker);
        tsmWorker.setCreateTime(curr);
        tsmWorker.setLastChgPwdTime(curr);
        tsmWorker.setState(1);
        tsmWorker.setLoginNum(0);
        if (StringUtils.hasText(workerC.getHeadPortraitPicKey())) {
            tsmWorker.setHeadPortraitPicKey(workerC.getHeadPortraitPicKey());
        }
        tsmWorker.setLeagueCode(workerC.getOrgCode());
        tsmWorker.setOrgId(workerC.getOrgId());
        String passwd = workerC.getLoginPwd();
        tsmWorker.setLoginPwd(AESUtil.encrypt(passwd));
        // 如果赋值组织信息 则判断组织类别
        if (StringUtils.hasText(tsmWorker.getOrgId())) {
            Integer registrationSystem = 1;
            if (directlyUnderAuthority.contains(tsmWorker.getOrgId())) {
                registrationSystem = 2;
            }
            tsmWorker.setRegistrationSystem(registrationSystem);
        }
        tsmWorker.setWorkerType(WorkerTypeEnum.WEB.getType());
        tsmWorkerRepo.save(tsmWorker);
        tsmWorkerRepo.flush();
        int loginId = tsmWorker.getLoginId();
        // 添加标签
        workerJdbcDao.workerAddLabel(loginId, workerC.getLabelIds());
        // 赋值角色
        List<Integer> roleIds1 = workerC.getRoleIds();
        if (Objects.isNull(workerC.getRoleIds())) {
            roleIds1 = new ArrayList<>();
        }
        if (roleIds1.contains(SysmgrConstants.DEPARTMENT_AUDIT_PERSON) && roleIds1.contains(SysmgrConstants.SYS_AUDIT_PERSON)) {
            throw new BusinessException(WORKER_TWO_ROLE_EXIST);
        }
        
        List<TsmWorkerRole> workerRoles = new ArrayList<>();
        savePost(workerC.getTemporaryOrgs(), workerC.getPostIds(), loginId,workerRoles);
        List<Integer> ids = workerRoles.stream().map(TsmWorkerRole::getRoleId).collect(Collectors.toList());
        //过滤掉存在重复的角色
        List<Integer> roleIds = roleIds1.stream().filter(s->!ids.contains(s) && !CommonConstants.COMMON_ROLE_ID.equals(s)).collect(Collectors.toList());
        for (Integer integer : roleIds) {
            TsmWorkerRole workerRole = new TsmWorkerRole();
            workerRole.setLoginId(tsmWorker.getLoginId());
            workerRole.setRoleId(integer);
            workerRole.setSource(1);
            workerRoles.add(workerRole);
        }
        // 默认赋值公共权限
        TsmWorkerRole workerRole = new TsmWorkerRole();
        workerRole.setLoginId(loginId);
        workerRole.setRoleId(CommonConstants.COMMON_ROLE_ID);
        workerRoles.add(workerRole);
        tsmWorkerRoleRepo.saveAllAndFlush(workerRoles);
        // 保存obsCode
        if (Objects.nonNull(workerC.getFileId())) {
            saveObsCode(loginId, workerC.getFileId());
        }
        //固定的线程池（当前线程池大小为5）
        // ExecutorService executor = Executors.newFixedThreadPool(5);
        TsmWorkerOrgC tsmWorkerOrgC = new TsmWorkerOrgC();
        tsmWorkerOrgC.setWorkerId(tsmWorker.getLoginId());
        tsmWorkerOrgC.setOrgId(tsmWorker.getOrgId());
        saveTsmWorkerOrg(tsmWorkerOrgC);
        //  executor.shutdown();
        return loginId;
    }

    @Override
    public List<WorkerListRspDto> getWorkerByDepartment(WorkerManageReq req) {
        List<WorkerListRspDto>result=new ArrayList<>();
        List<String> codes = tsmPropertyValueRepo.findByPropCode(propertyCode).stream().map(TsmPropertyValue::getValueCode).collect(Collectors.toList());
        if (!codes.contains(req.getDepartment())){
            throw new BusinessException(WORKER_DEPARTMENT_NOT_EXISTS);
        }
        for (TsmWorker worker : tsmWorkerRepo.findAllByDepartment(req.getDepartment())) {
            WorkerListRspDto workerListRspDto=new WorkerListRspDto();
            workerListRspDto.setLoginId((long)worker.getLoginId());
            workerListRspDto.setWorkerName(worker.getWorkerName());
            result.add(workerListRspDto);
        }
        return result;
    }

}
