OrgSyncByWxcpJob.java 28.4 KB
Newer Older
吴泽佳's avatar
吴泽佳 committed
1 2 3 4 5 6 7
package com.tanpu.feo.feojob.jobs;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.MD5;
import cn.hutool.json.JSONUtil;
8
import com.tanpu.common.util.JsonUtil;
吴泽佳's avatar
吴泽佳 committed
9
import com.tanpu.feo.feojob.constant.BaseConstant;
吴泽佳's avatar
吴泽佳 committed
10
import com.tanpu.feo.feojob.constant.OrgExtConstant;
11
import com.tanpu.feo.feojob.dao.user.entity.*;
吴泽佳's avatar
吴泽佳 committed
12 13
import com.tanpu.feo.feojob.dto.WorkDataDto;
import com.tanpu.feo.feojob.dto.WxCpDepartDto;
吴泽佳's avatar
吴泽佳 committed
14 15
import com.tanpu.feo.feojob.enums.EmployeeDutyEnum;
import com.tanpu.feo.feojob.enums.RoleTypeEnum;
16 17
import com.tanpu.feo.feojob.feign.CommonResp;
import com.tanpu.feo.feojob.feign.fatools.FeignClientForFatools;
吴泽佳's avatar
吴泽佳 committed
18 19 20 21 22 23 24 25 26
import com.tanpu.feo.feojob.service.*;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl;
import me.chanjar.weixin.cp.bean.Gender;
import me.chanjar.weixin.cp.bean.WxCpDepart;
import me.chanjar.weixin.cp.bean.WxCpUser;
import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl;
27 28
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
29
import org.springframework.beans.factory.annotation.Value;
吴泽佳's avatar
吴泽佳 committed
30 31 32 33
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
34
import java.util.*;
35
import java.util.stream.Collectors;
吴泽佳's avatar
吴泽佳 committed
36 37 38

/**
 * @author zejia zj wu
吴泽佳's avatar
吴泽佳 committed
39
 * @date 2021-05-18
吴泽佳's avatar
吴泽佳 committed
40 41 42 43 44 45
 * @Description 从企业微信 同步 组织信息 及 员工信息
 */
@Component
@Slf4j
public class OrgSyncByWxcpJob {

吴泽佳's avatar
吴泽佳 committed
46
    final static String keyStr = "{\"corpId\":\"ww08675a3a48c9e8a2\",\"agentId\":\"1000013\",\"corpSecret\":\"l7eLNC5DDNxmucc9emHsEaSXym4VKDy_D5w4IoOpvqk\",\"token\":\"E1zDvDkXWt\",\"aesKey\":\"43P8lbP5yt8AHLOUPGBPS252c60K9Vzofzm5NOxHHeP\",\"sendMessageAppId\":\"wxe177c62fa1e1c602\"}\n";
吴泽佳's avatar
吴泽佳 committed
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
    @Resource
    private OrgExtService orgExtService;
    @Resource
    private OrgService orgService;
    @Resource
    private UserInfoService userInfoService;
    @Resource
    private DepartmentService departmentService;
    @Resource
    private DepartmentEmployeeService departmentEmployeeService;
    @Resource
    private EmployeeService employeeService;
    @Resource
    private EmployeeRoleService employeeRoleService;
    @Resource
    private RoleService roleService;
    @Resource
吴泽佳's avatar
吴泽佳 committed
64
    private OrgSyncService orgSyncService;
65 66
    @Value("${tanpu.sync.job.skipped:true}")
    private boolean jobSkipped;
67 68
    @Resource
    private FeignClientForFatools feignClientForFatools;
吴泽佳's avatar
吴泽佳 committed
69

70
    @Scheduled(cron = "10 0/10 6-19/1 * * ?")   //每日凌晨6点30开始执行,半小时检查一次
71
    public void execute() {
吴泽佳's avatar
吴泽佳 committed
72 73
        log.info("====== 开始执行OrgSyncByWxcpJob ======");
        try {
74 75 76
            if (!jobSkipped) {
                orgSyncByWxcp("Y");
            }
吴泽佳's avatar
吴泽佳 committed
77
        } catch (Exception e) {
xd's avatar
xd committed
78
            log.error("====== 异常结束执行OrgSyncByWxcpJob,错误:{}=======", e.getMessage(), e);
吴泽佳's avatar
吴泽佳 committed
79 80 81 82 83 84
        }
        log.info("====== 结束执行OrgSyncByWxcpJob ======");
    }

    /**
     * 执行 部门 及 员工 同步任务
85
     *
吴泽佳's avatar
吴泽佳 committed
86 87 88 89
     * @param isAuto 任务触发类型 Y 定时任务 / N 手动
     */
    public void orgSyncByWxcp(String isAuto) {
        // 1 扫描 org_ext 表 获取需要 执行同步的 机构
吴泽佳's avatar
吴泽佳 committed
90
        List<OrgExtEntity> orgExtList = orgExtService.findOrgExtByModel(OrgExtConstant.MODEL_ONE);
吴泽佳's avatar
吴泽佳 committed
91 92
        for (OrgExtEntity orgExtEntity : orgExtList) {
            String orgId = orgExtEntity.getOrgId();
吴泽佳's avatar
吴泽佳 committed
93 94 95
            log.info("======开始同步机构:{} 的信息======", orgId);

            //2  根据orgId 查找机构 相关信息
吴泽佳's avatar
吴泽佳 committed
96
            OrgEntity orgEntity = orgService.findById(orgId);
吴泽佳's avatar
吴泽佳 committed
97 98

            //3 从企业微信获取组织信息及员工信息
吴泽佳's avatar
吴泽佳 committed
99 100
            log.info("======从企业微信获取组织信息及员工信息 开始======");
            WxCpDefaultConfigImpl wxCpDefaultConfig = JSONUtil.toBean(orgExtEntity.getJsonWxcpKey(), WxCpDefaultConfigImpl.class);
吴泽佳's avatar
吴泽佳 committed
101

吴泽佳's avatar
吴泽佳 committed
102 103
            List<WxCpDepart> wxCpDepartList; // 机构信息
            List<WxCpDepartDto> wxCpDepartDtoList;//自定义的 部门信息
吴泽佳's avatar
吴泽佳 committed
104 105
            try {
                wxCpDepartList = getWxCpDepartList(wxCpDefaultConfig);
106
                wxCpDepartDtoList = getWxCpUserList(wxCpDepartList, wxCpDefaultConfig);
吴泽佳's avatar
吴泽佳 committed
107
            } catch (Exception e) {
xd's avatar
xd committed
108
                log.error("======从企业微信获取组织信息及员工信息失败->机构:{} -> 错误信息-> {}======", orgId, e.getMessage(), e);
吴泽佳's avatar
吴泽佳 committed
109 110
                continue;
            }
吴泽佳's avatar
吴泽佳 committed
111
            log.info("======从企业微信获取组织信息及员工信息 结束======");
吴泽佳's avatar
吴泽佳 committed
112

113 114
            logOrgManSimpleInfo(orgId, wxCpDepartDtoList);

吴泽佳's avatar
吴泽佳 committed
115
            //4 判断是否需要 同步
吴泽佳's avatar
吴泽佳 committed
116
            String digestHex = isExecute(isAuto, wxCpDepartDtoList, orgExtEntity.getMd5WxcpData());
117
            log.info("====== 机构:{}整体digest, old: {}, new: {}=======", orgId, orgExtEntity.getMd5WxcpData(), digestHex);
吴泽佳's avatar
吴泽佳 committed
118 119 120 121
            if (StrUtil.isBlank(digestHex)) {
                log.info("====== 机构:{} 不需要执行同步=======", orgId);
                continue;
            }
122 123
            String qrCodeUrl = getQrCodeUrl(orgEntity.getId());

吴泽佳's avatar
吴泽佳 committed
124
            //5 开始比对 5张表 数据 user_info employee department department_employee employee_role
吴泽佳's avatar
吴泽佳 committed
125
            log.info("======开始比对 5张表 数据 ======");
126
            String corpId = wxCpDefaultConfig.getCorpId();
127
            WorkDataDto<UserInfoEntity> workUserInfo = userInfoWork(orgEntity.getId(), wxCpDepartDtoList, corpId, qrCodeUrl);
吴泽佳's avatar
吴泽佳 committed
128 129 130 131 132 133 134 135 136 137 138
            WorkDataDto<EmployeeEntity> workEmployee = employeeWork(orgEntity.getId(), wxCpDepartDtoList, corpId);
            WorkDataDto<DepartmentEntity> workDepartment = departmentWork(orgEntity.getId(), wxCpDepartDtoList);
            WorkDataDto<DepartmentEmployeeEntity> workDepartmentEmployee = departmentEmployeeWork(orgEntity.getId(), wxCpDepartDtoList, corpId);
            WorkDataDto<EmployeeRoleEntity> workEmployeeRole = employeeRoleWork(orgEntity.getId(), wxCpDepartDtoList, corpId);
            log.info("======结束比对 5张表 数据 ======");

            //6 数据 更新
            orgSyncService.updateData(orgId, workUserInfo, workEmployee, workDepartment, workDepartmentEmployee, workEmployeeRole);

            //7 讲最新的md5值 存至 orgExtEntity 表中
            orgExtEntity.setMd5WxcpData(digestHex);
吴泽佳's avatar
吴泽佳 committed
139
            orgExtService.updateById(orgExtEntity);
吴泽佳's avatar
吴泽佳 committed
140 141 142 143
        }

    }

144 145 146 147 148 149 150 151 152 153 154 155
    private void logOrgManSimpleInfo(String orgId, List<WxCpDepartDto> wxCpDepartDtoList) {
        if (CollectionUtils.isEmpty(wxCpDepartDtoList)) {
            log.info("机构{}当前无部门人员信息", orgId);
            return;
        }
        Map<String, Integer> map = new LinkedHashMap<>(wxCpDepartDtoList.size());
        for (WxCpDepartDto departDto : wxCpDepartDtoList) {
            map.put(departDto.getName() + "," + departDto.getEnName() + "," + departDto.getId(), departDto.getMembers());
        }
        log.info("机构{}当前部门数:{}, 人员数概要是: {}", orgId, wxCpDepartDtoList.size(), JsonUtil.toJson(map));
    }

156 157 158 159 160 161 162 163
    private String getQrCodeUrl(String orgId) {
        CommonResp<String> commonResp = feignClientForFatools.getQrCodeUrl(orgId);
        if (commonResp.isNotSuccess()) {
            throw new RuntimeException(commonResp.statusCode + ", " + commonResp.getMessage());
        }
        return commonResp.getAttributes();
    }

164
    /**
165 166 167 168
     * @description: 整理 员工与角色关联关系 数据
     * @Author: zejia zj wu
     * @date: 2021/5/27 3:08 下午
     */
吴泽佳's avatar
吴泽佳 committed
169 170 171 172 173
    private WorkDataDto<EmployeeRoleEntity> employeeRoleWork(String orgId, List<WxCpDepartDto> wxCpDepartDtoList, String corpId) {
        WorkDataDto<EmployeeRoleEntity> workDataDto = new WorkDataDto<>();
        List<EmployeeRoleEntity> insertList = new ArrayList<>();
        List<EmployeeRoleEntity> deleteList = new ArrayList<>();
        List<EmployeeRoleEntity> updateList = new ArrayList<>();
吴泽佳's avatar
吴泽佳 committed
174
        //获取 数据库 部门员工关系 信息
175
        List<EmployeeRoleEntity> employeeRoleList = employeeRoleService.findInfoByOrgId(orgId);
吴泽佳's avatar
吴泽佳 committed
176
        // 获取 role
177
        Map<String, String> roleMap = roleService.findInfoNoAdmin();
吴泽佳's avatar
吴泽佳 committed
178 179 180 181 182 183
        // 预处理 新数据
        HashMap<String, WxCpUser> hashMap = new HashMap<>();
        for (WxCpDepartDto wxCpDepartDto : wxCpDepartDtoList) {
            List<WxCpUser> wxCpUserList = wxCpDepartDto.getWxCpUserList();
            for (WxCpUser wxCpUser : wxCpUserList) {
                // key employee_id + '&' + role_id
184
                String type = wxCpUser.getIsLeader() != null && wxCpUser.getIsLeader() == 1 ? RoleTypeEnum.TEAM.code : RoleTypeEnum.IFA.code;
185
                hashMap.put(corpId + "_" + wxCpUser.getUserId() + "&" + roleMap.get(type), wxCpUser);
吴泽佳's avatar
吴泽佳 committed
186 187
            }
        }
吴泽佳's avatar
吴泽佳 committed
188
        for (EmployeeRoleEntity employeeRole : employeeRoleList) {
吴泽佳's avatar
吴泽佳 committed
189 190 191 192 193 194 195 196 197 198 199 200 201
            String employeeId = employeeRole.getEmployeeId();
            String roleId = employeeRole.getRoleId();
            String key = employeeId + "&" + roleId;
            WxCpUser wxCpUser = hashMap.get(key);
            //删除
            if (ObjectUtil.isNull(wxCpUser)) {
                // 删除
                deleteList.add(employeeRole);
                continue;
            }
            // 员工 角色关联关系没有 更新
            hashMap.remove(key);
        }
202 203
        Map<String, List<EmployeeRoleEntity>> map = employeeRoleList.stream().collect(Collectors.groupingBy(EmployeeRoleEntity::getEmployeeId));
        String adminRoleId = roleMap.get(RoleTypeEnum.ADMIN.code);
吴泽佳's avatar
吴泽佳 committed
204 205 206 207
        for (String key : hashMap.keySet()) {
            String[] split = key.split("&");
            String employeeId = split[0];
            String roleId = split[1];
208 209 210 211 212 213
            // 如果已经有一个admin的角色,那么就不要插入新的
            List<EmployeeRoleEntity> roleList = map.get(employeeId);
            if (CollectionUtils.isNotEmpty(roleList) && roleList.stream().anyMatch(p -> StringUtils.equals(p.getRoleId(), adminRoleId))) {
                log.info("成员已经有管理员角色了,不需要再插入, userId: {}, orgId:{}", employeeId, orgId);
                continue;
            }
吴泽佳's avatar
吴泽佳 committed
214
            EmployeeRoleEntity employeeRole = new EmployeeRoleEntity();
吴泽佳's avatar
吴泽佳 committed
215 216 217 218 219 220 221 222
            employeeRole.setEmployeeId(employeeId);
            employeeRole.setRoleId(roleId);
            employeeRole.setOrgId(orgId);
            insertList.add(employeeRole);
        }
        workDataDto.setDeleteList(deleteList);
        workDataDto.setInsertList(insertList);
        workDataDto.setUpdateList(updateList);
223
        return workDataDto;
吴泽佳's avatar
吴泽佳 committed
224 225 226

    }

227
    /**
228 229 230 231
     * @description: 整理 部门与员工关联关系 数据
     * @Author: zejia zj wu
     * @date: 2021/5/27 3:08 下午
     */
吴泽佳's avatar
吴泽佳 committed
232 233 234 235 236
    private WorkDataDto<DepartmentEmployeeEntity> departmentEmployeeWork(String orgId, List<WxCpDepartDto> wxCpDepartDtoList, String corpId) {
        WorkDataDto<DepartmentEmployeeEntity> workDataDto = new WorkDataDto<>();
        List<DepartmentEmployeeEntity> insertList = new ArrayList<>();
        List<DepartmentEmployeeEntity> deleteList = new ArrayList<>();
        List<DepartmentEmployeeEntity> updateList = new ArrayList<>();
吴泽佳's avatar
吴泽佳 committed
237
        //获取 数据库 部门员工关系 信息
238
        List<DepartmentEmployeeEntity> departmentEmployeeList = departmentEmployeeService.findInfoByOrgId(orgId);
吴泽佳's avatar
吴泽佳 committed
239 240 241 242 243 244
        // 预处理 新数据
        HashMap<String, WxCpUser> hashMap = new HashMap<>();
        for (WxCpDepartDto wxCpDepartDto : wxCpDepartDtoList) {
            List<WxCpUser> wxCpUserList = wxCpDepartDto.getWxCpUserList();
            for (WxCpUser wxCpUser : wxCpUserList) {
                // key department_id + '&' + employee_id
245
                hashMap.put(orgId + "_" + wxCpDepartDto.getId() + "&" + corpId + "_" + wxCpUser.getUserId(), wxCpUser);
吴泽佳's avatar
吴泽佳 committed
246 247 248

            }
        }
吴泽佳's avatar
吴泽佳 committed
249
        for (DepartmentEmployeeEntity departmentEmployee : departmentEmployeeList) {
吴泽佳's avatar
吴泽佳 committed
250 251 252 253 254 255 256 257 258 259
            String departmentId = departmentEmployee.getDepartmentId();
            String employeeId = departmentEmployee.getEmployeeId();
            String key = departmentId + "&" + employeeId;
            WxCpUser wxCpUser = hashMap.get(key);
            if (ObjectUtil.isNull(wxCpUser)) {
                // 删除
                deleteList.add(departmentEmployee);
                continue;
            }
            //更新
260
            String type = wxCpUser.getIsLeader() != null && wxCpUser.getIsLeader() == 1 ? EmployeeDutyEnum.DIRECTOR.code : EmployeeDutyEnum.STAFF.code;
吴泽佳's avatar
吴泽佳 committed
261 262 263 264 265 266 267 268
            if (!departmentEmployee.getType().equals(type)) {
                departmentEmployee.setType(type);
                updateList.add(departmentEmployee);
            }
            hashMap.remove(key);
        }
        for (String s : hashMap.keySet()) {
            WxCpUser wxCpUser = hashMap.get(s);
269
            String type = wxCpUser.getIsLeader() != null && wxCpUser.getIsLeader() == 1 ? EmployeeDutyEnum.DIRECTOR.code : EmployeeDutyEnum.STAFF.code;
吴泽佳's avatar
吴泽佳 committed
270 271 272
            String[] split = s.split("&");
            String departmentId = split[0];
            String employeeId = split[1];
吴泽佳's avatar
吴泽佳 committed
273
            DepartmentEmployeeEntity departmentEmployee = new DepartmentEmployeeEntity();
吴泽佳's avatar
吴泽佳 committed
274 275 276 277 278 279 280 281 282
            departmentEmployee.setEmployeeId(employeeId);
            departmentEmployee.setDepartmentId(departmentId);
            departmentEmployee.setType(type);
            departmentEmployee.setOrgId(orgId);
            insertList.add(departmentEmployee);
        }
        workDataDto.setDeleteList(deleteList);
        workDataDto.setInsertList(insertList);
        workDataDto.setUpdateList(updateList);
283
        return workDataDto;
吴泽佳's avatar
吴泽佳 committed
284 285
    }

286
    /**
287 288 289 290
     * @description: 整理 部门机构 数据
     * @Author: zejia zj wu
     * @date: 2021/5/27 3:09 下午
     */
吴泽佳's avatar
吴泽佳 committed
291 292 293 294 295
    private WorkDataDto<DepartmentEntity> departmentWork(String orgId, List<WxCpDepartDto> wxCpDepartDtoList) {
        WorkDataDto<DepartmentEntity> workDataDto = new WorkDataDto<>();
        List<DepartmentEntity> insertList = new ArrayList<>();
        List<DepartmentEntity> deleteList = new ArrayList<>();
        List<DepartmentEntity> updateList = new ArrayList<>();
吴泽佳's avatar
吴泽佳 committed
296
        //获取 数据库 部门 信息
297
        List<DepartmentEntity> departmentList = departmentService.findDepartmentByOrgId(orgId);
吴泽佳's avatar
吴泽佳 committed
298 299 300 301 302 303 304
        // 预处理 新数据
        HashMap<String, WxCpDepartDto> hashMap = new HashMap<>();
        HashMap<Long, WxCpDepartDto> hashMap2 = new HashMap<>();
        for (WxCpDepartDto wxCpDepartDto : wxCpDepartDtoList) {
            hashMap.put(orgId + "_" + wxCpDepartDto.getId(), wxCpDepartDto);
            hashMap2.put(wxCpDepartDto.getId(), wxCpDepartDto);
        }
吴泽佳's avatar
吴泽佳 committed
305
        for (DepartmentEntity department : departmentList) {
吴泽佳's avatar
吴泽佳 committed
306 307 308 309 310 311 312 313 314
            String departmentId = department.getDepartmentId();
            WxCpDepartDto wxCpDepartDto = hashMap.get(departmentId);
            //删除
            if (ObjectUtil.isNull(wxCpDepartDto)) {
                deleteList.add(department);
                continue;
            }
            //更新
            Long parentId1 = wxCpDepartDto.getParentId();
315
            String parentId = ObjectUtil.isNull(hashMap2.get(parentId1)) ? "" : orgId + "_" + parentId1;
吴泽佳's avatar
吴泽佳 committed
316
            Integer level = getLevel(hashMap2, wxCpDepartDto.getId());
吴泽佳's avatar
吴泽佳 committed
317
            if (!department.getDepartmentName().equals(wxCpDepartDto.getName()) || StrUtil.compareIgnoreCase(department.getParentDepartId(), parentId, false) != 0
318
                    || !department.getMembers().equals(wxCpDepartDto.getMembers()) || !level.equals(department.getLevel())) {
吴泽佳's avatar
吴泽佳 committed
319 320 321
                department.setDepartmentName(wxCpDepartDto.getName());
                department.setParentDepartId(parentId);
                department.setMembers(wxCpDepartDto.getMembers());
吴泽佳's avatar
吴泽佳 committed
322
                department.setLevel(level);
吴泽佳's avatar
吴泽佳 committed
323 324 325 326 327 328 329 330
                updateList.add(department);
            }
            hashMap.remove(departmentId);
        }
        //修改
        for (String departmentId : hashMap.keySet()) {
            WxCpDepartDto wxCpDepartDto = hashMap.get(departmentId);
            Long parentId1 = wxCpDepartDto.getParentId();
331
            String parentId = ObjectUtil.isNull(hashMap2.get(parentId1)) ? "" : orgId + "_" + parentId1;
吴泽佳's avatar
吴泽佳 committed
332
            DepartmentEntity department = new DepartmentEntity();
吴泽佳's avatar
吴泽佳 committed
333 334 335 336 337 338 339 340 341 342 343
            department.setDepartmentId(orgId + "_" + wxCpDepartDto.getId());
            department.setParentDepartId(parentId);
            department.setDepartmentName(wxCpDepartDto.getName());
            department.setLevel(getLevel(hashMap2, wxCpDepartDto.getId()));
            department.setMembers(wxCpDepartDto.getMembers());
            department.setOrgId(orgId);
            insertList.add(department);
        }
        workDataDto.setDeleteList(deleteList);
        workDataDto.setInsertList(insertList);
        workDataDto.setUpdateList(updateList);
344
        return workDataDto;
吴泽佳's avatar
吴泽佳 committed
345 346
    }

347
    /**
348 349 350 351
     * @description: 获取部门等级
     * @Author: zejia zj wu
     * @date: 2021/5/27 3:09 下午
     */
吴泽佳's avatar
吴泽佳 committed
352
    private Integer getLevel(HashMap<Long, WxCpDepartDto> hashMap2, Long id) {
吴泽佳's avatar
吴泽佳 committed
353 354
        Long parentId = hashMap2.get(id).getParentId();
        if (ObjectUtil.isNull(hashMap2.get(parentId))) {
吴泽佳's avatar
吴泽佳 committed
355 356
            return 1;
        }
357
        return 1 + getLevel(hashMap2, parentId);
吴泽佳's avatar
吴泽佳 committed
358 359
    }

360
    /**
361 362 363 364
     * @description: 整理 员工 数据
     * @Author: zejia zj wu
     * @date: 2021/5/27 3:09 下午
     */
吴泽佳's avatar
吴泽佳 committed
365 366 367 368 369
    private WorkDataDto<EmployeeEntity> employeeWork(String orgId, List<WxCpDepartDto> wxCpDepartDtoList, String corpId) {
        WorkDataDto<EmployeeEntity> workDataDto = new WorkDataDto<>();
        List<EmployeeEntity> insertList = new ArrayList<>();
        List<EmployeeEntity> deleteList = new ArrayList<>();
        List<EmployeeEntity> updateList = new ArrayList<>();
吴泽佳's avatar
吴泽佳 committed
370
        //获取 数据库 员工 信息
371
        List<EmployeeEntity> employeeList = employeeService.getEmployeeSListByOrgId(orgId);
吴泽佳's avatar
吴泽佳 committed
372 373 374 375 376 377

        // 预处理 新数据
        HashMap<String, WxCpUser> hashMap = new HashMap<>();
        for (WxCpDepartDto wxCpDepartDto : wxCpDepartDtoList) {
            List<WxCpUser> wxCpUserList = wxCpDepartDto.getWxCpUserList();
            for (WxCpUser wxCpUser : wxCpUserList) {
378
                hashMap.put(corpId + "_" + wxCpUser.getUserId(), wxCpUser);
吴泽佳's avatar
吴泽佳 committed
379 380 381 382
            }
        }

        // 计算 变化数据
吴泽佳's avatar
吴泽佳 committed
383
        for (EmployeeEntity employee : employeeList) {
吴泽佳's avatar
吴泽佳 committed
384 385 386 387 388 389 390 391 392 393
            String employeeId = employee.getEmployeeId();
            WxCpUser wxCpUser = hashMap.get(employeeId);
            //删除
            if (ObjectUtil.isNull(wxCpUser)) {
                deleteList.add(employee);
                continue;
            }
            //更新
            String status = wxCpUser.getStatus() == 1 ? "on" : "off";
            if (!employee.getName().equals(wxCpUser.getName()) || !employee.getMail().equals(wxCpUser.getEmail()) ||
吴泽佳's avatar
吴泽佳 committed
394
                    StrUtil.isBlank(employee.getBoundWechat()) || !employee.getStatus().equals(status)) {
吴泽佳's avatar
吴泽佳 committed
395 396 397 398 399 400 401 402 403 404 405 406 407
                employee.setName(wxCpUser.getName());
                employee.setMail(wxCpUser.getEmail());
                if (StrUtil.isBlankIfStr(employee.getBoundWechat())) {
                    employee.setBoundWechat(orgId + "_" + wxCpUser.getUserId());
                }
                employee.setStatus(status);
                updateList.add(employee);
            }
            hashMap.remove(employeeId);
        }
        //修改
        for (String key : hashMap.keySet()) {
            WxCpUser wxCpUser = hashMap.get(key);
吴泽佳's avatar
吴泽佳 committed
408
            EmployeeEntity employee = new EmployeeEntity();
409
            employee.setEmployeeId(corpId + "_" + wxCpUser.getUserId());
吴泽佳's avatar
吴泽佳 committed
410 411 412 413 414
            employee.setName(wxCpUser.getName());
            employee.setPhone(wxCpUser.getMobile());
            employee.setMail(wxCpUser.getEmail());
            employee.setNumber(null);
            employee.setOrgId(orgId);
吴泽佳's avatar
吴泽佳 committed
415
            employee.setBoundWechat(orgId + "_" + wxCpUser.getUserId());
吴泽佳's avatar
吴泽佳 committed
416
            employee.setStatus(wxCpUser.getStatus() == 1 ? BaseConstant.EmployeeStatus.ON_JOB : BaseConstant.EmployeeStatus.DEPARTED);
吴泽佳's avatar
吴泽佳 committed
417 418 419 420 421
            insertList.add(employee);
        }
        workDataDto.setDeleteList(deleteList);
        workDataDto.setInsertList(insertList);
        workDataDto.setUpdateList(updateList);
422
        return workDataDto;
吴泽佳's avatar
吴泽佳 committed
423 424
    }

425
    /**
426 427 428 429
     * @description: 整理 用户表 数据
     * @Author: zejia zj wu
     * @date: 2021/5/27 3:10 下午
     */
430
    private WorkDataDto<UserInfoEntity> userInfoWork(String orgId, List<WxCpDepartDto> wxCpDepartDtoList, String corpId, String qrCodeUrl) {
吴泽佳's avatar
吴泽佳 committed
431 432 433 434
        WorkDataDto<UserInfoEntity> workDataDto = new WorkDataDto<>();
        List<UserInfoEntity> insertList = new ArrayList<>();
        List<UserInfoEntity> deleteList = new ArrayList<>();
        List<UserInfoEntity> updateList = new ArrayList<>();
吴泽佳's avatar
吴泽佳 committed
435
        //获取 数据库用户信息
436
        List<UserInfoEntity> userInfoList = userInfoService.getUserInfoListByOrgIdAll(orgId);
吴泽佳's avatar
吴泽佳 committed
437 438 439 440 441 442

        // 预处理 新数据
        HashMap<String, WxCpUser> hashMap = new HashMap<>();
        for (WxCpDepartDto wxCpDepartDto : wxCpDepartDtoList) {
            List<WxCpUser> wxCpUserList = wxCpDepartDto.getWxCpUserList();
            for (WxCpUser wxCpUser : wxCpUserList) {
443
                hashMap.put(corpId + "_" + wxCpUser.getUserId(), wxCpUser);
吴泽佳's avatar
吴泽佳 committed
444 445 446 447 448
            }
        }


        // 计算 变化数据
吴泽佳's avatar
吴泽佳 committed
449
        for (UserInfoEntity userInfo : userInfoList) {
吴泽佳's avatar
吴泽佳 committed
450 451 452 453 454 455 456 457
            String id = userInfo.getId();
            WxCpUser wxCpUser = hashMap.get(id);
            // 删除
            if (ObjectUtil.isNull(wxCpUser)) {
                deleteList.add(userInfo);
                continue;
            }
            // 更新
458 459
            if (!StringUtils.equals(userInfo.getUiNickname(), wxCpUser.getName()) ||
                    !userInfo.getUiUsername().equals(wxCpUser.getName()) || StrUtil.isBlankIfStr(userInfo.getUiHeadimgMp())
吴泽佳's avatar
吴泽佳 committed
460
                    || !wxCpUser.getUserId().equals(userInfo.getWxcpUid()) || StrUtil.isBlankIfStr(userInfo.getUiWechatXcxQrcode())
461 462
                    || !userInfo.getUiShenfen().equals(String.valueOf(wxCpUser.getIsLeader()))
                    || !StringUtils.equals(userInfo.getUiHeadimg(), wxCpUser.getThumbAvatar())) {
463 464 465 466
                if ((StringUtils.equals(userInfo.getUiHeadimg(), wxCpUser.getThumbAvatar())
                        || StringUtils.isBlank(userInfo.getUiHeadimg()) && StringUtils.isBlank(wxCpUser.getThumbAvatar()))
                        && StringUtils.isNotBlank(userInfo.getUiWechatXcxQrcode())) {
                    log.info("用户头像未变化,无须重新生成qrcode,{}, {}", JsonUtil.toJson(userInfo), JsonUtil.toJson(wxCpUser));
467 468 469
                } else {
                    userInfo.setUiWechatXcxQrcode(orgSyncService.createWechatXcxQrcode(userInfo.getId(), wxCpUser.getThumbAvatar(), qrCodeUrl));
                }
470
                userInfo.setUiNickname(wxCpUser.getName());
吴泽佳's avatar
吴泽佳 committed
471 472
                userInfo.setUiUsername(wxCpUser.getName());
                userInfo.setUiHeadimgMp(wxCpUser.getThumbAvatar());
473
                userInfo.setUiHeadimg(wxCpUser.getThumbAvatar());
474
                userInfo.setWxcpUid(wxCpUser.getUserId());
吴泽佳's avatar
吴泽佳 committed
475
                userInfo.setUiShenfen(String.valueOf(wxCpUser.getIsLeader()));
吴泽佳's avatar
吴泽佳 committed
476 477 478 479 480 481
                updateList.add(userInfo);
            }
            hashMap.remove(id);
        }
        for (String key : hashMap.keySet()) {
            WxCpUser wxCpUser = hashMap.get(key);
吴泽佳's avatar
吴泽佳 committed
482
            UserInfoEntity userInfo = new UserInfoEntity();
吴泽佳's avatar
吴泽佳 committed
483 484 485
            userInfo.setUiTelphone(wxCpUser.getMobile());
            userInfo.setUiUsername(wxCpUser.getName());
            Gender gender = wxCpUser.getGender();
吴泽佳's avatar
吴泽佳 committed
486
            String sex = gender.getCode().equals("1") ? BaseConstant.Gender.MAN : BaseConstant.Gender.WOMEN;
吴泽佳's avatar
吴泽佳 committed
487
            userInfo.setUiSex(sex);
488
            userInfo.setUiNickname(wxCpUser.getName());
吴泽佳's avatar
吴泽佳 committed
489 490 491
            userInfo.setUiHeadimg(wxCpUser.getThumbAvatar());
            userInfo.setUiHeadimgMp(wxCpUser.getThumbAvatar());
            userInfo.setOrgId(orgId);
492
            userInfo.setId(corpId + "_" + wxCpUser.getUserId());
吴泽佳's avatar
吴泽佳 committed
493 494
            userInfo.setUiMobilephoneMp(wxCpUser.getMobile());
            userInfo.setDeletetag("0");
吴泽佳's avatar
吴泽佳 committed
495
            userInfo.setUiShenfen(String.valueOf(wxCpUser.getIsLeader()));
吴泽佳's avatar
吴泽佳 committed
496 497 498 499
            userInfo.setUiEmailMp(wxCpUser.getEmail());
            String nickName = wxCpUser.getName();
            userInfo.setUiUsername(nickName);
            userInfo.setUiUsernameMp(nickName);
吴泽佳's avatar
吴泽佳 committed
500
            userInfo.setUiRzstatus(1);
吴泽佳's avatar
吴泽佳 committed
501 502 503 504 505 506 507 508
            //默认小名片 0:小名片 1:大名片
            userInfo.setUiTypeMp("1");
            userInfo.setLevel(2);
            // 0: 白银  1:黄金  2:钻石
            userInfo.setUiGrade("0");
            userInfo.setUiSource("pc");
            userInfo.setUiRegisterTime(userInfo.getCreatetime());
            userInfo.setUiChannel(null);
509
            userInfo.setWxcpUid(wxCpUser.getUserId());
510
            userInfo.setUiWechatXcxQrcode(orgSyncService.createWechatXcxQrcode(userInfo.getId(), userInfo.getUiHeadimgMp(), qrCodeUrl));
吴泽佳's avatar
吴泽佳 committed
511 512 513 514 515
            insertList.add(userInfo);
        }
        workDataDto.setDeleteList(deleteList);
        workDataDto.setInsertList(insertList);
        workDataDto.setUpdateList(updateList);
516
        return workDataDto;
吴泽佳's avatar
吴泽佳 committed
517 518
    }

519

520
    /**
521 522 523 524
     * @description: 判断是否需要执行 并返回数据MD5
     * @Author: zejia zj wu
     * @date: 2021/5/27 3:10 下午
     */
吴泽佳's avatar
吴泽佳 committed
525 526 527 528 529
    private String isExecute(String isAuto, List<WxCpDepartDto> wxCpDepartDtoList, String md5WxcpData) {
        String digestHex = MD5.create().digestHex(JSONUtil.toJsonStr(wxCpDepartDtoList));
        if (!"Y".equals(isAuto)) {
            return digestHex;
        }
530
        if (digestHex.equals(md5WxcpData)) {
吴泽佳's avatar
吴泽佳 committed
531 532 533 534 535
            return null;
        }
        return digestHex;
    }

536
    /**
537 538 539 540
     * @description: 获取 企业微信 用户列表信息
     * @Author: zejia zj wu
     * @date: 2021/5/27 3:11 下午
     */
吴泽佳's avatar
吴泽佳 committed
541 542 543 544 545 546 547
    private List<WxCpDepartDto> getWxCpUserList(List<WxCpDepart> wxCpDepartList, WxCpDefaultConfigImpl wxCpDefaultConfig) throws Exception {
        WxCpService cpService = new WxCpServiceImpl();
        cpService.setWxCpConfigStorage(wxCpDefaultConfig);
        ArrayList<WxCpDepartDto> wxCpDepartDtoArrayList = new ArrayList<>();
        for (WxCpDepart wxCpDepart : wxCpDepartList) {
            try {
                List<WxCpUser> wxCpUsers = cpService.getUserService().listByDepartment(wxCpDepart.getId(), Boolean.FALSE, 0);
548 549 550 551
                if (wxCpUsers == null) {
                    wxCpUsers = new ArrayList<>();
                }
                wxCpUsers.stream().filter(p -> p.getIsLeader() == null).forEach(p -> p.setIsLeader(0));
吴泽佳's avatar
吴泽佳 committed
552 553 554 555 556 557
                WxCpDepartDto wxCpDepartDto = new WxCpDepartDto();
                BeanUtil.copyProperties(wxCpDepart, wxCpDepartDto, true);
                wxCpDepartDto.setWxCpUserList(wxCpUsers);
                wxCpDepartDto.setMembers(wxCpUsers.size());
                wxCpDepartDtoArrayList.add(wxCpDepartDto);
            } catch (WxErrorException e) {
xd's avatar
xd committed
558
                log.error("======根据企业微信key 获取企业微信员工信息调用失败,错误:{}=======", e.getMessage(), e);
吴泽佳's avatar
吴泽佳 committed
559 560 561 562 563 564
                throw new Exception("根据企业微信key 获取企业微信组织结构调用失败");
            }
        }
        return wxCpDepartDtoArrayList;
    }

565
    /**
566 567 568 569
     * @description: 获取 企业微信 部门聊表信息
     * @Author: zejia zj wu
     * @date: 2021/5/27 3:11 下午
     */
吴泽佳's avatar
吴泽佳 committed
570 571 572
    private List<WxCpDepart> getWxCpDepartList(WxCpDefaultConfigImpl wxCpDefaultConfig) throws Exception {
        WxCpService cpService = new WxCpServiceImpl();
        cpService.setWxCpConfigStorage(wxCpDefaultConfig);
吴泽佳's avatar
吴泽佳 committed
573
        List<WxCpDepart> wxCpDeparts;
吴泽佳's avatar
吴泽佳 committed
574 575 576
        try {
            wxCpDeparts = cpService.getDepartmentService().list(null);
        } catch (WxErrorException e) {
xd's avatar
xd committed
577
            log.error("======根据企业微信key 获取企业微信组织结构调用失败,错误:{}=======", e.getMessage(), e);
吴泽佳's avatar
吴泽佳 committed
578 579 580 581 582 583
            throw new Exception("根据企业微信key 获取企业微信组织结构调用失败");
        }
        return wxCpDeparts;
    }

    public static void main(String[] args) throws Exception {
584 585 586 587
        OrgSyncByWxcpJob orgSyncByWxcpJob = new OrgSyncByWxcpJob();
        WxCpDefaultConfigImpl wxCpDefaultConfig = JSONUtil.toBean(keyStr, WxCpDefaultConfigImpl.class);

        List<WxCpDepart> wxCpDepartList = orgSyncByWxcpJob.getWxCpDepartList(wxCpDefaultConfig); // 机构信息
588
        List<WxCpDepartDto> wxCpDepartDtoList = orgSyncByWxcpJob.getWxCpUserList(wxCpDepartList, wxCpDefaultConfig);
589 590 591 592 593
        log.info("=========================");
//        log.info(JSONUtil.toJsonStr(wxCpDepartDtoList));

        String digestHex = MD5.create().digestHex(JSONUtil.toJsonStr(wxCpDepartDtoList));
        log.info(digestHex);
吴泽佳's avatar
吴泽佳 committed
594 595 596
    }

}