Browse Source

add(backend) [粉丝图文影响力 1.0]

wangxiao 4 years ago
parent
commit
ca5157eddc

+ 139 - 6
operation-backend/src/main/java/com/idiot/operationbackend/controller/IndexController.java

@@ -2,18 +2,18 @@ package com.idiot.operationbackend.controller;
 
 import com.idiot.operationbackend.entity.Account;
 import com.idiot.operationbackend.entity.AccountStat;
+import com.idiot.operationbackend.entity.ArticleStat;
 import com.idiot.operationbackend.entity.FansActionStat;
-import com.idiot.operationbackend.service.facade.AccountFansService;
-import com.idiot.operationbackend.service.facade.AccountStatService;
-import com.idiot.operationbackend.service.facade.AccountService;
-import com.idiot.operationbackend.service.facade.FansActionStatService;
+import com.idiot.operationbackend.service.facade.*;
 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.ArticleStatData;
 import com.idiot.operationbackend.vo.GeneralStatData;
 
 import com.idiot.operationbackend.vo.NumberStatData;
+import com.idiot.operationbackend.vo.RemainStatData;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.slf4j.Logger;
@@ -67,6 +67,9 @@ public class IndexController {
     @Autowired
     private FansActionStatService actionStatService;
 
+    @Autowired
+    private ArticleStatService articleStatService;
+
 
 
 
@@ -193,7 +196,9 @@ public class IndexController {
                                                                               @RequestParam String startDate,
                                                                               @RequestParam String endDate) {
         String userId = JwtTokenUtil.getUserId(token);
-        checkDate(startDate,endDate);
+        if (!checkDate(startDate,endDate)){
+            throw new CustomException(500,"请选择查询时间范围!");
+        }
         logger.info("用户:{}查询首页单个公众号:{}粉丝活跃度,startDate:{},endDate:{} --->start",userId,accountId,startDate,endDate);
         List<AccountStat> accountStats = accountStatService.queryAccountStatByDate(accountId,startDate,endDate);
         logger.info("用户:{}查询首页单个公众号:{}粉丝活跃度,startDate:{},endDate:{} --->end",userId,accountId,startDate,endDate);
@@ -201,6 +206,50 @@ public class IndexController {
     }
 
 
+    @GetMapping("/remain/{accountId}")
+    @ApiOperation(value = "查询单个公众号--粉丝忠诚度")
+    public ResponseEntity<JsonResult<List<RemainStatData>>> getFansRemainStat(@RequestHeader String token,
+                                                                              @PathVariable String accountId,
+                                                                              @RequestParam String date) {
+        String userId = JwtTokenUtil.getUserId(token);
+        if (StringUtils.isEmpty(date)){
+            throw new CustomException(500,"请选择查询时间!");
+        }
+        LocalDateTime endDate = Constants.toLocalDateTime(date);
+        LocalDateTime startDate = Constants.toLocalDateTime(date).plusDays(-7);
+        logger.info("用户:{}查询首页单个公众号:{}粉丝忠诚度,date:{} --->start",userId,accountId,date);
+        List<AccountStat> accountStats = accountStatService.queryAccountStatByDate(accountId,startDate,endDate);
+        List<RemainStatData> remainStatData = statFansRemainData(accountStats);
+        if (Objects.isNull(remainStatData)) {
+            remainStatData = new ArrayList<>();
+        }
+        logger.info("用户:{}查询首页单个公众号:{}粉丝忠诚度,date:{} --->end",userId,accountId,date);
+        return ResponseEntity.ok(JsonResult.success(remainStatData));
+    }
+
+    @GetMapping("/articles/{accountId}")
+    @ApiOperation(value = "查询单个公众号--图文影响力")
+    public ResponseEntity<JsonResult<List<ArticleStatData>>> getFansPageStat(@RequestHeader String token,
+                                                                             @PathVariable String accountId,
+                                                                             @RequestParam String startDate,
+                                                                             @RequestParam String endDate) {
+        String userId = JwtTokenUtil.getUserId(token);
+        if (!checkDate(startDate,endDate)){
+            throw new CustomException(500,"请选择查询时间!");
+        }
+        logger.info("用户:{}查询首页单个公众号:{}图文影响力,startDate:{},endDate:{} --->start",userId,accountId,startDate,endDate);
+        List<ArticleStat> articleStats = articleStatService.queryArticleStatByDate(accountId,startDate,endDate);
+        List<ArticleStatData> articleStatData = statArticleData(articleStats);
+        if (CollectionUtils.isEmpty(articleStatData)){
+            articleStatData = new ArrayList<>();
+        }
+        logger.info("用户:{}查询首页单个公众号:{}图文影响力,startDate:{},endDate:{} --->start",userId,accountId,startDate,endDate);
+        return ResponseEntity.ok(JsonResult.success(articleStatData));
+    }
+
+
+
+
 
 
     /**
@@ -266,6 +315,8 @@ public class IndexController {
         return !(StringUtils.isEmpty(start) | StringUtils.isEmpty(end));
     }
 
+
+
     /**
      *  统计 粉丝增长 时间段
      * @author wangxiao
@@ -327,8 +378,90 @@ public class IndexController {
 
 
 
+    /**
+     *  统计留存粉丝
+     * @author wangxiao
+     * @date 14:22 2020/9/17
+     * @param accountStats
+     * @return java.util.List<com.idiot.operationbackend.vo.RemainStatData>
+     */
+    private List<RemainStatData> statFansRemainData(List<AccountStat> accountStats) {
+        if (CollectionUtils.isEmpty(accountStats)) {
+            return null;
+        }
+        int size = accountStats.size();
+        List<RemainStatData> remainStatDataList = new ArrayList<>(size);
+        String statDate = null;
+        Long newNum = null;
+        Long totalNum = null;
+        RemainStatData remain = null;
+        for (AccountStat temp : accountStats) {
+            statDate = temp.getStatDate();
+            newNum = temp.getNewNum();
+            totalNum = temp.getTotalFansNum();
+            remain = new RemainStatData(statDate,newNum);
+            remain.setDay1Num(calcRemain(accountStats,totalNum,statDate,1));
+            remain.setDay2Num(calcRemain(accountStats,totalNum,statDate,2));
+            remain.setDay3Num(calcRemain(accountStats,totalNum,statDate,3));
+            remain.setDay4Num(calcRemain(accountStats,totalNum,statDate,4));
+            remain.setDay5Num(calcRemain(accountStats,totalNum,statDate,5));
+            remain.setDay6Num(calcRemain(accountStats,totalNum,statDate,6));
+            remain.setDay7Num(calcRemain(accountStats,totalNum,statDate,7));
+            remainStatDataList.add(remain);
+        }
+        return remainStatDataList;
+    }
+    /**
+     *  计算留存数
+     * @author wangxiao
+     * @date 14:35 2020/9/17
+     * @param accountStats 数组
+     * @param nowTotal 当前总数
+     * @param targetIndex 几天前下表
+     * @param nowStatDate  当前统计日期
+     * @return long
+     */
+    private long calcRemain (List<AccountStat> accountStats,long nowTotal,String nowStatDate,int targetIndex) {
+        long remainNum;
+        LocalDate nowDate = LocalDate.parse(nowStatDate,Constants.DATE_FORMATTER);
+        String targetStatDate = nowDate.plusDays(-targetIndex).format(Constants.DATE_FORMATTER);
+        remainNum = accountStats.stream()
+                .filter(e->targetStatDate.equals(e.getStatDate()))
+                .findAny().map(e->e.getTotalFansNum()-nowTotal)
+                .orElse(0L);
+        return remainNum;
+    }
 
-
+    /**
+     *  统计图文影响力
+     * @author wangxiao
+     * @date 16:06 2020/9/17
+     * @param articleStats
+     * @return java.util.List<com.idiot.operationbackend.vo.ArticleStatData>
+     */
+    private List<ArticleStatData> statArticleData (List<ArticleStat> articleStats) {
+        if (CollectionUtils.isEmpty(articleStats)){
+            return null;
+        }
+        Map<String,List<ArticleStat>> temp = articleStats.stream().collect(Collectors.groupingBy(ArticleStat::getStatDate));
+        List<ArticleStatData> articleStatData = new ArrayList<>(temp.size());
+        List<ArticleStat> var = null;
+        ArticleStatData result =  null;
+        for (Map.Entry<String,List<ArticleStat>> entry : temp.entrySet()) {
+            var = entry.getValue();
+            result = new ArticleStatData(entry.getKey(),var);
+            result.setShareUser(var.stream().mapToLong(ArticleStat::getShareUser).sum());
+            result.setShareCount(var.stream().mapToLong(ArticleStat::getShareCount).sum());
+            result.setAddToFavCount(var.stream().mapToLong(ArticleStat::getAddToFavCount).sum());
+            result.setAddToFavUser(var.stream().mapToLong(ArticleStat::getAddToFavUser).sum());
+            result.setIntPageReadCount(var.stream().mapToLong(ArticleStat::getIntPageReadCount).sum());
+            result.setIntPageReadUser(var.stream().mapToLong(ArticleStat::getIntPageReadUser).sum());
+            result.setOriPageReadCount(var.stream().mapToLong(ArticleStat::getOriPageReadCount).sum());
+            result.setOriPageReadUser(var.stream().mapToLong(ArticleStat::getOriPageReadUser).sum());
+            articleStatData.add(result);
+        }
+        return articleStatData;
+    }
 
 
 }

+ 156 - 0
operation-backend/src/main/java/com/idiot/operationbackend/entity/ArticleStat.java

@@ -0,0 +1,156 @@
+package com.idiot.operationbackend.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+/**
+ * 图文阅读统计
+ * @author wang xiao
+ * @date Created in 15:32 2020/9/17
+ */
+@TableName("t_article_stat")
+public class ArticleStat {
+
+    @TableId
+    private String id;
+
+    private String accountId;
+
+    private String statDate;
+
+    private String msgId;
+
+    private String title;
+
+    private Long intPageReadUser;
+
+    private Long intPageReadCount;
+
+    private Long oriPageReadUser;
+
+    private Long oriPageReadCount;
+
+    private Long shareUser;
+
+    private Long shareCount;
+
+    private Long addToFavUser;
+
+    private Long addToFavCount;
+
+    private String createTime;
+
+
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getAccountId() {
+        return accountId;
+    }
+
+    public void setAccountId(String accountId) {
+        this.accountId = accountId;
+    }
+
+    public String getStatDate() {
+        return statDate;
+    }
+
+    public void setStatDate(String statDate) {
+        this.statDate = statDate;
+    }
+
+    public String getMsgId() {
+        return msgId;
+    }
+
+    public void setMsgId(String msgId) {
+        this.msgId = msgId;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public Long getIntPageReadUser() {
+        return intPageReadUser;
+    }
+
+    public void setIntPageReadUser(Long intPageReadUser) {
+        this.intPageReadUser = intPageReadUser;
+    }
+
+    public Long getIntPageReadCount() {
+        return intPageReadCount;
+    }
+
+    public void setIntPageReadCount(Long intPageReadCount) {
+        this.intPageReadCount = intPageReadCount;
+    }
+
+    public Long getOriPageReadUser() {
+        return oriPageReadUser;
+    }
+
+    public void setOriPageReadUser(Long oriPageReadUser) {
+        this.oriPageReadUser = oriPageReadUser;
+    }
+
+    public Long getOriPageReadCount() {
+        return oriPageReadCount;
+    }
+
+    public void setOriPageReadCount(Long oriPageReadCount) {
+        this.oriPageReadCount = oriPageReadCount;
+    }
+
+    public Long getShareUser() {
+        return shareUser;
+    }
+
+    public void setShareUser(Long shareUser) {
+        this.shareUser = shareUser;
+    }
+
+    public Long getShareCount() {
+        return shareCount;
+    }
+
+    public void setShareCount(Long shareCount) {
+        this.shareCount = shareCount;
+    }
+
+    public Long getAddToFavUser() {
+        return addToFavUser;
+    }
+
+    public void setAddToFavUser(Long addToFavUser) {
+        this.addToFavUser = addToFavUser;
+    }
+
+    public Long getAddToFavCount() {
+        return addToFavCount;
+    }
+
+    public void setAddToFavCount(Long addToFavCount) {
+        this.addToFavCount = addToFavCount;
+    }
+
+    public String getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(String createTime) {
+        this.createTime = createTime;
+    }
+}

+ 25 - 1
operation-backend/src/main/java/com/idiot/operationbackend/handler/ScheduledHandler.java

@@ -4,6 +4,7 @@ package com.idiot.operationbackend.handler;
 import com.idiot.operationbackend.entity.Account;
 import com.idiot.operationbackend.service.facade.AccountStatService;
 import com.idiot.operationbackend.service.facade.AccountService;
+import com.idiot.operationbackend.service.facade.ArticleStatService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -28,6 +29,9 @@ public class ScheduledHandler {
     @Autowired
     private AccountService accountService;
 
+    @Autowired
+    private ArticleStatService articleStatService;
+
     private final Logger logger = LoggerFactory.getLogger(ScheduledHandler.class);
 
     /**
@@ -36,7 +40,7 @@ public class ScheduledHandler {
      * @date 12:09 2020/9/17
      */
     @Scheduled(cron = "0 0 1 * * ?")
-    public void  scheduled () {
+    public void  scheduledAccount () {
         logger.info("开始同步微信用户分析数据----->start,时间:{}", LocalDateTime.now().toString());
         List<Account> accounts = accountService.queryAccount();
         if (null == accounts || accounts.isEmpty()) {
@@ -50,4 +54,24 @@ public class ScheduledHandler {
         logger.info("开始同步微信用户分析数据----->end,时间:{}", LocalDateTime.now().toString());
     }
 
+    /**
+     *  请求微信 同步图文统计信息
+     * @author wangxiao
+     * @date 12:09 2020/9/17
+     */
+    @Scheduled(cron = "0 0 2 * * ?")
+    public void  scheduledArticle () {
+        logger.info("开始同步微信图文分析数据----->start,时间:{}", LocalDateTime.now().toString());
+        List<Account> accounts = accountService.queryAccount();
+        if (null == accounts || accounts.isEmpty()) {
+            logger.info("开始同步微信图文分析数据----->认证公众号信息为空,时间:{}", LocalDateTime.now().toString());
+            return;
+        }
+        for (Account account : accounts) {
+            logger.info("同步微信公众号:{}用户分析数据----->,时间:{}", account.getId(),LocalDateTime.now().toString());
+            articleStatService.syncArticleStatData(account.getId());
+        }
+        logger.info("开始同步微信用户分析数据----->end,时间:{}", LocalDateTime.now().toString());
+    }
+
 }

+ 11 - 0
operation-backend/src/main/java/com/idiot/operationbackend/mappers/ArticleStatMapper.java

@@ -0,0 +1,11 @@
+package com.idiot.operationbackend.mappers;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.idiot.operationbackend.entity.ArticleStat;
+
+/**
+ * @author wang xiao
+ * @date Created in 15:39 2020/9/17
+ */
+public interface ArticleStatMapper extends BaseMapper<ArticleStat> {
+}

+ 14 - 1
operation-backend/src/main/java/com/idiot/operationbackend/service/facade/AccountStatService.java

@@ -2,8 +2,8 @@ package com.idiot.operationbackend.service.facade;
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.idiot.operationbackend.entity.AccountStat;
-import org.apache.ibatis.annotations.Select;
 
+import java.time.LocalDateTime;
 import java.util.List;
 
 /**
@@ -77,6 +77,8 @@ public interface AccountStatService extends IService<AccountStat> {
      * @return int
      */
     int inactiveFifteenFansNum (String accountId,String statDate);
+
+
     /**
      *  查询区间内 粉丝数据统计
      * @author wangxiao
@@ -87,4 +89,15 @@ public interface AccountStatService extends IService<AccountStat> {
      * @return java.util.List<com.idiot.operationbackend.entity.AccountStat>
      */
     List<AccountStat> queryAccountStatByDate (String accountId, String startDate,String endDate);
+
+    /**
+     *  查询区间内 粉丝数据统计
+     * @author wangxiao
+     * @date 12:00 2020/9/17
+     * @param accountId
+     * @param startDate
+     * @param endDate
+     * @return java.util.List<com.idiot.operationbackend.entity.AccountStat>
+     */
+    List<AccountStat> queryAccountStatByDate (String accountId, LocalDateTime startDate, LocalDateTime endDate);
 }

+ 45 - 0
operation-backend/src/main/java/com/idiot/operationbackend/service/facade/ArticleStatService.java

@@ -0,0 +1,45 @@
+package com.idiot.operationbackend.service.facade;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.idiot.operationbackend.entity.ArticleStat;
+
+import java.util.List;
+
+/**
+ * @author wang xiao
+ * @date Created in 15:39 2020/9/17
+ */
+public interface ArticleStatService extends IService<ArticleStat> {
+
+    /**
+     *  查询图文统计
+     * @author wangxiao
+     * @date 15:44 2020/9/17
+     * @param accountId
+     * @param startDate
+     * @param endDate
+     * @return java.util.List<com.idiot.operationbackend.entity.ArticleStat>
+     */
+    List<ArticleStat> queryArticleStatByDate (String accountId,String startDate,String endDate);
+
+
+    /**
+     *  同步微信图文数据
+     * @author wangxiao
+     * @date 16:13 2020/9/17
+     * @param accountId
+     * @return void
+     */
+    void syncArticleStatData (String accountId);
+
+
+    /**
+     *  查询统计信息
+     * @author wangxiao
+     * @date 16:22 2020/9/17
+     * @param accountId
+     * @param msgId
+     * @return com.idiot.operationbackend.entity.ArticleStat
+     */
+    ArticleStat queryByAccountIdAndMsgId(String accountId,String msgId);
+}

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

@@ -219,6 +219,18 @@ public interface WeChatService {
   String getFansCumulate(String accountId,String startDate,String endDate);
 
 
+  /**
+   *  查询图文阅读数据
+   * @author wangxiao
+   * @date 16:16 2020/9/17
+   * @param accountId
+   * @param startDate
+   * @param endDate
+   * @return java.lang.String
+   */
+  String getArticleSummary(String accountId,String startDate,String endDate );
+
+
   /**
    * 不支持的消息
    * @author wangxiao

+ 11 - 1
operation-backend/src/main/java/com/idiot/operationbackend/service/impl/AccountStatServiceImpl.java

@@ -87,7 +87,7 @@ public class AccountStatServiceImpl extends ServiceImpl<AccountStatMapper, Accou
         // 7天
         long sevenInactiveNum =  inactiveSevenFansNum(accountId,yesterday);
         // 15 天
-        long fifteenInactiveNum =  inactiveSevenFansNum(accountId,yesterday);
+        long fifteenInactiveNum =  inactiveFifteenFansNum(accountId,yesterday);
         AccountStat ydData = statData.stream().filter(e->yesterday.equals(e.getStatDate())).findFirst().orElseGet(AccountStat::new);
         addNum = newNum-cancelNum;
         ydData.setTotalFansNum(totalNum);
@@ -143,4 +143,14 @@ public class AccountStatServiceImpl extends ServiceImpl<AccountStatMapper, Accou
                 .ge(AccountStat::getStatDate,startDate)
                 .le(AccountStat::getStatDate,endDate));
     }
+
+    @Override
+    public List<AccountStat> queryAccountStatByDate(String accountId, LocalDateTime startDate, LocalDateTime endDate) {
+        String startStr = startDate.format(Constants.DATE_FORMATTER);
+        String endStr = endDate.format(Constants.DATE_FORMATTER);
+        return list(Wrappers.<AccountStat>lambdaQuery()
+                .eq(AccountStat::getAccountId,accountId)
+                .ge(AccountStat::getStatDate,startStr)
+                .le(AccountStat::getStatDate,endStr));
+    }
 }

+ 88 - 0
operation-backend/src/main/java/com/idiot/operationbackend/service/impl/ArticleStatServiceImpl.java

@@ -0,0 +1,88 @@
+package com.idiot.operationbackend.service.impl;
+
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.idiot.operationbackend.entity.ArticleStat;
+import com.idiot.operationbackend.mappers.ArticleStatMapper;
+import com.idiot.operationbackend.service.facade.ArticleStatService;
+import com.idiot.operationbackend.service.facade.WeChatService;
+import com.idiot.operationbackend.support.Constants;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * @author wang xiao
+ * @date Created in 15:40 2020/9/17
+ */
+@Service
+public class ArticleStatServiceImpl  extends ServiceImpl<ArticleStatMapper, ArticleStat>
+        implements ArticleStatService {
+
+
+    @Autowired
+    private WeChatService weChatService;
+
+
+    @Override
+    public List<ArticleStat> queryArticleStatByDate(String accountId, String startDate, String endDate) {
+        return list(Wrappers.<ArticleStat>lambdaQuery()
+                .eq(ArticleStat::getAccountId,accountId)
+                .ge(ArticleStat::getStatDate,startDate)
+                .le(ArticleStat::getStatDate,endDate));
+    }
+
+    @Override
+    public void syncArticleStatData(String accountId) {
+        String yeDay = LocalDate.now().plusDays(-1).format(Constants.DATE_FORMATTER);
+        String jsonStr = weChatService.getArticleSummary(accountId,yeDay,yeDay);
+        JSONArray jsonArray = JSONObject.parseObject(jsonStr).getJSONArray("list");
+        if (CollectionUtils.isEmpty(jsonArray)) {
+            return;
+        }
+        int size = jsonArray.size();
+        JSONObject var = null;
+        String msgId = null;
+        ArticleStat articleStat = null;
+        List<ArticleStat> varArray = new ArrayList<>(size);
+        for (int i = 0; i < size; i++) {
+            var = jsonArray.getJSONObject(i);
+            msgId = var.getString("msgid");
+            ArticleStat temp = queryByAccountIdAndMsgId(accountId,msgId);
+            if (Objects.nonNull(temp)){
+                articleStat.setId(temp.getId());
+            }
+            articleStat.setAccountId(accountId);
+            articleStat.setMsgId(msgId);
+            // 预设值
+            articleStat.setAddToFavCount(var.getLong("add_to_fav_count"));
+            articleStat.setAddToFavUser(var.getLong("add_to_fav_user"));
+            articleStat.setShareCount(var.getLong("share_count"));
+            articleStat.setShareUser(var.getLong("share_user"));
+            articleStat.setOriPageReadCount(var.getLong("ori_page_read_count"));
+            articleStat.setOriPageReadUser(var.getLong("ori_page_read_user"));
+            articleStat.setIntPageReadCount(var.getLong("int_page_read_count"));
+            articleStat.setIntPageReadUser(var.getLong("int_page_read_user"));
+            articleStat.setTitle(var.getString("title"));
+            articleStat.setStatDate(var.getString("ref_date"));
+            varArray.add(articleStat);
+        }
+        saveOrUpdateBatch(varArray);
+    }
+
+
+    @Override
+    public ArticleStat queryByAccountIdAndMsgId(String accountId, String msgId) {
+        return getOne(Wrappers.<ArticleStat>lambdaQuery()
+                .eq(ArticleStat::getAccountId,accountId)
+                .eq(ArticleStat::getMsgId,msgId),false);
+    }
+}

+ 19 - 0
operation-backend/src/main/java/com/idiot/operationbackend/service/impl/WeChatServiceImpl.java

@@ -448,4 +448,23 @@ public class WeChatServiceImpl implements WeChatService, InitializingBean {
                 LocalDateTime.now().toString(),jsonStr);
         return null;
     }
+
+    @Override
+    public String getArticleSummary(String accountId, String startDate, String endDate) {
+        String requestUrl = "https://api.weixin.qq.com/datacube/getarticlesummary?access_token=ACCESS_TOKEN";
+        String accessToken = getAuthorizerAccessToken(accountId);
+        requestUrl = String.format(requestUrl,accessToken);
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        logger.info("获取微信图文阅读数据,accountId:{}----start,时间:{}",accountId, LocalDateTime.now().toString());
+        MultiValueMap<String,String> params = new LinkedMultiValueMap<>(2);
+        params.add("begin_date",startDate);
+        params.add("end_date",endDate);
+        HttpEntity<MultiValueMap<String, String>>  entity = new HttpEntity<> (params,headers);
+        ResponseEntity<String> respStr = restTemplate.exchange(requestUrl,HttpMethod.POST,entity,String.class);
+        String jsonStr = respStr.getBody();
+        logger.info("获取微信图文阅读数据,accountId:{}----end,时间:{},微信返回{}",accountId,
+                LocalDateTime.now().toString(),jsonStr);
+        return jsonStr;
+    }
 }

+ 137 - 0
operation-backend/src/main/java/com/idiot/operationbackend/vo/ArticleStatData.java

@@ -0,0 +1,137 @@
+package com.idiot.operationbackend.vo;
+
+import com.idiot.operationbackend.entity.ArticleStat;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * @author wang xiao
+ * @date Created in 15:48 2020/9/17
+ */
+public class ArticleStatData {
+
+    private String statDate;
+
+    private Long intPageReadUser;
+
+    private Long intPageReadCount;
+
+    private Long oriPageReadUser;
+
+    private Long oriPageReadCount;
+
+    private Long shareUser;
+
+    private Long shareCount;
+
+    private Long addToFavUser;
+
+    private Long addToFavCount;
+
+    private Integer size;
+
+    private List<ArticleStat> list;
+
+    public ArticleStatData() {
+    }
+
+    public ArticleStatData(String statDate, Integer size) {
+        this.statDate = statDate;
+        this.size = size;
+    }
+
+    public ArticleStatData(String statDate, List<ArticleStat> list) {
+        this.statDate = statDate;
+        this.size = Objects.isNull(list)?0:list.size();
+        this.list = list;
+    }
+
+    public String getStatDate() {
+        return statDate;
+    }
+
+    public void setStatDate(String statDate) {
+        this.statDate = statDate;
+    }
+
+    public Long getIntPageReadUser() {
+        return intPageReadUser;
+    }
+
+    public void setIntPageReadUser(Long intPageReadUser) {
+        this.intPageReadUser = intPageReadUser;
+    }
+
+    public Long getIntPageReadCount() {
+        return intPageReadCount;
+    }
+
+    public void setIntPageReadCount(Long intPageReadCount) {
+        this.intPageReadCount = intPageReadCount;
+    }
+
+    public Long getOriPageReadUser() {
+        return oriPageReadUser;
+    }
+
+    public void setOriPageReadUser(Long oriPageReadUser) {
+        this.oriPageReadUser = oriPageReadUser;
+    }
+
+    public Long getOriPageReadCount() {
+        return oriPageReadCount;
+    }
+
+    public void setOriPageReadCount(Long oriPageReadCount) {
+        this.oriPageReadCount = oriPageReadCount;
+    }
+
+    public Long getShareUser() {
+        return shareUser;
+    }
+
+    public void setShareUser(Long shareUser) {
+        this.shareUser = shareUser;
+    }
+
+    public Long getShareCount() {
+        return shareCount;
+    }
+
+    public void setShareCount(Long shareCount) {
+        this.shareCount = shareCount;
+    }
+
+    public Long getAddToFavUser() {
+        return addToFavUser;
+    }
+
+    public void setAddToFavUser(Long addToFavUser) {
+        this.addToFavUser = addToFavUser;
+    }
+
+    public Long getAddToFavCount() {
+        return addToFavCount;
+    }
+
+    public void setAddToFavCount(Long addToFavCount) {
+        this.addToFavCount = addToFavCount;
+    }
+
+    public Integer getSize() {
+        return size;
+    }
+
+    public void setSize(Integer size) {
+        this.size = size;
+    }
+
+    public List<ArticleStat> getList() {
+        return list;
+    }
+
+    public void setList(List<ArticleStat> list) {
+        this.list = list;
+    }
+}

+ 117 - 0
operation-backend/src/main/java/com/idiot/operationbackend/vo/RemainStatData.java

@@ -0,0 +1,117 @@
+package com.idiot.operationbackend.vo;
+
+/**
+ * 粉丝留存
+ * @author wang xiao
+ * @date Created in 14:06 2020/9/17
+ */
+public class RemainStatData {
+
+    private String statDate;
+
+    /**
+     * 当天粉丝数
+     */
+    private Long nowNum;
+
+    /**
+     * 第1~7 留存 粉丝数
+     */
+    private Long day1Num;
+
+    private Long day2Num;
+
+    private Long day3Num;
+
+    private Long day4Num;
+
+    private Long day5Num;
+
+    private Long day6Num;
+
+    private Long day7Num;
+
+    public RemainStatData() {
+    }
+
+    public RemainStatData(String statDate) {
+        this.statDate = statDate;
+    }
+
+    public RemainStatData(String statDate, Long nowNum) {
+        this.statDate = statDate;
+        this.nowNum = nowNum;
+    }
+
+    public String getStatDate() {
+        return statDate;
+    }
+
+    public void setStatDate(String statDate) {
+        this.statDate = statDate;
+    }
+
+    public Long getNowNum() {
+        return nowNum;
+    }
+
+    public void setNowNum(Long nowNum) {
+        this.nowNum = nowNum;
+    }
+
+    public Long getDay1Num() {
+        return day1Num;
+    }
+
+    public void setDay1Num(Long day1Num) {
+        this.day1Num = day1Num;
+    }
+
+    public Long getDay2Num() {
+        return day2Num;
+    }
+
+    public void setDay2Num(Long day2Num) {
+        this.day2Num = day2Num;
+    }
+
+    public Long getDay3Num() {
+        return day3Num;
+    }
+
+    public void setDay3Num(Long day3Num) {
+        this.day3Num = day3Num;
+    }
+
+    public Long getDay4Num() {
+        return day4Num;
+    }
+
+    public void setDay4Num(Long day4Num) {
+        this.day4Num = day4Num;
+    }
+
+    public Long getDay5Num() {
+        return day5Num;
+    }
+
+    public void setDay5Num(Long day5Num) {
+        this.day5Num = day5Num;
+    }
+
+    public Long getDay6Num() {
+        return day6Num;
+    }
+
+    public void setDay6Num(Long day6Num) {
+        this.day6Num = day6Num;
+    }
+
+    public Long getDay7Num() {
+        return day7Num;
+    }
+
+    public void setDay7Num(Long day7Num) {
+        this.day7Num = day7Num;
+    }
+}

+ 24 - 0
sql/dataBase.sql

@@ -152,3 +152,27 @@ INSERT INTO `t_subscribe_scene` VALUES (6, 'ADD_SCENE_PROFILE_ITEM', '图文页
 INSERT INTO `t_subscribe_scene` VALUES (7, 'ADD_SCENE_PAID', '支付后关注');
 INSERT INTO `t_subscribe_scene` VALUES (8, 'ADD_SCENE_WECHAT_ADVERTISEMENT', '微信广告');
 INSERT INTO `t_subscribe_scene` VALUES (9, 'ADD_SCENE_OTHERS', '其他');
+
+
+
+-- ----------------------------
+-- Table structure for t_article_stat 图文阅读统计
+-- ----------------------------
+DROP TABLE IF EXISTS `t_article_stat`;
+CREATE TABLE `t_article_stat`  (
+  `id` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT 'id',
+  `account_id` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '公众号id',
+  `stat_date` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '数据日期',
+  `msg_id` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '微信返回msg_id',
+  `title` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '标题',
+  `int_page_read_user` int(0) NULL DEFAULT NULL COMMENT '图文页(点击群发图文卡片进入的页面)的阅读人数',
+  `int_page_read_count` int(0) NULL DEFAULT NULL COMMENT '图文页的阅读次数',
+  `ori_page_read_user` int(0) NULL DEFAULT NULL COMMENT '原文页(点击图文页“阅读原文”进入的页面)的阅读人数,无原文页时此处数据为0',
+  `ori_page_read_count` int(0) NULL DEFAULT NULL COMMENT '原文页的阅读次数',
+  `share_user` int(0) NULL DEFAULT NULL COMMENT '分享的人数',
+  `share_count` int(0) NULL DEFAULT NULL COMMENT '分享的次数',
+  `add_to_fav_user` int(0) NULL DEFAULT NULL COMMENT '收藏的人数',
+  `add_to_fav_count` int(0) NULL DEFAULT NULL COMMENT '收藏的次数',
+  `create_time` datetime(0) NULL DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '图文阅读统计' ROW_FORMAT = Dynamic;