| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- package com.qqflow.engine.domain.ewechat.service;
- import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
- import com.qqflow.engine.domain.ewechat.api.EnterpriseWechatApi;
- import com.qqflow.engine.domain.ewechat.mapper.EnterpriseWechatDepartmentMapper;
- import com.qqflow.engine.domain.ewechat.mapper.EnterpriseWechatMemberMapper;
- import com.qqflow.engine.domain.ewechat.model.enterprise.rsp.EnterpriseWechatUserListRsp;
- import com.qqflow.engine.domain.ewechat.po.EnterpriseWechatDepartment;
- import com.qqflow.engine.domain.ewechat.po.EnterpriseWechatMember;
- import lombok.RequiredArgsConstructor;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.stereotype.Service;
- import java.time.LocalDateTime;
- import java.util.*;
- /**
- * 企微通讯录同步服务(懒加载 + 全量同步)
- */
- @Slf4j
- @Service
- @RequiredArgsConstructor
- public class WecomContactSyncService {
- private final EnterpriseWechatDepartmentMapper departmentMapper;
- private final EnterpriseWechatMemberMapper memberMapper;
- private final EnterpriseWechatApi enterpriseWechatApi;
- private final EnterpriseWechatMsgService wechatMsgService;
- /** 获取子部门列表(从本地DB查询) */
- public List<EnterpriseWechatDepartment> listSubDepartments(Long parentId) {
- return departmentMapper.selectList(
- new LambdaQueryWrapper<EnterpriseWechatDepartment>().eq(EnterpriseWechatDepartment::getParentId, parentId));
- }
- /** 获取部门成员(懒加载) */
- public List<EnterpriseWechatMember> listDepartmentMembers(Long departmentId) {
- List<EnterpriseWechatMember> cached = memberMapper.selectList(
- new LambdaQueryWrapper<EnterpriseWechatMember>().eq(EnterpriseWechatMember::getDepartmentId, departmentId));
- if (!cached.isEmpty()) return cached;
- String accessToken = wechatMsgService.getCorpAccessToken();
- if (accessToken == null) return List.of();
- EnterpriseWechatUserListRsp rsp = enterpriseWechatApi.listDepartmentUsers(accessToken, departmentId);
- if (rsp == null || rsp.getUserlist() == null) return List.of();
- List<EnterpriseWechatMember> members = new ArrayList<>();
- for (var u : rsp.getUserlist()) {
- EnterpriseWechatMember wm = new EnterpriseWechatMember();
- wm.setUserid(u.getUserid());
- wm.setName(u.getName() != null ? u.getName() : u.getUserid());
- wm.setDepartmentId(departmentId);
- wm.setOpenUserid(u.getOpenUserid());
- memberMapper.insert(wm);
- members.add(wm);
- }
- return members;
- }
- // ==================== 全量同步 ====================
- /**
- * 全量同步:部门 + 成员
- * @return 同步结果摘要
- */
- public Map<String, Object> syncAll() {
- String accessToken = wechatMsgService.getCorpAccessToken();
- if (accessToken == null) {
- throw new RuntimeException("无法获取企微 access_token,请检查授权配置");
- }
- Map<String, Object> result = new LinkedHashMap<>();
- Map<String, Integer> deptResult = this.syncAllDepartments(accessToken);
- result.put("departments", deptResult);
- Map<String, Integer> memberResult = this.syncAllMembers(accessToken);
- result.put("members", memberResult);
- return result;
- }
- /**
- * 全量同步部门:从企微拉取完整部门树,upsert 到本地表
- */
- private Map<String, Integer> syncAllDepartments(String accessToken) {
- var rsp = enterpriseWechatApi.listDepartment(accessToken, null);
- if (rsp == null || rsp.getDepartment() == null || rsp.getDepartment().isEmpty()) {
- log.warn("[通讯录同步] 企微返回的部门列表为空");
- return Map.of("total", 0, "inserted", 0, "updated", 0);
- }
- int inserted = 0, updated = 0;
- for (var d : rsp.getDepartment()) {
- EnterpriseWechatDepartment dept = departmentMapper.selectById(d.getId());
- if (dept == null) {
- dept = new EnterpriseWechatDepartment();
- dept.setId(d.getId());
- dept.setCreatedTime(LocalDateTime.now());
- inserted++;
- } else {
- updated++;
- }
- dept.setName(d.getName());
- dept.setParentId(d.getParentid() != null ? d.getParentid() : 0L);
- this.departmentMapper.insertOrUpdate(dept);
- }
- log.info("[通讯录同步] 部门同步完成 | 总数:{} 新增:{} 更新:{}", rsp.getDepartment().size(), inserted, updated);
- return Map.of("total", rsp.getDepartment().size(), "inserted", inserted, "updated", updated);
- }
- /**
- * 全量同步成员:遍历本地已同步的所有部门,从企微拉取各部门成员并 upsert
- */
- private Map<String, Integer> syncAllMembers(String accessToken) {
- List<EnterpriseWechatDepartment> allDepts = departmentMapper.selectList(
- new LambdaQueryWrapper<EnterpriseWechatDepartment>());
- if (allDepts.isEmpty()) {
- log.warn("[通讯录同步] 本地无部门数据,请先同步部门");
- return Map.of("departments", 0, "total", 0, "inserted", 0, "updated", 0);
- }
- int totalInserted = 0, totalUpdated = 0, totalMembers = 0;
- for (var dept : allDepts) {
- var rsp = enterpriseWechatApi.listDepartmentUsers(accessToken, dept.getId());
- if (rsp == null || rsp.getUserlist() == null) continue;
- for (var u : rsp.getUserlist()) {
- totalMembers++;
- // 按 userid + departmentId 查重(一个用户可能在多个部门)
- var existing = memberMapper.selectList(
- new LambdaQueryWrapper<EnterpriseWechatMember>()
- .eq(EnterpriseWechatMember::getUserid, u.getUserid())
- .eq(EnterpriseWechatMember::getDepartmentId, dept.getId()));
- EnterpriseWechatMember wm;
- if (existing != null && !existing.isEmpty()) {
- wm = existing.get(0);
- totalUpdated++;
- } else {
- wm = new EnterpriseWechatMember();
- totalInserted++;
- }
- wm.setUserid(u.getUserid());
- wm.setName(u.getName() != null ? u.getName() : u.getUserid());
- wm.setDepartmentId(dept.getId());
- wm.setOpenUserid(u.getOpenUserid());
- wm.setUpdatedTime(LocalDateTime.now());
- this.memberMapper.insertOrUpdate(wm);
- }
- }
- log.info("[通讯录同步] 成员同步完成 | 部门数:{} 成员总数:{} 新增:{} 更新:{}",
- allDepts.size(), totalMembers, totalInserted, totalUpdated);
- return Map.of("departments", allDepts.size(), "total", totalMembers,
- "inserted", totalInserted, "updated", totalUpdated);
- }
- }
|