Explorar o código

add(backend) [粉丝统计 计算 2.0]

wangxiao %!s(int64=4) %!d(string=hai) anos
pai
achega
b6cb83ded7

+ 1 - 0
operation-backend/src/main/java/com/idiot/operationbackend/controller/IndexController.java

@@ -107,6 +107,7 @@ public class IndexController {
                                                                          @RequestParam String type,
                                                                          @RequestParam(required = false) String startDate,
                                                                          @RequestParam(required = false) String endDate) {
+
         return null;
     }
 

+ 64 - 0
operation-backend/src/main/java/com/idiot/operationbackend/entity/FansActionStat.java

@@ -0,0 +1,64 @@
+package com.idiot.operationbackend.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+/**
+ * 粉丝动作统计
+ * @author wang xiao
+ * @date Created in 11:17 2020/9/16
+ */
+@TableName("t_fans_action_stat")
+public class FansActionStat {
+
+    @TableId
+    private String id;
+
+    private String accountId;
+
+    private String openId;
+
+    private Integer action;
+
+    private Long 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 getOpenId() {
+        return openId;
+    }
+
+    public void setOpenId(String openId) {
+        this.openId = openId;
+    }
+
+    public Integer getAction() {
+        return action;
+    }
+
+    public void setAction(Integer action) {
+        this.action = action;
+    }
+
+    public Long getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Long createTime) {
+        this.createTime = createTime;
+    }
+}

+ 61 - 0
operation-backend/src/main/java/com/idiot/operationbackend/mappers/AccountFansStatMapper.java

@@ -2,10 +2,71 @@ package com.idiot.operationbackend.mappers;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.idiot.operationbackend.entity.AccountFansStat;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Result;
+import org.apache.ibatis.annotations.Results;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
 
 /**
  * @author wang xiao
  * @date Created in 14:52 2020/9/15
  */
 public interface AccountFansStatMapper extends BaseMapper<AccountFansStat> {
+
+    /**
+     *  查询 两个日期的统计数据
+     * @author wangxiao
+     * @date 10:33 2020/9/16
+     * @param accountId
+     * @param stateDate
+     * @param beforeDate
+     * @return java.util.List<com.idiot.operationbackend.entity.AccountFansStat>
+     */
+    @Select("SELECT " +
+            " t.id, " +
+            " t.account_id, " +
+            " t.stat_date, " +
+            " t.new_num, " +
+            " t.cancel_num, " +
+            " t.inactive_num, " +
+            " t.total_fans_num, " +
+            " t.add_num  " +
+            "FROM " +
+            " t_account_fans_stat t  " +
+            "WHERE " +
+            " t.account_id =  #{accountId}  " +
+            " AND t.stat_date = #{stateDate} " +
+            " UNION " +
+            "SELECT " +
+            " t.id, " +
+            " t.account_id, " +
+            " t.stat_date, " +
+            " t.new_num, " +
+            " t.cancel_num, " +
+            " t.inactive_num, " +
+            " t.total_fans_num, " +
+            " t.add_num  " +
+            "FROM " +
+            " t_account_fans_stat t  " +
+            "WHERE " +
+            " t.account_id = #{accountId}  " +
+            " AND t.stat_date = #{beforeDate} ")
+    @Results(id = "AccountFansStatMap",value = {
+            @Result(column = "id",id = true,property = "id"),
+            @Result(column = "account_id",property = "accountId"),
+            @Result(column = "new_num",property = "newNum"),
+            @Result(column = "cancel_num",property = "cancelNum"),
+            @Result(column = "inactive_num",property = "inactiveNum"),
+            @Result(column = "total_fans_num",property = "totalFansNum"),
+            @Result(column = "add_num",property = "addNum"),
+            @Result(column = "stat_date",property = "statDate"),
+    })
+    List<AccountFansStat> selectByDateAndAccId(@Param("accountId") String accountId, @Param("stateDate") String stateDate,
+                                               @Param("beforeDate")  String beforeDate);
+
+
+
+
 }

+ 13 - 0
operation-backend/src/main/java/com/idiot/operationbackend/mappers/FansActionStatMapper.java

@@ -0,0 +1,13 @@
+package com.idiot.operationbackend.mappers;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.idiot.operationbackend.entity.FansActionStat;
+
+
+/**
+ * @author wang xiao
+ * @date Created in 11:32 2020/9/16
+ */
+public interface FansActionStatMapper extends BaseMapper<FansActionStat> {
+
+}

+ 11 - 0
operation-backend/src/main/java/com/idiot/operationbackend/service/facade/AccountFansStatService.java

@@ -42,4 +42,15 @@ public interface AccountFansStatService extends IService<AccountFansStat> {
      * @return void
      */
     void  statAccountFansData (String accountId);
+
+
+    /**
+     * 昨日活跃数量
+     * @author wangxiao
+     * @date 10:28 2020/9/16
+     * @param accountId
+     * @param statDate
+     * @return int
+     */
+    int inactiveFansNum (String accountId,String statDate);
 }

+ 24 - 0
operation-backend/src/main/java/com/idiot/operationbackend/service/facade/FansActionStatService.java

@@ -0,0 +1,24 @@
+package com.idiot.operationbackend.service.facade;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.idiot.operationbackend.entity.FansActionStat;
+
+
+
+/**
+ * @author wang xiao
+ * @date Created in 11:33 2020/9/16
+ */
+public interface FansActionStatService extends IService<FansActionStat> {
+
+    /**
+     *  统计区间内 粉丝活跃数量 (秒级时间戳)
+     * @author wangxiao
+     * @date 11:39 2020/9/16
+     * @param accountId
+     * @param startDate
+     * @param endDate
+     * @return int
+     */
+    int countInactiveFansNum( String accountId, long startDate, long endDate );
+}

+ 42 - 2
operation-backend/src/main/java/com/idiot/operationbackend/service/impl/AccountFansStatServiceImpl.java

@@ -7,14 +7,16 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.idiot.operationbackend.entity.AccountFansStat;
 import com.idiot.operationbackend.mappers.AccountFansStatMapper;
 import com.idiot.operationbackend.service.facade.AccountFansStatService;
+import com.idiot.operationbackend.service.facade.FansActionStatService;
 import com.idiot.operationbackend.service.facade.WeChatService;
 import com.idiot.operationbackend.support.Constants;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 
-import javax.servlet.http.Cookie;
 import java.time.LocalDate;
+import java.time.LocalTime;
+import java.time.ZoneOffset;
 import java.util.List;
 
 /**
@@ -32,6 +34,10 @@ public class AccountFansStatServiceImpl extends ServiceImpl<AccountFansStatMappe
     private WeChatService weChatService;
 
 
+    @Autowired
+    private FansActionStatService actionStatService;
+
+
     @Override
     public List<AccountFansStat> queryByDateAndAccIds(List<String> accountIds, String statDate) {
         return list(Wrappers.<AccountFansStat>lambdaQuery().eq(AccountFansStat::getStatDate,statDate)
@@ -51,12 +57,14 @@ public class AccountFansStatServiceImpl extends ServiceImpl<AccountFansStatMappe
     @Async("asyncExecutor")
     public void statAccountFansData(String accountId) {
         String yesterday = Constants.DATE_FORMATTER.format(LocalDate.now().plusDays(-1));
+        String beforeDay = Constants.DATE_FORMATTER.format(LocalDate.now().plusDays(-2));
         String jsonStr = weChatService.getFansSunmmary(accountId,yesterday,yesterday);
         JSONObject jsonObject = JSONObject.parseObject(jsonStr);
         JSONArray jsonArray = jsonObject.getJSONArray("list");
         int size  = jsonArray.size();
         int newNum = 0;
         int cancelNum = 0;
+        int addNum = 0;
         JSONObject tempObject = null;
         // 昨日增减
         for (int i = 0; i < size; i++) {
@@ -74,9 +82,41 @@ public class AccountFansStatServiceImpl extends ServiceImpl<AccountFansStatMappe
             tempObject = jsonArray.getJSONObject(i);
             totalNum += tempObject.getInteger("cumulate_user");
         }
+        // 昨日和前日 数据
+        List<AccountFansStat> statData = baseMapper.selectByDateAndAccId(accountId,yesterday,beforeDay);
+        // 昨日活跃数量
+        int inactiveNum =  inactiveFansNum(accountId,yesterday);
+        AccountFansStat ydData = statData.stream().filter(e->yesterday.equals(e.getStatDate())).findFirst().orElseGet(AccountFansStat::new);
+        addNum = newNum-cancelNum;
+        ydData.setTotalFansNum(totalNum);
+        ydData.setNewNum(newNum);
+        ydData.setCancelNum(cancelNum);
+        ydData.setStatDate(yesterday);
+        ydData.setAccountId(accountId);
+        ydData.setAddNum(addNum);
+        ydData.setInactiveNum(inactiveNum);
+
+        statData.stream().filter(e->beforeDay.equals(e.getStatDate())).findFirst().map(e->{
+            ydData.setAddRate(Constants.calcRate(ydData.getAddNum(), e.getAddNum()));
+            ydData.setNewRate(Constants.calcRate(ydData.getNewNum(), e.getNewNum()));
+            ydData.setCancelRate(Constants.calcRate(ydData.getCancelNum(), e.getCancelNum()));
+            ydData.setInactiveRate(Constants.calcRate(ydData.getInactiveNum(), e.getInactiveNum()));
+            ydData.setPageReadRate(Constants.calcRate(ydData.getPageReadNum(),e.getPageReadNum()));
+            ydData.setInactiveRate(Constants.calcRate(ydData.getInactiveNum(),e.getInactiveNum()));
+            return e;
+        });
+        saveOrUpdate(ydData);
+    }
 
 
-        
+    @Override
+    public int inactiveFansNum(String accountId, String statDate) {
+        LocalDate localDate = LocalDate.parse(statDate,Constants.DATE_FORMATTER);
+        long start =  localDate.atTime(LocalTime.of(0,0,0)).toInstant(Constants.DEFAULT_ZONE).getEpochSecond();
+        long end = localDate.atTime(LocalTime.of(23,59,59)).toInstant(Constants.DEFAULT_ZONE).getEpochSecond();
+        return actionStatService.countInactiveFansNum(accountId,start,end);
     }
 
+
+
 }

+ 24 - 0
operation-backend/src/main/java/com/idiot/operationbackend/service/impl/FansActionStatServiceImpl.java

@@ -0,0 +1,24 @@
+package com.idiot.operationbackend.service.impl;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.idiot.operationbackend.entity.FansActionStat;
+import com.idiot.operationbackend.mappers.FansActionStatMapper;
+import com.idiot.operationbackend.service.facade.FansActionStatService;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author wang xiao
+ * @date Created in 11:33 2020/9/16
+ */
+@Service
+public class FansActionStatServiceImpl extends ServiceImpl<FansActionStatMapper, FansActionStat>
+        implements FansActionStatService {
+
+    @Override
+    public int countInactiveFansNum(String accountId, long startDate, long endDate) {
+        return count(Wrappers.<FansActionStat>lambdaQuery().eq(FansActionStat::getAccountId,accountId)
+                .ge(FansActionStat::getCreateTime,startDate)
+                .le(FansActionStat::getCreateTime,endDate));
+    }
+}

+ 4 - 0
operation-backend/src/main/java/com/idiot/operationbackend/support/Constants.java

@@ -2,6 +2,8 @@ package com.idiot.operationbackend.support;
 
 import java.math.BigDecimal;
 import java.net.URLDecoder;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
 import java.time.format.DateTimeFormatter;
 import java.util.Locale;
 
@@ -15,6 +17,8 @@ public class Constants {
 
     public static final Locale DEFAULT_LOCALE = Locale.CHINA;
 
+    public static final ZoneOffset DEFAULT_ZONE= ZoneOffset.of("+8");
+
     public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss",DEFAULT_LOCALE);
 
     public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd",DEFAULT_LOCALE);

+ 12 - 0
sql/dataBase.sql

@@ -112,6 +112,18 @@ CREATE TABLE `t_account_fans_stat`  (
   PRIMARY KEY (`id`) USING BTREE
 ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '公众号粉丝统计' ROW_FORMAT = Dynamic;
 
+-- ----------------------------
+-- Table structure for 粉丝动作统计
+-- ----------------------------
+DROP TABLE IF EXISTS `t_fans_action_stat`;
+CREATE TABLE `t_fans_action_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',
+  `opend_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT 'openid',
+  `action` int(0) NULL DEFAULT NULL COMMENT '粉丝动作 0-粉丝消息,1-新关注,2-关注,3-取关,4-扫描二维码,5-菜单点击',
+  `create_time` bigint(0) NULL DEFAULT NULL COMMENT '创建时间 秒级',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '粉丝动作统计' ROW_FORMAT = Dynamic;