数据统计
This commit is contained in:
@@ -81,7 +81,7 @@ public class CodeGen {
|
|||||||
//设置表前缀和只生成哪些表,setGenerateTable 未配置时,生成所有表
|
//设置表前缀和只生成哪些表,setGenerateTable 未配置时,生成所有表
|
||||||
globalConfig.getStrategyConfig()
|
globalConfig.getStrategyConfig()
|
||||||
.setTablePrefix("tb_")
|
.setTablePrefix("tb_")
|
||||||
.setGenerateTable("tb_prod_cons_relation");
|
.setGenerateTable("tb_shop_order_statistic", "tb_shop_prod_statistic", "tb_shop_table_order_statistic");
|
||||||
|
|
||||||
EntityConfig entityConfig = globalConfig.getEntityConfig();
|
EntityConfig entityConfig = globalConfig.getEntityConfig();
|
||||||
if (IS_OLD_VERSION) {
|
if (IS_OLD_VERSION) {
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package com.czg.mergedata.controller;
|
||||||
|
|
||||||
|
import com.czg.mergedata.cur.service.CurShopOrderStatisticService;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author GYJoker
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/statistic")
|
||||||
|
public class StatisticController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private CurShopOrderStatisticService curShopOrderStatisticService;
|
||||||
|
|
||||||
|
@RequestMapping("/order")
|
||||||
|
public Object curShopOrder() {
|
||||||
|
return curShopOrderStatisticService.statisticOrderData();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,161 @@
|
|||||||
|
package com.czg.mergedata.cur.entity;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.annotation.JSONField;
|
||||||
|
import com.mybatisflex.annotation.Column;
|
||||||
|
import com.mybatisflex.annotation.Id;
|
||||||
|
import com.mybatisflex.annotation.KeyType;
|
||||||
|
import com.mybatisflex.annotation.Table;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.sql.Date;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单统计表 实体类。
|
||||||
|
*
|
||||||
|
* @author mac
|
||||||
|
* @since 2025-03-19
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Table("tb_shop_order_statistic")
|
||||||
|
public class CurShopOrderStatistic implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Id(keyType = KeyType.Auto)
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 销售额
|
||||||
|
*/
|
||||||
|
private BigDecimal saleAmount = BigDecimal.ZERO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 销售数量
|
||||||
|
*/
|
||||||
|
private Long saleCount = 0L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优惠金额
|
||||||
|
*/
|
||||||
|
private BigDecimal discountAmount = BigDecimal.ZERO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优惠笔数
|
||||||
|
*/
|
||||||
|
private Long discountCount = 0L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款金额
|
||||||
|
*/
|
||||||
|
private BigDecimal refundAmount = BigDecimal.ZERO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款笔数
|
||||||
|
*/
|
||||||
|
private Long refundCount = 0L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信支付笔数
|
||||||
|
*/
|
||||||
|
private Long wechatPayCount = 0L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信支付金额
|
||||||
|
*/
|
||||||
|
private BigDecimal wechatPayAmount = BigDecimal.ZERO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付宝支付笔数
|
||||||
|
*/
|
||||||
|
private Long aliPayCount = 0L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付宝支付金额
|
||||||
|
*/
|
||||||
|
private BigDecimal aliPayAmount = BigDecimal.ZERO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 挂账支付笔数
|
||||||
|
*/
|
||||||
|
private Long creditPayCount = 0L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 挂账支付金额
|
||||||
|
*/
|
||||||
|
private BigDecimal creditPayAmount = BigDecimal.ZERO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会员支付笔数
|
||||||
|
*/
|
||||||
|
private Long memberPayCount = 0L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会员支付金额
|
||||||
|
*/
|
||||||
|
private BigDecimal memberPayAmount = BigDecimal.ZERO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主扫支付笔数
|
||||||
|
*/
|
||||||
|
private Long scanPayCount = 0L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主扫支付金额
|
||||||
|
*/
|
||||||
|
private BigDecimal scanPayAmount = BigDecimal.ZERO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 现金支付笔数
|
||||||
|
*/
|
||||||
|
private Long cashPayCount = 0L;
|
||||||
|
/**
|
||||||
|
* 现金支付金额
|
||||||
|
*/
|
||||||
|
private BigDecimal cashPayAmount = BigDecimal.ZERO;
|
||||||
|
/**
|
||||||
|
* 充值金额
|
||||||
|
*/
|
||||||
|
private BigDecimal rechargeAmount = BigDecimal.ZERO;
|
||||||
|
/**
|
||||||
|
* 客单价
|
||||||
|
*/
|
||||||
|
private BigDecimal customerUnitPrice = BigDecimal.ZERO;
|
||||||
|
/**
|
||||||
|
* 翻台率
|
||||||
|
*/
|
||||||
|
private BigDecimal tableTurnoverRate = BigDecimal.ZERO;
|
||||||
|
/**
|
||||||
|
* 新增会员数
|
||||||
|
*/
|
||||||
|
@Column(ignore = true)
|
||||||
|
private Long newMemberCount = 0L;
|
||||||
|
/**
|
||||||
|
* 店铺id
|
||||||
|
*/
|
||||||
|
@JSONField(serialize = false)
|
||||||
|
private Long shopId;
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@JSONField(serialize = false, format = "yyyy-MM-dd")
|
||||||
|
private Date createDay;
|
||||||
|
/**
|
||||||
|
* 最近一次统计时间
|
||||||
|
*/
|
||||||
|
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private LocalDateTime updateTime;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package com.czg.mergedata.cur.entity;
|
||||||
|
|
||||||
|
import com.mybatisflex.annotation.Id;
|
||||||
|
import com.mybatisflex.annotation.KeyType;
|
||||||
|
import com.mybatisflex.annotation.Table;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.sql.Date;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品统计表 实体类。
|
||||||
|
*
|
||||||
|
* @author mac
|
||||||
|
* @since 2025-03-19
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Table("tb_shop_prod_statistic")
|
||||||
|
public class CurShopProdStatistic implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Id(keyType = KeyType.Auto)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品id
|
||||||
|
*/
|
||||||
|
private Long prodId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 销售数量
|
||||||
|
*/
|
||||||
|
private BigDecimal saleCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 销售金额
|
||||||
|
*/
|
||||||
|
private BigDecimal saleAmount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退单量
|
||||||
|
*/
|
||||||
|
private BigDecimal refundCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退单金额
|
||||||
|
*/
|
||||||
|
private BigDecimal refundAmount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 店铺id
|
||||||
|
*/
|
||||||
|
private Long shopId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
private Date createDay;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
package com.czg.mergedata.cur.entity;
|
||||||
|
|
||||||
|
import com.mybatisflex.annotation.Id;
|
||||||
|
import com.mybatisflex.annotation.KeyType;
|
||||||
|
import com.mybatisflex.annotation.Table;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.sql.Date;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 台桌订单统计表 实体类。
|
||||||
|
*
|
||||||
|
* @author mac
|
||||||
|
* @since 2025-03-19
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Table("tb_shop_table_order_statistic")
|
||||||
|
public class CurShopTableOrderStatistic implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Id(keyType = KeyType.Auto)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private Long tableId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单数量
|
||||||
|
*/
|
||||||
|
private Long orderCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单金额
|
||||||
|
*/
|
||||||
|
private BigDecimal orderAmount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 店铺id
|
||||||
|
*/
|
||||||
|
private Long shopId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建日期 年月日
|
||||||
|
*/
|
||||||
|
private Date createDay;
|
||||||
|
/**
|
||||||
|
* 退款数量
|
||||||
|
*/
|
||||||
|
private long refundCount;
|
||||||
|
/**
|
||||||
|
* 退款金额
|
||||||
|
*/
|
||||||
|
private BigDecimal refundAmount;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.czg.mergedata.cur.mapper;
|
||||||
|
|
||||||
|
import com.mybatisflex.core.BaseMapper;
|
||||||
|
import com.czg.mergedata.cur.entity.CurShopOrderStatistic;
|
||||||
|
import org.apache.ibatis.annotations.Select;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单统计表 映射层。
|
||||||
|
*
|
||||||
|
* @author mac
|
||||||
|
* @since 2025-03-19
|
||||||
|
*/
|
||||||
|
public interface CurShopOrderStatisticMapper extends BaseMapper<CurShopOrderStatistic> {
|
||||||
|
@Select("truncate tb_shop_order_statistic")
|
||||||
|
void truncateTable();
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.czg.mergedata.cur.mapper;
|
||||||
|
|
||||||
|
import com.mybatisflex.core.BaseMapper;
|
||||||
|
import com.czg.mergedata.cur.entity.CurShopProdStatistic;
|
||||||
|
import org.apache.ibatis.annotations.Select;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品统计表 映射层。
|
||||||
|
*
|
||||||
|
* @author mac
|
||||||
|
* @since 2025-03-19
|
||||||
|
*/
|
||||||
|
public interface CurShopProdStatisticMapper extends BaseMapper<CurShopProdStatistic> {
|
||||||
|
@Select("truncate tb_shop_prod_statistic")
|
||||||
|
void truncateTable();
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.czg.mergedata.cur.mapper;
|
||||||
|
|
||||||
|
import com.mybatisflex.core.BaseMapper;
|
||||||
|
import com.czg.mergedata.cur.entity.CurShopTableOrderStatistic;
|
||||||
|
import org.apache.ibatis.annotations.Select;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 台桌订单统计表 映射层。
|
||||||
|
*
|
||||||
|
* @author mac
|
||||||
|
* @since 2025-03-19
|
||||||
|
*/
|
||||||
|
public interface CurShopTableOrderStatisticMapper extends BaseMapper<CurShopTableOrderStatistic> {
|
||||||
|
@Select("truncate tb_shop_table_order_statistic")
|
||||||
|
void truncateTable();
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.czg.mergedata.cur.service;
|
||||||
|
|
||||||
|
import com.czg.mergedata.common.resp.CzgResult;
|
||||||
|
import com.mybatisflex.core.service.IService;
|
||||||
|
import com.czg.mergedata.cur.entity.CurShopOrderStatistic;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单统计表 服务层。
|
||||||
|
*
|
||||||
|
* @author mac
|
||||||
|
* @since 2025-03-19
|
||||||
|
*/
|
||||||
|
public interface CurShopOrderStatisticService extends IService<CurShopOrderStatistic> {
|
||||||
|
CzgResult<String> statisticOrderData();
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.czg.mergedata.cur.service;
|
||||||
|
|
||||||
|
import com.mybatisflex.core.service.IService;
|
||||||
|
import com.czg.mergedata.cur.entity.CurShopProdStatistic;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品统计表 服务层。
|
||||||
|
*
|
||||||
|
* @author mac
|
||||||
|
* @since 2025-03-19
|
||||||
|
*/
|
||||||
|
public interface CurShopProdStatisticService extends IService<CurShopProdStatistic> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.czg.mergedata.cur.service;
|
||||||
|
|
||||||
|
import com.mybatisflex.core.service.IService;
|
||||||
|
import com.czg.mergedata.cur.entity.CurShopTableOrderStatistic;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 台桌订单统计表 服务层。
|
||||||
|
*
|
||||||
|
* @author mac
|
||||||
|
* @since 2025-03-19
|
||||||
|
*/
|
||||||
|
public interface CurShopTableOrderStatisticService extends IService<CurShopTableOrderStatistic> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,351 @@
|
|||||||
|
package com.czg.mergedata.cur.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.collection.ListUtil;
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||||
|
import com.czg.mergedata.common.resp.CzgResult;
|
||||||
|
import com.czg.mergedata.cur.entity.*;
|
||||||
|
import com.czg.mergedata.cur.mapper.CurShopOrderStatisticMapper;
|
||||||
|
import com.czg.mergedata.cur.mapper.CurShopProdStatisticMapper;
|
||||||
|
import com.czg.mergedata.cur.mapper.CurShopTableOrderStatisticMapper;
|
||||||
|
import com.czg.mergedata.cur.service.*;
|
||||||
|
import com.mybatisflex.core.query.QueryWrapper;
|
||||||
|
import com.mybatisflex.spring.service.impl.ServiceImpl;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
import java.sql.Date;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单统计表 服务层实现。
|
||||||
|
*
|
||||||
|
* @author mac
|
||||||
|
* @since 2025-03-19
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
public class CurShopOrderStatisticServiceImpl extends ServiceImpl<CurShopOrderStatisticMapper, CurShopOrderStatistic> implements CurShopOrderStatisticService {
|
||||||
|
@Resource
|
||||||
|
private CurShopProdStatisticMapper curShopProdStatisticMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private CurShopProdStatisticService curShopProdStatisticService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private CurShopTableOrderStatisticMapper curShopTableOrderStatisticMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private CurShopTableOrderStatisticService curShopTableOrderStatisticService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private CurOrderInfoService orderInfoService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private CurShopTableService shopTableService;
|
||||||
|
@Resource
|
||||||
|
private CurShopUserFlowService shopUserFlowService;
|
||||||
|
@Resource
|
||||||
|
private CurOrderDetailService orderDetailService;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
private static class ProdStatisticTask{
|
||||||
|
private BigDecimal successCount = BigDecimal.ZERO;
|
||||||
|
private BigDecimal successAmount = BigDecimal.ZERO;
|
||||||
|
private BigDecimal refundCount = BigDecimal.ZERO;
|
||||||
|
private BigDecimal refundAmount = BigDecimal.ZERO;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
private static class TableStatisticTask{
|
||||||
|
private long successCount = 0;
|
||||||
|
private BigDecimal successAmount = BigDecimal.ZERO;
|
||||||
|
private long refundCount = 0;
|
||||||
|
private BigDecimal refundAmount = BigDecimal.ZERO;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CzgResult<String> statisticOrderData() {
|
||||||
|
getMapper().truncateTable();
|
||||||
|
curShopProdStatisticMapper.truncateTable();
|
||||||
|
curShopTableOrderStatisticMapper.truncateTable();
|
||||||
|
|
||||||
|
startStsData();
|
||||||
|
|
||||||
|
return CzgResult.success("订单统计数据清理成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startStsData() {
|
||||||
|
AtomicInteger refundIndex = new AtomicInteger(0);
|
||||||
|
LocalDateTime localDateTime = LocalDateTime.now();
|
||||||
|
CurOrderInfo firstOrderInfo = orderInfoService.getOne(QueryWrapper.create().orderBy("create_time asc"));
|
||||||
|
|
||||||
|
LocalDateTime time = firstOrderInfo.getCreateTime();
|
||||||
|
|
||||||
|
LocalDateTime endTime = LocalDateTime.now().minusDays(1);
|
||||||
|
LocalDateTime endOfDay = LocalDateTimeUtil.endOfDay(endTime);
|
||||||
|
List<LocalDateTime> stsDays = new ArrayList<>();
|
||||||
|
while (time.isBefore(endOfDay)) {
|
||||||
|
stsDays.add(time);
|
||||||
|
time = time.plusDays(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("stsDays size: " + stsDays.size());
|
||||||
|
|
||||||
|
List<List<LocalDateTime>> lists = ListUtil.splitAvg(stsDays, 7);
|
||||||
|
|
||||||
|
List<CompletableFuture<Void>> futures = new ArrayList<>();
|
||||||
|
|
||||||
|
// lists.stream()
|
||||||
|
// .flatMap(List::stream)
|
||||||
|
// .forEach(stsDay -> {
|
||||||
|
// CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
|
||||||
|
// stsOrderData(stsDay);
|
||||||
|
// stsProdData(stsDay);
|
||||||
|
// stsTableData(stsDay);
|
||||||
|
// }).whenComplete((m, k) -> {
|
||||||
|
// LocalDateTime end = LocalDateTime.now();
|
||||||
|
// log.info("当前任务完成 当前耗时:{}秒", LocalDateTimeUtil.between(localDateTime, end, ChronoUnit.SECONDS));
|
||||||
|
// refundIndex.incrementAndGet();
|
||||||
|
// log.info("当前进度:{}", refundIndex.get());
|
||||||
|
// });
|
||||||
|
// futures.add(future);
|
||||||
|
// });
|
||||||
|
|
||||||
|
for (List<LocalDateTime> list : lists) {
|
||||||
|
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
|
||||||
|
for (LocalDateTime stsDay : list) {
|
||||||
|
stsOrderData(stsDay);
|
||||||
|
stsProdData(stsDay);
|
||||||
|
stsTableData(stsDay);
|
||||||
|
}
|
||||||
|
}).whenComplete((m, k) -> {
|
||||||
|
LocalDateTime end = LocalDateTime.now();
|
||||||
|
log.info("当前任务完成 当前耗时:{}秒", LocalDateTimeUtil.between(localDateTime, end, ChronoUnit.SECONDS));
|
||||||
|
refundIndex.incrementAndGet();
|
||||||
|
log.info("当前进度:{}", refundIndex.get());
|
||||||
|
});
|
||||||
|
futures.add(future);
|
||||||
|
}
|
||||||
|
|
||||||
|
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).whenComplete((m, k) -> {
|
||||||
|
LocalDateTime end = LocalDateTime.now();
|
||||||
|
log.info("所有任务已经完成 当前耗时:{}秒", LocalDateTimeUtil.between(localDateTime, end, ChronoUnit.SECONDS));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stsOrderData(LocalDateTime date) {
|
||||||
|
// 获取前一天的开始时间(00:00:00)
|
||||||
|
LocalDateTime startOfDay = LocalDateTimeUtil.beginOfDay(date);
|
||||||
|
// 获取前一天的结束时间(23:59:59)
|
||||||
|
LocalDateTime endOfDay = LocalDateTimeUtil.endOfDay(date);
|
||||||
|
List<CurOrderInfo> orderInfos = orderInfoService.list(new QueryWrapper()
|
||||||
|
.ge(CurOrderInfo::getCreateTime, startOfDay)
|
||||||
|
.le(CurOrderInfo::getCreateTime, endOfDay)
|
||||||
|
.ne(CurOrderInfo::getStatus, "unpaid").ne(CurOrderInfo::getStatus, "cancelled"));
|
||||||
|
|
||||||
|
// 统计充值记录
|
||||||
|
Map<Long, BigDecimal> flowMap = shopUserFlowService.list(new QueryWrapper()
|
||||||
|
.ge(CurShopUserFlow::getCreateTime, startOfDay)
|
||||||
|
.le(CurShopUserFlow::getCreateTime, endOfDay)
|
||||||
|
.in(CurShopUserFlow::getBizCode, CollUtil.newArrayList("cashIn", "wechatIn", "alipayIn", "awardIn"))).stream()
|
||||||
|
.collect(Collectors.groupingBy(
|
||||||
|
CurShopUserFlow::getShopId,
|
||||||
|
Collectors.reducing(
|
||||||
|
BigDecimal.ZERO,
|
||||||
|
CurShopUserFlow::getAmount,
|
||||||
|
BigDecimal::add
|
||||||
|
)
|
||||||
|
));
|
||||||
|
|
||||||
|
HashMap<Long, CurShopOrderStatistic> countInfo = new HashMap<>();
|
||||||
|
for (CurOrderInfo item : orderInfos) {
|
||||||
|
CurShopOrderStatistic statisticTask = countInfo.get(item.getShopId());
|
||||||
|
if (statisticTask == null) {
|
||||||
|
countInfo.put(item.getShopId(), statisticTask = new CurShopOrderStatistic());
|
||||||
|
}
|
||||||
|
|
||||||
|
BigDecimal bigDecimal = flowMap.get(item.getShopId());
|
||||||
|
if (bigDecimal != null) {
|
||||||
|
statisticTask.setRechargeAmount(bigDecimal);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("refunding".equals(item.getStatus()) || "refund".equals(item.getStatus()) || "part-refund".equals(item.getStatus())) {
|
||||||
|
statisticTask.setRefundAmount(statisticTask.getRefundAmount().add(item.getRefundAmount()));
|
||||||
|
statisticTask.setRefundCount(statisticTask.getRefundCount() + 1);
|
||||||
|
if (item.getRefundAmount().compareTo(item.getPayAmount()) < 0) {
|
||||||
|
statisticTask.setSaleAmount(statisticTask.getSaleAmount().add(item.getPayAmount().subtract(item.getRefundAmount())));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
statisticTask.setSaleCount(statisticTask.getSaleCount() + 1);
|
||||||
|
statisticTask.setSaleAmount(statisticTask.getSaleAmount().add(item.getPayAmount()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
switch (item.getPayType()) {
|
||||||
|
case "wechat-mini":
|
||||||
|
statisticTask.setWechatPayAmount(statisticTask.getWechatPayAmount().add(item.getPayAmount()));
|
||||||
|
statisticTask.setWechatPayCount(statisticTask.getWechatPayCount() + 1);
|
||||||
|
break;
|
||||||
|
case "main-scan", "back-scan":
|
||||||
|
statisticTask.setScanPayAmount(statisticTask.getScanPayAmount().add(item.getPayAmount()));
|
||||||
|
statisticTask.setScanPayCount(statisticTask.getScanPayCount() + 1);
|
||||||
|
break;
|
||||||
|
case "alipay-mini":
|
||||||
|
statisticTask.setAliPayAmount(statisticTask.getAliPayAmount().add(item.getPayAmount()));
|
||||||
|
statisticTask.setAliPayCount(statisticTask.getAliPayCount() + 1);
|
||||||
|
break;
|
||||||
|
case "vip-pay":
|
||||||
|
statisticTask.setMemberPayAmount(statisticTask.getMemberPayAmount().add(item.getPayAmount()));
|
||||||
|
statisticTask.setMemberPayCount(statisticTask.getMemberPayCount() + 1);
|
||||||
|
break;
|
||||||
|
case "credit-pay":
|
||||||
|
statisticTask.setCreditPayAmount(statisticTask.getCreditPayAmount().add(item.getPayAmount()));
|
||||||
|
statisticTask.setCreditPayCount(statisticTask.getCreditPayCount() + 1);
|
||||||
|
break;
|
||||||
|
case "cash-pay":
|
||||||
|
statisticTask.setCashPayAmount(statisticTask.getCashPayAmount().add(item.getPayAmount()));
|
||||||
|
statisticTask.setCashPayCount(statisticTask.getCashPayCount() + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
countInfo.forEach((shopId, info) -> {
|
||||||
|
Date format = DateUtil.parseDate(LocalDateTimeUtil.format(date, "yyyy-MM-dd")).toSqlDate();
|
||||||
|
CurShopOrderStatistic statistic = getOne(new QueryWrapper().eq(CurShopOrderStatistic::getShopId, shopId).eq(CurShopOrderStatistic::getCreateDay, format));
|
||||||
|
if (statistic == null) {
|
||||||
|
statistic = new CurShopOrderStatistic();
|
||||||
|
statistic.setShopId(shopId);
|
||||||
|
statistic.setCreateDay(format);
|
||||||
|
}
|
||||||
|
BigDecimal totalAmount = statistic.getSaleAmount().add(statistic.getRefundAmount());
|
||||||
|
BigDecimal totalCount = BigDecimal.valueOf(statistic.getSaleCount() + statistic.getRefundCount());
|
||||||
|
// 充值金额
|
||||||
|
// statistic.setRechargeAmount(BigDecimal.ZERO);
|
||||||
|
//客单价
|
||||||
|
if (totalAmount.compareTo(BigDecimal.ZERO) != 0) {
|
||||||
|
statistic.setCustomerUnitPrice(totalAmount.divide(totalCount, 2, RoundingMode.DOWN));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询台桌数量
|
||||||
|
long count = shopTableService.count(new QueryWrapper().eq(CurShopTable::getShopId, shopId));
|
||||||
|
|
||||||
|
//翻台率
|
||||||
|
if (count > 0) {
|
||||||
|
statistic.setTableTurnoverRate(totalCount.subtract(BigDecimal.valueOf(count)).divide(BigDecimal.valueOf(count), 2, RoundingMode.DOWN).multiply(BigDecimal.valueOf(100)));
|
||||||
|
}
|
||||||
|
statistic.setUpdateTime(LocalDateTime.now());
|
||||||
|
BeanUtil.copyProperties(info, statistic);
|
||||||
|
statistic.setShopId(shopId);
|
||||||
|
statistic.setCreateDay(format);
|
||||||
|
saveOrUpdate(statistic);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stsProdData(LocalDateTime date) {
|
||||||
|
// 获取前一天的开始时间(00:00:00)
|
||||||
|
LocalDateTime startOfDay = LocalDateTimeUtil.beginOfDay(date);
|
||||||
|
// 获取前一天的结束时间(23:59:59)
|
||||||
|
LocalDateTime endOfDay = LocalDateTimeUtil.endOfDay(date);
|
||||||
|
List<CurOrderDetail> orderDetails = orderDetailService.list(new QueryWrapper()
|
||||||
|
.ge(CurOrderDetail::getCreateTime, startOfDay)
|
||||||
|
.le(CurOrderDetail::getCreateTime, endOfDay)
|
||||||
|
.ne(CurOrderDetail::getStatus, "wait-pay"));
|
||||||
|
|
||||||
|
|
||||||
|
HashMap<Long, Map<Long, ProdStatisticTask>> countInfo = new HashMap<>();
|
||||||
|
for (CurOrderDetail item : orderDetails) {
|
||||||
|
Map<Long, ProdStatisticTask> map = countInfo.computeIfAbsent(item.getShopId(), k -> new HashMap<>());
|
||||||
|
ProdStatisticTask statisticTask = map.get(item.getProductId());
|
||||||
|
if (statisticTask == null) {
|
||||||
|
map.put(item.getProductId(), statisticTask = new ProdStatisticTask());
|
||||||
|
}
|
||||||
|
if ("refunding".equals(item.getStatus()) || "refund".equals(item.getStatus()) || "part-refund".equals(item.getStatus())) {
|
||||||
|
statisticTask.setRefundAmount(statisticTask.getRefundAmount().add(item.getReturnAmount()));
|
||||||
|
statisticTask.setRefundCount(statisticTask.getRefundCount().add(item.getRefundNum()));
|
||||||
|
if (item.getReturnNum().compareTo(item.getNum()) < 0) {
|
||||||
|
statisticTask.setSuccessAmount(statisticTask.getSuccessAmount().add(item.getPayAmount().subtract(item.getReturnAmount())));
|
||||||
|
statisticTask.setSuccessCount(statisticTask.getSuccessCount().add(item.getNum().subtract(item.getReturnAmount())));
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
statisticTask.setSuccessCount(statisticTask.getSuccessCount().add(item.getNum()));
|
||||||
|
statisticTask.setSuccessAmount(statisticTask.getSuccessAmount().add(item.getPayAmount()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
countInfo.forEach((shopId, map) -> map.forEach((productId, statisticTask) -> {
|
||||||
|
Date format = DateUtil.parseDate(LocalDateTimeUtil.format(date, "yyyy-MM-dd")).toSqlDate();
|
||||||
|
CurShopProdStatistic statistic = curShopProdStatisticService.getOne(new QueryWrapper().eq(CurShopProdStatistic::getShopId, shopId).eq(CurShopProdStatistic::getCreateDay, format));
|
||||||
|
if (statistic == null) {
|
||||||
|
statistic = new CurShopProdStatistic();
|
||||||
|
statistic.setShopId(shopId);
|
||||||
|
statistic.setCreateDay(format);
|
||||||
|
}
|
||||||
|
statistic.setProdId(productId);
|
||||||
|
statistic.setSaleCount(statisticTask.getSuccessCount());
|
||||||
|
statistic.setSaleAmount(statisticTask.getSuccessAmount());
|
||||||
|
statistic.setRefundCount(statisticTask.getRefundCount());
|
||||||
|
statistic.setRefundAmount(statisticTask.getRefundAmount());
|
||||||
|
curShopProdStatisticService.saveOrUpdate(statistic);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stsTableData(LocalDateTime date) {
|
||||||
|
// 获取前一天的开始时间(00:00:00)
|
||||||
|
LocalDateTime startOfDay = LocalDateTimeUtil.beginOfDay(date);
|
||||||
|
// 获取前一天的结束时间(23:59:59)
|
||||||
|
LocalDateTime endOfDay = LocalDateTimeUtil.endOfDay(date);
|
||||||
|
List<CurOrderInfo> orderInfos = orderInfoService.list(new QueryWrapper()
|
||||||
|
.ge(CurOrderInfo::getCreateTime, startOfDay)
|
||||||
|
.le(CurOrderInfo::getCreateTime, endOfDay)
|
||||||
|
.ne(CurOrderInfo::getStatus, "unpaid").ne(CurOrderInfo::getStatus, "cancelled"));
|
||||||
|
|
||||||
|
HashMap<Long, TableStatisticTask> countInfo = new HashMap<>();
|
||||||
|
for (CurOrderInfo item : orderInfos) {
|
||||||
|
TableStatisticTask statisticTask = countInfo.get(item.getShopId());
|
||||||
|
if (statisticTask == null) {
|
||||||
|
countInfo.put(item.getShopId(), statisticTask = new TableStatisticTask());
|
||||||
|
}
|
||||||
|
if ("refunding".equals(item.getStatus()) || "refund".equals(item.getStatus()) || "part-refund".equals(item.getStatus())) {
|
||||||
|
statisticTask.setRefundAmount(statisticTask.getRefundAmount().add(item.getRefundAmount()));
|
||||||
|
statisticTask.setRefundCount(statisticTask.getRefundCount() + 1);
|
||||||
|
if (item.getRefundAmount().compareTo(item.getPayAmount()) < 0) {
|
||||||
|
statisticTask.setSuccessAmount(statisticTask.getSuccessAmount().add(item.getPayAmount().subtract(item.getRefundAmount())));
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
statisticTask.setSuccessCount(statisticTask.getSuccessCount() + 1);
|
||||||
|
statisticTask.setSuccessAmount(statisticTask.getSuccessAmount().add(item.getPayAmount()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
countInfo.forEach((shopId, statisticTask) -> {
|
||||||
|
Date format = Date.valueOf(LocalDateTimeUtil.format(date, "yyyy-MM-dd"));
|
||||||
|
CurShopTableOrderStatistic statistic = curShopTableOrderStatisticService.getOne(new QueryWrapper().eq(CurShopTableOrderStatistic::getShopId, shopId).eq(CurShopTableOrderStatistic::getCreateDay, format));
|
||||||
|
if (statistic == null) {
|
||||||
|
statistic = new CurShopTableOrderStatistic();
|
||||||
|
statistic.setShopId(shopId);
|
||||||
|
statistic.setTableId(0L);
|
||||||
|
statistic.setCreateDay(format);
|
||||||
|
}
|
||||||
|
statistic.setOrderCount(statisticTask.getSuccessCount());
|
||||||
|
statistic.setOrderAmount(statisticTask.getSuccessAmount());
|
||||||
|
statistic.setRefundCount(statisticTask.getRefundCount());
|
||||||
|
statistic.setRefundAmount(statisticTask.getRefundAmount());
|
||||||
|
curShopTableOrderStatisticService.saveOrUpdate(statistic);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.czg.mergedata.cur.service.impl;
|
||||||
|
|
||||||
|
import com.mybatisflex.spring.service.impl.ServiceImpl;
|
||||||
|
import com.czg.mergedata.cur.entity.CurShopProdStatistic;
|
||||||
|
import com.czg.mergedata.cur.mapper.CurShopProdStatisticMapper;
|
||||||
|
import com.czg.mergedata.cur.service.CurShopProdStatisticService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品统计表 服务层实现。
|
||||||
|
*
|
||||||
|
* @author mac
|
||||||
|
* @since 2025-03-19
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class CurShopProdStatisticServiceImpl extends ServiceImpl<CurShopProdStatisticMapper, CurShopProdStatistic> implements CurShopProdStatisticService{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.czg.mergedata.cur.service.impl;
|
||||||
|
|
||||||
|
import com.mybatisflex.spring.service.impl.ServiceImpl;
|
||||||
|
import com.czg.mergedata.cur.entity.CurShopTableOrderStatistic;
|
||||||
|
import com.czg.mergedata.cur.mapper.CurShopTableOrderStatisticMapper;
|
||||||
|
import com.czg.mergedata.cur.service.CurShopTableOrderStatisticService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 台桌订单统计表 服务层实现。
|
||||||
|
*
|
||||||
|
* @author mac
|
||||||
|
* @since 2025-03-19
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class CurShopTableOrderStatisticServiceImpl extends ServiceImpl<CurShopTableOrderStatisticMapper, CurShopTableOrderStatistic> implements CurShopTableOrderStatisticService{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper
|
||||||
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.czg.mergedata.cur.mapper.CurShopOrderStatisticMapper">
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper
|
||||||
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.czg.mergedata.cur.mapper.CurShopProdStatisticMapper">
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper
|
||||||
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.czg.mergedata.cur.mapper.CurShopTableOrderStatisticMapper">
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@@ -212,4 +212,13 @@
|
|||||||
- tb_prod_cons_relation 表
|
- tb_prod_cons_relation 表
|
||||||
|
|
||||||
|
|
||||||
|
### 30. 统计订单数据
|
||||||
|
> /merge/statistic/order
|
||||||
|
#### 执行表
|
||||||
|
- tb_shop_order_statistic 表
|
||||||
|
- tb_shop_prod_statistic 表
|
||||||
|
- tb_shop_table_order_statistic 表
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user