Browse Source

更新用户

xueyiming 6 months ago
parent
commit
aa7a09ae05

+ 17 - 1
pom.xml

@@ -106,9 +106,25 @@
         <dependency>
             <groupId>org.apache.httpcomponents</groupId>
             <artifactId>httpclient</artifactId>
-            <version>4.5.13</version> <!-- 使用最新版本 -->
+            <version>4.5.14</version> <!-- 使用最新版本 -->
         </dependency>
 
+        <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpmime -->
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpmime</artifactId>
+            <version>4.5.14</version>
+        </dependency>
+
+        <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpcore -->
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpcore</artifactId>
+            <version>4.4.16</version>
+        </dependency>
+
+
+
         <dependency>
             <groupId>com.google.guava</groupId>
             <artifactId>guava</artifactId>

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

@@ -20,4 +20,18 @@ public interface WeComConstant {
     String WE_COM_SECRET = "X13JWOI5ud_IsT2RBXGDZmknysLKqZfGdAO8eszA090";
 
     String WE_COM_CROP_ID = "wwa4015dc7d652a21f";
+
+    //获取群发记录列表
+    String POST_WE_COM_GROUP_MSG_LIST_URL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_groupmsg_list_v2";
+
+    //获取群发成员发送任务列表
+    String POST_WE_COM_GROUP_MSG_TASK = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_groupmsg_task";
+
+    //获取企业群发成员执行结果
+    String POST_WE_COM_GROUP_MSG_SEND_RESULT = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_groupmsg_send_result";
+
+    //创建企业群发
+    String POST_WE_COM_ADD_MSG_TEMPLATE = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_msg_template";
+
+
 }

+ 1 - 1
we-com-server/src/main/java/com/tzld/piaoquan/wecom/controller/WeComController.java

@@ -79,7 +79,7 @@ public class WeComController {
 
             // 访问应用和企业回调传不同的ID
             if (type.equals("data")) {
-                id = corpId;
+                id = WeComServerConstant.CorpID;
             } else {
                 id = WeComServerConstant.SuiteID;
             }

+ 2 - 0
we-com-server/src/main/java/com/tzld/piaoquan/wecom/dao/mapper/UserMapper.java

@@ -34,5 +34,7 @@ public interface UserMapper {
 
     Long selectIdByExternalUserId3rdParty(String externalUserId3rdParty);
 
+    Long selectIdByExternalUserId(String externalUserId3rdParty);
+
     void insertList(@Param("list") List<User> list);
 }

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

@@ -0,0 +1,273 @@
+package com.tzld.piaoquan.wecom.job;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.tzld.piaoquan.wecom.common.constant.TimeConstant;
+import com.tzld.piaoquan.wecom.common.enums.MessageAttachmentTypeEnum;
+import com.tzld.piaoquan.wecom.dao.mapper.AlertMessageMapper;
+import com.tzld.piaoquan.wecom.dao.mapper.HistoryMessageMapper;
+import com.tzld.piaoquan.wecom.dao.mapper.StaffMapper;
+import com.tzld.piaoquan.wecom.dao.mapper.UserMapper;
+import com.tzld.piaoquan.wecom.model.bo.ExternalUser;
+import com.tzld.piaoquan.wecom.model.bo.MiniprogramRecord;
+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.HistoryMessageService;
+import com.tzld.piaoquan.wecom.service.MessageAttachmentService;
+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.slf4j.Slf4j;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.io.IOException;
+import java.util.*;
+
+import static com.tzld.piaoquan.wecom.common.constant.WeComConstant.*;
+
+@Slf4j
+@Component
+public class WeComHistoryDataJob1 {
+
+    private static final HttpPoolClient httpPoolClientDefault = HttpClientUtil.create(30000, 30000, 2000, 5000, 5, 30000);
+
+
+    @Autowired
+    private AccessTokenService accessTokenService;
+
+    @Autowired
+    private UserMapper userMapper;
+
+    @Autowired
+    private HistoryMessageMapper historyMessageMapper;
+
+    @Autowired
+    private HistoryMessageService historyMessageService;
+
+
+    @XxlJob("saveHistoryMessageJob1")
+    public ReturnT<String> selectHistoryMessageByDay1(String param) {
+        XxlJobParam xxlJobParam = new XxlJobParam();
+        if (StringUtils.isNotEmpty(param)) {
+            xxlJobParam = JSONObject.parseObject(param, XxlJobParam.class);
+        }
+        if (xxlJobParam.getStartTime() == null) {
+            HistoryMessageExample example = new HistoryMessageExample();
+            example.setOrderByClause("create_time desc");
+            example.setPage(new Page<>(1, 1));
+            List<HistoryMessage> historyMessages = historyMessageMapper.selectByExample(example);
+            xxlJobParam.setStartTime(historyMessages.get(0).getCreateTime().getTime() / 1000);
+        }
+        if (xxlJobParam.getEndTime() == null) {
+            xxlJobParam.setEndTime(System.currentTimeMillis() / 1000);
+        }
+        Long startTime = xxlJobParam.getStartTime();
+        Long endTime = xxlJobParam.getEndTime();
+
+        for (; startTime < endTime; startTime += TimeConstant.DAY) {
+            selectGroupMsgList(startTime, Math.min(startTime + TimeConstant.DAY, endTime));
+        }
+        return ReturnT.SUCCESS;
+    }
+
+    public void selectGroupMsgList(Long startTime, Long endTime) {
+        try {
+            String cursor = "";
+            do {
+                String res = getGroupMsgList(startTime, endTime, cursor);
+                JSONObject jsonObject = JSONObject.parseObject(res);
+                Integer errCode = jsonObject.getInteger("errcode");
+                if (errCode != 0) {
+                    log.error("selectGroupMsgList error startTime={}, endTime={}", startTime, endTime);
+                    return;
+                }
+                cursor = jsonObject.getString("next_cursor");
+                JSONArray groupMsgList = jsonObject.getJSONArray("group_msg_list");
+                if (CollectionUtils.isEmpty(groupMsgList)) {
+                    continue;
+                }
+                for (int i = 0; i < groupMsgList.size(); i++) {
+                    JSONObject groupMsg = groupMsgList.getJSONObject(i);
+                    JSONArray attachments = groupMsg.getJSONArray("attachments");
+                    String msgId = groupMsg.getString("msgid");
+                    if (CollectionUtils.isEmpty(attachments)) {
+                        continue;
+                    }
+                    List<MiniprogramRecord> miniprogramRecordList = new ArrayList<>();
+                    List<MessageAttachment> messageAttachmentList = new ArrayList<>();
+                    for (int j = 0; j < attachments.size(); j++) {
+                        JSONObject attachment = attachments.getJSONObject(j);
+                        if (attachment == null) {
+                            continue;
+                        }
+                        JSONObject miniprogram = attachment.getJSONObject("miniprogram");
+                        MiniprogramRecord miniprogramRecord = new MiniprogramRecord();
+                        MessageAttachment messageAttachment = new MessageAttachment();
+                        String title = miniprogram.getString("title");
+                        String appid = miniprogram.getString("appid");
+                        String page = miniprogram.getString("page");
+                        Long videoId = MessageUtil.getVideoId(page);
+
+                        miniprogramRecord.setVideoId(videoId);
+                        miniprogramRecord.setAttachmentIdx(j + 1);
+                        miniprogramRecordList.add(miniprogramRecord);
+
+                        messageAttachment.setAppid(appid);
+                        messageAttachment.setPage(page);
+                        messageAttachment.setTitle(title);
+                        messageAttachment.setMiniprogramVideoId(videoId);
+                        messageAttachment.setType(MessageAttachmentTypeEnum.MINIPROGRAM.getType());
+                        messageAttachmentList.add(messageAttachment);
+                    }
+                    List<String> userIdList = selectGroupMsgTask(msgId);
+                    if (CollectionUtils.isEmpty(userIdList)) {
+                        continue;
+                    }
+                    for (String userId : userIdList) {
+                        List<ExternalUser> externalUsers = selectGroupMsgSendResult(msgId, userId);
+                        if (CollectionUtils.isEmpty(externalUsers)) {
+                            continue;
+                        }
+//                        insertHistoryMessageList(externalUsers, miniprogramRecordList);
+//                        messageAttachmentService.addMiniprogram(messageAttachmentList);
+                    }
+
+
+                }
+            } while (StringUtils.isNotEmpty(cursor));
+        } catch (IOException e) {
+            log.error("selectGroupMsgList error", e);
+        }
+    }
+
+
+    private List<ExternalUser> selectGroupMsgSendResult(String msgId, String userId) throws IOException {
+        List<ExternalUser> resList = new ArrayList<>();
+        String cursor = "";
+        do {
+            String res = getGroupMsgSendResult(msgId, userId, cursor);
+            JSONObject jsonObject = JSONObject.parseObject(res);
+            Integer errCode = jsonObject.getInteger("errcode");
+            if (errCode != 0) {
+                String errmsg = jsonObject.getString("errmsg");
+                log.error("selectGroupMsgSendResult error msgId={} userId={} errCode={} errmsg={}", msgId, userId, errCode, errmsg);
+                return resList;
+            }
+            cursor = jsonObject.getString("next_cursor");
+            JSONArray sendList = jsonObject.getJSONArray("send_list");
+            for (int i = 0; i < sendList.size(); i++) {
+                JSONObject send = sendList.getJSONObject(i);
+                ExternalUser externalUser = new ExternalUser();
+                externalUser.setExternalUserId(send.getString("external_userid"));
+                externalUser.setStatus(send.getInteger("status"));
+                externalUser.setSendTime(send.getLong("send_time"));
+                resList.add(externalUser);
+            }
+        } while (StringUtils.isNotEmpty(cursor));
+        return resList;
+    }
+
+    private String getGroupMsgSendResult(String msgId, String userId, String cursor) throws IOException {
+        String accessToken = accessTokenService.getWeComAccessToken();
+        String url = POST_WE_COM_GROUP_MSG_SEND_RESULT
+                + "?access_token=" + accessToken;
+        JSONObject param = new JSONObject();
+        param.put("msgid", msgId);
+        param.put("userid", userId);
+        param.put("limit", 1000);
+        if (StringUtils.isNotEmpty(cursor)) {
+            param.put("cursor", cursor);
+        }
+        return httpPoolClientDefault.post(url, param.toJSONString());
+    }
+
+
+    private List<String> selectGroupMsgTask(String msgId) throws IOException {
+        List<String> resList = new ArrayList<>();
+        String cursor = "";
+        do {
+            String res = getGroupMsgTask(msgId, cursor);
+            JSONObject jsonObject = JSONObject.parseObject(res);
+            Integer errCode = jsonObject.getInteger("errcode");
+            if (errCode != 0) {
+                String errmsg = jsonObject.getString("errmsg");
+                log.error("selectGroupMsgTask error msgId={} errCode={} errmsg={}", msgId, errCode, errmsg);
+                return resList;
+            }
+            cursor = jsonObject.getString("next_cursor");
+            JSONArray taskList = jsonObject.getJSONArray("task_list");
+            for (int i = 0; i < taskList.size(); i++) {
+                JSONObject task = taskList.getJSONObject(i);
+                String userId = task.getString("userid");
+                resList.add(userId);
+            }
+        } while (StringUtils.isNotEmpty(cursor));
+        return resList;
+    }
+
+    private String getGroupMsgTask(String msgId, String cursor) throws IOException {
+        String accessToken = accessTokenService.getWeComAccessToken();
+        String url = POST_WE_COM_GROUP_MSG_TASK
+                + "?access_token=" + accessToken;
+        JSONObject param = new JSONObject();
+        param.put("msgid", msgId);
+        param.put("limit", 1000);
+        if (StringUtils.isNotEmpty(cursor)) {
+            param.put("cursor", cursor);
+        }
+        return httpPoolClientDefault.post(url, param.toJSONString());
+    }
+
+
+    private void insertHistoryMessageList(List<ExternalUser> externalUsers, List<MiniprogramRecord> miniprogramRecordList) {
+        if (CollectionUtils.isEmpty(externalUsers) || CollectionUtils.isEmpty(miniprogramRecordList)) {
+            return;
+        }
+        List<HistoryMessage> historyMessageList = new ArrayList<>();
+        for (ExternalUser externalUser : externalUsers) {
+            Long userId = userMapper.selectIdByExternalUserId(externalUser.getExternalUserId());
+            if (userId == null) {
+                continue;
+            }
+            for (MiniprogramRecord miniprogramRecord : miniprogramRecordList) {
+                HistoryMessage historyMessage = new HistoryMessage();
+                if (externalUser.getSendTime() != null) {
+                    historyMessage.setSendTime(new Date(externalUser.getSendTime()));
+                }
+                historyMessage.setAttachmentIdx(miniprogramRecord.getAttachmentIdx());
+                historyMessage.setVideoId(miniprogramRecord.getVideoId());
+                historyMessage.setUserId(userId);
+                historyMessageList.add(historyMessage);
+            }
+        }
+        historyMessageService.batchInsertHistoryMessage(historyMessageList);
+    }
+
+
+    private String getGroupMsgList(Long startTime, Long endTime, String cursor) throws IOException {
+        String accessToken = accessTokenService.getWeComAccessToken();
+        String url = POST_WE_COM_GROUP_MSG_LIST_URL
+                + "?access_token=" + accessToken;
+        JSONObject param = new JSONObject();
+        param.put("chat_type", "single");
+        param.put("start_time", startTime);
+        param.put("end_time", endTime);
+        param.put("limit", 100);
+        if (StringUtils.isNotEmpty(cursor)) {
+            param.put("cursor", cursor);
+        }
+        return httpPoolClientDefault.post(url, param.toJSONString());
+    }
+
+
+}
+
+
+
+

+ 90 - 4
we-com-server/src/main/java/com/tzld/piaoquan/wecom/job/WeComMessageDataJob.java

@@ -1,5 +1,6 @@
 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;
@@ -9,10 +10,7 @@ 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.DateUtil;
-import com.tzld.piaoquan.wecom.utils.MessageUtil;
-import com.tzld.piaoquan.wecom.utils.OdpsUtil;
-import com.tzld.piaoquan.wecom.utils.ToolUtils;
+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;
@@ -24,7 +22,14 @@ import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Component;
 import org.springframework.util.CollectionUtils;
 
+import java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
 import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -35,6 +40,8 @@ import static com.tzld.piaoquan.wecom.common.constant.TimeConstant.MILLISECOND_D
 @Component
 public class WeComMessageDataJob {
 
+    private static final HttpPoolClient httpPoolClientDefault = HttpClientUtil.create(30000, 30000, 2000, 5000, 5, 30000);
+
     @Autowired
     private UserMapper userMapper;
 
@@ -352,4 +359,83 @@ public class WeComMessageDataJob {
         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;
+    }
+
+
 }

+ 84 - 0
we-com-server/src/main/java/com/tzld/piaoquan/wecom/job/WeComUserDataJob1.java

@@ -0,0 +1,84 @@
+package com.tzld.piaoquan.wecom.job;
+
+import com.alibaba.fastjson.JSONObject;
+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.service.AccessTokenService;
+import com.tzld.piaoquan.wecom.utils.HttpClientUtil;
+import com.tzld.piaoquan.wecom.utils.HttpPoolClient;
+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.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+@Slf4j
+@Component
+public class WeComUserDataJob1 {
+
+    private static final HttpPoolClient httpPoolClientDefault = HttpClientUtil.create(30000, 30000, 2000, 5000, 5, 30000);
+
+
+    @Autowired
+    private UserMapper userMapper;
+    @Autowired
+    private AccessTokenService accessTokenService;
+
+    @XxlJob("setExternalUserIdJob")
+    public ReturnT<String> setExternalUserId(String param) throws IOException {
+        try {
+            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;
+                }
+                for (User user : userList) {
+                    String externalUserId3rdParty = user.getExternalUserId3rdParty();
+                    String externalUserId = getExternalUserId(externalUserId3rdParty);
+                    if (StringUtils.isEmpty(externalUserId)) {
+                        continue;
+                    }
+                    User updateUser = new User();
+                    updateUser.setId(user.getId());
+                    updateUser.setExternalUserId(externalUserId);
+                    userMapper.updateByPrimaryKeySelective(updateUser);
+                }
+            }
+        } catch (Exception e) {
+            log.error("setExternalUserId error", e);
+        }
+
+        return ReturnT.SUCCESS;
+    }
+
+    private String getExternalUserId(String externalUserId3rdParty) throws IOException {
+        String weComAccessToken = accessTokenService.getWeComAccessToken();
+        String url = String.format("https://qyapi.weixin.qq.com/cgi-bin/externalcontact/from_service_external_userid?access_token=%s", weComAccessToken);
+        JSONObject param = new JSONObject();
+        param.put("external_userid", externalUserId3rdParty);
+        param.put("source_agentid", 1000009);
+        String res = httpPoolClientDefault.post(url, param.toJSONString());
+        JSONObject jsonObject = JSONObject.parseObject(res);
+        Integer errcode = jsonObject.getInteger("errcode");
+        if (errcode == 0) {
+            return jsonObject.getString("external_userid");
+        }
+        return null;
+    }
+
+
+}

+ 13 - 0
we-com-server/src/main/java/com/tzld/piaoquan/wecom/model/bo/ExternalUser.java

@@ -0,0 +1,13 @@
+package com.tzld.piaoquan.wecom.model.bo;
+
+import lombok.Data;
+
+@Data
+public class ExternalUser {
+
+    private String externalUserId;
+
+    private Integer status;
+
+    private Long sendTime;
+}

+ 48 - 0
we-com-server/src/main/java/com/tzld/piaoquan/wecom/service/Impl/MessageAttachmentServiceImpl.java

@@ -22,8 +22,16 @@ import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
+import java.io.File;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.util.*;
+import java.util.concurrent.TimeUnit;
 
 import static com.tzld.piaoquan.wecom.common.constant.MessageConstant.appid;
 import static com.tzld.piaoquan.wecom.common.constant.OtherServerURL.POST_ADD_TENCENT;
@@ -113,6 +121,46 @@ public class MessageAttachmentServiceImpl implements MessageAttachmentService {
         return new HashMap<>();
     }
 
+    @Override
+    public String getPicMediaId(String cover) {
+        try {
+            String mediaId = (String) redisTemplate.opsForValue().get(cover);
+            if (StringUtils.isNotEmpty(mediaId)) {
+                return mediaId;
+            }
+            HttpURLConnection httpUrl = (HttpURLConnection) new URL(cover).openConnection();
+            httpUrl.connect();
+            InputStream inputStream = httpUrl.getInputStream();
+
+            // 将文件内容写入临时文件
+            String filePath = UUID.randomUUID() + ".jpg"; // 临时文件路径
+            try (OutputStream outputStream = Files.newOutputStream(Paths.get(filePath))) {
+                byte[] buffer = new byte[4096];
+                int bytesRead;
+                while ((bytesRead = inputStream.read(buffer)) != -1) {
+                    outputStream.write(buffer, 0, bytesRead);
+                }
+            }
+            inputStream.close();
+            httpUrl.disconnect();
+            File file = new java.io.File(filePath);
+            String url = String.format("https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=%s&type=image",
+                    "gj_f699xkVm62jtoNTZVbmMcrxCRo3ZWYEcodnmbuZDj1M5oms1Nnp4B-FSD6Lm2puKlxOurb-j8t-WiXgwtbXtEoP7M5qwjHY9E8yfuJaDkzYh54pUSzxSVF5whSetby6venHVGi9SnAtNt5ykyAbjpPQl3mKSG_HL3i3j45b4UJUXXtTWTuqNyxnEIGFbR1FHw0SaMTV8Hpsm5mv8FVg");
+            String res = httpPoolClientDefault.post(url, file);
+            JSONObject jsonObject = JSONObject.parseObject(res);
+            if (jsonObject != null && jsonObject.getInteger("errcode") == 0) {
+                mediaId = jsonObject.getString("media_id");
+                redisTemplate.opsForValue().set(cover, mediaId, 2, TimeUnit.DAYS);
+                return mediaId;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return null;
+    }
+
+
     @Override
     public String getPage(Staff staff, Long videoId) {
         try {

+ 20 - 3
we-com-server/src/main/java/com/tzld/piaoquan/wecom/service/Impl/MessageServiceImpl.java

@@ -18,6 +18,7 @@ import java.io.IOException;
 import java.util.concurrent.TimeUnit;
 
 import static com.tzld.piaoquan.wecom.common.constant.RedisConstant.PUSH_MESSAGE_TEXT;
+import static com.tzld.piaoquan.wecom.common.constant.WeComConstant.POST_WE_COM_ADD_MSG_TEMPLATE;
 import static com.tzld.piaoquan.wecom.common.enums.ExceptionCodeEnum.PARAMS_ERROR;
 import static com.tzld.piaoquan.wecom.common.constant.WeComConstant.POST_MESSAGE_PUSH_URL;
 
@@ -40,13 +41,29 @@ public class MessageServiceImpl implements MessageService {
             String url = POST_MESSAGE_PUSH_URL
                     + "?access_token=" + accessToken;
             String s = httpPoolClientDefault.post(url, jsonObject.toJSONString());
-            System.out.println(s);
             JSONObject res = JSONObject.parseObject(s);
-            log.info("MessageServiceImpl pushMessage res={}", res);
+            log.info("pushMessage res={}", res);
             Integer code = res.getInteger("errcode");
             return code == 0;
         } catch (IOException e) {
-            log.error("MessageServiceImpl pushMessage error", e);
+            log.error("pushMessage error", e);
+        }
+        return false;
+    }
+
+    @Override
+    public boolean pushWeComMessage(JSONObject jsonObject) {
+        try {
+            String accessToken = accessTokenService.getWeComAccessToken();
+            String url = POST_WE_COM_ADD_MSG_TEMPLATE
+                    + "?access_token=" + accessToken;
+            String s = httpPoolClientDefault.post(url, jsonObject.toJSONString());
+            JSONObject res = JSONObject.parseObject(s);
+            log.info("pushWeComMessage res={}", res);
+            Integer code = res.getInteger("errcode");
+            return code == 0;
+        } catch (IOException e) {
+            log.error("pushWeComMessage error", e);
         }
         return false;
     }

+ 2 - 0
we-com-server/src/main/java/com/tzld/piaoquan/wecom/service/MessageAttachmentService.java

@@ -11,5 +11,7 @@ public interface MessageAttachmentService {
 
     void createGuaranteedMiniprogram(List<Long> videos);
 
+    String getPicMediaId(String cover);
+
     String getPage(Staff staff, Long videoId);
 }

+ 2 - 0
we-com-server/src/main/java/com/tzld/piaoquan/wecom/service/MessageService.java

@@ -7,6 +7,8 @@ public interface MessageService {
 
     boolean pushMessage(JSONObject jsonObject);
 
+    boolean pushWeComMessage(JSONObject jsonObject);
+
     void createMessageText(MessageTextVo messageTextVo);
 
     String getMessageText();

+ 27 - 0
we-com-server/src/main/java/com/tzld/piaoquan/wecom/utils/HttpPoolClient.java

@@ -15,7 +15,10 @@ import org.apache.http.conn.socket.ConnectionSocketFactory;
 import org.apache.http.conn.socket.PlainConnectionSocketFactory;
 import org.apache.http.conn.ssl.NoopHostnameVerifier;
 import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.entity.ContentType;
 import org.apache.http.entity.StringEntity;
+import org.apache.http.entity.mime.HttpMultipartMode;
+import org.apache.http.entity.mime.MultipartEntityBuilder;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
 import org.apache.http.impl.client.HttpClientBuilder;
@@ -27,8 +30,12 @@ import org.slf4j.LoggerFactory;
 import org.slf4j.MDC;
 
 import javax.net.ssl.SSLContext;
+import java.io.File;
+import java.io.FileInputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.net.SocketTimeoutException;
+import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 import java.security.KeyManagementException;
 import java.security.KeyStoreException;
@@ -104,6 +111,26 @@ public class HttpPoolClient {
         return request(httpPost);
     }
 
+    public String post(String url, InputStream inputStream, String fileName) throws IOException {
+        HttpPost httpPost = new HttpPost(url);
+        MultipartEntityBuilder entity = MultipartEntityBuilder.create();
+        entity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
+        entity.setCharset(StandardCharsets.UTF_8);
+        entity.addBinaryBody("media", inputStream, ContentType.MULTIPART_FORM_DATA, fileName);
+        httpPost.setEntity(entity.build());
+
+
+        return request(httpPost);
+    }
+
+    public String post(String url, File file) throws IOException {
+        HttpPost uploadFile = new HttpPost(url);
+        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
+        builder.addBinaryBody("media", file);
+        uploadFile.setEntity(builder.build());
+        return request(uploadFile);
+    }
+
     public String request(HttpRequestBase request) throws IOException {
 
         if (LOGGER.isDebugEnabled()) {

+ 387 - 377
we-com-server/src/main/resources/mapper/UserMapper.xml

@@ -1,399 +1,409 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.tzld.piaoquan.wecom.dao.mapper.UserMapper">
-  <resultMap id="BaseResultMap" type="com.tzld.piaoquan.wecom.model.po.User">
-    <id column="id" jdbcType="BIGINT" property="id" />
-    <result column="external_user_id" jdbcType="VARCHAR" property="externalUserId" />
-    <result column="union_id" jdbcType="VARCHAR" property="unionId" />
-    <result column="external_user_id_3rd_party" jdbcType="VARCHAR" property="externalUserId3rdParty" />
-    <result column="type" jdbcType="INTEGER" property="type" />
-    <result column="name" jdbcType="VARCHAR" property="name" />
-    <result column="avatar" jdbcType="VARCHAR" property="avatar" />
-    <result column="gender" jdbcType="INTEGER" property="gender" />
-    <result column="is_delete" jdbcType="INTEGER" property="isDelete" />
-    <result column="created_at" jdbcType="BIGINT" property="createdAt" />
-    <result column="updated_at" jdbcType="BIGINT" property="updatedAt" />
-    <result column="deleted_at" jdbcType="BIGINT" property="deletedAt" />
-    <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
-    <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
-  </resultMap>
-  <sql id="Example_Where_Clause">
-    <where>
-      <foreach collection="oredCriteria" item="criteria" separator="or">
-        <if test="criteria.valid">
-          <trim prefix="(" prefixOverrides="and" suffix=")">
-            <foreach collection="criteria.criteria" item="criterion">
-              <choose>
-                <when test="criterion.noValue">
-                  and ${criterion.condition}
-                </when>
-                <when test="criterion.singleValue">
-                  and ${criterion.condition} #{criterion.value}
-                </when>
-                <when test="criterion.betweenValue">
-                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
-                </when>
-                <when test="criterion.listValue">
-                  and ${criterion.condition}
-                  <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
-                    #{listItem}
-                  </foreach>
-                </when>
-              </choose>
+    <resultMap id="BaseResultMap" type="com.tzld.piaoquan.wecom.model.po.User">
+        <id column="id" jdbcType="BIGINT" property="id"/>
+        <result column="external_user_id" jdbcType="VARCHAR" property="externalUserId"/>
+        <result column="union_id" jdbcType="VARCHAR" property="unionId"/>
+        <result column="external_user_id_3rd_party" jdbcType="VARCHAR" property="externalUserId3rdParty"/>
+        <result column="type" jdbcType="INTEGER" property="type"/>
+        <result column="name" jdbcType="VARCHAR" property="name"/>
+        <result column="avatar" jdbcType="VARCHAR" property="avatar"/>
+        <result column="gender" jdbcType="INTEGER" property="gender"/>
+        <result column="is_delete" jdbcType="INTEGER" property="isDelete"/>
+        <result column="created_at" jdbcType="BIGINT" property="createdAt"/>
+        <result column="updated_at" jdbcType="BIGINT" property="updatedAt"/>
+        <result column="deleted_at" jdbcType="BIGINT" property="deletedAt"/>
+        <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
+        <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
+    </resultMap>
+    <sql id="Example_Where_Clause">
+        <where>
+            <foreach collection="oredCriteria" item="criteria" separator="or">
+                <if test="criteria.valid">
+                    <trim prefix="(" prefixOverrides="and" suffix=")">
+                        <foreach collection="criteria.criteria" item="criterion">
+                            <choose>
+                                <when test="criterion.noValue">
+                                    and ${criterion.condition}
+                                </when>
+                                <when test="criterion.singleValue">
+                                    and ${criterion.condition} #{criterion.value}
+                                </when>
+                                <when test="criterion.betweenValue">
+                                    and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+                                </when>
+                                <when test="criterion.listValue">
+                                    and ${criterion.condition}
+                                    <foreach close=")" collection="criterion.value" item="listItem" open="("
+                                             separator=",">
+                                        #{listItem}
+                                    </foreach>
+                                </when>
+                            </choose>
+                        </foreach>
+                    </trim>
+                </if>
             </foreach>
-          </trim>
-        </if>
-      </foreach>
-    </where>
-  </sql>
-  <sql id="Update_By_Example_Where_Clause">
-    <where>
-      <foreach collection="example.oredCriteria" item="criteria" separator="or">
-        <if test="criteria.valid">
-          <trim prefix="(" prefixOverrides="and" suffix=")">
-            <foreach collection="criteria.criteria" item="criterion">
-              <choose>
-                <when test="criterion.noValue">
-                  and ${criterion.condition}
-                </when>
-                <when test="criterion.singleValue">
-                  and ${criterion.condition} #{criterion.value}
-                </when>
-                <when test="criterion.betweenValue">
-                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
-                </when>
-                <when test="criterion.listValue">
-                  and ${criterion.condition}
-                  <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
-                    #{listItem}
-                  </foreach>
-                </when>
-              </choose>
+        </where>
+    </sql>
+    <sql id="Update_By_Example_Where_Clause">
+        <where>
+            <foreach collection="example.oredCriteria" item="criteria" separator="or">
+                <if test="criteria.valid">
+                    <trim prefix="(" prefixOverrides="and" suffix=")">
+                        <foreach collection="criteria.criteria" item="criterion">
+                            <choose>
+                                <when test="criterion.noValue">
+                                    and ${criterion.condition}
+                                </when>
+                                <when test="criterion.singleValue">
+                                    and ${criterion.condition} #{criterion.value}
+                                </when>
+                                <when test="criterion.betweenValue">
+                                    and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+                                </when>
+                                <when test="criterion.listValue">
+                                    and ${criterion.condition}
+                                    <foreach close=")" collection="criterion.value" item="listItem" open="("
+                                             separator=",">
+                                        #{listItem}
+                                    </foreach>
+                                </when>
+                            </choose>
+                        </foreach>
+                    </trim>
+                </if>
             </foreach>
-          </trim>
-        </if>
-      </foreach>
-    </where>
-  </sql>
-  <sql id="Base_Column_List">
-    id, external_user_id, union_id, external_user_id_3rd_party, `type`, `name`, avatar, 
+        </where>
+    </sql>
+    <sql id="Base_Column_List">
+        id
+        , external_user_id, union_id, external_user_id_3rd_party, `type`, `name`, avatar,
     gender, is_delete, created_at, updated_at, deleted_at, create_time, update_time
-  </sql>
-  <select id="selectByExample" parameterType="com.tzld.piaoquan.wecom.model.po.UserExample" resultMap="BaseResultMap">
-    select
-    <if test="distinct">
-      distinct
-    </if>
-    <include refid="Base_Column_List" />
-    from we_com_user
-    <if test="_parameter != null">
-      <include refid="Example_Where_Clause" />
-    </if>
-    <if test="orderByClause != null">
-      order by ${orderByClause}
-    </if>
-    <if test="page != null">
-      limit #{page.offset} , #{page.pageSize}
-    </if>
-  </select>
-  <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
-    select 
-    <include refid="Base_Column_List" />
-    from we_com_user
-    where id = #{id,jdbcType=BIGINT}
-  </select>
-  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
-    delete from we_com_user
-    where id = #{id,jdbcType=BIGINT}
-  </delete>
-  <delete id="deleteByExample" parameterType="com.tzld.piaoquan.wecom.model.po.UserExample">
-    delete from we_com_user
-    <if test="_parameter != null">
-      <include refid="Example_Where_Clause" />
-    </if>
-  </delete>
-  <insert id="insert" parameterType="com.tzld.piaoquan.wecom.model.po.User">
-    insert into we_com_user (id, external_user_id, union_id, 
-      external_user_id_3rd_party, `type`, `name`, 
-      avatar, gender,
-      created_at, updated_at, deleted_at, 
-      create_time, update_time)
-    values (#{id,jdbcType=BIGINT}, #{externalUserId,jdbcType=VARCHAR}, #{unionId,jdbcType=VARCHAR}, 
-      #{externalUserId3rdParty,jdbcType=VARCHAR}, #{type,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR}, 
-      #{avatar,jdbcType=VARCHAR}, #{gender,jdbcType=INTEGER},
-      #{createdAt,jdbcType=BIGINT}, #{updatedAt,jdbcType=BIGINT}, #{deletedAt,jdbcType=BIGINT}, 
-      #{createTime,jdbcType=TIMESTAMP}, #{updateTime,jdbcType=TIMESTAMP})
-  </insert>
-  <insert id="insertSelective" parameterType="com.tzld.piaoquan.wecom.model.po.User">
-    insert into we_com_user
-    <trim prefix="(" suffix=")" suffixOverrides=",">
-      <if test="id != null">
-        id,
-      </if>
-      <if test="externalUserId != null">
-        external_user_id,
-      </if>
-      <if test="unionId != null">
-        union_id,
-      </if>
-      <if test="externalUserId3rdParty != null">
-        external_user_id_3rd_party,
-      </if>
-      <if test="type != null">
-        `type`,
-      </if>
-      <if test="name != null">
-        `name`,
-      </if>
-      <if test="avatar != null">
-        avatar,
-      </if>
-      <if test="gender != null">
-        gender,
-      </if>
-      <if test="isDelete != null">
-        is_delete,
-      </if>
-      <if test="createdAt != null">
-        created_at,
-      </if>
-      <if test="updatedAt != null">
-        updated_at,
-      </if>
-      <if test="deletedAt != null">
-        deleted_at,
-      </if>
-      <if test="createTime != null">
-        create_time,
-      </if>
-      <if test="updateTime != null">
-        update_time,
-      </if>
-    </trim>
-    <trim prefix="values (" suffix=")" suffixOverrides=",">
-      <if test="id != null">
-        #{id,jdbcType=BIGINT},
-      </if>
-      <if test="externalUserId != null">
-        #{externalUserId,jdbcType=VARCHAR},
-      </if>
-      <if test="unionId != null">
-        #{unionId,jdbcType=VARCHAR},
-      </if>
-      <if test="externalUserId3rdParty != null">
-        #{externalUserId3rdParty,jdbcType=VARCHAR},
-      </if>
-      <if test="type != null">
-        #{type,jdbcType=INTEGER},
-      </if>
-      <if test="name != null">
-        #{name,jdbcType=VARCHAR},
-      </if>
-      <if test="avatar != null">
-        #{avatar,jdbcType=VARCHAR},
-      </if>
-      <if test="gender != null">
-        #{gender,jdbcType=INTEGER},
-      </if>
-      <if test="isDelete != null">
-        #{isDelete,jdbcType=INTEGER},
-      </if>
-      <if test="createdAt != null">
-        #{createdAt,jdbcType=BIGINT},
-      </if>
-      <if test="updatedAt != null">
-        #{updatedAt,jdbcType=BIGINT},
-      </if>
-      <if test="deletedAt != null">
-        #{deletedAt,jdbcType=BIGINT},
-      </if>
-      <if test="createTime != null">
-        #{createTime,jdbcType=TIMESTAMP},
-      </if>
-      <if test="updateTime != null">
-        #{updateTime,jdbcType=TIMESTAMP},
-      </if>
-    </trim>
-  </insert>
-  <select id="countByExample" parameterType="com.tzld.piaoquan.wecom.model.po.UserExample" resultType="java.lang.Long">
-    select count(*) from we_com_user
-    <if test="_parameter != null">
-      <include refid="Example_Where_Clause" />
-    </if>
-  </select>
-  <update id="updateByExampleSelective" parameterType="map">
-    update we_com_user
-    <set>
-      <if test="record.id != null">
-        id = #{record.id,jdbcType=BIGINT},
-      </if>
-      <if test="record.externalUserId != null">
+    </sql>
+    <select id="selectByExample" parameterType="com.tzld.piaoquan.wecom.model.po.UserExample" resultMap="BaseResultMap">
+        select
+        <if test="distinct">
+            distinct
+        </if>
+        <include refid="Base_Column_List"/>
+        from we_com_user
+        <if test="_parameter != null">
+            <include refid="Example_Where_Clause"/>
+        </if>
+        <if test="orderByClause != null">
+            order by ${orderByClause}
+        </if>
+        <if test="page != null">
+            limit #{page.offset} , #{page.pageSize}
+        </if>
+    </select>
+    <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
+        select
+        <include refid="Base_Column_List"/>
+        from we_com_user
+        where id = #{id,jdbcType=BIGINT}
+    </select>
+    <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
+        delete
+        from we_com_user
+        where id = #{id,jdbcType=BIGINT}
+    </delete>
+    <delete id="deleteByExample" parameterType="com.tzld.piaoquan.wecom.model.po.UserExample">
+        delete from we_com_user
+        <if test="_parameter != null">
+            <include refid="Example_Where_Clause"/>
+        </if>
+    </delete>
+    <insert id="insert" parameterType="com.tzld.piaoquan.wecom.model.po.User">
+        insert into we_com_user (id, external_user_id, union_id,
+                                 external_user_id_3rd_party, `type`, `name`,
+                                 avatar, gender,
+                                 created_at, updated_at, deleted_at,
+                                 create_time, update_time)
+        values (#{id,jdbcType=BIGINT}, #{externalUserId,jdbcType=VARCHAR}, #{unionId,jdbcType=VARCHAR},
+                #{externalUserId3rdParty,jdbcType=VARCHAR}, #{type,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR},
+                #{avatar,jdbcType=VARCHAR}, #{gender,jdbcType=INTEGER},
+                #{createdAt,jdbcType=BIGINT}, #{updatedAt,jdbcType=BIGINT}, #{deletedAt,jdbcType=BIGINT},
+                #{createTime,jdbcType=TIMESTAMP}, #{updateTime,jdbcType=TIMESTAMP})
+    </insert>
+    <insert id="insertSelective" parameterType="com.tzld.piaoquan.wecom.model.po.User">
+        insert into we_com_user
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="id != null">
+                id,
+            </if>
+            <if test="externalUserId != null">
+                external_user_id,
+            </if>
+            <if test="unionId != null">
+                union_id,
+            </if>
+            <if test="externalUserId3rdParty != null">
+                external_user_id_3rd_party,
+            </if>
+            <if test="type != null">
+                `type`,
+            </if>
+            <if test="name != null">
+                `name`,
+            </if>
+            <if test="avatar != null">
+                avatar,
+            </if>
+            <if test="gender != null">
+                gender,
+            </if>
+            <if test="isDelete != null">
+                is_delete,
+            </if>
+            <if test="createdAt != null">
+                created_at,
+            </if>
+            <if test="updatedAt != null">
+                updated_at,
+            </if>
+            <if test="deletedAt != null">
+                deleted_at,
+            </if>
+            <if test="createTime != null">
+                create_time,
+            </if>
+            <if test="updateTime != null">
+                update_time,
+            </if>
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="id != null">
+                #{id,jdbcType=BIGINT},
+            </if>
+            <if test="externalUserId != null">
+                #{externalUserId,jdbcType=VARCHAR},
+            </if>
+            <if test="unionId != null">
+                #{unionId,jdbcType=VARCHAR},
+            </if>
+            <if test="externalUserId3rdParty != null">
+                #{externalUserId3rdParty,jdbcType=VARCHAR},
+            </if>
+            <if test="type != null">
+                #{type,jdbcType=INTEGER},
+            </if>
+            <if test="name != null">
+                #{name,jdbcType=VARCHAR},
+            </if>
+            <if test="avatar != null">
+                #{avatar,jdbcType=VARCHAR},
+            </if>
+            <if test="gender != null">
+                #{gender,jdbcType=INTEGER},
+            </if>
+            <if test="isDelete != null">
+                #{isDelete,jdbcType=INTEGER},
+            </if>
+            <if test="createdAt != null">
+                #{createdAt,jdbcType=BIGINT},
+            </if>
+            <if test="updatedAt != null">
+                #{updatedAt,jdbcType=BIGINT},
+            </if>
+            <if test="deletedAt != null">
+                #{deletedAt,jdbcType=BIGINT},
+            </if>
+            <if test="createTime != null">
+                #{createTime,jdbcType=TIMESTAMP},
+            </if>
+            <if test="updateTime != null">
+                #{updateTime,jdbcType=TIMESTAMP},
+            </if>
+        </trim>
+    </insert>
+    <select id="countByExample" parameterType="com.tzld.piaoquan.wecom.model.po.UserExample"
+            resultType="java.lang.Long">
+        select count(*) from we_com_user
+        <if test="_parameter != null">
+            <include refid="Example_Where_Clause"/>
+        </if>
+    </select>
+    <update id="updateByExampleSelective" parameterType="map">
+        update we_com_user
+        <set>
+            <if test="record.id != null">
+                id = #{record.id,jdbcType=BIGINT},
+            </if>
+            <if test="record.externalUserId != null">
+                external_user_id = #{record.externalUserId,jdbcType=VARCHAR},
+            </if>
+            <if test="record.unionId != null">
+                union_id = #{record.unionId,jdbcType=VARCHAR},
+            </if>
+            <if test="record.externalUserId3rdParty != null">
+                external_user_id_3rd_party = #{record.externalUserId3rdParty,jdbcType=VARCHAR},
+            </if>
+            <if test="record.type != null">
+                `type` = #{record.type,jdbcType=INTEGER},
+            </if>
+            <if test="record.name != null">
+                `name` = #{record.name,jdbcType=VARCHAR},
+            </if>
+            <if test="record.avatar != null">
+                avatar = #{record.avatar,jdbcType=VARCHAR},
+            </if>
+            <if test="record.gender != null">
+                gender = #{record.gender,jdbcType=INTEGER},
+            </if>
+            <if test="record.isDelete != null">
+                is_delete = #{record.isDelete,jdbcType=INTEGER},
+            </if>
+            <if test="record.createdAt != null">
+                created_at = #{record.createdAt,jdbcType=BIGINT},
+            </if>
+            <if test="record.updatedAt != null">
+                updated_at = #{record.updatedAt,jdbcType=BIGINT},
+            </if>
+            <if test="record.deletedAt != null">
+                deleted_at = #{record.deletedAt,jdbcType=BIGINT},
+            </if>
+            <if test="record.createTime != null">
+                create_time = #{record.createTime,jdbcType=TIMESTAMP},
+            </if>
+            <if test="record.updateTime != null">
+                update_time = #{record.updateTime,jdbcType=TIMESTAMP},
+            </if>
+        </set>
+        <if test="_parameter != null">
+            <include refid="Update_By_Example_Where_Clause"/>
+        </if>
+    </update>
+    <update id="updateByExample" parameterType="map">
+        update we_com_user
+        set id = #{record.id,jdbcType=BIGINT},
         external_user_id = #{record.externalUserId,jdbcType=VARCHAR},
-      </if>
-      <if test="record.unionId != null">
         union_id = #{record.unionId,jdbcType=VARCHAR},
-      </if>
-      <if test="record.externalUserId3rdParty != null">
         external_user_id_3rd_party = #{record.externalUserId3rdParty,jdbcType=VARCHAR},
-      </if>
-      <if test="record.type != null">
         `type` = #{record.type,jdbcType=INTEGER},
-      </if>
-      <if test="record.name != null">
         `name` = #{record.name,jdbcType=VARCHAR},
-      </if>
-      <if test="record.avatar != null">
         avatar = #{record.avatar,jdbcType=VARCHAR},
-      </if>
-      <if test="record.gender != null">
         gender = #{record.gender,jdbcType=INTEGER},
-      </if>
-      <if test="record.isDelete != null">
         is_delete = #{record.isDelete,jdbcType=INTEGER},
-      </if>
-      <if test="record.createdAt != null">
         created_at = #{record.createdAt,jdbcType=BIGINT},
-      </if>
-      <if test="record.updatedAt != null">
         updated_at = #{record.updatedAt,jdbcType=BIGINT},
-      </if>
-      <if test="record.deletedAt != null">
         deleted_at = #{record.deletedAt,jdbcType=BIGINT},
-      </if>
-      <if test="record.createTime != null">
         create_time = #{record.createTime,jdbcType=TIMESTAMP},
-      </if>
-      <if test="record.updateTime != null">
-        update_time = #{record.updateTime,jdbcType=TIMESTAMP},
-      </if>
-    </set>
-    <if test="_parameter != null">
-      <include refid="Update_By_Example_Where_Clause" />
-    </if>
-  </update>
-  <update id="updateByExample" parameterType="map">
-    update we_com_user
-    set id = #{record.id,jdbcType=BIGINT},
-      external_user_id = #{record.externalUserId,jdbcType=VARCHAR},
-      union_id = #{record.unionId,jdbcType=VARCHAR},
-      external_user_id_3rd_party = #{record.externalUserId3rdParty,jdbcType=VARCHAR},
-      `type` = #{record.type,jdbcType=INTEGER},
-      `name` = #{record.name,jdbcType=VARCHAR},
-      avatar = #{record.avatar,jdbcType=VARCHAR},
-      gender = #{record.gender,jdbcType=INTEGER},
-      is_delete = #{record.isDelete,jdbcType=INTEGER},
-      created_at = #{record.createdAt,jdbcType=BIGINT},
-      updated_at = #{record.updatedAt,jdbcType=BIGINT},
-      deleted_at = #{record.deletedAt,jdbcType=BIGINT},
-      create_time = #{record.createTime,jdbcType=TIMESTAMP},
-      update_time = #{record.updateTime,jdbcType=TIMESTAMP}
-    <if test="_parameter != null">
-      <include refid="Update_By_Example_Where_Clause" />
-    </if>
-  </update>
-  <update id="updateByPrimaryKeySelective" parameterType="com.tzld.piaoquan.wecom.model.po.User">
-    update we_com_user
-    <set>
-      <if test="externalUserId != null">
-        external_user_id = #{externalUserId,jdbcType=VARCHAR},
-      </if>
-      <if test="unionId != null">
-        union_id = #{unionId,jdbcType=VARCHAR},
-      </if>
-      <if test="externalUserId3rdParty != null">
-        external_user_id_3rd_party = #{externalUserId3rdParty,jdbcType=VARCHAR},
-      </if>
-      <if test="type != null">
-        `type` = #{type,jdbcType=INTEGER},
-      </if>
-      <if test="name != null">
-        `name` = #{name,jdbcType=VARCHAR},
-      </if>
-      <if test="avatar != null">
-        avatar = #{avatar,jdbcType=VARCHAR},
-      </if>
-      <if test="gender != null">
-        gender = #{gender,jdbcType=INTEGER},
-      </if>
-      <if test="isDelete != null">
-        is_delete = #{isDelete,jdbcType=INTEGER},
-      </if>
-      <if test="createdAt != null">
-        created_at = #{createdAt,jdbcType=BIGINT},
-      </if>
-      <if test="updatedAt != null">
-        updated_at = #{updatedAt,jdbcType=BIGINT},
-      </if>
-      <if test="deletedAt != null">
-        deleted_at = #{deletedAt,jdbcType=BIGINT},
-      </if>
-      <if test="createTime != null">
-        create_time = #{createTime,jdbcType=TIMESTAMP},
-      </if>
-      <if test="updateTime != null">
-        update_time = #{updateTime,jdbcType=TIMESTAMP},
-      </if>
-    </set>
-    where id = #{id,jdbcType=BIGINT}
-  </update>
-  <update id="updateByPrimaryKey" parameterType="com.tzld.piaoquan.wecom.model.po.User">
-    update we_com_user
-    set external_user_id = #{externalUserId,jdbcType=VARCHAR},
-      union_id = #{unionId,jdbcType=VARCHAR},
-      external_user_id_3rd_party = #{externalUserId3rdParty,jdbcType=VARCHAR},
-      `type` = #{type,jdbcType=INTEGER},
-      `name` = #{name,jdbcType=VARCHAR},
-      avatar = #{avatar,jdbcType=VARCHAR},
-      gender = #{gender,jdbcType=INTEGER},
-      is_delete = #{isDelete,jdbcType=INTEGER},
-      created_at = #{createdAt,jdbcType=BIGINT},
-      updated_at = #{updatedAt,jdbcType=BIGINT},
-      deleted_at = #{deletedAt,jdbcType=BIGINT},
-      create_time = #{createTime,jdbcType=TIMESTAMP},
-      update_time = #{updateTime,jdbcType=TIMESTAMP}
-    where id = #{id,jdbcType=BIGINT}
-  </update>
+        update_time = #{record.updateTime,jdbcType=TIMESTAMP}
+        <if test="_parameter != null">
+            <include refid="Update_By_Example_Where_Clause"/>
+        </if>
+    </update>
+    <update id="updateByPrimaryKeySelective" parameterType="com.tzld.piaoquan.wecom.model.po.User">
+        update we_com_user
+        <set>
+            <if test="externalUserId != null">
+                external_user_id = #{externalUserId,jdbcType=VARCHAR},
+            </if>
+            <if test="unionId != null">
+                union_id = #{unionId,jdbcType=VARCHAR},
+            </if>
+            <if test="externalUserId3rdParty != null">
+                external_user_id_3rd_party = #{externalUserId3rdParty,jdbcType=VARCHAR},
+            </if>
+            <if test="type != null">
+                `type` = #{type,jdbcType=INTEGER},
+            </if>
+            <if test="name != null">
+                `name` = #{name,jdbcType=VARCHAR},
+            </if>
+            <if test="avatar != null">
+                avatar = #{avatar,jdbcType=VARCHAR},
+            </if>
+            <if test="gender != null">
+                gender = #{gender,jdbcType=INTEGER},
+            </if>
+            <if test="isDelete != null">
+                is_delete = #{isDelete,jdbcType=INTEGER},
+            </if>
+            <if test="createdAt != null">
+                created_at = #{createdAt,jdbcType=BIGINT},
+            </if>
+            <if test="updatedAt != null">
+                updated_at = #{updatedAt,jdbcType=BIGINT},
+            </if>
+            <if test="deletedAt != null">
+                deleted_at = #{deletedAt,jdbcType=BIGINT},
+            </if>
+            <if test="createTime != null">
+                create_time = #{createTime,jdbcType=TIMESTAMP},
+            </if>
+            <if test="updateTime != null">
+                update_time = #{updateTime,jdbcType=TIMESTAMP},
+            </if>
+        </set>
+        where id = #{id,jdbcType=BIGINT}
+    </update>
+    <update id="updateByPrimaryKey" parameterType="com.tzld.piaoquan.wecom.model.po.User">
+        update we_com_user
+        set external_user_id           = #{externalUserId,jdbcType=VARCHAR},
+            union_id                   = #{unionId,jdbcType=VARCHAR},
+            external_user_id_3rd_party = #{externalUserId3rdParty,jdbcType=VARCHAR},
+            `type`                     = #{type,jdbcType=INTEGER},
+            `name`                     = #{name,jdbcType=VARCHAR},
+            avatar                     = #{avatar,jdbcType=VARCHAR},
+            gender                     = #{gender,jdbcType=INTEGER},
+            is_delete                  = #{isDelete,jdbcType=INTEGER},
+            created_at                 = #{createdAt,jdbcType=BIGINT},
+            updated_at                 = #{updatedAt,jdbcType=BIGINT},
+            deleted_at                 = #{deletedAt,jdbcType=BIGINT},
+            create_time                = #{createTime,jdbcType=TIMESTAMP},
+            update_time                = #{updateTime,jdbcType=TIMESTAMP}
+        where id = #{id,jdbcType=BIGINT}
+    </update>
 
 
-  <select id="selectIdByExternalUserId3rdParty" parameterType="String" resultType="Long">
-    select
-        id
-    from we_com_user
-    where external_user_id_3rd_party = #{externalUserId3rdParty}
-  </select>
+    <select id="selectIdByExternalUserId3rdParty" parameterType="String" resultType="Long">
+        select id
+        from we_com_user
+        where external_user_id_3rd_party = #{externalUserId3rdParty}
+    </select>
 
-  <insert id="insertList" parameterType="java.util.List">
-    insert into we_com_user
-    (
-    external_user_id,
-    union_id,
-    external_user_id_3rd_party,
-    `type`,
-    `name`,
-    avatar,
-    gender,
-    created_at,
-    updated_at,
-    deleted_at,
-    create_time,
-    update_time
-    )
-    values
-    <foreach collection="list" item="item" separator=",">
-      (
-      #{item.externalUserId,jdbcType=VARCHAR},
-      #{item.unionId,jdbcType=VARCHAR},
-      #{item.externalUserId3rdParty,jdbcType=VARCHAR},
-      #{item.type,jdbcType=INTEGER},
-      #{item.name,jdbcType=VARCHAR},
-      #{item.avatar,jdbcType=VARCHAR},
-      #{item.gender,jdbcType=INTEGER},
-      #{item.createdAt,jdbcType=BIGINT},
-      #{item.updatedAt,jdbcType=BIGINT},
-      #{item.deletedAt,jdbcType=BIGINT},
-      #{item.createTime,jdbcType=TIMESTAMP},
-      #{item.updateTime,jdbcType=TIMESTAMP}
-      )
-    </foreach>
-  </insert>
+    <select id="selectIdByExternalUserId" parameterType="String" resultType="Long">
+        select id
+        from we_com_user
+        where external_user_id = #{externalUserId}
+    </select>
+
+    <insert id="insertList" parameterType="java.util.List">
+        insert into we_com_user
+        (
+        external_user_id,
+        union_id,
+        external_user_id_3rd_party,
+        `type`,
+        `name`,
+        avatar,
+        gender,
+        created_at,
+        updated_at,
+        deleted_at,
+        create_time,
+        update_time
+        )
+        values
+        <foreach collection="list" item="item" separator=",">
+            (
+            #{item.externalUserId,jdbcType=VARCHAR},
+            #{item.unionId,jdbcType=VARCHAR},
+            #{item.externalUserId3rdParty,jdbcType=VARCHAR},
+            #{item.type,jdbcType=INTEGER},
+            #{item.name,jdbcType=VARCHAR},
+            #{item.avatar,jdbcType=VARCHAR},
+            #{item.gender,jdbcType=INTEGER},
+            #{item.createdAt,jdbcType=BIGINT},
+            #{item.updatedAt,jdbcType=BIGINT},
+            #{item.deletedAt,jdbcType=BIGINT},
+            #{item.createTime,jdbcType=TIMESTAMP},
+            #{item.updateTime,jdbcType=TIMESTAMP}
+            )
+        </foreach>
+    </insert>
 </mapper>