Bladeren bron

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

wangxiao 4 jaren geleden
bovenliggende
commit
586a7e50cc

+ 136 - 8
operation-backend/src/main/java/com/idiot/operationbackend/controller/IndexController.java

@@ -2,9 +2,13 @@ package com.idiot.operationbackend.controller;
 
 import com.idiot.operationbackend.entity.Account;
 import com.idiot.operationbackend.entity.AccountFansStat;
+import com.idiot.operationbackend.entity.FansActionStat;
+import com.idiot.operationbackend.service.facade.AccountFansService;
 import com.idiot.operationbackend.service.facade.AccountFansStatService;
 import com.idiot.operationbackend.service.facade.AccountService;
+import com.idiot.operationbackend.service.facade.FansActionStatService;
 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.StatData;
@@ -15,12 +19,15 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 
 import org.springframework.http.ResponseEntity;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
 import org.springframework.web.bind.annotation.*;
 
-import java.math.BigDecimal;
+import java.time.Instant;
 import java.time.LocalDate;
-import java.util.ArrayList;
-import java.util.List;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.*;
 import java.util.stream.Collectors;
 
 import static com.idiot.operationbackend.support.Constants.calcRate;
@@ -38,12 +45,28 @@ public class IndexController {
 
     private final Logger logger = LoggerFactory.getLogger(IndexController.class);
 
+    private final String HOUR = "H";
+
+    private final String WEEK = "W";
+
+    private final String DAY = "D";
+
+    private final String MONTH = "M";
+
     @Autowired
     private AccountService accountService;
 
     @Autowired
     private AccountFansStatService fansStatService;
 
+    @Autowired
+    private AccountFansService fansService;
+
+    @Autowired
+    private FansActionStatService actionStatService;
+
+
+
 
     @GetMapping("/summary")
     @ApiOperation(value = "查询公众号昨日统计数据概览")
@@ -102,13 +125,118 @@ public class IndexController {
 
     @GetMapping("/fansGrowth/{accountId}")
     @ApiOperation(value = "查询单个公众号--粉丝增长")
-    public ResponseEntity<JsonResult<List<StatData>>> getFansGrowthStat (@PathVariable String accountId,
-                                                                         @RequestHeader String token,
-                                                                         @RequestParam String type,
-                                                                         @RequestParam(required = false) String startDate,
-                                                                         @RequestParam(required = false) String endDate) {
+    public ResponseEntity<JsonResult<Map<String,Object>>> getFansGrowthStat (@PathVariable String accountId,
+                                                              @RequestHeader String token,
+                                                              @RequestParam String type,
+                                                              @RequestParam(required = false) String startDate,
+                                                              @RequestParam(required = false) String endDate) {
+        String userId = JwtTokenUtil.getUserId(token);
+        Map<String,Object> result = new HashMap<>(2);
+        logger.info("用户:{}查询首页单个公众号:{}粉丝增长---start",userId,accountId);
+        List<StatData> statData = queryFansGrowthStatData(accountId, type, startDate, endDate);
+        result.put("tableData",statData);
+        logger.info("用户:{}查询首页单个公众号:{}粉丝增长---end",userId,accountId);
+        return ResponseEntity.ok(JsonResult.success(result));
+    }
 
+    /**
+     *  统计粉丝数据  好难受写不出完美的代码
+     * @author wangxiao
+     * @date 16:00 2020/9/16 
+     * @param accountId
+     * @param type
+     * @param startDate
+     * @param endDate
+     * @return java.util.List<com.idiot.operationbackend.vo.StatData>
+     */
+    private List<StatData> queryFansGrowthStatData(String accountId, String type, String startDate, String endDate) {
+
+        int totalNum  = fansService.countFansByAccountId(accountId);
+        if (HOUR.equals(type)) {
+            // 小时数据 需要在粉丝 动作中统计
+            if (!checkDate(startDate,endDate)){
+                throw new CustomException(500,"请选择开始和结束时间");
+            }
+
+            long start =  LocalDate.parse(startDate).atTime(LocalTime.of(0,0,0))
+                    .toInstant(Constants.DEFAULT_ZONE).getEpochSecond();
+            long end = LocalDate.parse(endDate).atTime(LocalTime.of(23,59,59))
+                    .toInstant(Constants.DEFAULT_ZONE).getEpochSecond();
+            // 查询时间段内的值 
+            List<FansActionStat> fansActionStats = actionStatService.queryFansActionStat(accountId,start,end);
+            if (CollectionUtils.isEmpty(fansActionStats)) {
+                throw new CustomException(500,"暂无数据");
+            }
+            List<StatData> statDataList = new ArrayList<>();
+            StatData statData =  null;
+            List<FansActionStat> tempStatList = null;
+            while (start<=end){
+                long finalStart = start;
+                // 过滤两小时内
+                tempStatList = fansActionStats.stream()
+                        .filter(e->e.getCreateTime() >= finalStart && e.getCreateTime()<=  finalStart +7200)
+                        .sorted(Comparator.comparingLong(FansActionStat::getCreateTime))
+                        .collect(Collectors.toList());
+                statData = countStatData(tempStatList,finalStart,finalStart+7200);
+                statDataList.add(statData);
+                start += 7200;
+            }
+            return statDataList;
+        }
         return null;
+    
+    }
+
+    private boolean checkDate (String start, String end) {
+        return !(StringUtils.isEmpty(start) | StringUtils.isEmpty(end));
     }
 
+    /**
+     *  
+     * @author wangxiao
+     * @date 16:03 2020/9/16 
+     * @param fansActionStats
+     * @param start
+     * @param end
+     * @return com.idiot.operationbackend.vo.StatData
+     */
+    private StatData countStatData (List<FansActionStat> fansActionStats,long start,long end) {
+
+        LocalDateTime startTime =LocalDateTime.ofInstant(Instant.ofEpochSecond(start),Constants.DEFAULT_ZONE);
+        LocalDateTime endTime =LocalDateTime.ofInstant(Instant.ofEpochSecond(end),Constants.DEFAULT_ZONE);
+        StatData statData = new StatData();
+        int newNum = 0;
+        int cancelNum = 0;
+        int inactiveNum = 0;
+        if (!CollectionUtils.isEmpty(fansActionStats)) {
+            int size = fansActionStats.size();
+            FansActionStat temp = null;
+            for (int i = 0; i < size; i++) {
+                temp = fansActionStats.get(i);
+                switch (temp.getAction()){
+                    case Constants.NEW:
+                        newNum += 1;
+                        break;
+                    case Constants.CANCEL:
+                        cancelNum += 1;
+                        break;
+                    default:
+                        inactiveNum += 1;
+                        break;
+                }
+            }
+        }
+        String label = String.format("%s %s:%s-%s:%s",
+                startTime.toLocalDate(),startTime.getHour(),"00",endTime.getHour(),"00");
+        statData.setDateLabel(label);
+        statData.setAddNum(newNum-cancelNum);
+        statData.setCancelNum(cancelNum);
+        statData.setNewNum(newNum);
+        statData.setInactiveNum(inactiveNum);
+        return statData;
+    }
+
+
+
+
 }

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

@@ -19,4 +19,14 @@ public interface AccountFansService extends IService<AccountFans> {
      * @return com.idiot.operationbackend.entity.AccountFans
      */
     AccountFans queryByAccountIdAndOpenId (String accountId,String openId);
+
+
+    /**
+     *  统计粉丝总数目
+     * @author wangxiao
+     * @date 14:26 2020/9/16
+     * @param accountId
+     * @return int
+     */
+    int countFansByAccountId(String accountId);
 }

+ 30 - 2
operation-backend/src/main/java/com/idiot/operationbackend/service/facade/FansActionStatService.java

@@ -3,6 +3,7 @@ package com.idiot.operationbackend.service.facade;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.idiot.operationbackend.entity.FansActionStat;
 
+import java.util.List;
 
 
 /**
@@ -12,13 +13,40 @@ import com.idiot.operationbackend.entity.FansActionStat;
 public interface FansActionStatService extends IService<FansActionStat> {
 
     /**
-     *  统计区间内 粉丝活跃数量 (秒级时间戳)
+     * 统计区间内 粉丝活跃数量 (秒级时间戳)
+     *
+     * @param accountId
+     * @param startDate
+     * @param endDate
+     * @return int
      * @author wangxiao
      * @date 11:39 2020/9/16
+     */
+    int countInactiveFansNum(String accountId, long startDate, long endDate);
+
+
+    /**
+     * 查询区间内 粉丝活跃数量 (秒级时间戳)
+     *
      * @param accountId
      * @param startDate
      * @param endDate
      * @return int
+     * @author wangxiao
+     * @date 11:39 2020/9/16
+     */
+    List<FansActionStat> queryFansActionStat(String accountId, String startDate, String endDate);
+
+
+    /**
+     * 查询区间内 粉丝活跃数量 (秒级时间戳)
+     *
+     * @param accountId
+     * @param start
+     * @param end
+     * @return int
+     * @author wangxiao
+     * @date 11:39 2020/9/16
      */
-    int countInactiveFansNum( String accountId, long startDate, long endDate );
+    List<FansActionStat> queryFansActionStat(String accountId, long start, long end);
 }

+ 6 - 0
operation-backend/src/main/java/com/idiot/operationbackend/service/impl/AccountFansServiceImpl.java

@@ -21,4 +21,10 @@ public class AccountFansServiceImpl extends ServiceImpl<AccountFansMapper, Accou
         return getOne(Wrappers.<AccountFans>lambdaQuery().eq(AccountFans::getAccountId,accountId)
                 .eq(AccountFans::getOpenId,openId),false);
     }
+
+
+    @Override
+    public int countFansByAccountId(String accountId) {
+        return count(Wrappers.<AccountFans>lambdaQuery().eq(AccountFans::getAccountId,accountId));
+    }
 }

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

@@ -16,7 +16,6 @@ import org.springframework.stereotype.Service;
 
 import java.time.LocalDate;
 import java.time.LocalTime;
-import java.time.ZoneOffset;
 import java.util.List;
 
 /**
@@ -77,11 +76,8 @@ public class AccountFansStatServiceImpl extends ServiceImpl<AccountFansStatMappe
         String jsonStrTotal = weChatService.getFansCumulate(accountId,yesterday,yesterday);
         JSONObject jsonObjectTotal = JSONObject.parseObject(jsonStrTotal);
         JSONArray jsonArrayTotal = jsonObjectTotal.getJSONArray("list");
-        int sizeTotal  = jsonArrayTotal.size();
-        for (int i = 0; i < sizeTotal; i++) {
-            tempObject = jsonArray.getJSONObject(i);
-            totalNum += tempObject.getInteger("cumulate_user");
-        }
+        totalNum = jsonArrayTotal.getJSONObject(0).getInteger("cumulate_user");
+
         // 昨日和前日 数据
         List<AccountFansStat> statData = baseMapper.selectByDateAndAccId(accountId,yesterday,beforeDay);
         // 昨日活跃数量

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

@@ -5,8 +5,13 @@ 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 com.idiot.operationbackend.support.Constants;
 import org.springframework.stereotype.Service;
 
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.util.List;
+
 /**
  * @author wang xiao
  * @date Created in 11:33 2020/9/16
@@ -18,7 +23,30 @@ public class FansActionStatServiceImpl extends ServiceImpl<FansActionStatMapper,
     @Override
     public int countInactiveFansNum(String accountId, long startDate, long endDate) {
         return count(Wrappers.<FansActionStat>lambdaQuery().eq(FansActionStat::getAccountId,accountId)
+                .ne(FansActionStat::getAction,"3")
                 .ge(FansActionStat::getCreateTime,startDate)
                 .le(FansActionStat::getCreateTime,endDate));
     }
+
+
+    @Override
+    public List<FansActionStat> queryFansActionStat(String accountId, String startDate, String endDate) {
+        LocalDate var1 =LocalDate.parse(startDate, Constants.DATE_FORMATTER);
+        LocalDate var2 =LocalDate.parse(endDate, Constants.DATE_FORMATTER);
+        long start =  var1.atTime(LocalTime.of(0,0,0)).toInstant(Constants.DEFAULT_ZONE).getEpochSecond();
+        long end = var2.atTime(LocalTime.of(23,59,59)).toInstant(Constants.DEFAULT_ZONE).getEpochSecond();
+        return list(Wrappers.<FansActionStat>lambdaQuery().eq(FansActionStat::getAccountId,accountId)
+                .ge(FansActionStat::getCreateTime,start)
+                .le(FansActionStat::getCreateTime,end)
+                .orderByAsc(FansActionStat::getCreateTime));
+    }
+
+
+    @Override
+    public List<FansActionStat> queryFansActionStat(String accountId, long start, long end) {
+          return list(Wrappers.<FansActionStat>lambdaQuery().eq(FansActionStat::getAccountId,accountId)
+                .ge(FansActionStat::getCreateTime,start)
+                .le(FansActionStat::getCreateTime,end)
+                .orderByAsc(FansActionStat::getCreateTime));
+    }
 }

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

@@ -21,6 +21,8 @@ public class Constants {
 
     public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss",DEFAULT_LOCALE);
 
+    public static final DateTimeFormatter DATE_TIME_FORMATTER1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH",DEFAULT_LOCALE);
+
     public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd",DEFAULT_LOCALE);
 
     public static final String DEFAULT_HEAD_IMG = "http://pic.51yuansu.com/pic3/cover/01/69/80/595f67c2aff1e_610.jpg";
@@ -48,6 +50,21 @@ public class Constants {
 
     public static final BigDecimal ZERO_RATE = BigDecimal.valueOf(0.00);
 
+    /**
+     * 粉丝动作 0-粉丝消息,1-新关注,2-关注,3-取关,4-扫描二维码,5-菜单点击
+     */
+    public static final int NEW = 1;
+
+    public static final int MSG = 0;
+
+    public static final int SUBSCRIBE = 2;
+
+    public static final int CANCEL = 3;
+
+    public static final int SCAN = 4;
+
+    public static final int MENU = 5;
+
 
     public static BigDecimal calcRate(int now, int before) {
         if (0 == before) {

+ 11 - 20
operation-backend/src/main/java/com/idiot/operationbackend/vo/StatData.java

@@ -15,9 +15,10 @@ public class StatData {
 
     private Integer cancelNum;
 
-    private BigDecimal cancelRate;
+    private Integer addNum;
+
+    private Integer inactiveNum;
 
-    private Integer totalNum;
 
 
     public String getDateLabel() {
@@ -44,30 +45,20 @@ public class StatData {
         this.cancelNum = cancelNum;
     }
 
-    public BigDecimal getCancelRate() {
-        return cancelRate;
-    }
 
-    public void setCancelRate(BigDecimal cancelRate) {
-        this.cancelRate = cancelRate;
+    public Integer getAddNum() {
+        return addNum;
     }
 
-    public Integer getTotalNum() {
-        return totalNum;
+    public void setAddNum(Integer addNum) {
+        this.addNum = addNum;
     }
 
-    public void setTotalNum(Integer totalNum) {
-        this.totalNum = totalNum;
+    public Integer getInactiveNum() {
+        return inactiveNum;
     }
 
-    @Override
-    public String toString() {
-        return "StatData{" +
-                "dateLabel='" + dateLabel + '\'' +
-                ", newNum=" + newNum +
-                ", cancelNum=" + cancelNum +
-                ", cancelRate=" + cancelRate +
-                ", totalNum=" + totalNum +
-                '}';
+    public void setInactiveNum(Integer inactiveNum) {
+        this.inactiveNum = inactiveNum;
     }
 }