diff --git a/cash-api/account-server/src/main/java/com/czg/controller/admin/ShopShareController.java b/cash-api/account-server/src/main/java/com/czg/controller/admin/ShopShareController.java deleted file mode 100644 index 978076aec..000000000 --- a/cash-api/account-server/src/main/java/com/czg/controller/admin/ShopShareController.java +++ /dev/null @@ -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 get() { -// return CzgResult.success(shopShareService.get(StpKit.USER.getShopId())); -// } -// -// /** -// * 修改分享奖励配置 -// */ -// @SaAdminCheckPermission(value = "shopShare:add", name = "分享好友信息添加") -// @PostMapping -// public CzgResult 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> record(String key, Integer status) { -// return CzgResult.success(shopShareService.recordPage(StpKit.USER.getShopId(), key, status)); -// } -//} diff --git a/cash-api/account-server/src/main/java/com/czg/controller/admin/ShopStatisticController.java b/cash-api/account-server/src/main/java/com/czg/controller/admin/ShopStatisticController.java deleted file mode 100644 index 277b4e724..000000000 --- a/cash-api/account-server/src/main/java/com/czg/controller/admin/ShopStatisticController.java +++ /dev/null @@ -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)); - } -} diff --git a/cash-api/order-server/src/main/java/com/czg/controller/OrderPayController.java b/cash-api/order-server/src/main/java/com/czg/controller/OrderPayController.java index 6d1fb87f2..9974a924f 100644 --- a/cash-api/order-server/src/main/java/com/czg/controller/OrderPayController.java +++ b/cash-api/order-server/src/main/java/com/czg/controller/OrderPayController.java @@ -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 queryOrderStatus(Long orderId) { diff --git a/cash-api/order-server/src/main/java/com/czg/controller/StatisticTaskController.java b/cash-api/order-server/src/main/java/com/czg/controller/StatisticTaskController.java new file mode 100644 index 000000000..1490a2e56 --- /dev/null +++ b/cash-api/order-server/src/main/java/com/czg/controller/StatisticTaskController.java @@ -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"; + } +} diff --git a/cash-api/order-server/src/main/java/com/czg/controller/admin/DataSummaryController.java b/cash-api/order-server/src/main/java/com/czg/controller/admin/DataSummaryController.java index fb9c2148a..fd97eb4cb 100644 --- a/cash-api/order-server/src/main/java/com/czg/controller/admin/DataSummaryController.java +++ b/cash-api/order-server/src/main/java/com/czg/controller/admin/DataSummaryController.java @@ -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 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> getProductSaleData(DataSummaryProductSaleParam param) { + public CzgResult> getProductSaleData(DataSummaryTradeParam param) { ValidatorUtil.validateEntity(param, DefaultGroup.class); Long shopId = StpKit.USER.getShopId(); if (param.getShopId() == null) { param.setShopId(shopId); } - Page data = dataSummaryService.getProductSaleRankingPage(param); + List data = prodStatisticService.getArchiveTradeDataBy20(param.getShopId(), param.getRangeType(), param.getBeginDate(), param.getEndDate()); return CzgResult.success(data); } @@ -77,32 +87,30 @@ public class DataSummaryController { */ @GetMapping("dateAmount") @OperationLog("销售趋势柱状图 左下") -// @SaStaffCheckPermission("yun_xu_cha_kan_jing_ying_shu_ju") @SaAdminCheckPermission(value = "dataSummary:dateAmount", name = "销售趋势柱状图 左下") - public CzgResult getDateAmount(@RequestParam Integer day, @RequestParam(required = false) Long shopId) { + public CzgResult> 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 data = orderStatisticService.getDateAmount(shopId, day); return CzgResult.success(data); } /** * 支付占比饼图 左下 * - * @param day 天数 + * @param day 天数 * @param shopId 店铺id */ @GetMapping("datePayType") @OperationLog("支付占比饼图 左下") -// @SaStaffCheckPermission("yun_xu_cha_kan_jing_ying_shu_ju") @SaAdminCheckPermission(value = "dataSummary:datePayType", name = "支付占比饼图 左下2") - public CzgResult shopSummaryPayType(@RequestParam Integer day, @RequestParam(required = false) Long shopId) { + public CzgResult> 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 data = orderStatisticService.getSummaryPayTypeData(shopId, day); return CzgResult.success(data); } } diff --git a/cash-api/order-server/src/main/java/com/czg/controller/admin/SaleSummaryController.java b/cash-api/order-server/src/main/java/com/czg/controller/admin/SaleSummaryController.java index b08584fc5..c53a7164c 100644 --- a/cash-api/order-server/src/main/java/com/czg/controller/admin/SaleSummaryController.java +++ b/cash-api/order-server/src/main/java/com/czg/controller/admin/SaleSummaryController.java @@ -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 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> summaryPage(SaleSummaryCountParam param) { - Long shopId = StpKit.USER.getShopId(0L); + public CzgResult> summaryPage(SaleSummaryCountParam param) { + Long shopId = StpKit.USER.getShopId(); if (param.getShopId() == null) { param.setShopId(shopId); } - Page page = saleSummaryService.summaryPage(param); - return CzgResult.success(page); - } - - /** - * 导出 - */ - @ResponseExcel(name = "销售统计明细") - @GetMapping("/export") - @OperationLog("导出") - //@SaAdminCheckPermission("saleSummary:export") - public List summaryExport(SaleSummaryCountParam param) { - Long shopId = StpKit.USER.getShopId(0L); - if (param.getShopId() == null) { - param.setShopId(shopId); - } - return saleSummaryService.summaryList(param); + List list = prodStatisticService.getArchiveTradeData( + param.getShopId(),param.getProductName(), param.getRangeType(), param.getBeginDate(), param.getEndDate()); + return CzgResult.success(list); } } diff --git a/cash-api/order-server/src/main/java/com/czg/controller/admin/TableSummaryController.java b/cash-api/order-server/src/main/java/com/czg/controller/admin/TableSummaryController.java index 0fbc03098..a94faa746 100644 --- a/cash-api/order-server/src/main/java/com/czg/controller/admin/TableSummaryController.java +++ b/cash-api/order-server/src/main/java/com/czg/controller/admin/TableSummaryController.java @@ -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> summaryList(TableSummaryParam param) { - Long shopId = StpKit.USER.getShopId(0L); + public CzgResult> summaryList(DataSummaryTradeParam param) { + Long shopId = StpKit.USER.getShopId(); if (param.getShopId() == null) { param.setShopId(shopId); } - List data = tableSummaryService.summaryList(param); - return CzgResult.success(data); + List archiveTradeData = tableOrderStatisticService.getArchiveTradeData(param.getShopId(), param.getRangeType(), param.getBeginDate(), param.getEndDate()); + return CzgResult.success(archiveTradeData); } /** diff --git a/cash-api/order-server/src/main/java/com/czg/task/StatisticTask.java b/cash-api/order-server/src/main/java/com/czg/task/StatisticTask.java index fe7b2377e..43d11057f 100644 --- a/cash-api/order-server/src/main/java/com/czg/task/StatisticTask.java +++ b/cash-api/order-server/src/main/java/com/czg/task/StatisticTask.java @@ -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 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()); - } - - @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 statisticHistoryData() { - // 指定开始日期 - LocalDate startDate = LocalDate.of(2024, 3, 1); - // 指定结束日期 - LocalDate endDate = LocalDate.now(); - List shopIdList = DbChain.table("tb_shop_info").select("id").objListAs(Long.class); - List> split = CollUtil.split(shopIdList, 10); -// 1.清除历史统计的数据 - for (List 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)); - }); + public void statisticAndInsertProd(Long shopId, LocalDate date) { + try { + shopProdStatisticService.statisticAndInsert(shopId, date); + } catch (Exception e) { + log.error("统计商品数据失败,店铺id:{},日期:{}", shopId, date, e); } - // 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); - }); } + + public void statisticAndInsertTable(Long shopId, LocalDate date) { + try { + shopTableOrderStatisticService.statisticAndInsert(shopId, date); + } catch (Exception e) { + log.error("统计桌台数据失败,店铺id:{},日期:{}", shopId, date, e); + } + } + + } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/dto/OrderDetailDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/OrderDetailDTO.java index 7f33d9f71..dfed88831 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/account/dto/OrderDetailDTO.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/OrderDetailDTO.java @@ -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; diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/entity/ShopProdStatistic.java b/cash-common/cash-common-service/src/main/java/com/czg/account/entity/ShopProdStatistic.java deleted file mode 100644 index 95799a51c..000000000 --- a/cash-common/cash-common-service/src/main/java/com/czg/account/entity/ShopProdStatistic.java +++ /dev/null @@ -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; - -} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopInfoService.java b/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopInfoService.java index c98237820..34bc98890 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopInfoService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopInfoService.java @@ -16,6 +16,7 @@ import java.util.List; */ public interface ShopInfoService extends IService { + @Override ShopInfo getById(Serializable id) throws CzgException; Page get(PageDTO pageDTO, String shopName, Integer status, Integer isHeadShop); @@ -40,4 +41,11 @@ public interface ShopInfoService extends IService { List getByMainIdOrList(Long mainShopId, List shopIdList, String shopName); BigDecimal updateAmount(Long id, BigDecimal amount); + + /** + * 获取所有未删除的 过期时间>三天前 店铺id列表 + * + * @return 店铺id列表 + */ + List getShopIdList(); } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopProdStatisticService.java b/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopProdStatisticService.java deleted file mode 100644 index a8462f8d9..000000000 --- a/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopProdStatisticService.java +++ /dev/null @@ -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 { - - Page pageInfo(Long shopId, String name, String classifyId, String startTime, String endTime); -} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopShareService.java b/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopShareService.java deleted file mode 100644 index 96c282778..000000000 --- a/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopShareService.java +++ /dev/null @@ -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 { -// -// ShopShareVO get(Long shopId); -// -// Boolean add(Long shopId, ShopShareDTO shopShareDTO); -// -// Page recordPage(Long shopId, String key, Integer status); -//} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/vo/ShopProdStatisticVO.java b/cash-common/cash-common-service/src/main/java/com/czg/account/vo/ShopProdStatisticVO.java deleted file mode 100644 index b8a067eda..000000000 --- a/cash-common/cash-common-service/src/main/java/com/czg/account/vo/ShopProdStatisticVO.java +++ /dev/null @@ -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; -} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/dto/OrderInfoDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/order/dto/OrderInfoDTO.java index c6dcf5c0a..411cb3fb6 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/dto/OrderInfoDTO.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/dto/OrderInfoDTO.java @@ -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; diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/dto/OrderInfoQueryDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/order/dto/OrderInfoQueryDTO.java index da9344dcb..020e29c9b 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/dto/OrderInfoQueryDTO.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/dto/OrderInfoQueryDTO.java @@ -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; diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderDetail.java b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderDetail.java index 4723fee11..fc724af18 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderDetail.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderDetail.java @@ -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; diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderInfo.java b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderInfo.java index 4ba5465d4..3477e1f62 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderInfo.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderInfo.java @@ -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); + } } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopOrderStatistic.java b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopOrderStatistic.java index 88a1a55cd..e6d3e33f7 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopOrderStatistic.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopOrderStatistic.java @@ -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; + } + } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopProdStatistic.java b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopProdStatistic.java index e87bacbad..38ed83197 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopProdStatistic.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopProdStatistic.java @@ -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; + } + } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopTableOrderStatistic.java b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopTableOrderStatistic.java index af9648f8c..24bd09019 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopTableOrderStatistic.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopTableOrderStatistic.java @@ -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 mergeWithStream( + List realTimeData, + List 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); } } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/enums/PayEnums.java b/cash-common/cash-common-service/src/main/java/com/czg/order/enums/PayEnums.java index fe4350729..094b34ed5 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/enums/PayEnums.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/enums/PayEnums.java @@ -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 "未知支付方式"; - } - } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/param/DataSummaryProductSaleParam.java b/cash-common/cash-common-service/src/main/java/com/czg/order/param/DataSummaryProductSaleParam.java deleted file mode 100644 index a7ae4cb24..000000000 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/param/DataSummaryProductSaleParam.java +++ /dev/null @@ -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 days; - /** - * 店铺id - */ - private Long shopId; - /** - * 开始日期 - */ - @JSONField(serialize = false) - private String beginDate; - /** - * 结束日期 - */ - @JSONField(serialize = false) - private String endDate; - -} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/param/DataSummaryTradeParam.java b/cash-common/cash-common-service/src/main/java/com/czg/order/param/DataSummaryTradeParam.java index 6386984c3..dbc613de6 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/param/DataSummaryTradeParam.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/param/DataSummaryTradeParam.java @@ -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 */ diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/param/SaleSummaryCountParam.java b/cash-common/cash-common-service/src/main/java/com/czg/order/param/SaleSummaryCountParam.java index 671680549..59c4c35a5 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/param/SaleSummaryCountParam.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/param/SaleSummaryCountParam.java @@ -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; } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/service/DataSummaryService.java b/cash-common/cash-common-service/src/main/java/com/czg/order/service/DataSummaryService.java deleted file mode 100644 index 387702ca1..000000000 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/service/DataSummaryService.java +++ /dev/null @@ -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 getProductSaleRankingPage(DataSummaryProductSaleParam param); - - DataSummaryDateAmountVo getSummaryAmountData(Long shopId,Integer day); - - DataSummaryPayTypeVo getSummaryPayTypeData(Long shopId, Integer day); - - List getShopIdList(); -} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/service/SaleSummaryService.java b/cash-common/cash-common-service/src/main/java/com/czg/order/service/SaleSummaryService.java deleted file mode 100644 index ae9fedf3f..000000000 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/service/SaleSummaryService.java +++ /dev/null @@ -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 summaryPage(SaleSummaryCountParam param); - List summaryList(SaleSummaryCountParam param); - - -} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/service/ShopOrderStatisticService.java b/cash-common/cash-common-service/src/main/java/com/czg/order/service/ShopOrderStatisticService.java index 68dd4c8ab..25dbcec37 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/service/ShopOrderStatisticService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/service/ShopOrderStatisticService.java @@ -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 { - 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 getDateAmount(Long shopId, Integer day); + /** + * 获取支付方式数据 + */ + List 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); } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/service/ShopProdStatisticService.java b/cash-common/cash-common-service/src/main/java/com/czg/order/service/ShopProdStatisticService.java index 6e1b37906..a6402bce8 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/service/ShopProdStatisticService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/service/ShopProdStatisticService.java @@ -1,17 +1,72 @@ 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; + /** - * 服务层。 + * 服务层。 * * @author zs * @since 2025-03-07 */ public interface ShopProdStatisticService extends IService { - 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 getArchiveTradeData(Long shopId, String productName, String rangeType, LocalDate start, LocalDate end); + List getArchiveTradeDataBy20(Long shopId, String rangeType, LocalDate start, LocalDate end); + + //------------------------------------------------------------下列为 后台使用------------------------------------------------------------ + + /** + * 统计某天数据并插入数据库 + * + * @param day + */ + void statisticAndInsert(Long shopId, LocalDate day); + + /** + * 实时统计某天数据 + */ + List getRealTimeDataByDay(Long shopId, LocalDate day, String productName); + + /** + * 获取某一天的数据 历史数据 + * 从ShopOrderStatistic 表中查询 + */ + List getProdStatSingleDate(Long shopId, LocalDate day, String productName); + + /** + * 统计 某时间段数据 总和 不包括当日实时数据 + * + * @param start 开始时间 + * @param end 结束时间 + */ + List getProdStatDateRange(Long shopId, LocalDate start, LocalDate end, String productName); } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/service/ShopTableOrderStatisticService.java b/cash-common/cash-common-service/src/main/java/com/czg/order/service/ShopTableOrderStatisticService.java index 15f3314bc..788a75ad9 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/service/ShopTableOrderStatisticService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/service/ShopTableOrderStatisticService.java @@ -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 { - Page summary(Long shopId, String startTime, String endTime); /** - * 增加每日统计信息 - * @param shopId 店铺id - * @param tableId 台桌id - * @param count 订单数量 - * @param amount 订单总金额 - * @return 是否成功 + * @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 今天/昨天不用传 */ - boolean addInfo(long shopId, long tableId, long count, BigDecimal amount); + List getArchiveTradeData(Long shopId, String rangeType, LocalDate start, LocalDate end); - void statistic(DateTime dateTime); + //------------------------------------------------------------下列为 后台使用------------------------------------------------------------ + + /** + * 统计某天数据并插入数据库 + * + * @param day + */ + void statisticAndInsert(Long shopId, LocalDate day); + + /** + * 实时统计某天数据 + */ + List getRealTimeDataByDay(Long shopId, LocalDate day); + + /** + * 获取某一天的数据 历史数据 + * 从ShopOrderStatistic 表中查询 + */ + List getStatSingleDate(Long shopId, LocalDate day); + + /** + * 统计 某时间段数据 总和 不包括当日实时数据 + * + * @param start 开始时间 + * @param end 结束时间 + */ + List getStatDateRange(Long shopId, LocalDate start, LocalDate end); } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/service/TableSummaryService.java b/cash-common/cash-common-service/src/main/java/com/czg/order/service/TableSummaryService.java index 0296178a5..f2094d99a 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/service/TableSummaryService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/service/TableSummaryService.java @@ -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 summaryList(TableSummaryParam param); List summaryExportList(TableSummaryParam param); diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/vo/CountPayTypeVo.java b/cash-common/cash-common-service/src/main/java/com/czg/order/vo/CountPayTypeVo.java new file mode 100644 index 000000000..f0c096e96 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/vo/CountPayTypeVo.java @@ -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 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 mergePayTypeData(Map realTimeData, + Map historyData) { + + List result = new ArrayList<>(); + + for (Map.Entry 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 data, String key) { + if (data == null || data.isEmpty()) { + return null; + } + return data.get(key); + } +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/vo/DataSummaryDateAmountVo.java b/cash-common/cash-common-service/src/main/java/com/czg/order/vo/DataSummaryDateAmountVo.java deleted file mode 100644 index 6283e2c97..000000000 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/vo/DataSummaryDateAmountVo.java +++ /dev/null @@ -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 total = new ArrayList<>(); - -} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/vo/DataSummaryPayTypeVo.java b/cash-common/cash-common-service/src/main/java/com/czg/order/vo/DataSummaryPayTypeVo.java deleted file mode 100644 index 3298da9ab..000000000 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/vo/DataSummaryPayTypeVo.java +++ /dev/null @@ -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 countPayType = new ArrayList<>(); - - /** - * CountPayTypeVo - */ - @NoArgsConstructor - @Data - public static class CountPayTypeVo { - /** - * 笔数 - */ - private Integer count; - /** - * 支付方式 - */ - private String payType; - } -} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/vo/OrderInfoVo.java b/cash-common/cash-common-service/src/main/java/com/czg/order/vo/OrderInfoVo.java index b24a782ec..b7ce096d0 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/vo/OrderInfoVo.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/vo/OrderInfoVo.java @@ -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; diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/vo/SaleSummaryCountVo.java b/cash-common/cash-common-service/src/main/java/com/czg/order/vo/SaleSummaryCountVo.java index 8632a3a8a..8504c6659 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/vo/SaleSummaryCountVo.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/vo/SaleSummaryCountVo.java @@ -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 diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/vo/SaleSummaryInfoVo.java b/cash-common/cash-common-service/src/main/java/com/czg/order/vo/SaleSummaryInfoVo.java deleted file mode 100644 index 5781a06ec..000000000 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/vo/SaleSummaryInfoVo.java +++ /dev/null @@ -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; -} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/vo/TotalVo.java b/cash-common/cash-common-service/src/main/java/com/czg/order/vo/TotalVo.java index 8b9c4741c..85ed034db 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/vo/TotalVo.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/vo/TotalVo.java @@ -6,15 +6,18 @@ 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 */ @NoArgsConstructor @Data -public class TotalVo implements Serializable { +public class TotalVo implements Serializable { @Serial private static final long serialVersionUID = 1L; @@ -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 mergeAndFillData(TotalVo onlineData, List historyData, + LocalDate startDate, LocalDate endDate) { + // 创建日期到数据的映射,方便查找 + Map dataMap = new HashMap<>(); + + // 将历史数据放入映射 + for (TotalVo vo : historyData) { + if (vo.getTradeDay() != null) { + dataMap.put(vo.getTradeDay(), vo); + } + } + dataMap.put(onlineData.getTradeDay(), onlineData); + + List 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; + } } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/utils/CzgRandomUtils.java b/cash-common/cash-common-tools/src/main/java/com/czg/utils/CzgRandomUtils.java similarity index 100% rename from cash-common/cash-common-service/src/main/java/com/czg/utils/CzgRandomUtils.java rename to cash-common/cash-common-tools/src/main/java/com/czg/utils/CzgRandomUtils.java diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/mapper/ShopInfoMapper.java b/cash-service/account-service/src/main/java/com/czg/service/account/mapper/ShopInfoMapper.java index 0f3616147..d5d39a3ac 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/mapper/ShopInfoMapper.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/mapper/ShopInfoMapper.java @@ -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 { @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 getShopIdList(); } diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/mapper/ShopProdStatisticMapper.java b/cash-service/account-service/src/main/java/com/czg/service/account/mapper/ShopProdStatisticMapper.java deleted file mode 100644 index 452f3a6c2..000000000 --- a/cash-service/account-service/src/main/java/com/czg/service/account/mapper/ShopProdStatisticMapper.java +++ /dev/null @@ -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 { - - List pageInfo(@Param("shopId") Long shopId, @Param("name") String name, @Param("classifyId") String classifyId, - @Param("startTime") String startTime, @Param("endTime") String endTime); -} diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopInfoServiceImpl.java b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopInfoServiceImpl.java index 03bbe6edd..6cf973c23 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopInfoServiceImpl.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopInfoServiceImpl.java @@ -465,4 +465,8 @@ public class ShopInfoServiceImpl extends ServiceImpl i } + @Override + public List getShopIdList() { + return mapper.getShopIdList(); + } } diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopProdStatisticServiceImpl.java b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopProdStatisticServiceImpl.java deleted file mode 100644 index 9d1d13375..000000000 --- a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopProdStatisticServiceImpl.java +++ /dev/null @@ -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 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))); - } -} diff --git a/cash-service/account-service/src/main/resources/mapper/ShopProdStatisticMapper.xml b/cash-service/account-service/src/main/resources/mapper/ShopProdStatisticMapper.xml deleted file mode 100644 index 88f82e1a9..000000000 --- a/cash-service/account-service/src/main/resources/mapper/ShopProdStatisticMapper.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - diff --git a/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/ShopCouponServiceImpl.java b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/ShopCouponServiceImpl.java index 38617e1d1..d9d47862b 100644 --- a/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/ShopCouponServiceImpl.java +++ b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/ShopCouponServiceImpl.java @@ -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 { - ShopOrderStatistic getTradeData(DataSummaryTradeParam param); - long getNewMemberCount(DataSummaryTradeParam param); - List> 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> 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 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 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 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 getShopIdList(); } diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/mapper/ShopProdStatisticMapper.java b/cash-service/order-service/src/main/java/com/czg/service/order/mapper/ShopProdStatisticMapper.java index 960afacd1..020b37745 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/mapper/ShopProdStatisticMapper.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/mapper/ShopProdStatisticMapper.java @@ -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 { - List findProdRandingSummaryPage(DataSummaryProductSaleParam param); + /** + * 根据店铺id和日期 统计商品 + */ + List selectProStatByDay(Long shopId, LocalDate day, String productName); - List findProdRandingSummaryPage2(DataSummaryProductSaleParam param); + List getProdStatSingleDate(Long shopId, LocalDate day, String productName); - SaleSummaryCountVo getSaleSummaryCount(SaleSummaryCountParam param); + List getProdStatDateRange(Long shopId, LocalDate start, LocalDate end, String productName); - SaleSummaryCountVo getSaleSummaryCount2(SaleSummaryCountParam param); - List findSaleSummaryList(SaleSummaryCountParam param); - - List 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); } diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/mapper/ShopTableOrderStatisticMapper.java b/cash-service/order-service/src/main/java/com/czg/service/order/mapper/ShopTableOrderStatisticMapper.java index 14f16ccd0..8358da484 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/mapper/ShopTableOrderStatisticMapper.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/mapper/ShopTableOrderStatisticMapper.java @@ -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 { - List selectSummary(Long shopId, String startTime, String endTime); - boolean incrInfo(long shopId, long tableId, long count, BigDecimal amount, String dateStr); - List 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 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 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 getStatDateRange(Long shopId, LocalDate startDate, LocalDate endDate); - List findSummaryList2(TableSummaryParam param); List findSummaryExportList(TableSummaryParam param); } diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/print/PrinterHandler.java b/cash-service/order-service/src/main/java/com/czg/service/order/print/PrinterHandler.java index 15edee962..207539a49 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/print/PrinterHandler.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/print/PrinterHandler.java @@ -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()); } diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/DataSummaryServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/DataSummaryServiceImpl.java deleted file mode 100644 index 63619b328..000000000 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/DataSummaryServiceImpl.java +++ /dev/null @@ -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 funs = Arrays.asList("getPayTypeAmountCount", "getVipRechargeAmountCount", "getNewMemberCount", "getCustomerUnitPrice", "getTableTurnoverRate"); - Map collect = funs.parallelStream().collect(Collectors.toMap(fun -> fun, fun -> - ReflectUtil.invoke(shopOrderStatisticMapper, fun, param) - )); - /*Map 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> list = shopOrderStatisticMapper.getPayTypeAmountCount(param); - List> list = (List>) collect.get("getPayTypeAmountCount"); - Map sum = list.stream().collect(Collectors.toMap(item -> Convert.toStr(item.get("payType")), item -> Convert.toBigDecimal(item.get("amount")))); - Map 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> list1 = shopOrderStatisticMapper.getVipRechargeAmountCount(param); - List> list1 = (List>) collect.get("getVipRechargeAmountCount"); - Map sum1 = list1.stream().collect(Collectors.toMap(item -> Convert.toStr(item.get("bizCode")), item -> Convert.toBigDecimal(item.get("amount")))); - Map 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 getProductSaleRankingPage(DataSummaryProductSaleParam param) { - LocalDate now = LocalDate.now(); - Integer day = param.getDay(); - LocalDate beginDate = now.plusDays(-day); - List 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 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 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 total = new ArrayList<>(); - List days = new ArrayList<>(); - for (int i = 1; i <= day; i++) { - String thisDay = beginDate.plusDays(i).format(DatePattern.NORM_DATE_FORMATTER); - days.add(thisDay); - } - List 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 getShopIdList() { - return shopOrderStatisticMapper.getShopIdList(); - } - -} diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoServiceImpl.java index 946f471ce..142282da7 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoServiceImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoServiceImpl.java @@ -435,7 +435,7 @@ public class OrderInfoServiceImpl extends ServiceImpl 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 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()); } diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/SaleSummaryServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/SaleSummaryServiceImpl.java deleted file mode 100644 index e8c62aa6d..000000000 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/SaleSummaryServiceImpl.java +++ /dev/null @@ -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 summaryPage(SaleSummaryCountParam param) { - PageHelper.startPage(PageUtil.buildPageHelp()); - PageInfo pageInfo = new PageInfo<>(shopProdStatisticMapper.findSaleSummaryList(param)); - return PageUtil.convert(pageInfo); - } - - @Override - public List summaryList(SaleSummaryCountParam param) { - return shopProdStatisticMapper.findSaleSummaryList(param); - } -} diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopOrderStatisticServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopOrderStatisticServiceImpl.java index 7ec43c692..592ac0d84 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopOrderStatisticServiceImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopOrderStatisticServiceImpl.java @@ -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 implements ShopOrderStatisticService { - @Resource - private DataSummaryService dataSummaryService; - - @DubboReference - private ShopInfoService shopInfoService; - - @Override - public void statistic(DateTime dateTime) { - // 获取前一天的开始时间(00:00:00) - DateTime startOfDay = DateUtil.beginOfDay(dateTime); - // 获取前一天的结束时间(23:59:59) - DateTime endOfDay = DateUtil.endOfDay(dateTime); - List shopIdList = dataSummaryService.getShopIdList(); - if (CollUtil.isEmpty(shopIdList)) { - return; + 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)); } - List> split = CollUtil.split(shopIdList, 5); - for (List 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()); - } - // 如果没有订单和退款,则不更新数据,否则会产出很多数据 - 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); - } - } - }); + 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 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 statDateRange = mapper.getStatDateRange(shopId, startDate, currentDate); + + return TotalVo.mergeAndFillData(onlineDataAmount, statDateRange, startDate, currentDate); + } + + @Override + public List 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 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(); + } + return result; + } + + @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; + } + } diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopProdStatisticServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopProdStatisticServiceImpl.java index 176276cd2..700b78e05 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopProdStatisticServiceImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopProdStatisticServiceImpl.java @@ -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 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 getArchiveTradeDataBy20(Long shopId, String rangeType, LocalDate start, LocalDate end) { + List 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 shopIdList = dataSummaryService.getShopIdList(); - if (CollUtil.isEmpty(shopIdList)) { - return; - } - List> split = CollUtil.split(shopIdList, 5); - for (List 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 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()); - } else { - save(entity); - } + public List getArchiveTradeData(Long shopId, String productName, String rangeType, LocalDate start, LocalDate end) { + LocalDate currentDate = LocalDate.now(); + productName = CzgStrUtils.getStrOrNull(productName); + List resultList; + if ("today".equals(rangeType)) { + resultList = getRealTimeDataByDay(shopId, currentDate, productName); + } else if ("yesterday".equals(rangeType)) { + resultList = getProdStatSingleDate(shopId, currentDate.minusDays(1), productName); + } else { + 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 realTimeDataByDay = getRealTimeDataByDay(shopId, currentDate, productName); + List dateRange = getProdStatDateRange(shopId, start, end, productName); + + resultList = mergeProdStatistic(realTimeDataByDay, dateRange); } - }); + } + } + return resultList; + } + + + @Override + public void statisticAndInsert(Long shopId, LocalDate day) { + List 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 getRealTimeDataByDay(Long shopId, LocalDate day, String productName) { + return mapper.selectProStatByDay(shopId, day, productName); + } + + @Override + public List getProdStatSingleDate(Long shopId, LocalDate day, String productName) { + return mapper.getProdStatSingleDate(shopId, day, productName); + } + + @Override + public List 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 mergeProdStatistic(List realTimeDataByDay, List 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); + } } diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopTableOrderStatisticServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopTableOrderStatisticServiceImpl.java index dec24bc1f..4cd0f1348 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopTableOrderStatisticServiceImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopTableOrderStatisticServiceImpl.java @@ -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 implements ShopTableOrderStatisticService { - @Resource - private DataSummaryService dataSummaryService; - @Resource - private ShopTableOrderStatisticMapper shopTableOrderStatisticMapper; +public class ShopTableOrderStatisticServiceImpl extends ServiceImpl implements ShopTableOrderStatisticService{ @Override - public Page summary(Long shopId, String startTime, String endTime) { - Page page = PageUtil.buildPage(); - PageHelper.startPage(Math.toIntExact(page.getPageNumber()), Math.toIntExact(page.getPageSize())); - return PageUtil.convert(new PageInfo<>(mapper.selectSummary(shopId, startTime, endTime))); - } - - @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); + public List 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)); } - return mapper.incrInfo(shopId, tableId, count, amount, DateUtil.date().toDateStr()); - } - - @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 shopIdList = dataSummaryService.getShopIdList(); - if (CollUtil.isEmpty(shopIdList)) { - return; + if (start.isAfter(currentDate)) { + throw new CzgException("开始时间不能晚于当前时间"); } - List> split = CollUtil.split(shopIdList, 5); - for (List 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 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()); - } else { - save(entity); - } - } - }); + if (start.equals(end)) { + return getStatSingleDate(shopId, start); + } + //包括当前时间 + if (end.isBefore(currentDate)) { + return getStatDateRange(shopId, start, end); + } else { + List realTimeDataByDay = getRealTimeDataByDay(shopId, currentDate); + List statDateRange = getStatDateRange(shopId, start, end); + return ShopTableOrderStatistic.mergeWithStream(realTimeDataByDay, statDateRange); } } + + + @Override + public void statisticAndInsert(Long shopId, LocalDate day) { + List 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 getRealTimeDataByDay(Long shopId, LocalDate day) { + return mapper.getOnlineData(shopId, day); + } + + @Override + public List getStatSingleDate(Long shopId, LocalDate day) { + return mapper.getStatSingleDate(shopId, day); + } + + @Override + public List getStatDateRange(Long shopId, LocalDate start, LocalDate end) { + return mapper.getStatDateRange(shopId, start, end); + } } diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/TableSummaryServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/TableSummaryServiceImpl.java index cf43704b3..34d9b8a27 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/TableSummaryServiceImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/TableSummaryServiceImpl.java @@ -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 summaryList(TableSummaryParam param) { - return shopTableOrderStatisticMapper.findSummaryList(param); - } + @Override public List summaryExportList(TableSummaryParam param) { diff --git a/cash-service/order-service/src/main/resources/mapper/ShopOrderStatisticMapper.xml b/cash-service/order-service/src/main/resources/mapper/ShopOrderStatisticMapper.xml index 83749ccc7..b9a3af7e3 100644 --- a/cash-service/order-service/src/main/resources/mapper/ShopOrderStatisticMapper.xml +++ b/cash-service/order-service/src/main/resources/mapper/ShopOrderStatisticMapper.xml @@ -3,125 +3,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - - - - - - - diff --git a/cash-service/order-service/src/main/resources/mapper/ShopProdStatisticMapper.xml b/cash-service/order-service/src/main/resources/mapper/ShopProdStatisticMapper.xml index d4ebdb653..90cdb0bfd 100644 --- a/cash-service/order-service/src/main/resources/mapper/ShopProdStatisticMapper.xml +++ b/cash-service/order-service/src/main/resources/mapper/ShopProdStatisticMapper.xml @@ -4,164 +4,120 @@ "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - - - - 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 - and t2.product_name like concat('%', #{productName}, '%') - - - and t2.category_id like concat('%,', #{prodCategoryId}, ',%') - - - and t1.create_time >= str_to_date(#{beginDate}, '%Y-%m-%d %H:%i:%s') - - - + AND detail.name LIKE CONCAT('%',#{productName},'%') + GROUP BY prodId - 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} - and t1.product_name like concat('%', #{productName}, '%') + AND prod.name LIKE CONCAT('%',#{productName},'%') - - and t2.category_id = #{prodCategoryId} - - - and t1.create_time >= str_to_date(#{beginDate}, '%Y-%m-%d %H:%i:%s') - - - - - 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 + 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} + + AND prod.name LIKE CONCAT('%',#{productName},'%') - - - - 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 + + + + + + + + diff --git a/cash-service/order-service/src/main/resources/mapper/ShopTableOrderStatisticMapper.xml b/cash-service/order-service/src/main/resources/mapper/ShopTableOrderStatisticMapper.xml index e7b089b03..b4514137f 100644 --- a/cash-service/order-service/src/main/resources/mapper/ShopTableOrderStatisticMapper.xml +++ b/cash-service/order-service/src/main/resources/mapper/ShopTableOrderStatisticMapper.xml @@ -3,124 +3,50 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - - 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} - - SELECT - a.table_id as tableId, b.name as name, sum(a.order_count) as orderCount, sum(a.order_amount) as orderAmount + t.product_name, + date_format(t.create_time, '%Y-%m-%d') as create_date, + if(t.table_name = 'NONE','银收客',t.table_name) as table_name, + concat(if(t.table_name = 'NONE','银收客',t.table_name),'-',date_format(t.create_time, '%Y-%m-%d')) as tableConcatDate, + t.category_name, + t.unit_name, + group_concat(distinct t.sku_name SEPARATOR ';') as sku_name, + sum(t.num) as num, + avg(t.unit_price) as unit_price, + sum(t.num*t.unit_price) as amount, + sum(-t.refund_num) as refund_num, + sum(-t.refund_num*t.unit_price) as refund_amount 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} - - AND a.create_day >= #{startTime} - - - and a.create_day <= #{endTime} - - GROUP BY - a.table_id - order by a.id desc - - - -