Jelajahi Sumber

更新用户

xueyiming 6 bulan lalu
induk
melakukan
d847b48067

+ 3 - 0
we-com-server/src/main/java/com/tzld/piaoquan/wecom/common/constant/WeComConstant.java

@@ -33,5 +33,8 @@ public interface WeComConstant {
     //创建企业群发
     //创建企业群发
     String POST_WE_COM_ADD_MSG_TEMPLATE = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_msg_template";
     String POST_WE_COM_ADD_MSG_TEMPLATE = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_msg_template";
 
 
+    //批量获取客户详情
+    String POST_WE_COM_GET_BY_USER = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/batch/get_by_user";
+
 
 
 }
 }

+ 1 - 1
we-com-server/src/main/java/com/tzld/piaoquan/wecom/job/WeComHistoryDataJob1.java

@@ -52,7 +52,7 @@ public class WeComHistoryDataJob1 {
 
 
 
 
     @XxlJob("saveHistoryMessageJob1")
     @XxlJob("saveHistoryMessageJob1")
-    public ReturnT<String> selectHistoryMessageByDay1(String param) {
+    public ReturnT<String> selectHistoryMessageByDay(String param) {
         XxlJobParam xxlJobParam = new XxlJobParam();
         XxlJobParam xxlJobParam = new XxlJobParam();
         if (StringUtils.isNotEmpty(param)) {
         if (StringUtils.isNotEmpty(param)) {
             xxlJobParam = JSONObject.parseObject(param, XxlJobParam.class);
             xxlJobParam = JSONObject.parseObject(param, XxlJobParam.class);

+ 1 - 78
we-com-server/src/main/java/com/tzld/piaoquan/wecom/job/WeComMessageDataJob.java

@@ -143,6 +143,7 @@ public class WeComMessageDataJob {
             staffId = Long.parseLong(param);
             staffId = Long.parseLong(param);
         }
         }
         UserExample example = new UserExample();
         UserExample example = new UserExample();
+        example.createCriteria().andExternalUserId3rdPartyIsNotNull();
         long count = userMapper.countByExample(example);
         long count = userMapper.countByExample(example);
         int page = 1;
         int page = 1;
         int pageSize = 1000;
         int pageSize = 1000;
@@ -359,83 +360,5 @@ public class WeComMessageDataJob {
         return true;
         return true;
     }
     }
 
 
-    public boolean pushMessage1(List<String> sendUserList, SendMessage sendMessage) {
-        List<JSONObject> pushList = new ArrayList<>();
-        StaffExample staffExample = new StaffExample();
-        staffExample.createCriteria().andIdEqualTo(sendMessage.getStaffId());
-        List<Staff> staffList = staffMapper.selectByExample(staffExample);
-        Staff staff = staffList.get(0);
-        String text = messageService.getMessageText();
-
-        JSONObject jsonObject = new JSONObject();
-        jsonObject.put("chat_type", "single");
-        jsonObject.put("text", text);
-        jsonObject.put("sender", staff.getCarrierId());
-        JSONArray attachments = new JSONArray();
-        List<Long> videoIdList = new ArrayList<>();
-        videoIdList.add(sendMessage.getVideoId1());
-        videoIdList.add(sendMessage.getVideoId2());
-        videoIdList.add(sendMessage.getVideoId3());
-        for (Long videoId : videoIdList) {
-            JSONObject attachment = new JSONObject();
-            attachment.put("msgtype", "miniprogram");
-            MessageAttachmentExample example = new MessageAttachmentExample();
-            example.createCriteria().andMiniprogramVideoIdEqualTo(videoId);
-            List<MessageAttachment> messageAttachmentList = messageAttachmentMapper.selectByExample(example);
-            if (CollectionUtils.isEmpty(messageAttachmentList)) {
-                throw new RuntimeException("附件信息查询异常");
-            }
-            MessageAttachment messageAttachment = messageAttachmentList.get(0);
-            JSONObject miniprogram = new JSONObject();
-            miniprogram.put("appid", messageAttachment.getAppid());
-            String title = messageAttachment.getTitle();
-            if (title.getBytes(StandardCharsets.UTF_8).length > MAX_BYTES) {
-                title = ToolUtils.truncateString(title, MAX_BYTES - 3) + "...";
-            }
-            miniprogram.put("title", title);
-            String picMediaId = messageAttachmentService.getPicMediaId(messageAttachment.getCover());
-            if (StringUtils.isEmpty(picMediaId)) {
-                log.error("pushMessage getPicMediaId error cover={}", messageAttachment.getCover());
-                return false;
-            }
-            miniprogram.put("pic_media_id", picMediaId);
-            String page = "";
-            String key = staff.getCarrierId() + "_" + videoId;
-            if (pageMap.containsKey(key)) {
-                page = pageMap.get(key);
-            } else {
-                page = messageAttachmentService.getPage(staff, videoId);
-                pageMap.put(key, page);
-            }
-            if (StringUtils.isEmpty(page)) {
-                log.error("pushMessage get page error videoId={} staff={}", videoId, staff);
-                return false;
-            }
-            miniprogram.put("page", page);
-            attachment.put("miniprogram", miniprogram);
-            attachments.add(0, attachment);
-        }
-        jsonObject.put("attachments", attachments);
-        List<List<String>> lists = Lists.partition(sendUserList, 10000);
-        for (List<String> list : lists) {
-            JSONArray externalUserIds = JSONArray.parseArray(JSON.toJSONString(list));
-            JSONObject newJSONObject = new JSONObject();
-            newJSONObject.putAll(jsonObject);
-            newJSONObject.put("external_userid", externalUserIds);
-            pushList.add(newJSONObject);
-        }
-        if (CollectionUtils.isEmpty(pushList)) {
-            return false;
-        }
-        for (JSONObject pushJsonObject : pushList) {
-            log.info("pushMessage pushJsonObject={}", pushJsonObject);
-            boolean flag = messageService.pushMessage(pushJsonObject);
-            if (!flag) {
-                return flag;
-            }
-        }
-        return true;
-    }
-
 
 
 }
 }

+ 358 - 0
we-com-server/src/main/java/com/tzld/piaoquan/wecom/job/WeComMessageDataJob1.java

@@ -0,0 +1,358 @@
+package com.tzld.piaoquan.wecom.job;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.aliyun.odps.data.Record;
+import com.google.common.collect.Lists;
+import com.tzld.piaoquan.wecom.dao.mapper.*;
+import com.tzld.piaoquan.wecom.model.bo.PushMessage;
+import com.tzld.piaoquan.wecom.model.po.*;
+import com.tzld.piaoquan.wecom.service.MessageAttachmentService;
+import com.tzld.piaoquan.wecom.service.MessageService;
+import com.tzld.piaoquan.wecom.utils.*;
+import com.tzld.piaoquan.wecom.utils.page.Page;
+import com.xxl.job.core.biz.model.ReturnT;
+import com.xxl.job.core.handler.annotation.XxlJob;
+import lombok.extern.log4j.Log4j2;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static com.tzld.piaoquan.wecom.common.constant.RedisConstant.GUARANTEED_MINIPROGRAM_KEY;
+import static com.tzld.piaoquan.wecom.common.constant.TimeConstant.MILLISECOND_DAY;
+
+@Log4j2
+@Component
+public class WeComMessageDataJob1 {
+
+    private static final HttpPoolClient httpPoolClientDefault = HttpClientUtil.create(30000, 30000, 2000, 5000, 5, 30000);
+
+    @Autowired
+    private UserMapper userMapper;
+
+    @Autowired
+    private MessageAttachmentMapper messageAttachmentMapper;
+
+    @Autowired
+    private RedisTemplate<String, Object> redisTemplate;
+
+    @Autowired
+    private MessageService messageService;
+
+    @Autowired
+    private MessageAttachmentService messageAttachmentService;
+
+    @Autowired
+    private StaffWithUserMapper staffWithUserMapper;
+
+    @Autowired
+    private StaffMapper staffMapper;
+
+    @Autowired
+    SendMessageMapper sendMessageMapper;
+
+    private static final int MAX_VIDEO_NUM = 3;
+
+    //发送小程序标题限制字节数
+    private static final int MAX_BYTES = 64;
+
+    //历史优质视频可推送用户列表
+    List<PushMessage> goodHistoryPushList = new ArrayList<>();
+
+    //保底视频列表
+    List<Long> guaranteedVideoIdList = new ArrayList<>();
+
+    //从缓存中获取的保底视频数量
+    int getGuaranteedVideoIdNum = 0;
+
+    Map<String, String> pageMap = new HashMap<>();
+
+    //初始化操作
+    void init() {
+        //历史优质视频获取
+        String sql = String.format("SELECT * FROM loghubods.history_good_video_can_push_user_list where dt = %s;", DateUtil.getBeforeDayDateString());
+        List<Record> recordList = OdpsUtil.getOdpsData(sql);
+        if (CollectionUtils.isEmpty(recordList)) {
+            return;
+        }
+        List<PushMessage> list = new ArrayList<>();
+        for (Record record : recordList) {
+            PushMessage pushMessage = new PushMessage();
+            Long videoId = Long.parseLong((String) record.get(0));
+            Set<Long> userIds = new HashSet<>(JSONObject.parseArray((String) record.get(1), Long.class));
+            pushMessage.setVideoId(videoId);
+            pushMessage.setUserIds(userIds);
+            list.add(pushMessage);
+        }
+        goodHistoryPushList = list;
+
+        getGuaranteedVideoIdNum = 0;
+        //保底视频获取
+        List<Long> videoIdList = Objects.requireNonNull(redisTemplate.opsForList().range(GUARANTEED_MINIPROGRAM_KEY, 0, -1))
+                .stream().map(o -> (Integer) o).map(String::valueOf).map(Long::parseLong).collect(Collectors.toList());
+        if (CollectionUtils.isEmpty(videoIdList)) {
+            log.error("推送消息初始化失败,保底数据为空");
+            throw new RuntimeException("保底数据为空");
+        }
+        List<Long> saveVideoIds = new ArrayList<>();
+        for (Long videoId : videoIdList) {
+            getGuaranteedVideoIdNum++;
+            MessageAttachmentExample example = new MessageAttachmentExample();
+            example.createCriteria().andMiniprogramVideoIdEqualTo(videoId);
+            List<MessageAttachment> messageAttachmentList = messageAttachmentMapper.selectByExample(example);
+            if (CollectionUtils.isEmpty(messageAttachmentList)) {
+                continue;
+            }
+            MessageAttachment messageAttachment = messageAttachmentList.get(0);
+            if (messageAttachment.getSendTime() != null
+                    && DateUtil.dateDifference(new Date(), messageAttachment.getSendTime()) < 180 * MILLISECOND_DAY) {
+                continue;
+            }
+            saveVideoIds.add(videoId);
+            if (saveVideoIds.size() >= MAX_VIDEO_NUM) {
+                break;
+            }
+        }
+        if (saveVideoIds.size() < MAX_VIDEO_NUM) {
+            log.error("推送消息初始化失败,保底数据不足");
+            throw new RuntimeException("保底数据不足");
+        }
+        guaranteedVideoIdList = saveVideoIds;
+    }
+
+    @XxlJob("assembleSendMessageJob1")
+    public ReturnT<String> assembleSendMessage(String param) {
+        init();
+        Long staffId = null;
+        if (StringUtils.isNotEmpty(param)) {
+            staffId = Long.parseLong(param);
+        }
+        UserExample example = new UserExample();
+        long count = userMapper.countByExample(example);
+        int page = 1;
+        int pageSize = 1000;
+        long totalPageSize = count / pageSize + 1;
+        for (; page <= totalPageSize; page++) {
+            example.setPage(new Page<>(page, pageSize));
+            List<User> userList = userMapper.selectByExample(example);
+            if (CollectionUtils.isEmpty(userList)) {
+                continue;
+            }
+            //落库逻辑
+            List<SendMessage> allSeneMessageList = new ArrayList<>();
+            for (User user : userList) {
+                List<SendMessage> sendMessageList = getSendMessage(user, staffId);
+                if (!CollectionUtils.isEmpty(sendMessageList)) {
+                    allSeneMessageList.addAll(sendMessageList);
+                }
+            }
+            if (!CollectionUtils.isEmpty(allSeneMessageList)) {
+                sendMessageMapper.insertList(allSeneMessageList);
+            }
+        }
+        //组装好当天要发送的消息后  记录时间  删除保底数据
+        saveGuaranteedVideoIdList(guaranteedVideoIdList);
+        return ReturnT.SUCCESS;
+    }
+
+    public void saveGuaranteedVideoIdList(List<Long> videoIdList) {
+        MessageAttachmentExample example = new MessageAttachmentExample();
+        example.createCriteria().andMiniprogramVideoIdIn(videoIdList);
+        List<MessageAttachment> messageAttachmentList = messageAttachmentMapper.selectByExample(example);
+        for (MessageAttachment messageAttachment : messageAttachmentList) {
+            MessageAttachment updateMessageAttachment = new MessageAttachment();
+            updateMessageAttachment.setId(messageAttachment.getId());
+            updateMessageAttachment.setSendTime(new Date());
+            messageAttachmentMapper.updateByPrimaryKeySelective(updateMessageAttachment);
+        }
+        log.info("getGuaranteedVideoIdNum={}", getGuaranteedVideoIdNum);
+        //移除从redis中获取的保底数据
+        for (int i = 0; i < getGuaranteedVideoIdNum; i++) {
+            redisTemplate.opsForList().leftPop(GUARANTEED_MINIPROGRAM_KEY);
+        }
+    }
+
+    public List<SendMessage> getSendMessage(User user, Long staffId) {
+        StaffWithUserExample example = new StaffWithUserExample();
+        StaffWithUserExample.Criteria criteria = example.createCriteria();
+        criteria.andUserIdEqualTo(user.getId());
+        if (staffId != null) {
+            criteria.andUserIdEqualTo(staffId);
+        }
+        List<StaffWithUser> staffWithUserList = staffWithUserMapper.selectByExample(example);
+        if (CollectionUtils.isEmpty(staffWithUserList)) {
+            return null;
+        }
+        int n = 0;
+        List<SendMessage> sendMessageList = new ArrayList<>();
+        SendMessage sendMessage = new SendMessage();
+        for (PushMessage pushMessage : goodHistoryPushList) {
+            if (pushMessage.getUserIds().contains(user.getId())) {
+                if (n == 0) {
+                    sendMessage.setVideoId1(pushMessage.getVideoId());
+                }
+                if (n == 1) {
+                    sendMessage.setVideoId2(pushMessage.getVideoId());
+                }
+                if (n == 2) {
+                    sendMessage.setVideoId3(pushMessage.getVideoId());
+                }
+                n++;
+                if (n >= MAX_VIDEO_NUM) {
+                    break;
+                }
+            }
+        }
+        //保底数据
+        if (n < MAX_VIDEO_NUM) {
+            for (Long videoId : guaranteedVideoIdList) {
+                if (n == 0) {
+                    sendMessage.setVideoId1(videoId);
+                }
+                if (n == 1) {
+                    sendMessage.setVideoId2(videoId);
+                }
+                if (n == 2) {
+                    sendMessage.setVideoId3(videoId);
+                }
+                n++;
+                if (n >= MAX_VIDEO_NUM) {
+                    break;
+                }
+            }
+        }
+        if (n < MAX_VIDEO_NUM) {
+            log.error("组装数据失败 user={}", user);
+            return null;
+        }
+        for (StaffWithUser staffWithUser : staffWithUserList) {
+            SendMessage newSendMessage = new SendMessage();
+            BeanUtils.copyProperties(sendMessage, newSendMessage);
+            newSendMessage.setStaffId(staffWithUser.getStaffId());
+            newSendMessage.setUserId(staffWithUser.getUserId());
+            sendMessageList.add(newSendMessage);
+        }
+        return sendMessageList;
+    }
+
+
+    @XxlJob("pushSendMessageJob1")
+    public ReturnT<String> pushSendMessage(String param) {
+        List<SendMessage> groupList = sendMessageMapper.getGroupList(DateUtil.getThatDayDate(), 0);
+        if (StringUtils.isNotEmpty(param)) {
+            groupList = groupList.stream().filter(e -> e.getStaffId() == Long.parseLong(param)).collect(Collectors.toList());
+        }
+        if (CollectionUtils.isEmpty(groupList)) {
+            return ReturnT.SUCCESS;
+        }
+        for (SendMessage sendMessage : groupList) {
+            sendMessage.setIsSend(0);
+            sendMessage.setCreateTime(DateUtil.getThatDayDate());
+            List<String> sendUserList = sendMessageMapper.selectExternalUserId3rdParty(sendMessage);
+            boolean flag = pushMessage(sendUserList, sendMessage);
+            if (flag) {
+                SendMessage updateSendMessage = new SendMessage();
+                updateSendMessage.setIsSend(1);
+                SendMessageExample example = new SendMessageExample();
+                example.createCriteria()
+                        .andVideoId1EqualTo(sendMessage.getVideoId1())
+                        .andVideoId2EqualTo(sendMessage.getVideoId2())
+                        .andVideoId3EqualTo(sendMessage.getVideoId3())
+                        .andStaffIdEqualTo(sendMessage.getStaffId())
+                        .andCreateTimeGreaterThan(DateUtil.getThatDayDate());
+                sendMessageMapper.updateByExampleSelective(updateSendMessage, example);
+            }
+
+        }
+        return ReturnT.SUCCESS;
+    }
+
+
+    public boolean pushMessage(List<String> sendUserList, SendMessage sendMessage) {
+        List<JSONObject> pushList = new ArrayList<>();
+        StaffExample staffExample = new StaffExample();
+        staffExample.createCriteria().andIdEqualTo(sendMessage.getStaffId());
+        List<Staff> staffList = staffMapper.selectByExample(staffExample);
+        Staff staff = staffList.get(0);
+        String text = messageService.getMessageText();
+
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put("chat_type", "single");
+        jsonObject.put("text", text);
+        jsonObject.put("sender", staff.getCarrierId());
+        JSONArray attachments = new JSONArray();
+        List<Long> videoIdList = new ArrayList<>();
+        videoIdList.add(sendMessage.getVideoId1());
+        videoIdList.add(sendMessage.getVideoId2());
+        videoIdList.add(sendMessage.getVideoId3());
+        for (Long videoId : videoIdList) {
+            JSONObject attachment = new JSONObject();
+            attachment.put("msgtype", "miniprogram");
+            MessageAttachmentExample example = new MessageAttachmentExample();
+            example.createCriteria().andMiniprogramVideoIdEqualTo(videoId);
+            List<MessageAttachment> messageAttachmentList = messageAttachmentMapper.selectByExample(example);
+            if (CollectionUtils.isEmpty(messageAttachmentList)) {
+                throw new RuntimeException("附件信息查询异常");
+            }
+            MessageAttachment messageAttachment = messageAttachmentList.get(0);
+            JSONObject miniprogram = new JSONObject();
+            miniprogram.put("appid", messageAttachment.getAppid());
+            String title = messageAttachment.getTitle();
+            if (title.getBytes(StandardCharsets.UTF_8).length > MAX_BYTES) {
+                title = ToolUtils.truncateString(title, MAX_BYTES - 3) + "...";
+            }
+            miniprogram.put("title", title);
+            String picMediaId = messageAttachmentService.getPicMediaId(messageAttachment.getCover());
+            if (StringUtils.isEmpty(picMediaId)) {
+                log.error("pushMessage getPicMediaId error cover={}", messageAttachment.getCover());
+                return false;
+            }
+            miniprogram.put("pic_media_id", picMediaId);
+            String page = "";
+            String key = staff.getCarrierId() + "_" + videoId;
+            if (pageMap.containsKey(key)) {
+                page = pageMap.get(key);
+            } else {
+                page = messageAttachmentService.getPage(staff, videoId);
+                pageMap.put(key, page);
+            }
+            if (StringUtils.isEmpty(page)) {
+                log.error("pushMessage get page error videoId={} staff={}", videoId, staff);
+                return false;
+            }
+            miniprogram.put("page", page);
+            attachment.put("miniprogram", miniprogram);
+            attachments.add(0, attachment);
+        }
+        jsonObject.put("attachments", attachments);
+        List<List<String>> lists = Lists.partition(sendUserList, 10000);
+        for (List<String> list : lists) {
+            JSONArray externalUserIds = JSONArray.parseArray(JSON.toJSONString(list));
+            JSONObject newJSONObject = new JSONObject();
+            newJSONObject.putAll(jsonObject);
+            newJSONObject.put("external_userid", externalUserIds);
+            pushList.add(newJSONObject);
+        }
+        if (CollectionUtils.isEmpty(pushList)) {
+            return false;
+        }
+        for (JSONObject pushJsonObject : pushList) {
+            log.info("pushMessage pushJsonObject={}", pushJsonObject);
+            boolean flag = messageService.pushMessage(pushJsonObject);
+            if (!flag) {
+                return flag;
+            }
+        }
+        return true;
+    }
+
+
+}

+ 113 - 4
we-com-server/src/main/java/com/tzld/piaoquan/wecom/job/WeComUserDataJob1.java

@@ -1,9 +1,13 @@
 package com.tzld.piaoquan.wecom.job;
 package com.tzld.piaoquan.wecom.job;
 
 
+import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.JSONObject;
+import com.tzld.piaoquan.wecom.common.constant.TimeConstant;
+import com.tzld.piaoquan.wecom.dao.mapper.StaffMapper;
+import com.tzld.piaoquan.wecom.dao.mapper.StaffWithUserMapper;
 import com.tzld.piaoquan.wecom.dao.mapper.UserMapper;
 import com.tzld.piaoquan.wecom.dao.mapper.UserMapper;
-import com.tzld.piaoquan.wecom.model.po.User;
-import com.tzld.piaoquan.wecom.model.po.UserExample;
+import com.tzld.piaoquan.wecom.model.bo.XxlJobParam;
+import com.tzld.piaoquan.wecom.model.po.*;
 import com.tzld.piaoquan.wecom.service.AccessTokenService;
 import com.tzld.piaoquan.wecom.service.AccessTokenService;
 import com.tzld.piaoquan.wecom.utils.HttpClientUtil;
 import com.tzld.piaoquan.wecom.utils.HttpClientUtil;
 import com.tzld.piaoquan.wecom.utils.HttpPoolClient;
 import com.tzld.piaoquan.wecom.utils.HttpPoolClient;
@@ -11,6 +15,7 @@ import com.tzld.piaoquan.wecom.utils.page.Page;
 import com.xxl.job.core.biz.model.ReturnT;
 import com.xxl.job.core.biz.model.ReturnT;
 import com.xxl.job.core.handler.annotation.XxlJob;
 import com.xxl.job.core.handler.annotation.XxlJob;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 import org.springframework.stereotype.Component;
@@ -20,20 +25,124 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.List;
 
 
+import static com.tzld.piaoquan.wecom.common.constant.WeComConstant.POST_WE_COM_GET_BY_USER;
+import static com.tzld.piaoquan.wecom.common.constant.WeComConstant.UPDATE_USER_URL;
+
 @Slf4j
 @Slf4j
 @Component
 @Component
 public class WeComUserDataJob1 {
 public class WeComUserDataJob1 {
 
 
     private static final HttpPoolClient httpPoolClientDefault = HttpClientUtil.create(30000, 30000, 2000, 5000, 5, 30000);
     private static final HttpPoolClient httpPoolClientDefault = HttpClientUtil.create(30000, 30000, 2000, 5000, 5, 30000);
 
 
-
+    @Autowired
+    private StaffMapper staffMapper;
     @Autowired
     @Autowired
     private UserMapper userMapper;
     private UserMapper userMapper;
     @Autowired
     @Autowired
     private AccessTokenService accessTokenService;
     private AccessTokenService accessTokenService;
+    @Autowired
+    private StaffWithUserMapper staffWithUserMapper;
+
+    @XxlJob("updateStaffWithUserJob1")
+    public ReturnT<String> updateStaffWithUser(String param) {
+        XxlJobParam xxlJobParam = new XxlJobParam();
+        if (StringUtils.isNotEmpty(param)) {
+            xxlJobParam = JSONObject.parseObject(param, XxlJobParam.class);
+        }
+        StaffExample example = new StaffExample();
+        StaffExample.Criteria criteria = example.createCriteria();
+        if (xxlJobParam.getStaffId() != null) {
+            criteria.andIdEqualTo(xxlJobParam.getStaffId());
+        }
+        List<Staff> staffList = staffMapper.selectByExample(example);
+        for (Staff staff : staffList) {
+            updateUserList(staff);
+        }
+        return ReturnT.SUCCESS;
+    }
+
+
+    private void updateUserList(Staff staff) {
+        try {
+            String cursor = "";
+            do {
+                String res = getUserList(staff.getCarrierId(), cursor);
+                JSONObject jsonObject = JSONObject.parseObject(res);
+                Integer errCode = jsonObject.getInteger("errcode");
+                if (errCode != 0) {
+                    log.error("updateUserList error carrierId={} cursor={}", staff.getCarrierId(), cursor);
+                    return;
+                }
+                cursor = jsonObject.getString("next_cursor");
+                JSONArray externalContactList = jsonObject.getJSONArray("external_contact_list");
+                for (int i = 0; i < externalContactList.size(); i++) {
+                    JSONObject externalContact = externalContactList.getJSONObject(i).getJSONObject("external_contact");
+                    JSONObject followInfo =  externalContactList.getJSONObject(i).getJSONObject("follow_info");
+                    Long createAt = followInfo.getLong("createtime");
+                    String externalUserId = externalContact.getString("external_userid");
+                    String name = externalContact.getString("name");
+                    String unionId = externalContact.getString("unionid");
+                    String avatar = externalContact.getString("avatar");
+                    Integer type = externalContact.getInteger("type");
+                    Integer gender = externalContact.getInteger("gender");
+                    UserExample example = new UserExample();
+                    example.createCriteria().andExternalUserIdEqualTo(externalUserId);
+                    List<User> userList = userMapper.selectByExample(example);
+                    User user = new User();
+                    user.setExternalUserId(externalUserId);
+                    user.setName(name);
+                    user.setType(type);
+                    user.setUnionId(unionId);
+                    user.setGender(gender);
+                    user.setAvatar(avatar);
+                    user.setCreatedAt(createAt);
+                    Long userId;
+                    if (CollectionUtils.isEmpty(userList)) {
+                        userMapper.insert(user);
+                        userId = user.getId();
+                    } else {
+                        User oldUser = userList.get(0);
+                        user.setId(oldUser.getId());
+                        userMapper.updateByPrimaryKeySelective(user);
+                        userId = oldUser.getId();
+                    }
+                    if (userId == null) {
+                        continue;
+                    }
+                    StaffWithUserExample staffWithUserExample = new StaffWithUserExample();
+                    staffWithUserExample.createCriteria().andStaffIdEqualTo(staff.getId()).andUserIdEqualTo(userId);
+                    List<StaffWithUser> staffWithUserList = staffWithUserMapper.selectByExample(staffWithUserExample);
+                    if (CollectionUtils.isEmpty(staffWithUserList)) {
+                        StaffWithUser staffWithUser = new StaffWithUser();
+                        staffWithUser.setStaffId(staff.getId());
+                        staffWithUser.setUserId(userId);
+                        staffWithUserMapper.insert(staffWithUser);
+                    }
+                }
+            } while (StringUtils.isEmpty(cursor));
+        } catch (IOException e) {
+            log.error("updateUser error", e);
+        }
+    }
+
+    private String getUserList(String userId, String cursor) throws IOException {
+        String accessToken = accessTokenService.getWeComAccessToken();
+        String url = POST_WE_COM_GET_BY_USER
+                + "?access_token=" + accessToken;
+        JSONObject param = new JSONObject();
+        JSONArray userIdList = new JSONArray();
+        userIdList.add(userId);
+        param.put("userid_list", userIdList);
+        param.put("limit", 100);
+        if (StringUtils.isNotEmpty(cursor)) {
+            param.put("cursor", cursor);
+        }
+        return httpPoolClientDefault.post(url, param.toJSONString());
+    }
+
 
 
     @XxlJob("setExternalUserIdJob")
     @XxlJob("setExternalUserIdJob")
-    public ReturnT<String> setExternalUserId(String param) throws IOException {
+    public ReturnT<String> setExternalUserId(String param) {
         try {
         try {
             UserExample example = new UserExample();
             UserExample example = new UserExample();
             long count = userMapper.countByExample(example);
             long count = userMapper.countByExample(example);