瀏覽代碼

add(backend) [群发消息]

wangxiao 4 年之前
父節點
當前提交
37336bf820

+ 16 - 0
operation-backend/src/main/java/com/idiot/operationbackend/controller/JobTaskController.java

@@ -10,6 +10,7 @@ import com.idiot.operationbackend.support.Constants;
 import com.idiot.operationbackend.support.CustomException;
 import com.idiot.operationbackend.support.JsonResult;
 import com.idiot.operationbackend.util.JwtTokenUtil;
+import com.idiot.operationbackend.vo.BaseType;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.slf4j.Logger;
@@ -19,6 +20,7 @@ import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
 
 import java.time.LocalDateTime;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -78,4 +80,18 @@ public class JobTaskController {
         boolean upResult = jobTaskService.updateById(jobTask);
         return ResponseEntity.ok(JsonResult.success(upResult));
     }
+
+    @GetMapping("/type")
+    @ApiOperation(value = "定时任务类型")
+    public ResponseEntity<JsonResult<List<BaseType>>> customerStatus () {
+
+        List<BaseType> baseTypes = new ArrayList<>(4);
+        BaseType group = new BaseType(Constants.GROUP,"群发消息");
+        BaseType template  = new BaseType(Constants.TEMPLATE,"模板消息");
+        BaseType customer  = new BaseType(Constants.CUSTOMER,"客服消息");
+        baseTypes.add(group);
+        baseTypes.add(template);
+        baseTypes.add(customer);
+        return ResponseEntity.ok(JsonResult.success(baseTypes));
+    }
 }

+ 19 - 0
operation-backend/src/main/java/com/idiot/operationbackend/entity/AccountFans.java

@@ -40,6 +40,8 @@ public class AccountFans {
 
     private String tagIdList;
 
+    private String tags;
+
     private String remark;
 
     private String unionId;
@@ -223,4 +225,21 @@ public class AccountFans {
     public void setState(Boolean state) {
         this.state = state;
     }
+
+
+    public String getTags() {
+        return tags;
+    }
+
+    public void setTags(String tags) {
+        this.tags = tags;
+    }
+
+    public  String  initTags () {
+        String tagIdList = this.getTagIdList();
+        return tagIdList.replace("[","").replace("]","");
+    }
+
+
+
 }

+ 16 - 9
operation-backend/src/main/java/com/idiot/operationbackend/handler/SyncUserTask.java → operation-backend/src/main/java/com/idiot/operationbackend/handler/FansInfoHandler.java

@@ -1,33 +1,40 @@
 package com.idiot.operationbackend.handler;
 
 import com.idiot.operationbackend.service.facade.WeChatService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Component;
 
 import java.util.List;
 
 /**
+ *  粉丝信息
  * @author wang xiao
  * @date Created in 18:41 2020/9/14
  */
-public class SyncUserTask {
 
-    private String accountId;
+@Component
+public class FansInfoHandler {
+
+
 
-    private  List<String> openIds;
 
     private WeChatService weChatService;
 
 
 
+    @Autowired
+    @Lazy
+    public void setWeChatService(WeChatService weChatService) {
+        this.weChatService = weChatService;
+    }
+
     /**
      * 卸载这里原因是 jdk 代理 异步方法不生效
      */
-    public void  doSyncUserTask () {
+    public void  doSyncUserTask (String accountId,List<String> openIds) {
         weChatService.syncUserTask(accountId,openIds);
     }
 
-    public SyncUserTask(String accountId, List<String> openIds, WeChatService weChatService) {
-        this.accountId = accountId;
-        this.openIds = openIds;
-        this.weChatService = weChatService;
-    }
+
 }

+ 23 - 4
operation-backend/src/main/java/com/idiot/operationbackend/handler/JobScheduleHandler.java

@@ -1,8 +1,15 @@
 package com.idiot.operationbackend.handler;
 
+import com.idiot.operationbackend.entity.GroupMsg;
 import com.idiot.operationbackend.entity.JobTask;
+import com.idiot.operationbackend.service.facade.GroupMsgService;
 import com.idiot.operationbackend.service.facade.JobTaskService;
-import com.idiot.operationbackend.support.job.BaseScheduledTask;
+import com.idiot.operationbackend.service.facade.WeChatService;
+import com.idiot.operationbackend.support.Constants;
+
+
+import com.idiot.operationbackend.support.job.BaseJobTask;
+import com.idiot.operationbackend.support.job.GroupJobTask;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.InitializingBean;
@@ -41,7 +48,8 @@ public class JobScheduleHandler implements InitializingBean {
 
     private final ReentrantLock lock = new ReentrantLock();
 
-
+    @Autowired
+    private WeChatService weChatService;
 
     @Autowired
     @Qualifier(value = "taskScheduler")
@@ -51,6 +59,9 @@ public class JobScheduleHandler implements InitializingBean {
     @Autowired
     private JobTaskService jobTaskService;
 
+    @Autowired
+    private GroupMsgService groupMsgService;
+
 
     /**
      *  添加任务
@@ -93,7 +104,7 @@ public class JobScheduleHandler implements InitializingBean {
         }
         logger.info("任务:[任务id:{},公众号:{},描述:{}]注册------->start",jobTask.getId(),jobTask.getAccountId(),jobTask.getTaskLabel());
         Long  taskTime = jobTask.getTaskTimer();
-        BaseScheduledTask scheduledTask = getTaskByKey(taskKey);
+        BaseJobTask scheduledTask = getTaskByKey(taskKey);
         if (Objects.isNull(scheduledTask)){
             logger.info("任务:[任务id:{},公众号:{},描述:{}]注册------->is null",jobTask.getId(),jobTask.getAccountId(),jobTask.getTaskLabel());
             return;
@@ -186,7 +197,15 @@ public class JobScheduleHandler implements InitializingBean {
      * @param taskKey
      * @return com.idiot.operationbackend.support.job.BaseScheduledTask
      */
-    private BaseScheduledTask getTaskByKey (String taskKey) {
+    private BaseJobTask getTaskByKey (String taskKey) {
+        JobTask jobTask = taskMap.get(taskKey);
+        if (Objects.isNull(jobTask)){
+            return null;
+        }
+        if (Constants.GROUP == jobTask.getType()) {
+            GroupMsg groupMsg = groupMsgService.getById(taskKey);
+            return new GroupJobTask(groupMsg,weChatService);
+        }
         return null;
     }
 

+ 15 - 0
operation-backend/src/main/java/com/idiot/operationbackend/service/facade/AccountFansService.java

@@ -123,4 +123,19 @@ public interface AccountFansService extends IService<AccountFans> {
      * @return java.util.List<com.idiot.operationbackend.entity.AccountFans>
      */
     List<AccountFans> queryAccountFans(List<String> openIds,String accountId);
+
+
+    /**
+     *  查询粉丝数量
+     * @author wangxiao
+     * @date 18:17 2020/9/23
+     * @param accountId accountId
+     * @param sex sex
+     * @param province province
+     * @param city city
+     * @param tags tags
+     * @param subscribeTime subscribeTime
+     * @return java.util.List<com.idiot.operationbackend.entity.AccountFans>
+     */
+    List<AccountFans> queryAccountFans(String accountId,Integer sex,String province,String city,String tags,String subscribeTime);
 }

+ 10 - 10
operation-backend/src/main/java/com/idiot/operationbackend/service/facade/WeChatService.java

@@ -1,9 +1,6 @@
 package com.idiot.operationbackend.service.facade;
 
-import com.idiot.operationbackend.entity.Account;
-import com.idiot.operationbackend.entity.AccountMenu;
-import com.idiot.operationbackend.entity.Articles;
-import com.idiot.operationbackend.entity.QrCode;
+import com.idiot.operationbackend.entity.*;
 import com.idiot.operationbackend.support.Constants;
 import com.idiot.operationbackend.support.WxInputStreamResource;
 import org.dom4j.Document;
@@ -317,8 +314,8 @@ public interface WeChatService {
     *  生成二维码
     * @author wangxiao
     * @date 19:29 2020/9/21
-    * @param qrCode
-    * @param accountId
+    * @param qrCode qrCode
+    * @param accountId accountId
     * @return java.lang.String
     */
    String createQrCode(QrCode qrCode,String accountId);
@@ -356,10 +353,13 @@ public interface WeChatService {
    String getTemplate(String accountId);
 
 
-
-
-
-
+   /**
+    *  群发消息 任务
+    * @author wangxiao
+    * @date 17:35 2020/9/23
+    * @param groupMsg  groupMsg
+    */
+   void groupMsgTask(GroupMsg groupMsg);
 
   /**
    * 不支持的消息

+ 47 - 1
operation-backend/src/main/java/com/idiot/operationbackend/service/impl/AccountFansServiceImpl.java

@@ -17,8 +17,10 @@ import org.springframework.stereotype.Service;
 
 import java.time.LocalDateTime;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
+import java.util.stream.Collectors;
 
 /**
  * @author wang xiao
@@ -99,7 +101,7 @@ public class AccountFansServiceImpl extends ServiceImpl<AccountFansMapper, Accou
             queryWrapper.le(AccountFans::getSubscribeTime,end);
         }
         if (StringUtils.isNotBlank(tagId)) {
-            queryWrapper.last(" AND locate('"+tagId+"' , tag_id_list) ORDER BY subscribe_time DESC");
+            queryWrapper.last(" AND  FIND_IN_SET('"+tagId+"',tags)");
         }else {
             queryWrapper.orderByDesc(AccountFans::getSubscribeTime);
         }
@@ -130,6 +132,7 @@ public class AccountFansServiceImpl extends ServiceImpl<AccountFansMapper, Accou
             JSONArray jsonArray = JSONArray.parseArray(temp.getTagIdList());
             jsonArray.add(wxId);
             temp.setTagIdList(jsonArray.toJSONString());
+            temp.setTags(temp.initTags());
             temp.setUpdateTime(LocalDateTime.now().format(Constants.DATE_TIME_FORMATTER));
             fans.add(temp);
 
@@ -153,6 +156,7 @@ public class AccountFansServiceImpl extends ServiceImpl<AccountFansMapper, Accou
             JSONArray jsonArray = JSONArray.parseArray(temp.getTagIdList());
             jsonArray.remove(wxId);
             temp.setTagIdList(jsonArray.toJSONString());
+            temp.setTags(temp.initTags());
             temp.setUpdateTime(LocalDateTime.now().format(Constants.DATE_TIME_FORMATTER));
             fans.add(temp);
 
@@ -169,4 +173,46 @@ public class AccountFansServiceImpl extends ServiceImpl<AccountFansMapper, Accou
                .eq(AccountFans::getAccountId,accountId)
                .in(AccountFans::getOpenId,openIds));
     }
+
+
+    @Override
+    public List<AccountFans> queryAccountFans(String accountId, Integer sex, String province, String city, String tags, String subscribeTime) {
+        LambdaQueryWrapper<AccountFans> queryWrapper = Wrappers.<AccountFans>lambdaQuery();
+        queryWrapper.eq(AccountFans::getAccountId,accountId).eq(AccountFans::getState,1);
+        if (Objects.nonNull(sex)) {
+            queryWrapper.eq(AccountFans::getSex,sex);
+        }
+        if (StringUtils.isNotBlank(province)) {
+            queryWrapper.eq(AccountFans::getProvince,province);
+        }
+        if (StringUtils.isNotBlank(city)) {
+            queryWrapper.eq(AccountFans::getCity,city);
+        }
+        if (StringUtils.isNotBlank(subscribeTime)) {
+            long start = Constants.toLocalDateTime1(subscribeTime.split("-")[0])
+                    .toEpochSecond(Constants.DEFAULT_ZONE);
+            long end = Constants.toLocalDateTime1(subscribeTime.split("-")[1])
+                    .toEpochSecond(Constants.DEFAULT_ZONE);
+            queryWrapper.ge(AccountFans::getSubscribeTime,start)
+                    .le(AccountFans::getSubscribeTime,end);
+        }
+
+        if (StringUtils.isNotBlank(tags)) {
+            List<String> strings = Arrays.stream(tags.split(",")).collect(Collectors.toList());
+            String sql = " AND (%s)";
+            StringBuilder buffer = new StringBuilder();
+            for (int i = 0; i < strings.size(); i++) {
+                if (i>0) {
+                    buffer.append(" OR ");
+                }
+                buffer.append(" FIND_IN_SET('").append(strings.get(i)).append("',tags) ");
+            }
+            sql = String.format(sql,buffer.toString());
+            queryWrapper.last(sql);
+        }
+        return list(queryWrapper);
+    }
+
+
+
 }

+ 59 - 16
operation-backend/src/main/java/com/idiot/operationbackend/service/impl/WeChatServiceImpl.java

@@ -4,11 +4,10 @@ import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
-import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.google.common.cache.*;
 import com.idiot.operationbackend.config.PlatformProperties;
 import com.idiot.operationbackend.entity.*;
-import com.idiot.operationbackend.handler.SyncUserTask;
+import com.idiot.operationbackend.handler.FansInfoHandler;
 import com.idiot.operationbackend.service.facade.AccountFansService;
 import com.idiot.operationbackend.service.facade.AccountService;
 import com.idiot.operationbackend.service.facade.AccountTagService;
@@ -22,8 +21,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.InitializingBean;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.io.FileSystemResource;
-import org.springframework.core.io.WritableResource;
 import org.springframework.http.*;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
@@ -31,12 +28,8 @@ import org.springframework.util.LinkedMultiValueMap;
 import org.springframework.util.MultiValueMap;
 import org.springframework.util.StringUtils;
 import org.springframework.web.client.RestTemplate;
-import org.springframework.web.multipart.MultipartFile;
 
 import javax.annotation.Resource;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStream;
 import java.time.LocalDateTime;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
@@ -65,22 +58,18 @@ public class WeChatServiceImpl implements WeChatService, InitializingBean {
 
     private final String ERROR_CODE = "errcode";
 
-    @Resource(name = "rpcRestTemplate")
     private RestTemplate restTemplate;
 
-
-    @Autowired
     private PlatformProperties properties;
 
-    @Autowired
     private AccountService accountService;
 
-    @Autowired
     private AccountFansService fansService;
 
-    @Autowired
     private AccountTagService tagService;
 
+    private FansInfoHandler fansInfoHandler;
+
 
     @Override
     public String notice(Map<String, String> param) {
@@ -306,7 +295,7 @@ public class WeChatServiceImpl implements WeChatService, InitializingBean {
             nextOpenId = respJsonBody.getString("next_openid");
             JSONArray openIdArray = respJsonBody.getJSONObject("data").getJSONArray("openid");
             List<String> openIds = JSONArray.parseArray(openIdArray.toJSONString(),String.class);
-            new SyncUserTask(accountId,openIds,this);
+            fansInfoHandler.doSyncUserTask(accountId,openIds);
         }while (count < total);
         cache.invalidate(lockKey);
         logger.info("公众号:{}同步粉丝数据----end,时间:{}",accountId, LocalDateTime.now().toString());
@@ -344,7 +333,8 @@ public class WeChatServiceImpl implements WeChatService, InitializingBean {
             fans.setUnionId(fansObject.getString("unionid"));
             fans.setRemark(fansObject.getString("remark"));
             fans.setGroupId(fansObject.getInteger("groupid"));
-            fans.setTagIdList(JSONObject.toJSONString(fansObject.getJSONObject("tagid_list")));
+            fans.setTagIdList(JSONObject.toJSONString(fansObject.getJSONArray("tagid_list")));
+            fans.setTags(fans.initTags());
             accountFans.add(fans);
         }
         logger.info("公众号:{}同步粉丝请求粉丝信息,openId 大小:{}---- end,时间:{}",accountId,size,LocalDateTime.now().toString());
@@ -713,6 +703,29 @@ public class WeChatServiceImpl implements WeChatService, InitializingBean {
         return jsonStr;
     }
 
+
+    @Override
+    public void groupMsgTask(GroupMsg groupMsg) {
+        if (Objects.isNull(groupMsg)) {
+            return ;
+        }
+        String accountId = groupMsg.getAccountId();
+        Integer sex = null;
+        String province = null;
+        String city = null;
+        String tag = null;
+        String subscribeTime = null;
+        if (Constants.SELECT == groupMsg.getType()) {
+            sex = groupMsg.getSelectSex();
+            province = groupMsg.getSelectProvince();
+            city = groupMsg.getSelectCity();
+            tag = groupMsg.getSelectTag();
+            subscribeTime = groupMsg.getSelectSubscribeTime();
+        }
+        List<AccountFans> fans = fansService.queryAccountFans(accountId,sex,province,city,tag,subscribeTime);
+
+    }
+
     private String parseToJson (List<AccountMenu> accountMenus) {
         int size  = accountMenus.size();
         JSONObject jsonObject = new JSONObject(1);
@@ -744,4 +757,34 @@ public class WeChatServiceImpl implements WeChatService, InitializingBean {
         jsonObject.put("button",button);
         return jsonObject.toJSONString();
     }
+
+    @Resource(name = "rpcRestTemplate")
+    public void setRestTemplate(RestTemplate restTemplate) {
+        this.restTemplate = restTemplate;
+    }
+
+    @Autowired
+    public void setProperties(PlatformProperties properties) {
+        this.properties = properties;
+    }
+
+    @Autowired
+    public void setAccountService(AccountService accountService) {
+        this.accountService = accountService;
+    }
+
+    @Autowired
+    public void setFansService(AccountFansService fansService) {
+        this.fansService = fansService;
+    }
+
+    @Autowired
+    public void setTagService(AccountTagService tagService) {
+        this.tagService = tagService;
+    }
+
+    @Resource
+    public void setFansInfoHandler(FansInfoHandler fansInfoHandler) {
+        this.fansInfoHandler = fansInfoHandler;
+    }
 }

+ 29 - 10
operation-backend/src/main/java/com/idiot/operationbackend/support/Constants.java

@@ -89,30 +89,45 @@ public class Constants {
      *  发送状态码 '0'-已发送,'1'-未发送,'2'-发送中, '3'-发送终止,4'-发送失败
      * @author wangxiao
      */
-     public static final Integer SUCCESSED = 0;
+     public static final int SUCCESSED = 0;
 
-     public static final Integer WAITING = 1;
+     public static final int WAITING = 1;
 
-     public static final Integer RUNING = 2;
+     public static final int RUNING = 2;
 
-     public static final Integer END = 3;
+     public static final int END = 3;
 
-     public static final Integer FAILED = 4;
+     public static final int FAILED = 4;
 
 
     /**
      *  发送消息状态码 类型,1-图文,2-图片,3-文字,4-音频,5-视频"
      * @author wangxiao
      */
-    public static final Integer NEWS = 1;
+    public static final int NEWS = 1;
 
-    public static final Integer IMG = 2;
+    public static final int IMG = 2;
 
-    public static final Integer TEXT = 3;
+    public static final int TEXT = 3;
 
-    public static final Integer VOI = 4;
+    public static final int VOI = 4;
 
-    public static final Integer VID = 5;
+    public static final int VID = 5;
+
+    /**
+     *  消息任务类型 群发,模板 ,客服
+     * @author wangxiao
+     */
+    public static final int GROUP =1;
+    public static final int TEMPLATE = 2;
+    public static final int CUSTOMER = 3;
+
+    /**
+     *  全部 ,筛选
+     * @author wangxiao
+     */
+    public static final int ALL =1;
+    public static final int SELECT = 0;
 
 
     /**
@@ -145,6 +160,10 @@ public class Constants {
         return LocalDate.parse(dateStr,Constants.DATE_FORMATTER).atTime(0,0,0);
     }
 
+    public static LocalDateTime toLocalDateTime1 (String dateStr) {
+        return LocalDate.parse(dateStr,DateTimeFormatter.ofPattern("yyyy/MM/dd")).atTime(0,0,0);
+    }
+
     /**
      *  描述转时间(多余)
      * @author wangxiao

+ 1 - 1
operation-backend/src/main/java/com/idiot/operationbackend/support/job/BaseScheduledTask.java → operation-backend/src/main/java/com/idiot/operationbackend/support/job/BaseJobTask.java

@@ -5,5 +5,5 @@ package com.idiot.operationbackend.support.job;
  * @author wang xiao
  * @date Created in 15:07 2020/9/23
  */
-public interface BaseScheduledTask extends Runnable{
+public interface BaseJobTask extends Runnable{
 }

+ 33 - 0
operation-backend/src/main/java/com/idiot/operationbackend/support/job/GroupJobTask.java

@@ -0,0 +1,33 @@
+package com.idiot.operationbackend.support.job;
+
+import com.idiot.operationbackend.entity.GroupMsg;
+import com.idiot.operationbackend.service.facade.WeChatService;
+
+/**
+ *  群发任务 中介一层是因为 构造参数 可能未知
+ * @author wang xiao
+ * @date Created in 15:09 2020/9/23
+ */
+public class GroupJobTask implements BaseJobTask {
+
+    private GroupMsg groupMsg;
+
+    private WeChatService weChatService;
+
+    public GroupJobTask() {
+    }
+
+    public GroupJobTask(GroupMsg groupMsg, WeChatService weChatService) {
+        this.groupMsg = groupMsg;
+        this.weChatService = weChatService;
+    }
+
+    @Override
+    public void run() {
+        weChatService.groupMsgTask(groupMsg);
+    }
+
+
+
+
+}

+ 0 - 14
operation-backend/src/main/java/com/idiot/operationbackend/support/job/GroupScheduledTaskTask.java

@@ -1,14 +0,0 @@
-package com.idiot.operationbackend.support.job;
-
-/**
- * @author wang xiao
- * @date Created in 15:09 2020/9/23
- */
-public class GroupScheduledTaskTask implements BaseScheduledTask {
-
-
-    @Override
-    public void run() {
-
-    }
-}

+ 29 - 0
operation-backend/src/main/java/com/idiot/operationbackend/support/job/TemplateJobTask.java

@@ -0,0 +1,29 @@
+package com.idiot.operationbackend.support.job;
+
+import com.idiot.operationbackend.entity.TemplateMsg;
+import com.idiot.operationbackend.service.facade.WeChatService;
+
+/**
+ * 模板消息发送任务 中介一层是因为 构造参数 可能未知
+ * @author wang xiao
+ * @date Created in 17:55 2020/9/23
+ */
+public class TemplateJobTask implements BaseJobTask {
+
+    private TemplateMsg templateMsg;
+
+    private WeChatService weChatService;
+
+    public TemplateJobTask() {
+    }
+
+    public TemplateJobTask(TemplateMsg templateMsg, WeChatService weChatService) {
+        this.templateMsg = templateMsg;
+        this.weChatService = weChatService;
+    }
+
+    @Override
+    public void run() {
+
+    }
+}

+ 1 - 1
sql/dataBase.sql

@@ -70,11 +70,11 @@ CREATE TABLE `t_account_fans`  (
   `state` tinyint(1) NULL DEFAULT NULL COMMENT '状态码',
   `create_time` bigint(0) NULL DEFAULT NULL COMMENT '创建时间 秒数时间戳',
   `update_time` datetime(0) NULL DEFAULT NULL,
+  `tags` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '添加这个字段是为了方便查询',
   PRIMARY KEY (`id`) USING BTREE
 ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '公众号粉丝' ROW_FORMAT = Dynamic;
 
 
-
 -- ----------------------------
 -- Table structure for 公众号标签
 -- ----------------------------