From 076c7f1df538ed9c04701ebda3f6fe11c47e91e4 Mon Sep 17 00:00:00 2001
From: zxl <763096477@qq.com>
Date: 星期四, 25 九月 2025 17:16:11 +0800
Subject: [PATCH] 订单统计

---
 framework/src/main/java/cn/lili/modules/order/order/serviceimpl/OrderServiceImpl.java |  312 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 304 insertions(+), 8 deletions(-)

diff --git a/framework/src/main/java/cn/lili/modules/order/order/serviceimpl/OrderServiceImpl.java b/framework/src/main/java/cn/lili/modules/order/order/serviceimpl/OrderServiceImpl.java
index 9d38114..62358bd 100644
--- a/framework/src/main/java/cn/lili/modules/order/order/serviceimpl/OrderServiceImpl.java
+++ b/framework/src/main/java/cn/lili/modules/order/order/serviceimpl/OrderServiceImpl.java
@@ -10,6 +10,7 @@
 import cn.hutool.poi.excel.ExcelReader;
 import cn.hutool.poi.excel.ExcelUtil;
 import cn.hutool.poi.excel.ExcelWriter;
+import cn.lili.base.Result;
 import cn.lili.common.enums.ClientTypeEnum;
 import cn.lili.common.enums.PromotionTypeEnum;
 import cn.lili.common.enums.ResultCode;
@@ -25,10 +26,15 @@
 import cn.lili.common.utils.StringUtils;
 import cn.lili.common.vo.ResultMessage;
 import cn.lili.modules.goods.entity.dos.Goods;
+import cn.lili.modules.goods.entity.dos.GoodsSku;
 import cn.lili.modules.goods.entity.dto.GoodsCompleteMessage;
 import cn.lili.modules.goods.service.GoodsService;
+import cn.lili.modules.goods.service.GoodsSkuService;
+import cn.lili.modules.lmk.domain.entity.CouponVirtual;
 import cn.lili.modules.lmk.domain.vo.OrderCountVO;
 import cn.lili.modules.lmk.enums.general.AdminRoleEnum;
+import cn.lili.modules.lmk.enums.general.VirtualGoodsTypeEnum;
+import cn.lili.modules.lmk.service.CouponVirtualService;
 import cn.lili.modules.member.entity.dos.Member;
 import cn.lili.modules.member.entity.dto.MemberAddressDTO;
 import cn.lili.modules.member.mapper.MemberMapper;
@@ -47,8 +53,11 @@
 import cn.lili.modules.permission.entity.dos.AdminUser;
 import cn.lili.modules.permission.service.AdminUserService;
 import cn.lili.modules.permission.service.RoleService;
+import cn.lili.modules.promotion.entity.dos.Coupon;
 import cn.lili.modules.promotion.entity.dos.Pintuan;
+import cn.lili.modules.promotion.service.CouponService;
 import cn.lili.modules.promotion.service.PintuanService;
+import cn.lili.modules.statistics.entity.dto.StatisticsQueryParam;
 import cn.lili.modules.store.entity.dto.StoreDeliverGoodsAddressDTO;
 import cn.lili.modules.store.service.StoreDetailService;
 import cn.lili.modules.system.aspect.annotation.SystemLogPoint;
@@ -79,7 +88,9 @@
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import io.reactivex.rxjava3.core.Maybe;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.Row;
@@ -87,6 +98,7 @@
 import org.apache.poi.ss.util.CellRangeAddressList;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.apache.rocketmq.spring.core.RocketMQTemplate;
+import org.redisson.api.RLock;
 import org.redisson.api.RedissonClient;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationEventPublisher;
@@ -101,6 +113,10 @@
 import java.io.InputStream;
 import java.math.BigDecimal;
 import java.net.URLEncoder;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
@@ -199,8 +215,20 @@
     @Resource
     private RedisTemplate<Object,Object> redisTemplate;
 
+    @Autowired
+    private CouponService couponService;
+
+    @Autowired
+    private CouponVirtualService couponVirtualService;
+
+    @Autowired
+    private RedissonClient redissonClient;
+
+    @Autowired
+    private GoodsSkuService goodsSkuService;
     private final static  String LOCK_ORDER_NO_MQ="lock_order_no_mq:";
     private final static  String LOCK_EDIT_ORDER_ADDRESS="lock_edit_order_address:";
+    private final static  String LOCK_COUPON_CARD="lock_coupon_card:";
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void intoDB(TradeDTO tradeDTO) {
@@ -236,7 +264,21 @@
 //                        item.getPriceDetailDTO().setPlatFormCommissionPoint(Double.valueOf(goods.getCommission().toString()));
 //                        e.setPriceDetailDTO(item.getPriceDetailDTO());
 //                        orderItems.add(e);
-                        orderItems.add(new OrderItem(sku, item, tradeDTO));
+                        //鐗规畩澶勭悊绾夸笂绀煎搧鍗¢棶棰�
+                        String skuId = sku.getGoodsSku().getId();
+                        GoodsSku skuInfo = goodsSkuService.getById(skuId);
+                        OrderItem orderItem = new OrderItem(sku, item, tradeDTO);
+                        if (skuInfo != null) {
+                            String goodsId = skuInfo.getGoodsId();
+                            Goods goodsInfo = goodsService.getById(goodsId);
+                            if (goodsInfo != null&& VirtualGoodsTypeEnum.COUPON.name().equals(goodsInfo.getVirtualGoodsType())) {
+                                String couponId = skuInfo.getCouponId();
+                                String couponName = skuInfo.getCouponName();
+                                orderItem.setCouponId(couponId);
+                                orderItem.setCouponName(couponName);
+                            }
+                        }
+                        orderItems.add(orderItem);
                         currentOrderItems.add(new OrderItem(sku, item, tradeDTO));
                     }
             );
@@ -786,17 +828,80 @@
     @OrderLogPoint(description = "'璁㈠崟['+#orderSn+']鏍搁攢锛屾牳閿�鐮乕'+#verificationCode+']'", orderSn = "#orderSn")
     @Transactional(rollbackFor = Exception.class)
     public Order take(String orderSn, String verificationCode) {
+        log.info("璁㈠崟鏍搁攢璁㈠崟鍙蜂负锛歿}锛屾牳閿�鐮佷负{}",orderSn,verificationCode);
+        Order order;
+        RLock lock = redissonClient.getLock(LOCK_COUPON_CARD + orderSn);
+        try {
+             lock.lock();
+            //鑾峰彇璁㈠崟淇℃伅
+            order = this.getBySn(orderSn);
+            log.info("鑾峰彇鍒扮殑璁㈠崟淇℃伅涓簕}",JSON.toJSONString(order));
+            //璁㈠崟骞傜瓑闂
+            if (OrderStatusEnum.COMPLETED.name().equals(order.getOrderStatus())) {
+                throw new ServiceException("褰撳墠璁㈠崟宸插畬鎴愭棤娉曞啀娆℃牳楠�");
+            }
 
-        //鑾峰彇璁㈠崟淇℃伅
-        Order order = this.getBySn(orderSn);
-        //妫�娴嬭櫄鎷熻鍗曚俊鎭�
-        checkVerificationOrder(order, verificationCode);
-        order.setOrderStatus(OrderStatusEnum.COMPLETED.name());
-        //璁㈠崟瀹屾垚
-        this.complete(orderSn);
+            //妫�娴嬭櫄鎷熻鍗曚俊鎭�
+            checkVerificationOrder(order, verificationCode);
+            order.setOrderStatus(OrderStatusEnum.COMPLETED.name());
+            //璁㈠崟瀹屾垚
+            //鑾峰彇鎵�鏈夌殑璁㈠崟瀛愰」鐢ㄤ簬鐢熸垚浼樻儬鍗疯鍗曚俊鎭�
+            List<OrderItem> orderItems = orderItemService.getByOrderSn(orderSn);
+            List<CouponVirtual> couponVirtuals = new  ArrayList<>();
+            for (OrderItem orderItem : orderItems) {
+                log.info("鑾峰彇鍒扮殑瀛愯鍗曚俊鎭负{}",JSON.toJSONString(orderItem));
+                String couponId = orderItem.getCouponId();
+                if (StringUtils.isBlank(couponId)) {
+                    continue;
+                }
+                String storeId = order.getStoreId();
+                Coupon one = couponService.getOne(Wrappers.<Coupon>lambdaQuery().eq(Coupon::getStoreId, storeId).eq(Coupon::getId, couponId));
+                if (one == null) {
+                    log.error("褰撳墠璁㈠崟璁㈠崟鍙蜂负:{}涓嶅瓨鍦ㄤ腑鐨勪紭鎯犲嵎涓嶅瓨鍦�----------------------->{}",order.getId(),orderItem.getOrderSn());
+                }else {
+                    Integer num = orderItem.getNum();
+                    //褰撹喘涔版暟閲忎笉涓虹┖鐨勬椂鍊欒繘琛�
+                    if (num != null) {
+                        for (int i = 1; i <= num; i++) {
+                            CouponVirtual couponVirtual = getCouponVirtual(orderItem);
+                            couponVirtual.setCouponNo(String.format("%08d", i));
+                            couponVirtuals.add(couponVirtual);
+                        }
+                    }
+
+                }
+            }
+            if (!couponVirtuals.isEmpty()) {
+                log.info("鐢熸垚鐨勫厬鎹㈠崱涓簕}",JSON.toJSONString(couponVirtuals));
+                order.setCouponFlag(CouPonFlagEnum.COUPON.name());
+                couponVirtualService.saveBatch(couponVirtuals);
+                //鏇存柊鐘舵�佺敤浜庡悗缁皬绋嬪簭鍒ゆ柇寮瑰嚭鍗峰垪琛�
+                this.updateById(order);
+            }
+            this.complete(orderSn);
+        } finally {
+            assert lock != null;
+            if (lock.isHeldByCurrentThread()) {
+                lock.unlock();
+            }
+        }
         return order;
     }
 
+    private static CouponVirtual getCouponVirtual(OrderItem orderItem) {
+        CouponVirtual couponVirtual = new CouponVirtual();
+        couponVirtual.setOrderId(orderItem.getOrderSn());
+        couponVirtual.setCouponId(orderItem.getCouponId());
+        couponVirtual.setCouponName(orderItem.getCouponName());
+        couponVirtual.setGoodsId(orderItem.getGoodsId());
+        couponVirtual.setSkuId(orderItem.getSkuId());
+        couponVirtual.setItemOrderId(orderItem.getId());
+        couponVirtual.setSkuName(orderItem.getGoodsName());
+        couponVirtual.setName(orderItem.getCouponName());
+        couponVirtual.setShareStatus(ShareStatusEnum.NOT_SHARE.name());
+        couponVirtual.setClaimStatus(ClaimStatusEnum.NOT_CLAIM.name());
+        return couponVirtual;
+    }
     @Override
     public Order take(String verificationCode) {
         String storeId = OperationalJudgment.judgment(UserContext.getCurrentUser()).getStoreId();
@@ -1170,6 +1275,197 @@
         return order;
     }
 
+    @Override
+    public Result getOrderCount(StatisticsQueryParam queryParam) {
+        Date startTime = null;
+        Date endTime = new Date(); // 缁撴潫鏃堕棿榛樿鏄綋鍓嶆椂闂�
+        List<String> dateList = new ArrayList<>();
+
+        Calendar calendar = Calendar.getInstance(); // 鐢ㄤ簬鏃ユ湡璁$畻鐨勬棩鍘嗗疄渚�
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+        int days = 0;
+        switch (queryParam.getSearchType()) {
+            case "TODAY":
+                // 浠婂ぉ锛氫粠浠婂ぉ0鐐瑰埌鐜板湪
+                calendar.setTime(new Date()); // 閲嶇疆涓哄綋鍓嶆椂闂�
+                calendar.set(Calendar.HOUR_OF_DAY, 0); // 灏忔椂璁句负0锛�24灏忔椂鍒讹級
+                calendar.set(Calendar.MINUTE, 0);      // 鍒嗛挓璁句负0
+                calendar.set(Calendar.SECOND, 0);      // 绉掕涓�0
+                calendar.set(Calendar.MILLISECOND, 0); // 姣璁句负0
+                startTime = calendar.getTime();        // 寰楀埌浠婂ぉ0鐐圭殑Date瀵硅薄
+                dateList.add(sdf.format(startTime));
+                break;
+            case "YESTERDAY":
+                // 鏄ㄥぉ锛氫粠鏄ㄥぉ0鐐瑰埌鏄ㄥぉ23:59:59.999
+                calendar.setTime(new Date());
+                calendar.add(Calendar.DATE, -1); // 鏃ユ湡鍑�1澶╋紙鍙樹负鏄ㄥぉ锛�
+
+                // 璁剧疆鏄ㄥぉ0鐐�
+                calendar.set(Calendar.HOUR_OF_DAY, 0);
+                calendar.set(Calendar.MINUTE, 0);
+                calendar.set(Calendar.SECOND, 0);
+                calendar.set(Calendar.MILLISECOND, 0);
+                startTime = calendar.getTime();
+
+                // 璁剧疆鏄ㄥぉ23:59:59.999
+                calendar.set(Calendar.HOUR_OF_DAY, 23);
+                calendar.set(Calendar.MINUTE, 59);
+                calendar.set(Calendar.SECOND, 59);
+                calendar.set(Calendar.MILLISECOND, 999);
+                endTime = calendar.getTime();
+
+                dateList.add(sdf.format(startTime));
+                break;
+            case "LAST_SEVEN":
+                // 杩囧幓涓冨ぉ锛氫粠7澶╁墠0鐐瑰埌鐜板湪锛堝惈浠婂ぉ鍏�7澶╋級
+                calendar.setTime(new Date());
+                calendar.add(Calendar.DATE, -6); // 鏃ユ湡鍑�6澶╋紙7澶╁墠鐨勪粖澶╋級
+
+                // 璁剧疆7澶╁墠0鐐�
+                calendar.set(Calendar.HOUR_OF_DAY, 0);
+                calendar.set(Calendar.MINUTE, 0);
+                calendar.set(Calendar.SECOND, 0);
+                calendar.set(Calendar.MILLISECOND, 0);
+                startTime = calendar.getTime();
+
+                days = 7;
+                // 寰幆鐢熸垚7澶╃殑鏃ユ湡瀛楃涓�
+                Calendar tempCalendar = Calendar.getInstance();
+                tempCalendar.setTime(startTime);
+                for (int i = 0; i < days; i++) {
+                    dateList.add(sdf.format(tempCalendar.getTime()));
+                    tempCalendar.add(Calendar.DATE, 1); // 姣忓ぉ绱姞1澶�
+                }
+                break;
+            case "LAST_THIRTY":
+                // 杩囧幓30澶╋細浠�30澶╁墠0鐐瑰埌鐜板湪锛堝惈浠婂ぉ鍏�30澶╋級
+                calendar.setTime(new Date());
+                calendar.add(Calendar.DATE, -29); // 鏃ユ湡鍑�29澶╋紙30澶╁墠鐨勪粖澶╋級
+
+                // 璁剧疆30澶╁墠0鐐�
+                calendar.set(Calendar.HOUR_OF_DAY, 0);
+                calendar.set(Calendar.MINUTE, 0);
+                calendar.set(Calendar.SECOND, 0);
+                calendar.set(Calendar.MILLISECOND, 0);
+                startTime = calendar.getTime();
+
+                days = 30;
+                // 寰幆鐢熸垚30澶╃殑鏃ユ湡瀛楃涓�
+                Calendar tempCalendar30 = Calendar.getInstance();
+                tempCalendar30.setTime(startTime);
+                for (int i = 0; i < days; i++) {
+                    dateList.add(sdf.format(tempCalendar30.getTime()));
+                    tempCalendar30.add(Calendar.DATE, 1); // 姣忓ぉ绱姞1澶�
+                }
+                break;
+            default:
+                return Result.error("涓嶆敮鎸佺殑鏃堕棿鑼冨洿绫诲瀷");
+        }
+        List<Map<String, Object>> maps = baseMapper.selectOrderCountByDay(startTime,endTime);
+
+        Map<String, Long> dayCountMap = maps.stream()
+                .collect(Collectors.toMap(
+                        map -> map.get("day").toString(),  // 鏃ユ湡瀛楃涓诧紙濡�2023-09-19锛�
+                        map -> Long.valueOf(map.get("count").toString())  // 璁㈠崟鏁伴噺
+                ));
+
+        List<Long> orderCounts = new ArrayList<>();
+        for (String date : dateList) {
+            // 鏍稿績锛氬瓨鍦ㄥ垯鍙栨煡璇㈢粨鏋滐紝涓嶅瓨鍦ㄥ垯琛�0
+            orderCounts.add(dayCountMap.getOrDefault(date, 0L));
+        }
+
+
+        return Result.ok().data(orderCounts);
+    }
+
+    @Override
+    public Result getOrderTimePeriod(StatisticsQueryParam queryParam) {
+        Date startTime = null;
+        Date endTime = new Date(); // 缁撴潫鏃堕棿榛樿鏄綋鍓嶆椂闂�
+        List<String> dateList = new ArrayList<>();
+
+        Calendar calendar = Calendar.getInstance(); // 鐢ㄤ簬鏃ユ湡璁$畻鐨勬棩鍘嗗疄渚�
+        for (int i =0;i<=24;i++){
+            dateList.add(i + "鐐�");
+        }
+        switch (queryParam.getSearchType()) {
+            case "TODAY":
+                // 浠婂ぉ锛氫粠浠婂ぉ0鐐瑰埌鐜板湪
+                calendar.setTime(new Date()); // 閲嶇疆涓哄綋鍓嶆椂闂�
+                calendar.set(Calendar.HOUR_OF_DAY, 0); // 灏忔椂璁句负0锛�24灏忔椂鍒讹級
+                calendar.set(Calendar.MINUTE, 0);      // 鍒嗛挓璁句负0
+                calendar.set(Calendar.SECOND, 0);      // 绉掕涓�0
+                calendar.set(Calendar.MILLISECOND, 0); // 姣璁句负0
+                startTime = calendar.getTime();        // 寰楀埌浠婂ぉ0鐐圭殑Date瀵硅薄
+                break;
+            case "YESTERDAY":
+                // 鏄ㄥぉ锛氫粠鏄ㄥぉ0鐐瑰埌鏄ㄥぉ23:59:59.999
+                calendar.setTime(new Date());
+                calendar.add(Calendar.DATE, -1); // 鏃ユ湡鍑�1澶╋紙鍙樹负鏄ㄥぉ锛�
+
+                // 璁剧疆鏄ㄥぉ0鐐�
+                calendar.set(Calendar.HOUR_OF_DAY, 0);
+                calendar.set(Calendar.MINUTE, 0);
+                calendar.set(Calendar.SECOND, 0);
+                calendar.set(Calendar.MILLISECOND, 0);
+                startTime = calendar.getTime();
+
+                // 璁剧疆鏄ㄥぉ23:59:59.999
+                calendar.set(Calendar.HOUR_OF_DAY, 23);
+                calendar.set(Calendar.MINUTE, 59);
+                calendar.set(Calendar.SECOND, 59);
+                calendar.set(Calendar.MILLISECOND, 999);
+                endTime = calendar.getTime();
+
+                break;
+            case "LAST_SEVEN":
+                // 杩囧幓涓冨ぉ锛氫粠7澶╁墠0鐐瑰埌鐜板湪锛堝惈浠婂ぉ鍏�7澶╋級
+                calendar.setTime(new Date());
+                calendar.add(Calendar.DATE, -6); // 鏃ユ湡鍑�6澶╋紙7澶╁墠鐨勪粖澶╋級
+
+                // 璁剧疆7澶╁墠0鐐�
+                calendar.set(Calendar.HOUR_OF_DAY, 0);
+                calendar.set(Calendar.MINUTE, 0);
+                calendar.set(Calendar.SECOND, 0);
+                calendar.set(Calendar.MILLISECOND, 0);
+                startTime = calendar.getTime();
+
+                break;
+            case "LAST_THIRTY":
+                // 杩囧幓30澶╋細浠�30澶╁墠0鐐瑰埌鐜板湪锛堝惈浠婂ぉ鍏�30澶╋級
+                calendar.setTime(new Date());
+                calendar.add(Calendar.DATE, -29); // 鏃ユ湡鍑�29澶╋紙30澶╁墠鐨勪粖澶╋級
+
+                // 璁剧疆30澶╁墠0鐐�
+                calendar.set(Calendar.HOUR_OF_DAY, 0);
+                calendar.set(Calendar.MINUTE, 0);
+                calendar.set(Calendar.SECOND, 0);
+                calendar.set(Calendar.MILLISECOND, 0);
+                startTime = calendar.getTime();
+
+                break;
+            default:
+                return Result.error("涓嶆敮鎸佺殑鏃堕棿鑼冨洿绫诲瀷");
+        }
+        List<Map<String, Object>> maps = baseMapper.selectOrderTimePeriod(startTime,endTime);
+
+        Map<String, Long> dayCountMap = maps.stream()
+                .collect(Collectors.toMap(
+                        map -> map.get("day").toString(),  // 鏃ユ湡瀛楃涓诧紙濡�2023-09-19锛�
+                        map -> Long.valueOf(map.get("count").toString())  // 璁㈠崟鏁伴噺
+                ));
+
+        List<Long> orderCounts = new ArrayList<>();
+        for (String date : dateList) {
+            // 鏍稿績锛氬瓨鍦ㄥ垯鍙栨煡璇㈢粨鏋滐紝涓嶅瓨鍦ㄥ垯琛�0
+            orderCounts.add(dayCountMap.getOrDefault(date, 0L));
+        }
+
+
+        return Result.ok().data(orderCounts);
+    }
+
     /**
      * 铏氭嫙鎴愬洟
      *

--
Gitblit v1.8.0