ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/CacheConstants.java
@@ -10,7 +10,7 @@ /** * 缓存有效期,默认720(分钟) */ public final static long EXPIRATION = 720; public final static long EXPIRATION = 720 * 10; /** * 缓存刷新时间,默认120(分钟) ruoyi-modules/ruoyi-auction/src/main/java/com/ruoyi/auction/RuoYiAuctionApplication.java
@@ -6,12 +6,16 @@ import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; /** * 系统模块 * * @author ruoyi */ @EnableAsync @EnableScheduling @EnableCustomConfig @MapperScan({"com.ruoyi.auction.mapper"}) @EnableCustomSwagger2 ruoyi-modules/ruoyi-auction/src/main/java/com/ruoyi/auction/service/async/AuctionAsyncMethodService.java
@@ -32,6 +32,7 @@ @Async @Transactional(rollbackFor = Exception.class) public void auctionGoodsScheduleTask(List<AuctionGoods> auctionGoodsList) { log.info("开始执行定时任务"); for (AuctionGoods auctionGoods : auctionGoodsList) { LocalDateTime startTime = auctionGoods.getStartTime(); LocalDateTime endTime = auctionGoods.getEndTime(); @@ -93,9 +94,6 @@ private void handleStartDelayTask(Long id, DelayTaskEnum delayTaskEnum, LocalDateTime startTime, Long timeout) { String startTaskKey = delayTaskEnum.getCode() + "-" + id; redisService.setCacheObject( startTaskKey, startTime, timeout, TimeUnit.SECONDS); // 查询延时任务 DelayTask startDelayTask = sysUserClient.getDelayTask( startTaskKey, SecurityConstants.INNER).getData(); @@ -109,10 +107,8 @@ sysUserClient.addDelayTask(startDelayTask, SecurityConstants.INNER); } else { if (!startDelayTask.getExecuteTime().isEqual(startTime)) { sysUserClient.deleteDelayTask( startTaskKey, SecurityConstants.INNER); redisService.deleteObject( startTaskKey); sysUserClient.deleteDelayTask(startTaskKey, SecurityConstants.INNER); redisService.deleteObject(startTaskKey); startDelayTask.setDelFlag(0); startDelayTask.setCreateTime(LocalDateTime.now()); startDelayTask.setExecuteTime(LocalDateTime.now().plusSeconds(timeout)); @@ -121,6 +117,7 @@ sysUserClient.addDelayTask(startDelayTask, SecurityConstants.INNER); } } redisService.setCacheObject(startTaskKey, startTime, timeout, TimeUnit.SECONDS); log.info(">>>>>>>>>>>>>>>>>>>>延时任务{}执行了<<<<<<<<<<<<<<<<<<<<", startTaskKey); } } ruoyi-modules/ruoyi-auction/src/main/java/com/ruoyi/auction/service/impl/AuctionGoodsServiceImpl.java
@@ -66,7 +66,14 @@ import io.seata.spring.annotation.GlobalTransactional; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.*; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; import javax.annotation.Resource; @@ -213,6 +220,15 @@ if (goodsSku.getStock() + auctionGoodsOrg.getAuctionStock() < dto.getAuctionStock()) { throw new ServiceException("商品库存不足"); } if (!auctionGoodsOrg.getAuctionStock().equals(dto.getAuctionStock())) { // 更新商品库存 GoodsStockUpdDTO goodsStockUpdDTO = new GoodsStockUpdDTO(); goodsStockUpdDTO.setGoodsSkuId(goodsSkuId); goodsStockUpdDTO.setAuctionStock( auctionGoodsOrg.getAuctionStock() - dto.getAuctionStock()); goodsSkuClient.updGoodsStock(Lists.newArrayList(goodsStockUpdDTO), SecurityConstants.INNER); } auctionGoodsOrg.setStartingPrice(dto.getStartingPrice()); auctionGoodsOrg.setMinimumMarkupAmount(dto.getMinimumMarkupAmount()); auctionGoodsOrg.setStartTime(dto.getStartTime()); @@ -224,15 +240,8 @@ auctionGoodsOrg.setShareTitle(dto.getShareTitle()); auctionGoodsOrg.setSharePic(dto.getSharePic()); this.updateById(auctionGoodsOrg); // 更新商品库存 GoodsStockUpdDTO goodsStockUpdDTO = new GoodsStockUpdDTO(); goodsStockUpdDTO.setGoodsSkuId(goodsSkuId); goodsStockUpdDTO.setAuctionStock( auctionGoodsOrg.getAuctionStock() - dto.getAuctionStock()); goodsSkuClient.updGoodsStock(Lists.newArrayList(goodsStockUpdDTO), SecurityConstants.INNER); auctionAsyncMethodService.auctionGoodsScheduleTask(Lists.newArrayList(auctionGoods)); } auctionAsyncMethodService.auctionGoodsScheduleTask(Lists.newArrayList(auctionGoods)); } /** @@ -640,7 +649,6 @@ .equals(AuctionStartStatusEnum.IN_AUCTION)) { auctionGoods.setStartStatus(AuctionStartStatusEnum.ENDED); this.updateById(auctionGoods); // TODO 退保证金 orderClient.returnBondByAuctionGoodsId(id, SecurityConstants.INNER); Map<String, Object> map = new ConcurrentHashMap<>(); ruoyi-modules/ruoyi-auction/src/main/java/com/ruoyi/auction/task/AuctionGoodsScheduler.java
@@ -31,7 +31,7 @@ } private void handleTaskStart() { log.info(">>>>>>>>>>>>>>>>>>>>定时任务秒杀/团购开始执行<<<<<<<<<<<<<<<<<<<<"); log.info(">>>>>>>>>>>>>>>>>>>>定时任务普通拍品开始执行<<<<<<<<<<<<<<<<<<<<"); LocalDateTime checkTime = LocalDateTime.now().plusHours(1); List<AuctionGoods> list = auctionGoodsService.lambdaQuery() .eq(AuctionGoods::getListingStatus, ListingStatusEnum.ON_SHELVES) ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/RuoYiGoodsApplication.java
@@ -6,6 +6,7 @@ import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; /** @@ -13,6 +14,7 @@ * * @author ruoyi */ @EnableAsync @EnableCustomConfig @MapperScan({"com.ruoyi.goods.mapper"}) @EnableCustomSwagger2 ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/async/AsyncMethodService.java
@@ -3,7 +3,6 @@ import com.ruoyi.common.core.constant.SecurityConstants; import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.redis.service.RedisService; import com.ruoyi.system.api.domain.GoodsGroupPurchase; import com.ruoyi.system.api.constants.DelayTaskEnum; import com.ruoyi.system.api.domain.DelayTask; import com.ruoyi.system.api.domain.GoodsGroupPurchase; @@ -120,9 +119,6 @@ private void handleStartDelayTask(Long id, DelayTaskEnum delayTaskEnum, LocalDateTime startTime, Long timeout) { String startTaskKey = delayTaskEnum.getCode() + "-" + id; redisService.setCacheObject( startTaskKey, startTime, timeout, TimeUnit.SECONDS); //查询延时任务 DelayTask startDelayTask = sysUserClient.getDelayTask( startTaskKey, SecurityConstants.INNER).getData(); @@ -148,6 +144,7 @@ sysUserClient.addDelayTask(startDelayTask, SecurityConstants.INNER); } } redisService.setCacheObject(startTaskKey, startTime, timeout, TimeUnit.SECONDS); log.info(">>>>>>>>>>>>>>>>>>>>延时任务{}执行了<<<<<<<<<<<<<<<<<<<<", startTaskKey); } } ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/GoodsSkuServiceImpl.java
@@ -17,7 +17,6 @@ import com.ruoyi.goods.controller.management.dto.GoodsInfoTitleValueDTO; import com.ruoyi.goods.controller.management.dto.GoodsSkuDTO; import com.ruoyi.goods.controller.management.dto.GoodsSkuQuery; import com.ruoyi.system.api.domain.vo.GoodsInfoTitleValueVO; import com.ruoyi.goods.controller.management.vo.GoodsSkuVO; import com.ruoyi.goods.domain.GoodsBrowseRecord; import com.ruoyi.goods.domain.GoodsInfoTitleValue; @@ -39,6 +38,7 @@ import com.ruoyi.system.api.domain.dto.GoodsStockUpdDTO; import com.ruoyi.system.api.domain.dto.HomeGoodsSkuDTO; import com.ruoyi.system.api.domain.dto.ListStatusDTO; import com.ruoyi.system.api.domain.vo.GoodsInfoTitleValueVO; import com.ruoyi.system.api.domain.vo.HomeGoodsSkuInfoVO; import com.ruoyi.system.api.domain.vo.HomeGoodsSkuListVO; import com.ruoyi.system.api.domain.vo.OrderVO; @@ -270,6 +270,7 @@ @Override @Transactional(propagation = Propagation.REQUIRES_NEW) public void updGoodsStock(List<GoodsStockUpdDTO> goodsStockUpdDTOS) { log.info("开始批量更新商品库存"); List<Long> goodsSkuIdList = goodsStockUpdDTOS.stream() .map(GoodsStockUpdDTO::getGoodsSkuId) .collect(Collectors.toList()); @@ -287,7 +288,7 @@ try { redissonLock.lock(30, TimeUnit.SECONDS); Integer auctionStock = stockMap.get(skus.getId()); if (StringUtils.isNotNull(auctionStock) && auctionStock > 0) { if (StringUtils.isNotNull(auctionStock)) { // 更新商品库存,更新五次失败抛出异常 boolean isUpdated = false; for (int i = 0; i < 5; i++) { @@ -306,7 +307,7 @@ redissonLock.unlock(); } } log.info("批量更新商品库存结束"); } @Override ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/controller/management/MgtBusinessDataController.java
@@ -2,11 +2,14 @@ import com.ruoyi.common.core.domain.R; import com.ruoyi.order.controller.management.dto.MgtOrderStaticsQuery; import com.ruoyi.order.controller.management.vo.MgtOrderStaticsChartVO; import com.ruoyi.order.controller.management.vo.MgtOrderStaticsVO; import com.ruoyi.order.service.impl.MgtBusinessDataService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -16,7 +19,7 @@ * @author mitao * @date 2024/6/19 */ @Api(tags = "业务数据相关接口") @Api(tags = {"管理后台-工作台-业务数据统计"}) @RestController @RequestMapping("/mgt/business-data") @RequiredArgsConstructor @@ -24,8 +27,27 @@ private final MgtBusinessDataService mgtBusinessDataService; /** * 获取业务数据统计 * * @param query 订单统计查询对象 * @return MgtOrderStaticsVO */ @ApiOperation(value = "获取业务数据统计", notes = "获取业务数据统计") @PostMapping("/get-overview") public R<MgtOrderStaticsVO> getOverview(@Validated @RequestBody MgtOrderStaticsQuery query) { return R.ok(mgtBusinessDataService.getOverview(query)); } /** * 获取图表数据 * * @return MgtOrderStaticsChartVO */ @ApiOperation(value = "获取业务数据统计图表数据", notes = "获取业务数据统计图表数据") @GetMapping("/get-chart") public R<MgtOrderStaticsChartVO> getChart() { return R.ok(mgtBusinessDataService.getChart()); } } ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/controller/management/dto/MgtOrderStaticsQuery.java
@@ -6,13 +6,19 @@ import java.io.Serializable; import java.time.LocalDateTime; import javax.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; /** * @author mitao * @date 2024/6/19 */ @Data @Builder @NoArgsConstructor @AllArgsConstructor @ApiModel("订单统计查询对象") public class MgtOrderStaticsQuery implements Serializable { ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/controller/management/vo/MgtAmountChartVO.java
New file @@ -0,0 +1,20 @@ package com.ruoyi.order.controller.management.vo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import java.io.Serializable; import java.math.BigDecimal; import lombok.Data; @Data @ApiModel("订单金额统计图表对象") public class MgtAmountChartVO implements Serializable { private static final long serialVersionUID = 8440194640873107140L; @ApiModelProperty(value = "日期", notes = "X轴") private String date; @ApiModelProperty(value = "总金额", notes = "Y轴") private BigDecimal value; } ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/controller/management/vo/MgtCountChartVO.java
New file @@ -0,0 +1,18 @@ package com.ruoyi.order.controller.management.vo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import java.io.Serializable; import lombok.Data; @Data @ApiModel("订单总数统计图表对象") public class MgtCountChartVO implements Serializable { private static final long serialVersionUID = 8440194640873107140L; @ApiModelProperty(value = "日期", notes = "X轴") private String date; @ApiModelProperty(value = "订单总数", notes = "Y轴") private Long value; } ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/controller/management/vo/MgtOrderStaticsChartVO.java
New file @@ -0,0 +1,30 @@ package com.ruoyi.order.controller.management.vo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import java.util.List; import lombok.Data; /** * @author mitao * @date 2024/6/25 */ @Data @ApiModel("订单统计图表对象") public class MgtOrderStaticsChartVO { @ApiModelProperty(value = "商城订单总数", notes = "商城订单总数") private List<MgtCountChartVO> mallOrderCountList; @ApiModelProperty(value = "商城订单总金额", notes = "商城订单总金额") private List<MgtAmountChartVO> mallOrderTotalAmountList; @ApiModelProperty(value = "拍卖订单总数", notes = "拍卖订单总数") private List<MgtCountChartVO> auctionOrderCount; @ApiModelProperty(value = "拍卖订单总金额", notes = "拍卖订单总金额") private List<MgtAmountChartVO> auctionOrderTotalAmount; } ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/controller/management/vo/MgtOrderStaticsVO.java
@@ -16,16 +16,16 @@ private static final long serialVersionUID = -6511810306263817540L; @ApiModelProperty("商城订单统计-订单总数") private Integer mallOrderTotalCount; private Long mallOrderTotalCount; @ApiModelProperty("商城订单统计-商城订单") private Integer mallOrderCount; private Long mallOrderCount; @ApiModelProperty("商城订单统计-秒杀订单") private Integer seckillOrderCount; private Long seckillOrderCount; @ApiModelProperty("商城订单统计-团购订单") private Integer groupPurchaseOrderCount; private Long groupPurchaseOrderCount; @ApiModelProperty("商城订单统计-订单总金额") private BigDecimal mallOrderTotalAmount; @@ -40,13 +40,13 @@ private BigDecimal groupPurchaseTotalAmount; @ApiModelProperty("拍卖订单统计-订单总数") private Integer auctionOrderTotalCount; private Long auctionOrderTotalCount; @ApiModelProperty("拍卖订单统计-拍卖商品订单") private Integer auctionGoodsOrderCount; private Long auctionGoodsOrderCount; @ApiModelProperty("拍卖订单统计-拍卖场订单") private Integer auctionSalesroomOrderCount; private Long auctionSalesroomOrderCount; @ApiModelProperty("拍卖订单统计-订单总金额") private BigDecimal auctionOrderTotalAmount; ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/mapper/OrderMapper.java
@@ -2,11 +2,11 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.system.api.domain.Order; import java.util.List; import com.ruoyi.system.api.domain.dto.HomeGoodsSkuDTO; import com.ruoyi.system.api.domain.dto.MemberOrderDTO; import com.ruoyi.system.api.domain.vo.OrderVO; import java.time.LocalDateTime; import java.util.List; import org.apache.ibatis.annotations.Param; /** @@ -42,4 +42,13 @@ List<OrderVO> getOrderByGroupPurchaseMemberList(HomeGoodsSkuDTO homeGoodsSkuDTO); /** * 查询统计订单列表 * * @param startTime 开始时间 * @param endTime 结束时间 * @return List<Order> */ List<Order> getStaticsOrderList(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime); } ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/IOrderService.java
@@ -14,6 +14,7 @@ import com.ruoyi.system.api.domain.vo.MemberOrderNumVO; import com.ruoyi.system.api.domain.vo.MemberTiOrderVO; import com.ruoyi.system.api.domain.vo.OrderVO; import java.time.LocalDateTime; import java.util.Collection; import java.util.List; import org.springframework.web.bind.annotation.RequestBody; @@ -128,4 +129,13 @@ * @param id 订单id */ void refundBond(Long id); /** * 查询统计订单列表 * * @param startTime 开始时间 * @param endTime 结束时间 * @return List<Order> */ List<Order> getStaticsOrderList(LocalDateTime startTime, LocalDateTime endTime); } ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/MgtBusinessDataService.java
@@ -1,44 +1,163 @@ package com.ruoyi.order.service.impl; import com.ruoyi.common.core.enums.AuctionOrderTypeEnum; import com.ruoyi.common.core.enums.OrderFromEnum; import com.ruoyi.common.core.enums.OrderTypeEnum; import com.ruoyi.common.core.enums.TimeTypeEnum; import com.ruoyi.common.core.exception.ServiceException; import com.ruoyi.common.core.utils.DateUtils; import com.ruoyi.common.core.utils.page.CollUtils; import com.ruoyi.order.controller.management.dto.MgtOrderStaticsQuery; import com.ruoyi.order.controller.management.vo.MgtAmountChartVO; import com.ruoyi.order.controller.management.vo.MgtCountChartVO; import com.ruoyi.order.controller.management.vo.MgtOrderStaticsChartVO; import com.ruoyi.order.controller.management.vo.MgtOrderStaticsVO; import com.ruoyi.order.service.IOrderService; import com.ruoyi.system.api.domain.Order; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.stream.Collectors; import java.util.stream.Stream; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.jetbrains.annotations.NotNull; import org.springframework.stereotype.Service; /** * @author mitao * @date 2024/6/19 */ @Slf4j @Service @RequiredArgsConstructor public class MgtBusinessDataService { private final IOrderService orderService; /** * 获取业务数据统计 * * @param query 订单统计查询对象 * @return MgtOrderStaticsVO */ public MgtOrderStaticsVO getOverview(MgtOrderStaticsQuery query) { LocalDateTime now = LocalDateTime.now(); LocalDateTime startTime = null; LocalDateTime endTime = null; getTimeByTimeType(query, startTime, endTime, now); return null; getTimeByTimeType(query, startTime, endTime); List<Order> orderList = orderService.getStaticsOrderList(startTime, endTime); if (orderList.isEmpty()) { throw new ServiceException("暂无数据"); } MgtOrderStaticsVO mgtOrderStaticsVO = new MgtOrderStaticsVO(); /* ***************************************商城订单统计*************************************** */ // 商城订单统计-订单总数 long mallOrderTotalCount = orderList.stream() .filter(order -> !order.getOrderFrom().equals(OrderFromEnum.AUCTION_ORDERS)) .count(); // 商城订单统计-订单总数 long mallOrderCount = orderList.stream() .filter(order -> order.getOrderFrom().equals(OrderFromEnum.COMMODITY_ORDER)) .count(); // 商城订单统计-商城订单 long seckillOrderCount = orderList.stream() .filter(order -> order.getOrderFrom().equals(OrderFromEnum.SNAP_ORDERS)) .count(); // 商城订单统计-团购订单 long groupPurchaseOrderCount = orderList.stream() .filter(order -> order.getOrderFrom().equals(OrderFromEnum.GROUP_PURCHASE_ORDERS)) .count(); // 商城订单统计-订单总金额 BigDecimal mallOrderTotalAmount = orderList.stream() .filter(order -> !order.getOrderFrom().equals(OrderFromEnum.AUCTION_ORDERS)) .map(Order::getTotalAmount).reduce(BigDecimal::add).orElse(BigDecimal.ZERO); // 商城订单统计 - 商城总金额 BigDecimal mallTotalAmount = orderList.stream() .filter(order -> order.getOrderFrom().equals(OrderFromEnum.COMMODITY_ORDER)) .map(Order::getTotalAmount).reduce(BigDecimal::add).orElse(BigDecimal.ZERO); // 商城订单统计-秒杀总金额 BigDecimal seckillTotalAmount = orderList.stream() .filter(order -> order.getOrderFrom().equals(OrderFromEnum.SNAP_ORDERS)) .map(Order::getTotalAmount).reduce(BigDecimal::add).orElse(BigDecimal.ZERO); // 商城订单统计-团购总金额 BigDecimal groupPurchaseTotalAmount = orderList.stream() .filter(order -> order.getOrderFrom().equals(OrderFromEnum.GROUP_PURCHASE_ORDERS)) .map(Order::getTotalAmount).reduce(BigDecimal::add).orElse(BigDecimal.ZERO); mgtOrderStaticsVO.setMallOrderTotalCount(mallOrderTotalCount); mgtOrderStaticsVO.setMallOrderCount(mallOrderCount); mgtOrderStaticsVO.setSeckillOrderCount(seckillOrderCount); mgtOrderStaticsVO.setGroupPurchaseOrderCount(groupPurchaseOrderCount); mgtOrderStaticsVO.setMallOrderTotalAmount(mallOrderTotalAmount); mgtOrderStaticsVO.setMallTotalAmount(mallTotalAmount); mgtOrderStaticsVO.setSeckillTotalAmount(seckillTotalAmount); mgtOrderStaticsVO.setGroupPurchaseTotalAmount(groupPurchaseTotalAmount); /* ***************************************拍卖订单统计*************************************** */ // 拍卖订单统计-订单总数 long auctionOrderTotalCount = orderList.stream() .filter(order -> order.getOrderFrom().equals(OrderFromEnum.AUCTION_ORDERS)) .count(); // 商城订单统计-订单总数 long auctionGoodsOrderCount = orderList.stream() .filter(order -> order.getOrderFrom().equals(OrderFromEnum.AUCTION_ORDERS) && order.getAuctionOrderType().equals(AuctionOrderTypeEnum.REGULAR_ITEMS)) .count(); // 拍卖订单统计-拍卖商品订单 long auctionSalesroomOrderCount = orderList.stream() .filter(order -> order.getOrderFrom().equals(OrderFromEnum.AUCTION_ORDERS) && order.getAuctionOrderType().equals(AuctionOrderTypeEnum.AUCTION_ITEMS)) .count(); // 拍卖订单统计-订单总金额 BigDecimal auctionOrderTotalAmount = orderList.stream() .filter(order -> order.getOrderFrom().equals(OrderFromEnum.AUCTION_ORDERS)) .map(Order::getTotalAmount) .reduce(BigDecimal::add).orElse(BigDecimal.ZERO); // 拍卖订单统计-拍卖商品总金额 BigDecimal auctionGoodsTotalAmount = orderList.stream() .filter(order -> order.getOrderFrom().equals(OrderFromEnum.AUCTION_ORDERS) && order.getAuctionOrderType().equals(AuctionOrderTypeEnum.REGULAR_ITEMS) ) .map(Order::getTotalAmount).reduce(BigDecimal::add).orElse(BigDecimal.ZERO); // 拍卖订单统计-拍卖场总金额 BigDecimal auctionSalesroomTotalAmount = orderList.stream() .filter(order -> order.getOrderFrom().equals(OrderFromEnum.AUCTION_ORDERS) && order.getAuctionOrderType().equals(AuctionOrderTypeEnum.AUCTION_ITEMS)) .map(Order::getTotalAmount).reduce(BigDecimal::add).orElse(BigDecimal.ZERO); mgtOrderStaticsVO.setAuctionOrderTotalCount(auctionOrderTotalCount); mgtOrderStaticsVO.setAuctionGoodsOrderCount(auctionGoodsOrderCount); mgtOrderStaticsVO.setAuctionSalesroomOrderCount(auctionSalesroomOrderCount); mgtOrderStaticsVO.setAuctionOrderTotalAmount(auctionOrderTotalAmount); mgtOrderStaticsVO.setAuctionGoodsTotalAmount(auctionGoodsTotalAmount); mgtOrderStaticsVO.setAuctionSalesroomTotalAmount(auctionSalesroomTotalAmount); return mgtOrderStaticsVO; } private static void getTimeByTimeType(MgtOrderStaticsQuery query, LocalDateTime startTime, LocalDateTime endTime, LocalDateTime now) { private void getTimeByTimeType(MgtOrderStaticsQuery query, LocalDateTime startTime, LocalDateTime endTime) { LocalDateTime now = LocalDateTime.now(); if (Objects.equals(TimeTypeEnum.TODAY.getCode(), query.getTimeType())) { startTime = DateUtils.getDayStart(now); endTime = DateUtils.getDayEnd(now); } else if (Objects.equals(TimeTypeEnum.PAST_SEVEN_DAYS.getCode(), query.getTimeType())) { startTime = DateUtils.getDayStart(now.minusDays(7)); startTime = DateUtils.getDayStart(now.minusDays(6)); // 过去七天 为过去六天加今天 endTime = DateUtils.getDayEnd(now); } else if (Objects.equals(TimeTypeEnum.PAST_THIRTY_DAYS.getCode(), query.getTimeType())) { startTime = DateUtils.getDayStart(now.minusDays(30)); startTime = DateUtils.getDayStart(now.minusDays(29)); // 过去30天 为过去29天加今天 endTime = DateUtils.getDayEnd(now); } else if (Objects.equals(TimeTypeEnum.CUSTOM.getCode(), query.getTimeType())) { if (Objects.isNull(query.getStartTime()) || Objects.isNull(query.getEndTime())) { @@ -51,4 +170,138 @@ endTime = DateUtils.getDayEnd(now); } } /** * 获取图表数据 * * @return MgtOrderStaticsChartVO */ public MgtOrderStaticsChartVO getChart() { LocalDateTime now = LocalDateTime.now(); LocalDateTime startTime = DateUtils.getDayStart(now.minusDays(29)); LocalDateTime endTime = DateUtils.getDayEnd(now); List<LocalDate> datesBetween = getDatesBetween(startTime.toLocalDate(), endTime.toLocalDate()); // 根据开始时间和结束时间,获取这个范围的每一天的日期 List<Order> orderList = orderService.getStaticsOrderList(startTime, endTime); ExecutorService executorService = Executors.newFixedThreadPool(4); // 商城订单总数 CompletableFuture<List<MgtCountChartVO>> mallOrderCountFuture = CompletableFuture.supplyAsync( () -> getMgtCountChartVOS(datesBetween, orderList, OrderTypeEnum.MALL_ODER), executorService); // 商城订单总金额 CompletableFuture<List<MgtAmountChartVO>> mallOrderTotalAmountFuture = CompletableFuture.supplyAsync( () -> getMgtAmountChartVOS(datesBetween, orderList, OrderTypeEnum.MALL_ODER), executorService); // 拍卖订单总数 CompletableFuture<List<MgtCountChartVO>> auctionOrderCountFuture = CompletableFuture.supplyAsync( () -> getMgtCountChartVOS(datesBetween, orderList, OrderTypeEnum.AUCTION_ORDER), executorService); // 拍卖订单总金额 CompletableFuture<List<MgtAmountChartVO>> auctionOrderTotalAmountFuture = CompletableFuture.supplyAsync( () -> getMgtAmountChartVOS(datesBetween, orderList, OrderTypeEnum.AUCTION_ORDER), executorService); // 等待所有任务完成 CompletableFuture<Void> futureAll = CompletableFuture.allOf(mallOrderCountFuture, mallOrderTotalAmountFuture, auctionOrderCountFuture, auctionOrderTotalAmountFuture); MgtOrderStaticsChartVO mgtOrderStaticsChartVO = new MgtOrderStaticsChartVO(); futureAll.thenRun(() -> { try { mgtOrderStaticsChartVO.setMallOrderCountList(mallOrderCountFuture.get()); mgtOrderStaticsChartVO.setMallOrderTotalAmountList( mallOrderTotalAmountFuture.get()); mgtOrderStaticsChartVO.setAuctionOrderCount(auctionOrderCountFuture.get()); mgtOrderStaticsChartVO.setAuctionOrderTotalAmount( auctionOrderTotalAmountFuture.get()); } catch (InterruptedException | ExecutionException e) { throw new RuntimeException(e); } executorService.shutdown(); // 关闭线程池 }); return mgtOrderStaticsChartVO; } @NotNull private static List<MgtAmountChartVO> getMgtAmountChartVOS(List<LocalDate> datesBetween, List<Order> orderList, OrderTypeEnum type) { Map<String, BigDecimal> orderTotalAmountMap; if (type.equals(OrderTypeEnum.MALL_ODER)) { orderTotalAmountMap = orderList.stream() .filter(order -> !order.getOrderFrom().equals(OrderFromEnum.AUCTION_ORDERS)) .collect(Collectors.groupingBy(order -> order.getOrderTime().toLocalDate() .format(DateTimeFormatter.ofPattern("MM-dd")), Collectors.reducing(BigDecimal.ZERO, Order::getTotalAmount, BigDecimal::add))); } else if (type.equals(OrderTypeEnum.AUCTION_ORDER)) { orderTotalAmountMap = orderList.stream() .filter(order -> order.getOrderFrom().equals(OrderFromEnum.AUCTION_ORDERS)) .collect(Collectors.groupingBy(order -> order.getOrderTime().toLocalDate() .format(DateTimeFormatter.ofPattern("MM-dd")), Collectors.reducing(BigDecimal.ZERO, Order::getTotalAmount, BigDecimal::add))); } else { orderTotalAmountMap = null; } if (orderTotalAmountMap != null) { return datesBetween.stream().map(date -> { MgtAmountChartVO mgtAmountChartVO = new MgtAmountChartVO(); mgtAmountChartVO.setDate(date.format(DateTimeFormatter.ofPattern("MM-dd"))); BigDecimal orderTotalAmount = orderTotalAmountMap.get( date.format(DateTimeFormatter.ofPattern("MM-dd"))); mgtAmountChartVO.setValue( orderTotalAmount == null ? BigDecimal.ZERO : orderTotalAmount); return mgtAmountChartVO; }).collect(Collectors.toList()); } else { return CollUtils.emptyList(); } } @NotNull private static List<MgtCountChartVO> getMgtCountChartVOS(List<LocalDate> datesBetween, List<Order> orderList, OrderTypeEnum type) { Map<String, Long> orderCountMap; if (type.equals(OrderTypeEnum.MALL_ODER)) { orderCountMap = orderList.stream() .filter(order -> !order.getOrderFrom().equals(OrderFromEnum.AUCTION_ORDERS)) .collect(Collectors.groupingBy(order -> order.getOrderTime().toLocalDate() .format(DateTimeFormatter.ofPattern("MM-dd")), Collectors.counting())); } else if (type.equals(OrderTypeEnum.AUCTION_ORDER)) { orderCountMap = orderList.stream() .filter(order -> order.getOrderFrom().equals(OrderFromEnum.AUCTION_ORDERS)) .collect(Collectors.groupingBy(order -> order.getOrderTime().toLocalDate() .format(DateTimeFormatter.ofPattern("MM-dd")), Collectors.counting())); } else { orderCountMap = null; } if (orderCountMap != null) { return datesBetween.stream().map(date -> { MgtCountChartVO mgtCountChartVO = new MgtCountChartVO(); mgtCountChartVO.setDate(date.format(DateTimeFormatter.ofPattern("MM-dd"))); Long orderCount = orderCountMap.get( date.format(DateTimeFormatter.ofPattern("MM-dd"))); mgtCountChartVO.setValue(orderCount == null ? 0L : orderCount); return mgtCountChartVO; }).collect(Collectors.toList()); } else { return CollUtils.emptyList(); } } public List<LocalDate> getDatesBetween(LocalDate startDate, LocalDate endDate) { // 检查开始日期是否晚于结束日期 if (startDate.isAfter(endDate)) { throw new IllegalArgumentException("开始日期必须早于结束日期"); } // 使用ChronoUnit.DAYS.between计算日期差,并生成日期范围的流 long numOfDaysBetween = ChronoUnit.DAYS.between(startDate, endDate); // 使用Stream.iterate生成日期序列,再用limit限制天数,最后collect收集结果 return Stream.iterate(startDate, date -> date.plusDays(1)) .limit(numOfDaysBetween + 1) // 加1是因为包含结束日期 .collect(Collectors.toList()); } } ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/OrderServiceImpl.java
@@ -1198,4 +1198,16 @@ } } } /** * 查询统计订单列表 * * @param startTime 开始时间 * @param endTime 结束时间 * @return List<Order> */ @Override public List<Order> getStaticsOrderList(LocalDateTime startTime, LocalDateTime endTime) { return baseMapper.getStaticsOrderList(startTime, endTime); } } ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderMapper.xml
@@ -92,5 +92,17 @@ AND o.member_id=#{memberId} </where> </select> <select id="getStaticsOrderList" resultType="com.ruoyi.system.api.domain.Order"> SELECT o.* FROM t_order o LEFT JOIN t_order_return_request torr ON o.id = torr.order_id <where> o.order_status IN (1, 2, 3, 4) OR (o.order_status = 6 AND torr.audit_status != 2) <if test="startTime != null and endTime != null"> AND o.create_time between #{startTime,jdbcType=TIMESTAMP} and #{endTime,jdbcType=TIMESTAMP} </if> </where> </select> </mapper>