package com.lz.modules.job.business;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiSmartworkHrmEmployeeQueryonjobRequest;
import com.dingtalk.api.response.OapiSmartworkHrmEmployeeQueryonjobResponse;
import com.google.common.collect.Lists;
import com.lz.common.emun.WorkMsgTypeEnum;
import com.lz.common.utils.DateUtils;
import com.lz.common.utils.DingTalkUtil;
import com.lz.common.utils.R;
import com.lz.modules.app.dao.StaffDao;
import com.lz.modules.app.entity.*;
import com.lz.modules.app.service.DepartmentsService;
import com.lz.modules.app.service.DepartmentsStaffRelateService;
import com.lz.modules.app.service.StaffOccupationService;
import com.lz.modules.app.service.StaffService;
import com.lz.modules.flow.entity.*;
import com.lz.modules.flow.service.*;
import com.lz.modules.job.model.responseBo.DepartmentInfosBo;
import com.lz.modules.job.model.responseBo.DepartmentStaffBo;
import com.lz.modules.performance.entity.TaskProcessRecord;
import com.lz.modules.performance.service.ResultTaskService;
import com.lz.modules.performance.service.TaskProcessRecordService;
import com.lz.modules.sys.dao.SysUserTokenDao;
import com.lz.modules.sys.entity.SysUserTokenEntity;
import com.lz.modules.sys.entity.app.ResultDetail;
import com.lz.modules.sys.entity.app.ResultRecord;
import com.lz.modules.sys.service.app.ResultDetailService;
import com.lz.modules.sys.service.app.ResultRecordService;
import com.lz.modules.third.entity.ThirdAppConfig;
import com.lz.modules.third.entity.ThirdMsgSendRecord;
import com.lz.modules.third.entity.WorkMsg;
import com.lz.modules.third.service.ThirdAppConfigService;
import com.lz.modules.third.service.ThirdMsgSendRecordService;
import com.taobao.api.ApiException;
import org.apache.commons.collections.map.HashedMap;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.net.URLEncoder;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author fumeiai
 * @date 2019-05-29 17:06
 * @Description 钉钉同步业务
 * @注意 本内容仅限于杭州霖梓网络科技有限公司内部传阅，禁止外泄以及用于其他的商业目的
 */
@Component(value = "dingtalkBusiness")
public class DingtalkBusiness {
    protected final static org.slf4j.Logger logger = LoggerFactory.getLogger(DingtalkBusiness.class);
    //token过期时间12小时
    private final static int EXPIRE = 3600 * 12;
    @Autowired
    DingTalkUtil dingTalkUtil;

    @Resource
    DepartmentsService departmentsService;

    @Resource
    DepartmentsStaffRelateService departmentsStaffRelateService;

    @Resource
    StaffService staffService;

    @Resource
    StaffOccupationService staffOccupationService;

    @Autowired
    ThirdAppConfigService thirdAppConfigService;

    @Autowired
    private SysUserTokenDao sysUserTokenDao;

    @Autowired
    private ResultRecordService resultRecordService;

    @Autowired
    private FlowRecordService flowRecordService;

    @Autowired
    private FlowStartService flowStartService;

    @Autowired
    private FlowChangeService flowChangeService;

    @Autowired
    private ThirdMsgSendRecordService thirdMsgSendRecordService;

    @Autowired
    private ResultDetailService resultDetailService;

    @Autowired
    private ResultTaskService resultTaskService;

    @Autowired
    private TaskProcessRecordService taskProcessRecordService;

    @Autowired
    private StaffRoleService staffRoleService;

    @Autowired
    private StaffRoleDepartmentService staffRoleDepartmentService;

    @Autowired
    private StaffRoleEvaluationGroupService staffRoleEvaluationGroupService;

    @Resource
    StaffDao staffDao;

    static String homeUrl = "https://lzmanagement.ldxinyong.com/digitization";

    @Value("${dingtalk.appid}")
    private String appid;

    /**
     * 获取组织架构信息并录入到数据库
     */
//    @DataSource(name = DataSourceNames.FOUR)
    public void getDingTalkepartmentsIntoData(String appid) {

        /*List<StaffEntity> staffEntityList = staffDao.selectByRang("1004");//飞书数据更新为钉钉数据
        for (StaffEntity staff:staffEntityList
             ) {
            List<StaffEntity> list = staffDao.selectByName(staff.getName());
            if(list.size() > 0){
                StaffEntity staff1 = list.get(0);
                if(staff.getId().intValue() != staff1.getId().intValue()){
                    staff1.setJobNumber(staff.getJobNumber());
                    staff1.setAvatar(staff.getAvatar());
                    staff1.setEmployeeId(staff.getEmployeeId());
                    staff1.setOpenId(staff.getOpenId());
                    staff1.setUnionId(staff.getUnionId());


                    staffDao.deleteById(staff.getId());
                    staffDao.updateStaff(staff1);
                }

            }


        }
        return;*/
        //获取Token
        String token = dingTalkUtil.getAccessToken(appid);
        if(token != null && token.length() > 0){

            /*DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/role/list");
            OapiRoleListRequest request = new OapiRoleListRequest();
            request.setOffset(0L);
            request.setSize(10L);

            OapiRoleListResponse response = null;
            try {
                response = client.execute(request, token);
                logger.info("角色返回{}", response.getBody());
                JSONObject jsonObject = JSONObject.parseObject(response.getBody());
                JSONArray jsonArray = jsonObject.getJSONObject("result").getJSONArray("list");
                for (int i = 0; i < jsonArray.size(); i++
                     ) {
                    JSONObject json = jsonArray.getJSONObject(i);
                    JSONArray array = json.getJSONArray("roles");
                    logger.info("角色组{}", json.getString("name"));
                    for(int j = 0; j < array.size(); j++){
                        json = array.getJSONObject(j);
                        client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/role/simplelist");
                        OapiRoleSimplelistRequest request1 = new OapiRoleSimplelistRequest();
                        request1.setRoleId(json.getLong("id"));
                        request1.setOffset(0L);
                        request1.setSize(200L);

                        OapiRoleSimplelistResponse response1 = client.execute(request1, token);
                        logger.info("钉钉获取角色{},数据为{}", json.getString("name"), response1.getBody());
                    }
                }
            } catch (ApiException e) {
                e.printStackTrace();
            }*/

            List<DepartmentsEntity> addDeparts = new ArrayList<>();//需要新增的部门信息
            List<DepartmentsEntity> updateDeparts = new ArrayList<>();//需要更新的部门信息

            List<StaffEntity> addStaffs = new ArrayList<>();//需要新增的人员信息
            List<StaffEntity> updateStaffs = new ArrayList<>();//需要更新的人员

            List<DepartmentsStaffRelateEntity> addDepartStaff = new ArrayList<>();//需要新增的部门人员对应关系
            List<DepartmentsStaffRelateEntity> updateDepartStaff = new ArrayList<>();//需要更新部门人员对应关系
            Map<String, DepartmentsStaffRelateEntity> mapEmployeeIdDeparts = new HashedMap();//新员工对应的部门对应关系

            List<StaffOccupationEntity> addStaffOcc = new ArrayList<>();//需要新增的职位信息
            List<StaffOccupationEntity> updateStaffOcc = new ArrayList<>();//需要更新的职位信息
            Map<String, StaffOccupationEntity> mapEmployeeIdStaffOccs = new HashedMap();//新员工对应的职位对应关系

            List<String> newDepartIds = new ArrayList<>();//新的部门或者新的人员对应信息
            List<String> newPositions = new ArrayList<>();//新的职位或者新的人员对应信息

            //获取所有的部门详情
            List<DepartmentInfosBo> departmentInfosBos = dingTalkUtil.getDepartmentDetailsV2(token, "1");

            if(departmentInfosBos.size() > 0){
                List<String> probationUserIDS = getProbationStaff(token);//获取试用期人员信息
                Map<String, String> mapProbation = null;
                if(probationUserIDS != null){
                    mapProbation = probationUserIDS.stream().collect(Collectors.toMap(String::toString, Function.identity(), (e, r) -> e));
                }

                //获取原有部门信息
                Map<String, DepartmentInfosBo> mapDepartmentInfosBos
                        = departmentInfosBos.stream().collect(Collectors.toMap(DepartmentInfosBo::getId, Function.identity(), (e, r) -> e));
                List<DepartmentsEntity> departmentsEntities = departmentsService.selectAll();
                Map<String, DepartmentsEntity> mapDeparts = null;
                if(departmentsEntities.size() > 0){
                    mapDeparts =
                            departmentsEntities.stream().collect(Collectors.toMap(DepartmentsEntity::getDepartmentId, Function.identity(), (e, r) -> e));
                }

                //获取原有的部门人员对应关系
                List<DepartmentsStaffRelateEntity> departmentsStaffRelateEntities = departmentsStaffRelateService.selectAll();

                Map<String, DepartmentsStaffRelateEntity> mapDepStaffs = null;
                if(departmentsStaffRelateEntities.size() > 0){
                    mapDepStaffs =
                            departmentsStaffRelateEntities.stream().collect(
                                    Collectors.toMap(DepartmentsStaffRelateEntity::getKey,
                                    Function.identity(), (e, r) -> e));
                }

                //获取所有人员信息
                List<StaffEntity> staffEntities = staffService.selectAll();
                Map<String, StaffEntity> mapStaffs = null;
                if(staffEntities.size() > 0){
                    mapStaffs = staffEntities.stream().
                            collect(Collectors.toMap(StaffEntity::getEmployeeId, Function.identity(), (e, r)->e));
                }
                Map<String, StaffEntity> mapMorDepartStaffs = new HashedMap();//跨部门人员
                List<StaffOccupationEntity> staffOccupationEntities = staffOccupationService.selectAll();
                Map<String, StaffOccupationEntity> mapStaffOccs = null;
                if(staffOccupationEntities.size() > 0){
                    mapStaffOccs =
                            staffOccupationEntities.stream().collect(Collectors.toMap(StaffOccupationEntity::getKey, Function.identity(), (e, r) -> e));
                }
                Map<String, StaffOccupationEntity> mapHaveStaffOccs = new HashedMap();

                //删除原有的对应关系下面在更新
                //未在飞书组织架构里的成员，置为离职(全部置为离职，再把在职的恢复)
                //获取飞书部门对应的用户详情
                for (DepartmentInfosBo departmentInfo : departmentInfosBos) {
                    //DepartmentInfosBo departmentInfo = departmentInfosBos.get(key);
                    String key = departmentInfo.getId();
                    DepartmentsEntity departmentsEntity = null;
                    if(mapDeparts != null && mapDeparts.containsKey(key)){
                        //部门存在
                        departmentsEntity = mapDeparts.get(key);
                        updateDeparts.add(departmentsEntity);
                        mapDeparts.remove(key);
                    }else{//新增部门信息
                        departmentsEntity = new DepartmentsEntity();
                        departmentsEntity.setDepartmentId(departmentInfo.getId());
                        addDeparts.add(departmentsEntity);
                    }

                    //获取部门用户详情
                    List<DepartmentStaffBo> staffs = dingTalkUtil.getDepartmentStaffDetailsV2(token, departmentInfo.getId(), mapProbation);
                    logger.info("=============================" + departmentInfo.getName() + "================================");
                    //设置本部门人数
                    if(departmentInfo.getMemberCount() == null){
                        departmentInfo.setMemberCount(0);
                    }
                    departmentInfo.setMemberCount(departmentInfo.getMemberCount() + staffs.size());
                    //计算父类的
                    DepartmentInfosBo integer = departmentInfo;
                    while(!integer.getParentId().equals("1")){
                        integer = mapDepartmentInfosBos.get(integer.getParentId());
                        if(integer.getMemberCount() == null){
                            integer.setMemberCount(0);
                        }
                        integer.setMemberCount(integer.getMemberCount() + staffs.size());
                    }

                    if(staffs.size() > 0){
                        for (DepartmentStaffBo departmentStaffBo:staffs
                             ) {
                            StaffEntity staff = staffService.convertStaffEntity(departmentStaffBo);
                            if(mapStaffs != null && mapStaffs.containsKey(departmentStaffBo.getEmployeeId())){//老员工
                                StaffEntity entity = mapStaffs.get(departmentStaffBo.getEmployeeId());
                                staff.setId(entity.getId());
                                staff.setCreateTime(entity.getCreateTime());
                                staff.setUpdateTime(new Date());
                                updateStaffs.add(staff);
                                if(!mapMorDepartStaffs.containsKey(departmentStaffBo.getEmployeeId())){
                                    mapMorDepartStaffs.put(departmentStaffBo.getEmployeeId(), staff);
                                }
                                mapStaffs.remove(departmentStaffBo.getEmployeeId());

                                StaffOccupationEntity staffOccupation = new StaffOccupationEntity();
                                staffOccupation.setStaffId(staff.getId());
                                staffOccupation.setPosition(departmentStaffBo.getPosition());//职位信息
                                staffOccupation.setEmployeeNo(departmentStaffBo.getEmployeeNo());
                                staffOccupation.setStaffNo(departmentStaffBo.getEmployeeNo());//钉钉的员工工号
                                staffOccupation.setStaffType(departmentStaffBo.getEmployeeType());
                                staffOccupation.setStaffStatus(departmentStaffBo.getStatus());
                                String key1 = entity.getId() + "_" + staffOccupation.getPosition();
                                if(mapStaffOccs != null && mapStaffOccs.containsKey(key1)){//职位信息已存在，更新
                                    StaffOccupationEntity staffOccupation1 = mapStaffOccs.get(key1);
                                    staffOccupation.setId(staffOccupation1.getId());
                                    staffOccupation.setUpdateTime(new Date());
                                    updateStaffOcc.add(staffOccupation);
                                    mapStaffOccs.remove(key1);
                                    mapHaveStaffOccs.put(key1, staffOccupation);
                                }else if(!mapHaveStaffOccs.containsKey(key1)){//职位信息不存在，新建

                                    addStaffOcc.add(staffOccupation);
                                    mapHaveStaffOccs.put(key1, staffOccupation);
                                }

                                DepartmentsStaffRelateEntity departmentsStaffRelateEntity = new DepartmentsStaffRelateEntity();
                                departmentsStaffRelateEntity.setDepartmentId(departmentInfo.getId());
                                departmentsStaffRelateEntity.setStaffId(staff.getId());
                                departmentsStaffRelateEntity.setIsLeader(departmentStaffBo.getIsLeader());
                                if(mapDepStaffs != null && mapDepStaffs.containsKey(departmentsStaffRelateEntity.getKey())){//对应关系已经存在
                                    DepartmentsStaffRelateEntity staffRelateEntityentity1 = mapDepStaffs.get(departmentsStaffRelateEntity.getKey());
                                    if(staffRelateEntityentity1.getIsLeader().intValue() != departmentsStaffRelateEntity.getIsLeader().intValue()){
                                        departmentsStaffRelateEntity.setId(staffRelateEntityentity1.getId());
                                        departmentsStaffRelateEntity.setUpdateTime(new Date());
                                        updateDepartStaff.add(departmentsStaffRelateEntity);

                                    }
                                    mapDepStaffs.remove(departmentsStaffRelateEntity.getKey());

                                }else{//不存在对应关系
                                    addDepartStaff.add(departmentsStaffRelateEntity);
                                }
                            }else if(mapMorDepartStaffs.containsKey(departmentStaffBo.getEmployeeId())){
                                //跨部门人员
                                StaffEntity entity = mapMorDepartStaffs.get(departmentStaffBo.getEmployeeId());
                                staff.setId(entity.getId());
                                DepartmentsStaffRelateEntity departmentsStaffRelateEntity = new DepartmentsStaffRelateEntity();
                                departmentsStaffRelateEntity.setDepartmentId(departmentInfo.getId());
                                departmentsStaffRelateEntity.setIsLeader(departmentStaffBo.getIsLeader());
                                departmentsStaffRelateEntity.setStaffId(staff.getId());

                                StaffOccupationEntity staffOccupation = new StaffOccupationEntity();
                                staffOccupation.setStaffId(staff.getId());
                                staffOccupation.setPosition(departmentStaffBo.getPosition());//职位信息
                                staffOccupation.setEmployeeNo(departmentStaffBo.getEmployeeNo());
                                staffOccupation.setStaffNo(departmentStaffBo.getEmployeeNo());//钉钉的员工工号
                                staffOccupation.setStaffType(departmentStaffBo.getEmployeeType());
                                staffOccupation.setStaffStatus(departmentStaffBo.getStatus());


                                if(entity.getId() == null){//新用户
                                    key = staff.getEmployeeId() + "_" + departmentsStaffRelateEntity.getDepartmentId();
                                    if(!mapEmployeeIdDeparts.containsKey(key)){

                                        departmentsStaffRelateEntity.setIsLeader(departmentStaffBo.getIsLeader());
                                        mapEmployeeIdDeparts.put(key
                                                , departmentsStaffRelateEntity);
                                        newDepartIds.add(departmentsStaffRelateEntity.getDepartmentId());
                                    }

                                    key = staff.getEmployeeId() + "_" + staffOccupation.getPosition();
                                    if(!mapEmployeeIdStaffOccs.containsKey(key)){

                                        mapEmployeeIdStaffOccs.put(key
                                                , staffOccupation);
                                        newPositions.add(departmentStaffBo.getPosition());
                                    }
                                }else{
                                    String key1 = entity.getId() + "_" + staffOccupation.getPosition();
                                    if(mapStaffOccs != null && mapStaffOccs.containsKey(key1)){//职位信息已存在，更新
                                        StaffOccupationEntity staffOccupation1 = mapStaffOccs.get(key1);
                                        staffOccupation.setId(staffOccupation1.getId());//职位信息
                                        staffOccupation.setUpdateTime(new Date());
                                        updateStaffOcc.add(staffOccupation);
                                        mapStaffOccs.remove(key1);
                                        mapHaveStaffOccs.put(key1, staffOccupation);
                                    }else if(!mapHaveStaffOccs.containsKey(key1)){//职位信息不存在，新建
                                        addStaffOcc.add(staffOccupation);
                                        mapHaveStaffOccs.put(key1, staffOccupation);
                                    }

                                    if(mapDepStaffs != null && mapDepStaffs.containsKey(departmentsStaffRelateEntity.getKey())){//对应关系已经存在
                                        DepartmentsStaffRelateEntity staffRelateEntityentity1 = mapDepStaffs.get(departmentsStaffRelateEntity.getKey());
                                        if(staffRelateEntityentity1.getIsLeader().intValue() != departmentsStaffRelateEntity.getIsLeader().intValue()){
                                            departmentsStaffRelateEntity.setId(staffRelateEntityentity1.getId());
                                            departmentsStaffRelateEntity.setUpdateTime(new Date());
                                            updateDepartStaff.add(departmentsStaffRelateEntity);

                                        }
                                        mapDepStaffs.remove(departmentsStaffRelateEntity.getKey());
                                    }else{//不存在对应关系
                                        addDepartStaff.add(departmentsStaffRelateEntity);
                                    }
                                }
                            }else{//新的员工信息
                                addStaffs.add(staff);

                                if(!mapMorDepartStaffs.containsKey(departmentStaffBo.getEmployeeId())){
                                    mapMorDepartStaffs.put(departmentStaffBo.getEmployeeId(), staff);
                                }

                                //新增部门人员对应关系，新增人员后插入数据库
                                DepartmentsStaffRelateEntity  departmentsStaffRelateEntity = new DepartmentsStaffRelateEntity();
                                departmentsStaffRelateEntity.setDepartmentId(departmentInfo.getId());
                                key = staff.getEmployeeId() + "_" + departmentsStaffRelateEntity.getDepartmentId();
                                if(!mapEmployeeIdDeparts.containsKey(key)){

                                    departmentsStaffRelateEntity.setIsLeader(departmentStaffBo.getIsLeader());
                                    mapEmployeeIdDeparts.put(key
                                            , departmentsStaffRelateEntity);
                                    newDepartIds.add(departmentsStaffRelateEntity.getDepartmentId());
                                }

                                //新增人员职位信息，新增人员后插入数据库
                                StaffOccupationEntity staffOccupation = new StaffOccupationEntity();
                                staffOccupation.setPosition(departmentStaffBo.getPosition());//职位信息
                                key = staff.getEmployeeId() + "_" + staffOccupation.getPosition();
                                if(!mapEmployeeIdStaffOccs.containsKey(key)){

                                    staffOccupation.setEmployeeNo(departmentStaffBo.getEmployeeNo());
                                    staffOccupation.setStaffNo(departmentStaffBo.getEmployeeNo());//钉钉的员工工号
                                    staffOccupation.setStaffType(departmentStaffBo.getEmployeeType());
                                    staffOccupation.setStaffStatus(departmentStaffBo.getStatus());
                                    mapEmployeeIdStaffOccs.put(key
                                            , staffOccupation);
                                    newPositions.add(departmentStaffBo.getPosition());
                                }

                            }
                        }
                    }
                }
                if(mapDeparts != null && mapDeparts.size() > 0){//有需要删除的部门信息
                    logger.info("删除部门信息个数{}", mapDeparts.size());
                    departmentsEntities = mapDeparts.values().stream().collect(Collectors.toList());
                    for(DepartmentsEntity entity:departmentsEntities) {
                        entity.setIsDelete(1);
                        entity.setUpdateTime(new Date());
                    }
                    departmentsService.updateBatchById(departmentsEntities);
                }
                if(addDeparts.size() > 0){//有新增部门
                    logger.info("新增部门信息个数{}", addDeparts.size());
                    for (DepartmentsEntity entity:addDeparts
                         ) {
                        DepartmentInfosBo departmentInfo = mapDepartmentInfosBos.get(entity.getDepartmentId());
                        entity.setDepartmentId(departmentInfo.getId());
                        entity.setDepartmentName(departmentInfo.getName());
                        entity.setDepartmentParentId(departmentInfo.getParentId());
                        entity.setMemberCount(departmentInfo.getMemberCount());
                        entity.setChatId(departmentInfo.getChatId());
                        entity.setLeaderEmployeeId(departmentInfo.getLeaderEmployeeId());
                        entity.setLeaderOpenId(departmentInfo.getLeaderOpenId());
                        entity.setStatus(1);
                    }
                    departmentsService.saveBatch(addDeparts);
                }

                if(updateDeparts.size() > 0){//有新增部门
                    logger.info("更新部门信息个数{}", updateDeparts.size());
                    for (DepartmentsEntity entity:updateDeparts
                    ) {
                        DepartmentInfosBo departmentInfo = mapDepartmentInfosBos.get(entity.getDepartmentId());
                        entity.setDepartmentId(departmentInfo.getId());
                        entity.setDepartmentName(departmentInfo.getName());
                        entity.setDepartmentParentId(departmentInfo.getParentId());
                        entity.setMemberCount(departmentInfo.getMemberCount());
                        entity.setChatId(departmentInfo.getChatId());
                        entity.setLeaderEmployeeId(departmentInfo.getLeaderEmployeeId());
                        entity.setLeaderOpenId(departmentInfo.getLeaderOpenId());
                        entity.setStatus(1);
                    }
                    departmentsService.updateBatchById(updateDeparts);
                }

                if(addStaffs.size() > 0){//有新增部门
                    logger.info("新增人员信息个数{}", addStaffs.size());

                    staffService.saveBatch(addStaffs);
                    String key;
                    for (StaffEntity entity:addStaffs
                         ) {
                        for (String departId:newDepartIds
                             ) {
                            key = entity.getEmployeeId() + "_" + departId;
                            if(mapEmployeeIdDeparts.containsKey(key)){
                                DepartmentsStaffRelateEntity  departmentsStaffRelateEntity =
                                        mapEmployeeIdDeparts.get(key);
                                departmentsStaffRelateEntity.setStaffId(entity.getId());
                                addDepartStaff.add(departmentsStaffRelateEntity);
                                mapEmployeeIdDeparts.remove(key);
                            }
                        }

                        for (String position:newPositions
                        ) {
                            key = entity.getEmployeeId() + "_" + position;
                            if(mapEmployeeIdStaffOccs.containsKey(key)){
                                StaffOccupationEntity staffOccupation = mapEmployeeIdStaffOccs.get(key);
                                staffOccupation.setStaffId(entity.getId());
                                addStaffOcc.add(staffOccupation);
                                mapEmployeeIdStaffOccs.remove(key);
                            }
                        }
                    }
                }



                if(updateStaffs.size() > 0){//有新增部门
                    logger.info("更新人员信息个数{}", updateStaffs.size());
                    staffService.updateBatchById(updateStaffs);
                }

                if(mapDepStaffs != null && mapDepStaffs.size() > 0){
                    logger.info("删除人员部门个数{}", mapDepStaffs.size());
                    departmentsStaffRelateEntities = mapDepStaffs.values().stream().collect(Collectors.toList());
                    for (DepartmentsStaffRelateEntity entity:departmentsStaffRelateEntities
                         ) {
                        entity.setIsDelete(1);
                    }
                    departmentsStaffRelateService.updateBatchById(departmentsStaffRelateEntities);
                }

                if(addDepartStaff.size() > 0){//有新增部门
                    logger.info("新增部门人员对应关系个数{}", addDepartStaff.size());
                    departmentsStaffRelateService.saveBatch(addDepartStaff);

                }

                if(updateDepartStaff.size() > 0){//有新增部门
                    logger.info("更新部门人员对应关系个数{}", updateDepartStaff.size());
                    departmentsStaffRelateService.updateBatchById(updateDepartStaff);
                }

                if(addStaffOcc.size() > 0){//有新增部门
                    logger.info("新增人员职位对应关系个数{}", addStaffOcc.size());
                    staffOccupationService.saveBatch(addStaffOcc);

                }

                if(updateStaffOcc.size() > 0){//有新增部门
                    logger.info("更新人员对职位应关系个数{}", updateStaffOcc.size());
                    staffOccupationService.updateBatchById(updateStaffOcc);
                }

                if(mapStaffs != null && mapStaffs.size() > 0){//离职人员
                    logger.info("离职人员可能个数{}", mapStaffs.size());
                    if(mapStaffOccs != null && mapStaffOccs.size() > 0){
                        logger.info("离职人员对应的职位信息个数{}", mapStaffs.size());
                        staffEntities = mapStaffs.values().stream().collect(Collectors.toList());
                        staffOccupationEntities.clear();
                        for (StaffEntity entity:staffEntities
                        ) {
                            if(mapStaffOccs.containsKey(entity.getId())){
                                StaffOccupationEntity staffOccupationEntity = mapStaffOccs.get(entity.getId());
                                if(staffOccupationEntity.getStaffStatus().intValue() == 0){
                                    staffOccupationEntity.setStaffStatus(1);
                                    staffOccupationEntity.setUpdateTime(new Date());
                                    staffOccupationEntities.add(staffOccupationEntity);
                                }
                            }
                        }
                        logger.info("离职人员实际个数{}", staffOccupationEntities.size());
                        staffOccupationService.updateBatchById(staffOccupationEntities);
                    }
                }
            }else{
                logger.info("部门信息为空");
            }
        }
    }

    private List<String> getProbationStaff(String token){
        //获取试用期员工信息
        List<String> ids = null;
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/smartwork/hrm/employee/queryonjob");
            OapiSmartworkHrmEmployeeQueryonjobRequest req = new OapiSmartworkHrmEmployeeQueryonjobRequest();
            Long offSet = 0L;
            req.setStatusList("2");
            req.setSize(50L);
            boolean isNext = false;
            ids =  new ArrayList<>();
            {
                req.setOffset(offSet);
                OapiSmartworkHrmEmployeeQueryonjobResponse rsp = client.execute(req, token);
                logger.info("钉钉请求试用期员工返回信息{}", rsp.getBody());
                JSONObject jsonObject = JSONObject.parseObject(rsp.getBody());
                if(jsonObject.getIntValue("errcode") == 0){
                    jsonObject = jsonObject.getJSONObject("result");
                    offSet = jsonObject.getLong("next_cursor");
                    if(offSet != null){
                        isNext = true;
                    }
                    JSONArray jsonArray = JSONArray.parseArray(jsonObject.getString("data_list"));
                    ids.addAll(Arrays.stream(jsonArray.toArray(new String[jsonArray.size()])).collect(Collectors.toList()));
                }else{
                    logger.info("钉钉请求返回错误{}", jsonObject);
                }
            }while(isNext);

        } catch (ApiException e) {
            e.printStackTrace();
        }
        return ids;
    }


    public void enterStaffOccupationInfos(List<DepartmentStaffBo> staffs) {
        List<StaffOccupationEntity> StaffOccupations = Lists.newArrayList();
        for (DepartmentStaffBo departmentStaffBo : staffs) {
            StaffEntity staffEntity = staffService.getStaffInfoByOpenId(departmentStaffBo.getOpenId());
            Long staffId = staffEntity.getId();
            StaffOccupationEntity staffOccupationEntity = staffOccupationService.getStaffOccupationByStaffId(staffId);
            if (staffOccupationEntity == null) {
                StaffOccupationEntity staffOccupation = new StaffOccupationEntity();
                staffOccupation.setStaffId(staffId);
                staffOccupation.setPosition(departmentStaffBo.getPosition());//职位信息
                staffOccupation.setEmployeeNo(departmentStaffBo.getEmployeeNo());
                staffOccupation.setStaffNo(departmentStaffBo.getEmployeeNo());//钉钉的员工工号
                staffOccupation.setStaffType(departmentStaffBo.getEmployeeType());
                staffOccupation.setStaffStatus(departmentStaffBo.getStatus());
                staffOccupation.setEntryTime(DateUtils.getCurrentDate());
                StaffOccupations.add(staffOccupation);
            } else {
                staffOccupationService.updateStatusByStaff(staffId, departmentStaffBo);//更新职位信息，工号信息
            }
        }
        if (StaffOccupations.size() > 0) {
            staffOccupationService.saveBatch(StaffOccupations);
        }
    }

    public String urging(Long recordId) {
        ResultRecord lzResultRecord = resultRecordService.selectResultRecordById(recordId);
        //获取当前节点，谁在处理
        List<FlowRecord> flowRecords = flowRecordService.selectFlowRecordsByRecordIdAndStatus(recordId, 2);
        if(flowRecords.size() > 0){
            List<Long> ids = flowRecords.stream().map(new Function<FlowRecord, Long>() {
                @Override
                public Long apply(FlowRecord flowRecord) {
                    return flowRecord.getApprovalStaffId();
                }
            }).collect(Collectors.toList());
            List<StaffEntity> staffs = staffService.selectNamesByIds(ids);
            sendNoticeMsg(lzResultRecord, staffs);
            return "OK";
        }
        return "error";
    }



    public String sendTaskInputMsg(List<StaffEntity> staffs){
        int m = 0;
        String userIds = "";
        ThirdAppConfig thirdAppConfig = thirdAppConfigService.getByAppId(appid);
        String token = dingTalkUtil.getAccessTokenWitchEntity(thirdAppConfig);
        if(token != null && token.length() > 0){
            String url = homeUrl;
            if(url.contains("?")){
                url += "&halokit=" + System.currentTimeMillis();
            }else{
                url += "?halokit=" + System.currentTimeMillis();
            }
            url = URLEncoder.encode(url);


            url = "dingtalk://dingtalkclient/action/openapp?corpid=" + thirdAppConfig.getCorpId() +
                    "&container_type=work_platform&app_id=0_" +
                    appid + "&redirect_type=jump&redirect_url=" + url;

            for (int i = 0; i < staffs.size(); i++) {
                StaffEntity staff = staffs.get(i);
                userIds += (staff.getEmployeeId() + ",");
                if(m >= 99 || i == staffs.size() - 1){
                    //发送消息
                    StaffEntity info = new StaffEntity();
                    info.setId(0L);
                    info.setEmployeeId(userIds);
                    dingTalkUtil.sendSingleActionCardMSG(appid, info,  WorkMsgTypeEnum.TASK_UPDATE.getTitle(),
                            WorkMsgTypeEnum.TASK_UPDATE.getContent(),  WorkMsgTypeEnum.TASK_UPDATE.getBtnText(), url, token);
                    m = 0;
                    userIds = "";
                    continue;
                }
                m++;
            }
        }
        return "OK";
    }

    public String sendTaskNoticeMsg(Long detailId, Long taskId) {
        ResultDetail resultDetail = resultDetailService.selectResultDetailById(detailId);
        logger.info("评论通知指标id{}， 任务id{}, 指标信息{}", detailId, taskId, resultDetail);
        if(resultDetail != null){
            TaskProcessRecord taskProcessRecord = null;
            if(taskId == null){
                taskProcessRecord = taskProcessRecordService.selectCommentTaskProcessRecordByDetailId(detailId);
            }else{
                taskProcessRecord = taskProcessRecordService.selectCommentTaskProcessRecordByTaskId(taskId);
            }
            if(taskProcessRecord != null) {
                ThirdAppConfig thirdAppConfig = thirdAppConfigService.getByAppId(appid);
                String token = dingTalkUtil.getAccessTokenWitchEntity(thirdAppConfig);
                String url = homeUrl;
                if (url.contains("?")) {
                    url += "&halokit=" + System.currentTimeMillis();
                } else {
                    url += "?halokit=" + System.currentTimeMillis();
                }
                url += ("&detail=1&id=" + resultDetail.getRecordId() + "&detailId=" + resultDetail.getId());
                url = URLEncoder.encode(url);


                url = "dingtalk://dingtalkclient/action/openapp?corpid=" + thirdAppConfig.getCorpId() +
                        "&container_type=work_platform&app_id=0_" +
                        appid + "&redirect_type=jump&redirect_url=" + url;
                if (token != null && token.length() > 0) {

                    StaffSimpleInfo fromStaffSimpleInfo = staffService.selectStaffSimpleInfo(taskProcessRecord.getStaffId());
                    if (taskProcessRecord.getStaffId().longValue() != resultDetail.getStaffId().longValue()) {
                        //自己评论自己的不允许给自己发消息
                        StaffSimpleInfo toStaffSimpleInfo = staffService.selectStaffSimpleInfo(resultDetail.getStaffId());

                        StaffEntity info = new StaffEntity();
                        info.setId(toStaffSimpleInfo.getId());
                        info.setEmployeeId(toStaffSimpleInfo.getEmployeeId());
                        String content = WorkMsgTypeEnum.TASK_COMMENT.getContent().replace("@1", fromStaffSimpleInfo.getName());
                        content = content.replace("@2", "“" + resultDetail.getTarget() + "”");
                        logger.info("通知内容{},url{}", content, url);
                        dingTalkUtil.sendSingleActionCardMSG(appid, info, WorkMsgTypeEnum.TASK_COMMENT.getTitle(),
                                content, WorkMsgTypeEnum.TASK_COMMENT.getBtnText(), url, token);

                    }
                    if(taskProcessRecord.getAtStaffIds().length() > 0){
                        //@的人员
                        List<Long> ids = Arrays.stream(taskProcessRecord.getAtStaffIds().split(","))
                                .map(new Function<String, Long>() {
                                    @Override
                                    public Long apply(String s) {
                                        return Long.parseLong(s);
                                    }
                                }).collect(Collectors.toList());
                        List<StaffEntity> staffEntities = staffService.selectByIds(ids);
                        logger.info("评论推送人员个数{}", staffEntities.size());
                        String content = WorkMsgTypeEnum.TASK_REPLY_COMMENT.getContent().replace("@1", fromStaffSimpleInfo.getName());
                        content = content.replace("@2", "“" + resultDetail.getTarget() + "”");
                        logger.info("通知内容{},url{}", content, url);
                        String userIds = "";
                        int m = 0;
                        for (int i = 0; i < staffEntities.size(); i++) {
                            StaffEntity staff = staffEntities.get(i);
                            userIds += (staff.getEmployeeId() + ",");
                            if(m >= 99 || i == staffEntities.size() - 1){
                                //发送消息
                                StaffEntity info = new StaffEntity();
                                info.setId(0L);
                                info.setEmployeeId(userIds);
                                logger.info("推送的人员信息{}", info);
                                dingTalkUtil.sendSingleActionCardMSG(appid, info,  WorkMsgTypeEnum.TASK_REPLY_COMMENT.getTitle(),
                                        content,  WorkMsgTypeEnum.TASK_REPLY_COMMENT.getBtnText(), url, token);
                                m = 0;
                                userIds = "";
                                continue;
                            }
                            m++;
                        }

                    }
                    return "OK";
                }else {
                    return "token无效";
                }
            }else{
                logger.info("任务不存在");
            }

        }
        return "OK";
    }
    public String sendNoticeMsg(ResultRecord lzResultRecord, List<StaffEntity> staffs) {

        ThirdAppConfig thirdAppConfig = thirdAppConfigService.getByAppId(appid);
        String token = dingTalkUtil.getAccessTokenWitchEntity(thirdAppConfig);
        if(token != null && token.length() > 0){
            String url = homeUrl;
            if(url.contains("?")){
                url += "&halokit=" + System.currentTimeMillis();
            }else{
                url += "?halokit=" + System.currentTimeMillis();
            }
            url += ("&detail=1&id=" + lzResultRecord.getId());
            url = URLEncoder.encode(url);


            url = "dingtalk://dingtalkclient/action/openapp?corpid=" + thirdAppConfig.getCorpId() +
                    "&container_type=work_platform&app_id=0_" +
                    appid + "&redirect_type=jump&redirect_url=" + url;
            logger.info("推送消息个数{}", staffs.size());
            for (StaffEntity info:
                    staffs) {
                logger.info("发送消息给{}，url:{}", info, url);
                String content = null;
                if(!lzResultRecord.getStaffName().equals(info.getName())){
                    content = WorkMsgTypeEnum.URGING.getContent().replace("@", lzResultRecord.getStaffName());
                }else{
                    content = WorkMsgTypeEnum.URGING.getContent().replace("@", "您");
                }

                dingTalkUtil.sendSingleActionCardMSG(appid, info,  WorkMsgTypeEnum.URGING.getTitle(),
                        content,  WorkMsgTypeEnum.URGING.getBtnText(), url, token);
            }
            return "OK";

        }else{
            return "token无效";
        }
    }

    public String sendWorkMSG(String appid, Long fromStaffid, long toStaffid, int type) {
        //获取Token
        StaffEntity toStaffEntity = staffService.selectStaffById(toStaffid);
        StaffEntity fromStaffEntity = staffService.selectStaffById(fromStaffid);

        WorkMsgTypeEnum workMsgTypeEnum = WorkMsgTypeEnum.findRoleTypeByCode(type);
        return sendWorkMSGByEntity(appid, fromStaffEntity, toStaffEntity, workMsgTypeEnum, "https://www.baidu.com");
    }

    public String delWorkMSGWithStart(List<Long> recordIds){

        logger.info("批量删除待办任务{}", recordIds.size());
        ThreadSendMessage threadSendMessage = new ThreadSendMessage();
        threadSendMessage.setUpdateData(recordIds, WorkMsgTypeEnum.CLEARN, appid);
        Thread thread = new Thread(threadSendMessage);
        thread.start();

        return "OK";
    }


    public String sendWorkMSGWithAsyn(Long resultRecordId ,Long flowRecordId, int type) {
        logger.info("开始处理数据");
        //流程跳转专用
        ResultRecord resultRecord = resultRecordService.selectResultRecordById(resultRecordId);
        if(resultRecord != null){
            FlowStart flowStart = flowStartService.selectFlowStartById(resultRecord.getStartId());
            StaffSimpleInfo fromStaff = staffService.selectStaffSimpleInfo(resultRecord.getStaffId());//查询来自那里
            fromStaff.setResultRecord(resultRecord);
            fromStaff.setFlowStart(flowStart);
            fromStaff.setFlowRecordId(flowRecordId);
            if(type == WorkMsgTypeEnum.REJECT.getType()){//被拒
                return sendWorkMSGWithAsyn(fromStaff, null, WorkMsgTypeEnum.REJECT.getType());
            }else if(type == WorkMsgTypeEnum.URGING.getType()){//被拒

                return sendWorkMSGWithAsyn(fromStaff, null, WorkMsgTypeEnum.URGING.getType());
            }else if(type == WorkMsgTypeEnum.SKIP.getType()){//被拒

                return sendWorkMSGWithAsyn(fromStaff, null, WorkMsgTypeEnum.SKIP.getType());
            }else if(type == WorkMsgTypeEnum.TRANSFER.getType()){//被拒

                return sendWorkMSGWithAsyn(fromStaff, null, WorkMsgTypeEnum.TRANSFER.getType());
            }else{
                return sendWorkMSGWithAsyn(fromStaff, null, WorkMsgTypeEnum.PROCESS.getType());
            }
        }
        logger.info("无记录");
        return "error";
    }
    //流程流转发送消息
    public String sendWorkMSGWithAsyn(Long resultRecordId , int type) {
        logger.info("流程流转发送消息");
        return sendWorkMSGWithAsyn(resultRecordId, 0L, type);

    }


    public String sendWorkMSGWithAsyn(StaffSimpleInfo fromStaff, List<StaffSimpleInfo> toStaffids, int type) {

        if (toStaffids != null && toStaffids.size() > 0 && (toStaffids.get(0).getEmployeeId() == null || toStaffids.get(0).getEmployeeId().length() == 0)) {
            //查询第三方id
            List<Long> ids = toStaffids.stream().map(new Function<StaffSimpleInfo, Long>() {
                @Override
                public Long apply(StaffSimpleInfo staffSimpleInfo) {
                    return staffSimpleInfo.getId();
                }
            }).collect(Collectors.toList());
            List<StaffSimpleInfo> staffSimpleInfos = staffService.selectStaffSimpleInfos(ids);
            Map<Long, StaffSimpleInfo> map = toStaffids.stream().collect(Collectors.toMap(StaffSimpleInfo::getId, e -> e));
            for (StaffSimpleInfo staff : staffSimpleInfos
            ) {
                StaffSimpleInfo staff1 = map.get(staff.getId());
                staff1.setEmployeeId(staff1.getEmployeeId());
            }
        }
        WorkMsgTypeEnum workMsgTypeEnum = WorkMsgTypeEnum.findRoleTypeByCode(type);

        ThreadSendMessage threadSendMessage = new ThreadSendMessage(fromStaff, toStaffids, workMsgTypeEnum, appid);
        Thread thread = new Thread(threadSendMessage);
        thread.start();

        return "OK";

    }


    public String sendWorkMSGWithAsyn(List<StaffSimpleInfo> toStaffids, int type) {

        return sendWorkMSGWithAsyn(null, toStaffids, type);

    }

    public String sendWorkMSGByEntity(String appid, StaffEntity fromStaffEntity, StaffEntity toStaffEntity,
                                      WorkMsgTypeEnum workMsgTypeEnum, String url){
        if(toStaffEntity != null && fromStaffEntity != null){

            ThirdAppConfig thirdAppConfig = thirdAppConfigService.getByAppId(appid);
            String token = dingTalkUtil.getAccessTokenWitchEntity(thirdAppConfig);
            if(token != null && token.length() > 0){
                //下面防止第二次发送消息时钉钉不推送
                if(url.contains("?")){
                    url += "&halokit=" + System.currentTimeMillis();
                }else{
                    url += "?halokit=" + System.currentTimeMillis();
                }
                url = URLEncoder.encode(url);
               /* url = "dingtalk://dingtalkclient/action/openapp?corpid=" + thirdAppConfig.getCorpId() +
                        "&container_type=work_platform&app_id=0_" + appid + "&redirect_type=jump&redirect_url=" + url;*/

                url = "dingtalk://dingtalkclient/page/link?pc_slide=true&url=" + url;

                String content = workMsgTypeEnum.getContent().replace("@", fromStaffEntity.getName());
                return dingTalkUtil.sendSingleActionCardMSG(appid, toStaffEntity, workMsgTypeEnum.getTitle(),
                        content, workMsgTypeEnum.getBtnText(), url, token);
            }else{
                return "token无效";
            }
        }
        return "无相关人员信息";
    }

    public R login(String code, String appid) {
        logger.info("钉钉登录appid{}", appid);
        String token = dingTalkUtil.getAccessToken(appid);
        if(token != null && token.length() > 0){
            return dingTalkUtil.getUserIdByCode(code, token);
        }
        return R.error("授权失败，未授权");
    }

    public R luck(String code, String appid, Long luckId) {
        String token = dingTalkUtil.getAccessToken(appid);
        if(token != null && token.length() > 0){
            return dingTalkUtil.luck(code, token, luckId);
        }
        return R.error("授权失败，未授权");
    }

    public R jump(String code) {
        SysUserTokenEntity tokenEntity = sysUserTokenDao.getByTokenCode(code);
        if(tokenEntity != null){//token不存在或者超过2分钟
            long big = System.currentTimeMillis() - tokenEntity.getCodeTime().getTime();
            logger.info("跳转的时间差{}", big);
            if(big < 120000L){
                //这里不更新时间了
                tokenEntity.setTokenCode("");
                sysUserTokenDao.updateById(tokenEntity);
                long expire = tokenEntity.getExpireTime().getTime() - System.currentTimeMillis();
                return R.ok().put("token", tokenEntity.getToken()).put("expire", expire);
            }

        }
        logger.info("token的token_code不存在");
        return R.error("未授权登录");
    }

    public void urging(List<FlowRecord> flowRecords, Map<Long, StaffEntity> mapStaffs, Map<Long, ResultRecord> mapReords) {
        ThreadSendUrgingMessage threadSendUrgingMessage = new ThreadSendUrgingMessage(flowRecords, mapReords, mapStaffs);
        Thread thread = new Thread(threadSendUrgingMessage);
        thread.start();

    }

    public class ThreadSendUrgingMessage implements Runnable{
        List<FlowRecord> flowRecords;
        Map<Long, ResultRecord> mapReords;
        Map<Long, StaffEntity> mapStaffs;
        public ThreadSendUrgingMessage(List<FlowRecord> flowRecords, Map<Long, ResultRecord> mapReords, Map<Long, StaffEntity> mapStaffs){
            this.flowRecords = flowRecords;
            this.mapReords = mapReords;
            this.mapStaffs = mapStaffs;
        }

        @Override
        public void run() {
            logger.info("批量催办");
            ThirdAppConfig thirdAppConfig = thirdAppConfigService.getByAppId(appid);
            String token = dingTalkUtil.getAccessTokenWitchEntity(thirdAppConfig);
            if(token != null && token.length() > 0){

                for (FlowRecord flowRecord:flowRecords
                ) {
                    ResultRecord record = mapReords.get(flowRecord.getRecordId());
                    StaffEntity info = mapStaffs.get(flowRecord.getApprovalStaffId());
                    if(record != null && info != null){
                        String url = homeUrl;
                        if(url.contains("?")){
                            url += "&halokit=" + System.currentTimeMillis();
                        }else{
                            url += "?halokit=" + System.currentTimeMillis();
                        }
                        url += ("&detail=1&id=" + record.getId());
                        url = URLEncoder.encode(url);

                        url = "dingtalk://dingtalkclient/action/openapp?corpid=" + thirdAppConfig.getCorpId() +
                                "&container_type=work_platform&app_id=0_" +
                                appid + "&redirect_type=jump&redirect_url=" + url;

                        logger.info("发送消息给{}，url:{}", info, url);
                        String content = null;
                        if(!record.getStaffName().equals(info.getName())){
                            content = WorkMsgTypeEnum.URGING.getContent().replace("@", record.getStaffName());
                        }else{
                            content = WorkMsgTypeEnum.URGING.getContent().replace("@", "您");
                        }

                        dingTalkUtil.sendSingleActionCardMSG(appid, info,  WorkMsgTypeEnum.URGING.getTitle(),
                                content,  WorkMsgTypeEnum.URGING.getBtnText(), url, token);

                    }else{
                        logger.info("无对应的record");
                    }
                }
            }else{
                logger.info("token无效"); ;
            }
        }
    }

    public class ThreadSendMessage implements Runnable{
        List<StaffSimpleInfo> toStaffids;
        StaffSimpleInfo fromStaff = null;
        List<Long> recordIds;
        WorkMsgTypeEnum workMsgTypeEnum;
        String appid;
        String hostUrl = homeUrl;
        public ThreadSendMessage(StaffSimpleInfo fromStaff, List<StaffSimpleInfo> toStaffids, WorkMsgTypeEnum typeEnum, String appid){
            this.fromStaff = fromStaff;
            this.toStaffids = toStaffids;
            workMsgTypeEnum = typeEnum;
            this.appid = appid;
        }



        public void setUpdateData(List<Long> recordIds, WorkMsgTypeEnum typeEnum, String appid){
            this.recordIds = recordIds;
            workMsgTypeEnum = typeEnum;
            this.appid = appid;
        }
        public ThreadSendMessage(){

        }



        private void sendNotic(Long staffId, String employeeId,
                          String content1, String content2, String content3,
                               String token, String url, Long recordId){
            StaffEntity entity = new StaffEntity();
            entity.setId(staffId);
            entity.setEmployeeId(employeeId);
            List<WorkMsg> msgs = new ArrayList<>();
            WorkMsg workMsg = new WorkMsg("任务内容", content1);
            msgs.add(workMsg);
            workMsg = new WorkMsg("考核名称", content2);
            msgs.add(workMsg);
            workMsg = new WorkMsg("被考核人", content3);
            msgs.add(workMsg);
            dingTalkUtil.sendSingleWorkMSG(appid, entity, workMsgTypeEnum.getTitle(),
                    msgs,
                    url, token, "霖梓控股", 1, recordId);
        }

        @Override
        public void run() {

            ThirdAppConfig thirdAppConfig = thirdAppConfigService.getByAppId(appid);
            String token = dingTalkUtil.getAccessTokenWitchEntity(thirdAppConfig);
            if(token != null && token.length() > 0){
                if(workMsgTypeEnum.getType() == WorkMsgTypeEnum.CLEARN.getType()){
                    //绩效催办
                    logger.info("绩效清空");


                    List<ThirdMsgSendRecord> threadSendMessages
                            = thirdMsgSendRecordService.selectThirdMsgSendRecordsByRecordIds(recordIds, 1, 1);
                    logger.info("需要删除的条数为{}", threadSendMessages.size());
                    for (ThirdMsgSendRecord thirdMsgSendRecord:threadSendMessages
                    ) {
                        dingTalkUtil.updateWorkMSG(thirdMsgSendRecord, token);
                    }
                }else{
                    logger.info("开始批量推送消息，appid{}", appid);

                    if(toStaffids == null){//流程流转走的代码
                        logger.info("需要处理人员信息{}", fromStaff);
                        String url = hostUrl;
                        if(url.contains("?")){
                            url += "&halokit=" + System.currentTimeMillis();
                        }else{
                            url += "?halokit=" + System.currentTimeMillis();
                        }
                        url += ("&detail=1&id=" + fromStaff.getResultRecord().getId());
                        url = URLEncoder.encode(url);


                        url = "dingtalk://dingtalkclient/action/openapp?corpid=" + thirdAppConfig.getCorpId() +
                                "&container_type=work_platform&app_id=0_" +
                                appid + "&redirect_type=jump&redirect_url=" + url;
                        if(workMsgTypeEnum.getType() == WorkMsgTypeEnum.URGING.getType()){
                            //绩效催办
                            logger.info("绩效催办");
                        }else {
                            //流程流转通知

                            if(workMsgTypeEnum.getType() == WorkMsgTypeEnum.TRANSFER.getType()){//转交
                                //转交
                                //并发转交会有问题
                                logger.info("转交待办任务处理");
                                FlowChange flowChange = flowChangeService.selectFlowChangeByFlowRecordIdAndType(
                                        fromStaff.getFlowRecordId(),
                                        1);
                                if(flowChange != null){
                                    ThirdMsgSendRecord thirdMsgSendRecord =
                                            thirdMsgSendRecordService.selectThirdMsgSendRecordByWorkIdAndStaffIdAndTypeAndStatus(
                                                    fromStaff.getResultRecord().getId(), flowChange.getApprovalId(), 1, 1);
                                    if(thirdMsgSendRecord != null){//把原来的任务更新掉
                                        dingTalkUtil.updateWorkMSG(thirdMsgSendRecord, token);
                                    }
                                    FlowRecord flowRecord = flowRecordService.selectFlowRecordById(flowChange.getFlowRecordId());
                                    if(flowRecord != null && flowRecord.getStatus().intValue() == 2){
                                        logger.info("转交存在且为当前要处理的节点");
                                        StaffSimpleInfo staffSimpleInfo = staffService.selectStaffSimpleInfo(flowRecord.getApprovalStaffId());
                                        //List<FlowRecord> flowRecords = flowRecordService.selectFlowRecordByRecordIdStatus(info.getResultRecord().getId(), 2);
                                        //发送待办任务到新指定人员，转交过来一定会有数据
                                        sendNotic(staffSimpleInfo.getId(), staffSimpleInfo.getEmployeeId(),
                                                flowRecord.getFlowName(), fromStaff.getFlowStart().getName(),
                                                fromStaff.getResultRecord().getStaffName(), token, url, fromStaff.getResultRecord().getId());
                                    }else{
                                        logger.info("转交不存在，或者当前非处理节点无需发送");
                                    }
                                }else{
                                    logger.info("流转变更记录不存在");
                                }


                            }else if(workMsgTypeEnum.getType() == WorkMsgTypeEnum.SKIP.getType()){//跳过
                                //跳过
                                logger.info("跳过待办任务处理");
                                List<FlowRecord> flowRecords =
                                        flowRecordService.selectSkipFlowRecordsById(fromStaff.getResultRecord().getId());//取消所有跳过的人
                                logger.info("查询到可能需要更新待办任务数量{}", flowRecords.size());
                                if(flowRecords.size() > 0){
                                    //或签
                                    for (FlowRecord flowRecord:flowRecords
                                    ) {
                                        logger.info("更新非直接跳关人员的待办任务，人员id:{}, 姓名:{}", flowRecord.getApprovalStaffId(),
                                                flowRecord.getApprovalStaffName());
                                        ThirdMsgSendRecord thirdMsgSendRecord =
                                                thirdMsgSendRecordService.selectThirdMsgSendRecordByWorkIdAndStaffIdAndTypeAndStatus(
                                                        fromStaff.getResultRecord().getId(),
                                                        flowRecord.getApprovalStaffId(), 1, 1);
                                        if(thirdMsgSendRecord != null){//把原来的任务更新掉
                                            dingTalkUtil.updateWorkMSG(thirdMsgSendRecord, token);
                                        }else{
                                            logger.info("无需更新");
                                        }
                                    }
                                }
                                //获取具体跳过的步骤
                                FlowRecord flowRecord = flowRecordService.selectFlowRecordById(fromStaff.getFlowRecordId());//
                            }else{
                                logger.info("流程正常流转");
                                List<FlowRecord> flowRecords = flowRecordService.selectFlowRecordByRecordIdStatus(fromStaff.getResultRecord().getId(), 2);
                                //取消上一步骤发送的待办任务
                                List<FlowRecord> cancelRecords;
                                if(flowRecords.size() == 0){//任务结束了
                                    logger.info("任务结束了");
                                    cancelRecords = flowRecordService.selectLastFlowRecordsById(fromStaff.getResultRecord().getId());
                                }else{
                                    if(workMsgTypeEnum.getType() == WorkMsgTypeEnum.REJECT.getType()){//被拒
                                        logger.info("任务驳回");
                                        cancelRecords = flowRecordService.selectFirstFlowRecordsByIdAndFlowIndex(fromStaff.getResultRecord().getId()
                                                , flowRecords.get(0).getFlowIndex().intValue() + 1, 0);//获取下一步的数据
                                    }else{
                                        logger.info("任务流转下一步");
                                        cancelRecords = flowRecordService.selectLastFlowRecordsByIdAndFlowIndex(fromStaff.getResultRecord().getId()
                                                , flowRecords.get(0).getFlowIndex().intValue() - 1, 1);//获取上一步的数据
                                    }

                                }
                                logger.info("查询到可能需要更新的待办任务数量{}", cancelRecords.size());
                                if(cancelRecords.size() > 0){
                                    int flowIndex = cancelRecords.get(0).getFlowIndex().intValue();
                                    for (FlowRecord flowRecord:cancelRecords
                                    ) {
                                        if(flowRecord.getFlowIndex() == flowIndex){//同一个小结点的才进来
                                            if(flowRecord.getStatus().intValue() == 1
                                                    || flowRecord.getStatus().intValue() == 3
                                                    || flowRecord.getStatus().intValue() == 4
                                                    || workMsgTypeEnum.getType() == WorkMsgTypeEnum.REJECT.getType()){
                                                logger.info("将要更新人员的待办任务，人员id:{}, 姓名:{}", flowRecord.getApprovalStaffId(),
                                                        flowRecord.getApprovalStaffName());
                                                ThirdMsgSendRecord thirdMsgSendRecord =
                                                        thirdMsgSendRecordService.selectThirdMsgSendRecordByWorkIdAndStaffIdAndTypeAndStatus(
                                                                fromStaff.getResultRecord().getId(),
                                                                flowRecord.getApprovalStaffId(), 1, 1);
                                                if(thirdMsgSendRecord != null){//把原来的任务更新掉
                                                    dingTalkUtil.updateWorkMSG(thirdMsgSendRecord, token);
                                                }else{
                                                    logger.info("无需更新待办任务");
                                                }
                                            }
                                        }else{
                                            logger.info("已经取消完毕");
                                            break;
                                        }

                                    }
                                }
                                //给下一步需要处理的人员发送待办任务
                                if(flowRecords.size() > 0){//给下一步骤需要处理的人发送待办任务
                                    if(flowRecords.get(0).getFlowProcess().intValue() != 2){//执行中流程的不发送待办
                                        logger.info("非执行中的节点发送待办任务：{}", flowRecords.get(0).getFlowName());
                                        List<Long> ids = flowRecords.stream().map(new Function<FlowRecord, Long>() {
                                            @Override
                                            public Long apply(FlowRecord flowRecord) {
                                                return flowRecord.getApprovalStaffId();
                                            }
                                        }).collect(Collectors.toList());
                                        List<StaffSimpleInfo> staffSimpleInfos = staffService.selectStaffSimpleInfos(ids);
                                        for (StaffSimpleInfo staffSimpleInfo:staffSimpleInfos
                                        ) {
                                            sendNotic(staffSimpleInfo.getId(), staffSimpleInfo.getEmployeeId(),
                                                    flowRecords.get(0).getFlowName(), fromStaff.getFlowStart().getName(),
                                                    fromStaff.getResultRecord().getStaffName(), token, url, fromStaff.getResultRecord().getId());

                                        }
                                    }
                                }

                            }
                        }


                    }else{//批量推送给指定人员
                        logger.info("批量推送数量{}", toStaffids.size());
                        for (StaffSimpleInfo info:toStaffids
                        ) {

                            //下面防止第二次发送消息时钉钉不推送
                            String url = hostUrl;
                            if (url.contains("?")) {
                                url += "&halokit=" + System.currentTimeMillis();
                            } else {
                                url += "?halokit=" + System.currentTimeMillis();
                            }
                            url += ("&detail=1&id=" + info.getResultRecord().getId());
                            url = URLEncoder.encode(url);
                            url = "dingtalk://dingtalkclient/action/openapp?corpid=" + thirdAppConfig.getCorpId() +
                                    "&container_type=work_platform&app_id=0_" +
                                    appid + "&redirect_type=jump&redirect_url=" + url;

                            if (workMsgTypeEnum.getType() == WorkMsgTypeEnum.START_WORK.getType()) {
                                //发送制定目标通知
                                logger.info("目标制定");
                                sendNotic(info.getId(), info.getEmployeeId(),
                                        "目标制定", info.getFlowStart().getName(),
                                        info.getResultRecord().getStaffName(), token, url, info.getResultRecord().getId());

                            } else if (workMsgTypeEnum.getType() == WorkMsgTypeEnum.START_SCORE.getType()) {
                                //发送开始评分通知
                                logger.info("结果录入");
                                sendNotic(info.getId(), info.getEmployeeId(),
                                        "结果录入", info.getFlowStart().getName(),
                                        info.getResultRecord().getStaffName(), token, url, info.getResultRecord().getId());

                            }else{
                                logger.info("未定义消息类型");
                            }

                        }
                    }
                }
            }else{
                logger.info("ThreadSendMessage token无效"); ;
            }

        }
    }
}
