数据统计
This commit is contained in:
@@ -81,7 +81,7 @@ public class CodeGen {
|
||||
//设置表前缀和只生成哪些表,setGenerateTable 未配置时,生成所有表
|
||||
globalConfig.getStrategyConfig()
|
||||
.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();
|
||||
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 表
|
||||
|
||||
|
||||
### 30. 统计订单数据
|
||||
> /merge/statistic/order
|
||||
#### 执行表
|
||||
- tb_shop_order_statistic 表
|
||||
- tb_shop_prod_statistic 表
|
||||
- tb_shop_table_order_statistic 表
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user