package shop.alien.store.service;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import shop.alien.entity.result.R;
import shop.alien.entity.store.*;
import shop.alien.entity.store.dto.LifeUserOrderDto;
import shop.alien.entity.store.excelVo.LifeUserOrderExcelVo;
import shop.alien.entity.store.excelVo.util.ExcelGenerator;
import shop.alien.entity.store.vo.LifeUserOrderVo;
import shop.alien.entity.store.vo.StoreInfoVo;
import shop.alien.entity.store.vo.WebSocketVo;
import shop.alien.mapper.*;
import shop.alien.store.config.GaoDeMapUtil;
import shop.alien.store.config.WebSocketProcess;
import shop.alien.store.strategy.payment.PaymentStrategyFactory;
import shop.alien.store.util.ali.AliApi;
import shop.alien.util.ali.AliOSSUtil;
import shop.alien.util.common.UniqueRandomNumGenerator;
import shop.alien.util.common.constant.*;
import shop.alien.util.type.LifeFansIdentityQuery;
import shop.alien.util.type.LifeNoticeUtil;
import shop.alien.util.type.TypeUtil;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class LifeUserOrderService extends ServiceImpl<LifeUserOrderMapper, LifeUserOrder> {

    private final LifeUserOrderMapper lifeUserOrderMapper;

    private final LifeCouponMapper lifeCouponMapper;

    private final LifeRefundOrderMapper lifeRefundOrderMapper;

    private final StoreInfoMapper storeInfoMapper;

    private final LifeUserService lifeUserService;

    private final GaoDeMapUtil gaoDeMapUtil;

    private final LifeFansMapper lifeFansMapper;
    private final TypeUtil typeUtil;

    private final StoreCommentService storeCommentService;

    private final LifeUserMapper lifeUserMapper;

    private final LifeNoticeMapper lifeNoticeMapper;

    private final LifeNoticeUtil lifeNoticeUtil;

    private final StoreImgMapper storeImgMapper;

    private final StoreUserMapper storeUserMapper;

    private final LifeDiscountCouponUserMapper lifeDiscountCouponUserMapper;

    private final OrderCouponMiddleService orderCouponMiddleService;

    private final AliOSSUtil aliOSSUtil;

    private final OrderCouponMiddleMapper orderCouponMiddleMapper;

    private final LifeGroupBuyMainMapper lifeGroupBuyMainMapper;

    private final AliApi aliApi;

    private final LifeDiscountCouponMapper lifeDiscountCouponMapper;

    private final WebSocketProcess webSocketProcess;

    @Value("${spring.web.resources.excel-path}")
    private String excelPath;

    @Value("${spring.web.resources.excel-generate-path}")
    private String excelGeneratePath;

    private final PaymentStrategyFactory paymentStrategyFactory;

    public List<Map<String, Object>> getOrderListByStatus(Integer page, Integer size, String userId, String status,
                                                          String quanNameSearch, Integer storeType, String baojiaStatus, String orderNo, Integer storeId) {
        List<Map<String, Object>> returnList = new ArrayList<>();

        // 构建基础查询条件
        LambdaQueryWrapper<LifeUserOrder> baseWrapper = new LambdaQueryWrapper<>();
        baseWrapper.eq(StringUtils.isNotEmpty(userId), LifeUserOrder::getUserId, userId);
        baseWrapper.eq(StringUtils.isNotEmpty(status), LifeUserOrder::getStatus, status);
        baseWrapper.like(StringUtils.isNotEmpty(orderNo), LifeUserOrder::getOrderNo, orderNo);
        baseWrapper.like(null != storeId, LifeUserOrder::getStoreId, storeId);

        // 先查询符合条件的订单号，并进行分页
        baseWrapper
                .groupBy(LifeUserOrder::getOrderNo)
                .orderByAsc(LifeUserOrder::getStatus)
                .orderByDesc(LifeUserOrder::getUpdatedTime);

        List<LifeUserOrder> orderList = lifeUserOrderMapper.selectList(baseWrapper);
        if (orderList.isEmpty()) {
            return new ArrayList<>();
        }

        //获取所有订单号
        List<String> orderNos = orderList.stream()
                .map(LifeUserOrder::getOrderNo)
                .collect(Collectors.toList());

        // 按订单号分组处理
        Map<String, List<LifeUserOrder>> orderDetailsGrouped = orderList.stream()
                .collect(Collectors.groupingBy(LifeUserOrder::getOrderNo));

        //一次性获取所有优惠券id
        List<String> quanIdList = orderList.stream().map(LifeUserOrder::getQuanId).collect(Collectors.toList());
        //查询所有优惠券
        List<LifeCoupon> lifeCoupons = lifeCouponMapper.getList(new LambdaQueryWrapper<LifeCoupon>().in(!quanIdList.isEmpty(), LifeCoupon::getId, quanIdList));

        //一次性获取所有店铺id
        List<String> storeIdList = orderList.stream().map(LifeUserOrder::getStoreId).collect(Collectors.toList());
        //查询所有店铺
        List<StoreInfo> storeInfoList = storeInfoMapper.getList(new LambdaQueryWrapper<StoreInfo>().in(!storeIdList.isEmpty(), StoreInfo::getId, storeIdList));

        // 查询所有店铺用户
        List<StoreUser> storeUsers = storeUserMapper.selectList(new QueryWrapper<StoreUser>().isNotNull("store_id"));
        Map<Integer, List<StoreUser>> collect1 = storeUsers.stream().collect(Collectors.groupingBy(StoreUser::getStoreId));
        // 遍历每个订单号，处理订单详情
        for (String orderNum : orderNos) {
            List<LifeUserOrder> orderDetails = orderDetailsGrouped.getOrDefault(orderNum, Collections.emptyList());
            if (orderDetails.isEmpty()) {
                continue;
            }
            LifeUserOrder lifeUserOrder = orderDetails.get(0);
            if (StringUtils.isEmpty(lifeUserOrder.getQuanId())) {
                continue;
            }
            LifeCoupon quan = lifeCoupons.stream().filter(a -> a.getId().equals(lifeUserOrder.getQuanId())).collect(Collectors.toList()).get(0);
            if (StringUtils.isEmpty(lifeUserOrder.getStoreId())) {
                continue;
            }
            StoreInfo storeInfo = storeInfoList.stream().filter(a -> lifeUserOrder.getStoreId().equals(a.getId().toString())).collect(Collectors.toList()).get(0);

            Map<String, Object> map = new HashMap<>();
            map.put("orderId", lifeUserOrder.getId());
            map.put("orderNo", lifeUserOrder.getOrderNo());
            Integer deleteFlag = 1;
            Integer storeStatus = 0;
            Integer logoutFlag = 0;
            // 店铺用户状态，注销，删除，禁用;
            if (collect1.containsKey(Integer.parseInt(lifeUserOrder.getStoreId()))) {
                List<StoreUser> storeUsers1 = collect1.get(Integer.parseInt(lifeUserOrder.getStoreId()));
                StoreUser storeUser = storeUsers1.get(0);
                deleteFlag = storeUser.getDeleteFlag();
                storeStatus = storeUser.getStatus();
                logoutFlag = storeUser.getLogoutFlag();
            }
            ;
            map.put("abnormalStateFlag", 0);
            if (deleteFlag == 1 || storeStatus == 1 || logoutFlag == 1 || logoutFlag == 2) {
                map.put("abnormalStateFlag", 1);
            }
            // 营业状态
            map.put("businessStatus", storeInfo.getBusinessStatus());
            // 计算实付金额
            String finalPrice = new BigDecimal(lifeUserOrder.getFinalPrice())
                    .multiply(new BigDecimal(orderDetails.size()))
                    .toString();
            map.put("price", finalPrice);
            map.put("count", lifeUserOrderMapper.selectCount(new LambdaQueryWrapper<LifeUserOrder>().eq(LifeUserOrder::getOrderNo, lifeUserOrder.getOrderNo())));

            if (lifeUserOrder.getStatus() == 0) {
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(lifeUserOrder.getBuyTime());
                calendar.add(Calendar.DAY_OF_MONTH, quan.getExpirationDate());
                Date expirationDate = calendar.getTime();
                if (quan.getEndDate() == null) {
                    map.put("youxiaoqiTime", expirationDate);
                } else {
                    Date youxiaoqiTime = expirationDate.compareTo(quan.getEndDate()) > 0 ? quan.getEndDate() : expirationDate;
                    map.put("youxiaoqiTime", youxiaoqiTime);
                }
            } else {
                map.put("xiadanTime", lifeUserOrder.getPayTime());
            }
            map.put("storeName", storeInfo.getStoreName());
            map.put("storeType", storeInfo.getBusinessSection());

            // 计算保价状态
            // 0 未开启 1 生效中 2 已过期
            int priceProtectionStatus = 0;
            if (quan.getOpenPriceProtection() != null && quan.getOpenPriceProtection() != 0) {
                LocalDateTime sevenDaysAgo = LocalDateTime.now().minusDays(7);
                Date createdTime = lifeUserOrder.getCreatedTime();
                LocalDateTime orderCreatedTime = createdTime.toInstant()
                        .atZone(ZoneId.systemDefault())
                        .toLocalDateTime();
                priceProtectionStatus = orderCreatedTime.isAfter(sevenDaysAgo) ? 1 : 2;
            }
            map.put("baojiaStatus", priceProtectionStatus);

            // 只有当baojiaStatus参数存在且筛选结果不包含当前订单时，跳过该订单
            if (baojiaStatus != null && !baojiaStatus.isEmpty()) {
                try {
                    int targetStatus = Integer.parseInt(baojiaStatus);
                    if (priceProtectionStatus != targetStatus) {
                        continue;
                    }
                } catch (NumberFormatException e) {
                    throw new RuntimeException("保价状态参数格式错误", e);
                }
            }

            // 继续设置其他订单信息
            map.put("storeName", storeInfo.getStoreName());
            map.put("quanName", quan.getName());
            map.put("quanId", quan.getId());
            map.put("status", lifeUserOrder.getStatus());

            //
            String imgs = quan.getImagePath();
            if (imgs != null && !imgs.startsWith("h")) {
                if (StringUtils.isNotEmpty(imgs)) {
                    List<String> collect = Arrays.stream(imgs.split(","))
                            .map(String::trim)
                            .collect(Collectors.toList());
                    List<StoreImg> storeImgs = storeImgMapper.selectList(new LambdaQueryWrapper<StoreImg>().in(StoreImg::getId, collect));
                    if (storeImgs != null) {
                        imgs = storeImgs.stream()
                                .map(StoreImg::getImgUrl)
                                .collect(Collectors.joining(","));
                    }
                }

            }


            map.put("image", imgs);
            map.put("quanType", quan.getType());

            // 获取全部券码
            String quanCode = orderDetails.stream()
                    .filter(o -> o.getStatus() == 0)
                    .map(LifeUserOrder::getQuanCode)
                    .collect(Collectors.joining(","));
            map.put("quanCode", quanCode);
            map.put("storeId", storeInfo.getId());

            // 检查是否已评价
            LambdaQueryWrapper<StoreComment> storeCommentWrapper = new LambdaQueryWrapper<>();
            storeCommentWrapper.eq(StoreComment::getUserId, userId);
            storeCommentWrapper.eq(StoreComment::getStoreId, lifeUserOrder.getStoreId());
            storeCommentWrapper.eq(StoreComment::getBusinessType, 5);
            storeCommentWrapper.eq(StoreComment::getBusinessId, lifeUserOrder.getId());
            int count = storeCommentService.count(storeCommentWrapper);
            map.put("hasComment", count > 0);

            returnList.add(map);
        }

        List<Map<String, Object>> resultList = returnList;
        if (null != storeType) {
            resultList = resultList.stream().filter(a -> a.get("storeType").equals(storeType)).collect(Collectors.toList());
        }
        if (StringUtils.isNotEmpty(quanNameSearch)) {
            resultList = resultList.stream().filter(a -> a.get("quanName").toString().contains(quanNameSearch) || a.get("storeName").toString().contains(quanNameSearch)).collect(Collectors.toList());
        }
        return resultList;
    }

    public Map<String, Object> getOrderByOrderId(String orderId, String jingdu, String weidu) {
        Map<String, Object> returnMap = new HashMap<>();
        LifeUserOrder order = lifeUserOrderMapper.selectById(orderId);
        if (order == null) {
            return null;
        }
        // 获取该订单编号的所有订单
        LambdaQueryWrapper<LifeUserOrder> allOrderWrapper = new LambdaQueryWrapper<>();
        allOrderWrapper.eq(LifeUserOrder::getOrderNo, order.getOrderNo());
        String quanCodes = lifeUserOrderMapper.selectList(allOrderWrapper).stream().filter(o -> o.getStatus() == 0)
                .map(o -> o.getQuanCode())
                .collect(Collectors.joining(","));

        Map<String, Object> orderMap = new HashMap<>();
        String quanPrice = order.getPrice();
        String finalPrice = order.getFinalPrice();
        String unusedDate;
        String useRule;
        String applicableRule;
        int status = order.getStatus();
        String imagePath;
        LifeCoupon quan = lifeCouponMapper.selectById(order.getQuanId());
        if (quan == null) {
            return null;
        }
        unusedDate = quan.getUnusedDate();
        useRule = quan.getUseRule();
        applicableRule = quan.getApplicableRule();
        imagePath = quan.getImagePath();
        orderMap.put("orderId", order.getId());
        orderMap.put("quanName", quan.getName());
        orderMap.put("quanPrice", quanPrice);
        orderMap.put("shifuPrice", finalPrice);
        orderMap.put("unusedDate", unusedDate);
        orderMap.put("useRule", useRule);
        orderMap.put("applicableRule", applicableRule);
        orderMap.put("quanCode", quanCodes);
        orderMap.put("status", status);
        orderMap.put("imagePath", imagePath);
        QueryWrapper<StoreInfoVo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("a.id", order.getStoreId());
        StoreInfoVo store = storeInfoMapper.getStoreInfoVoOne(queryWrapper);
        orderMap.put("storeId", store.getId());
        returnMap.put("order", orderMap);

        // 添加是否关注逻辑
        String userId = order.getUserId();
        LifeUser userById = lifeUserService.getUserById(userId);
        String s = "user_" + userById.getUserPhone();

        String receiverId = "store_" + store.getStorePhone();

        LifeFansIdentityQuery.Scope userScope = LifeFansIdentityQuery.resolve(s, typeUtil);
        LifeFansIdentityQuery.Scope storeScope = LifeFansIdentityQuery.resolve(receiverId, typeUtil);

        //关注我的
        LambdaQueryWrapper<LifeFans> wrapperOne = new LambdaQueryWrapper<>();
        wrapperOne.eq(LifeFans::getDeleteFlag, 0);
        LifeFansIdentityQuery.applyPair(wrapperOne, storeScope, userScope);
        List<LifeFans> isFollowMeList = lifeFansMapper.selectList(wrapperOne);

        //我关注的
        LambdaQueryWrapper<LifeFans> wrapperTwo = new LambdaQueryWrapper<>();
        wrapperTwo.eq(LifeFans::getDeleteFlag, 0);
        LifeFansIdentityQuery.applyPair(wrapperTwo, userScope, storeScope);
        List<LifeFans> isFollowThisList = lifeFansMapper.selectList(wrapperTwo);

        Map<String, Object> storeMap = new HashMap<>();
        storeMap.put("storeName", store.getStoreName());
        storeMap.put("openTime", "9:00-22:00");
        if ((jingdu != null && !jingdu.isEmpty()) && (weidu != null && !weidu.isEmpty())) {
            double storeDistance = gaoDeMapUtil.getDistance(jingdu, weidu, store.getStorePosition().split(",")[0], store.getStorePosition().split(",")[1]);
            DecimalFormat df = new DecimalFormat("#.0");
            storeMap.put("distance", Double.parseDouble(df.format(storeDistance / 1000)) + "km");
        } else {
            storeMap.put("distance", "没有位置信息");
        }
        storeMap.put("address", store.getStoreAddress());
        storeMap.put("contactPerson", store.getStoreContact());
        storeMap.put("phoneNum", store.getStorePhone());
        storeMap.put("jingdu", store.getStorePosition().split(",")[0]);
        storeMap.put("weidu", store.getStorePosition().split(",")[1]);
        returnMap.put("store", storeMap);
        Map<String, Object> goumaixuzhiMap = new HashMap<>();
        goumaixuzhiMap.put("expirationDate", "购买后" + quan.getExpirationDate() + "天有效");
        goumaixuzhiMap.put("useTime", "营业时间可用");
        goumaixuzhiMap.put("useRange", quan.getUseRule());
        goumaixuzhiMap.put("applicableRule", quan.getApplicableRule());
        returnMap.put("gouMaiXuZhi", goumaixuzhiMap);
        Map<String, Object> orderInfoMap = new HashMap<>();
        orderInfoMap.put("orderNo", order.getOrderNo());
        orderInfoMap.put("payMethod", order.getPayMethod());
        LifeUser byId = lifeUserService.getById(order.getUserId());
        orderInfoMap.put("phoneNum", byId.getUserPhone());
        orderInfoMap.put("buyTime", order.getBuyTime());
        orderInfoMap.put("payTime", order.getPayTime());
        orderInfoMap.put("isFollowMe", !isFollowMeList.isEmpty() ? 1 : 0);
        orderInfoMap.put("isFollowThis", !isFollowThisList.isEmpty() ? 1 : 0);

        // 判断保价状态
        Date currentDate = new Date();
        Calendar payTimeCal = Calendar.getInstance();
        payTimeCal.setTime(order.getPayTime());
        Calendar currentCal = Calendar.getInstance();
        currentCal.setTime(currentDate);

        long diffInMillis = currentCal.getTimeInMillis() - payTimeCal.getTimeInMillis();
        long diffInDays = diffInMillis / (24 * 60 * 60 * 1000);
        String priceProtectionStatus = diffInDays < 7 ? "1" : "0";
        orderInfoMap.put("priceProtectionStatus", priceProtectionStatus);
        returnMap.put("orderInfo", orderInfoMap);
        return returnMap;
    }

    public int deleteOrdersById(String orderId) {
        return lifeUserOrderMapper.deleteById(orderId);
    }

    public List<String> getQuanCodeList(String orderNo) {
        LambdaUpdateWrapper<LifeUserOrder> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(LifeUserOrder::getOrderNo, orderNo);
        List<LifeUserOrder> orders = lifeUserOrderMapper.selectList(wrapper);
        return orders.stream().map(LifeUserOrder::getQuanCode).collect(Collectors.toList());
    }

    /**
     * 申请退款
     *
     * @param refundOrder
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public R<String> requestRefund(LifeRefundOrder refundOrder) {
        if (StringUtils.isEmpty(refundOrder.getRefundMoney())) {
            return R.fail("退款金额为null");
        }
        List<OrderCouponMiddle> orderCouponMiddles = orderCouponMiddleMapper.selectList(new QueryWrapper<OrderCouponMiddle>()
                .eq("order_id", refundOrder.getOrderId()).eq("delete_flag", 0));
        // 1.查询订单信息  订单表 + 中间表
        LifeUserOrder order = lifeUserOrderMapper.selectById(refundOrder.getOrderId());
        Integer refundCouponAmount = refundOrder.getRefundCouponAmount();
        // 待使用的券（可退款的券 || 退款失败的券 目前没做失败的券状态更新 暂时不加）
        List<OrderCouponMiddle> orderCouponMiddles1 = orderCouponMiddles.stream().filter(orderCouponMiddle -> orderCouponMiddle.getStatus() == OrderStatusEnum.WAIT_USE.getStatus()).collect(Collectors.toList());
        if (orderCouponMiddles1.size() < refundCouponAmount) {
            return R.fail("退款券数不足");
        }
        // 判断累计退款金额
        BigDecimal totalRefundMoney = new BigDecimal(refundOrder.getRefundMoney());
        // 累计退款个数
        int refundCouponCount = 0;
        List<LifeRefundOrder> lifeRefundOrderList = lifeRefundOrderMapper.selectList(new QueryWrapper<LifeRefundOrder>().eq("order_id", refundOrder.getOrderId())
                .eq("status", 0));
        for (LifeRefundOrder lifeRefundOrder : lifeRefundOrderList) {
            totalRefundMoney = totalRefundMoney.add(new BigDecimal(lifeRefundOrder.getRefundMoney()));
            refundCouponCount += lifeRefundOrder.getRefundCouponAmount();
        }
        if (totalRefundMoney.compareTo(new BigDecimal(order.getFinalPrice())) > 0) {
            return R.fail("退款金额(已退+当前退)不能大于订单金额");
        }
        Date now = new Date();
        boolean ifPartialRefund = false;
        String PartialRefundCode = "";
        // 只要本次退款不是全退都是部分退
        if (refundCouponAmount != orderCouponMiddles.size()) {
            ifPartialRefund = true;
            PartialRefundCode = UniqueRandomNumGenerator.generateUniqueCode(12);
        }
        // TODO 微信/支付宝退款接口
        // 获取paymethod 并且构建 请求参数
        String payMethod = order.getPayMethod();
        String payType = "";
        Map<String, String> params = new HashMap<>();
        if("支付宝支付".equals(payMethod)) {
            payType = PaymentEnum.ALIPAY.getType();
            params.put("outTradeNo", order.getOrderNo());
            params.put("refundAmount", refundOrder.getRefundMoney());
            params.put("refundReason", refundOrder.getDescription());
            params.put("partialRefundCode",PartialRefundCode);
        } else {
            payType = PaymentEnum.WECHAT_PAY.getType();
            params.put("outTradeNo", order.getOrderNo());
            params.put("reason", refundOrder.getReason() == null ? "退款" : refundOrder.getReason());
            params.put("refundAmount", String.valueOf(new BigDecimal(refundOrder.getRefundMoney()).multiply(new BigDecimal(100)).longValue()));
            params.put("totalAmount", String.valueOf(new BigDecimal(order.getFinalPrice()).multiply(new BigDecimal(100)).longValue()));
        }
        // 调用支付策略
        String result = "";
        try {
            result = paymentStrategyFactory.getStrategy(payType).handleRefund(params);
        } catch (Exception e) {
            log.error(String.format("LifeUserOrderService requestRefund error, payType: %s, params: %s, error: %s", payType, params, e.getMessage()));
            return R.fail(e.getMessage());
        }
        String refundMessage = "";

        // 更新的中间表id
        List<Integer> updateIds = orderCouponMiddles1.stream().limit(refundCouponAmount).map(x -> x.getId()).collect(Collectors.toList());
        if (!result.equals("调用成功")) {
            refundMessage = "编号为" + order.getOrderNo() + "的订单退款失败，请重新发起申请。";
            // TODO 退款失败目前不做处理
            /*orderCouponMiddleMapper.update(null,new UpdateWrapper<OrderCouponMiddle>().in("id",updateIds)
                    .set("status",OrderStatusEnum.REFUND_FAILED.getStatus())
                    .set("refund_time",now)
                    .set(ifPartialRefund,"refund_code",PartialRefundCode)
                    .set("refund_reason",refundOrder.getReason()));
            // 退款记录
            refundOrder.setApplicationTime(now).setRefundTime(now).setStatus(1);*/
            return R.fail(refundMessage);
        } else {
            refundMessage = "编号为" + order.getOrderNo() + "的订单已退款成功，退款金额" + refundOrder.getRefundMoney() + "元，已返还至您的支付渠道，请注意查收";
            orderCouponMiddleMapper.update(null, new UpdateWrapper<OrderCouponMiddle>().in("id", updateIds)
                    .set("status", OrderStatusEnum.REFUND.getStatus())
                    .set("refund_time", now)
                    .set(ifPartialRefund, "partial_refund_code", PartialRefundCode)
                    .set("refund_reason", refundOrder.getReason()));
            // 退款记录
            refundOrder.setApplicationTime(now).setRefundTime(now).setStatus(0);
            if (ifPartialRefund) {
                refundOrder.setPartialRefundCode(PartialRefundCode);
            }
        }
        // 更新总订单数据（中间表数据+订单表数据：当已退款个数+当前退款个数=已使用的券数时，订单状态改为已退款）
        if (refundCouponCount + refundCouponAmount == orderCouponMiddles.size()) {
            lifeUserOrderMapper.update(null, new UpdateWrapper<LifeUserOrder>().eq("id", order.getId())
                    .set("status", OrderStatusEnum.REFUND.getStatus())
                    .set("refund_time", now)
                    .set("finish_time", now));
            if (null != order.getQuanId()) {
                lifeDiscountCouponUserMapper.update(null, new UpdateWrapper<LifeDiscountCouponUser>().eq("id", order.getQuanId())
                        .set("status", DiscountCouponEnum.WAITING_USED.getValue()).set("use_time", null));
            } else {
                // 处理 quanId 为 null 的情况，例如日志记录
                log.error("更新优惠券状态失败");
            }
        } else if (refundCouponCount + refundCouponAmount != orderCouponMiddles.size() && refundCouponAmount == orderCouponMiddles1.size()) {
            // 累计退券个数+当前退券个数!=总个数 且 当前退券数量 = 可退券数
            lifeUserOrderMapper.update(null, new UpdateWrapper<LifeUserOrder>().eq("id", order.getId())
                    .set("status", OrderStatusEnum.COMPLETE.getStatus())
                    .set("finish_time", now));
        }

        // 将退款记录插入到数据库中
        if (lifeRefundOrderMapper.insert(refundOrder) > 0) {
            // 发送通知
            LifeNotice lifeMessage = new LifeNotice();
            LifeUser lifeUser = lifeUserMapper.selectById(order.getUserId());
            lifeMessage.setReceiverId("user_" + lifeUser.getUserPhone());
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("message", refundMessage);
            lifeMessage.setContext(jsonObject.toJSONString());
            lifeMessage.setSenderId("system");
            lifeMessage.setIsRead(0);
            lifeMessage.setNoticeType(2);
            lifeMessage.setTitle("退款成功");
            lifeNoticeUtil.fillUserTypeAndRefId(lifeMessage);
            lifeNoticeMapper.insert(lifeMessage);

            WebSocketVo websocketVo = new WebSocketVo();
            websocketVo.setSenderId("system");
            websocketVo.setReceiverId("user_" + lifeUser.getUserPhone());
            websocketVo.setCategory("notice");
            websocketVo.setNoticeType("1");
            websocketVo.setIsRead(0);
            websocketVo.setText(JSONObject.from(lifeMessage).toJSONString());
            try {
                webSocketProcess.sendMessage("user_" + lifeUser.getUserPhone(), JSONObject.from(websocketVo).toJSONString());
            } catch (Exception e) {
                log.error("LifeUserOrderService requestRefund Stack={}", e);
            }
        }
        // 退款后更新库存
        Integer couponType = order.getCouponType();
        OrderCouponMiddle orderCouponMiddle = orderCouponMiddleMapper.selectOne(new QueryWrapper<OrderCouponMiddle>().eq("order_id", refundOrder.getOrderId()).last("limit 1"));
        Integer couponId = orderCouponMiddle.getCouponId();

        restoreInventory(couponType, refundCouponAmount, couponId);
        return R.success(refundMessage);
    }

    /**
     * 退款,取消订单时候，恢复库存
     *
     * @param couponType         类型 1-代金券，2-团购
     * @param refundCouponAmount 团购券/代金券张数
     * @param couponId           团购券/代金券id
     */
    private void restoreInventory(Integer couponType, Integer refundCouponAmount, Integer couponId) {
        try {
            if (CouponTypeEnum.COUPON.getCode() == couponType) {
                // 代金券信息
                lifeCouponMapper.update(null, new LambdaUpdateWrapper<LifeCoupon>()
                        .setSql("single_qty=single_qty+" + refundCouponAmount)
                        .eq(LifeCoupon::getId, couponId));

                //判断当前时间在开始时间start_date和结束时间end_date之间，并且库存single_qty大于0，则修改状态status为5
                lifeCouponMapper.update(null, new LambdaUpdateWrapper<LifeCoupon>()
                        .set(LifeCoupon::getStatus, CouponStatusEnum.ONGOING.getCode())
                        .eq(LifeCoupon::getId, couponId)
                        .le(LifeCoupon::getStartDate, LocalDate.now())
                        .ge(LifeCoupon::getEndDate, LocalDate.now())
                        .gt(LifeCoupon::getSingleQty, 0));
            } else {
                // 团购信息
                lifeGroupBuyMainMapper.update(null, new LambdaUpdateWrapper<LifeGroupBuyMain>()
                        .setSql("inventory_num=inventory_num+" + refundCouponAmount)
                        .eq(LifeGroupBuyMain::getId, couponId));

                //判断当前时间在开始时间start_date和结束时间end_date之间，并且库存single_qty大于0，则修改状态status为5
                lifeGroupBuyMainMapper.update(null, new LambdaUpdateWrapper<LifeGroupBuyMain>()
                        .set(LifeGroupBuyMain::getStatus, CouponStatusEnum.ONGOING.getCode())
                        .eq(LifeGroupBuyMain::getId, couponId)
                        .le(LifeGroupBuyMain::getStartTimeValue, LocalDate.now())
                        .ge(LifeGroupBuyMain::getEndTime, LocalDate.now())
                        .gt(LifeGroupBuyMain::getInventoryNum, 0));
            }
        } catch (Exception e) {
            log.error("LifeUserOrderService，恢复团购券/代金券数量报错={}", e);
        }

    }

    /**
     * 退款检查
     *
     * @param refundOrder
     * @return
     */
    public Map<String, Object> refundCheck(Map<String, String> refundOrder) {
        Map<String, Object> returnMap = new HashMap<>();
        LifeUserOrder order = lifeUserOrderMapper.selectById(refundOrder.get("orderId"));
        if (null == order) {
            returnMap.put("success", "不可退款");
            returnMap.put("reason", "未查询到订单");
            return returnMap;
        }
        if (order.getStatus() != 1) {
            returnMap.put("success", "不可退款");
            returnMap.put("reason", "当前订单状态不是待消费");
            return returnMap;
        }
        if (Double.parseDouble(order.getFinalPrice()) < Double.parseDouble(refundOrder.get("refundMoney"))) {
            returnMap.put("success", "不可退款");
            returnMap.put("reason", "退款金额大于实付款");
            return returnMap;
        }
        returnMap.put("success", "可以退款");
        return returnMap;
    }

    /**
     * 根据订单号获取可用优惠劵数量
     *
     * @param orderNo
     * @return
     */
    public Integer getAvailableOrderNumByOrderNo(String orderNo) {
        // 统计可用优惠劵数量
        return orderCouponMiddleMapper.selectCount(new QueryWrapper<OrderCouponMiddle>().inSql("id", "select id from life_user_order where order_no = " + orderNo));
    }

    public String exportExcel(String orderNo, String storeId, String quanName, String baojiaStatus, String status) throws IOException {
        // 定义格式化模式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        List<LifeUserOrderExcelVo> lifeUserOrderExcelVos = new ArrayList<>();
        LambdaUpdateWrapper<LifeUserOrder> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(StringUtils.isNotEmpty(status), LifeUserOrder::getStatus, status);
        wrapper.like(StringUtils.isNotEmpty(orderNo), LifeUserOrder::getOrderNo, orderNo);
        wrapper.like(StringUtils.isNotEmpty(storeId), LifeUserOrder::getStoreId, storeId);

        boolean flag = true;
        if (StringUtils.isNotEmpty(quanName)) {
            LambdaUpdateWrapper<LifeCoupon> wrapper1 = new LambdaUpdateWrapper<>();
            wrapper1.like(LifeCoupon::getName, quanName);
            List<LifeCoupon> quanList = lifeCouponMapper.selectList(wrapper1);
            List<String> idList = quanList.stream().map(LifeCoupon::getId).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(idList)) {
                wrapper.in(LifeUserOrder::getQuanId, idList);
            } else {
                flag = false;
            }
        }
        if (flag) {
            wrapper.orderByAsc(LifeUserOrder::getStatus).orderByDesc(LifeUserOrder::getUpdatedTime);
        }
        List<Map<String, Object>> orderNoPage = lifeUserOrderMapper.selectMaps(wrapper);
        List<Object> orderNos = orderNoPage.stream()
                .map(record -> record.get("order_no"))
                .collect(Collectors.toList());
        // 根据订单号列表查询所有相关订单明细
        LambdaQueryWrapper<LifeUserOrder> detailWrapper = new LambdaQueryWrapper<>();
        detailWrapper.in(LifeUserOrder::getOrderNo, orderNos);
        List<LifeUserOrder> allOrderDetails = lifeUserOrderMapper.selectList(detailWrapper);
        // 按订单号分组处理
        Map<String, List<LifeUserOrder>> orderDetailsGrouped = allOrderDetails.stream()
                .collect(Collectors.groupingBy(LifeUserOrder::getOrderNo));
        int serialNumber = 0;
        for (Object orderDetails : orderDetailsGrouped.keySet()) {
            String orderNum = orderDetails.toString();
            List<LifeUserOrder> order = orderDetailsGrouped.getOrDefault(orderNum, Collections.emptyList());
            LifeUserOrder lifeUserOrder = order.get(0);
            LifeUserOrderExcelVo lifeUserOrderExcelVo = new LifeUserOrderExcelVo();
            if (lifeUserOrder.getCouponType() == 1) {
                if (null != lifeUserOrder.getQuanId() && !"".equals(lifeUserOrder.getQuanId())) {
                    LifeDiscountCouponUser lifeDiscountCouponUser = lifeDiscountCouponUserMapper.selectById(lifeUserOrder.getQuanId());
                    LifeCoupon quan = lifeCouponMapper.selectById(lifeDiscountCouponUser.getCouponId());
                    if (null != quan) {
                        lifeUserOrderExcelVo.setCouponName(quan.getName());
                        lifeUserOrderExcelVo.setImage(quan.getImagePath());
                        lifeUserOrderExcelVo.setPrice("¥" + quan.getPrice());
                    }
                }
            } else {
                OrderCouponMiddle orderCouponMiddle = orderCouponMiddleMapper.selectOne(new LambdaQueryWrapper<OrderCouponMiddle>().eq(OrderCouponMiddle::getOrderId, lifeUserOrder.getId()));
                LifeGroupBuyMain lifeGroupBuyMain = lifeGroupBuyMainMapper.selectOne(new LambdaQueryWrapper<LifeGroupBuyMain>().eq(LifeGroupBuyMain::getId, orderCouponMiddle.getCouponId()));
                lifeUserOrderExcelVo.setCouponName(lifeGroupBuyMain.getGroupName());
                lifeUserOrderExcelVo.setImage(storeImgMapper.selectById(Integer.parseInt(lifeGroupBuyMain.getImageId())).getImgUrl());
                lifeUserOrderExcelVo.setPrice("¥" + lifeGroupBuyMain.getPreferentialPrice());
            }
            QueryWrapper<StoreInfoVo> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("a.id", lifeUserOrder.getStoreId());
            StoreInfoVo storeInfoVoOne = storeInfoMapper.getStoreInfoVoOne(queryWrapper);
            lifeUserOrderExcelVo.setSerialNumber(++serialNumber);
            lifeUserOrderExcelVo.setOrderNo(lifeUserOrder.getOrderNo());
            lifeUserOrderExcelVo.setStoreId(lifeUserOrder.getStoreId());

            lifeUserOrderExcelVo.setStoreContact(storeInfoVoOne.getStoreContact());
            lifeUserOrderExcelVo.setPhone(storeInfoVoOne.getStorePhone());
            if (lifeUserOrder.getStatus() == 4) {
                Instant instant = lifeUserOrder.getCancelTime().toInstant();
                String formattedTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime().format(formatter);
                lifeUserOrderExcelVo.setCancelTime(formattedTime);
            } else if(lifeUserOrder.getStatus() != 0){
                Instant instant = lifeUserOrder.getPayTime().toInstant();
                // 格式化时间
                String formattedTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime().format(formatter);
                lifeUserOrderExcelVo.setPayTime(formattedTime);
                lifeUserOrderExcelVo.setFinishTime(formattedTime);
            }
            lifeUserOrderExcelVo.setOrderStatus(String.valueOf(lifeUserOrder.getStatus()));
            // 订单状态转换
            switch (lifeUserOrder.getStatus()) {
                case 0:
                    lifeUserOrderExcelVo.setOrderStatus("待使用");
                    break;
                case 1:
                    lifeUserOrderExcelVo.setOrderStatus("已核销");
                    break;
                case 2:
                    lifeUserOrderExcelVo.setOrderStatus("已过期");
                    break;
                case 3:
                    lifeUserOrderExcelVo.setOrderStatus("待退款");
                    break;
                case 4:
                    lifeUserOrderExcelVo.setOrderStatus("已退款");
                    break;
                case 5:
                    lifeUserOrderExcelVo.setOrderStatus("退款失败");
                    break;
                case 6:
                    lifeUserOrderExcelVo.setOrderStatus("已取消");
                    break;
                default:
                    lifeUserOrderExcelVo.setOrderStatus("未知状态");
            }
            lifeUserOrderExcelVos.add(lifeUserOrderExcelVo);
        }
        String fileName = UUID.randomUUID().toString().replace("-", "");
        String filePath = ExcelGenerator.generateExcel(excelPath + excelGeneratePath + fileName + ".xlsx", lifeUserOrderExcelVos, LifeUserOrderExcelVo.class);
        return aliOSSUtil.uploadFile(new File(filePath), "excel/" + fileName + ".xlsx");
    }

    /**
     * 创建用户订单
     *
     * @param lifeUserOrderDto 构造数据用
     */
    @Transactional(rollbackFor = Exception.class)
    public R createUserOrder(LifeUserOrderDto lifeUserOrderDto) {
        Date date = new Date();
        //1.创建订单
        LifeUserOrder lifeUserOrder = new LifeUserOrder();
        // 用户id
        lifeUserOrder.setUserId(lifeUserOrderDto.getUserId());
        // 店铺id
        lifeUserOrder.setStoreId(lifeUserOrderDto.getStoreId());
        // 订单号
        lifeUserOrder.setOrderNo(lifeUserOrderDto.getOrderNo());
        // 订单订单字符串
        lifeUserOrder.setOrderStr(lifeUserOrderDto.getOrderStr());
        // 优惠券id
        lifeUserOrder.setQuanId(lifeUserOrderDto.getYhquanId());
        // 原价金额
        lifeUserOrder.setPrice(lifeUserOrderDto.getPrice());
        // 付款金额
        lifeUserOrder.setFinalPrice(lifeUserOrderDto.getFinalPrice());
        // 订单类型
        lifeUserOrder.setCouponType(null == lifeUserOrderDto.getCouponType() ? 1 : lifeUserOrderDto.getCouponType());
        // 订单状态
        lifeUserOrder.setStatus(null == lifeUserOrderDto.getStatus() ? 0 : lifeUserOrderDto.getStatus());
        // 购买时间
        lifeUserOrder.setBuyTime(date);
        this.saveOrUpdate(lifeUserOrder);

        //3.根据购买数量增加中间关系 订单id+券编号 确定一条数据
        int buyCount = lifeUserOrderDto.getCount();
        BigDecimal totalPrice = new BigDecimal(lifeUserOrderDto.getFinalPrice());
        BigDecimal countDecimal = new BigDecimal(buyCount);
        BigDecimal perPrice = totalPrice.divide(countDecimal, 2, RoundingMode.DOWN);
        BigDecimal lastPrice = totalPrice.subtract(perPrice.multiply(countDecimal.subtract(BigDecimal.ONE)));

        //2.判断是否使用优惠券
        //查询优惠券信息
        BigDecimal avgDiscountCouponPrice = BigDecimal.ZERO;
        BigDecimal avgDiscountCouponLastPrice = BigDecimal.ZERO;
        LifeDiscountCoupon lifeDiscountCoupon = null;
        if (StringUtils.isNotEmpty(lifeUserOrderDto.getYhquanId())) {
            LifeDiscountCouponUser lifeDiscountCouponUser = lifeDiscountCouponUserMapper.selectById(lifeUserOrderDto.getYhquanId());
            //将优惠券状态变更为已使用
            lifeDiscountCouponUser.setStatus(Integer.parseInt(DiscountCouponEnum.HAVE_BEEN_USED.getValue()));
            //将优惠券使用时间存入
            lifeDiscountCouponUser.setUseTime(date);
            lifeDiscountCouponUserMapper.updateById(lifeDiscountCouponUser);
            lifeDiscountCoupon = lifeDiscountCouponMapper.selectByIdIncludeDeleted(lifeDiscountCouponUser.getCouponId());
            
            // 根据优惠券类型计算优惠金额
            Integer couponType = lifeDiscountCoupon.getCouponType();
            if (couponType == null || couponType == 1) {
                // 满减券（默认类型，兼容旧数据）：直接使用面值作为减免金额
                BigDecimal nominalValue = lifeDiscountCoupon.getNominalValue();
                if (nominalValue == null) {
                    nominalValue = BigDecimal.ZERO;
                }
                avgDiscountCouponPrice = nominalValue.divide(countDecimal, 2, RoundingMode.DOWN);
                avgDiscountCouponLastPrice = nominalValue.subtract(avgDiscountCouponPrice.multiply(countDecimal.subtract(BigDecimal.ONE)));
            } else if (couponType == 2) {
                // 折扣券：根据订单金额和折扣率计算优惠金额
                // 注意：totalPrice 是使用优惠券后的价格，需要反推原始价格
                // 如果折扣率为 discountRate（例如80表示8折），则：
                // 原始价格 = 优惠后价格 / (discountRate / 100)
                // 优惠金额 = 原始价格 - 优惠后价格
                BigDecimal discountRate = lifeDiscountCoupon.getDiscountRate();
                if (discountRate == null || discountRate.compareTo(BigDecimal.ZERO) <= 0 || discountRate.compareTo(new BigDecimal(100)) > 0) {
                    // 折扣率无效，使用0作为优惠金额
                    avgDiscountCouponPrice = BigDecimal.ZERO;
                    avgDiscountCouponLastPrice = BigDecimal.ZERO;
                } else {
                    // 计算原始订单总金额（使用优惠券前）
                    BigDecimal originalTotalPrice = totalPrice.divide(discountRate.divide(new BigDecimal(100), 4, RoundingMode.HALF_UP), 2, RoundingMode.HALF_UP);
                    // 计算总优惠金额
                    BigDecimal totalDiscountAmount = originalTotalPrice.subtract(totalPrice);
                    // 平均分配到每个券上
                    avgDiscountCouponPrice = totalDiscountAmount.divide(countDecimal, 2, RoundingMode.DOWN);
                    avgDiscountCouponLastPrice = totalDiscountAmount.subtract(avgDiscountCouponPrice.multiply(countDecimal.subtract(BigDecimal.ONE)));
                }
            } else {
                // 未知类型，使用0作为优惠金额
                avgDiscountCouponPrice = BigDecimal.ZERO;
                avgDiscountCouponLastPrice = BigDecimal.ZERO;
            }
        }

        for (int i = 0; i < buyCount; i++) {
            String code = UniqueRandomNumGenerator.generateUniqueCode(12);
            OrderCouponMiddle orderCouponMiddle = new OrderCouponMiddle();
            // 订单id
            orderCouponMiddle.setOrderId(lifeUserOrder.getId());
            // 团购/代金券id
            orderCouponMiddle.setCouponId(lifeUserOrderDto.getCouponId());
            // 团购/代金券 code
            orderCouponMiddle.setCouponCode(code);
            // 团购/代金券价格
            orderCouponMiddle.setPrice(i == buyCount - 1 ? lastPrice : perPrice);
            // 订单状态
            orderCouponMiddle.setStatus(0);
            // 设置平均优惠价
            orderCouponMiddle.setAvgDiscountCouponPrice(i == buyCount - 1 ? avgDiscountCouponLastPrice : avgDiscountCouponPrice);
            orderCouponMiddleService.save(orderCouponMiddle);
        }
        //4. 代金券/团购库存扣除 coupon_type 1 代金券 2团购
        Map<String, Object> returnMap = new HashMap<>();
        int soldOutStatus = CouponStatusEnum.SOLD_OUT.getCode();
        int updateRows = 0;

        if (lifeUserOrderDto.getCouponType() == 2) {
            // 团购库存：原子扣减
            updateRows = lifeGroupBuyMainMapper.deductInventoryAtomically(
                    lifeUserOrderDto.getCouponId(),
                    buyCount,
                    soldOutStatus
            );
        } else {
            // 代金券库存：原子扣减
            updateRows = lifeCouponMapper.deductInventoryAtomically(
                    lifeUserOrderDto.getCouponId(),
                    buyCount,
                    soldOutStatus
            );
        }
// 判断库存扣减结果
        if (updateRows == 0) {
            log.error("couponid:" + lifeUserOrderDto.getCouponId() + " 库存不足，当前购买数量:" + buyCount);
            // 手动抛出异常，触发事务回滚（回滚之前创建的订单和优惠券状态变更）
            return R.fail("库存不足，下单失败");
        }
        returnMap.put("success", "下单成功");
        returnMap.put("orderNo", lifeUserOrderDto.getOrderNo());
        returnMap.put("lifeUserOrder", lifeUserOrder);
        return R.data(returnMap);
    }

    /**
     * 更新用户订单
     *
     * @param lifeUserOrderDto 构造数据用
     */
    @Transactional
    public boolean updateUserOrder(LifeUserOrderDto lifeUserOrderDto) {
        Date date = new Date();
        LifeUserOrder lifeUserOrder = lifeUserOrderMapper.selectById(lifeUserOrderDto.getId());
        if (null == lifeUserOrder) {
            log.error("updateUserOrder未查询到订单");
            return false;
        }
        UpdateWrapper<OrderCouponMiddle> orderCouponMiddleUpdateWrapper = new UpdateWrapper<>();
        orderCouponMiddleUpdateWrapper.eq("order_id", lifeUserOrderDto.getId());
        // 根据状态判断怎么更新数据 目前只进行已支付，已取消，已过期判断
        switch (lifeUserOrderDto.getStatus()) {
            case 1:
                lifeUserOrder.setPayTime(date);
                lifeUserOrder.setPayMethod(lifeUserOrderDto.getPayMethod());
                lifeUserOrder.setStatus(lifeUserOrderDto.getStatus());
                lifeUserOrder.setOrderNo(lifeUserOrderDto.getOrderNo());
                orderCouponMiddleUpdateWrapper.set("status", lifeUserOrderDto.getStatus());
                break;
            case 3:
            case 4:
                lifeUserOrder.setStatus(lifeUserOrderDto.getStatus());
                lifeUserOrder.setCancelTime(date);
                lifeUserOrder.setFinishTime(date);
                orderCouponMiddleUpdateWrapper.set("status", lifeUserOrderDto.getStatus());
                break;
        }
        // 查询券id->查询一个
        int updateNum = orderCouponMiddleMapper.update(null, orderCouponMiddleUpdateWrapper);
        if (1 != lifeUserOrderDto.getStatus()) {
            List<OrderCouponMiddle> orderCouponMiddles = orderCouponMiddleMapper.selectList(new QueryWrapper<OrderCouponMiddle>().eq("order_id", lifeUserOrderDto.getId()));
            if (0 != updateNum && orderCouponMiddles.size() > 0) {
                Integer couponId = orderCouponMiddles.get(0).getCouponId();
                // 2.过期后更新库存
                Integer couponType = lifeUserOrder.getCouponType();
                restoreInventory(couponType, updateNum, couponId);
            } else {
                log.error("取消失败，未查询到订单");
                throw new RuntimeException("取消失败，未查询到订单");
            }
        }
        return this.saveOrUpdate(lifeUserOrder);
    }

    /**
     * 删除用户订单,删除需要判断订单状态并且删除中间关系
     *
     * @param orderId 订单id
     */
    @Transactional
    public boolean deleteUserOrder(String orderId) {
        LifeUserOrder lifeUserOrder = lifeUserOrderMapper.selectById(orderId);
        if (null == lifeUserOrder) {
            log.error("deleteUserOrder未查询到订单");
            return false;
        }
        // 判断订单状态
        // 已核销才可以删除和已退款可以核销
        if (lifeUserOrder.getStatus() == OrderStatusEnum.WAIT_USE.getStatus()) {
            log.error("deleteUserOrder订单状态错误,订单完成才可以删除");
            return false;
        }
        // 删除中间关系
        UpdateWrapper<OrderCouponMiddle> orderCouponMiddleUpdateWrapper = new UpdateWrapper<>();
        orderCouponMiddleUpdateWrapper.eq("order_id", orderId);
        return this.removeById(orderId) && orderCouponMiddleService.remove(orderCouponMiddleUpdateWrapper);
    }

    /**
     * 查询用户订单列表
     *
     * @param page       页码
     * @param size       每页数量
     * @param userId     用户id
     * @param couponType 订单类型
     * @param name       店铺名称
     */
    public IPage<LifeUserOrderVo> queryUserOrderList(Integer page, Integer size, String userId, String storeId, String couponType, String orderStatus, String name, String startTime, String endTime) {
        IPage<LifeUserOrderVo> brandedPage = new Page<>(page, size);
        QueryWrapper<LifeUserOrderVo> lifeUserOrderQueryWrapper = new QueryWrapper<>();
        lifeUserOrderQueryWrapper.eq(org.apache.commons.lang3.StringUtils.isNotBlank(userId), "luo.user_id", userId);
        lifeUserOrderQueryWrapper.eq(org.apache.commons.lang3.StringUtils.isNotBlank(storeId), "luo.store_id", storeId);
        lifeUserOrderQueryWrapper.eq(null != couponType && !"-1".equals(couponType), "luo.coupon_type", couponType);

        // 提取SQL基础部分，避免重复定义
        String baseSql = "select DISTINCT ocm1.order_id from order_coupon_middle ocm1 where 1=1";
        // TODO 应该可以直接判断总表
        if (!"-1".equals(orderStatus)) {
            // 非-1状态：直接添加状态条件
            String sql = baseSql + " and ocm1.status = " + orderStatus;
            if ("2".equals(orderStatus)) {
                // 已完成进行特殊处理,
                sql = sql + " and ocm1.order_id not in (\n" +
                        "\tselect\n" +
                        "\tDISTINCT ocm2.order_id\n" +
                        "from\n" +
                        "\torder_coupon_middle ocm2\n" +
                        "where\n" +
                        "\t ocm2.status = 1\n" +
                        "\t)";
            }
            lifeUserOrderQueryWrapper.inSql("luo.id", sql);
        } else {
            // -1状态且storeId不为空时添加条件
            if (org.apache.commons.lang3.StringUtils.isNotBlank(storeId)) {
                // 注意：原代码中的concat不会修改原字符串，需要重新赋值
                String sql = baseSql + " and ocm1.status not in  (" + OrderStatusEnum.WAIT_PAY.getStatus()
                        + "," + OrderStatusEnum.EXPIRE.getStatus()
                        + "," + OrderStatusEnum.CANCEL.getStatus()
                        + "," + OrderStatusEnum.REFUND.getStatus()
                        + ")";
                lifeUserOrderQueryWrapper.inSql("luo.id", sql);
            }
        }
        lifeUserOrderQueryWrapper.like(org.apache.commons.lang3.StringUtils.isNotBlank(name), "tc.coupon_name", name);
        lifeUserOrderQueryWrapper.gt(org.apache.commons.lang3.StringUtils.isNotBlank(startTime), "luo.created_time", startTime + " 00:00:00");
        lifeUserOrderQueryWrapper.lt(org.apache.commons.lang3.StringUtils.isNotBlank(endTime), "luo.created_time", endTime + " 23:59:59");
        lifeUserOrderQueryWrapper.eq("luo.delete_flag", 0);
        lifeUserOrderQueryWrapper.orderByDesc("luo.created_time");
        lifeUserOrderQueryWrapper.groupBy("luo.coupon_type", "luo.id");
        IPage<LifeUserOrderVo> lifeUserOrderVoIPage = lifeUserOrderMapper.queryUserOrderList(brandedPage, lifeUserOrderQueryWrapper);
        if (!"-1".equals(orderStatus)) {
            lifeUserOrderVoIPage.getRecords().forEach(x -> x.setStatus(Integer.parseInt(orderStatus)));
        }
        // 计算退款金额
        for (LifeUserOrderVo record : lifeUserOrderVoIPage.getRecords()) {
            record.setOrderCouponMiddleList(orderCouponMiddleMapper.selectList(new QueryWrapper<OrderCouponMiddle>().eq("order_id", record.getId())));
            calcExpectIncome(record);
            // 如果代金券为平台优惠券并且是商户查询,则需要计算代金券金额
            if ("3".equals(record.getType()) && org.apache.commons.lang3.StringUtils.isNotBlank(record.getStoreId())) {
                // 如果付款为0，商家收入为套餐原价
                if (record.getFinalPrice().equals("0")) {
                    // 如果付款为0，商家收入为套餐原价*数量
                    record.setFinalPrice(new BigDecimal(record.getPrice()).multiply(new BigDecimal(record.getCouponCount().toString())).toString());
                } else {
                    record.setFinalPrice(record.getNominalValue().add(new BigDecimal(record.getFinalPrice())).toString());
                }
            }
        }
        return lifeUserOrderVoIPage;
    }

    /**
     * 全部订单类型标识
     */
    private static final String ALL_COUPON_TYPE = "-1";

    /**
     * 删除标记：未删除
     */
    private static final Integer DELETE_FLAG_NOT_DELETED = 0;

    /**
     * 默认订单数量
     */
    private static final Long DEFAULT_ORDER_COUNT = 0L;

    /**
     * Map key：订单状态
     */
    private static final String KEY_ORDER_STATUS = "orderStatus";

    /**
     * Map key：订单数量
     */
    private static final String KEY_ORDER_COUNT = "orderCount";

    /**
     * 时间格式后缀：开始时间
     */
    private static final String TIME_START_SUFFIX = " 00:00:00";

    /**
     * 时间格式后缀：结束时间
     */
    private static final String TIME_END_SUFFIX = " 23:59:59";

    /**
     * Map key：订单列表
     */
    private static final String KEY_ORDER_LIST = "orderList";

    /**
     * Map key：待支付订单数量
     */
    private static final String KEY_WAIT_PAY_COUNT = "waitPayCount";

    /**
     * Map key：已支付/待使用订单数量
     */
    private static final String KEY_WAIT_USE_COUNT = "waitUseCount";

    /**
     * Map key：已核销订单数量
     */
    private static final String KEY_USED_COUNT = "usedCount";

    /**
     * Map key：已过期订单数量
     */
    private static final String KEY_EXPIRE_COUNT = "expireCount";

    /**
     * Map key：已取消订单数量
     */
    private static final String KEY_CANCEL_COUNT = "cancelCount";

    /**
     * Map key：已退款订单数量
     */
    private static final String KEY_REFUND_COUNT = "refundCount";

    /**
     * Map key：退款失败订单数量
     */
    private static final String KEY_REFUND_FAILED_COUNT = "refundFailedCount";

    /**
     * Map key：已完成订单数量
     */
    private static final String KEY_COMPLETE_COUNT = "completeCount";

    /**
     * Map key：全部订单数量
     */
    private static final String KEY_TOTAL_ORDER_COUNT = "total";

    /**
     * 查询用户订单列表（包含各状态订单数量统计）
     * <p>
     * 此方法用于查询订单列表并统计各状态订单数量，返回订单列表和统计信息
     * </p>
     *
     * @param page        页码，必须大于0
     * @param size        每页数量，必须大于0
     * @param userId      用户id，可为空
     * @param storeId     商户id，可为空
     * @param couponType  订单类型，-1表示全部
     * @param orderStatus 订单状态，-1表示全部
     * @param name        订单名称，可为空
     * @param startTime   开始时间，格式：yyyy-MM-dd，可为空
     * @param endTime     结束时间，格式：yyyy-MM-dd，可为空
     * @return 订单列表及统计信息Map，包含订单列表和各状态订单数量
     */
    public Map<String, Object> queryUserOrderListWithStatistics(
            Integer page, Integer size, String userId, String storeId, String couponType,
            String orderStatus, String name, String startTime, String endTime) {
        log.info("查询用户订单列表（包含统计）开始，page={}, size={}, userId={}, storeId={}, couponType={}, "
                        + "orderStatus={}, name={}, startTime={}, endTime={}",
                page, size, userId, storeId, couponType, orderStatus, name, startTime, endTime);

        // 参数校验（Controller层已有默认值，此处仅做防御性校验，不影响正常调用）
        // 注意：如果page或size为null或<=0，Page构造函数可能会抛出异常，保持与原代码行为一致
        if (page == null || page <= 0) {
            log.warn("查询用户订单列表（包含统计）参数校验失败：页码必须大于0，page={}", page);
            throw new IllegalArgumentException("页码必须大于0");
        }
        if (size == null || size <= 0) {
            log.warn("查询用户订单列表（包含统计）参数校验失败：每页数量必须大于0，size={}", size);
            throw new IllegalArgumentException("每页数量必须大于0");
        }

        // 查询订单列表
        IPage<LifeUserOrderVo> orderList = queryUserOrderListForStatistics(
                page, size, userId, storeId, couponType, orderStatus, name, startTime, endTime);

        // 构建统计查询条件
        QueryWrapper<LifeUserOrderVo> statisticsQueryWrapper = buildStatisticsQueryWrapper(
                userId, storeId, couponType, name, startTime, endTime);

        // 统计各状态订单数量
        List<Map<String, Object>> statusCountList = lifeUserOrderMapper.countOrdersByStatus(statisticsQueryWrapper);

        // 统计全部订单数量
        Long totalOrderCount = getTotalOrderCount(statisticsQueryWrapper);

        // 构建返回结果
        Map<String, Object> result = buildResultMap(orderList, totalOrderCount, statusCountList);

        log.info("查询用户订单列表（包含统计）成功，page={}, size={}, totalOrderCount={}, orderListSize={}",
                page, size, totalOrderCount, orderList.getRecords().size());

        return result;
    }

    /**
     * 查询用户订单列表（用于统计接口）
     * <p>
     * 此方法用于queryUserOrderListWithStatistics接口，逻辑与queryUserOrderList相同
     * 但不修改原queryUserOrderList方法
     * </p>
     *
     * @param page        页码
     * @param size        每页数量
     * @param userId      用户id
     * @param storeId     商户id
     * @param couponType  订单类型
     * @param orderStatus 订单状态
     * @param name        订单名称
     * @param startTime   开始时间
     * @param endTime     结束时间
     * @return 订单列表分页结果
     */
    private IPage<LifeUserOrderVo> queryUserOrderListForStatistics(
            Integer page, Integer size, String userId, String storeId, String couponType,
            String orderStatus, String name, String startTime, String endTime) {
        // 构建分页对象
        IPage<LifeUserOrderVo> brandedPage = new Page<>(page, size);

        // 构建查询条件
        QueryWrapper<LifeUserOrderVo> queryWrapper = buildOrderListQueryWrapper(
                userId, storeId, couponType, orderStatus, name, startTime, endTime);

        // 执行查询
        IPage<LifeUserOrderVo> lifeUserOrderVoIPage = lifeUserOrderMapper.queryUserOrderList(
                brandedPage, queryWrapper);

        // 设置订单状态
        setOrderStatus(lifeUserOrderVoIPage, orderStatus);

        // 处理订单数据（计算退款金额等）
        processOrderRecords(lifeUserOrderVoIPage.getRecords());

        return lifeUserOrderVoIPage;
    }

    /**
     * 构建订单列表查询条件
     *
     * @param userId      用户id
     * @param storeId     商户id
     * @param couponType  订单类型
     * @param orderStatus 订单状态
     * @param name        订单名称
     * @param startTime   开始时间
     * @param endTime     结束时间
     * @return 查询条件包装器
     */
    private QueryWrapper<LifeUserOrderVo> buildOrderListQueryWrapper(
            String userId, String storeId, String couponType, String orderStatus,
            String name, String startTime, String endTime) {
        QueryWrapper<LifeUserOrderVo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(org.apache.commons.lang3.StringUtils.isNotBlank(userId), "luo.user_id", userId);
        queryWrapper.eq(org.apache.commons.lang3.StringUtils.isNotBlank(storeId), "luo.store_id", storeId);
        queryWrapper.eq(null != couponType && !ALL_COUPON_TYPE.equals(couponType),
                "luo.coupon_type", couponType);

        // 构建订单状态查询条件
        buildOrderStatusQueryCondition(queryWrapper, orderStatus, storeId);

        queryWrapper.like(org.apache.commons.lang3.StringUtils.isNotBlank(name), "tc.coupon_name", name);
        queryWrapper.gt(org.apache.commons.lang3.StringUtils.isNotBlank(startTime),
                "luo.created_time", startTime + TIME_START_SUFFIX);
        queryWrapper.lt(org.apache.commons.lang3.StringUtils.isNotBlank(endTime),
                "luo.created_time", endTime + TIME_END_SUFFIX);
        queryWrapper.eq("luo.delete_flag", DELETE_FLAG_NOT_DELETED);
        queryWrapper.orderByDesc("luo.created_time");
        queryWrapper.groupBy("luo.coupon_type", "luo.id");

        return queryWrapper;
    }

    /**
     * 构建订单状态查询条件
     *
     * @param queryWrapper 查询条件包装器
     * @param orderStatus 订单状态
     * @param storeId     商户id
     */
    private void buildOrderStatusQueryCondition(QueryWrapper<LifeUserOrderVo> queryWrapper,
                                                String orderStatus, String storeId) {
        String baseSql = "select DISTINCT ocm1.order_id from order_coupon_middle ocm1 where 1=1";

        if (!ALL_COUPON_TYPE.equals(orderStatus)) {
            // 非-1状态：直接添加状态条件
            String sql = baseSql + " and ocm1.status = " + orderStatus;
            if ("2".equals(orderStatus)) {
                // 已完成状态进行特殊处理：排除待使用订单
                sql = sql + " and ocm1.order_id not in (\n" +
                        "\tselect\n" +
                        "\tDISTINCT ocm2.order_id\n" +
                        "from\n" +
                        "\torder_coupon_middle ocm2\n" +
                        "where\n" +
                        "\t ocm2.status = 1\n" +
                        "\t)";
            }
            queryWrapper.inSql("luo.id", sql);
        } else {
            // -1状态且storeId不为空时添加条件：排除待支付、已过期、已取消、已退款订单
            if (org.apache.commons.lang3.StringUtils.isNotBlank(storeId)) {
                String sql = baseSql + " and ocm1.status not in  (" + OrderStatusEnum.WAIT_PAY.getStatus()
                        + "," + OrderStatusEnum.EXPIRE.getStatus()
                        + "," + OrderStatusEnum.CANCEL.getStatus()
                        + "," + OrderStatusEnum.REFUND.getStatus()
                        + ")";
                queryWrapper.inSql("luo.id", sql);
            }
        }
    }

    /**
     * 设置订单状态
     * <p>
     * 保持与原queryUserOrderList方法相同的逻辑：如果orderStatus格式错误，会抛出NumberFormatException
     * </p>
     *
     * @param lifeUserOrderVoIPage 订单分页结果
     * @param orderStatus          订单状态
     */
    private void setOrderStatus(IPage<LifeUserOrderVo> lifeUserOrderVoIPage, String orderStatus) {
        if (!ALL_COUPON_TYPE.equals(orderStatus)) {
            // 保持与原代码相同的逻辑：直接解析，如果失败会抛出NumberFormatException
            Integer status = Integer.parseInt(orderStatus);
            lifeUserOrderVoIPage.getRecords().forEach(x -> x.setStatus(status));
        }
    }

    /**
     * 处理订单记录（计算退款金额等）
     *
     * @param records 订单记录列表
     */
    private void processOrderRecords(List<LifeUserOrderVo> records) {
        if (records == null || records.isEmpty()) {
            return;
        }

        for (LifeUserOrderVo record : records) {
            // 设置订单优惠券中间表数据
            setOrderCouponMiddleList(record);

            // 计算预期收入
            calcExpectIncome(record);

            // 计算平台优惠券金额（如果是商户查询）
            calculatePlatformCouponAmount(record);
        }
    }

    /**
     * 设置订单优惠券中间表数据
     *
     * @param record 订单记录
     */
    private void setOrderCouponMiddleList(LifeUserOrderVo record) {
        if (record == null || record.getId() == null) {
            return;
        }
        QueryWrapper<OrderCouponMiddle> middleQueryWrapper = new QueryWrapper<>();
        middleQueryWrapper.eq("order_id", record.getId());
        record.setOrderCouponMiddleList(orderCouponMiddleMapper.selectList(middleQueryWrapper));
    }

    /**
     * 计算平台优惠券金额（如果是商户查询）
     * <p>
     * 如果代金券为平台优惠券（type=3）并且是商户查询，则需要计算代金券金额
     * 保持与原queryUserOrderList方法相同的逻辑：如果finalPrice为null，会抛出NullPointerException
     * </p>
     *
     * @param record 订单记录
     */
    private void calculatePlatformCouponAmount(LifeUserOrderVo record) {
        if (record == null) {
            return;
        }

        // 如果代金券为平台优惠券并且是商户查询
        if (!"3".equals(record.getType()) || org.apache.commons.lang3.StringUtils.isBlank(record.getStoreId())) {
            return;
        }

        // 保持与原代码相同的逻辑：直接调用equals，如果finalPrice为null会抛出NullPointerException
        // 如果付款为0，商家收入为套餐原价*数量
        if (record.getFinalPrice().equals("0")) {
            // 如果付款为0，商家收入为套餐原价*数量
            record.setFinalPrice(new BigDecimal(record.getPrice())
                    .multiply(new BigDecimal(record.getCouponCount().toString())).toString());
        } else {
            // 如果付款不为0，商家收入为面额+最终价格
            record.setFinalPrice(record.getNominalValue()
                    .add(new BigDecimal(record.getFinalPrice())).toString());
        }
    }

    /**
     * 获取全部订单数量
     *
     * @param statisticsQueryWrapper 统计查询条件
     * @return 全部订单数量，如果为null则返回默认值0
     */
    private Long getTotalOrderCount(QueryWrapper<LifeUserOrderVo> statisticsQueryWrapper) {
        Long totalOrderCount = lifeUserOrderMapper.countTotalOrders(statisticsQueryWrapper);
        return totalOrderCount == null ? DEFAULT_ORDER_COUNT : totalOrderCount;
    }

    /**
     * 构建返回结果Map
     *
     * @param orderList      订单列表分页结果
     * @param totalOrderCount 全部订单数量
     * @param statusCountList 各状态订单数量统计列表
     * @return 包含订单列表和统计信息的结果Map
     */
    private Map<String, Object> buildResultMap(IPage<LifeUserOrderVo> orderList,
                                                Long totalOrderCount,
                                                List<Map<String, Object>> statusCountList) {
        Map<String, Object> result = new HashMap<>(16);
        result.put(KEY_ORDER_LIST, orderList.getRecords());
        result.put(KEY_TOTAL_ORDER_COUNT, totalOrderCount);

        // 初始化各状态订单数量为默认值
        initializeStatusCounts(result);

        // 填充各状态订单数量
        fillStatusCountsToMap(result, statusCountList);

        return result;
    }

    /**
     * 初始化各状态订单数量为默认值
     *
     * @param result 结果Map
     */
    private void initializeStatusCounts(Map<String, Object> result) {
        result.put(KEY_WAIT_PAY_COUNT, DEFAULT_ORDER_COUNT);
        result.put(KEY_WAIT_USE_COUNT, DEFAULT_ORDER_COUNT);
        result.put(KEY_USED_COUNT, DEFAULT_ORDER_COUNT);
        result.put(KEY_EXPIRE_COUNT, DEFAULT_ORDER_COUNT);
        result.put(KEY_CANCEL_COUNT, DEFAULT_ORDER_COUNT);
        result.put(KEY_REFUND_COUNT, DEFAULT_ORDER_COUNT);
        result.put(KEY_REFUND_FAILED_COUNT, DEFAULT_ORDER_COUNT);
        result.put(KEY_COMPLETE_COUNT, DEFAULT_ORDER_COUNT);
    }

    /**
     * 构建统计查询条件
     * <p>
     * 与列表查询条件相同，但不包含状态筛选、分页和分组
     * </p>
     *
     * @param userId     用户id
     * @param storeId    商户id
     * @param couponType 订单类型
     * @param name       订单名称
     * @param startTime  开始时间
     * @param endTime    结束时间
     * @return 查询条件包装器
     */
    private QueryWrapper<LifeUserOrderVo> buildStatisticsQueryWrapper(String userId, String storeId,
                                                                      String couponType, String name,
                                                                      String startTime, String endTime) {
        QueryWrapper<LifeUserOrderVo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(org.apache.commons.lang3.StringUtils.isNotBlank(userId), "luo.user_id", userId);
        queryWrapper.eq(org.apache.commons.lang3.StringUtils.isNotBlank(storeId), "luo.store_id", storeId);
        queryWrapper.eq(null != couponType && !ALL_COUPON_TYPE.equals(couponType), "luo.coupon_type", couponType);
        queryWrapper.like(org.apache.commons.lang3.StringUtils.isNotBlank(name), "tc.coupon_name", name);
        queryWrapper.gt(org.apache.commons.lang3.StringUtils.isNotBlank(startTime),
                "luo.created_time", startTime + TIME_START_SUFFIX);
        queryWrapper.lt(org.apache.commons.lang3.StringUtils.isNotBlank(endTime),
                "luo.created_time", endTime + TIME_END_SUFFIX);
        queryWrapper.eq("luo.delete_flag", DELETE_FLAG_NOT_DELETED);
        return queryWrapper;
    }

    /**
     * 填充各状态订单数量到Map
     * <p>
     * 遍历状态统计列表，将各状态的订单数量填充到结果Map中
     * </p>
     *
     * @param result         结果Map
     * @param statusCountList 状态统计列表
     */
    private void fillStatusCountsToMap(Map<String, Object> result,
                                       List<Map<String, Object>> statusCountList) {
        if (statusCountList == null || statusCountList.isEmpty()) {
            log.debug("状态统计列表为空，跳过填充");
            return;
        }

        for (Map<String, Object> item : statusCountList) {
            Integer status = getIntegerValue(item.get(KEY_ORDER_STATUS));
            Long count = getLongValue(item.get(KEY_ORDER_COUNT));
            if (status != null && count != null) {
                setStatusCountToMap(result, status, count);
            } else {
                log.warn("状态统计项数据异常，status={}, count={}", status, count);
            }
        }
    }

    /**
     * 根据订单状态设置对应的数量到Map
     * <p>
     * 根据订单状态枚举值，将对应的订单数量设置到结果Map的相应key中
     * </p>
     *
     * @param result 结果Map
     * @param status 订单状态
     * @param count  订单数量
     */
    private void setStatusCountToMap(Map<String, Object> result, Integer status, Long count) {
        if (OrderStatusEnum.WAIT_PAY.getStatus().equals(status)) {
            result.put(KEY_WAIT_PAY_COUNT, count);
        } else if (OrderStatusEnum.WAIT_USE.getStatus().equals(status)) {
            result.put(KEY_WAIT_USE_COUNT, count);
        } else if (OrderStatusEnum.USED.getStatus().equals(status)) {
            result.put(KEY_USED_COUNT, count);
        } else if (OrderStatusEnum.EXPIRE.getStatus().equals(status)) {
            result.put(KEY_EXPIRE_COUNT, count);
        } else if (OrderStatusEnum.CANCEL.getStatus().equals(status)) {
            result.put(KEY_CANCEL_COUNT, count);
        } else if (OrderStatusEnum.REFUND.getStatus().equals(status)) {
            result.put(KEY_REFUND_COUNT, count);
        } else if (OrderStatusEnum.REFUND_FAILED.getStatus().equals(status)) {
            result.put(KEY_REFUND_FAILED_COUNT, count);
        } else if (OrderStatusEnum.COMPLETE.getStatus().equals(status)) {
            result.put(KEY_COMPLETE_COUNT, count);
        } else {
            log.warn("未知的订单状态，status={}, count={}", status, count);
        }
    }

    /**
     * 从Map中获取Integer值
     * <p>
     * 支持Integer、Long、Number类型的转换
     * </p>
     *
     * @param value 对象值，可能为Integer、Long或其他Number类型
     * @return Integer值，如果value为null或无法转换则返回null
     */
    private Integer getIntegerValue(Object value) {
        if (value == null) {
            return null;
        }
        if (value instanceof Integer) {
            return (Integer) value;
        }
        if (value instanceof Long) {
            return ((Long) value).intValue();
        }
        if (value instanceof Number) {
            return ((Number) value).intValue();
        }
        return null;
    }

    /**
     * 从Map中获取Long值
     * <p>
     * 支持Long、Integer、Number类型的转换
     * </p>
     *
     * @param value 对象值，可能为Long、Integer或其他Number类型
     * @return Long值，如果value为null或无法转换则返回null
     */
    private Long getLongValue(Object value) {
        if (value == null) {
            return null;
        }
        if (value instanceof Long) {
            return (Long) value;
        }
        if (value instanceof Integer) {
            return ((Integer) value).longValue();
        }
        if (value instanceof Number) {
            return ((Number) value).longValue();
        }
        return null;
    }

    /**
     * 查询用户订单详情
     *
     * @param orderId
     * @return
     */
    public R<LifeUserOrderVo> queryUserOrderDetail(String orderId, String longitude, String latitude) {
        LifeUserOrderVo lifeUserOrderVo = lifeUserOrderMapper.queryUserOrderDetail(orderId, org.apache.commons.lang3.StringUtils.isNotBlank(longitude) && org.apache.commons.lang3.StringUtils.isNotBlank(latitude) ? longitude + "," + latitude : "");
        if (null == lifeUserOrderVo) {
            log.error("queryUserOrderDetail未查询到订单");
            return R.fail("未查询到订单");
        }
        calcExpectIncome(lifeUserOrderVo);
        return R.data(lifeUserOrderVo);
    }

    private static void calcExpectIncome(LifeUserOrderVo lifeUserOrderVo) {
        // 退款记录
        List<OrderCouponMiddle> orderCouponMiddleList = lifeUserOrderVo.getOrderCouponMiddleList();
        List<OrderCouponMiddle> refundList = orderCouponMiddleList.stream().filter(x -> x.getStatus() == OrderStatusEnum.REFUND.getStatus()).collect(Collectors.toList());
        lifeUserOrderVo.setRefundList(refundList);
        // 预计收入
        // 退款金额
        BigDecimal refundAmount = new BigDecimal(0);
        if (!CollectionUtils.isEmpty(refundList)) {
            refundAmount = refundList.stream().map(OrderCouponMiddle::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
        }
        // 预计收入
        BigDecimal expectIncome = BigDecimal.ZERO;
        // 如果使用了平台优惠券则预计收入特殊处理
        if ("3".equals(lifeUserOrderVo.getType())) {
            if (lifeUserOrderVo.getFinalPrice().equals("0")) {
                // 如果付款为0，商家收入为套餐原价*数量
                expectIncome = new BigDecimal(lifeUserOrderVo.getPrice()).multiply(new BigDecimal(orderCouponMiddleList.size()));
            } else {
                expectIncome = new BigDecimal(lifeUserOrderVo.getFinalPrice()).add(lifeUserOrderVo.getNominalValue());
            }
        } else {
            expectIncome = new BigDecimal(lifeUserOrderVo.getFinalPrice());
        }
        expectIncome = expectIncome.subtract(refundAmount);
        String commissionRateStr = lifeUserOrderVo.getCommissionRate();
        BigDecimal commissionRate = BigDecimal.ZERO;
        if (org.apache.commons.lang3.StringUtils.isNotBlank(commissionRateStr)) {
            try {
                // 将字符串转换为 BigDecimal，并除以 100（转换为小数）
                commissionRate = new BigDecimal(commissionRateStr)
                        .divide(new BigDecimal("100"), 4, RoundingMode.DOWN);
                // 保留 4 位小数，四舍五入（确保计算精度）
            } catch (NumberFormatException e) {
                // 处理非数字格式的异常（如 commissionRate 为空或非法字符）
                e.printStackTrace();
                // 可根据业务需求设置默认值或抛出提示
            } catch (ArithmeticException e) {
                // 处理除法异常（理论上除以 100 不会出现，此处为稳妥处理）
                e.printStackTrace();
            }
        }
        expectIncome = expectIncome.subtract(expectIncome.multiply(commissionRate)).setScale(2, RoundingMode.DOWN);
        lifeUserOrderVo.setExpectIncome(expectIncome);
    }

    /**
     * 平台端-查询订单列表
     *
     * @param page            页码
     * @param size            每页数量
     * @param orderNo         订单号
     * @param orderStatus     订单状态
     * @param couponName      优惠券名称
     * @param couponType      优惠券类型
     * @param storeName       店铺名称
     * @param buyStartTime    购买时间开始
     * @param buyEndTime      购买时间结束
     * @param payStartTime    支付时间开始
     * @param payEndTime      支付时间结束
     * @param finishStartTime 完成时间开始
     * @param finishEndTime   完成时间结束
     */
    public IPage<LifeUserOrderVo> queryOrderList(Integer page, Integer size, String orderNo, String orderStatus, String couponName, String couponType, String storeName, String buyStartTime, String buyEndTime, String payStartTime, String payEndTime, String finishStartTime, String finishEndTime) {
        IPage<LifeUserOrderVo> brandedPage = new Page<>(page, size);
        QueryWrapper<LifeUserOrderVo> lifeUserOrderQueryWrapper = new QueryWrapper<>();
        lifeUserOrderQueryWrapper.like(org.apache.commons.lang3.StringUtils.isNotBlank(orderNo), "luo.order_no", orderNo);
        lifeUserOrderQueryWrapper.like(org.apache.commons.lang3.StringUtils.isNotBlank(couponName), "tc.coupon_name", couponName);
        lifeUserOrderQueryWrapper.eq(org.apache.commons.lang3.StringUtils.isNotBlank(couponType), "tc.coupon_type", couponType);
        lifeUserOrderQueryWrapper.like(org.apache.commons.lang3.StringUtils.isNotBlank(storeName), "si.store_name", storeName);
        lifeUserOrderQueryWrapper.gt(org.apache.commons.lang3.StringUtils.isNotBlank(buyStartTime), "luo.buy_time", buyStartTime + " 00:00:00");
        lifeUserOrderQueryWrapper.lt(org.apache.commons.lang3.StringUtils.isNotBlank(buyEndTime), "luo.buy_time", buyEndTime + " 23:59:59");
        lifeUserOrderQueryWrapper.gt(org.apache.commons.lang3.StringUtils.isNotBlank(payStartTime), "luo.pay_time", payStartTime + " 00:00:00");
        lifeUserOrderQueryWrapper.lt(org.apache.commons.lang3.StringUtils.isNotBlank(payEndTime), "luo.pay_time", payEndTime + " 23:59:59");
        lifeUserOrderQueryWrapper.gt(org.apache.commons.lang3.StringUtils.isNotBlank(finishStartTime), "luo.finish_time", finishStartTime + " 00:00:00");
        lifeUserOrderQueryWrapper.lt(org.apache.commons.lang3.StringUtils.isNotBlank(finishEndTime), "luo.finish_time", finishEndTime + " 23:59:59");
//            @ApiImplicitParam(name = "orderStatus", value = "订单状态,-1，全部（可以不传）；0，待支付;1，已支付/待使用;2，已核销；3，已过期;4，已取消;5.已退款，全退款了才算", required = false),
        // 提取SQL基础部分，避免重复定义
//        String baseSql = "select DISTINCT ocm1.order_id from order_coupon_middle ocm1 where 1=1";

        if (!"-1".equals(orderStatus)) {
            // 非-1状态：直接添加状态条件
//            String sql = baseSql + " and ocm1.status = " + orderStatus;
//            lifeUserOrderQueryWrapper.inSql("luo.id", sql);
            lifeUserOrderQueryWrapper.eq("luo.status", orderStatus);
        }
        lifeUserOrderQueryWrapper.groupBy("luo.id");
        IPage<LifeUserOrderVo> lifeUserOrderVoIPage = lifeUserOrderMapper.queryUserOrderList(brandedPage, lifeUserOrderQueryWrapper);

        if (!"-1".equals(orderStatus)) {
            lifeUserOrderVoIPage.getRecords().forEach(x -> x.setStatus(Integer.parseInt(orderStatus)));
        }
        return lifeUserOrderVoIPage;
    }

    /**
     * 平台-查询订单列表
     *
     * @param page            页码
     * @param size            每页数量
     * @param orderNo         订单号
     * @param orderStatus     订单状态
     * @param couponName      优惠券名称
     * @param couponType      优惠券类型
     * @param storeName       店铺名称
     * @param buyStartTime    购买时间开始
     * @param buyEndTime      购买时间结束
     * @param payStartTime    支付时间开始
     * @param payEndTime      支付时间结束
     * @param finishStartTime 完成时间开始
     * @param finishEndTime   完成时间结束
     */
    public IPage<LifeUserOrderVo> queryPlatformOrderList(Integer page, Integer size, String orderNo, String orderStatus, String couponName, String couponType, String storeName, String buyStartTime, String buyEndTime, String payStartTime, String payEndTime, String finishStartTime, String finishEndTime) {
        IPage<LifeUserOrderVo> brandedPage = new Page<>(page, size);
        QueryWrapper<LifeUserOrderVo> lifeUserOrderQueryWrapper = new QueryWrapper<>();
        lifeUserOrderQueryWrapper.like(org.apache.commons.lang3.StringUtils.isNotBlank(orderNo), "luo.order_no", orderNo);
        lifeUserOrderQueryWrapper.like(org.apache.commons.lang3.StringUtils.isNotBlank(couponName), "tc.coupon_name", couponName);
        lifeUserOrderQueryWrapper.eq(org.apache.commons.lang3.StringUtils.isNotBlank(couponType), "tc.coupon_type", couponType);
        lifeUserOrderQueryWrapper.like(org.apache.commons.lang3.StringUtils.isNotBlank(storeName), "si.store_name", storeName);
        lifeUserOrderQueryWrapper.gt(org.apache.commons.lang3.StringUtils.isNotBlank(buyStartTime), "luo.buy_time", buyStartTime + " 00:00:00");
        lifeUserOrderQueryWrapper.lt(org.apache.commons.lang3.StringUtils.isNotBlank(buyEndTime), "luo.buy_time", buyEndTime + " 23:59:59");
        lifeUserOrderQueryWrapper.gt(org.apache.commons.lang3.StringUtils.isNotBlank(payStartTime), "luo.pay_time", payStartTime + " 00:00:00");
        lifeUserOrderQueryWrapper.lt(org.apache.commons.lang3.StringUtils.isNotBlank(payEndTime), "luo.pay_time", payEndTime + " 23:59:59");
        lifeUserOrderQueryWrapper.gt(org.apache.commons.lang3.StringUtils.isNotBlank(finishStartTime), "luo.finish_time", finishStartTime + " 00:00:00");
        lifeUserOrderQueryWrapper.lt(org.apache.commons.lang3.StringUtils.isNotBlank(finishEndTime), "luo.finish_time", finishEndTime + " 23:59:59");

//            @ApiImplicitParam(name = "orderStatus", value = "订单状态,-1，全部（可以不传）；0，待支付;1，已支付/待使用;2，已核销；3，已过期;4，已取消;5.已退款，全退款了才算", required = false),
        // 提取SQL基础部分，避免重复定义
//        String baseSql = "select DISTINCT ocm1.order_id from order_coupon_middle ocm1 where 1=1";

        if (!"-1".equals(orderStatus)) {
            // 非-1状态：直接添加状态条件
//            String sql = baseSql + " and ocm1.status = " + orderStatus;
//            lifeUserOrderQueryWrapper.inSql("luo.id", sql);
            lifeUserOrderQueryWrapper.eq("luo.status", orderStatus);
        } else {
            lifeUserOrderQueryWrapper.in("luo.status", 0,1,4,5,7);
        }

        lifeUserOrderQueryWrapper.groupBy("luo.id");
        IPage<LifeUserOrderVo> lifeUserOrderVoIPage = lifeUserOrderMapper.queryPlatformOrderList(brandedPage, lifeUserOrderQueryWrapper);

        if (!"-1".equals(orderStatus)) {
            lifeUserOrderVoIPage.getRecords().forEach(x -> x.setStatus(Integer.parseInt(orderStatus)));
        }
        return lifeUserOrderVoIPage;
    }

    /**
     * 平台端-查询订单详情
     *
     * @param orderId
     * @return
     */
    public R queryOrderDetail(String orderId) {
        LifeUserOrderVo lifeUserOrderVo = lifeUserOrderMapper.queryUserOrderDetail(orderId, null);
        if (null == lifeUserOrderVo) {
            log.error("queryUserOrderDetail未查询到订单");
            return R.fail("未查询到订单");
        }
        // 退款记录
        calcExpectIncome(lifeUserOrderVo);
        lifeUserOrderVo.setCouponCount(lifeUserOrderVo.getOrderCouponMiddleList().size());
        // 查询订单图片列表
        String imgIds = lifeUserOrderVo.getImgIds();
        if(StringUtils.isNotEmpty(imgIds)){
            LambdaQueryWrapper<StoreImg> storeImgLambdaQueryWrapper = new LambdaQueryWrapper<>();
            List<String> imgIdList = Arrays.stream(imgIds.split(","))
                    .map(String::trim)
                    .collect(Collectors.toList());
            storeImgLambdaQueryWrapper.in(StoreImg::getId, imgIdList);
            List<StoreImg> storeImgList = storeImgMapper.selectList(storeImgLambdaQueryWrapper);
            if(CollectionUtils.isNotEmpty(storeImgList)){
                List<String> imgUrlList = storeImgList.stream()    // 转换为 Stream
                        .map(StoreImg::getImgUrl)                  // 映射，提取 name 字段
                        .collect(Collectors.toList());
                lifeUserOrderVo.setImgUrls(imgUrlList);
            }
        }
        return R.data(lifeUserOrderVo);
    }

    /**
     * 团购/代金券-校验用户是否可以购买
     *
     * @param couponId   团购/代金券id
     * @param couponType 团购/代金券类型
     * @param userId     用户id
     * @param count      购买数量
     * @return
     */
    public Map<String, Object> buyCouponCheck(String couponId, Integer couponType, String userId, String storeId, Integer count) {
        Map<String, Object> returnMap = new HashMap<>();
        // 获取团购/代金券信息
        Integer status = 0;
        // 限购数量， 已购数量
        Integer buyLimit = 0;
        Integer buyCount = 0;
        // 库存
        Integer stockQty = 0;
        // 结束时间
        Date endTime = null;
        if (couponType == CouponTypeEnum.GROUP_BUY.getCode()) {
            // 团购
            LifeGroupBuyMain lifeGroupBuyMain = lifeGroupBuyMainMapper.selectById(couponId);
            status = lifeGroupBuyMain.getStatus();
            // 限购类型
            Integer quotaType = lifeGroupBuyMain.getQuotaType();
            if (0 != quotaType) {
                // 限购数量
                buyLimit = Integer.parseInt(lifeGroupBuyMain.getQuotaValue());
                // 已购数量
                buyCount = orderCouponMiddleMapper.selectCount(new QueryWrapper<OrderCouponMiddle>().eq("coupon_id", couponId).notIn("status", OrderStatusEnum.CANCEL.getStatus(), OrderStatusEnum.REFUND.getStatus())
                        .inSql("order_id", "select id from life_user_order where user_id = " + userId + " and store_id = " + storeId));
            }
            // 库存 inventory_num
            stockQty = lifeGroupBuyMain.getInventoryNum();
            endTime = lifeGroupBuyMain.getEndTime();
        } else if (couponType == CouponTypeEnum.COUPON.getCode()) {
            // 代金券
            LifeCoupon lifeCoupon = lifeCouponMapper.selectById(couponId);
            status = lifeCoupon.getStatus();
            // 限购数量
            buyLimit = Integer.parseInt(lifeCoupon.getPurchaseLimitCode());
            // 已购数量
            buyCount = orderCouponMiddleMapper.selectCount(new QueryWrapper<OrderCouponMiddle>().eq("coupon_id", couponId).notIn("status", OrderStatusEnum.CANCEL.getStatus(), OrderStatusEnum.REFUND.getStatus())
                    .inSql("order_id", "select id from life_user_order where user_id = " + userId + " and store_id = " + storeId));
            stockQty = lifeCoupon.getSingleQty();
            endTime = lifeCoupon.getEndDate();
        } else {
            log.error("buyCouponCheck-团购/代金券类型错误");
            returnMap.put("success", false);
            returnMap.put("reason", "团购/代金券类型错误");
            return returnMap;
        }
        // 状态(0草稿/1待审核/2未开始/3审核拒绝/4已售罄/5进行中/6已下架/7已结束/8=2+手动下架)
        if (status != CouponStatusEnum.ONGOING.getCode()) {
            returnMap.put("success", false);
            if (status == CouponStatusEnum.SOLD_OUT.getCode()) {
                returnMap.put("reason", "团购/代金券已售罄");
            } else {
                returnMap.put("reason", "团购/代金券未开始");
            }
            return returnMap;
        }
        // 限购
        if (0 != buyLimit) {
            if (buyCount + count > buyLimit) {
                returnMap.put("success", false);
                returnMap.put("reason", "已达限购上限");
                return returnMap;
            }
        }
        // 库存
        if (count > stockQty) {
            returnMap.put("success", false);
            returnMap.put("reason", "购买数量大于库存数量");
            return returnMap;
        }
        // 时间
        Date now = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(now);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        Date nowDay = calendar.getTime();
        if (nowDay.compareTo(endTime) > 0) {
            if (couponType == CouponTypeEnum.GROUP_BUY.getCode()) {
                lifeGroupBuyMainMapper.update(null, new UpdateWrapper<LifeGroupBuyMain>().set("status", CouponStatusEnum.ENDED.getCode()).eq("id", couponId));
            } else {
                lifeCouponMapper.update(null, new UpdateWrapper<LifeCoupon>().set("status", CouponStatusEnum.ENDED.getCode()).eq("id", couponId));
            }
            returnMap.put("success", false);
            returnMap.put("reason", "活动已结束");
            return returnMap;
        }
        returnMap.put("success", true);
        returnMap.put("reason", "可以支付");
        return returnMap;
    }
}