Parcourir la source

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

wangxiao il y a 4 ans
Parent
commit
f59c3d1fd5

+ 2 - 0
operation-backend/src/main/java/com/idiot/operationbackend/OperationBackendApplication.java

@@ -4,12 +4,14 @@ import org.mybatis.spring.annotation.MapperScan;
 import org.mybatis.spring.annotation.MapperScans;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableScheduling;
 
 /**
  * 微信公众号运营平台
  * @author wangxiao
  * @date 2020-09-09
  */
+@EnableScheduling
 @SpringBootApplication
 @MapperScans(value = {@MapperScan("com.idiot.operationbackend.mappers")})
 public class OperationBackendApplication {

+ 27 - 15
operation-backend/src/main/java/com/idiot/operationbackend/controller/IndexController.java

@@ -7,6 +7,7 @@ import com.idiot.operationbackend.service.facade.AccountService;
 import com.idiot.operationbackend.support.Constants;
 import com.idiot.operationbackend.support.JsonResult;
 import com.idiot.operationbackend.util.JwtTokenUtil;
+import com.idiot.operationbackend.vo.StatData;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.slf4j.Logger;
@@ -14,10 +15,7 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 
 import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestHeader;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 import java.math.BigDecimal;
 import java.time.LocalDate;
@@ -25,6 +23,8 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.stream.Collectors;
 
+import static com.idiot.operationbackend.support.Constants.calcRate;
+
 /**
  * 运营星 首页
  * @author wang xiao
@@ -52,19 +52,20 @@ public class IndexController {
         logger.info("用户:{}查询首页数据统计概览---start",userId);
         List<Account> accounts = accountService.queryAccountByUserId(userId);
         List<String> accountIds =  accounts.stream().map(Account::getId).collect(Collectors.toList());
-
+        // 查询数据  不知道怎么优化
         String yesterdayStr = Constants.DATE_FORMATTER.format(LocalDate.now().plusDays(-1));
         List<AccountFansStat> ydStatData = fansStatService.queryByDateAndAccIds(accountIds,yesterdayStr);
         String beforeYesterdayStr = Constants.DATE_FORMATTER.format(LocalDate.now().plusDays(-2));
         List<AccountFansStat> beforeYdStat = fansStatService.queryByDateAndAccIds(accountIds,beforeYesterdayStr);
 
         logger.info("用户:{}首页概览数据计算中---ing",userId);
+        // 所有公众号昨日数据
         int totalNum = ydStatData.stream().mapToInt(AccountFansStat::getTotalFansNum).sum();
         int addNum = ydStatData.stream().mapToInt(AccountFansStat::getAddNum).sum();
         int cancelNum = ydStatData.stream().mapToInt(AccountFansStat::getCancelNum).sum();
         int newNum = ydStatData.stream().mapToInt(AccountFansStat::getNewNum).sum();
         int inactiveNum = ydStatData.stream().mapToInt(AccountFansStat::getInactiveNum).sum();
-
+        // 所有公众号前日数据
         int bfCancelNum = beforeYdStat.stream().mapToInt(AccountFansStat::getCancelNum).sum();
         int bfAddNum = beforeYdStat.stream().mapToInt(AccountFansStat::getAddNum).sum();
         int bfNewNum = beforeYdStat.stream().mapToInt(AccountFansStat::getNewNum).sum();
@@ -86,16 +87,27 @@ public class IndexController {
         return ResponseEntity.ok(JsonResult.success(result));
     }
 
+    @GetMapping("/single/{accountId}")
+    @ApiOperation(value = "查询单个公众号昨日统计数据概览")
+    public ResponseEntity<JsonResult<AccountFansStat>> getSingleFansStat (@RequestHeader String token,
+                                                                          @PathVariable String accountId) {
+        String userId = JwtTokenUtil.getUserId(token);
+        logger.info("用户:{}查询首页单个公众号:{}数据统计概览---start",userId,accountId);
+        String yesterdayStr = Constants.DATE_FORMATTER.format(LocalDate.now().plusDays(-1));
+        AccountFansStat fansStat = fansStatService.queryByDateAndAccountId(accountId,yesterdayStr);
+        logger.info("用户:{}查询首页单个公众号:{}数据统计概览---end",userId,accountId);
+        return ResponseEntity.ok(JsonResult.success(fansStat));
+    }
 
 
-
-    private BigDecimal calcRate(int now, int before) {
-        if (0 == before) {
-           return BigDecimal.valueOf((now*100.0)/1.0);
-        } else if (0 == now) {
-            return Constants.ZERO_RATE;
-        }else {
-            return BigDecimal.valueOf(((now - before) * 100) / before).setScale(2);
-        }
+    @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) {
+        return null;
     }
+
 }

+ 48 - 0
operation-backend/src/main/java/com/idiot/operationbackend/handler/ScheduledHandler.java

@@ -0,0 +1,48 @@
+package com.idiot.operationbackend.handler;
+
+
+import com.idiot.operationbackend.entity.Account;
+import com.idiot.operationbackend.service.facade.AccountFansStatService;
+import com.idiot.operationbackend.service.facade.AccountService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * @author wang xiao
+ * @date Created in 17:31 2020/9/15
+ */
+@Component
+public class ScheduledHandler {
+
+
+    @Autowired
+    private AccountFansStatService fansStatService;
+
+
+    @Autowired
+    private AccountService accountService;
+
+    private final Logger logger = LoggerFactory.getLogger(ScheduledHandler.class);
+
+    @Scheduled(cron = "0 0 1 * * ?")
+    public void  scheduled () {
+        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());
+            fansStatService.statAccountFansData(account.getId());
+        }
+        logger.info("开始同步微信用户分析数据----->end,时间:{}", LocalDateTime.now().toString());
+    }
+
+}

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

@@ -31,4 +31,15 @@ public interface AccountFansStatService extends IService<AccountFansStat> {
      * @return com.idiot.operationbackend.entity.AccountFansStat
      */
     AccountFansStat queryByDateAndAccountId(String accountId,String statDate);
+
+
+
+    /**
+     *  统计粉丝数据
+     * @author wangxiao
+     * @date 17:19 2020/9/15
+     * @param accountId
+     * @return void
+     */
+    void  statAccountFansData (String accountId);
 }

+ 8 - 0
operation-backend/src/main/java/com/idiot/operationbackend/service/facade/AccountService.java

@@ -51,4 +51,12 @@ public interface AccountService extends IService<Account> {
      * @return java.util.List<com.idiot.operationbackend.entity.Account>
      */
     List<Account> queryAccountBuSubUserIds(List<String> userIds);
+
+    /**
+     *  查询所有已经认证成功的公众号
+     * @author wangxiao
+     * @date 17:43 2020/9/15
+     * @return java.util.List<com.idiot.operationbackend.entity.Account>
+     */
+    List<Account> queryAccount();
 }

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

@@ -29,16 +29,7 @@ public interface WeChatService {
     String notice(Map<String,String> param);
 
 
-  /**
-   * 不支持的消息
-   * @author wangxiao
-   * @date 15:27 2020/7/1
-   * @param param
-   * @return java.lang.String
-   */
-  default String unSupportedMessage(Map<String,String> param) {
-    return Constants.SUCCESS;
-  }
+
 
 
 
@@ -204,6 +195,40 @@ public interface WeChatService {
   boolean confirmAccount(String accountId,String userId);
 
 
+  /**
+   *  获取微信用户增减数据
+   * @author wangxiao
+   * @date 17:57 2020/9/15
+   * @param accountId
+   * @param endDate  结束日期
+   * @param startDate  开始日期
+   * @return java.lang.String
+   */
+  String getFansSunmmary(String accountId,String startDate,String endDate);
+
+
+  /**
+   *  查询汇总数据
+   * @author wangxiao
+   * @date 20:20 2020/9/15
+   * @param accountId
+   * @param startDate
+   * @param endDate
+   * @return java.lang.String
+   */
+  String getFansCumulate(String accountId,String startDate,String endDate);
+
+
+  /**
+   * 不支持的消息
+   * @author wangxiao
+   * @date 15:27 2020/7/1
+   * @param param
+   * @return java.lang.String
+   */
+  default String unSupportedMessage(Map<String,String> param) {
+    return Constants.SUCCESS;
+  }
 
 
 

+ 47 - 0
operation-backend/src/main/java/com/idiot/operationbackend/service/impl/AccountFansStatServiceImpl.java

@@ -1,12 +1,20 @@
 package com.idiot.operationbackend.service.impl;
 
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 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.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.util.List;
 
 /**
@@ -19,6 +27,11 @@ public class AccountFansStatServiceImpl extends ServiceImpl<AccountFansStatMappe
         implements AccountFansStatService {
 
 
+
+    @Autowired
+    private WeChatService weChatService;
+
+
     @Override
     public List<AccountFansStat> queryByDateAndAccIds(List<String> accountIds, String statDate) {
         return list(Wrappers.<AccountFansStat>lambdaQuery().eq(AccountFansStat::getStatDate,statDate)
@@ -32,4 +45,38 @@ public class AccountFansStatServiceImpl extends ServiceImpl<AccountFansStatMappe
                 .eq(AccountFansStat::getAccountId,accountId)
                 .eq(AccountFansStat::getStatDate,statDate));
     }
+
+
+    @Override
+    @Async("asyncExecutor")
+    public void statAccountFansData(String accountId) {
+        String yesterday = Constants.DATE_FORMATTER.format(LocalDate.now().plusDays(-1));
+        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;
+        JSONObject tempObject = null;
+        // 昨日增减
+        for (int i = 0; i < size; i++) {
+            tempObject = jsonArray.getJSONObject(i);
+            newNum += tempObject.getInteger("new_user");
+            cancelNum += tempObject.getInteger("cancel_user");
+        }
+        int totalNum = 0;
+        // 昨日汇总
+        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");
+        }
+
+
+        
+    }
+
 }

+ 5 - 0
operation-backend/src/main/java/com/idiot/operationbackend/service/impl/AccountServiceImpl.java

@@ -54,4 +54,9 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account>
     public List<Account> queryAccountBuSubUserIds(List<String> userIds) {
         return list(Wrappers.<Account>lambdaQuery().in(Account::getCreateUserId,userIds));
     }
+
+    @Override
+    public List<Account> queryAccount() {
+        return list(Wrappers.<Account>lambdaQuery().eq(Account::getState,"1"));
+    }
 }

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

@@ -409,4 +409,43 @@ public class WeChatServiceImpl implements WeChatService, InitializingBean {
     public boolean confirmAccount(String accountId, String userId) {
         return accountService.updateUserIdByAccount(accountId,userId);
     }
+
+    @Override
+    public String getFansSunmmary(String accountId,String startDate,String endDate) {
+        String requestUrl = "https://api.weixin.qq.com/datacube/getusersummary?access_token=%s";
+        String accessToken = getAuthorizerAccessToken(accountId);
+        requestUrl = String.format(requestUrl,accessToken);
+        logger.info("获取微信用户增减数据,accountId:{}----start,时间:{}",accountId, LocalDateTime.now().toString());
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        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;
+    }
+
+
+    @Override
+    public String getFansCumulate(String accountId, String startDate, String endDate) {
+        String requestUrl = "https://api.weixin.qq.com/datacube/getusercumulate?access_token=%s";
+        String accessToken = getAuthorizerAccessToken(accountId);
+        requestUrl = String.format(requestUrl,accessToken);
+        logger.info("获取微信用户汇总数据,accountId:{}----start,时间:{}",accountId, LocalDateTime.now().toString());
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        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 null;
+    }
 }

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

@@ -43,4 +43,15 @@ public class Constants {
 
 
     public static final BigDecimal ZERO_RATE = BigDecimal.valueOf(0.00);
+
+
+    public static BigDecimal calcRate(int now, int before) {
+        if (0 == before) {
+            return BigDecimal.valueOf((now*100.0)/1.0);
+        } else if (0 == now) {
+            return Constants.ZERO_RATE;
+        }else {
+            return BigDecimal.valueOf(((now - before) * 100) / before).setScale(2);
+        }
+    }
 }

+ 73 - 0
operation-backend/src/main/java/com/idiot/operationbackend/vo/StatData.java

@@ -0,0 +1,73 @@
+package com.idiot.operationbackend.vo;
+
+import java.math.BigDecimal;
+
+/**
+ * 粉丝 数据统计
+ * @author wang xiao
+ * @date Created in 17:01 2020/9/15
+ */
+public class StatData {
+
+    private String dateLabel;
+
+    private Integer newNum;
+
+    private Integer cancelNum;
+
+    private BigDecimal cancelRate;
+
+    private Integer totalNum;
+
+
+    public String getDateLabel() {
+        return dateLabel;
+    }
+
+    public void setDateLabel(String dateLabel) {
+        this.dateLabel = dateLabel;
+    }
+
+    public Integer getNewNum() {
+        return newNum;
+    }
+
+    public void setNewNum(Integer newNum) {
+        this.newNum = newNum;
+    }
+
+    public Integer getCancelNum() {
+        return cancelNum;
+    }
+
+    public void setCancelNum(Integer cancelNum) {
+        this.cancelNum = cancelNum;
+    }
+
+    public BigDecimal getCancelRate() {
+        return cancelRate;
+    }
+
+    public void setCancelRate(BigDecimal cancelRate) {
+        this.cancelRate = cancelRate;
+    }
+
+    public Integer getTotalNum() {
+        return totalNum;
+    }
+
+    public void setTotalNum(Integer totalNum) {
+        this.totalNum = totalNum;
+    }
+
+    @Override
+    public String toString() {
+        return "StatData{" +
+                "dateLabel='" + dateLabel + '\'' +
+                ", newNum=" + newNum +
+                ", cancelNum=" + cancelNum +
+                ", cancelRate=" + cancelRate +
+                ", totalNum=" + totalNum +
+                '}';
+    }
+}