OrgSyncByWxcpJob.java 26.6 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;
吴泽佳's avatar
吴泽佳 committed
8
import com.tanpu.feo.feojob.constant.BaseConstant;
吴泽佳's avatar
吴泽佳 committed
9
import com.tanpu.feo.feojob.constant.OrgExtConstant;
10
import com.tanpu.feo.feojob.dao.user.entity.*;
吴泽佳's avatar
吴泽佳 committed
11 12
import com.tanpu.feo.feojob.dto.WorkDataDto;
import com.tanpu.feo.feojob.dto.WxCpDepartDto;
吴泽佳's avatar
吴泽佳 committed
13 14
import com.tanpu.feo.feojob.enums.EmployeeDutyEnum;
import com.tanpu.feo.feojob.enums.RoleTypeEnum;
15 16
import com.tanpu.feo.feojob.feign.CommonResp;
import com.tanpu.feo.feojob.feign.fatools.FeignClientForFatools;
吴泽佳's avatar
吴泽佳 committed
17 18 19 20 21 22 23 24 25
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;
26 27
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
28
import org.springframework.beans.factory.annotation.Value;
吴泽佳's avatar
吴泽佳 committed
29 30 31 32
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
吴泽佳's avatar
吴泽佳 committed
33 34 35 36
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
37
import java.util.stream.Collectors;
吴泽佳's avatar
吴泽佳 committed
38 39 40

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

吴泽佳's avatar
吴泽佳 committed
48
    final static String keyStr = "{\"corpId\":\"ww08675a3a48c9e8a2\",\"agentId\":\"1000013\",\"corpSecret\":\"l7eLNC5DDNxmucc9emHsEaSXym4VKDy_D5w4IoOpvqk\",\"token\":\"E1zDvDkXWt\",\"aesKey\":\"43P8lbP5yt8AHLOUPGBPS252c60K9Vzofzm5NOxHHeP\",\"sendMessageAppId\":\"wxe177c62fa1e1c602\"}\n";
吴泽佳's avatar
吴泽佳 committed
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
    @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
66
    private OrgSyncService orgSyncService;
67 68
    @Value("${tanpu.sync.job.skipped:true}")
    private boolean jobSkipped;
69 70
    @Resource
    private FeignClientForFatools feignClientForFatools;
吴泽佳's avatar
吴泽佳 committed
71

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

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

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

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

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

            //4 判断是否需要 同步
吴泽佳's avatar
吴泽佳 committed
116
            String digestHex = isExecute(isAuto, wxCpDepartDtoList, orgExtEntity.getMd5WxcpData());
吴泽佳's avatar
吴泽佳 committed
117 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
    private String getQrCodeUrl(String orgId) {
        CommonResp<String> commonResp = feignClientForFatools.getQrCodeUrl(orgId);
        if (commonResp.isNotSuccess()) {
            throw new RuntimeException(commonResp.statusCode + ", " + commonResp.getMessage());
        }
        return commonResp.getAttributes();
    }

152
    /**
153 154 155 156
     * @description: 整理 员工与角色关联关系 数据
     * @Author: zejia zj wu
     * @date: 2021/5/27 3:08 下午
     */
吴泽佳's avatar
吴泽佳 committed
157 158 159 160 161
    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
162
        //获取 数据库 部门员工关系 信息
163
        List<EmployeeRoleEntity> employeeRoleList = employeeRoleService.findInfoByOrgId(orgId);
吴泽佳's avatar
吴泽佳 committed
164
        // 获取 role
165
        Map<String, String> roleMap = roleService.findInfoNoAdmin();
吴泽佳's avatar
吴泽佳 committed
166 167 168 169 170 171
        // 预处理 新数据
        HashMap<String, WxCpUser> hashMap = new HashMap<>();
        for (WxCpDepartDto wxCpDepartDto : wxCpDepartDtoList) {
            List<WxCpUser> wxCpUserList = wxCpDepartDto.getWxCpUserList();
            for (WxCpUser wxCpUser : wxCpUserList) {
                // key employee_id + '&' + role_id
吴泽佳's avatar
吴泽佳 committed
172
                String type = wxCpUser.getIsLeader() == 1 ? RoleTypeEnum.TEAM.code : RoleTypeEnum.IFA.code;
173
                hashMap.put(corpId + "_" + wxCpUser.getUserId() + "&" + roleMap.get(type), wxCpUser);
吴泽佳's avatar
吴泽佳 committed
174 175
            }
        }
吴泽佳's avatar
吴泽佳 committed
176
        for (EmployeeRoleEntity employeeRole : employeeRoleList) {
吴泽佳's avatar
吴泽佳 committed
177 178 179 180 181 182 183 184 185 186 187 188 189
            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);
        }
190 191
        Map<String, List<EmployeeRoleEntity>> map = employeeRoleList.stream().collect(Collectors.groupingBy(EmployeeRoleEntity::getEmployeeId));
        String adminRoleId = roleMap.get(RoleTypeEnum.ADMIN.code);
吴泽佳's avatar
吴泽佳 committed
192 193 194 195
        for (String key : hashMap.keySet()) {
            String[] split = key.split("&");
            String employeeId = split[0];
            String roleId = split[1];
196 197 198 199 200 201
            // 如果已经有一个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
202
            EmployeeRoleEntity employeeRole = new EmployeeRoleEntity();
吴泽佳's avatar
吴泽佳 committed
203 204 205 206 207 208 209 210
            employeeRole.setEmployeeId(employeeId);
            employeeRole.setRoleId(roleId);
            employeeRole.setOrgId(orgId);
            insertList.add(employeeRole);
        }
        workDataDto.setDeleteList(deleteList);
        workDataDto.setInsertList(insertList);
        workDataDto.setUpdateList(updateList);
211
        return workDataDto;
吴泽佳's avatar
吴泽佳 committed
212 213 214

    }

215
    /**
216 217 218 219
     * @description: 整理 部门与员工关联关系 数据
     * @Author: zejia zj wu
     * @date: 2021/5/27 3:08 下午
     */
吴泽佳's avatar
吴泽佳 committed
220 221 222 223 224
    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
225
        //获取 数据库 部门员工关系 信息
226
        List<DepartmentEmployeeEntity> departmentEmployeeList = departmentEmployeeService.findInfoByOrgId(orgId);
吴泽佳's avatar
吴泽佳 committed
227 228 229 230 231 232
        // 预处理 新数据
        HashMap<String, WxCpUser> hashMap = new HashMap<>();
        for (WxCpDepartDto wxCpDepartDto : wxCpDepartDtoList) {
            List<WxCpUser> wxCpUserList = wxCpDepartDto.getWxCpUserList();
            for (WxCpUser wxCpUser : wxCpUserList) {
                // key department_id + '&' + employee_id
233
                hashMap.put(orgId + "_" + wxCpDepartDto.getId() + "&" + corpId + "_" + wxCpUser.getUserId(), wxCpUser);
吴泽佳's avatar
吴泽佳 committed
234 235 236

            }
        }
吴泽佳's avatar
吴泽佳 committed
237
        for (DepartmentEmployeeEntity departmentEmployee : departmentEmployeeList) {
吴泽佳's avatar
吴泽佳 committed
238 239 240 241 242 243 244 245 246 247
            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;
            }
            //更新
248
            String type = wxCpUser.getIsLeader() == 1 ? EmployeeDutyEnum.DIRECTOR.code : EmployeeDutyEnum.STAFF.code;
吴泽佳's avatar
吴泽佳 committed
249 250 251 252 253 254 255 256
            if (!departmentEmployee.getType().equals(type)) {
                departmentEmployee.setType(type);
                updateList.add(departmentEmployee);
            }
            hashMap.remove(key);
        }
        for (String s : hashMap.keySet()) {
            WxCpUser wxCpUser = hashMap.get(s);
257
            String type = wxCpUser.getIsLeader() == 1 ? EmployeeDutyEnum.DIRECTOR.code : EmployeeDutyEnum.STAFF.code;
吴泽佳's avatar
吴泽佳 committed
258 259 260
            String[] split = s.split("&");
            String departmentId = split[0];
            String employeeId = split[1];
吴泽佳's avatar
吴泽佳 committed
261
            DepartmentEmployeeEntity departmentEmployee = new DepartmentEmployeeEntity();
吴泽佳's avatar
吴泽佳 committed
262 263 264 265 266 267 268 269 270
            departmentEmployee.setEmployeeId(employeeId);
            departmentEmployee.setDepartmentId(departmentId);
            departmentEmployee.setType(type);
            departmentEmployee.setOrgId(orgId);
            insertList.add(departmentEmployee);
        }
        workDataDto.setDeleteList(deleteList);
        workDataDto.setInsertList(insertList);
        workDataDto.setUpdateList(updateList);
271
        return workDataDto;
吴泽佳's avatar
吴泽佳 committed
272 273
    }

274
    /**
275 276 277 278
     * @description: 整理 部门机构 数据
     * @Author: zejia zj wu
     * @date: 2021/5/27 3:09 下午
     */
吴泽佳's avatar
吴泽佳 committed
279 280 281 282 283
    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
284
        //获取 数据库 部门 信息
285
        List<DepartmentEntity> departmentList = departmentService.findDepartmentByOrgId(orgId);
吴泽佳's avatar
吴泽佳 committed
286 287 288 289 290 291 292
        // 预处理 新数据
        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
293
        for (DepartmentEntity department : departmentList) {
吴泽佳's avatar
吴泽佳 committed
294 295 296 297 298 299 300 301 302
            String departmentId = department.getDepartmentId();
            WxCpDepartDto wxCpDepartDto = hashMap.get(departmentId);
            //删除
            if (ObjectUtil.isNull(wxCpDepartDto)) {
                deleteList.add(department);
                continue;
            }
            //更新
            Long parentId1 = wxCpDepartDto.getParentId();
303
            String parentId = ObjectUtil.isNull(hashMap2.get(parentId1)) ? null : orgId + "_" + parentId1;
吴泽佳's avatar
吴泽佳 committed
304
            Integer level = getLevel(hashMap2, wxCpDepartDto.getId());
吴泽佳's avatar
吴泽佳 committed
305
            if (!department.getDepartmentName().equals(wxCpDepartDto.getName()) || StrUtil.compareIgnoreCase(department.getParentDepartId(), parentId, false) != 0
306
                    || !department.getMembers().equals(wxCpDepartDto.getMembers()) || !level.equals(department.getLevel())) {
吴泽佳's avatar
吴泽佳 committed
307 308 309
                department.setDepartmentName(wxCpDepartDto.getName());
                department.setParentDepartId(parentId);
                department.setMembers(wxCpDepartDto.getMembers());
吴泽佳's avatar
吴泽佳 committed
310
                department.setLevel(level);
吴泽佳's avatar
吴泽佳 committed
311 312 313 314 315 316 317 318
                updateList.add(department);
            }
            hashMap.remove(departmentId);
        }
        //修改
        for (String departmentId : hashMap.keySet()) {
            WxCpDepartDto wxCpDepartDto = hashMap.get(departmentId);
            Long parentId1 = wxCpDepartDto.getParentId();
319
            String parentId = ObjectUtil.isNull(hashMap2.get(parentId1)) ? null : orgId + "_" + parentId1;
吴泽佳's avatar
吴泽佳 committed
320
            DepartmentEntity department = new DepartmentEntity();
吴泽佳's avatar
吴泽佳 committed
321 322 323 324 325 326 327 328 329 330 331
            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);
332
        return workDataDto;
吴泽佳's avatar
吴泽佳 committed
333 334
    }

335
    /**
336 337 338 339
     * @description: 获取部门等级
     * @Author: zejia zj wu
     * @date: 2021/5/27 3:09 下午
     */
吴泽佳's avatar
吴泽佳 committed
340
    private Integer getLevel(HashMap<Long, WxCpDepartDto> hashMap2, Long id) {
吴泽佳's avatar
吴泽佳 committed
341 342
        Long parentId = hashMap2.get(id).getParentId();
        if (ObjectUtil.isNull(hashMap2.get(parentId))) {
吴泽佳's avatar
吴泽佳 committed
343 344
            return 1;
        }
345
        return 1 + getLevel(hashMap2, parentId);
吴泽佳's avatar
吴泽佳 committed
346 347
    }

348
    /**
349 350 351 352
     * @description: 整理 员工 数据
     * @Author: zejia zj wu
     * @date: 2021/5/27 3:09 下午
     */
吴泽佳's avatar
吴泽佳 committed
353 354 355 356 357
    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
358
        //获取 数据库 员工 信息
359
        List<EmployeeEntity> employeeList = employeeService.getEmployeeSListByOrgId(orgId);
吴泽佳's avatar
吴泽佳 committed
360 361 362 363 364 365

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

        // 计算 变化数据
吴泽佳's avatar
吴泽佳 committed
371
        for (EmployeeEntity employee : employeeList) {
吴泽佳's avatar
吴泽佳 committed
372 373 374 375 376 377 378 379 380 381
            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
382
                    StrUtil.isBlank(employee.getBoundWechat()) || !employee.getStatus().equals(status)) {
吴泽佳's avatar
吴泽佳 committed
383 384 385 386 387 388 389 390 391 392 393 394 395
                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
396
            EmployeeEntity employee = new EmployeeEntity();
397
            employee.setEmployeeId(corpId + "_" + wxCpUser.getUserId());
吴泽佳's avatar
吴泽佳 committed
398 399 400 401 402
            employee.setName(wxCpUser.getName());
            employee.setPhone(wxCpUser.getMobile());
            employee.setMail(wxCpUser.getEmail());
            employee.setNumber(null);
            employee.setOrgId(orgId);
吴泽佳's avatar
吴泽佳 committed
403
            employee.setBoundWechat(orgId + "_" + wxCpUser.getUserId());
吴泽佳's avatar
吴泽佳 committed
404
            employee.setStatus(wxCpUser.getStatus() == 1 ? BaseConstant.EmployeeStatus.ON_JOB : BaseConstant.EmployeeStatus.DEPARTED);
吴泽佳's avatar
吴泽佳 committed
405 406 407 408 409
            insertList.add(employee);
        }
        workDataDto.setDeleteList(deleteList);
        workDataDto.setInsertList(insertList);
        workDataDto.setUpdateList(updateList);
410
        return workDataDto;
吴泽佳's avatar
吴泽佳 committed
411 412
    }

413
    /**
414 415 416 417
     * @description: 整理 用户表 数据
     * @Author: zejia zj wu
     * @date: 2021/5/27 3:10 下午
     */
418
    private WorkDataDto<UserInfoEntity> userInfoWork(String orgId, List<WxCpDepartDto> wxCpDepartDtoList, String corpId, String qrCodeUrl) {
吴泽佳's avatar
吴泽佳 committed
419 420 421 422
        WorkDataDto<UserInfoEntity> workDataDto = new WorkDataDto<>();
        List<UserInfoEntity> insertList = new ArrayList<>();
        List<UserInfoEntity> deleteList = new ArrayList<>();
        List<UserInfoEntity> updateList = new ArrayList<>();
吴泽佳's avatar
吴泽佳 committed
423
        //获取 数据库用户信息
424
        List<UserInfoEntity> userInfoList = userInfoService.getUserInfoListByOrgIdAll(orgId);
吴泽佳's avatar
吴泽佳 committed
425 426 427 428 429 430

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


        // 计算 变化数据
吴泽佳's avatar
吴泽佳 committed
437
        for (UserInfoEntity userInfo : userInfoList) {
吴泽佳's avatar
吴泽佳 committed
438 439 440 441 442 443 444 445
            String id = userInfo.getId();
            WxCpUser wxCpUser = hashMap.get(id);
            // 删除
            if (ObjectUtil.isNull(wxCpUser)) {
                deleteList.add(userInfo);
                continue;
            }
            // 更新
446 447
            if (!StringUtils.equals(userInfo.getUiNickname(), wxCpUser.getName()) ||
                    !userInfo.getUiUsername().equals(wxCpUser.getName()) || StrUtil.isBlankIfStr(userInfo.getUiHeadimgMp())
吴泽佳's avatar
吴泽佳 committed
448 449
                    || !wxCpUser.getUserId().equals(userInfo.getWxcpUid()) || StrUtil.isBlankIfStr(userInfo.getUiWechatXcxQrcode())
                    || !userInfo.getUiShenfen().equals(String.valueOf(wxCpUser.getIsLeader()))) {
450
                userInfo.setUiNickname(wxCpUser.getName());
吴泽佳's avatar
吴泽佳 committed
451 452
                userInfo.setUiUsername(wxCpUser.getName());
                userInfo.setUiHeadimgMp(wxCpUser.getThumbAvatar());
453
                userInfo.setWxcpUid(wxCpUser.getUserId());
吴泽佳's avatar
吴泽佳 committed
454
                userInfo.setUiShenfen(String.valueOf(wxCpUser.getIsLeader()));
455
                userInfo.setUiWechatXcxQrcode(orgSyncService.createWechatXcxQrcode(userInfo.getId(), wxCpUser.getThumbAvatar(), qrCodeUrl));
吴泽佳's avatar
吴泽佳 committed
456 457 458 459 460 461
                updateList.add(userInfo);
            }
            hashMap.remove(id);
        }
        for (String key : hashMap.keySet()) {
            WxCpUser wxCpUser = hashMap.get(key);
吴泽佳's avatar
吴泽佳 committed
462
            UserInfoEntity userInfo = new UserInfoEntity();
吴泽佳's avatar
吴泽佳 committed
463 464 465
            userInfo.setUiTelphone(wxCpUser.getMobile());
            userInfo.setUiUsername(wxCpUser.getName());
            Gender gender = wxCpUser.getGender();
吴泽佳's avatar
吴泽佳 committed
466
            String sex = gender.getCode().equals("1") ? BaseConstant.Gender.MAN : BaseConstant.Gender.WOMEN;
吴泽佳's avatar
吴泽佳 committed
467
            userInfo.setUiSex(sex);
468
            userInfo.setUiNickname(wxCpUser.getName());
吴泽佳's avatar
吴泽佳 committed
469 470 471
            userInfo.setUiHeadimg(wxCpUser.getThumbAvatar());
            userInfo.setUiHeadimgMp(wxCpUser.getThumbAvatar());
            userInfo.setOrgId(orgId);
472
            userInfo.setId(corpId + "_" + wxCpUser.getUserId());
吴泽佳's avatar
吴泽佳 committed
473 474
            userInfo.setUiMobilephoneMp(wxCpUser.getMobile());
            userInfo.setDeletetag("0");
吴泽佳's avatar
吴泽佳 committed
475
            userInfo.setUiShenfen(String.valueOf(wxCpUser.getIsLeader()));
吴泽佳's avatar
吴泽佳 committed
476 477 478 479
            userInfo.setUiEmailMp(wxCpUser.getEmail());
            String nickName = wxCpUser.getName();
            userInfo.setUiUsername(nickName);
            userInfo.setUiUsernameMp(nickName);
吴泽佳's avatar
吴泽佳 committed
480
            userInfo.setUiRzstatus(1);
吴泽佳's avatar
吴泽佳 committed
481 482 483 484 485 486 487 488
            //默认小名片 0:小名片 1:大名片
            userInfo.setUiTypeMp("1");
            userInfo.setLevel(2);
            // 0: 白银  1:黄金  2:钻石
            userInfo.setUiGrade("0");
            userInfo.setUiSource("pc");
            userInfo.setUiRegisterTime(userInfo.getCreatetime());
            userInfo.setUiChannel(null);
489
            userInfo.setWxcpUid(wxCpUser.getUserId());
490
            userInfo.setUiWechatXcxQrcode(orgSyncService.createWechatXcxQrcode(userInfo.getId(), userInfo.getUiHeadimgMp(), qrCodeUrl));
吴泽佳's avatar
吴泽佳 committed
491 492 493 494 495
            insertList.add(userInfo);
        }
        workDataDto.setDeleteList(deleteList);
        workDataDto.setInsertList(insertList);
        workDataDto.setUpdateList(updateList);
496
        return workDataDto;
吴泽佳's avatar
吴泽佳 committed
497 498
    }

499

500
    /**
501 502 503 504
     * @description: 判断是否需要执行 并返回数据MD5
     * @Author: zejia zj wu
     * @date: 2021/5/27 3:10 下午
     */
吴泽佳's avatar
吴泽佳 committed
505 506 507 508 509
    private String isExecute(String isAuto, List<WxCpDepartDto> wxCpDepartDtoList, String md5WxcpData) {
        String digestHex = MD5.create().digestHex(JSONUtil.toJsonStr(wxCpDepartDtoList));
        if (!"Y".equals(isAuto)) {
            return digestHex;
        }
510
        if (digestHex.equals(md5WxcpData)) {
吴泽佳's avatar
吴泽佳 committed
511 512 513 514 515
            return null;
        }
        return digestHex;
    }

516
    /**
517 518 519 520
     * @description: 获取 企业微信 用户列表信息
     * @Author: zejia zj wu
     * @date: 2021/5/27 3:11 下午
     */
吴泽佳's avatar
吴泽佳 committed
521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540
    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);
                WxCpDepartDto wxCpDepartDto = new WxCpDepartDto();
                BeanUtil.copyProperties(wxCpDepart, wxCpDepartDto, true);
                wxCpDepartDto.setWxCpUserList(wxCpUsers);
                wxCpDepartDto.setMembers(wxCpUsers.size());
                wxCpDepartDtoArrayList.add(wxCpDepartDto);
            } catch (WxErrorException e) {
                log.error("======根据企业微信key 获取企业微信员工信息调用失败,错误:{}=======", e.getMessage());
                throw new Exception("根据企业微信key 获取企业微信组织结构调用失败");
            }
        }
        return wxCpDepartDtoArrayList;
    }

541
    /**
542 543 544 545
     * @description: 获取 企业微信 部门聊表信息
     * @Author: zejia zj wu
     * @date: 2021/5/27 3:11 下午
     */
吴泽佳's avatar
吴泽佳 committed
546 547 548
    private List<WxCpDepart> getWxCpDepartList(WxCpDefaultConfigImpl wxCpDefaultConfig) throws Exception {
        WxCpService cpService = new WxCpServiceImpl();
        cpService.setWxCpConfigStorage(wxCpDefaultConfig);
吴泽佳's avatar
吴泽佳 committed
549
        List<WxCpDepart> wxCpDeparts;
吴泽佳's avatar
吴泽佳 committed
550 551 552 553 554 555 556 557 558 559
        try {
            wxCpDeparts = cpService.getDepartmentService().list(null);
        } catch (WxErrorException e) {
            log.error("======根据企业微信key 获取企业微信组织结构调用失败,错误:{}=======", e.getMessage());
            throw new Exception("根据企业微信key 获取企业微信组织结构调用失败");
        }
        return wxCpDeparts;
    }

    public static void main(String[] args) throws Exception {
560 561 562 563
        OrgSyncByWxcpJob orgSyncByWxcpJob = new OrgSyncByWxcpJob();
        WxCpDefaultConfigImpl wxCpDefaultConfig = JSONUtil.toBean(keyStr, WxCpDefaultConfigImpl.class);

        List<WxCpDepart> wxCpDepartList = orgSyncByWxcpJob.getWxCpDepartList(wxCpDefaultConfig); // 机构信息
564
        List<WxCpDepartDto> wxCpDepartDtoList = orgSyncByWxcpJob.getWxCpUserList(wxCpDepartList, wxCpDefaultConfig);
565 566 567 568 569
        log.info("=========================");
//        log.info(JSONUtil.toJsonStr(wxCpDepartDtoList));

        String digestHex = MD5.create().digestHex(JSONUtil.toJsonStr(wxCpDepartDtoList));
        log.info(digestHex);
吴泽佳's avatar
吴泽佳 committed
570 571 572
    }

}