统计
This commit is contained in:
@@ -1,54 +0,0 @@
|
||||
//package com.czg.controller.admin;
|
||||
//
|
||||
//import com.czg.account.dto.ShopShareDTO;
|
||||
//import com.czg.account.service.ShopShareService;
|
||||
//import com.czg.account.vo.ShopShareRecordVO;
|
||||
//import com.czg.account.vo.ShopShareVO;
|
||||
//import com.czg.annotation.SaAdminCheckPermission;
|
||||
//import com.czg.resp.CzgResult;
|
||||
//import com.czg.sa.StpKit;
|
||||
//import com.mybatisflex.core.paginate.Page;
|
||||
//import jakarta.annotation.Resource;
|
||||
//import org.springframework.validation.annotation.Validated;
|
||||
//import org.springframework.web.bind.annotation.*;
|
||||
//
|
||||
///**
|
||||
// * 小程序分享奖励管理
|
||||
// * @author Administrator
|
||||
// */
|
||||
//@RestController
|
||||
//@RequestMapping("/admin/shopShare")
|
||||
//public class ShopShareController {
|
||||
// @Resource
|
||||
// private ShopShareService shopShareService;
|
||||
//
|
||||
// /**
|
||||
// * 获取分享奖励配置
|
||||
// */
|
||||
// @SaAdminCheckPermission(value = "shopShare:list", name = "分享好友信息")
|
||||
// @GetMapping
|
||||
// public CzgResult<ShopShareVO> get() {
|
||||
// return CzgResult.success(shopShareService.get(StpKit.USER.getShopId()));
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 修改分享奖励配置
|
||||
// */
|
||||
// @SaAdminCheckPermission(value = "shopShare:add", name = "分享好友信息添加")
|
||||
// @PostMapping
|
||||
// public CzgResult<Boolean> add(@RequestBody @Validated ShopShareDTO shopShareDTO) {
|
||||
// return CzgResult.success(shopShareService.add(StpKit.USER.getShopId(), shopShareDTO));
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 分享奖励记录
|
||||
// * @param key 邀请人/被邀请人手机号或昵称
|
||||
// * @param status 0 非新用户 1 未领取 2 已领取 3 已使用 不传递为全部
|
||||
// * @return 分页数据
|
||||
// */
|
||||
// @SaAdminCheckPermission(value = "shopShare:record", name = "分享邀请记录")
|
||||
// @GetMapping("/record")
|
||||
// public CzgResult<Page<ShopShareRecordVO>> record(String key, Integer status) {
|
||||
// return CzgResult.success(shopShareService.recordPage(StpKit.USER.getShopId(), key, status));
|
||||
// }
|
||||
//}
|
||||
@@ -1,24 +0,0 @@
|
||||
package com.czg.controller.admin;
|
||||
|
||||
import com.czg.account.service.ShopProdStatisticService;
|
||||
import com.czg.resp.CzgResult;
|
||||
import com.czg.sa.StpKit;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/admin/statistic")
|
||||
public class ShopStatisticController {
|
||||
@Resource
|
||||
private ShopProdStatisticService shopProdStatisticService;
|
||||
|
||||
@GetMapping("/prod")
|
||||
public CzgResult<?> getProduct(String name, String categoryId, String startTime, String endTime) {
|
||||
return CzgResult.success(shopProdStatisticService.pageInfo(StpKit.USER.getShopId(), name, categoryId, startTime, endTime));
|
||||
}
|
||||
}
|
||||
@@ -176,7 +176,7 @@ public class OrderPayController {
|
||||
|
||||
/**
|
||||
* 获取订单状态
|
||||
* unpaid-待支付;in-production 制作中;wait-out 待取餐;;done-订单完成;refunding-申请退单;refund-退单;part-refund 部分退单;cancelled-取消订单
|
||||
* unpaid-待支付;in-production 制作中;wait_out 待取餐;;done-订单完成;refunding-申请退单;refund-退单;part_refund 部分退单;cancelled-取消订单
|
||||
*/
|
||||
@GetMapping("/queryOrderStatus")
|
||||
public CzgResult<String> queryOrderStatus(Long orderId) {
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.czg.controller;
|
||||
|
||||
import com.czg.task.StatisticTask;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* @author ww
|
||||
* @description
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/task")
|
||||
public class StatisticTaskController {
|
||||
|
||||
@Resource
|
||||
private StatisticTask statisticTask;
|
||||
|
||||
/**
|
||||
* 基础统计
|
||||
*
|
||||
* @param date 日期yyyy-MM-dd
|
||||
*/
|
||||
@GetMapping("/base")
|
||||
public String baseStatistic(@RequestParam LocalDate date, @RequestParam Long shopId, @RequestParam String type) {
|
||||
if ("order".equals(type)) {
|
||||
statisticTask.statisticAndInsertOrder(shopId, date);
|
||||
} else if ("prod".equals(type)) {
|
||||
statisticTask.statisticAndInsertProd(shopId, date);
|
||||
} else if ("table".equals(type)) {
|
||||
statisticTask.statisticAndInsertTable(shopId, date);
|
||||
} else {
|
||||
return "未知错误";
|
||||
}
|
||||
return "success";
|
||||
}
|
||||
}
|
||||
@@ -1,27 +1,29 @@
|
||||
package com.czg.controller.admin;
|
||||
|
||||
import com.czg.annotation.SaAdminCheckPermission;
|
||||
import com.czg.annotation.SaStaffCheckPermission;
|
||||
import com.czg.log.annotation.OperationLog;
|
||||
import com.czg.order.entity.ShopOrderStatistic;
|
||||
import com.czg.order.param.DataSummaryProductSaleParam;
|
||||
import com.czg.order.entity.ShopProdStatistic;
|
||||
import com.czg.order.param.DataSummaryTradeParam;
|
||||
import com.czg.order.service.DataSummaryService;
|
||||
import com.czg.order.vo.DataSummaryDateAmountVo;
|
||||
import com.czg.order.vo.DataSummaryPayTypeVo;
|
||||
import com.czg.order.vo.DataSummaryProductSaleRankingVo;
|
||||
import com.czg.order.service.ShopOrderStatisticService;
|
||||
import com.czg.order.service.ShopProdStatisticService;
|
||||
import com.czg.order.vo.CountPayTypeVo;
|
||||
import com.czg.order.vo.TotalVo;
|
||||
import com.czg.resp.CzgResult;
|
||||
import com.czg.sa.StpKit;
|
||||
import com.czg.service.RedisService;
|
||||
import com.czg.utils.AssertUtil;
|
||||
import com.czg.validator.ValidatorUtil;
|
||||
import com.czg.validator.group.DefaultGroup;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 数据统计
|
||||
*
|
||||
@@ -33,22 +35,31 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
@RequestMapping("/admin/data/summary")
|
||||
public class DataSummaryController {
|
||||
|
||||
private final DataSummaryService dataSummaryService;
|
||||
@Resource
|
||||
private RedisService redisService;
|
||||
@Resource
|
||||
private ShopOrderStatisticService orderStatisticService;
|
||||
@Resource
|
||||
private ShopProdStatisticService prodStatisticService;
|
||||
|
||||
|
||||
/**
|
||||
* 营业板块-上半部分
|
||||
*/
|
||||
@GetMapping("trade")
|
||||
@OperationLog("营业板块-上半部分")
|
||||
// @SaStaffCheckPermission("yun_xu_cha_kan_jing_ying_shu_ju")
|
||||
@SaAdminCheckPermission(value = "dataSummary:trade", name = "营业板块-上半部分")
|
||||
public CzgResult<ShopOrderStatistic> getTradeData(DataSummaryTradeParam param) {
|
||||
Boolean hasKey = redisService.hasKey("task:statistic:date:");
|
||||
if (hasKey) {
|
||||
return CzgResult.failure("数据统计任务正在运行中,请稍后再试");
|
||||
}
|
||||
ValidatorUtil.validateEntity(param, DefaultGroup.class);
|
||||
Long shopId = StpKit.USER.getShopId();
|
||||
if (param.getShopId() == null) {
|
||||
param.setShopId(shopId);
|
||||
}
|
||||
ShopOrderStatistic data = dataSummaryService.getArchiveTradeData(param);
|
||||
ShopOrderStatistic data = orderStatisticService.getArchiveTradeData(param.getShopId(), param.getRangeType(), param.getBeginDate(), param.getEndDate());
|
||||
return CzgResult.success(data);
|
||||
}
|
||||
|
||||
@@ -57,15 +68,14 @@ public class DataSummaryController {
|
||||
*/
|
||||
@GetMapping("productSaleDate")
|
||||
@OperationLog("商品销售-右下")
|
||||
// @SaStaffCheckPermission("yun_xu_cha_kan_jing_ying_shu_ju")
|
||||
@SaAdminCheckPermission(value = "dataSummary:productSaleData", name = "商品销售-右下")
|
||||
public CzgResult<Page<DataSummaryProductSaleRankingVo>> getProductSaleData(DataSummaryProductSaleParam param) {
|
||||
public CzgResult<List<ShopProdStatistic>> getProductSaleData(DataSummaryTradeParam param) {
|
||||
ValidatorUtil.validateEntity(param, DefaultGroup.class);
|
||||
Long shopId = StpKit.USER.getShopId();
|
||||
if (param.getShopId() == null) {
|
||||
param.setShopId(shopId);
|
||||
}
|
||||
Page<DataSummaryProductSaleRankingVo> data = dataSummaryService.getProductSaleRankingPage(param);
|
||||
List<ShopProdStatistic> data = prodStatisticService.getArchiveTradeDataBy20(param.getShopId(), param.getRangeType(), param.getBeginDate(), param.getEndDate());
|
||||
return CzgResult.success(data);
|
||||
}
|
||||
|
||||
@@ -77,14 +87,13 @@ public class DataSummaryController {
|
||||
*/
|
||||
@GetMapping("dateAmount")
|
||||
@OperationLog("销售趋势柱状图 左下")
|
||||
// @SaStaffCheckPermission("yun_xu_cha_kan_jing_ying_shu_ju")
|
||||
@SaAdminCheckPermission(value = "dataSummary:dateAmount", name = "销售趋势柱状图 左下")
|
||||
public CzgResult<DataSummaryDateAmountVo> getDateAmount(@RequestParam Integer day, @RequestParam(required = false) Long shopId) {
|
||||
public CzgResult<List<TotalVo>> getDateAmount(@RequestParam Integer day, @RequestParam(required = false) Long shopId) {
|
||||
AssertUtil.isNull(day, "天数不能为空");
|
||||
if (shopId == null) {
|
||||
shopId = StpKit.USER.getShopId();
|
||||
}
|
||||
DataSummaryDateAmountVo data = dataSummaryService.getSummaryAmountData(shopId, day);
|
||||
List<TotalVo> data = orderStatisticService.getDateAmount(shopId, day);
|
||||
return CzgResult.success(data);
|
||||
}
|
||||
|
||||
@@ -96,13 +105,12 @@ public class DataSummaryController {
|
||||
*/
|
||||
@GetMapping("datePayType")
|
||||
@OperationLog("支付占比饼图 左下")
|
||||
// @SaStaffCheckPermission("yun_xu_cha_kan_jing_ying_shu_ju")
|
||||
@SaAdminCheckPermission(value = "dataSummary:datePayType", name = "支付占比饼图 左下2")
|
||||
public CzgResult<DataSummaryPayTypeVo> shopSummaryPayType(@RequestParam Integer day, @RequestParam(required = false) Long shopId) {
|
||||
public CzgResult<List<CountPayTypeVo>> shopSummaryPayType(@RequestParam Integer day, @RequestParam(required = false) Long shopId) {
|
||||
if (shopId == null) {
|
||||
shopId = StpKit.USER.getShopId(0L);
|
||||
shopId = StpKit.USER.getShopId();
|
||||
}
|
||||
DataSummaryPayTypeVo data = dataSummaryService.getSummaryPayTypeData(shopId, day);
|
||||
List<CountPayTypeVo> data = orderStatisticService.getSummaryPayTypeData(shopId, day);
|
||||
return CzgResult.success(data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
package com.czg.controller.admin;
|
||||
|
||||
import com.czg.log.annotation.OperationLog;
|
||||
import com.czg.order.entity.ShopProdStatistic;
|
||||
import com.czg.order.param.SaleSummaryCountParam;
|
||||
import com.czg.order.service.SaleSummaryService;
|
||||
import com.czg.order.service.ShopProdStatisticService;
|
||||
import com.czg.order.vo.SaleSummaryCountVo;
|
||||
import com.czg.order.vo.SaleSummaryInfoVo;
|
||||
import com.czg.resp.CzgResult;
|
||||
import com.czg.sa.StpKit;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
import com.pig4cloud.plugin.excel.annotation.ResponseExcel;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
@@ -28,7 +27,8 @@ import java.util.List;
|
||||
@RestController
|
||||
@RequestMapping("/admin/sale/summary")
|
||||
public class SaleSummaryController {
|
||||
private final SaleSummaryService saleSummaryService;
|
||||
@Resource
|
||||
private ShopProdStatisticService prodStatisticService;
|
||||
|
||||
/**
|
||||
* 统计
|
||||
@@ -37,11 +37,12 @@ public class SaleSummaryController {
|
||||
@OperationLog("统计")
|
||||
//@SaAdminCheckPermission("saleSummary:count")
|
||||
public CzgResult<SaleSummaryCountVo> summaryCount(SaleSummaryCountParam param) {
|
||||
Long shopId = StpKit.USER.getShopId(0L);
|
||||
Long shopId = StpKit.USER.getShopId();
|
||||
if (param.getShopId() == null) {
|
||||
param.setShopId(shopId);
|
||||
}
|
||||
SaleSummaryCountVo data = saleSummaryService.summaryCount(param);
|
||||
SaleSummaryCountVo data = prodStatisticService.summaryCount(
|
||||
param.getShopId(), param.getProductName(), param.getRangeType(), param.getBeginDate(), param.getEndDate());
|
||||
return CzgResult.success(data);
|
||||
}
|
||||
|
||||
@@ -51,28 +52,14 @@ public class SaleSummaryController {
|
||||
@GetMapping("page")
|
||||
@OperationLog("分页")
|
||||
//@SaAdminCheckPermission("saleSummary:page")
|
||||
public CzgResult<Page<SaleSummaryInfoVo>> summaryPage(SaleSummaryCountParam param) {
|
||||
Long shopId = StpKit.USER.getShopId(0L);
|
||||
public CzgResult<List<ShopProdStatistic>> summaryPage(SaleSummaryCountParam param) {
|
||||
Long shopId = StpKit.USER.getShopId();
|
||||
if (param.getShopId() == null) {
|
||||
param.setShopId(shopId);
|
||||
}
|
||||
Page<SaleSummaryInfoVo> page = saleSummaryService.summaryPage(param);
|
||||
return CzgResult.success(page);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出
|
||||
*/
|
||||
@ResponseExcel(name = "销售统计明细")
|
||||
@GetMapping("/export")
|
||||
@OperationLog("导出")
|
||||
//@SaAdminCheckPermission("saleSummary:export")
|
||||
public List<SaleSummaryInfoVo> summaryExport(SaleSummaryCountParam param) {
|
||||
Long shopId = StpKit.USER.getShopId(0L);
|
||||
if (param.getShopId() == null) {
|
||||
param.setShopId(shopId);
|
||||
}
|
||||
return saleSummaryService.summaryList(param);
|
||||
List<ShopProdStatistic> list = prodStatisticService.getArchiveTradeData(
|
||||
param.getShopId(),param.getProductName(), param.getRangeType(), param.getBeginDate(), param.getEndDate());
|
||||
return CzgResult.success(list);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,13 +3,16 @@ package com.czg.controller.admin;
|
||||
import com.czg.handel.ExcelMergeHandler;
|
||||
import com.czg.handel.TableRefundCellHandel;
|
||||
import com.czg.log.annotation.OperationLog;
|
||||
import com.czg.order.entity.ShopTableOrderStatistic;
|
||||
import com.czg.order.param.DataSummaryTradeParam;
|
||||
import com.czg.order.param.TableSummaryParam;
|
||||
import com.czg.order.service.ShopTableOrderStatisticService;
|
||||
import com.czg.order.service.TableSummaryService;
|
||||
import com.czg.order.vo.TableSummaryExportVo;
|
||||
import com.czg.order.vo.TableSummaryInfoVo;
|
||||
import com.czg.resp.CzgResult;
|
||||
import com.czg.sa.StpKit;
|
||||
import com.pig4cloud.plugin.excel.annotation.ResponseExcel;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
@@ -29,19 +32,22 @@ import java.util.List;
|
||||
public class TableSummaryController {
|
||||
private final TableSummaryService tableSummaryService;
|
||||
|
||||
@Resource
|
||||
private ShopTableOrderStatisticService tableOrderStatisticService;
|
||||
|
||||
/**
|
||||
* 统计
|
||||
*/
|
||||
@GetMapping("list")
|
||||
@OperationLog("统计")
|
||||
//@SaAdminCheckPermission("tableSummary:list")
|
||||
public CzgResult<List<TableSummaryInfoVo>> summaryList(TableSummaryParam param) {
|
||||
Long shopId = StpKit.USER.getShopId(0L);
|
||||
public CzgResult<List<ShopTableOrderStatistic>> summaryList(DataSummaryTradeParam param) {
|
||||
Long shopId = StpKit.USER.getShopId();
|
||||
if (param.getShopId() == null) {
|
||||
param.setShopId(shopId);
|
||||
}
|
||||
List<TableSummaryInfoVo> data = tableSummaryService.summaryList(param);
|
||||
return CzgResult.success(data);
|
||||
List<ShopTableOrderStatistic> archiveTradeData = tableOrderStatisticService.getArchiveTradeData(param.getShopId(), param.getRangeType(), param.getBeginDate(), param.getEndDate());
|
||||
return CzgResult.success(archiveTradeData);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,21 +1,14 @@
|
||||
package com.czg.task;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.czg.order.entity.ShopOrderStatistic;
|
||||
import com.czg.order.entity.ShopProdStatistic;
|
||||
import com.czg.order.entity.ShopTableOrderStatistic;
|
||||
import com.czg.account.service.ShopInfoService;
|
||||
import com.czg.order.service.ShopOrderStatisticService;
|
||||
import com.czg.order.service.ShopProdStatisticService;
|
||||
import com.czg.order.service.ShopTableOrderStatisticService;
|
||||
import com.czg.service.order.mapper.ShopOrderStatisticMapper;
|
||||
import com.czg.service.order.mapper.ShopProdStatisticMapper;
|
||||
import com.czg.service.order.mapper.ShopTableOrderStatisticMapper;
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
import com.mybatisflex.core.row.DbChain;
|
||||
import com.czg.service.RedisService;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.dubbo.config.annotation.DubboReference;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -28,87 +21,73 @@ import java.util.List;
|
||||
@Component
|
||||
@Slf4j
|
||||
public class StatisticTask {
|
||||
@DubboReference
|
||||
private ShopInfoService shopInfoService;
|
||||
|
||||
@Resource
|
||||
private ShopOrderStatisticService orderStatisticService;
|
||||
@Resource
|
||||
private RedisService redisService;
|
||||
@Resource
|
||||
private ShopTableOrderStatisticService shopTableOrderStatisticService;
|
||||
@Resource
|
||||
private ShopProdStatisticService shopProdStatisticService;
|
||||
@Resource
|
||||
private ShopOrderStatisticService shopOrderStatisticService;
|
||||
@Resource
|
||||
private ShopOrderStatisticMapper shopOrderStatisticMapper;
|
||||
@Resource
|
||||
private ShopProdStatisticMapper shopProdStatisticMapper;
|
||||
@Resource
|
||||
private ShopTableOrderStatisticMapper shopTableOrderStatisticMapper;
|
||||
|
||||
|
||||
//每天 00点15分 执行 开始统计数据
|
||||
@Scheduled(cron = "0 15 0 * * ? ")
|
||||
public void run() {
|
||||
log.info("统计数据,定时任务执行");
|
||||
long start = System.currentTimeMillis();
|
||||
// 获取前一天
|
||||
LocalDate yesterday = LocalDate.now().minusDays(1);
|
||||
baseStatistic(yesterday);
|
||||
log.info("统计数据,定时任务执行完毕,耗时:{}ms", start - System.currentTimeMillis());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 基础统计
|
||||
*
|
||||
* @param dateTime 日期时间
|
||||
* @param date 日期yyyy-MM-dd
|
||||
*/
|
||||
private void baseStatistic(DateTime dateTime) {
|
||||
try {
|
||||
shopOrderStatisticService.statistic(dateTime);
|
||||
} catch (Exception e) {
|
||||
log.error("统计订单数据失败", e);
|
||||
private void baseStatistic(LocalDate date) {
|
||||
List<Long> shopIdList = shopInfoService.getShopIdList();
|
||||
if (CollUtil.isEmpty(shopIdList)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
shopProdStatisticService.statistic(dateTime);
|
||||
} catch (Exception e) {
|
||||
log.error("统计商品数据失败", e);
|
||||
redisService.set("task:statistic:date:", "");
|
||||
for (Long shopId : shopIdList) {
|
||||
statisticAndInsertOrder(shopId, date);
|
||||
statisticAndInsertProd(shopId, date);
|
||||
statisticAndInsertTable(shopId, date);
|
||||
}
|
||||
redisService.del("task:statistic:date:");
|
||||
}
|
||||
|
||||
public void statisticAndInsertOrder(Long shopId, LocalDate date) {
|
||||
try {
|
||||
shopTableOrderStatisticService.statistic(dateTime);
|
||||
orderStatisticService.statisticAndInsert(shopId, date);
|
||||
} catch (Exception e) {
|
||||
log.error("统计桌台数据失败", e);
|
||||
log.error("统计订单数据失败,店铺id:{},日期:{}", shopId, date, e);
|
||||
}
|
||||
}
|
||||
|
||||
// @Scheduled(cron = "1/6 * * * * ? ")
|
||||
@Scheduled(cron = "0 0 8 * * ?")
|
||||
public void run() {
|
||||
long start = System.currentTimeMillis();
|
||||
log.info("定时任务执行,开始统计数据");
|
||||
// 获取前一天
|
||||
DateTime yesterday = DateUtil.yesterday();
|
||||
baseStatistic(yesterday);
|
||||
log.info("定时任务执行完毕,耗时:{}ms", start - System.currentTimeMillis());
|
||||
public void statisticAndInsertProd(Long shopId, LocalDate date) {
|
||||
try {
|
||||
shopProdStatisticService.statisticAndInsert(shopId, date);
|
||||
} catch (Exception e) {
|
||||
log.error("统计商品数据失败,店铺id:{},日期:{}", shopId, date, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Scheduled(cron = "0 0,15,30,45 * * * ? ")
|
||||
public void run2() {
|
||||
long start = System.currentTimeMillis();
|
||||
log.info("定时任务2执行,开始统计数据");
|
||||
// 获取当天
|
||||
DateTime today = DateUtil.date();
|
||||
baseStatistic(today);
|
||||
log.info("定时任务2执行完毕,耗时:{}ms", start - System.currentTimeMillis());
|
||||
public void statisticAndInsertTable(Long shopId, LocalDate date) {
|
||||
try {
|
||||
shopTableOrderStatisticService.statisticAndInsert(shopId, date);
|
||||
} catch (Exception e) {
|
||||
log.error("统计桌台数据失败,店铺id:{},日期:{}", shopId, date, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 统计历史数据
|
||||
*/
|
||||
public void statisticHistoryData() {
|
||||
// 指定开始日期
|
||||
LocalDate startDate = LocalDate.of(2024, 3, 1);
|
||||
// 指定结束日期
|
||||
LocalDate endDate = LocalDate.now();
|
||||
List<Long> shopIdList = DbChain.table("tb_shop_info").select("id").objListAs(Long.class);
|
||||
List<List<Long>> split = CollUtil.split(shopIdList, 10);
|
||||
// 1.清除历史统计的数据
|
||||
for (List<Long> splitIdList : split) {
|
||||
splitIdList.parallelStream().forEach(shopId -> {
|
||||
shopOrderStatisticMapper.deleteByQuery(QueryWrapper.create().eq(ShopOrderStatistic::getShopId, shopId));
|
||||
shopProdStatisticMapper.deleteByQuery(QueryWrapper.create().eq(ShopProdStatistic::getShopId, shopId));
|
||||
shopTableOrderStatisticMapper.deleteByQuery(QueryWrapper.create().eq(ShopTableOrderStatistic::getShopId, shopId));
|
||||
});
|
||||
}
|
||||
// 2.开始从2024-3-1开始统计数据
|
||||
startDate.datesUntil(endDate.plusDays(1)).forEach(date -> {
|
||||
System.out.println(date.toString());
|
||||
DateTime dateTime = DateUtil.parseDate(date.toString());
|
||||
System.out.println(dateTime);
|
||||
baseStatistic(dateTime);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ public class OrderDetailDTO implements Serializable {
|
||||
private String discountSaleNote;
|
||||
|
||||
/**
|
||||
* 状态: wait-pay 待支付;in-production 制作中;wait-out 待取餐;refunding 退款中; part-refund 部分退单; refund-退单; done 完成;
|
||||
* 状态: wait-pay 待支付;in-production 制作中;wait_out 待取餐;refunding 退款中; part_refund 部分退单; refund-退单; done 完成;
|
||||
*/
|
||||
private String status;
|
||||
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
package com.czg.account.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.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 实体类。
|
||||
*
|
||||
* @author zs
|
||||
* @since 2025-03-06
|
||||
*/
|
||||
@Data
|
||||
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table("tb_shop_prod_statistic")
|
||||
public class ShopProdStatistic implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Id(keyType = KeyType.Auto)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 商品id
|
||||
*/
|
||||
private Long prodId;
|
||||
|
||||
/**
|
||||
* 销售数量
|
||||
*/
|
||||
private Long saleNum;
|
||||
|
||||
/**
|
||||
* 销售金额
|
||||
*/
|
||||
private BigDecimal saleAmount;
|
||||
|
||||
/**
|
||||
* 退单量
|
||||
*/
|
||||
private Long refundNum;
|
||||
|
||||
/**
|
||||
* 退单金额
|
||||
*/
|
||||
private BigDecimal refundAmount;
|
||||
|
||||
/**
|
||||
* 店铺id
|
||||
*/
|
||||
private Long shopId;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createDay;
|
||||
|
||||
}
|
||||
@@ -16,6 +16,7 @@ import java.util.List;
|
||||
*/
|
||||
public interface ShopInfoService extends IService<ShopInfo> {
|
||||
|
||||
@Override
|
||||
ShopInfo getById(Serializable id) throws CzgException;
|
||||
Page<ShopInfo> get(PageDTO pageDTO, String shopName, Integer status, Integer isHeadShop);
|
||||
|
||||
@@ -40,4 +41,11 @@ public interface ShopInfoService extends IService<ShopInfo> {
|
||||
List<ShopInfo> getByMainIdOrList(Long mainShopId, List<Long> shopIdList, String shopName);
|
||||
|
||||
BigDecimal updateAmount(Long id, BigDecimal amount);
|
||||
|
||||
/**
|
||||
* 获取所有未删除的 过期时间>三天前 店铺id列表
|
||||
*
|
||||
* @return 店铺id列表
|
||||
*/
|
||||
List<Long> getShopIdList();
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
package com.czg.account.service;
|
||||
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
import com.mybatisflex.core.service.IService;
|
||||
import com.czg.account.entity.ShopProdStatistic;
|
||||
|
||||
/**
|
||||
* 服务层。
|
||||
*
|
||||
* @author zs
|
||||
* @since 2025-03-06
|
||||
*/
|
||||
public interface ShopProdStatisticService extends IService<ShopProdStatistic> {
|
||||
|
||||
Page<?> pageInfo(Long shopId, String name, String classifyId, String startTime, String endTime);
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
//package com.czg.account.service;
|
||||
//
|
||||
//import com.czg.account.dto.ShopShareDTO;
|
||||
//import com.czg.account.vo.ShopShareRecordVO;
|
||||
//import com.czg.account.vo.ShopShareVO;
|
||||
//import com.mybatisflex.core.paginate.Page;
|
||||
//import com.mybatisflex.core.service.IService;
|
||||
//import com.czg.account.entity.ShopShare;
|
||||
//
|
||||
///**
|
||||
// * 店铺分享 服务层。
|
||||
// *
|
||||
// * @author zs
|
||||
// * @since 2025-03-05
|
||||
// */
|
||||
//public interface ShopShareService extends IService<ShopShare> {
|
||||
//
|
||||
// ShopShareVO get(Long shopId);
|
||||
//
|
||||
// Boolean add(Long shopId, ShopShareDTO shopShareDTO);
|
||||
//
|
||||
// Page<ShopShareRecordVO> recordPage(Long shopId, String key, Integer status);
|
||||
//}
|
||||
@@ -1,14 +0,0 @@
|
||||
package com.czg.account.vo;
|
||||
|
||||
import com.czg.account.entity.ShopProdStatistic;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class ShopProdStatisticVO extends ShopProdStatistic {
|
||||
private String name;
|
||||
}
|
||||
@@ -63,6 +63,10 @@ public class OrderInfoDTO implements Serializable {
|
||||
* 抹零金额 减免多少钱
|
||||
*/
|
||||
private BigDecimal roundAmount;
|
||||
/**
|
||||
* 优惠总金额
|
||||
*/
|
||||
private BigDecimal discountAllAmount;
|
||||
|
||||
/**
|
||||
* 订单金额 (扣除各类折扣)
|
||||
@@ -104,10 +108,10 @@ public class OrderInfoDTO implements Serializable {
|
||||
*/
|
||||
private BigDecimal discountAmount;
|
||||
|
||||
/**
|
||||
* 折扣比例
|
||||
*/
|
||||
private BigDecimal discountRatio;
|
||||
// /**
|
||||
// * 折扣比例
|
||||
// */
|
||||
// private BigDecimal discountRatio;
|
||||
|
||||
/**
|
||||
* 打包费
|
||||
@@ -161,7 +165,7 @@ public class OrderInfoDTO implements Serializable {
|
||||
private String payType;
|
||||
|
||||
/**
|
||||
* 状态: unpaid-待支付;in-production 制作中;wait-out 待取餐;;done-订单完成;refunding-申请退单;refund-退单;part-refund 部分退单;cancelled-取消订单
|
||||
* 状态: unpaid-待支付;in-production 制作中;wait_out 待取餐;;done-订单完成;refunding-申请退单;refund-退单;part_refund 部分退单;cancelled-取消订单
|
||||
*/
|
||||
private String status;
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ public class OrderInfoQueryDTO implements Serializable {
|
||||
|
||||
|
||||
/**
|
||||
* 状态: unpaid-待支付;in-production 制作中;wait-out 待取餐;;done-订单完成;refunding-申请退单;refund-退单;part-refund 部分退单;cancelled-取消订单
|
||||
* 状态: unpaid-待支付;in-production 制作中;wait_out 待取餐;;done-订单完成;refunding-申请退单;refund-退单;part_refund 部分退单;cancelled-取消订单
|
||||
*/
|
||||
private String status;
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ public class OrderDetail implements Serializable {
|
||||
private String discountSaleNote;
|
||||
|
||||
/**
|
||||
* 状态: in-production 制作中;wait-out 待取餐;refunding 退款中; part-refund 部分退单; refund-退单; done 完成;
|
||||
* 状态: in-production 制作中;wait_out 待取餐;refunding 退款中; part_refund 部分退单; refund-退单; done 完成;
|
||||
*/
|
||||
private String status;
|
||||
|
||||
|
||||
@@ -73,6 +73,10 @@ public class OrderInfo implements Serializable {
|
||||
* 订单金额 (扣除各类折扣)
|
||||
*/
|
||||
private BigDecimal orderAmount;
|
||||
/**
|
||||
* 优惠总金额
|
||||
*/
|
||||
private BigDecimal discountAllAmount;
|
||||
|
||||
/**
|
||||
* 实际支付金额
|
||||
@@ -122,10 +126,10 @@ public class OrderInfo implements Serializable {
|
||||
*/
|
||||
private BigDecimal discountAmount;
|
||||
|
||||
/**
|
||||
* 折扣比例
|
||||
*/
|
||||
private BigDecimal discountRatio;
|
||||
// /**
|
||||
// * 折扣比例
|
||||
// */
|
||||
// private BigDecimal discountRatio;
|
||||
|
||||
/**
|
||||
* 打包费
|
||||
@@ -186,7 +190,7 @@ public class OrderInfo implements Serializable {
|
||||
|
||||
/**
|
||||
* {@link com.czg.service.order.enums.OrderStatusEnums}
|
||||
* 状态: unpaid-待支付;in-production 制作中;wait-out 待取餐;;done-订单完成;refunding-申请退单;refund-退单;part-refund 部分退单;cancelled-取消订单
|
||||
* 状态: unpaid-待支付;in-production 制作中;wait_out 待取餐;;done-订单完成;refunding-申请退单;refund-退单;part_refund 部分退单;cancelled-取消订单
|
||||
*/
|
||||
private String status;
|
||||
|
||||
@@ -319,4 +323,21 @@ public class OrderInfo implements Serializable {
|
||||
public BigDecimal getPackFee() {
|
||||
return packFee == null ? BigDecimal.ZERO : packFee;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 计算并设置所有优惠金额的总和
|
||||
*/
|
||||
public void initDiscountAllAmount() {
|
||||
this.discountAllAmount = BigDecimal.ZERO
|
||||
.add(this.getProductCouponDiscountAmount() != null ? this.getProductCouponDiscountAmount() : BigDecimal.ZERO)
|
||||
.add(this.getOtherCouponDiscountAmount() != null ? this.getOtherCouponDiscountAmount() : BigDecimal.ZERO)
|
||||
.add(this.getPointsDiscountAmount() != null ? this.getPointsDiscountAmount() : BigDecimal.ZERO)
|
||||
.add(this.getNewCustomerDiscountAmount() != null ? this.getNewCustomerDiscountAmount() : BigDecimal.ZERO)
|
||||
.add(this.getDiscountAmount() != null ? this.getDiscountAmount() : BigDecimal.ZERO)
|
||||
.add(this.getDiscountActAmount() != null ? this.getDiscountActAmount() : BigDecimal.ZERO)
|
||||
.add(this.getVipDiscountAmount() != null ? this.getVipDiscountAmount() : BigDecimal.ZERO);
|
||||
// 如果需要加上抹零金额,可以取消下面这行注释
|
||||
// .add(this.getRoundAmount() != null ? this.getRoundAmount() : BigDecimal.ZERO);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package com.czg.order.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 lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@@ -15,13 +16,13 @@ import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 实体类。
|
||||
* 店铺订单统计报表 实体类。
|
||||
*
|
||||
* @author zs
|
||||
* @since 2025-03-07
|
||||
* @author ww
|
||||
* @since 2025-11-20
|
||||
*/
|
||||
@Data
|
||||
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table("tb_shop_order_statistic")
|
||||
@@ -30,151 +31,469 @@ public class ShopOrderStatistic implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 检查订单统计数据是否有效
|
||||
*
|
||||
* @param stat 订单统计数据
|
||||
* @return 是否有效
|
||||
*/
|
||||
public boolean hasValidData(ShopOrderStatistic stat) {
|
||||
if (stat == null) {
|
||||
return false;
|
||||
}
|
||||
// 检查BigDecimal类型字段 检查Long类型字段
|
||||
return checkBigDecimalFields(stat) && checkLongFields(stat);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* 初始化空白数据 标识为 无效数据 valid = false
|
||||
*/
|
||||
public void init() {
|
||||
this.valid = false;
|
||||
this.originAmount = zero;
|
||||
this.payAmount = zero;
|
||||
this.refundAmount = zero;
|
||||
this.onlineRefundAmount = zero;
|
||||
this.cashRefundAmount = zero;
|
||||
this.memberRefundAmount = zero;
|
||||
this.memberPayAmount = zero;
|
||||
this.memberPayCount = 0L;
|
||||
this.rechargeAmount = zero;
|
||||
this.onlineRechargeAmount = zero;
|
||||
this.cashRechargeAmount = zero;
|
||||
this.giveAmount = zero;
|
||||
this.rechargeRefundAmount = zero;
|
||||
this.onlineRechargeRefundAmount = zero;
|
||||
this.cashRechargeRefundAmount = zero;
|
||||
this.newMemberCount = 0L;
|
||||
this.customerCount = 0L;
|
||||
this.orderCount = 0L;
|
||||
this.tableCount = 0L;
|
||||
this.avgPayAmount = zero;
|
||||
this.turnoverRate = zero;
|
||||
this.profitAmount = zero;
|
||||
this.productCostAmount = zero;
|
||||
this.profitRate = zero;
|
||||
this.netProfitAmount = zero;
|
||||
this.netProfitRate = zero;
|
||||
this.discountAmount = zero;
|
||||
this.discountCount = 0L;
|
||||
this.newCustomerDiscountAmount = zero;
|
||||
this.fullDiscountAmount = zero;
|
||||
this.couponDiscountAmount = zero;
|
||||
this.pointDiscountAmount = zero;
|
||||
this.backDiscountAmount = zero;
|
||||
this.memberDiscountAmount = zero;
|
||||
this.orderPriceDiscountAmount = zero;
|
||||
this.onlinePayAmount = zero;
|
||||
this.cashPayAmount = zero;
|
||||
this.wechatPayAmount = zero;
|
||||
this.alipayPayAmount = zero;
|
||||
this.backScanPayAmount = zero;
|
||||
this.mainScanPayAmount = zero;
|
||||
this.creditPayAmount = zero;
|
||||
this.cashPayCount = 0L;
|
||||
this.wechatPayCount = 0L;
|
||||
this.alipayPayCount = 0L;
|
||||
this.backScanPayCount = 0L;
|
||||
this.mainScanPayCount = 0L;
|
||||
this.creditPayCount = 0L;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
@Id(keyType = KeyType.Auto)
|
||||
private Integer id;
|
||||
|
||||
/**
|
||||
* 销售额
|
||||
* 店铺id
|
||||
*/
|
||||
private BigDecimal saleAmount = BigDecimal.ZERO;
|
||||
private Long shopId;
|
||||
/**
|
||||
* 统计日期 yyyy-MM-dd
|
||||
*/
|
||||
private LocalDate statisticDate;
|
||||
//*********************以下为订单金额********************************************************************************
|
||||
|
||||
/**
|
||||
* 销售数量
|
||||
* 订单金额 订单原金额
|
||||
*/
|
||||
private Long saleCount = 0L;
|
||||
private BigDecimal originAmount;
|
||||
/**
|
||||
* 实付金额 (线上付款 现金支付 会员支付 挂账)
|
||||
*/
|
||||
private BigDecimal payAmount;
|
||||
/**
|
||||
* 线上付款金额
|
||||
*/
|
||||
private BigDecimal onlinePayAmount;
|
||||
/**
|
||||
* 订单退款 退款金额(原路返回 现金退款)
|
||||
*/
|
||||
private BigDecimal refundAmount;
|
||||
/**
|
||||
* 订单退款 线上退款金额
|
||||
*/
|
||||
private BigDecimal onlineRefundAmount;
|
||||
/**
|
||||
* 订单退款 线下退款金额/现金退款金额
|
||||
*/
|
||||
private BigDecimal cashRefundAmount;
|
||||
/**
|
||||
* 订单退款 会员退款金额
|
||||
*/
|
||||
private BigDecimal memberRefundAmount;
|
||||
|
||||
/**
|
||||
* 优惠金额
|
||||
* 会员消费 会员订单支付金额
|
||||
*/
|
||||
private BigDecimal discountAmount = BigDecimal.ZERO;
|
||||
private BigDecimal memberPayAmount;
|
||||
/**
|
||||
* 会员消费笔数
|
||||
*/
|
||||
private Long memberPayCount;
|
||||
|
||||
|
||||
//*********************以下为充值金额********************************************************************************
|
||||
/**
|
||||
* 会员充值 充值金额(包含现金支付) 不包括赠送 多店 按 主店算
|
||||
*/
|
||||
private BigDecimal rechargeAmount;
|
||||
/**
|
||||
* 会员充值 线上充值金额
|
||||
*/
|
||||
private BigDecimal onlineRechargeAmount;
|
||||
/**
|
||||
* 会员充值 现金充值金额
|
||||
*/
|
||||
private BigDecimal cashRechargeAmount;
|
||||
/**
|
||||
* 会员充值 充值赠送金额
|
||||
*/
|
||||
private BigDecimal giveAmount;
|
||||
|
||||
/**
|
||||
* 优惠笔数
|
||||
* 会员充值退款 充值退款金额(线上退款+现金退款)
|
||||
*/
|
||||
private Long discountCount = 0L;
|
||||
|
||||
private BigDecimal rechargeRefundAmount;
|
||||
/**
|
||||
* 退款金额
|
||||
* 会员充值退款 线上退款
|
||||
*/
|
||||
private BigDecimal refundAmount = BigDecimal.ZERO;
|
||||
|
||||
private BigDecimal onlineRechargeRefundAmount;
|
||||
/**
|
||||
* 退款笔数
|
||||
* 会员充值退款 现金退款金额
|
||||
*/
|
||||
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 backScanPayCount = 0L;
|
||||
|
||||
/**
|
||||
* 被扫支付金额
|
||||
*/
|
||||
private BigDecimal backScanPayAmount = BigDecimal.ZERO;
|
||||
|
||||
/**
|
||||
* 被扫支付笔数
|
||||
*/
|
||||
private Long h5PayCount = 0L;
|
||||
|
||||
/**
|
||||
* 被扫支付金额
|
||||
*/
|
||||
private BigDecimal h5PayAmount = BigDecimal.ZERO;
|
||||
|
||||
/**
|
||||
* 现金支付笔数
|
||||
*/
|
||||
private Long cashPayCount = 0L;
|
||||
/**
|
||||
* 现金支付金额
|
||||
*/
|
||||
private BigDecimal cashPayAmount = BigDecimal.ZERO;
|
||||
/**
|
||||
* 充值金额
|
||||
*/
|
||||
private BigDecimal rechargeAmount = BigDecimal.ZERO;
|
||||
/**
|
||||
* 充值退款金额
|
||||
*/
|
||||
private BigDecimal rechargeRefundAmount = BigDecimal.ZERO;
|
||||
/**
|
||||
* 客单价
|
||||
*/
|
||||
private BigDecimal customerUnitPrice = BigDecimal.ZERO;
|
||||
/**
|
||||
* 翻台率
|
||||
*/
|
||||
private BigDecimal tableTurnoverRate = BigDecimal.ZERO;
|
||||
private BigDecimal cashRechargeRefundAmount;
|
||||
/**
|
||||
* 新增会员数
|
||||
*/
|
||||
private Long newMemberCount = 0L;
|
||||
private Long newMemberCount;
|
||||
|
||||
|
||||
//*********************以下为客单价 翻台率 的计算********************************************************************************
|
||||
/**
|
||||
* 店铺id
|
||||
* 就餐人数
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
private Long shopId;
|
||||
private Long customerCount;
|
||||
/**
|
||||
* 订单数
|
||||
*/
|
||||
private Long orderCount;
|
||||
/**
|
||||
* 桌台数
|
||||
*/
|
||||
private Long tableCount;
|
||||
/**
|
||||
* 客单价
|
||||
* 实付金额(包含现金支付 包含会员支付 包含挂账)/就餐人数
|
||||
* 没有具体人数时,默认一桌按照1人计算
|
||||
*/
|
||||
private BigDecimal avgPayAmount;
|
||||
/**
|
||||
* 翻台率
|
||||
* (订单数-桌台数)/桌台数*100%
|
||||
*/
|
||||
private BigDecimal turnoverRate;
|
||||
|
||||
/**
|
||||
* 毛利润(订单实付金额-商品成本)
|
||||
*/
|
||||
private BigDecimal profitAmount;
|
||||
/**
|
||||
* 商品成本
|
||||
*/
|
||||
private BigDecimal productCostAmount;
|
||||
/**
|
||||
* 毛利率(订单实付金额-商品成本)/订单实付金额*100%
|
||||
*/
|
||||
private BigDecimal profitRate;
|
||||
/**
|
||||
* 净利润
|
||||
*/
|
||||
private BigDecimal netProfitAmount;
|
||||
/**
|
||||
* 净利润率
|
||||
*/
|
||||
private BigDecimal netProfitRate;
|
||||
|
||||
|
||||
//*********************以下为优惠金额********************************************************************************
|
||||
/**
|
||||
* 优惠总金额
|
||||
*/
|
||||
private BigDecimal discountAmount;
|
||||
/**
|
||||
* 优惠笔数
|
||||
*/
|
||||
private Long discountCount;
|
||||
|
||||
/**
|
||||
* 新客立减金额
|
||||
*/
|
||||
private BigDecimal newCustomerDiscountAmount;
|
||||
/**
|
||||
* 满减活动金额
|
||||
*/
|
||||
private BigDecimal fullDiscountAmount;
|
||||
/**
|
||||
* 优惠券抵扣金额
|
||||
*/
|
||||
private BigDecimal couponDiscountAmount;
|
||||
/**
|
||||
* 积分抵扣金额
|
||||
*/
|
||||
private BigDecimal pointDiscountAmount;
|
||||
/**
|
||||
* 霸王餐金额
|
||||
*/
|
||||
private BigDecimal backDiscountAmount;
|
||||
/**
|
||||
* 会员整单折扣金额
|
||||
*/
|
||||
private BigDecimal memberDiscountAmount;
|
||||
/**
|
||||
* 订单改价金额
|
||||
*/
|
||||
private BigDecimal orderPriceDiscountAmount;
|
||||
|
||||
|
||||
//*********************以下为支付金额********************************************************************************
|
||||
/**
|
||||
* 现金支付金额
|
||||
*/
|
||||
private BigDecimal cashPayAmount;
|
||||
/**
|
||||
* 现金支付笔数
|
||||
*/
|
||||
private Long cashPayCount;
|
||||
/**
|
||||
* 微信小程序支付金额
|
||||
*/
|
||||
private BigDecimal wechatPayAmount;
|
||||
/**
|
||||
* 微信小程序支付笔数
|
||||
*/
|
||||
private Long wechatPayCount;
|
||||
/**
|
||||
* 支付宝小程序支付金额
|
||||
*/
|
||||
private BigDecimal alipayPayAmount;
|
||||
/**
|
||||
* 支付宝小程序支付笔数
|
||||
*/
|
||||
private Long alipayPayCount;
|
||||
/**
|
||||
* 被扫收款金额
|
||||
*/
|
||||
private BigDecimal backScanPayAmount;
|
||||
/**
|
||||
* 被扫收款笔数
|
||||
*/
|
||||
private Long backScanPayCount;
|
||||
/**
|
||||
* 主扫收款金额
|
||||
*/
|
||||
private BigDecimal mainScanPayAmount;
|
||||
/**
|
||||
* 主扫收款笔数
|
||||
*/
|
||||
private Long mainScanPayCount;
|
||||
/**
|
||||
* 挂账支付金额
|
||||
*/
|
||||
private BigDecimal creditPayAmount;
|
||||
/**
|
||||
* 挂账支付笔数
|
||||
*/
|
||||
private Long creditPayCount;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@JSONField(serialize = false, format = "yyyy-MM-dd")
|
||||
private LocalDate createDay;
|
||||
@Column(onInsertValue = "now()")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/**
|
||||
* 最近一次统计时间
|
||||
* 更新时间
|
||||
*/
|
||||
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
||||
@Column(onInsertValue = "now()", onUpdateValue = "now()")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
@Column(ignore = true)
|
||||
BigDecimal zero = BigDecimal.ZERO;
|
||||
|
||||
/**
|
||||
* 是否有效
|
||||
*/
|
||||
@Column(ignore = true)
|
||||
private Boolean valid = true;
|
||||
|
||||
|
||||
private static boolean checkBigDecimalFields(ShopOrderStatistic stat) {
|
||||
return
|
||||
isGreaterThanZero(stat.getOriginAmount()) ||
|
||||
isGreaterThanZero(stat.getPayAmount()) ||
|
||||
isGreaterThanZero(stat.getRefundAmount()) ||
|
||||
isGreaterThanZero(stat.getOnlineRefundAmount()) ||
|
||||
isGreaterThanZero(stat.getCashRefundAmount()) ||
|
||||
isGreaterThanZero(stat.getMemberRefundAmount()) ||
|
||||
isGreaterThanZero(stat.getMemberPayAmount()) ||
|
||||
isGreaterThanZero(stat.getRechargeAmount()) ||
|
||||
isGreaterThanZero(stat.getOnlineRechargeAmount()) ||
|
||||
isGreaterThanZero(stat.getCashRechargeAmount()) ||
|
||||
isGreaterThanZero(stat.getGiveAmount()) ||
|
||||
isGreaterThanZero(stat.getRechargeRefundAmount()) ||
|
||||
isGreaterThanZero(stat.getOnlineRechargeRefundAmount()) ||
|
||||
isGreaterThanZero(stat.getCashRechargeRefundAmount()) ||
|
||||
isGreaterThanZero(stat.getAvgPayAmount()) ||
|
||||
isGreaterThanZero(stat.getTurnoverRate()) ||
|
||||
isGreaterThanZero(stat.getProfitAmount()) ||
|
||||
isGreaterThanZero(stat.getProductCostAmount()) ||
|
||||
isGreaterThanZero(stat.getProfitRate()) ||
|
||||
isGreaterThanZero(stat.getNetProfitAmount()) ||
|
||||
isGreaterThanZero(stat.getNetProfitRate()) ||
|
||||
isGreaterThanZero(stat.getDiscountAmount()) ||
|
||||
isGreaterThanZero(stat.getNewCustomerDiscountAmount()) ||
|
||||
isGreaterThanZero(stat.getFullDiscountAmount()) ||
|
||||
isGreaterThanZero(stat.getCouponDiscountAmount()) ||
|
||||
isGreaterThanZero(stat.getPointDiscountAmount()) ||
|
||||
isGreaterThanZero(stat.getBackDiscountAmount()) ||
|
||||
isGreaterThanZero(stat.getMemberDiscountAmount()) ||
|
||||
isGreaterThanZero(stat.getOrderPriceDiscountAmount()) ||
|
||||
isGreaterThanZero(stat.getOnlinePayAmount()) ||
|
||||
isGreaterThanZero(stat.getCashPayAmount()) ||
|
||||
isGreaterThanZero(stat.getWechatPayAmount()) ||
|
||||
isGreaterThanZero(stat.getAlipayPayAmount()) ||
|
||||
isGreaterThanZero(stat.getBackScanPayAmount()) ||
|
||||
isGreaterThanZero(stat.getMainScanPayAmount()) ||
|
||||
isGreaterThanZero(stat.getCreditPayAmount());
|
||||
}
|
||||
|
||||
private static boolean checkLongFields(ShopOrderStatistic stat) {
|
||||
return (stat.getMemberPayCount() != null && stat.getMemberPayCount() > 0) ||
|
||||
(stat.getNewMemberCount() != null && stat.getNewMemberCount() > 0) ||
|
||||
(stat.getCustomerCount() != null && stat.getCustomerCount() > 0) ||
|
||||
(stat.getOrderCount() != null && stat.getOrderCount() > 0) ||
|
||||
(stat.getTableCount() != null && stat.getTableCount() > 0) ||
|
||||
(stat.getDiscountCount() != null && stat.getDiscountCount() > 0) ||
|
||||
(stat.getCashPayCount() != null && stat.getCashPayCount() > 0) ||
|
||||
(stat.getWechatPayCount() != null && stat.getWechatPayCount() > 0) ||
|
||||
(stat.getAlipayPayCount() != null && stat.getAlipayPayCount() > 0) ||
|
||||
(stat.getBackScanPayCount() != null && stat.getBackScanPayCount() > 0) ||
|
||||
(stat.getMainScanPayCount() != null && stat.getMainScanPayCount() > 0) ||
|
||||
(stat.getCreditPayCount() != null && stat.getCreditPayCount() > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 合并两个统计对象
|
||||
*/
|
||||
public static ShopOrderStatistic mergeStatistics(ShopOrderStatistic stat1, ShopOrderStatistic stat2) {
|
||||
if (stat2 == null) return stat1;
|
||||
if (stat1 == null) return stat2;
|
||||
|
||||
if(!stat2.getValid()) return stat1;
|
||||
if(!stat1.getValid()) return stat2;
|
||||
|
||||
ShopOrderStatistic result = new ShopOrderStatistic();
|
||||
|
||||
// 合并BigDecimal字段
|
||||
result.setOriginAmount(safeAdd(stat1.getOriginAmount(), stat2.getOriginAmount()));
|
||||
result.setPayAmount(safeAdd(stat1.getPayAmount(), stat2.getPayAmount()));
|
||||
result.setRefundAmount(safeAdd(stat1.getRefundAmount(), stat2.getRefundAmount()));
|
||||
result.setOnlineRefundAmount(safeAdd(stat1.getOnlineRefundAmount(), stat2.getOnlineRefundAmount()));
|
||||
result.setCashRefundAmount(safeAdd(stat1.getCashRefundAmount(), stat2.getCashRefundAmount()));
|
||||
result.setMemberRefundAmount(safeAdd(stat1.getMemberRefundAmount(), stat2.getMemberRefundAmount()));
|
||||
result.setMemberPayAmount(safeAdd(stat1.getMemberPayAmount(), stat2.getMemberPayAmount()));
|
||||
result.setRechargeAmount(safeAdd(stat1.getRechargeAmount(), stat2.getRechargeAmount()));
|
||||
result.setOnlineRechargeAmount(safeAdd(stat1.getOnlineRechargeAmount(), stat2.getOnlineRechargeAmount()));
|
||||
result.setCashRechargeAmount(safeAdd(stat1.getCashRechargeAmount(), stat2.getCashRechargeAmount()));
|
||||
result.setGiveAmount(safeAdd(stat1.getGiveAmount(), stat2.getGiveAmount()));
|
||||
result.setRechargeRefundAmount(safeAdd(stat1.getRechargeRefundAmount(), stat2.getRechargeRefundAmount()));
|
||||
result.setOnlineRechargeRefundAmount(safeAdd(stat1.getOnlineRechargeRefundAmount(), stat2.getOnlineRechargeRefundAmount()));
|
||||
result.setCashRechargeRefundAmount(safeAdd(stat1.getCashRechargeRefundAmount(), stat2.getCashRechargeRefundAmount()));
|
||||
result.setAvgPayAmount(safeAdd(stat1.getAvgPayAmount(), stat2.getAvgPayAmount()));
|
||||
result.setTurnoverRate(safeAdd(stat1.getTurnoverRate(), stat2.getTurnoverRate()));
|
||||
result.setProfitAmount(safeAdd(stat1.getProfitAmount(), stat2.getProfitAmount()));
|
||||
result.setProductCostAmount(safeAdd(stat1.getProductCostAmount(), stat2.getProductCostAmount()));
|
||||
result.setProfitRate(safeAdd(stat1.getProfitRate(), stat2.getProfitRate()));
|
||||
result.setNetProfitAmount(safeAdd(stat1.getNetProfitAmount(), stat2.getNetProfitAmount()));
|
||||
result.setNetProfitRate(safeAdd(stat1.getNetProfitRate(), stat2.getNetProfitRate()));
|
||||
result.setDiscountAmount(safeAdd(stat1.getDiscountAmount(), stat2.getDiscountAmount()));
|
||||
result.setNewCustomerDiscountAmount(safeAdd(stat1.getNewCustomerDiscountAmount(), stat2.getNewCustomerDiscountAmount()));
|
||||
result.setFullDiscountAmount(safeAdd(stat1.getFullDiscountAmount(), stat2.getFullDiscountAmount()));
|
||||
result.setCouponDiscountAmount(safeAdd(stat1.getCouponDiscountAmount(), stat2.getCouponDiscountAmount()));
|
||||
result.setPointDiscountAmount(safeAdd(stat1.getPointDiscountAmount(), stat2.getPointDiscountAmount()));
|
||||
result.setBackDiscountAmount(safeAdd(stat1.getBackDiscountAmount(), stat2.getBackDiscountAmount()));
|
||||
result.setMemberDiscountAmount(safeAdd(stat1.getMemberDiscountAmount(), stat2.getMemberDiscountAmount()));
|
||||
result.setOrderPriceDiscountAmount(safeAdd(stat1.getOrderPriceDiscountAmount(), stat2.getOrderPriceDiscountAmount()));
|
||||
result.setOnlinePayAmount(safeAdd(stat1.getOnlinePayAmount(), stat2.getOnlinePayAmount()));
|
||||
result.setCashPayAmount(safeAdd(stat1.getCashPayAmount(), stat2.getCashPayAmount()));
|
||||
result.setWechatPayAmount(safeAdd(stat1.getWechatPayAmount(), stat2.getWechatPayAmount()));
|
||||
result.setAlipayPayAmount(safeAdd(stat1.getAlipayPayAmount(), stat2.getAlipayPayAmount()));
|
||||
result.setBackScanPayAmount(safeAdd(stat1.getBackScanPayAmount(), stat2.getBackScanPayAmount()));
|
||||
result.setMainScanPayAmount(safeAdd(stat1.getMainScanPayAmount(), stat2.getMainScanPayAmount()));
|
||||
result.setCreditPayAmount(safeAdd(stat1.getCreditPayAmount(), stat2.getCreditPayAmount()));
|
||||
|
||||
// 合并Long字段
|
||||
result.setMemberPayCount(safeAdd(stat1.getMemberPayCount(), stat2.getMemberPayCount()));
|
||||
result.setNewMemberCount(safeAdd(stat1.getNewMemberCount(), stat2.getNewMemberCount()));
|
||||
result.setCustomerCount(safeAdd(stat1.getCustomerCount(), stat2.getCustomerCount()));
|
||||
result.setOrderCount(safeAdd(stat1.getOrderCount(), stat2.getOrderCount()));
|
||||
result.setTableCount(safeAdd(stat1.getTableCount(), stat2.getTableCount()));
|
||||
result.setDiscountCount(safeAdd(stat1.getDiscountCount(), stat2.getDiscountCount()));
|
||||
result.setCashPayCount(safeAdd(stat1.getCashPayCount(), stat2.getCashPayCount()));
|
||||
result.setWechatPayCount(safeAdd(stat1.getWechatPayCount(), stat2.getWechatPayCount()));
|
||||
result.setAlipayPayCount(safeAdd(stat1.getAlipayPayCount(), stat2.getAlipayPayCount()));
|
||||
result.setBackScanPayCount(safeAdd(stat1.getBackScanPayCount(), stat2.getBackScanPayCount()));
|
||||
result.setMainScanPayCount(safeAdd(stat1.getMainScanPayCount(), stat2.getMainScanPayCount()));
|
||||
result.setCreditPayCount(safeAdd(stat1.getCreditPayCount(), stat2.getCreditPayCount()));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全的BigDecimal相加
|
||||
*/
|
||||
private static BigDecimal safeAdd(BigDecimal num1, BigDecimal num2) {
|
||||
if (num1 == null) return num2;
|
||||
if (num2 == null) return num1;
|
||||
return num1.add(num2);
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全的Long相加
|
||||
*/
|
||||
private static Long safeAdd(Long num1, Long num2) {
|
||||
if (num1 == null) return num2;
|
||||
if (num2 == null) return num1;
|
||||
return num1 + num2;
|
||||
}
|
||||
|
||||
private static boolean isGreaterThanZero(BigDecimal value) {
|
||||
return value != null && value.compareTo(BigDecimal.ZERO) > 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.czg.order.entity;
|
||||
|
||||
import com.mybatisflex.annotation.Column;
|
||||
import com.mybatisflex.annotation.Id;
|
||||
import com.mybatisflex.annotation.KeyType;
|
||||
import com.mybatisflex.annotation.Table;
|
||||
@@ -35,6 +36,11 @@ public class ShopProdStatistic implements Serializable {
|
||||
* 商品id
|
||||
*/
|
||||
private Long prodId;
|
||||
/**
|
||||
* 商品名称
|
||||
*/
|
||||
@Column(ignore = true)
|
||||
private String productName;
|
||||
|
||||
/**
|
||||
* 销售数量
|
||||
@@ -66,4 +72,25 @@ public class ShopProdStatistic implements Serializable {
|
||||
*/
|
||||
private Date createDay;
|
||||
|
||||
// 在 ShopProdStatistic.java 中添加以下方法
|
||||
/**
|
||||
* 判断当前统计数据是否有效(销售数量、金额,退单数量、金额均有值且大于0)
|
||||
* @return true=有效,false=无效
|
||||
*/
|
||||
public boolean isValid() {
|
||||
// 1. 校验所有字段是否为 null
|
||||
if (saleCount == null || saleAmount == null || refundCount == null || refundAmount == null) {
|
||||
return false;
|
||||
}
|
||||
// 2. 校验所有字段是否大于 0(BigDecimal 需用 compareTo 比较,不能直接用 >)
|
||||
if (saleCount.compareTo(BigDecimal.ZERO) <= 0 ||
|
||||
saleAmount.compareTo(BigDecimal.ZERO) <= 0 ||
|
||||
refundCount.compareTo(BigDecimal.ZERO) <= 0 ||
|
||||
refundAmount.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
return false;
|
||||
}
|
||||
// 3. 所有条件满足,返回 true
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,7 +10,9 @@ import lombok.NoArgsConstructor;
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* 台桌订单统计表 实体类。
|
||||
@@ -18,6 +20,7 @@ import java.util.Date;
|
||||
* @author zs
|
||||
* @since 2025-03-07
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table("tb_shop_table_order_statistic")
|
||||
@@ -74,92 +77,58 @@ public class ShopTableOrderStatistic implements Serializable {
|
||||
private BigDecimal refundAmount;
|
||||
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
/**
|
||||
* 判断是否有有效数据
|
||||
*/
|
||||
public boolean hasValidData() {
|
||||
return (orderCount != null && orderCount > 0) ||
|
||||
(orderAmount != null && orderAmount.compareTo(BigDecimal.ZERO) > 0) ||
|
||||
(refundCount != null && refundCount > 0) ||
|
||||
(refundAmount != null && refundAmount.compareTo(BigDecimal.ZERO) > 0);
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
|
||||
public static List<ShopTableOrderStatistic> mergeWithStream(
|
||||
List<ShopTableOrderStatistic> realTimeData,
|
||||
List<ShopTableOrderStatistic> historyData) {
|
||||
// 最简单的合并方式
|
||||
return Stream.concat(realTimeData.stream(), historyData.stream())
|
||||
.filter(item -> item != null && item.getTableId() != null)
|
||||
.collect(Collectors.toMap(
|
||||
ShopTableOrderStatistic::getTableId,
|
||||
item -> item,
|
||||
(item1, item2) -> {
|
||||
ShopTableOrderStatistic merged = new ShopTableOrderStatistic();
|
||||
merged.setTableId(item1.getTableId());
|
||||
merged.setTableCode(item1.getTableCode());
|
||||
merged.setTableName(item1.getTableName());
|
||||
merged.setAreaName(item1.getAreaName());
|
||||
|
||||
// 数值字段求和
|
||||
merged.setOrderCount(addLong(item1.getOrderCount(), item2.getOrderCount()));
|
||||
merged.setOrderAmount(addBigDecimal(item1.getOrderAmount(), item2.getOrderAmount()));
|
||||
merged.setRefundCount(addLong(item1.getRefundCount(), item2.getRefundCount()));
|
||||
merged.setRefundAmount(addBigDecimal(item1.getRefundAmount(), item2.getRefundAmount()));
|
||||
return merged;
|
||||
}
|
||||
))
|
||||
.values()
|
||||
.stream()
|
||||
.sorted(Comparator.comparing(
|
||||
(ShopTableOrderStatistic item) -> item.getOrderCount() != null ? item.getOrderCount() : 0L,
|
||||
// 降序排列
|
||||
Comparator.reverseOrder()
|
||||
))
|
||||
.toList();
|
||||
}
|
||||
|
||||
public Long getTableId() {
|
||||
return tableId;
|
||||
// 辅助方法
|
||||
private static Long addLong(Long a, Long b) {
|
||||
return (a != null ? a : 0L) + (b != null ? b : 0L);
|
||||
}
|
||||
|
||||
public void setTableId(Long tableId) {
|
||||
this.tableId = tableId;
|
||||
}
|
||||
|
||||
public String getTableCode() {
|
||||
return tableCode;
|
||||
}
|
||||
|
||||
public void setTableCode(String tableCode) {
|
||||
this.tableCode = tableCode;
|
||||
}
|
||||
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
public void setTableName(String tableName) {
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
public String getAreaName() {
|
||||
return areaName;
|
||||
}
|
||||
|
||||
public void setAreaName(String areaName) {
|
||||
this.areaName = areaName;
|
||||
}
|
||||
|
||||
public Long getOrderCount() {
|
||||
return orderCount;
|
||||
}
|
||||
|
||||
public void setOrderCount(Long orderCount) {
|
||||
this.orderCount = orderCount;
|
||||
}
|
||||
|
||||
public BigDecimal getOrderAmount() {
|
||||
return orderAmount;
|
||||
}
|
||||
|
||||
public void setOrderAmount(BigDecimal orderAmount) {
|
||||
this.orderAmount = orderAmount;
|
||||
}
|
||||
|
||||
public Long getShopId() {
|
||||
return shopId;
|
||||
}
|
||||
|
||||
public void setShopId(Long shopId) {
|
||||
this.shopId = shopId;
|
||||
}
|
||||
|
||||
public Date getCreateDay() {
|
||||
return createDay;
|
||||
}
|
||||
|
||||
public void setCreateDay(Date createDay) {
|
||||
this.createDay = createDay;
|
||||
}
|
||||
|
||||
public Long getRefundCount() {
|
||||
return refundCount;
|
||||
}
|
||||
|
||||
public void setRefundCount(Long refundCount) {
|
||||
this.refundCount = refundCount;
|
||||
}
|
||||
|
||||
public BigDecimal getRefundAmount() {
|
||||
return refundAmount;
|
||||
}
|
||||
|
||||
public void setRefundAmount(BigDecimal refundAmount) {
|
||||
this.refundAmount = refundAmount;
|
||||
private static BigDecimal addBigDecimal(BigDecimal a, BigDecimal b) {
|
||||
return (a != null ? a : BigDecimal.ZERO).add(b != null ? b : BigDecimal.ZERO);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,10 @@ public enum PayEnums {
|
||||
* 挂账支付
|
||||
*/
|
||||
CREDIT_PAY("credit_pay", "挂账支付"),
|
||||
/**
|
||||
* 霸王餐支付
|
||||
*/
|
||||
FREE_PAY("free_pay", "霸王餐支付"),
|
||||
/**
|
||||
* h5支付
|
||||
*/
|
||||
@@ -56,12 +60,4 @@ public enum PayEnums {
|
||||
return Arrays.stream(values()).map(PayEnums::getValue).toList();
|
||||
}
|
||||
|
||||
public static String getText(String value) {
|
||||
PayEnums item = Arrays.stream(values()).filter(obj -> value.equals(obj.getValue())).findFirst().orElse(null);
|
||||
if (item != null) {
|
||||
return item.getMsg();
|
||||
}
|
||||
return "未知支付方式";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
package com.czg.order.param;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import com.czg.validator.group.DefaultGroup;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 数据统计-营业-产品销量
|
||||
*
|
||||
* @author tankaikai
|
||||
* @since 2025-03-07 15:35
|
||||
*/
|
||||
@Data
|
||||
public class DataSummaryProductSaleParam implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 天数
|
||||
*/
|
||||
@NotNull(message = "天数不能为空", groups = DefaultGroup.class)
|
||||
private Integer day;
|
||||
/**
|
||||
* 天数列表
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
private List<String> days;
|
||||
/**
|
||||
* 店铺id
|
||||
*/
|
||||
private Long shopId;
|
||||
/**
|
||||
* 开始日期
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
private String beginDate;
|
||||
/**
|
||||
* 结束日期
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
private String endDate;
|
||||
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* 数据统计-营业-上半部分
|
||||
@@ -20,15 +21,26 @@ public class DataSummaryTradeParam implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 开始时间 格式:yyyy-MM-dd HH:mm:ss
|
||||
* 开始时间 格式:yyyy-MM-dd
|
||||
*/
|
||||
@NotBlank(message = "开始日期不能为空", groups = DefaultGroup.class)
|
||||
private String beginDate;
|
||||
private LocalDate beginDate;
|
||||
/**
|
||||
* 结束时间 格式:yyyy-MM-dd HH:mm:ss
|
||||
* 结束时间 格式:yyyy-MM-dd
|
||||
*/
|
||||
@NotBlank(message = "结束日期不能为空", groups = DefaultGroup.class)
|
||||
private String endDate;
|
||||
private LocalDate endDate;
|
||||
/**
|
||||
* 时间范围类型
|
||||
* TODAY, 今天
|
||||
* YESTERDAY, 昨天
|
||||
* LAST_7_DAYS, 最近7天
|
||||
* LAST_30_DAYS,最近30天
|
||||
* THIS_WEEK, 本周
|
||||
* THIS_MONTH 本月
|
||||
* CUSTOM 自定义时间范围
|
||||
*/
|
||||
private String rangeType;
|
||||
/**
|
||||
* 店铺id
|
||||
*/
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
package com.czg.order.param;
|
||||
|
||||
import com.czg.validator.group.DefaultGroup;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* 销售统计Count入参
|
||||
@@ -16,24 +19,34 @@ public class SaleSummaryCountParam implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 店铺id
|
||||
*/
|
||||
private Long shopId;
|
||||
/**
|
||||
* 商品名称
|
||||
*/
|
||||
private String productName;
|
||||
|
||||
/**
|
||||
* 商品分类id
|
||||
* 开始时间 格式:yyyy-MM-dd
|
||||
*/
|
||||
private Long prodCategoryId;
|
||||
@NotBlank(message = "开始日期不能为空", groups = DefaultGroup.class)
|
||||
private LocalDate beginDate;
|
||||
/**
|
||||
* 开始日期 格式:yyyy-MM-dd HH:mm:ss
|
||||
* 结束时间 格式:yyyy-MM-dd
|
||||
*/
|
||||
private String beginDate;
|
||||
@NotBlank(message = "结束日期不能为空", groups = DefaultGroup.class)
|
||||
private LocalDate endDate;
|
||||
/**
|
||||
* 结束日期 格式:yyyy-MM-dd HH:mm:ss
|
||||
* 时间范围类型
|
||||
* TODAY, 今天
|
||||
* YESTERDAY, 昨天
|
||||
* LAST_7_DAYS, 最近7天
|
||||
* LAST_30_DAYS,最近30天
|
||||
* THIS_WEEK, 本周
|
||||
* THIS_MONTH 本月
|
||||
* CUSTOM 自定义时间范围
|
||||
*/
|
||||
private String endDate;
|
||||
private String rangeType;
|
||||
/**
|
||||
* 店铺id
|
||||
*/
|
||||
private Long shopId;
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
package com.czg.order.service;
|
||||
|
||||
import com.czg.order.entity.ShopOrderStatistic;
|
||||
import com.czg.order.param.DataSummaryProductSaleParam;
|
||||
import com.czg.order.param.DataSummaryTradeParam;
|
||||
import com.czg.order.vo.DataSummaryDateAmountVo;
|
||||
import com.czg.order.vo.DataSummaryPayTypeVo;
|
||||
import com.czg.order.vo.DataSummaryProductSaleRankingVo;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 数据统计Service接口
|
||||
*
|
||||
* @author tankaikai
|
||||
* @since 2025-03-07 15:31
|
||||
*/
|
||||
public interface DataSummaryService {
|
||||
|
||||
ShopOrderStatistic getArchiveTradeData(DataSummaryTradeParam param);
|
||||
|
||||
ShopOrderStatistic getRealTimeTradeData(DataSummaryTradeParam param);
|
||||
|
||||
Page<DataSummaryProductSaleRankingVo> getProductSaleRankingPage(DataSummaryProductSaleParam param);
|
||||
|
||||
DataSummaryDateAmountVo getSummaryAmountData(Long shopId,Integer day);
|
||||
|
||||
DataSummaryPayTypeVo getSummaryPayTypeData(Long shopId, Integer day);
|
||||
|
||||
List<Long> getShopIdList();
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package com.czg.order.service;
|
||||
|
||||
import com.czg.order.param.SaleSummaryCountParam;
|
||||
import com.czg.order.vo.SaleSummaryCountVo;
|
||||
import com.czg.order.vo.SaleSummaryInfoVo;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 销量统计Service接口
|
||||
*
|
||||
* @author tankaikai
|
||||
* @since 2025-03-07 15:31
|
||||
*/
|
||||
public interface SaleSummaryService {
|
||||
|
||||
SaleSummaryCountVo summaryCount(SaleSummaryCountParam param);
|
||||
Page<SaleSummaryInfoVo> summaryPage(SaleSummaryCountParam param);
|
||||
List<SaleSummaryInfoVo> summaryList(SaleSummaryCountParam param);
|
||||
|
||||
|
||||
}
|
||||
@@ -1,17 +1,73 @@
|
||||
package com.czg.order.service;
|
||||
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import com.czg.order.entity.ShopOrderStatistic;
|
||||
import com.czg.order.vo.CountPayTypeVo;
|
||||
import com.czg.order.vo.TotalVo;
|
||||
import com.mybatisflex.core.service.IService;
|
||||
import com.czg.order.entity.ShopOrderStatistic;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 服务层。
|
||||
* 店铺订单统计报表 服务层。
|
||||
*
|
||||
* @author zs
|
||||
* @since 2025-03-07
|
||||
* @author ww
|
||||
* @since 2025-11-20
|
||||
*/
|
||||
public interface ShopOrderStatisticService extends IService<ShopOrderStatistic> {
|
||||
|
||||
void statistic(DateTime dateTime);
|
||||
/**
|
||||
* 数据统计 营业板块上半部分
|
||||
* @param shopId 店铺id
|
||||
* @param rangeType 时间范围类型
|
||||
* TODAY, // 今天
|
||||
* YESTERDAY, // 昨天
|
||||
* LAST_7_DAYS, // 最近7天
|
||||
* LAST_30_DAYS,// 最近30天
|
||||
* THIS_WEEK, // 本周
|
||||
* THIS_MONTH // 本月
|
||||
* CUSTOM // 自定义时间范围
|
||||
* @param start 开始时间 格式yyyy-MM-dd 今天/昨天不用传
|
||||
* @param end 结束时间 格式yyyy-MM-dd 今天/昨天不用传
|
||||
*/
|
||||
ShopOrderStatistic getArchiveTradeData(Long shopId, String rangeType, LocalDate start, LocalDate end);
|
||||
|
||||
/**
|
||||
* 获取多少天的数据 30/90天
|
||||
*/
|
||||
List<TotalVo> getDateAmount(Long shopId, Integer day);
|
||||
/**
|
||||
* 获取支付方式数据
|
||||
*/
|
||||
List<CountPayTypeVo> getSummaryPayTypeData(Long shopId, Integer day);
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------下列为 后台使用------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 统计某天数据并插入数据库
|
||||
*
|
||||
* @param day 日期
|
||||
*/
|
||||
void statisticAndInsert(Long shopId, LocalDate day);
|
||||
|
||||
/**
|
||||
* 实时统计某天数据
|
||||
*/
|
||||
ShopOrderStatistic getRealTimeDataByDay(Long shopId, LocalDate day);
|
||||
|
||||
/**
|
||||
* 获取某一天的数据 历史数据
|
||||
* 从ShopOrderStatistic 表中查询
|
||||
*/
|
||||
ShopOrderStatistic getStatSingleDate(Long shopId, LocalDate day);
|
||||
|
||||
/**
|
||||
* 统计 某时间段数据 总和 不包括当日实时数据
|
||||
*
|
||||
* @param start 开始时间
|
||||
* @param end 结束时间
|
||||
*/
|
||||
ShopOrderStatistic getStatDateRange(Long shopId, LocalDate start, LocalDate end);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
package com.czg.order.service;
|
||||
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import com.czg.order.entity.ShopProdStatistic;
|
||||
import com.czg.order.vo.SaleSummaryCountVo;
|
||||
import com.mybatisflex.core.service.IService;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 服务层。
|
||||
*
|
||||
@@ -12,6 +15,58 @@ import com.mybatisflex.core.service.IService;
|
||||
*/
|
||||
public interface ShopProdStatisticService extends IService<ShopProdStatistic> {
|
||||
|
||||
void statistic(DateTime dateTime);
|
||||
/**
|
||||
* 统计一段时间内的商品交易数据
|
||||
*
|
||||
* @param param 入参
|
||||
* @return 商品数据
|
||||
*/
|
||||
SaleSummaryCountVo summaryCount(Long shopId, String productName, String rangeType, LocalDate start, LocalDate end);
|
||||
|
||||
/**
|
||||
* 获取某一段时间的商品交易数据
|
||||
*
|
||||
* @param shopId 店铺id
|
||||
* @param rangeType 时间范围类型
|
||||
* TODAY, // 今天
|
||||
* YESTERDAY, // 昨天
|
||||
* LAST_7_DAYS, // 最近7天
|
||||
* LAST_30_DAYS,// 最近30天
|
||||
* THIS_WEEK, // 本周
|
||||
* THIS_MONTH // 本月
|
||||
* CUSTOM // 自定义时间范围
|
||||
* @param start 开始时间 格式yyyy-MM-dd 今天/昨天不用传
|
||||
* @param end 结束时间 格式yyyy-MM-dd 今天/昨天不用传
|
||||
* @return 商品数据
|
||||
*/
|
||||
List<ShopProdStatistic> getArchiveTradeData(Long shopId, String productName, String rangeType, LocalDate start, LocalDate end);
|
||||
List<ShopProdStatistic> getArchiveTradeDataBy20(Long shopId, String rangeType, LocalDate start, LocalDate end);
|
||||
|
||||
//------------------------------------------------------------下列为 后台使用------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 统计某天数据并插入数据库
|
||||
*
|
||||
* @param day
|
||||
*/
|
||||
void statisticAndInsert(Long shopId, LocalDate day);
|
||||
|
||||
/**
|
||||
* 实时统计某天数据
|
||||
*/
|
||||
List<ShopProdStatistic> getRealTimeDataByDay(Long shopId, LocalDate day, String productName);
|
||||
|
||||
/**
|
||||
* 获取某一天的数据 历史数据
|
||||
* 从ShopOrderStatistic 表中查询
|
||||
*/
|
||||
List<ShopProdStatistic> getProdStatSingleDate(Long shopId, LocalDate day, String productName);
|
||||
|
||||
/**
|
||||
* 统计 某时间段数据 总和 不包括当日实时数据
|
||||
*
|
||||
* @param start 开始时间
|
||||
* @param end 结束时间
|
||||
*/
|
||||
List<ShopProdStatistic> getProdStatDateRange(Long shopId, LocalDate start, LocalDate end, String productName);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package com.czg.order.service;
|
||||
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import com.czg.order.entity.ShopTableOrderStatistic;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
import com.mybatisflex.core.service.IService;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 台桌订单统计表 服务层。
|
||||
@@ -14,17 +13,47 @@ import java.math.BigDecimal;
|
||||
* @since 2025-03-07
|
||||
*/
|
||||
public interface ShopTableOrderStatisticService extends IService<ShopTableOrderStatistic> {
|
||||
Page<ShopTableOrderStatistic> summary(Long shopId, String startTime, String endTime);
|
||||
|
||||
/**
|
||||
* 增加每日统计信息
|
||||
* @param shopId 店铺id
|
||||
* @param tableId 台桌id
|
||||
* @param count 订单数量
|
||||
* @param amount 订单总金额
|
||||
* @return 是否成功
|
||||
* @param rangeType 时间范围类型
|
||||
* TODAY, // 今天
|
||||
* YESTERDAY, // 昨天
|
||||
* LAST_7_DAYS, // 最近7天
|
||||
* LAST_30_DAYS,// 最近30天
|
||||
* THIS_WEEK, // 本周
|
||||
* THIS_MONTH // 本月
|
||||
* CUSTOM // 自定义时间范围
|
||||
* @param start 开始时间 格式yyyy-MM-dd 今天/昨天不用传
|
||||
* @param end 结束时间 格式yyyy-MM-dd 今天/昨天不用传
|
||||
*/
|
||||
boolean addInfo(long shopId, long tableId, long count, BigDecimal amount);
|
||||
List<ShopTableOrderStatistic> getArchiveTradeData(Long shopId, String rangeType, LocalDate start, LocalDate end);
|
||||
|
||||
void statistic(DateTime dateTime);
|
||||
//------------------------------------------------------------下列为 后台使用------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 统计某天数据并插入数据库
|
||||
*
|
||||
* @param day
|
||||
*/
|
||||
void statisticAndInsert(Long shopId, LocalDate day);
|
||||
|
||||
/**
|
||||
* 实时统计某天数据
|
||||
*/
|
||||
List<ShopTableOrderStatistic> getRealTimeDataByDay(Long shopId, LocalDate day);
|
||||
|
||||
/**
|
||||
* 获取某一天的数据 历史数据
|
||||
* 从ShopOrderStatistic 表中查询
|
||||
*/
|
||||
List<ShopTableOrderStatistic> getStatSingleDate(Long shopId, LocalDate day);
|
||||
|
||||
/**
|
||||
* 统计 某时间段数据 总和 不包括当日实时数据
|
||||
*
|
||||
* @param start 开始时间
|
||||
* @param end 结束时间
|
||||
*/
|
||||
List<ShopTableOrderStatistic> getStatDateRange(Long shopId, LocalDate start, LocalDate end);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.czg.order.service;
|
||||
|
||||
import com.czg.order.param.TableSummaryParam;
|
||||
import com.czg.order.vo.TableSummaryExportVo;
|
||||
import com.czg.order.vo.TableSummaryInfoVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -14,7 +13,6 @@ import java.util.List;
|
||||
*/
|
||||
public interface TableSummaryService {
|
||||
|
||||
List<TableSummaryInfoVo> summaryList(TableSummaryParam param);
|
||||
|
||||
List<TableSummaryExportVo> summaryExportList(TableSummaryParam param);
|
||||
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.czg.order.vo;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author ww
|
||||
* @description
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class CountPayTypeVo {
|
||||
/**
|
||||
* 笔数
|
||||
*/
|
||||
private Integer count;
|
||||
/**
|
||||
* 支付方式
|
||||
*/
|
||||
private String payType;
|
||||
|
||||
private static final Map<String, String> PAY_TYPE_MAPPING = new LinkedHashMap<>();
|
||||
|
||||
static {
|
||||
PAY_TYPE_MAPPING.put("memberPay", "会员支付");
|
||||
PAY_TYPE_MAPPING.put("cashPay", "现金支付");
|
||||
PAY_TYPE_MAPPING.put("wechatPay", "微信支付");
|
||||
PAY_TYPE_MAPPING.put("alipayPay", "支付宝支付");
|
||||
PAY_TYPE_MAPPING.put("mainScanPay", "主扫支付");
|
||||
PAY_TYPE_MAPPING.put("backScanPay", "被扫支付");
|
||||
PAY_TYPE_MAPPING.put("creditPay", "信用支付");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 合并实时数据和历史统计数据
|
||||
*/
|
||||
public static List<CountPayTypeVo> mergePayTypeData(Map<String, Integer> realTimeData,
|
||||
Map<String, Integer> historyData) {
|
||||
|
||||
List<CountPayTypeVo> result = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<String, String> entry : PAY_TYPE_MAPPING.entrySet()) {
|
||||
String payCode = entry.getKey();
|
||||
String payName = entry.getValue();
|
||||
|
||||
Integer realTimeCount = getSafeValue(realTimeData, payCode);
|
||||
Integer historyCount = getSafeValue(historyData, payCode);
|
||||
|
||||
int totalCount = (realTimeCount != null ? realTimeCount : 0)
|
||||
+ (historyCount != null ? historyCount : 0);
|
||||
|
||||
result.add(new CountPayTypeVo(totalCount, payName));
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全获取Map中的值,处理null情况
|
||||
*/
|
||||
private static Integer getSafeValue(Map<String, Integer> data, String key) {
|
||||
if (data == null || data.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return data.get(key);
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package com.czg.order.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 销售趋势柱状图 左下
|
||||
* @author tankaikai
|
||||
* @since 2025-03-07 16:08
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public class DataSummaryDateAmountVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* total
|
||||
*/
|
||||
private List<TotalVo> total = new ArrayList<>();
|
||||
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package com.czg.order.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 支付占比饼图 左下
|
||||
* @author tankaikai
|
||||
* @since 2025-03-07 16:08
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public class DataSummaryPayTypeVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
/**
|
||||
* countPayType
|
||||
*/
|
||||
private List<CountPayTypeVo> countPayType = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* CountPayTypeVo
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public static class CountPayTypeVo {
|
||||
/**
|
||||
* 笔数
|
||||
*/
|
||||
private Integer count;
|
||||
/**
|
||||
* 支付方式
|
||||
*/
|
||||
private String payType;
|
||||
}
|
||||
}
|
||||
@@ -102,7 +102,7 @@ public class OrderInfoVo implements Serializable {
|
||||
private String payType;
|
||||
|
||||
/**
|
||||
* 状态: unpaid-待支付;in-production 制作中;wait-out 待取餐;;done-订单完成;refunding-申请退单;refund-退单;part-refund 部分退单;cancelled-取消订单
|
||||
* 状态: unpaid-待支付;in-production 制作中;wait_out 待取餐;;done-订单完成;refunding-申请退单;refund-退单;part_refund 部分退单;cancelled-取消订单
|
||||
*/
|
||||
private String status;
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.czg.order.vo;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
@@ -12,6 +14,8 @@ import java.math.BigDecimal;
|
||||
* @since 2025-03-07 16:22
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class SaleSummaryCountVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
package com.czg.order.vo;
|
||||
|
||||
import cn.idev.excel.annotation.ExcelIgnore;
|
||||
import cn.idev.excel.annotation.ExcelProperty;
|
||||
import cn.idev.excel.annotation.write.style.ColumnWidth;
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import com.pig4cloud.plugin.excel.annotation.ExcelLine;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 销量统计明细
|
||||
* @author tankaikai
|
||||
* @since 2025-03-07 16:22
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
@ColumnWidth(30)
|
||||
public class SaleSummaryInfoVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 导入时候回显行号
|
||||
*/
|
||||
@ExcelLine
|
||||
@ExcelIgnore
|
||||
@JSONField(serialize = false)
|
||||
private Long lineNum;
|
||||
/**
|
||||
* 商品分类
|
||||
*/
|
||||
@ExcelProperty("商品分类")
|
||||
private String categoryName;
|
||||
/**
|
||||
* 商品名称
|
||||
*/
|
||||
@ExcelProperty("商品名称")
|
||||
private String productName;
|
||||
/**
|
||||
* 销量
|
||||
*/
|
||||
@ExcelProperty("销量")
|
||||
private BigDecimal saleCount;
|
||||
/**
|
||||
* 销售金额
|
||||
*/
|
||||
@ExcelProperty("销售金额")
|
||||
private BigDecimal saleAmount;
|
||||
/**
|
||||
* 退单量
|
||||
*/
|
||||
@ExcelProperty("退单量")
|
||||
private BigDecimal refundCount;
|
||||
/**
|
||||
* 退单金额
|
||||
*/
|
||||
@ExcelProperty("退单金额")
|
||||
private BigDecimal refundAmount;
|
||||
}
|
||||
@@ -6,9 +6,12 @@ import lombok.NoArgsConstructor;
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 销售趋势柱状图 左下
|
||||
*
|
||||
* @author tankaikai
|
||||
* @since 2025-03-07 16:08
|
||||
*/
|
||||
@@ -34,5 +37,44 @@ public class TotalVo implements Serializable {
|
||||
/**
|
||||
* 日期
|
||||
*/
|
||||
private String tradeDay;
|
||||
private LocalDate tradeDay;
|
||||
|
||||
|
||||
public TotalVo(LocalDate tradeDay) {
|
||||
this.tradeDay = tradeDay;
|
||||
}
|
||||
|
||||
/**
|
||||
* 合并实时数据和历史数据,并填充缺失的日期
|
||||
*/
|
||||
public static List<TotalVo> mergeAndFillData(TotalVo onlineData, List<TotalVo> historyData,
|
||||
LocalDate startDate, LocalDate endDate) {
|
||||
// 创建日期到数据的映射,方便查找
|
||||
Map<LocalDate, TotalVo> dataMap = new HashMap<>();
|
||||
|
||||
// 将历史数据放入映射
|
||||
for (TotalVo vo : historyData) {
|
||||
if (vo.getTradeDay() != null) {
|
||||
dataMap.put(vo.getTradeDay(), vo);
|
||||
}
|
||||
}
|
||||
dataMap.put(onlineData.getTradeDay(), onlineData);
|
||||
|
||||
List<TotalVo> result = new ArrayList<>();
|
||||
LocalDate currentDay = startDate;
|
||||
|
||||
while (!currentDay.isAfter(endDate)) {
|
||||
if (dataMap.containsKey(currentDay)) {
|
||||
result.add(dataMap.get(currentDay));
|
||||
} else {
|
||||
// 创建空的TotalVo填充缺失的日期
|
||||
TotalVo emptyVo = new TotalVo(currentDay);
|
||||
result.add(emptyVo);
|
||||
}
|
||||
currentDay = currentDay.plusDays(1);
|
||||
}
|
||||
// 按日期排序确保顺序正确
|
||||
result.sort(Comparator.comparing(TotalVo::getTradeDay));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package com.czg.service.account.mapper;
|
||||
|
||||
import com.czg.account.dto.shopinfo.ShopInfoDetailDTO;
|
||||
import com.czg.account.dto.shopinfo.ShopInfoSubVO;
|
||||
import com.czg.account.entity.ShopInfo;
|
||||
import com.mybatisflex.core.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
@@ -22,4 +22,16 @@ public interface ShopInfoMapper extends BaseMapper<ShopInfo> {
|
||||
|
||||
@Update("update tb_shop_info set amount = amount + #{amount} where id = #{id} and amount + #{amount} >= 0")
|
||||
boolean updateAmount(@Param("id") Long id, @Param("amount") BigDecimal amount);
|
||||
|
||||
/**
|
||||
* 获取所有未删除的 过期时间>三天前 店铺id列表
|
||||
*
|
||||
* @return 店铺id列表
|
||||
*/
|
||||
@Select("SELECT id " +
|
||||
"FROM tb_shop_info " +
|
||||
"WHERE id > 1 " +
|
||||
" AND expire_time > DATE_SUB(NOW(), INTERVAL 3 DAY) " +
|
||||
" AND is_deleted = 0;")
|
||||
List<Long> getShopIdList();
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
package com.czg.service.account.mapper;
|
||||
|
||||
import com.czg.account.vo.ShopProdStatisticVO;
|
||||
import com.mybatisflex.core.BaseMapper;
|
||||
import com.czg.account.entity.ShopProdStatistic;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 映射层。
|
||||
*
|
||||
* @author zs
|
||||
* @since 2025-03-06
|
||||
*/
|
||||
public interface ShopProdStatisticMapper extends BaseMapper<ShopProdStatistic> {
|
||||
|
||||
List<ShopProdStatisticVO> pageInfo(@Param("shopId") Long shopId, @Param("name") String name, @Param("classifyId") String classifyId,
|
||||
@Param("startTime") String startTime, @Param("endTime") String endTime);
|
||||
}
|
||||
@@ -465,4 +465,8 @@ public class ShopInfoServiceImpl extends ServiceImpl<ShopInfoMapper, ShopInfo> i
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<Long> getShopIdList() {
|
||||
return mapper.getShopIdList();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
package com.czg.service.account.service.impl;
|
||||
|
||||
import com.czg.utils.PageUtil;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
import com.mybatisflex.spring.service.impl.ServiceImpl;
|
||||
import com.czg.account.entity.ShopProdStatistic;
|
||||
import com.czg.account.service.ShopProdStatisticService;
|
||||
import com.czg.service.account.mapper.ShopProdStatisticMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 服务层实现。
|
||||
*
|
||||
* @author zs
|
||||
* @since 2025-03-06
|
||||
*/
|
||||
@Service
|
||||
public class ShopProdStatisticServiceImpl extends ServiceImpl<ShopProdStatisticMapper, ShopProdStatistic> implements ShopProdStatisticService{
|
||||
@Override
|
||||
public Page<?> pageInfo(Long shopId, String name, String classifyId, String startTime, String endTime) {
|
||||
PageHelper.startPage(PageUtil.buildPageHelp());
|
||||
return PageUtil.convert(new PageInfo<>(mapper.pageInfo(shopId, name, classifyId, startTime, endTime)));
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?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.service.account.mapper.ShopProdStatisticMapper">
|
||||
|
||||
<select id="pageInfo" resultType="com.czg.account.vo.ShopProdStatisticVO">
|
||||
select * from tb_shop_prod_statistic as a
|
||||
left join tb_product as b on a.prod_id=b.id
|
||||
where a.shop_id=#{shopId} and b.name like and b.category_id=
|
||||
</select>
|
||||
</mapper>
|
||||
@@ -3,8 +3,6 @@ package com.czg.service.market.service.impl;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.exceptions.ValidateException;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
@@ -14,7 +12,6 @@ import com.czg.account.entity.ShopUser;
|
||||
import com.czg.account.service.ShopInfoService;
|
||||
import com.czg.account.service.ShopUserService;
|
||||
import com.czg.account.vo.ShopInfoCouponVO;
|
||||
import com.czg.account.vo.UserCouponFoodVo;
|
||||
import com.czg.account.vo.UserCouponVo;
|
||||
import com.czg.exception.CzgException;
|
||||
import com.czg.market.dto.MkShopCouponGiftDTO;
|
||||
@@ -47,7 +44,6 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.dubbo.config.annotation.DubboReference;
|
||||
import org.apache.dubbo.config.annotation.DubboService;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
@@ -84,6 +80,7 @@ public class ShopCouponServiceImpl extends ServiceImpl<ShopCouponMapper, ShopCou
|
||||
QueryWrapper queryWrapper = new QueryWrapper();
|
||||
queryWrapper.eq(ShopCoupon::getShopId, param.getShopId())
|
||||
.eq(ShopCoupon::getCouponType, param.getCouponType())
|
||||
.like(ShopCoupon::getTitle, CzgStrUtils.getStrOrNull(param.getTitle()))
|
||||
.eq(ShopCoupon::getIsDel, 0)
|
||||
.orderBy(ShopCoupon::getCreateTime).desc();
|
||||
return pageAs(PageUtil.buildPage(), queryWrapper, ShopCouponDTO.class);
|
||||
|
||||
@@ -1,33 +1,269 @@
|
||||
package com.czg.service.order.mapper;
|
||||
|
||||
import com.czg.order.entity.ShopOrderStatistic;
|
||||
import com.czg.order.param.DataSummaryTradeParam;
|
||||
import com.czg.order.vo.TotalVo;
|
||||
import com.mybatisflex.core.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import com.czg.order.entity.ShopOrderStatistic;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 映射层。
|
||||
* 店铺订单统计报表 映射层。
|
||||
*
|
||||
* @author zs
|
||||
* @since 2025-03-07
|
||||
* @author ww
|
||||
* @since 2025-11-20
|
||||
*/
|
||||
@Mapper
|
||||
public interface ShopOrderStatisticMapper extends BaseMapper<ShopOrderStatistic> {
|
||||
|
||||
ShopOrderStatistic getTradeData(DataSummaryTradeParam param);
|
||||
long getNewMemberCount(DataSummaryTradeParam param);
|
||||
|
||||
List<Map<String, Object>> getPayTypeAmountCount(DataSummaryTradeParam param);
|
||||
@Select("SELECT"+
|
||||
" SUM(pay_amount) AS payAmount,"+
|
||||
" SUM(online_pay_amount) AS onlinePayAmount,"+
|
||||
" SUM(member_pay_amount) AS memberPayAmount,"+
|
||||
" SUM(member_pay_count) AS memberPayCount,"+
|
||||
" SUM(refund_amount) AS refundAmount,"+
|
||||
" SUM(online_refund_amount) AS onlineRefundAmount,"+
|
||||
" SUM(recharge_amount) AS rechargeAmount,"+
|
||||
" SUM(online_recharge_amount) AS onlineRechargeAmount,"+
|
||||
" SUM(give_amount) AS giveAmount,"+
|
||||
" SUM(recharge_refund_amount) AS rechargeRefundAmount,"+
|
||||
" SUM(online_recharge_refund_amount) AS onlineRechargeRefundAmount,"+
|
||||
" SUM(cash_recharge_refund_amount) AS cashRechargeRefundAmount,"+
|
||||
" SUM(cash_recharge_amount) AS cashRechargeAmount,"+
|
||||
" SUM(member_refund_amount) AS memberRefundAmount,"+
|
||||
" SUM(cash_refund_amount) AS cashRefundAmount,"+
|
||||
" SUM(new_member_count) AS newMemberCount,"+
|
||||
" SUM(customer_count) AS customerCount,"+
|
||||
" SUM(order_count) AS orderCount,"+
|
||||
" SUM(table_count) AS tableCount,"+
|
||||
" SUM(avg_pay_amount) AS avgPayAmount,"+
|
||||
" SUM(turnover_rate) AS turnoverRate,"+
|
||||
" SUM(profit_amount) AS profitAmount,"+
|
||||
" SUM(product_cost_amount) AS productCostAmount,"+
|
||||
" SUM(profit_rate) AS profitRate,"+
|
||||
" SUM(net_profit_amount) AS netProfitAmount,"+
|
||||
" SUM(net_profit_rate) AS netProfitRate,"+
|
||||
" SUM(discount_amount) AS discountAmount,"+
|
||||
" SUM(discount_count) AS discountCount,"+
|
||||
" SUM(new_customer_discount_amount) AS newCustomerDiscountAmount,"+
|
||||
" SUM(full_discount_amount) AS fullDiscountAmount,"+
|
||||
" SUM(coupon_discount_amount) AS couponDiscountAmount,"+
|
||||
" SUM(point_discount_amount) AS pointDiscountAmount,"+
|
||||
" SUM(back_discount_amount) AS backDiscountAmount,"+
|
||||
" SUM(member_discount_amount) AS memberDiscountAmount,"+
|
||||
" SUM(order_price_discount_amount) AS orderPriceDiscountAmount,"+
|
||||
" SUM(cash_pay_amount) AS cashPayAmount,"+
|
||||
" SUM(wechat_pay_amount) AS wechatPayAmount,"+
|
||||
" SUM(alipay_pay_amount) AS alipayPayAmount,"+
|
||||
" SUM(back_scan_pay_amount) AS backScanPayAmount,"+
|
||||
" SUM(main_scan_pay_amount) AS mainScanPayAmount,"+
|
||||
" SUM(credit_pay_amount) AS creditPayAmount "+
|
||||
"FROM"+
|
||||
" tb_shop_order_statistic " +
|
||||
"WHERE " +
|
||||
" shop_id = #{shopId} " +
|
||||
" AND statistic_date BETWEEN #{start} AND #{end} ")
|
||||
ShopOrderStatistic countStatistic(Long shopId, LocalDate start, LocalDate end);
|
||||
//---------------------------------------------金额统计---------------------------------------------------
|
||||
/**
|
||||
* 订单金额统计 当日实时数据
|
||||
*/
|
||||
@Select("SELECT" +
|
||||
" SUM(origin_amount) as orderAmount, " +
|
||||
" SUM(order_amount) as actualAmount, " +
|
||||
" SUM(origin_amount - order_amount) as discountAmount, " +
|
||||
" trade_day as tradeDay" +
|
||||
" FROM" +
|
||||
" tb_order_info " +
|
||||
" WHERE" +
|
||||
" shop_id = #{shopId} " +
|
||||
"and trade_day = #{tradeDay} " +
|
||||
"and paid_time is not null " +
|
||||
"GROUP BY trade_day desc")
|
||||
TotalVo getOnlineDataAmount(Long shopId, LocalDate tradeDay);
|
||||
|
||||
List<Map<String, Object>> getVipRechargeAmountCount(DataSummaryTradeParam param);
|
||||
/**
|
||||
* 订单金额统计 按日期范围查询
|
||||
*/
|
||||
@Select("SELECT" +
|
||||
" SUM(origin_amount) as orderAmount, " +
|
||||
" SUM(order_amount) as actualAmount, " +
|
||||
" SUM(origin_amount - order_amount) as discountAmount, " +
|
||||
" statistic_date as tradeDay" +
|
||||
" FROM" +
|
||||
" tb_shop_order_statistic " +
|
||||
" WHERE" +
|
||||
" shop_id = #{shopId} " +
|
||||
"and statistic_date >= #{start} " +
|
||||
"and statistic_date <= #{end} " +
|
||||
"GROUP BY tradeDay asc")
|
||||
List<TotalVo> getStatDateRange(Long shopId, LocalDate start, LocalDate end);
|
||||
|
||||
BigDecimal getCustomerUnitPrice(DataSummaryTradeParam param);
|
||||
/**
|
||||
* 订单支付方式统计 当日实时数据
|
||||
*/
|
||||
@Select("SELECT" +
|
||||
" SUM(CASE WHEN pay_type = 'main_scan' THEN pay_amount ELSE 0 END) AS mainScanPay," +
|
||||
" SUM(CASE WHEN pay_type = 'back_scan' THEN pay_amount ELSE 0 END) AS backScanPay," +
|
||||
" SUM(CASE WHEN pay_type = 'wechat_mini' THEN pay_amount ELSE 0 END) AS wechatPay," +
|
||||
" SUM(CASE WHEN pay_type = 'alipay_mini' THEN pay_amount ELSE 0 END) AS alipayPay," +
|
||||
" SUM(CASE WHEN pay_type = 'vip_pay' THEN pay_amount ELSE 0 END) AS memberPay," +
|
||||
" SUM(CASE WHEN pay_type = 'cash_pay' THEN pay_amount ELSE 0 END) AS cashPay," +
|
||||
" SUM(CASE WHEN pay_type = 'credit_pay' THEN pay_amount ELSE 0 END) AS creditPay" +
|
||||
" FROM" +
|
||||
" tb_order_info " +
|
||||
" WHERE" +
|
||||
" shop_id = #{shopId} " +
|
||||
"and trade_day = #{tradeDay} " +
|
||||
"and paid_time is not null ")
|
||||
Map<String, Integer> getOnlinePayTypeDate(Long shopId, LocalDate tradeDay);
|
||||
|
||||
BigDecimal getTableTurnoverRate(DataSummaryTradeParam param);
|
||||
/**
|
||||
* 订单支付方式统计 按日期范围查询
|
||||
*/
|
||||
@Select("SELECT" +
|
||||
" SUM(member_pay_count) as memberPay, " +
|
||||
" SUM(cash_pay_count) as cashPay, " +
|
||||
" SUM(wechat_pay_count) as wechatPay, " +
|
||||
" SUM(alipay_pay_count) as alipayPay, " +
|
||||
" SUM(main_scan_pay_count) as mainScanPay, " +
|
||||
" SUM(back_scan_pay_count) as backScanPay, " +
|
||||
" SUM(credit_pay_count) as creditPay " +
|
||||
" FROM tb_shop_order_statistic " +
|
||||
" WHERE shop_id = #{shopId} " +
|
||||
" AND statistic_date >= #{start} " +
|
||||
" AND statistic_date <= #{end} ")
|
||||
Map<String, Integer> getPayTypeDateRangeRaw(Long shopId, LocalDate start, LocalDate end);
|
||||
|
||||
|
||||
//*********************以下为日常统计********************************************************************************
|
||||
|
||||
|
||||
/**
|
||||
* 统计某日支付数据 当日实时数据/昨日数据落地
|
||||
* order 订单支付
|
||||
* refund 订单退款
|
||||
* free 霸王餐
|
||||
* memberIn 会员充值
|
||||
* memberRefund 会员充值的退款
|
||||
*/
|
||||
@Select("SELECT " +
|
||||
" SUM(CASE WHEN pay_type = 'order' THEN amount ELSE 0 END) AS onlinePayAmount," +
|
||||
" SUM(CASE WHEN pay_type = 'refund' THEN amount ELSE 0 END) AS onlineRefundAmount," +
|
||||
" SUM(CASE WHEN pay_type = 'free' THEN amount ELSE 0 END) AS backDiscountAmount," +
|
||||
" SUM(CASE WHEN pay_type = 'memberIn' THEN amount ELSE 0 END) AS onlineRechargeAmount, " +
|
||||
" SUM(CASE WHEN pay_type = 'memberRefund' THEN amount ELSE 0 END) AS onlineRechargeRefundAmount " +
|
||||
"FROM" +
|
||||
" tb_order_payment " +
|
||||
"WHERE " +
|
||||
" pay_status = 'success' " +
|
||||
" AND shop_id = #{shopId}" +
|
||||
" AND pay_type NOT IN ('memberPay', 'distribution', 'distributionRecharge')" +
|
||||
" AND pay_date = #{tradeDay} ;")
|
||||
ShopOrderStatistic getOnlineStatSingleDate(Long shopId, LocalDate tradeDay);
|
||||
|
||||
/**
|
||||
* 统计某日订单数据 当日实时数据/昨日数据落地
|
||||
*/
|
||||
@Select("SELECT" +
|
||||
" SUM(tb_order_info.origin_amount) AS originAmount," +
|
||||
" SUM(CASE WHEN pay_type = 'main_scan' THEN pay_amount ELSE 0 END) AS mainScanPayAmount," +
|
||||
" SUM(CASE WHEN pay_type = 'back_scan' THEN pay_amount ELSE 0 END) AS backScanPayAmount," +
|
||||
" SUM(CASE WHEN pay_type = 'wechat_mini' THEN pay_amount ELSE 0 END) AS wechatPayAmount," +
|
||||
" SUM(CASE WHEN pay_type = 'alipay_mini' THEN pay_amount ELSE 0 END) AS alipayPayAmount," +
|
||||
" SUM(CASE WHEN pay_type = 'vip_pay' THEN pay_amount ELSE 0 END) AS memberPayAmount," +
|
||||
" SUM(CASE WHEN pay_type = 'cash_pay' THEN pay_amount ELSE 0 END) AS cashPayAmount," +
|
||||
" SUM(CASE WHEN pay_type = 'credit_pay' THEN pay_amount ELSE 0 END) AS creditPayAmount," +
|
||||
" SUM(CASE WHEN pay_type = 'free_pay' THEN order_amount ELSE 0 END) AS backDiscountAmount," +
|
||||
" " +
|
||||
" SUM(CASE WHEN pay_type = 'vip_pay' THEN refund_amount ELSE 0 END) AS memberRefundAmount," +
|
||||
" " +
|
||||
" SUM(CASE WHEN pay_type = 'vip_pay' THEN 1 ELSE 0 END) as memberPayCount," +
|
||||
" SUM(CASE WHEN pay_type = 'cash_pay' THEN 1 ELSE 0 END) as cashPayCount," +
|
||||
" SUM(CASE WHEN pay_type = 'wechat_mini' THEN 1 ELSE 0 END) as wechatPayCount," +
|
||||
" SUM(CASE WHEN pay_type = 'alipay_mini' THEN 1 ELSE 0 END) as alipayPayCount," +
|
||||
" SUM(CASE WHEN pay_type = 'back_scan' THEN 1 ELSE 0 END) as backScanPayCount," +
|
||||
" SUM(CASE WHEN pay_type = 'main_scan' THEN 1 ELSE 0 END) as mainScanPayCount," +
|
||||
" SUM(CASE WHEN pay_type = 'credit_pay' THEN 1 ELSE 0 END) as creditPayCount," +
|
||||
" " +
|
||||
" SUM(refund_amount) as refundAmount," +
|
||||
" " +
|
||||
" SUM(new_customer_discount_amount) as newCustomerDiscountAmount," +
|
||||
" SUM(discount_act_amount) as fullDiscountAmount," +
|
||||
" SUM(product_coupon_discount_amount) + SUM(other_coupon_discount_amount) as couponDiscountAmount," +
|
||||
" SUM(points_discount_amount) as pointDiscountAmount," +
|
||||
" SUM(vip_discount_amount) as memberDiscountAmount," +
|
||||
" SUM(discount_amount) as orderPriceDiscountAmount ," +
|
||||
" count(1) as orderCount," +
|
||||
" sum(CASE WHEN seat_num IS NULL OR seat_num <= 0 THEN 1 ELSE seat_num END) as customerCount " +
|
||||
"FROM" +
|
||||
" tb_order_info " +
|
||||
"WHERE" +
|
||||
" shop_id = #{shopId} " +
|
||||
"and trade_day = #{tradeDay} " +
|
||||
"and paid_time is not null")
|
||||
ShopOrderStatistic getOrderStatSingleDate(Long shopId, LocalDate tradeDay);
|
||||
|
||||
|
||||
/**
|
||||
* 统计某日用户用户余额数据 当日实时数据/昨日数据落地
|
||||
*/
|
||||
@Select("SELECT " +
|
||||
" SUM(CASE WHEN biz_code = 'cashIn' THEN amount ELSE 0 END) AS cashRechargeAmount, " +
|
||||
" SUM(CASE WHEN biz_code = 'awardIn' THEN amount ELSE 0 END) AS giveAmount, " +
|
||||
" SUM(CASE WHEN biz_code = 'cashRefund' THEN amount ELSE 0 END) AS cashRechargeRefundAmount " +
|
||||
"FROM " +
|
||||
" tb_shop_user_flow " +
|
||||
"WHERE " +
|
||||
" shop_id = #{shopId} " +
|
||||
" AND trade_day = #{tradeDay} ;")
|
||||
ShopOrderStatistic getShopUserFlowStatSingleDate(Long shopId, LocalDate tradeDay);
|
||||
|
||||
/**
|
||||
* 优惠笔数 discountCount
|
||||
*/
|
||||
@Select("SELECT count(*) " +
|
||||
"FROM tb_order_info WHERE shop_id = #{shopId} and trade_day = #{tradeDay} and paid_time is not null and discount_all_amount > 0")
|
||||
Long countDiscountOrder(Long shopId, LocalDate tradeDay);
|
||||
|
||||
/**
|
||||
* 优惠总金额 discountAmount
|
||||
*/
|
||||
@Select("SELECT sum(discount_all_amount) " +
|
||||
"FROM tb_order_info WHERE shop_id = #{shopId} and trade_day = #{tradeDay} and paid_time is not null and discount_all_amount > 0")
|
||||
BigDecimal countDiscountAmount(Long shopId, LocalDate tradeDay);
|
||||
|
||||
|
||||
/**
|
||||
* 统计店铺桌台数 tableCount
|
||||
*/
|
||||
@Select("SELECT count(*) FROM tb_order_info WHERE shop_id = #{shopId} and status != 'unbound'")
|
||||
Long countShopTable(Long shopId);
|
||||
|
||||
/**
|
||||
* 新增会员数 newMemberCount
|
||||
*/
|
||||
@Select("SELECT count(*) FROM tb_shop_user WHERE main_shop_id = #{mainShopId} and is_vip = 1 " +
|
||||
"AND join_time BETWEEN CONCAT(#{tradeDay}, ' 00:00:00') AND CONCAT(#{tradeDay}, ' 23:59:59')")
|
||||
Long countNewMember(Long mainShopId, LocalDate tradeDay);
|
||||
|
||||
/**
|
||||
* 商品成本 productCostAmount
|
||||
*/
|
||||
@Select("SELECT " +
|
||||
" SUM(CASE WHEN sku.cost_price IS NULL OR sku.cost_price <= 0 THEN 0 ELSE sku.cost_price END) AS productCostAmount " +
|
||||
"FROM " +
|
||||
" tb_order_info `order` " +
|
||||
" INNER JOIN tb_order_detail detail ON `order`.id = detail.order_id " +
|
||||
" AND is_temporary = 0 " +
|
||||
" LEFT JOIN tb_prod_sku sku ON detail.sku_id = sku.id " +
|
||||
"WHERE " +
|
||||
" `order`.shop_id = #{shopId} " +
|
||||
" and trade_day = #{tradeDay} " +
|
||||
" and paid_time is not null")
|
||||
BigDecimal countProductCostAmount(Long shopId, LocalDate tradeDay);
|
||||
|
||||
List<Long> getShopIdList();
|
||||
}
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
package com.czg.service.order.mapper;
|
||||
|
||||
import com.czg.order.entity.ShopProdStatistic;
|
||||
import com.czg.order.param.DataSummaryProductSaleParam;
|
||||
import com.czg.order.param.SaleSummaryCountParam;
|
||||
import com.czg.order.vo.DataSummaryProductSaleRankingVo;
|
||||
import com.czg.order.vo.SaleSummaryCountVo;
|
||||
import com.czg.order.vo.SaleSummaryInfoVo;
|
||||
import com.mybatisflex.core.BaseMapper;
|
||||
import com.czg.order.entity.ShopProdStatistic;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 映射层。
|
||||
* 商品统计表 映射层。
|
||||
*
|
||||
* @author zs
|
||||
* @since 2025-03-07
|
||||
* @author ww
|
||||
* @since 2025-11-21
|
||||
*/
|
||||
public interface ShopProdStatisticMapper extends BaseMapper<ShopProdStatistic> {
|
||||
|
||||
List<DataSummaryProductSaleRankingVo> findProdRandingSummaryPage(DataSummaryProductSaleParam param);
|
||||
/**
|
||||
* 根据店铺id和日期 统计商品
|
||||
*/
|
||||
List<ShopProdStatistic> selectProStatByDay(Long shopId, LocalDate day, String productName);
|
||||
|
||||
List<DataSummaryProductSaleRankingVo> findProdRandingSummaryPage2(DataSummaryProductSaleParam param);
|
||||
List<ShopProdStatistic> getProdStatSingleDate(Long shopId, LocalDate day, String productName);
|
||||
|
||||
SaleSummaryCountVo getSaleSummaryCount(SaleSummaryCountParam param);
|
||||
List<ShopProdStatistic> getProdStatDateRange(Long shopId, LocalDate start, LocalDate end, String productName);
|
||||
|
||||
SaleSummaryCountVo getSaleSummaryCount2(SaleSummaryCountParam param);
|
||||
|
||||
List<SaleSummaryInfoVo> findSaleSummaryList(SaleSummaryCountParam param);
|
||||
|
||||
List<SaleSummaryInfoVo> findSaleSummaryList2(SaleSummaryCountParam param);
|
||||
//-----------------总统计 总金额统计-----------------
|
||||
|
||||
SaleSummaryCountVo summaryCountByDay(Long shopId, LocalDate day, String productName);
|
||||
SaleSummaryCountVo summaryCountSingleDate(Long shopId, LocalDate day, String productName);
|
||||
SaleSummaryCountVo summaryCountDateRange(Long shopId, LocalDate start, LocalDate end, String productName);
|
||||
}
|
||||
|
||||
@@ -3,27 +3,88 @@ package com.czg.service.order.mapper;
|
||||
import com.czg.order.entity.ShopTableOrderStatistic;
|
||||
import com.czg.order.param.TableSummaryParam;
|
||||
import com.czg.order.vo.TableSummaryExportVo;
|
||||
import com.czg.order.vo.TableSummaryInfoVo;
|
||||
import com.mybatisflex.core.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 台桌订单统计表 映射层。
|
||||
*
|
||||
* @author zs
|
||||
* @since 2025-03-07
|
||||
* @author ww
|
||||
* @since 2025-11-21
|
||||
*/
|
||||
public interface ShopTableOrderStatisticMapper extends BaseMapper<ShopTableOrderStatistic> {
|
||||
|
||||
List<ShopTableOrderStatistic> selectSummary(Long shopId, String startTime, String endTime);
|
||||
|
||||
boolean incrInfo(long shopId, long tableId, long count, BigDecimal amount, String dateStr);
|
||||
|
||||
List<TableSummaryInfoVo> findSummaryList(TableSummaryParam param);
|
||||
/**
|
||||
* 获取指定天的在线数据台桌
|
||||
*
|
||||
* @param shopId 店铺ID
|
||||
* @param tradeDay 时间 yyyy-MM-dd
|
||||
*/
|
||||
@Select("SELECT " +
|
||||
" `table`.id AS tableId, " +
|
||||
" `table`.table_code AS tableCode, " +
|
||||
" `table`.`name` AS tableName, " +
|
||||
" `area`.`name` AS areaName, " +
|
||||
" count( `order`.id ) AS orderCount, " +
|
||||
" SUM( CASE WHEN `order`.pay_type = 'free_pay' THEN `order`.order_amount ELSE `order`.pay_amount END ) AS orderAmount, " +
|
||||
" SUM( CASE WHEN `order`.refund_amount > 0 THEN 1 ELSE 0 END ) AS refundCount, " +
|
||||
" SUM( `order`.refund_amount ) AS refundAmount " +
|
||||
"FROM " +
|
||||
" tb_order_info `order` " +
|
||||
" INNER JOIN tb_shop_table `table` ON `order`.shop_id = `table`.shop_id " +
|
||||
" AND `order`.table_code = `table`.table_code " +
|
||||
" LEFT JOIN tb_shop_table_area `area` ON `table`.area_id = `area`.id " +
|
||||
" AND `table`.shop_id = `area`.shop_id " +
|
||||
"WHERE " +
|
||||
" `order`.shop_id = #{shopId} " +
|
||||
" AND `order`.trade_day = #{tradeDay} " +
|
||||
" AND `order`.paid_time IS NOT NULL " +
|
||||
" AND `order`.pay_mode != 'no-table'")
|
||||
List<ShopTableOrderStatistic> getOnlineData(Long shopId, LocalDate tradeDay);
|
||||
|
||||
/**
|
||||
* 获取指定天的台桌订单统计数据
|
||||
*
|
||||
* @param shopId 店铺ID
|
||||
* @param tradeDay 时间 yyyy-MM-dd
|
||||
*/
|
||||
@Select("SELECT " +
|
||||
" * " +
|
||||
"FROM " +
|
||||
" `tb_shop_table_order_statistic` " +
|
||||
"WHERE " +
|
||||
" shop_id = #{shopId} " +
|
||||
" AND create_day = #{tradeDay}")
|
||||
List<ShopTableOrderStatistic> getStatSingleDate(Long shopId, LocalDate tradeDay);
|
||||
|
||||
|
||||
/**
|
||||
* 获取指定时间范围内的台桌订单统计数据
|
||||
*
|
||||
* @param shopId 店铺ID
|
||||
* @param startDate 开始时间 yyyy-MM-dd
|
||||
* @param endDate 结束时间 yyyy-MM-dd
|
||||
*/
|
||||
@Select("SELECT" +
|
||||
" id,table_id,table_code,table_name,area_name," +
|
||||
" sum(order_count) as orderCount," +
|
||||
" sum(order_amount) as orderAmount," +
|
||||
" sum(refund_count) as refundCount," +
|
||||
" sum(refund_amount) as refundAmount" +
|
||||
" FROM" +
|
||||
" tb_shop_table_order_statistic " +
|
||||
"WHERE" +
|
||||
" shop_id = #{shopId} " +
|
||||
" AND create_day >=#{startDate} " +
|
||||
" AND create_day <=#{endDate} " +
|
||||
" GROUP BY table_id")
|
||||
List<ShopTableOrderStatistic> getStatDateRange(Long shopId, LocalDate startDate, LocalDate endDate);
|
||||
|
||||
List<TableSummaryInfoVo> findSummaryList2(TableSummaryParam param);
|
||||
|
||||
List<TableSummaryExportVo> findSummaryExportList(TableSummaryParam param);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.czg.account.dto.HandoverRecordDTO;
|
||||
import com.czg.account.dto.PrintOrderDetailDTO;
|
||||
@@ -578,7 +577,7 @@ public abstract class PrinterHandler {
|
||||
* @return 是否退款
|
||||
*/
|
||||
protected static boolean isReturn(OrderInfo orderInfo) {
|
||||
return ArrayUtil.contains(new String[]{"refunding", "part-refund", "refund"}, orderInfo.getStatus());
|
||||
return ArrayUtil.contains(new String[]{"refunding", "part_refund", "refund"}, orderInfo.getStatus());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,220 +0,0 @@
|
||||
package com.czg.service.order.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import com.czg.order.entity.OrderInfo;
|
||||
import com.czg.order.entity.ShopOrderStatistic;
|
||||
import com.czg.order.enums.PayEnums;
|
||||
import com.czg.order.param.DataSummaryProductSaleParam;
|
||||
import com.czg.order.param.DataSummaryTradeParam;
|
||||
import com.czg.order.service.DataSummaryService;
|
||||
import com.czg.order.vo.DataSummaryDateAmountVo;
|
||||
import com.czg.order.vo.DataSummaryPayTypeVo;
|
||||
import com.czg.order.vo.DataSummaryProductSaleRankingVo;
|
||||
import com.czg.order.vo.TotalVo;
|
||||
import com.czg.service.order.mapper.OrderInfoMapper;
|
||||
import com.czg.service.order.mapper.ShopOrderStatisticMapper;
|
||||
import com.czg.service.order.mapper.ShopProdStatisticMapper;
|
||||
import com.czg.utils.PageUtil;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 数据统计Service实现类
|
||||
*
|
||||
* @author tankaikai
|
||||
* @since 2025-03-07 15:32
|
||||
*/
|
||||
@Service
|
||||
public class DataSummaryServiceImpl implements DataSummaryService {
|
||||
|
||||
@Resource
|
||||
private ShopOrderStatisticMapper shopOrderStatisticMapper;
|
||||
@Resource
|
||||
private OrderInfoMapper orderInfoMapper;
|
||||
@Resource
|
||||
private ShopProdStatisticMapper shopProdStatisticMapper;
|
||||
|
||||
@Override
|
||||
public ShopOrderStatistic getArchiveTradeData(DataSummaryTradeParam param) {
|
||||
ShopOrderStatistic shopOrderStatistic = shopOrderStatisticMapper.getTradeData(param);
|
||||
if(shopOrderStatistic == null){
|
||||
shopOrderStatistic = new ShopOrderStatistic();
|
||||
}
|
||||
shopOrderStatistic.setCustomerUnitPrice(shopOrderStatistic.getCustomerUnitPrice().setScale(2, java.math.RoundingMode.HALF_UP));
|
||||
shopOrderStatistic.setTableTurnoverRate(shopOrderStatistic.getTableTurnoverRate().setScale(2, java.math.RoundingMode.HALF_UP));
|
||||
return shopOrderStatistic;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShopOrderStatistic getRealTimeTradeData(DataSummaryTradeParam param) {
|
||||
List<String> funs = Arrays.asList("getPayTypeAmountCount", "getVipRechargeAmountCount", "getNewMemberCount", "getCustomerUnitPrice", "getTableTurnoverRate");
|
||||
Map<String, Object> collect = funs.parallelStream().collect(Collectors.toMap(fun -> fun, fun ->
|
||||
ReflectUtil.invoke(shopOrderStatisticMapper, fun, param)
|
||||
));
|
||||
/*Map<String, Object> collect = new ConcurrentHashMap<>();
|
||||
for (String fun : funs) {
|
||||
Object invoke = ReflectUtil.invoke(shopOrderStatisticMapper, fun, param);
|
||||
collect.put(fun, ObjUtil.defaultIfNull(invoke,BigDecimal.ZERO));
|
||||
}*/
|
||||
ShopOrderStatistic data = new ShopOrderStatistic();
|
||||
//List<Map<String, Object>> list = shopOrderStatisticMapper.getPayTypeAmountCount(param);
|
||||
List<Map<String, Object>> list = (List<Map<String, Object>>) collect.get("getPayTypeAmountCount");
|
||||
Map<String, BigDecimal> sum = list.stream().collect(Collectors.toMap(item -> Convert.toStr(item.get("payType")), item -> Convert.toBigDecimal(item.get("amount"))));
|
||||
Map<String, Long> count = list.stream().collect(Collectors.toMap(item -> Convert.toStr(item.get("payType")), item -> Convert.toLong(item.get("count"))));
|
||||
data.setWechatPayAmount(sum.getOrDefault(PayEnums.WECHAT_MINI.getValue(), BigDecimal.ZERO));
|
||||
data.setWechatPayCount(count.getOrDefault(PayEnums.WECHAT_MINI.getValue(), 0L));
|
||||
data.setAliPayAmount(sum.getOrDefault(PayEnums.ALIPAY_MINI.getValue(), BigDecimal.ZERO));
|
||||
data.setAliPayCount(count.getOrDefault(PayEnums.ALIPAY_MINI.getValue(), 0L));
|
||||
data.setScanPayAmount(sum.getOrDefault(PayEnums.MAIN_SCAN.getValue(), BigDecimal.ZERO));
|
||||
data.setScanPayCount(count.getOrDefault(PayEnums.MAIN_SCAN.getValue(), 0L));
|
||||
data.setCashPayAmount(sum.getOrDefault(PayEnums.CASH_PAY.getValue(), BigDecimal.ZERO));
|
||||
data.setCashPayCount(count.getOrDefault(PayEnums.CASH_PAY.getValue(), 0L));
|
||||
data.setCreditPayAmount(sum.getOrDefault(PayEnums.CREDIT_PAY.getValue(), BigDecimal.ZERO));
|
||||
data.setCreditPayCount(count.getOrDefault(PayEnums.CREDIT_PAY.getValue(), 0L));
|
||||
data.setBackScanPayAmount(sum.getOrDefault(PayEnums.BACK_SCAN.getValue(), BigDecimal.ZERO));
|
||||
data.setBackScanPayCount(count.getOrDefault(PayEnums.BACK_SCAN.getValue(), 0L));
|
||||
data.setH5PayAmount(sum.getOrDefault(PayEnums.H5_PAY.getValue(), BigDecimal.ZERO));
|
||||
data.setH5PayCount(count.getOrDefault(PayEnums.H5_PAY.getValue(), 0L));
|
||||
|
||||
//List<Map<String, Object>> list1 = shopOrderStatisticMapper.getVipRechargeAmountCount(param);
|
||||
List<Map<String, Object>> list1 = (List<Map<String, Object>>) collect.get("getVipRechargeAmountCount");
|
||||
Map<String, BigDecimal> sum1 = list1.stream().collect(Collectors.toMap(item -> Convert.toStr(item.get("bizCode")), item -> Convert.toBigDecimal(item.get("amount"))));
|
||||
Map<String, Long> count1 = list1.stream().collect(Collectors.toMap(item -> Convert.toStr(item.get("bizCode")), item -> Convert.toLong(item.get("count"))));
|
||||
data.setRechargeAmount(NumberUtil.add(sum1.getOrDefault("cashIn", BigDecimal.ZERO), sum1.getOrDefault("wechatIn", BigDecimal.ZERO), sum1.getOrDefault("alipayIn", BigDecimal.ZERO)));
|
||||
data.setRechargeRefundAmount(sum1.getOrDefault("rechargeRefund", BigDecimal.ZERO).abs());
|
||||
data.setMemberPayAmount(sum1.getOrDefault("orderPay", BigDecimal.ZERO).abs());
|
||||
data.setMemberPayCount(count1.getOrDefault("orderPay", 0L));
|
||||
data.setSaleAmount(NumberUtil.add(data.getWechatPayAmount(), data.getAliPayAmount(), data.getScanPayAmount(), data.getCashPayAmount(), data.getCreditPayAmount(),data.getBackScanPayAmount(),data.getH5PayAmount()));
|
||||
data.setSaleCount(NumberUtil.add(data.getWechatPayCount(), data.getAliPayCount(), data.getScanPayCount(), data.getCashPayCount(), data.getCreditPayCount(),data.getBackScanPayCount(),data.getH5PayCount()).longValue());
|
||||
BigDecimal refundAmount = list.stream().filter(item -> item.get("payType") != null).map(item -> Convert.toBigDecimal(item.get("refund"), BigDecimal.ZERO)).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
data.setRefundAmount(refundAmount);
|
||||
long refundCount = list.stream().filter(item -> item.get("payType") != null).map(item -> Convert.toLong(item.get("refundCount"), 0L)).reduce(0L, Long::sum);
|
||||
data.setRefundCount(refundCount);
|
||||
//long newMemberCount = shopOrderStatisticMapper.getNewMemberCount(param);
|
||||
long newMemberCount = (long) collect.get("getNewMemberCount");
|
||||
data.setNewMemberCount(newMemberCount);
|
||||
//BigDecimal customerUnitPrice = shopOrderStatisticMapper.getCustomerUnitPrice(param);
|
||||
BigDecimal customerUnitPrice = (BigDecimal) collect.get("getCustomerUnitPrice");
|
||||
data.setCustomerUnitPrice(NumberUtil.nullToZero(customerUnitPrice).setScale(2, java.math.RoundingMode.HALF_UP));
|
||||
//BigDecimal tableTurnoverRate = shopOrderStatisticMapper.getTableTurnoverRate(param);
|
||||
BigDecimal tableTurnoverRate = (BigDecimal) collect.get("getTableTurnoverRate");
|
||||
data.setTableTurnoverRate(tableTurnoverRate);
|
||||
BigDecimal discountAmount = list.stream().filter(item -> item.get("payType") != null).map(item -> Convert.toBigDecimal(item.get("discount"), BigDecimal.ZERO)).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
long discountCount = list.stream().filter(item -> item.get("payType") != null).map(item -> Convert.toLong(item.get("discountCount"), 0L)).reduce(0L, Long::sum);
|
||||
data.setDiscountAmount(discountAmount);
|
||||
data.setDiscountCount(discountCount);
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<DataSummaryProductSaleRankingVo> getProductSaleRankingPage(DataSummaryProductSaleParam param) {
|
||||
LocalDate now = LocalDate.now();
|
||||
Integer day = param.getDay();
|
||||
LocalDate beginDate = now.plusDays(-day);
|
||||
List<String> days = new ArrayList<>();
|
||||
for (int i = 1; i <= day; i++) {
|
||||
String thisDay = beginDate.plusDays(i).format(DatePattern.NORM_DATE_FORMATTER);
|
||||
days.add(thisDay);
|
||||
}
|
||||
param.setDays(days);
|
||||
param.setBeginDate(days.getFirst() + " 00:00:00");
|
||||
param.setEndDate(days.getLast() + " 23:59:59");
|
||||
PageHelper.startPage(PageUtil.buildPageHelp());
|
||||
PageInfo<DataSummaryProductSaleRankingVo> pageInfo = new PageInfo<>(shopProdStatisticMapper.findProdRandingSummaryPage(param));
|
||||
return PageUtil.convert(pageInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSummaryDateAmountVo getSummaryAmountData(Long shopId, Integer day) {
|
||||
LocalDate now = LocalDate.now();
|
||||
LocalDate beginDate = now.plusDays(-day);
|
||||
DataSummaryDateAmountVo data = new DataSummaryDateAmountVo();
|
||||
List<TotalVo> total = new ArrayList<>();
|
||||
for (int i = 1; i <= day; i++) {
|
||||
String thisDay = beginDate.plusDays(i).format(DatePattern.NORM_DATE_FORMATTER);
|
||||
OrderInfo orderInfo = orderInfoMapper.selectOneByQuery(QueryWrapper.create()
|
||||
.select("ifnull(sum(order_amount),0) as order_amount,ifnull(sum(pay_amount),0) as pay_amount,ifnull(sum(order_amount-pay_amount),0) as discount_amount")
|
||||
.eq(OrderInfo::getShopId, shopId)
|
||||
.eq(OrderInfo::getTradeDay, thisDay)
|
||||
.isNotNull(OrderInfo::getPaidTime)
|
||||
);
|
||||
TotalVo totalVo = new TotalVo();
|
||||
if (orderInfo != null) {
|
||||
totalVo.setOrderAmount(orderInfo.getOrderAmount());
|
||||
totalVo.setActualAmount(orderInfo.getPayAmount());
|
||||
totalVo.setDiscountAmount(orderInfo.getDiscountAmount());
|
||||
}
|
||||
totalVo.setTradeDay(thisDay);
|
||||
total.add(totalVo);
|
||||
}
|
||||
data.setTotal(total);
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSummaryPayTypeVo getSummaryPayTypeData(Long shopId, Integer day) {
|
||||
LocalDate now = LocalDate.now();
|
||||
LocalDate beginDate = now.plusDays(-day);
|
||||
DataSummaryPayTypeVo data = new DataSummaryPayTypeVo();
|
||||
List<DataSummaryPayTypeVo.CountPayTypeVo> total = new ArrayList<>();
|
||||
List<String> days = new ArrayList<>();
|
||||
for (int i = 1; i <= day; i++) {
|
||||
String thisDay = beginDate.plusDays(i).format(DatePattern.NORM_DATE_FORMATTER);
|
||||
days.add(thisDay);
|
||||
}
|
||||
List<OrderInfo> orderList = orderInfoMapper.selectListByQuery(QueryWrapper.create()
|
||||
.select("pay_type,count(1) as place_num")
|
||||
.eq(OrderInfo::getShopId, shopId)
|
||||
.in(OrderInfo::getTradeDay, days)
|
||||
.isNotNull(OrderInfo::getPaidTime)
|
||||
.groupBy(OrderInfo::getPayType)
|
||||
);
|
||||
|
||||
PayEnums[] pays = PayEnums.values();
|
||||
if (CollUtil.isEmpty(orderList)) {
|
||||
for (PayEnums pay : pays) {
|
||||
DataSummaryPayTypeVo.CountPayTypeVo payTypeVo = new DataSummaryPayTypeVo.CountPayTypeVo();
|
||||
payTypeVo.setPayType(pay.getMsg());
|
||||
payTypeVo.setCount(0);
|
||||
total.add(payTypeVo);
|
||||
}
|
||||
data.setCountPayType(total);
|
||||
return data;
|
||||
}
|
||||
for (PayEnums pay : pays) {
|
||||
OrderInfo orderInfo = orderList.stream().filter(order -> pay.getValue().equals(order.getPayType())).findFirst().orElse(null);
|
||||
DataSummaryPayTypeVo.CountPayTypeVo payTypeVo = new DataSummaryPayTypeVo.CountPayTypeVo();
|
||||
payTypeVo.setPayType(pay.getMsg());
|
||||
payTypeVo.setCount(0);
|
||||
if (orderInfo != null) {
|
||||
payTypeVo.setPayType(PayEnums.getText(orderInfo.getPayType()));
|
||||
payTypeVo.setCount(orderInfo.getPlaceNum());
|
||||
}
|
||||
total.add(payTypeVo);
|
||||
}
|
||||
data.setCountPayType(total);
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> getShopIdList() {
|
||||
return shopOrderStatisticMapper.getShopIdList();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -435,7 +435,7 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
|
||||
//优惠券部分 目前规则 每个券只能用一张
|
||||
couponExecute(orderDetails, param, totalAmount, tempAmount, prodCouponAmount,
|
||||
oneGiftAmount, twoHalfAmount, rateAmount, fullReductionAmount);
|
||||
orderInfo.setOriginAmount(param.getOriginAmount());
|
||||
|
||||
//总商品支付金额 不包含打包费 用来计算后续
|
||||
BigDecimal newTotalAmount = totalAmount.getPrice();
|
||||
|
||||
@@ -465,7 +465,8 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
|
||||
}
|
||||
//(商品金额+打包费+餐位费)
|
||||
newTotalAmount = newTotalAmount.add(packAmount.getPrice()).add(orderInfo.getSeatAmount());
|
||||
|
||||
//填充原价
|
||||
orderInfo.setOriginAmount(totalAmount.getPrice().add(packAmount.getPrice()).add(orderInfo.getSeatAmount()));
|
||||
//新客立减
|
||||
if (shopUser != null) {
|
||||
newTotalAmount = newTotalAmount.subtract(param.getNewCustomerDiscountAmount());
|
||||
@@ -1090,6 +1091,8 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
|
||||
orderInfo1.setIsFreeDine(1);
|
||||
orderInfo1.setStatus(OrderStatusEnums.DONE.getCode());
|
||||
orderInfo1.setPayAmount(BigDecimal.ZERO);
|
||||
orderInfo1.setPaidTime(LocalDateTime.now());
|
||||
orderInfo1.setPayType(PayEnums.FREE_PAY.getValue());
|
||||
updateById(orderInfo1);
|
||||
orderDetailService.updateOrderDetailStatus(orderInfo.getId(), OrderStatusEnums.DONE.getCode());
|
||||
redisService.del(RedisCst.classKeyExpired.EXPIRED_ORDER + orderInfo.getId());
|
||||
@@ -1105,6 +1108,7 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
|
||||
updateChain().eq(OrderInfo::getId, orderInfo.getId())
|
||||
.set(OrderInfo::getPayType, PayEnums.VIP_PAY.getValue())
|
||||
.set(OrderInfo::getStatus, OrderStatusEnums.DONE.getCode())
|
||||
.set(OrderInfo::getPaidTime, LocalDateTime.now())
|
||||
.set(OrderInfo::getPayAmount, orderInfo.getOrderAmount())
|
||||
.update();
|
||||
orderDetailService.updateOrderDetailStatus(orderInfo.getId(), OrderStatusEnums.DONE.getCode());
|
||||
@@ -1441,23 +1445,30 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
|
||||
private void upOrderPayInfo(OrderInfo orderInfo, CheckOrderPay param) {
|
||||
orderInfo.setPointsNum(param.getPointsNum());
|
||||
orderInfo.setIsPrint(param.getIsPrint());
|
||||
orderInfo.setRoundAmount(param.getRoundAmount());
|
||||
orderInfo.setOrderAmount(param.getOrderAmount());
|
||||
orderInfo.setPointsDiscountAmount(param.getPointsDiscountAmount());
|
||||
// ----------------------优惠金额-------------------------
|
||||
//优惠卷
|
||||
orderInfo.setCouponInfoList(CollUtil.isEmpty(param.getCouponList()) ? "" : JSONObject.toJSONString(param.getCouponList()));
|
||||
orderInfo.setProductCouponDiscountAmount(param.getProductCouponDiscountAmount());
|
||||
orderInfo.setOtherCouponDiscountAmount(param.getOtherCouponDiscountAmount());
|
||||
//积分
|
||||
orderInfo.setPointsDiscountAmount(param.getPointsDiscountAmount());
|
||||
//新客立减
|
||||
orderInfo.setNewCustomerDiscountAmount(param.getNewCustomerDiscountAmount());
|
||||
// orderInfo.setFullCouponDiscountAmount(param.getFullCouponDiscountAmount());
|
||||
orderInfo.setOtherCouponDiscountAmount(param.getOtherCouponDiscountAmount());
|
||||
//商家最终改价
|
||||
orderInfo.setDiscountAmount(param.getDiscountAmount());
|
||||
//优惠券
|
||||
orderInfo.setCouponInfoList(CollUtil.isEmpty(param.getCouponList()) ? "" : JSONObject.toJSONString(param.getCouponList()));
|
||||
//满减活动抵扣金额
|
||||
orderInfo.setDiscountActAmount(param.getDiscountActAmount());
|
||||
//会员折扣金额
|
||||
orderInfo.setVipDiscountAmount(param.getVipDiscountAmount());
|
||||
//抹零
|
||||
// orderInfo.setRoundAmount(param.getRoundAmount());
|
||||
//优惠总金额
|
||||
orderInfo.initDiscountAllAmount();
|
||||
//折扣信息
|
||||
orderInfo.setDiscountInfo(buildDiscountInfo(orderInfo));
|
||||
|
||||
|
||||
//0元按照现金支付处理
|
||||
if (orderInfo.getOrderAmount().compareTo(BigDecimal.ZERO) == 0) {
|
||||
orderInfo.setStatus(OrderStatusEnums.DONE.getCode());
|
||||
@@ -1508,6 +1519,9 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
|
||||
if (orderInfo.getProductCouponDiscountAmount().compareTo(BigDecimal.ZERO) > 0) {
|
||||
jsonObject.put("商品券抵扣", orderInfo.getProductCouponDiscountAmount());
|
||||
}
|
||||
if (orderInfo.getOtherCouponDiscountAmount().compareTo(BigDecimal.ZERO) > 0) {
|
||||
jsonObject.put("其它优惠券折扣", orderInfo.getOtherCouponDiscountAmount());
|
||||
}
|
||||
if (orderInfo.getDiscountAmount().compareTo(BigDecimal.ZERO) > 0) {
|
||||
jsonObject.put("打折优惠", orderInfo.getDiscountAmount());
|
||||
}
|
||||
@@ -1517,9 +1531,6 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
|
||||
if (orderInfo.getVipDiscountAmount() != null && orderInfo.getVipDiscountAmount().compareTo(BigDecimal.ZERO) > 0) {
|
||||
jsonObject.put("会员整单折扣", orderInfo.getVipDiscountAmount());
|
||||
}
|
||||
if (orderInfo.getOtherCouponDiscountAmount().compareTo(BigDecimal.ZERO) > 0) {
|
||||
jsonObject.put("其它优惠券折扣", orderInfo.getOtherCouponDiscountAmount());
|
||||
}
|
||||
if (orderInfo.getPointsDiscountAmount().compareTo(BigDecimal.ZERO) > 0) {
|
||||
jsonObject.put("积分抵扣", orderInfo.getPointsDiscountAmount());
|
||||
}
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
package com.czg.service.order.service.impl;
|
||||
|
||||
import com.czg.order.param.SaleSummaryCountParam;
|
||||
import com.czg.order.service.SaleSummaryService;
|
||||
import com.czg.order.vo.SaleSummaryCountVo;
|
||||
import com.czg.order.vo.SaleSummaryInfoVo;
|
||||
import com.czg.service.order.mapper.ShopProdStatisticMapper;
|
||||
import com.czg.utils.PageUtil;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 销量统计Service实现类
|
||||
*
|
||||
* @author tankaikai
|
||||
* @since 2025-03-07 15:32
|
||||
*/
|
||||
@Service
|
||||
public class SaleSummaryServiceImpl implements SaleSummaryService {
|
||||
@Resource
|
||||
private ShopProdStatisticMapper shopProdStatisticMapper;
|
||||
|
||||
@Override
|
||||
public SaleSummaryCountVo summaryCount(SaleSummaryCountParam param) {
|
||||
SaleSummaryCountVo saleSummaryCount = shopProdStatisticMapper.getSaleSummaryCount(param);
|
||||
if (saleSummaryCount == null) {
|
||||
saleSummaryCount = new SaleSummaryCountVo();
|
||||
}
|
||||
return saleSummaryCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<SaleSummaryInfoVo> summaryPage(SaleSummaryCountParam param) {
|
||||
PageHelper.startPage(PageUtil.buildPageHelp());
|
||||
PageInfo<SaleSummaryInfoVo> pageInfo = new PageInfo<>(shopProdStatisticMapper.findSaleSummaryList(param));
|
||||
return PageUtil.convert(pageInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SaleSummaryInfoVo> summaryList(SaleSummaryCountParam param) {
|
||||
return shopProdStatisticMapper.findSaleSummaryList(param);
|
||||
}
|
||||
}
|
||||
@@ -1,88 +1,174 @@
|
||||
package com.czg.service.order.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.czg.account.entity.ShopInfo;
|
||||
import com.czg.account.service.ShopInfoService;
|
||||
import com.czg.exception.CzgException;
|
||||
import com.czg.order.entity.ShopOrderStatistic;
|
||||
import com.czg.order.param.DataSummaryTradeParam;
|
||||
import com.czg.order.service.DataSummaryService;
|
||||
import com.czg.order.service.ShopOrderStatisticService;
|
||||
import com.czg.order.vo.CountPayTypeVo;
|
||||
import com.czg.order.vo.TotalVo;
|
||||
import com.czg.service.order.mapper.ShopOrderStatisticMapper;
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
import com.mybatisflex.spring.service.impl.ServiceImpl;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.dubbo.config.annotation.DubboReference;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDate;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
/**
|
||||
* 服务层实现。
|
||||
* 店铺订单统计报表 服务层实现。
|
||||
*
|
||||
* @author zs
|
||||
* @since 2025-03-07
|
||||
* @author ww
|
||||
* @since 2025-11-20
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class ShopOrderStatisticServiceImpl extends ServiceImpl<ShopOrderStatisticMapper, ShopOrderStatistic> implements ShopOrderStatisticService {
|
||||
@Resource
|
||||
private DataSummaryService dataSummaryService;
|
||||
|
||||
@DubboReference
|
||||
private ShopInfoService shopInfoService;
|
||||
@Override
|
||||
public ShopOrderStatistic getArchiveTradeData(Long shopId, String rangeType, LocalDate start, LocalDate end) {
|
||||
LocalDate currentDate = LocalDate.now();
|
||||
if ("today".equals(rangeType)) {
|
||||
return getRealTimeDataByDay(shopId, currentDate);
|
||||
} else if ("yesterday".equals(rangeType)) {
|
||||
return getStatSingleDate(shopId, currentDate.minusDays(1));
|
||||
}
|
||||
if (start.isAfter(currentDate)) {
|
||||
throw new CzgException("开始时间不能晚于当前时间");
|
||||
}
|
||||
if (start.equals(end)) {
|
||||
return getStatSingleDate(shopId, start);
|
||||
}
|
||||
//包括当前时间
|
||||
if (end.isBefore(currentDate)) {
|
||||
return getStatDateRange(shopId, start, end);
|
||||
} else {
|
||||
ShopOrderStatistic realTimeDataByDay = getRealTimeDataByDay(shopId, currentDate);
|
||||
ShopOrderStatistic statDateRange = getStatDateRange(shopId, start, end);
|
||||
ShopOrderStatistic shopOrderStatistic = ShopOrderStatistic.mergeStatistics(realTimeDataByDay, statDateRange);
|
||||
shopOrderStatistic.setShopId(shopId);
|
||||
return shopOrderStatistic;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TotalVo> getDateAmount(Long shopId, Integer day) {
|
||||
LocalDate currentDate = LocalDate.now();
|
||||
LocalDate startDate = currentDate;
|
||||
if (day == 7) {
|
||||
startDate = currentDate.minusDays(6);
|
||||
} else if (day == 30) {
|
||||
startDate = currentDate.minusDays(29);
|
||||
}
|
||||
TotalVo onlineDataAmount = mapper.getOnlineDataAmount(shopId, currentDate);
|
||||
List<TotalVo> statDateRange = mapper.getStatDateRange(shopId, startDate, currentDate);
|
||||
|
||||
return TotalVo.mergeAndFillData(onlineDataAmount, statDateRange, startDate, currentDate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CountPayTypeVo> getSummaryPayTypeData(Long shopId, Integer day) {
|
||||
LocalDate currentDate = LocalDate.now();
|
||||
LocalDate startDate = currentDate;
|
||||
if (day == 7) {
|
||||
startDate = currentDate.minusDays(6);
|
||||
} else if (day == 30) {
|
||||
startDate = currentDate.minusDays(29);
|
||||
}
|
||||
return CountPayTypeVo.mergePayTypeData(
|
||||
mapper.getOnlinePayTypeDate(shopId, currentDate),
|
||||
mapper.getPayTypeDateRangeRaw(shopId, startDate, currentDate));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void statisticAndInsert(Long shopId, LocalDate day) {
|
||||
ShopOrderStatistic realTimeData = getRealTimeDataByDay(shopId, day);
|
||||
if (realTimeData != null && realTimeData.hasValidData(realTimeData)) {
|
||||
ShopOrderStatistic result = getOne(QueryWrapper.create().eq(ShopOrderStatistic::getShopId, shopId).eq(ShopOrderStatistic::getStatisticDate, day));
|
||||
if (result != null) {
|
||||
removeById(result);
|
||||
}
|
||||
save(realTimeData);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShopOrderStatistic getRealTimeDataByDay(Long shopId, LocalDate day) {
|
||||
ShopOrderStatistic result = new ShopOrderStatistic();
|
||||
|
||||
ShopOrderStatistic onlineStat = mapper.getOnlineStatSingleDate(shopId, day);
|
||||
ShopOrderStatistic orderStat = mapper.getOrderStatSingleDate(shopId, day);
|
||||
ShopOrderStatistic userFlowStat = mapper.getShopUserFlowStatSingleDate(shopId, day);
|
||||
Long discountCount = mapper.countDiscountOrder(shopId, day);
|
||||
BigDecimal discountAmount = mapper.countDiscountAmount(shopId, day);
|
||||
Long tableCount = mapper.countShopTable(shopId);
|
||||
Long newMemberCount = mapper.countNewMember(shopId, day);
|
||||
BigDecimal productCostAmount = mapper.countProductCostAmount(shopId, day);
|
||||
// 合并结果
|
||||
BeanUtils.copyProperties(onlineStat, result);
|
||||
BeanUtils.copyProperties(orderStat, result);
|
||||
BeanUtils.copyProperties(userFlowStat, result);
|
||||
|
||||
result.setShopId(shopId);
|
||||
result.setStatisticDate(day);
|
||||
|
||||
result.setDiscountCount(discountCount);
|
||||
result.setDiscountAmount(discountAmount);
|
||||
result.setTableCount(tableCount);
|
||||
result.setNewMemberCount(newMemberCount);
|
||||
result.setProductCostAmount(productCostAmount);
|
||||
|
||||
//会员充值退款 充值退款金额(线上退款+现金退款)
|
||||
result.setRechargeRefundAmount(onlineStat.getOnlineRechargeRefundAmount().add(userFlowStat.getCashRechargeRefundAmount()));
|
||||
//实付金额 (线上付款 现金支付 会员支付 挂账)
|
||||
result.setPayAmount(onlineStat.getOnlinePayAmount().add(orderStat.getCashPayAmount()).add(orderStat.getMemberPayAmount()).add(orderStat.getCreditPayAmount()));
|
||||
//毛利润(订单实付金额-商品成本)
|
||||
result.setProfitAmount(result.getPayAmount().subtract(productCostAmount));
|
||||
//毛利率(订单实付金额-商品成本)/订单实付金额*100%
|
||||
if (result.getPayAmount().compareTo(BigDecimal.ZERO) > 0) {
|
||||
BigDecimal profitRate = result.getProfitAmount().divide(result.getPayAmount(), 4, RoundingMode.HALF_DOWN).multiply(BigDecimal.valueOf(100));
|
||||
result.setProfitRate(profitRate);
|
||||
result.setNetProfitAmount(profitRate);
|
||||
} else {
|
||||
result.setProfitRate(BigDecimal.ZERO);
|
||||
result.setNetProfitAmount(BigDecimal.ZERO);
|
||||
}
|
||||
//客单价 实付金额(包括线上支付 包含现金支付 包含会员支付 包含挂账)/就餐人数
|
||||
result.setAvgPayAmount(result.getPayAmount().divide(new BigDecimal(result.getCustomerCount()), 2, RoundingMode.HALF_DOWN));
|
||||
//翻台率 (订单数-桌台数)/桌台数*100%
|
||||
if (tableCount > 0) {
|
||||
BigDecimal turnoverRate = new BigDecimal(result.getOrderCount()).subtract(new BigDecimal(tableCount)).divide(new BigDecimal(tableCount), 4, RoundingMode.HALF_DOWN).multiply(BigDecimal.valueOf(100));
|
||||
result.setTurnoverRate(turnoverRate);
|
||||
} else {
|
||||
result.setTurnoverRate(BigDecimal.ZERO);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void statistic(DateTime dateTime) {
|
||||
// 获取前一天的开始时间(00:00:00)
|
||||
DateTime startOfDay = DateUtil.beginOfDay(dateTime);
|
||||
// 获取前一天的结束时间(23:59:59)
|
||||
DateTime endOfDay = DateUtil.endOfDay(dateTime);
|
||||
List<Long> shopIdList = dataSummaryService.getShopIdList();
|
||||
if (CollUtil.isEmpty(shopIdList)) {
|
||||
return;
|
||||
public ShopOrderStatistic getStatSingleDate(Long shopId, LocalDate day) {
|
||||
ShopOrderStatistic result = getOne(QueryWrapper.create().eq(ShopOrderStatistic::getShopId, shopId).eq(ShopOrderStatistic::getStatisticDate, day));
|
||||
if (result == null) {
|
||||
result = new ShopOrderStatistic();
|
||||
result.setShopId(shopId);
|
||||
result.setStatisticDate(day);
|
||||
result.init();
|
||||
}
|
||||
List<List<Long>> split = CollUtil.split(shopIdList, 5);
|
||||
for (List<Long> splitIdList : split) {
|
||||
splitIdList.parallelStream().forEach(shopId -> {
|
||||
Long mainShopId = shopInfoService.getMainIdByShopId(shopId);
|
||||
DataSummaryTradeParam param = new DataSummaryTradeParam();
|
||||
param.setShopId(shopId);
|
||||
param.setMainShopId(mainShopId);
|
||||
param.setBeginDate(startOfDay.toStringDefaultTimeZone());
|
||||
param.setEndDate(endOfDay.toStringDefaultTimeZone());
|
||||
ShopOrderStatistic statistic = dataSummaryService.getRealTimeTradeData(param);
|
||||
statistic.setShopId(shopId);
|
||||
statistic.setCreateDay(dateTime.toLocalDateTime().toLocalDate());
|
||||
statistic.setUpdateTime(LocalDateTime.now());
|
||||
if (statistic.getNewMemberCount() != 0L) {
|
||||
System.out.println("newMemberCount:" + statistic.getNewMemberCount());
|
||||
return result;
|
||||
}
|
||||
// 如果没有订单和退款,则不更新数据,否则会产出很多数据
|
||||
if (statistic.getSaleCount() == 0
|
||||
&& statistic.getRefundCount() == 0
|
||||
&& statistic.getMemberPayCount() == 0
|
||||
&& statistic.getNewMemberCount() == 0
|
||||
) {
|
||||
log.info("店铺:{},{},没有要存档的订单统计数据", shopId, dateTime.toDateStr());
|
||||
} else {
|
||||
ShopOrderStatistic entity =
|
||||
getMapper()
|
||||
.selectOneByQuery(query().eq("shop_id", shopId)
|
||||
.eq("create_day", dateTime.toDateStr()));
|
||||
if (entity != null) {
|
||||
statistic.setId(entity.getId());
|
||||
updateById(statistic);
|
||||
} else {
|
||||
save(statistic);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@Override
|
||||
public ShopOrderStatistic getStatDateRange(Long shopId, LocalDate start, LocalDate end) {
|
||||
ShopOrderStatistic result = mapper.countStatistic(shopId, start, end);
|
||||
if (result == null) {
|
||||
result = new ShopOrderStatistic();
|
||||
result.setStatisticDate(start);
|
||||
result.init();
|
||||
}
|
||||
result.setShopId(shopId);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,87 +1,194 @@
|
||||
package com.czg.service.order.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import com.czg.exception.CzgException;
|
||||
import com.czg.order.entity.ShopProdStatistic;
|
||||
import com.czg.order.param.DataSummaryProductSaleParam;
|
||||
import com.czg.order.service.DataSummaryService;
|
||||
import com.czg.order.service.ShopProdStatisticService;
|
||||
import com.czg.order.vo.DataSummaryProductSaleRankingVo;
|
||||
import com.czg.order.vo.SaleSummaryCountVo;
|
||||
import com.czg.service.order.mapper.ShopProdStatisticMapper;
|
||||
import com.czg.utils.CzgStrUtils;
|
||||
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.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* 服务层实现。
|
||||
* 商品统计表 服务层实现。
|
||||
*
|
||||
* @author zs
|
||||
* @since 2025-03-07
|
||||
* @author ww
|
||||
* @since 2025-11-21
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class ShopProdStatisticServiceImpl extends ServiceImpl<ShopProdStatisticMapper, ShopProdStatistic> implements ShopProdStatisticService {
|
||||
@Resource
|
||||
private DataSummaryService dataSummaryService;
|
||||
@Resource
|
||||
private ShopProdStatisticMapper shopProdStatisticMapper;
|
||||
|
||||
@Data
|
||||
private static class StatisticTask {
|
||||
private BigDecimal successCount = BigDecimal.ZERO;
|
||||
private BigDecimal successAmount = BigDecimal.ZERO;
|
||||
private BigDecimal refundCount = BigDecimal.ZERO;
|
||||
private BigDecimal refundAmount = BigDecimal.ZERO;
|
||||
@Override
|
||||
public List<ShopProdStatistic> getArchiveTradeDataBy20(Long shopId, String rangeType, LocalDate start, LocalDate end) {
|
||||
List<ShopProdStatistic> archiveTradeData = getArchiveTradeData(shopId, null, rangeType, start, end);
|
||||
// 按照 saleCount 降序排序
|
||||
return archiveTradeData.stream()
|
||||
.sorted(
|
||||
Comparator.comparing(
|
||||
ShopProdStatistic::getSaleCount,
|
||||
Comparator.nullsLast(BigDecimal::compareTo).reversed()
|
||||
)
|
||||
)
|
||||
.limit(20)
|
||||
.toList();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SaleSummaryCountVo summaryCount(Long shopId, String productName, String rangeType, LocalDate start, LocalDate end) {
|
||||
LocalDate currentDate = LocalDate.now();
|
||||
if ("today".equals(rangeType)) {
|
||||
return mapper.summaryCountByDay(shopId, currentDate, productName);
|
||||
} else if ("yesterday".equals(rangeType)) {
|
||||
return mapper.summaryCountSingleDate(shopId, currentDate.minusDays(1), productName);
|
||||
} else {
|
||||
if (start.isAfter(currentDate)) {
|
||||
throw new CzgException("开始时间不能晚于当前时间");
|
||||
}
|
||||
if (start.equals(end)) {
|
||||
return mapper.summaryCountSingleDate(shopId, start, productName);
|
||||
} else {
|
||||
if (end.isBefore(currentDate)) {
|
||||
return mapper.summaryCountDateRange(shopId, start, end, productName);
|
||||
} else {
|
||||
SaleSummaryCountVo todaySummary = mapper.summaryCountByDay(shopId, currentDate, productName);
|
||||
SaleSummaryCountVo dateRangeSummary = mapper.summaryCountDateRange(shopId, start, end, productName);
|
||||
return mergeSummaryCountVo(todaySummary, dateRangeSummary);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void statistic(DateTime dateTime) {
|
||||
// 获取前一天的开始时间(00:00:00)
|
||||
DateTime startOfDay = DateUtil.beginOfDay(dateTime);
|
||||
// 获取前一天的结束时间(23:59:59)
|
||||
DateTime endOfDay = DateUtil.endOfDay(dateTime);
|
||||
List<Long> shopIdList = dataSummaryService.getShopIdList();
|
||||
if (CollUtil.isEmpty(shopIdList)) {
|
||||
return;
|
||||
}
|
||||
List<List<Long>> split = CollUtil.split(shopIdList, 5);
|
||||
for (List<Long> splitIdList : split) {
|
||||
splitIdList.parallelStream().forEach(shopId -> {
|
||||
DataSummaryProductSaleParam param = new DataSummaryProductSaleParam();
|
||||
param.setShopId(shopId);
|
||||
param.setBeginDate(startOfDay.toStringDefaultTimeZone());
|
||||
param.setEndDate(endOfDay.toStringDefaultTimeZone());
|
||||
// 删除之前统计数据
|
||||
getMapper().deleteByQuery(
|
||||
QueryWrapper.create()
|
||||
.eq("shop_id", shopId)
|
||||
.eq("create_day", dateTime.toDateStr()));
|
||||
// 重新统计数据
|
||||
List<DataSummaryProductSaleRankingVo> list = shopProdStatisticMapper.findProdRandingSummaryPage2(param);
|
||||
for (DataSummaryProductSaleRankingVo dto : list) {
|
||||
ShopProdStatistic entity = new ShopProdStatistic();
|
||||
entity.setProdId(dto.getProductId());
|
||||
entity.setSaleCount(dto.getNumber());
|
||||
entity.setSaleAmount(dto.getAmount());
|
||||
entity.setRefundCount(dto.getRefundCount());
|
||||
entity.setRefundAmount(dto.getRefundAmount());
|
||||
entity.setShopId(shopId);
|
||||
entity.setCreateDay(dateTime.toJdkDate());
|
||||
if (NumberUtil.isLessOrEqual(entity.getSaleCount(), BigDecimal.ZERO) && NumberUtil.isLessOrEqual(entity.getRefundCount(), BigDecimal.ZERO)) {
|
||||
log.info("店铺:{},{},没有要存档的商品统计数据", shopId, dateTime.toDateStr());
|
||||
public List<ShopProdStatistic> getArchiveTradeData(Long shopId, String productName, String rangeType, LocalDate start, LocalDate end) {
|
||||
LocalDate currentDate = LocalDate.now();
|
||||
productName = CzgStrUtils.getStrOrNull(productName);
|
||||
List<ShopProdStatistic> resultList;
|
||||
if ("today".equals(rangeType)) {
|
||||
resultList = getRealTimeDataByDay(shopId, currentDate, productName);
|
||||
} else if ("yesterday".equals(rangeType)) {
|
||||
resultList = getProdStatSingleDate(shopId, currentDate.minusDays(1), productName);
|
||||
} else {
|
||||
save(entity);
|
||||
if (start.isAfter(currentDate)) {
|
||||
throw new CzgException("开始时间不能晚于当前时间");
|
||||
}
|
||||
}
|
||||
});
|
||||
if (start.equals(end)) {
|
||||
resultList = getProdStatSingleDate(shopId, start, productName);
|
||||
} else {
|
||||
if (end.isBefore(currentDate)) {
|
||||
resultList = getProdStatDateRange(shopId, start, end, productName);
|
||||
} else {
|
||||
List<ShopProdStatistic> realTimeDataByDay = getRealTimeDataByDay(shopId, currentDate, productName);
|
||||
List<ShopProdStatistic> dateRange = getProdStatDateRange(shopId, start, end, productName);
|
||||
|
||||
resultList = mergeProdStatistic(realTimeDataByDay, dateRange);
|
||||
}
|
||||
}
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void statisticAndInsert(Long shopId, LocalDate day) {
|
||||
List<ShopProdStatistic> realTimeData = getRealTimeDataByDay(shopId, day, null);
|
||||
if (CollUtil.isNotEmpty(realTimeData)) {
|
||||
// 过滤掉没有有效数据的记录
|
||||
realTimeData = realTimeData.stream()
|
||||
.filter(ShopProdStatistic::isValid)
|
||||
.toList();
|
||||
if(CollUtil.isNotEmpty(realTimeData)) {
|
||||
boolean exists = exists(QueryWrapper.create().eq(ShopProdStatistic::getShopId, shopId).eq(ShopProdStatistic::getCreateDay, day));
|
||||
if (exists) {
|
||||
remove(QueryWrapper.create().eq(ShopProdStatistic::getShopId, shopId).eq(ShopProdStatistic::getCreateDay, day));
|
||||
}
|
||||
saveBatch(realTimeData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ShopProdStatistic> getRealTimeDataByDay(Long shopId, LocalDate day, String productName) {
|
||||
return mapper.selectProStatByDay(shopId, day, productName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ShopProdStatistic> getProdStatSingleDate(Long shopId, LocalDate day, String productName) {
|
||||
return mapper.getProdStatSingleDate(shopId, day, productName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ShopProdStatistic> getProdStatDateRange(Long shopId, LocalDate start, LocalDate end, String productName) {
|
||||
return mapper.getProdStatDateRange(shopId, start, end, productName);
|
||||
}
|
||||
|
||||
private SaleSummaryCountVo mergeSummaryCountVo(SaleSummaryCountVo todaySummary, SaleSummaryCountVo dateRangeSummary) {
|
||||
if (todaySummary == null) todaySummary = new SaleSummaryCountVo();
|
||||
if (dateRangeSummary == null) dateRangeSummary = new SaleSummaryCountVo();
|
||||
|
||||
return new SaleSummaryCountVo(
|
||||
safeAdd(todaySummary.getTotalAmount(), dateRangeSummary.getTotalAmount()),
|
||||
safeAdd(todaySummary.getRefundAmount(), dateRangeSummary.getRefundAmount()),
|
||||
safeAdd(todaySummary.getSaleCount(), dateRangeSummary.getSaleCount()),
|
||||
safeAdd(todaySummary.getRefundCount(), dateRangeSummary.getRefundCount())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 合并实时数据和日期范围数据
|
||||
*
|
||||
* @param realTimeDataByDay 实时数据
|
||||
* @param dateRange 日期范围数据
|
||||
* @return 合并后的数据
|
||||
*/
|
||||
private List<ShopProdStatistic> mergeProdStatistic(List<ShopProdStatistic> realTimeDataByDay, List<ShopProdStatistic> dateRange) {
|
||||
if (realTimeDataByDay == null) realTimeDataByDay = new ArrayList<>();
|
||||
if (dateRange == null) dateRange = new ArrayList<>();
|
||||
|
||||
return Stream.concat(realTimeDataByDay.stream(), dateRange.stream())
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toMap(
|
||||
ShopProdStatistic::getProdId,
|
||||
Function.identity(),
|
||||
(stat1, stat2) -> {
|
||||
// 创建合并后的对象
|
||||
ShopProdStatistic merged = new ShopProdStatistic();
|
||||
merged.setId(stat1.getId());
|
||||
merged.setProdId(stat1.getProdId());
|
||||
merged.setShopId(stat1.getShopId());
|
||||
|
||||
// 安全处理BigDecimal相加,处理null值
|
||||
merged.setSaleCount(safeAdd(stat1.getSaleCount(), stat2.getSaleCount()));
|
||||
merged.setSaleAmount(safeAdd(stat1.getSaleAmount(), stat2.getSaleAmount()));
|
||||
merged.setRefundCount(safeAdd(stat1.getRefundCount(), stat2.getRefundCount()));
|
||||
merged.setRefundAmount(safeAdd(stat1.getRefundAmount(), stat2.getRefundAmount()));
|
||||
|
||||
return merged;
|
||||
}
|
||||
))
|
||||
.values()
|
||||
.stream()
|
||||
.toList();
|
||||
}
|
||||
|
||||
|
||||
private BigDecimal safeAdd(BigDecimal num1, BigDecimal num2) {
|
||||
BigDecimal safeNum1 = num1 != null ? num1 : BigDecimal.ZERO;
|
||||
BigDecimal safeNum2 = num2 != null ? num2 : BigDecimal.ZERO;
|
||||
return safeNum1.add(safeNum2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,118 +1,79 @@
|
||||
package com.czg.service.order.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.czg.exception.CzgException;
|
||||
import com.czg.order.entity.ShopTableOrderStatistic;
|
||||
import com.czg.order.param.TableSummaryParam;
|
||||
import com.czg.order.service.DataSummaryService;
|
||||
import com.czg.order.service.ShopTableOrderStatisticService;
|
||||
import com.czg.order.vo.TableSummaryInfoVo;
|
||||
import com.czg.service.order.mapper.ShopTableOrderStatisticMapper;
|
||||
import com.czg.utils.PageUtil;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
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.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 台桌订单统计表 服务层实现。
|
||||
*
|
||||
* @author zs
|
||||
* @since 2025-03-07
|
||||
* @author ww
|
||||
* @since 2025-11-21
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class ShopTableOrderStatisticServiceImpl extends ServiceImpl<ShopTableOrderStatisticMapper, ShopTableOrderStatistic> implements ShopTableOrderStatisticService{
|
||||
@Resource
|
||||
private DataSummaryService dataSummaryService;
|
||||
@Resource
|
||||
private ShopTableOrderStatisticMapper shopTableOrderStatisticMapper;
|
||||
|
||||
@Override
|
||||
public Page<ShopTableOrderStatistic> summary(Long shopId, String startTime, String endTime) {
|
||||
Page<Object> page = PageUtil.buildPage();
|
||||
PageHelper.startPage(Math.toIntExact(page.getPageNumber()), Math.toIntExact(page.getPageSize()));
|
||||
return PageUtil.convert(new PageInfo<>(mapper.selectSummary(shopId, startTime, endTime)));
|
||||
public List<ShopTableOrderStatistic> getArchiveTradeData(Long shopId, String rangeType, LocalDate start, LocalDate end) {
|
||||
LocalDate currentDate = LocalDate.now();
|
||||
if ("today".equals(rangeType)) {
|
||||
return getRealTimeDataByDay(shopId, currentDate);
|
||||
} else if ("yesterday".equals(rangeType)) {
|
||||
return getStatSingleDate(shopId, currentDate.minusDays(1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addInfo(long shopId, long tableId, long count, BigDecimal amount) {
|
||||
ShopTableOrderStatistic statistic = getOne(new QueryWrapper().eq(ShopTableOrderStatistic::getShopId, shopId).eq(ShopTableOrderStatistic::getTableId, tableId)
|
||||
.eq(ShopTableOrderStatistic::getCreateDay, DateUtil.date().toDateStr()));
|
||||
if (statistic == null) {
|
||||
statistic = new ShopTableOrderStatistic();
|
||||
statistic.setShopId(shopId);
|
||||
statistic.setTableId(tableId);
|
||||
statistic.setCreateDay(DateUtil.date().toSqlDate());
|
||||
statistic.setOrderCount(count);
|
||||
statistic.setOrderAmount(amount);
|
||||
save(statistic);
|
||||
if (start.isAfter(currentDate)) {
|
||||
throw new CzgException("开始时间不能晚于当前时间");
|
||||
}
|
||||
return mapper.incrInfo(shopId, tableId, count, amount, DateUtil.date().toDateStr());
|
||||
if (start.equals(end)) {
|
||||
return getStatSingleDate(shopId, start);
|
||||
}
|
||||
|
||||
@Data
|
||||
private static class StatisticTask {
|
||||
private long successCount = 0;
|
||||
private BigDecimal successAmount = BigDecimal.ZERO;
|
||||
private long refundCount = 0;
|
||||
private BigDecimal refundAmount = BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void statistic(DateTime dateTime) {
|
||||
// 获取前一天的开始时间(00:00:00)
|
||||
DateTime startOfDay = DateUtil.beginOfDay(dateTime);
|
||||
// 获取前一天的结束时间(23:59:59)
|
||||
DateTime endOfDay = DateUtil.endOfDay(dateTime);
|
||||
List<Long> shopIdList = dataSummaryService.getShopIdList();
|
||||
if (CollUtil.isEmpty(shopIdList)) {
|
||||
return;
|
||||
}
|
||||
List<List<Long>> split = CollUtil.split(shopIdList, 5);
|
||||
for (List<Long> splitIdList : split) {
|
||||
splitIdList.parallelStream().forEach(shopId -> {
|
||||
TableSummaryParam param = new TableSummaryParam();
|
||||
param.setShopId(shopId);
|
||||
param.setBeginDate(startOfDay.toStringDefaultTimeZone());
|
||||
param.setEndDate(endOfDay.toStringDefaultTimeZone());
|
||||
// 删除之前统计数据
|
||||
getMapper()
|
||||
.deleteByQuery(
|
||||
new QueryWrapper()
|
||||
.eq("shop_id", shopId)
|
||||
.eq("create_day", dateTime.toDateStr()));
|
||||
// 重新统计数据
|
||||
List<TableSummaryInfoVo> list = shopTableOrderStatisticMapper.findSummaryList2(param);
|
||||
for (TableSummaryInfoVo dto : list) {
|
||||
ShopTableOrderStatistic entity = new ShopTableOrderStatistic();
|
||||
entity.setTableId(dto.getTableId());
|
||||
entity.setTableCode(dto.getTableCode());
|
||||
entity.setTableName(dto.getTableName());
|
||||
entity.setAreaName(dto.getAreaName());
|
||||
entity.setOrderCount(dto.getOrderCount());
|
||||
entity.setOrderAmount(dto.getOrderAmount());
|
||||
entity.setRefundCount(dto.getRefundCount());
|
||||
entity.setRefundAmount(dto.getRefundAmount());
|
||||
entity.setShopId(shopId);
|
||||
entity.setCreateDay(dateTime.toJdkDate());
|
||||
if (entity.getOrderCount() == 0L && entity.getRefundCount() == 0L) {
|
||||
log.info("店铺:{},{},没有要存档的台桌统计数据", shopId, dateTime.toDateStr());
|
||||
//包括当前时间
|
||||
if (end.isBefore(currentDate)) {
|
||||
return getStatDateRange(shopId, start, end);
|
||||
} else {
|
||||
save(entity);
|
||||
}
|
||||
}
|
||||
});
|
||||
List<ShopTableOrderStatistic> realTimeDataByDay = getRealTimeDataByDay(shopId, currentDate);
|
||||
List<ShopTableOrderStatistic> statDateRange = getStatDateRange(shopId, start, end);
|
||||
return ShopTableOrderStatistic.mergeWithStream(realTimeDataByDay, statDateRange);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void statisticAndInsert(Long shopId, LocalDate day) {
|
||||
List<ShopTableOrderStatistic> realTimeData = getRealTimeDataByDay(shopId, day);
|
||||
if (CollUtil.isNotEmpty(realTimeData)) {
|
||||
// 过滤掉没有有效数据的记录
|
||||
realTimeData = realTimeData.stream()
|
||||
.filter(ShopTableOrderStatistic::hasValidData)
|
||||
.toList();
|
||||
if (CollUtil.isNotEmpty(realTimeData)) {
|
||||
remove(QueryWrapper.create().eq(ShopTableOrderStatistic::getShopId, shopId).eq(ShopTableOrderStatistic::getCreateDay, day));
|
||||
saveBatch(realTimeData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ShopTableOrderStatistic> getRealTimeDataByDay(Long shopId, LocalDate day) {
|
||||
return mapper.getOnlineData(shopId, day);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ShopTableOrderStatistic> getStatSingleDate(Long shopId, LocalDate day) {
|
||||
return mapper.getStatSingleDate(shopId, day);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ShopTableOrderStatistic> getStatDateRange(Long shopId, LocalDate start, LocalDate end) {
|
||||
return mapper.getStatDateRange(shopId, start, end);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import cn.hutool.core.collection.CollUtil;
|
||||
import com.czg.order.param.TableSummaryParam;
|
||||
import com.czg.order.service.TableSummaryService;
|
||||
import com.czg.order.vo.TableSummaryExportVo;
|
||||
import com.czg.order.vo.TableSummaryInfoVo;
|
||||
import com.czg.service.order.mapper.ShopTableOrderStatisticMapper;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -28,10 +27,7 @@ public class TableSummaryServiceImpl implements TableSummaryService {
|
||||
@Resource
|
||||
private ShopTableOrderStatisticMapper shopTableOrderStatisticMapper;
|
||||
|
||||
@Override
|
||||
public List<TableSummaryInfoVo> summaryList(TableSummaryParam param) {
|
||||
return shopTableOrderStatisticMapper.findSummaryList(param);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<TableSummaryExportVo> summaryExportList(TableSummaryParam param) {
|
||||
|
||||
@@ -3,125 +3,4 @@
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.czg.service.order.mapper.ShopOrderStatisticMapper">
|
||||
<select id="getTradeData" resultType="com.czg.order.entity.ShopOrderStatistic">
|
||||
select
|
||||
sum(sale_amount) as sale_amount,
|
||||
sum(sale_count) as sale_count,
|
||||
sum(discount_amount) as discount_amount,
|
||||
sum(discount_count) as discount_count,
|
||||
sum(refund_amount) as refund_amount,
|
||||
sum(refund_count) as refund_count,
|
||||
sum(wechat_pay_count) as wechat_pay_count,
|
||||
sum(wechat_pay_amount) as wechat_pay_amount,
|
||||
sum(ali_pay_count) as ali_pay_count,
|
||||
sum(ali_pay_amount) as ali_pay_amount,
|
||||
sum(credit_pay_count) as credit_pay_count,
|
||||
sum(credit_pay_amount) as credit_pay_amount,
|
||||
sum(member_pay_count) as member_pay_count,
|
||||
sum(member_pay_amount) as member_pay_amount,
|
||||
sum(scan_pay_count) as scan_pay_count,
|
||||
sum(scan_pay_amount) as scan_pay_amount,
|
||||
sum(cash_pay_count) as cash_pay_count,
|
||||
sum(cash_pay_amount) as cash_pay_amount,
|
||||
sum(recharge_amount) as recharge_amount,
|
||||
avg(customer_unit_price) as customer_unit_price,
|
||||
avg(table_turnover_rate) as table_turnover_rate,
|
||||
sum(new_member_count) as new_member_count,
|
||||
max(update_time) as update_time
|
||||
from tb_shop_order_statistic
|
||||
where shop_id = #{shopId}
|
||||
<if test="beginDate != null and beginDate != ''">
|
||||
and create_day >= str_to_date(#{beginDate}, '%Y-%m-%d')
|
||||
</if>
|
||||
<if test="endDate != null and endDate != ''">
|
||||
<![CDATA[
|
||||
and create_day <= str_to_date(#{endDate}, '%Y-%m-%d')
|
||||
]]>
|
||||
</if>
|
||||
group by shop_id
|
||||
</select>
|
||||
<select id="getNewMemberCount" resultType="java.lang.Long">
|
||||
select count(1) from tb_shop_user where main_shop_id = #{mainShopId} and is_vip = 1
|
||||
<if test="beginDate != null and beginDate != ''">
|
||||
and join_time >= str_to_date(#{beginDate}, '%Y-%m-%d %H:%i:%s')
|
||||
</if>
|
||||
<if test="endDate != null and endDate != ''">
|
||||
<![CDATA[
|
||||
and join_time <= str_to_date(#{endDate}, '%Y-%m-%d %H:%i:%s')
|
||||
]]>
|
||||
</if>
|
||||
</select>
|
||||
<select id="getPayTypeAmountCount" resultType="java.util.Map">
|
||||
SELECT
|
||||
t1.pay_type as payType,
|
||||
sum(t1.pay_amount) as amount,
|
||||
sum(t1.refund_amount) as refund,
|
||||
count(case when t1.refund_amount>0 then 1 end) as refundCount,
|
||||
sum(t1.discount_amount) as discount,
|
||||
count(case when t1.discount_amount>0 then 1 end) as discountCount,
|
||||
count(*) as count
|
||||
FROM
|
||||
tb_order_info t1
|
||||
WHERE t1.shop_id = #{shopId}
|
||||
and t1.paid_time is not null
|
||||
<if test="beginDate != null and beginDate != ''">
|
||||
and t1.create_time >= str_to_date(#{beginDate}, '%Y-%m-%d %H:%i:%s')
|
||||
</if>
|
||||
<if test="endDate != null and endDate != ''">
|
||||
<![CDATA[
|
||||
and t1.create_time <= str_to_date(#{endDate}, '%Y-%m-%d %H:%i:%s')
|
||||
]]>
|
||||
</if>
|
||||
group by t1.pay_type
|
||||
</select>
|
||||
<select id="getVipRechargeAmountCount" resultType="java.util.Map">
|
||||
select
|
||||
t1.biz_code as bizCode,sum(t1.amount) as amount,count(*) as count
|
||||
from tb_shop_user_flow t1
|
||||
where t1.shop_id = #{shopId}
|
||||
<if test="beginDate != null and beginDate != ''">
|
||||
and t1.create_time >= str_to_date(#{beginDate}, '%Y-%m-%d %H:%i:%s')
|
||||
</if>
|
||||
<if test="endDate != null and endDate != ''">
|
||||
<![CDATA[
|
||||
and t1.create_time <= str_to_date(#{endDate}, '%Y-%m-%d %H:%i:%s')
|
||||
]]>
|
||||
</if>
|
||||
group by t1.biz_code
|
||||
</select>
|
||||
<select id="getCustomerUnitPrice" resultType="java.math.BigDecimal">
|
||||
SELECT
|
||||
ifnull((sum(t1.pay_amount)-sum(t1.refund_amount))/count(ifnull(case t1.seat_num when 0 then 1 end,1)),0.00) as customerUnitPrice
|
||||
FROM
|
||||
tb_order_info t1
|
||||
WHERE t1.shop_id = #{shopId}
|
||||
and t1.paid_time is not null
|
||||
<if test="beginDate != null and beginDate != ''">
|
||||
and t1.create_time >= str_to_date(#{beginDate}, '%Y-%m-%d %H:%i:%s')
|
||||
</if>
|
||||
<if test="endDate != null and endDate != ''">
|
||||
<![CDATA[
|
||||
and t1.create_time <= str_to_date(#{endDate}, '%Y-%m-%d %H:%i:%s')
|
||||
]]>
|
||||
</if>
|
||||
</select>
|
||||
<select id="getTableTurnoverRate" resultType="java.math.BigDecimal">
|
||||
SELECT
|
||||
ifnull((count(*)-count(DISTINCT t1.table_code))/count(DISTINCT t1.table_code)*100,0.00)
|
||||
FROM
|
||||
tb_order_info t1
|
||||
WHERE t1.shop_id = #{shopId}
|
||||
and t1.paid_time is not null
|
||||
<if test="beginDate != null and beginDate != ''">
|
||||
and t1.create_time >= str_to_date(#{beginDate}, '%Y-%m-%d %H:%i:%s')
|
||||
</if>
|
||||
<if test="endDate != null and endDate != ''">
|
||||
<![CDATA[
|
||||
and t1.create_time <= str_to_date(#{endDate}, '%Y-%m-%d %H:%i:%s')
|
||||
]]>
|
||||
</if>
|
||||
</select>
|
||||
<select id="getShopIdList" resultType="java.lang.Long">
|
||||
select id from tb_shop_info order by id
|
||||
</select>
|
||||
</mapper>
|
||||
|
||||
@@ -4,164 +4,120 @@
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.czg.service.order.mapper.ShopProdStatisticMapper">
|
||||
|
||||
<select id="findProdRandingSummaryPage" resultType="com.czg.order.vo.DataSummaryProductSaleRankingVo">
|
||||
select
|
||||
t1.prod_id,
|
||||
t2.name as product_name,
|
||||
sum(t1.sale_count) as number,
|
||||
sum(t1.sale_amount) as amount
|
||||
from tb_shop_prod_statistic t1
|
||||
left join tb_product t2 on t1.prod_id = t2.id
|
||||
where t1.shop_id = #{shopId}
|
||||
and t1.create_day in
|
||||
<foreach item="day" collection="days" open="(" separator="," close=")">
|
||||
#{day}
|
||||
</foreach>
|
||||
group by t1.prod_id,t2.name
|
||||
order by sum(t1.sale_count) desc
|
||||
</select>
|
||||
<select id="getSaleSummaryCount" resultType="com.czg.order.vo.SaleSummaryCountVo">
|
||||
select
|
||||
sum(t1.sale_count) as sale_count,
|
||||
sum(t1.sale_amount) as total_amount,
|
||||
sum(t1.refund_count) as refund_count,
|
||||
sum(t1.refund_amount) as refund_amount
|
||||
from tb_shop_prod_statistic t1
|
||||
left join tb_product t2 on t1.prod_id = t2.id
|
||||
where t1.shop_id = #{shopId}
|
||||
<if test="productName != null and productName != ''">
|
||||
and t2.name like concat('%', #{productName}, '%')
|
||||
</if>
|
||||
<if test="prodCategoryId != null">
|
||||
and t2.category_id = #{prodCategoryId}
|
||||
</if>
|
||||
<if test="beginDate != null and beginDate != ''">
|
||||
and t1.create_day >= str_to_date(#{beginDate}, '%Y-%m-%d')
|
||||
</if>
|
||||
<if test="endDate != null and endDate != ''">
|
||||
<![CDATA[
|
||||
and t1.create_day <= str_to_date(#{endDate}, '%Y-%m-%d')
|
||||
]]>
|
||||
</if>
|
||||
</select>
|
||||
<select id="findSaleSummaryList" resultType="com.czg.order.vo.SaleSummaryInfoVo">
|
||||
select
|
||||
t1.prod_id,
|
||||
max(t1.id) as id,
|
||||
t2.NAME AS product_name,
|
||||
t3.name as category_name,
|
||||
sum(t1.sale_count) as sale_count,
|
||||
sum(t1.sale_amount) as sale_amount,
|
||||
sum(t1.refund_count) as refund_count,
|
||||
sum(t1.refund_amount) as refund_amount
|
||||
from tb_shop_prod_statistic t1
|
||||
left join tb_product t2 on t1.prod_id = t2.id
|
||||
left join tb_shop_prod_category t3 on t2.category_id = t3.id
|
||||
where t1.shop_id = #{shopId}
|
||||
<if test="productName != null and productName != ''">
|
||||
and t2.name like concat('%', #{productName}, '%')
|
||||
</if>
|
||||
<if test="prodCategoryId != null">
|
||||
and t2.category_id = #{prodCategoryId}
|
||||
</if>
|
||||
<if test="beginDate != null and beginDate != ''">
|
||||
and t1.create_day >= str_to_date(#{beginDate}, '%Y-%m-%d')
|
||||
</if>
|
||||
<if test="endDate != null and endDate != ''">
|
||||
<![CDATA[
|
||||
and t1.create_day <= str_to_date(#{endDate}, '%Y-%m-%d')
|
||||
]]>
|
||||
</if>
|
||||
group by t1.prod_id
|
||||
ORDER BY sum( t1.sale_count ) DESC,max(t1.id) DESC
|
||||
</select>
|
||||
<select id="getSaleSummaryCount2" resultType="com.czg.order.vo.SaleSummaryCountVo">
|
||||
<select id="selectProStatByDay" resultType="com.czg.order.entity.ShopProdStatistic">
|
||||
SELECT
|
||||
sum(t1.pay_amount) as totalAmount,
|
||||
sum(t1.refund_amount) as refundAmount,
|
||||
count(*) as saleCount,
|
||||
count(case when t1.refund_amount > 0 then 1 end) as refundCount
|
||||
CASE WHEN detail.is_temporary = 1 THEN -1 ELSE detail.product_id END AS prodId,
|
||||
CASE WHEN detail.is_temporary = 1 THEN '临时菜' ELSE prod.name END AS productName,
|
||||
sum(detail.num-detail.return_num) as saleCount,
|
||||
sum(detail.pay_amount) as saleAmount,
|
||||
sum(detail.refund_num) refundCount,
|
||||
sum(detail.return_amount) refundAmount
|
||||
FROM
|
||||
tb_order_info t1
|
||||
left join (
|
||||
SELECT
|
||||
x1.order_id,
|
||||
concat( ',', GROUP_CONCAT( x2.category_id ), ',' ) AS category_id,
|
||||
GROUP_CONCAT( x1.product_name ) AS product_name
|
||||
FROM
|
||||
tb_order_detail x1
|
||||
LEFT JOIN tb_product x2 ON x1.product_id = x2.id
|
||||
GROUP BY x1.order_id
|
||||
) t2 on t1.id = t2.order_id
|
||||
where t1.shop_id = #{shopId}
|
||||
and t1.status in ('part-refund','refund','done')
|
||||
tb_order_info `order`
|
||||
INNER JOIN tb_order_detail detail ON `order`.id = detail.order_id
|
||||
LEFT JOIN tb_product prod ON detail.product_id = prod.id
|
||||
WHERE
|
||||
`order`.shop_id = #{shopId}
|
||||
AND `order`.trade_day = #{tradeDay}
|
||||
AND `order`.paid_time IS NOT NULL
|
||||
<if test="productName != null and productName != ''">
|
||||
and t2.product_name like concat('%', #{productName}, '%')
|
||||
</if>
|
||||
<if test="prodCategoryId != null">
|
||||
and t2.category_id like concat('%,', #{prodCategoryId}, ',%')
|
||||
</if>
|
||||
<if test="beginDate != null and beginDate != ''">
|
||||
and t1.create_time >= str_to_date(#{beginDate}, '%Y-%m-%d %H:%i:%s')
|
||||
</if>
|
||||
<if test="endDate != null and endDate != ''">
|
||||
<![CDATA[
|
||||
and t1.create_time <= str_to_date(#{endDate}, '%Y-%m-%d %H:%i:%s')
|
||||
]]>
|
||||
AND detail.name LIKE CONCAT('%',#{productName},'%')
|
||||
</if>
|
||||
GROUP BY prodId
|
||||
</select>
|
||||
<select id="findSaleSummaryList2" resultType="com.czg.order.vo.SaleSummaryInfoVo">
|
||||
|
||||
<select id="getProdStatSingleDate" resultType="com.czg.order.entity.ShopProdStatistic">
|
||||
SELECT
|
||||
t1.product_id,
|
||||
t1.product_name as productName,
|
||||
t3.name as category_name,
|
||||
sum( t1.num ) AS saleCount,
|
||||
sum( t1.pay_amount ) AS saleAmount,
|
||||
sum( t1.return_num ) AS refundCount,
|
||||
sum( t1.return_amount ) AS refundAmount
|
||||
tb_shop_prod_statistic.*,
|
||||
CASE WHEN tb_shop_prod_statistic.prod_id = -1 THEN '临时菜' ELSE prod.name END AS productName
|
||||
FROM
|
||||
tb_order_detail t1
|
||||
left join tb_product t2 on t1.product_id = t2.id
|
||||
left join tb_shop_prod_category t3 on t2.category_id = t3.id
|
||||
where t1.shop_id = #{shopId}
|
||||
and t1.status in ('part-refund','refund','done')
|
||||
tb_shop_prod_statistic
|
||||
LEFT JOIN tb_product prod ON tb_shop_prod_statistic.prod_id = prod.id
|
||||
WHERE
|
||||
tb_shop_prod_statistic.shop_id = #{shopId}
|
||||
AND tb_shop_prod_statistic.create_day = #{day}
|
||||
<if test="productName != null and productName != ''">
|
||||
and t1.product_name like concat('%', #{productName}, '%')
|
||||
AND prod.name LIKE CONCAT('%',#{productName},'%')
|
||||
</if>
|
||||
<if test="prodCategoryId != null">
|
||||
and t2.category_id = #{prodCategoryId}
|
||||
</if>
|
||||
<if test="beginDate != null and beginDate != ''">
|
||||
and t1.create_time >= str_to_date(#{beginDate}, '%Y-%m-%d %H:%i:%s')
|
||||
</if>
|
||||
<if test="endDate != null and endDate != ''">
|
||||
<![CDATA[
|
||||
and t1.create_time <= str_to_date(#{endDate}, '%Y-%m-%d %H:%i:%s')
|
||||
]]>
|
||||
</if>
|
||||
GROUP BY t1.product_id,t1.product_name
|
||||
ORDER BY sum( t1.num ) DESC,max(t1.product_id) DESC
|
||||
ORDER BY
|
||||
tb_shop_prod_statistic.sale_count DESC, tb_shop_prod_statistic.prod_id
|
||||
</select>
|
||||
<select id="findProdRandingSummaryPage2" resultType="com.czg.order.vo.DataSummaryProductSaleRankingVo">
|
||||
select
|
||||
t1.product_id,
|
||||
t1.product_name,
|
||||
sum(t1.num) as number,
|
||||
sum(t1.pay_amount) as amount,
|
||||
sum(t1.return_num) AS refundCount,
|
||||
sum(t1.return_amount) AS refundAmount
|
||||
from tb_order_detail t1
|
||||
where t1.shop_id = #{shopId}
|
||||
and t1.status in ('part-refund','refund','done')
|
||||
<if test="beginDate != null and beginDate != ''">
|
||||
and t1.create_time >= str_to_date(#{beginDate}, '%Y-%m-%d %H:%i:%s')
|
||||
<select id="getProdStatDateRange" resultType="com.czg.order.entity.ShopProdStatistic">
|
||||
SELECT
|
||||
tb_shop_prod_statistic.prod_id as prodId,
|
||||
CASE WHEN prod_id = -1 THEN '临时菜' ELSE prod.name END AS productName,
|
||||
tb_shop_prod_statistic.shop_id as shopId,
|
||||
SUM(tb_shop_prod_statistic.sale_count) AS saleCount,
|
||||
SUM(tb_shop_prod_statistic.sale_amount) AS saleAmount,
|
||||
SUM(tb_shop_prod_statistic.refund_count) AS refundCount,
|
||||
SUM(tb_shop_prod_statistic.refund_amount) AS refundAmount
|
||||
FROM
|
||||
tb_shop_prod_statistic
|
||||
LEFT JOIN tb_product prod ON tb_shop_prod_statistic.prod_id = prod.id
|
||||
WHERE
|
||||
tb_shop_prod_statistic.shop_id = #{shopId}
|
||||
AND tb_shop_prod_statistic.create_day >= #{start}
|
||||
AND tb_shop_prod_statistic.create_day <= #{end}
|
||||
<if test="productName != null and productName != ''">
|
||||
AND prod.name LIKE CONCAT('%',#{productName},'%')
|
||||
</if>
|
||||
<if test="endDate != null and endDate != ''">
|
||||
<![CDATA[
|
||||
and t1.create_time <= str_to_date(#{endDate}, '%Y-%m-%d %H:%i:%s')
|
||||
]]>
|
||||
</if>
|
||||
GROUP BY t1.product_id,t1.product_name
|
||||
order by sum(t1.num) desc
|
||||
GROUP BY
|
||||
tb_shop_prod_statistic.prod_id
|
||||
ORDER BY
|
||||
tb_shop_prod_statistic.sale_count DESC, tb_shop_prod_statistic.prod_id
|
||||
</select>
|
||||
|
||||
|
||||
<select id="summaryCountByDay" resultType="com.czg.order.vo.SaleSummaryCountVo">
|
||||
SELECT
|
||||
sum(detail.num-detail.return_num) as saleCount,
|
||||
sum(detail.pay_amount) as saleAmount,
|
||||
sum(detail.refund_num) refundCount,
|
||||
sum(detail.return_amount) refundAmount
|
||||
FROM
|
||||
tb_order_info `order`
|
||||
INNER JOIN tb_order_detail detail ON `order`.id = detail.order_id
|
||||
LEFT JOIN tb_product prod ON detail.product_id = prod.id
|
||||
WHERE
|
||||
`order`.shop_id = #{shopId}
|
||||
AND `order`.trade_day = #{day}
|
||||
AND `order`.paid_time IS NOT NULL
|
||||
<if test="productName != null and productName != ''">
|
||||
AND detail.name LIKE CONCAT('%',#{productName},'%')
|
||||
</if>
|
||||
</select>
|
||||
<select id="summaryCountSingleDate" resultType="com.czg.order.vo.SaleSummaryCountVo">
|
||||
SELECT
|
||||
sum(tb_shop_prod_statistic.sale_count) AS saleCount,
|
||||
sum(tb_shop_prod_statistic.sale_amount) AS saleAmount,
|
||||
sum(tb_shop_prod_statistic.refund_count) AS refundCount,
|
||||
sum(tb_shop_prod_statistic.refund_amount) AS refundAmount
|
||||
FROM
|
||||
tb_shop_prod_statistic
|
||||
WHERE
|
||||
tb_shop_prod_statistic.shop_id = #{shopId}
|
||||
AND tb_shop_prod_statistic.create_day = #{day}
|
||||
<if test="productName != null and productName != ''">
|
||||
AND prod.name LIKE CONCAT('%',#{productName},'%')
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="summaryCountDateRange" resultType="com.czg.order.vo.SaleSummaryCountVo">
|
||||
SELECT
|
||||
sum(tb_shop_prod_statistic.sale_count) AS saleCount,
|
||||
sum(tb_shop_prod_statistic.sale_amount) AS saleAmount,
|
||||
sum(tb_shop_prod_statistic.refund_count) AS refundCount,
|
||||
sum(tb_shop_prod_statistic.refund_amount) AS refundAmount
|
||||
FROM
|
||||
tb_shop_prod_statistic
|
||||
WHERE
|
||||
tb_shop_prod_statistic.shop_id = #{shopId}
|
||||
AND tb_shop_prod_statistic.create_day >= #{start}
|
||||
AND tb_shop_prod_statistic.create_day <= #{end}
|
||||
<if test="productName != null and productName != ''">
|
||||
AND prod.name LIKE CONCAT('%',#{productName},'%')
|
||||
</if>
|
||||
</select>
|
||||
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -3,81 +3,7 @@
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.czg.service.order.mapper.ShopTableOrderStatisticMapper">
|
||||
<update id="incrInfo">
|
||||
update tb_shop_table_order_statistic set order_count=order_count + #{count}, order_amount=order_amount + #{count}
|
||||
where shop_id = #{shopId} and table_id = #{tableId} and create_day=#{date}
|
||||
</update>
|
||||
|
||||
<select id="selectSummary" resultType="com.czg.order.entity.ShopTableOrderStatistic">
|
||||
SELECT
|
||||
a.table_id as tableId, b.name as name, sum(a.order_count) as orderCount, sum(a.order_amount) as orderAmount
|
||||
FROM
|
||||
tb_shop_table_order_statistic as a
|
||||
left join tb_shop_table as b on a.table_id = b.id
|
||||
WHERE
|
||||
a.shop_id = #{shopId}
|
||||
<if test="startTime != null and startTime != ''">
|
||||
AND a.create_day >= #{startTime}
|
||||
</if>
|
||||
<if test="endTime != null and endTime != ''">
|
||||
and a.create_day <= #{endTime}
|
||||
</if>
|
||||
GROUP BY
|
||||
a.table_id
|
||||
order by a.id desc
|
||||
</select>
|
||||
<select id="findSummaryList" resultType="com.czg.order.vo.TableSummaryInfoVo">
|
||||
select
|
||||
t1.table_code,
|
||||
t1.table_id,
|
||||
t1.table_name as table_name,
|
||||
t1.area_name as area_name,
|
||||
sum(t1.order_count) as order_count,
|
||||
sum(t1.order_amount) as order_amount,
|
||||
ifnull(sum(t1.refund_count),0) as refund_count,
|
||||
ifnull(sum(t1.refund_amount),0) as refund_amount
|
||||
from tb_shop_table_order_statistic t1
|
||||
left join tb_shop_table t2 on t1.table_id = t2.id
|
||||
left join tb_shop_table_area t3 on t2.area_id = t3.id
|
||||
where t1.shop_id = #{shopId}
|
||||
<if test="beginDate != null and beginDate != ''">
|
||||
AND t1.create_day >= str_to_date(#{beginDate}, '%Y-%m-%d')
|
||||
</if>
|
||||
<if test="endDate != null and endDate != ''">
|
||||
and t1.create_day <= str_to_date(#{endDate}, '%Y-%m-%d')
|
||||
</if>
|
||||
group by t1.table_code
|
||||
order by sum(t1.order_count) desc,sum(t1.order_amount) desc
|
||||
</select>
|
||||
<select id="findSummaryList2" resultType="com.czg.order.vo.TableSummaryInfoVo">
|
||||
SELECT
|
||||
t1.table_code,
|
||||
t2.id as table_id,
|
||||
ifnull(t2.NAME,t1.table_code) AS table_name,
|
||||
ifnull(t3.NAME,'未知') AS area_name,
|
||||
count( t1.id ) AS order_count,
|
||||
sum( t1.pay_amount ) as order_amount,
|
||||
ifnull(count( case when t1.refund_amount > 0 then 1 end),0) AS refund_count,
|
||||
ifnull( sum( t1.refund_amount ), 0 ) AS refund_amount
|
||||
FROM
|
||||
tb_order_info t1
|
||||
LEFT JOIN tb_shop_table t2 ON t1.table_code = t2.table_code and t1.shop_id = t2.shop_id
|
||||
LEFT JOIN tb_shop_table_area t3 ON t2.area_id = t3.id
|
||||
where t1.shop_id = #{shopId}
|
||||
and t1.table_code is not null
|
||||
and t2.table_code is not null
|
||||
and t2.table_code != ''
|
||||
and t2.name is not null
|
||||
and t1.paid_time is not null
|
||||
<if test="beginDate != null and beginDate != ''">
|
||||
AND t1.create_time >= str_to_date(#{beginDate}, '%Y-%m-%d %H:%i:%s')
|
||||
</if>
|
||||
<if test="endDate != null and endDate != ''">
|
||||
and t1.create_time <= str_to_date(#{endDate}, '%Y-%m-%d %H:%i:%s')
|
||||
</if>
|
||||
GROUP BY t1.table_code
|
||||
order by count( t1.id ) desc,sum( t1.pay_amount ) desc
|
||||
</select>
|
||||
<select id="findSummaryExportList" resultType="com.czg.order.vo.TableSummaryExportVo">
|
||||
SELECT
|
||||
t.product_name,
|
||||
|
||||
Reference in New Issue
Block a user