|
@@ -0,0 +1,231 @@
|
|
|
|
|
+package com.cyksj.task;
|
|
|
|
|
+
|
|
|
|
|
+import cn.hutool.core.collection.CollUtil;
|
|
|
|
|
+import cn.hutool.core.date.DateTime;
|
|
|
|
|
+import cn.hutool.core.date.DateUtil;
|
|
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
|
|
+import com.cyksj.common.task.GlobalThreadPoolTaskExecutor;
|
|
|
|
|
+import com.cyksj.mapper.GoodsDonMapper;
|
|
|
|
|
+import com.cyksj.mapper.manage.statistics.AppleOneDataMapper;
|
|
|
|
|
+import com.cyksj.mapper.manage.statistics.RealGoodsDataMapper;
|
|
|
|
|
+import com.cyksj.mapper.manage.statistics.StreamingAccountDataMapper;
|
|
|
|
|
+import com.cyksj.model.entity.*;
|
|
|
|
|
+import com.cyksj.service.mange.CmsAccountService;
|
|
|
|
|
+import com.cyksj.service.mange.CmsGoodsDonSkuService;
|
|
|
|
|
+import com.cyksj.service.order.OrderDonService;
|
|
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
+import org.springframework.scheduling.annotation.Scheduled;
|
|
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
|
|
+
|
|
|
|
|
+import java.math.BigDecimal;
|
|
|
|
|
+import java.util.*;
|
|
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
+
|
|
|
|
|
+/*
|
|
|
|
|
+ *项目名: netflix
|
|
|
|
|
+ *文件名: StatisticsDataScheduler
|
|
|
|
|
+ *创建者: JavaZou
|
|
|
|
|
+ *创建时间:2022/10/18 12:07
|
|
|
|
|
+ */
|
|
|
|
|
+@Component
|
|
|
|
|
+@Slf4j
|
|
|
|
|
+@RequiredArgsConstructor
|
|
|
|
|
+public class StatisticsDataScheduler {
|
|
|
|
|
+
|
|
|
|
|
+ private final OrderDonService orderDonService;
|
|
|
|
|
+
|
|
|
|
|
+ private final CmsGoodsDonSkuService goodsDonSkuService;
|
|
|
|
|
+
|
|
|
|
|
+ private final CmsAccountService accountService;
|
|
|
|
|
+
|
|
|
|
|
+ private static final GlobalThreadPoolTaskExecutor TASK_POOL = GlobalThreadPoolTaskExecutor.getInstance();
|
|
|
|
|
+
|
|
|
|
|
+ private final AppleOneDataMapper appleOneDataMapper;
|
|
|
|
|
+
|
|
|
|
|
+ private final StreamingAccountDataMapper streamingAccountDataMapper;
|
|
|
|
|
+
|
|
|
|
|
+ private final static String APPLE_ONE = "Apple One";
|
|
|
|
|
+
|
|
|
|
|
+ public static List<String> noOrderStatus = List.of("close", "noPayment");
|
|
|
|
|
+
|
|
|
|
|
+ public static List<String> payType = List.of("拼车/月", "拼车/季", "拼车/年");
|
|
|
|
|
+
|
|
|
|
|
+ private final static List<String> APPLE_ONE_AREA = List.of("美区", "马来西亚区");
|
|
|
|
|
+
|
|
|
|
|
+ private static Long DAY_MILLS = 86400000l;
|
|
|
|
|
+
|
|
|
|
|
+ private final GoodsDonMapper goodsDonMapper;
|
|
|
|
|
+
|
|
|
|
|
+ private final RealGoodsDataMapper realGoodsDataMapper;
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 后台数据统计 定时器
|
|
|
|
|
+ */
|
|
|
|
|
+ @Scheduled(cron = "0 0 1 * * ?")
|
|
|
|
|
+ public void statisticsData() {
|
|
|
|
|
+ Date thisZeroDate = DateUtil.beginOfDay(DateTime.now());
|
|
|
|
|
+ Date yesZeroDate = DateTime.of(thisZeroDate.getTime() - DAY_MILLS);
|
|
|
|
|
+ //统计AppleOne数据
|
|
|
|
|
+ TASK_POOL.execute(() -> statisticsAppleOneData(yesZeroDate, thisZeroDate));
|
|
|
|
|
+ //统计流媒体账号数据
|
|
|
|
|
+ TASK_POOL.execute(() -> statisticsStreamingAccountData(yesZeroDate, thisZeroDate));
|
|
|
|
|
+ //统计实物数据
|
|
|
|
|
+ statisticsRealGoodsData(yesZeroDate, thisZeroDate);
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 统计AppleOne数据
|
|
|
|
|
+ */
|
|
|
|
|
+ private void statisticsAppleOneData(Date yesZeroDate, Date thisZeroDate) {
|
|
|
|
|
+ //美区
|
|
|
|
|
+ String americaAre = APPLE_ONE_AREA.get(0);
|
|
|
|
|
+ //马来西亚区
|
|
|
|
|
+ String malaysiaAre = APPLE_ONE_AREA.get(1);
|
|
|
|
|
+ List<GoodsDonSku> americaSku = Optional.ofNullable(goodsDonSkuService.list(Wrappers.lambdaQuery(GoodsDonSku.class).like(GoodsDonSku::getSpecVal, americaAre).select(GoodsDonSku::getId))).orElse(new ArrayList<>());
|
|
|
|
|
+ List<GoodsDonSku> malaysiaSku = Optional.ofNullable(goodsDonSkuService.list(Wrappers.lambdaQuery(GoodsDonSku.class).like(GoodsDonSku::getSpecVal, malaysiaAre).select(GoodsDonSku::getId))).orElse(new ArrayList<>());
|
|
|
|
|
+ Map<String, List<Long>> areaDataMap = new HashMap<>();
|
|
|
|
|
+ areaDataMap.put(americaAre, americaSku.stream().map(GoodsDonSku::getId).collect(Collectors.toList()));
|
|
|
|
|
+ areaDataMap.put(malaysiaAre, malaysiaSku.stream().map(GoodsDonSku::getId).collect(Collectors.toList()));
|
|
|
|
|
+ List<AbstractBackData> appleOneSave = new ArrayList<>();
|
|
|
|
|
+ areaDataMap.forEach((areaName, skuIds) -> {
|
|
|
|
|
+ AppleOneData appleOne = new AppleOneData();
|
|
|
|
|
+ appleOne.setAreaName(areaName);
|
|
|
|
|
+ //通过skuIds找到对应的appleOne统计数据
|
|
|
|
|
+ List<OrderDon> orderDons = orderDonService.getAppleOneOrderDons(APPLE_ONE, skuIds, noOrderStatus, yesZeroDate, thisZeroDate);
|
|
|
|
|
+ appleOneDataStatistics(orderDons, appleOne, appleOneSave);
|
|
|
|
|
+ });
|
|
|
|
|
+ for (AbstractBackData appleOne : appleOneSave) {
|
|
|
|
|
+ appleOneDataMapper.insert((AppleOneData) appleOne);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void appleOneDataStatistics(List<OrderDon> orderDons, AppleOneData appleOne, List<AbstractBackData> appleOneSave) {
|
|
|
|
|
+ if (CollUtil.isNotEmpty(orderDons)) {
|
|
|
|
|
+ //用户人数
|
|
|
|
|
+ Set<Long> numOfUser = Optional.ofNullable(orderDons.stream().map(OrderDon::getUserId).collect(Collectors.toSet())).orElse(new HashSet<>());
|
|
|
|
|
+ appleOne.setNumOfUser(numOfUser.size());
|
|
|
|
|
+ //订单数
|
|
|
|
|
+ appleOne.setNumOfOrder(orderDons.size());
|
|
|
|
|
+ //金额
|
|
|
|
|
+ Optional<BigDecimal> money = orderDons.stream().map(OrderDon::getMoney).reduce(BigDecimal::add);
|
|
|
|
|
+ if (money.isPresent()) {
|
|
|
|
|
+ appleOne.setMoney(money.get());
|
|
|
|
|
+ } else appleOne.setMoney(BigDecimal.ZERO);
|
|
|
|
|
+ getNumOfOrderByPayType(orderDons, appleOne);
|
|
|
|
|
+ }
|
|
|
|
|
+ appleOneSave.add(appleOne);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 统计流媒体账号数据
|
|
|
|
|
+ */
|
|
|
|
|
+ private void statisticsStreamingAccountData(Date yesZeroDate, Date thisZeroDate) {
|
|
|
|
|
+ List<Account> accounts = accountService.getNoAppleOneAccount(APPLE_ONE);
|
|
|
|
|
+ Map<Long, List<Account>> accountMaps = accounts.stream().collect(Collectors.groupingBy(Account::getGoodsId));
|
|
|
|
|
+ List<StreamingAccountData> StreamingAccountDataSave = new ArrayList<>(accounts.size());
|
|
|
|
|
+ accountMaps.forEach((goodsId, accountList) -> {
|
|
|
|
|
+ StreamingAccountData streamingAccount = new StreamingAccountData();
|
|
|
|
|
+ streamingAccount.setAccountName(accountList.get(0).getTitle());
|
|
|
|
|
+ streamingAccount.setGoodsId(goodsId);
|
|
|
|
|
+ streamingAccountDataStatistics(accountList, streamingAccount, StreamingAccountDataSave, yesZeroDate, thisZeroDate);
|
|
|
|
|
+ });
|
|
|
|
|
+ for (StreamingAccountData streamingAccountData : StreamingAccountDataSave) {
|
|
|
|
|
+ streamingAccountDataMapper.insert(streamingAccountData);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 统计实物数据
|
|
|
|
|
+ */
|
|
|
|
|
+ private void statisticsRealGoodsData(Date yesZeroDate, Date thisZeroDate) {
|
|
|
|
|
+ List<GoodsDon> goodsDons = goodsDonMapper.selectList(Wrappers.lambdaQuery(GoodsDon.class).eq(GoodsDon::getType, 2));
|
|
|
|
|
+ List<RealGoodsData> realGoodsDataList = new ArrayList<>();
|
|
|
|
|
+ if (!goodsDons.isEmpty()) {
|
|
|
|
|
+ goodsDons.forEach(goods -> {
|
|
|
|
|
+ List<GoodsDonSku> skuList = goodsDonSkuService.list(Wrappers.lambdaQuery(GoodsDonSku.class).eq(GoodsDonSku::getGoodsId, goods.getId()));
|
|
|
|
|
+ if (!skuList.isEmpty()) {
|
|
|
|
|
+ skuList.forEach(sku -> {
|
|
|
|
|
+ RealGoodsData realGoodsData = new RealGoodsData();
|
|
|
|
|
+ realGoodsData.setGoodsId(goods.getId());
|
|
|
|
|
+ realGoodsData.setGoodsTitle(goods.getTitle());
|
|
|
|
|
+ realGoodsData.setSkuId(sku.getId());
|
|
|
|
|
+ realGoodsData.setSpecVal(sku.getSpecVal());
|
|
|
|
|
+ //用户数
|
|
|
|
|
+ List<OrderDon> orderDon = Optional.ofNullable(orderDonService.list(Wrappers.lambdaQuery(OrderDon.class).eq(OrderDon::getSkuId, sku.getId()).between(OrderDon::getCreatedTime, yesZeroDate, thisZeroDate))).orElse(new ArrayList<>());
|
|
|
|
|
+ Set<Long> userList = Optional.ofNullable(orderDon.stream().map(OrderDon::getUserId).collect(Collectors.toSet())).orElse(new HashSet<>());
|
|
|
|
|
+ realGoodsData.setNumOfUser(userList.size());
|
|
|
|
|
+ realGoodsData.setNumOfOrder(orderDon.size());
|
|
|
|
|
+ Optional<BigDecimal> money = orderDon.stream().map(OrderDon::getMoney).reduce(BigDecimal::add);
|
|
|
|
|
+ realGoodsData.setMoney(money.isPresent() ? money.get() : BigDecimal.ZERO);
|
|
|
|
|
+ realGoodsDataList.add(realGoodsData);
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!realGoodsDataList.isEmpty()) {
|
|
|
|
|
+ realGoodsDataList.forEach(data -> realGoodsDataMapper.insert(data));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * @param accounts 主账号
|
|
|
|
|
+ * @param streamingAccountData
|
|
|
|
|
+ * @param dataSave 入库实体集合
|
|
|
|
|
+ * @param yesZeroDate 昨日零时
|
|
|
|
|
+ * @param thisZeroDate 今日零时
|
|
|
|
|
+ */
|
|
|
|
|
+ private void streamingAccountDataStatistics(List<Account> accounts, StreamingAccountData streamingAccountData, List<StreamingAccountData> dataSave, Date yesZeroDate, Date thisZeroDate) {
|
|
|
|
|
+ //主账号
|
|
|
|
|
+ List<Long> accountIds = accounts.stream().map(Account::getId).collect(Collectors.toList());
|
|
|
|
|
+ if (CollUtil.isNotEmpty(accountIds)) {
|
|
|
|
|
+ List<Integer> userIds = Optional.ofNullable(accountService.getNumOfUser(accountIds, yesZeroDate, thisZeroDate)).orElse(new ArrayList<>());
|
|
|
|
|
+ //用户数
|
|
|
|
|
+ streamingAccountData.setNumOfUser(userIds.size());
|
|
|
|
|
+ List<OrderDon> orderDons = new ArrayList<>();
|
|
|
|
|
+ if (CollUtil.isNotEmpty(userIds)) {
|
|
|
|
|
+ orderDons = orderDonService.list(Wrappers.lambdaQuery(OrderDon.class).in(OrderDon::getUserId, userIds).notIn(OrderDon::getStatus, noOrderStatus).between(OrderDon::getPayTime, yesZeroDate, thisZeroDate).select(OrderDon::getId, OrderDon::getMoney, OrderDon::getSkuId));
|
|
|
|
|
+ getNumOfOrderByPayType(orderDons, streamingAccountData);
|
|
|
|
|
+ }
|
|
|
|
|
+ streamingAccountData.setNumOfOrder(orderDons.size());
|
|
|
|
|
+ Optional<BigDecimal> reduce = orderDons.stream().map(OrderDon::getMoney).reduce(BigDecimal::add);
|
|
|
|
|
+ BigDecimal totalMoney = BigDecimal.valueOf(0);
|
|
|
|
|
+ if (reduce.isPresent()) {
|
|
|
|
|
+ totalMoney = reduce.get();
|
|
|
|
|
+ }
|
|
|
|
|
+ //金额
|
|
|
|
|
+ streamingAccountData.setMoney(totalMoney);
|
|
|
|
|
+ }
|
|
|
|
|
+ dataSave.add(streamingAccountData);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 根据不同支付条件统计对应月、季、年订单
|
|
|
|
|
+ */
|
|
|
|
|
+ private void getNumOfOrderByPayType(List<OrderDon> orderDons, AbstractBackData backData) {
|
|
|
|
|
+ Integer numOfMonthOrder = 0;
|
|
|
|
|
+ Integer numOfSeasonOrder = 0;
|
|
|
|
|
+ Integer numOfYearOrder = 0;
|
|
|
|
|
+ Map<Long, List<OrderDon>> skuIdMaps = orderDons.stream().collect(Collectors.groupingBy(OrderDon::getSkuId));
|
|
|
|
|
+ if (!skuIdMaps.isEmpty()) {
|
|
|
|
|
+ List<GoodsDonSku> goodsDonSkus = Optional.ofNullable(goodsDonSkuService.list(Wrappers.lambdaQuery(GoodsDonSku.class).in(GoodsDonSku::getId, skuIdMaps.keySet()))).orElse(new ArrayList<>());
|
|
|
|
|
+ for (GoodsDonSku donSkus : goodsDonSkus) {
|
|
|
|
|
+ int size = skuIdMaps.get(donSkus.getId()).size();
|
|
|
|
|
+ if (donSkus.getSpecVal().contains(payType.get(0))) {
|
|
|
|
|
+ numOfMonthOrder += size;
|
|
|
|
|
+ } else if (donSkus.getSpecVal().contains(payType.get(1))) {
|
|
|
|
|
+ numOfSeasonOrder += size;
|
|
|
|
|
+ } else if (donSkus.getSpecVal().contains(payType.get(2))) {
|
|
|
|
|
+ numOfYearOrder += size;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ //月付
|
|
|
|
|
+ backData.setNumOfMonthOrder(numOfMonthOrder);
|
|
|
|
|
+ //季付
|
|
|
|
|
+ backData.setNumOfSeasonOrder(numOfSeasonOrder);
|
|
|
|
|
+ //年付
|
|
|
|
|
+ backData.setNumOfYearOrder(numOfYearOrder);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|