package com.yiqi.order.service.impl;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.yiqi.common.exception.ServiceException;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yiqi.app.domain.AppCouponItem;
import com.yiqi.app.domain.AppUser;
import com.yiqi.app.domain.dto.AppDeliveryManListQueryDTO;
import com.yiqi.app.domain.vo.AppUserVO;
import com.yiqi.app.service.IAppCouponItemService;
import com.yiqi.app.service.IAppUserBillMstrService;
import com.yiqi.app.service.IAppUserService;
import com.yiqi.common.core.domain.AuthHolder;
import com.yiqi.common.core.domain.BaseEntity;
import com.yiqi.common.core.domain.PageVO;
import com.yiqi.common.core.domain.R;
import com.yiqi.common.enums.*;
import com.yiqi.common.utils.*;
import com.yiqi.common.utils.pay.PayCodeUtils;
import com.yiqi.core.domain.*;
import com.yiqi.core.domain.vo.ClothHangerOrderRelationVO;
import com.yiqi.core.service.*;
import com.yiqi.delay.DelayMessage;
import com.yiqi.delay.DelayQueueCache;
import com.yiqi.order.domain.*;
import com.yiqi.order.domain.dto.*;
import com.yiqi.order.domain.dto.weapp.OrderClothAppQueryDTO;
import com.yiqi.order.domain.vo.*;
import com.yiqi.order.service.*;
import com.yiqi.recharge.service.IRechargePasswordCardService;
import com.yiqi.system.domain.SysOrg;
import com.yiqi.system.domain.SysSettlementRate;
import com.yiqi.system.domain.SysStore;
import com.yiqi.system.service.ISysConfigService;
import com.yiqi.system.service.ISysOrgService;
import com.yiqi.system.service.ISysSettlementRateService;
import com.yiqi.system.service.ISysStoreService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.yiqi.order.mapper.OrderClothMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

/**
 * 洗衣订单Service业务层处理
 *
 * @author ruoyi
 * @date 2023-10-06
 */
@Service
public class OrderClothServiceImpl extends ServiceImpl<OrderClothMapper, OrderCloth> implements IOrderClothService {

    @Autowired
    private IClothSpeedService clothSpeedService;
    @Autowired
    private IClothWashModeService clothWashModeService;
    @Autowired
    private IClothFlawService clothFlawService;
    @Autowired
    private IClothFlawTypeService clothFlawTypeService;
    @Autowired
    private IClothColorService clothColorService;
    @Autowired
    private IClothCraftService clothCraftService;
    @Autowired
    private IClothTypeService clothTypeService;
    @Autowired
    private IOrderClothRefundService orderClothRefundService;
    @Autowired
    private ISysStoreService sysStoreService;
    @Autowired
    private IAppUserService appUserService;
    @Autowired
    private IOrderClothItemService orderClothItemService;
    @Autowired
    private IOrderClothFlawService orderClothFlawService;
    @Autowired
    private IOrderClothColorService orderClothColorService;
    @Autowired
    private IOrderClothCraftService orderClothCraftService;
    @Autowired
    private IOrderClothTypeService orderClothTypeService;
    @Autowired
    private IOrderClothAdjunctService orderClothAdjunctService;
    @Autowired
    private ISysConfigService sysConfigService;
    @Autowired
    private IOrderClothCouponRelationService orderClothCouponRelationService;
    @Autowired
    private IOrderClothItemCouponRelationService orderClothItemCouponRelationService;
    @Autowired
    private IAppCouponItemService appCouponItemService;
    @Autowired
    private IRechargePasswordCardService rechargePasswordCardService;
    @Autowired
    private IAppUserBillMstrService appUserBillMstrService;
    @Autowired
    private OrderNoUtils orderNoUtils;
    @Autowired
    private ISysOrgService sysOrgService;
    @Autowired
    private IPayService payService;
    @Autowired
    private IOrderClothItemFlowRecordService orderClothItemFlowRecordService;
    @Autowired
    private IOrderGoodsService orderGoodsService;
    @Autowired
    private IOrderRechargeService orderRechargeService;
    @Autowired
    private ISysSettlementRateService sysSettlementRateService;
    @Autowired
    private ISysConfigService configService;
    @Autowired
    private IOrderClothDeliveryAddressService orderClothDeliveryAddressService;
    @Autowired
    private IOrderClothAddressService orderClothAddressService;
    @Autowired
    private IOrderPayInfoService orderPayInfoService;
    @Autowired
    private DelayQueueCache delayQueueCache;

    @Override
    public void handleDeliverySuccessUpdateOrderStatus(String orderNo) {
        OrderClothDeliveryAddress orderClothDeliveryAddress = orderClothDeliveryAddressService.getOne(
                new QueryWrapper<OrderClothDeliveryAddress>().lambda()
                        .eq(OrderClothDeliveryAddress::getThirdDeliveryOrderNo, orderNo));
        if (orderClothDeliveryAddress == null) {
            throw new ServiceException("未查询到配送信息");
        }
        OrderCloth orderCloth = getOne(
                new QueryWrapper<OrderCloth>().lambda().eq(OrderCloth::getId, orderClothDeliveryAddress.getOrderId()));
        if (orderCloth == null) {
            throw new ServiceException("未查询到洗衣订单");
        }
        if (orderClothDeliveryAddress.getClothOrderType().equals(ClothOrderDeliveryType.collectCloth.getCode())
                && (orderCloth.getOrderStatus().equals(ClothOrderStatusType.WAITING_TO_DOOR.getCode())
                || orderCloth.getOrderStatus().equals(ClothOrderStatusType.HAS_TO_DOOR.getCode()))) {
            update(new UpdateWrapper<OrderCloth>().lambda()
                    .set(OrderCloth::getOrderStatus, ClothOrderStatusType.HAS_TAKING.getCode())
                    .eq(OrderCloth::getId, orderCloth.getId()));
        }
        if (orderClothDeliveryAddress.getClothOrderType().equals(ClothOrderDeliveryType.takeCloth.getCode())
                && (orderCloth.getOrderStatus().equals(ClothOrderStatusType.WAITING_TO_SEND.getCode())
                || orderCloth.getOrderStatus().equals(ClothOrderStatusType.SENDING.getCode()))) {
            update(new UpdateWrapper<OrderCloth>().lambda()
                    .set(OrderCloth::getOrderStatus, ClothOrderStatusType.FINISH.getCode())
                    .eq(OrderCloth::getId, orderCloth.getId()));
        }
    }

    @Override
    public R paySuccess(String orderNo, String outTradeNo) {
        //查询订单
        OrderCloth orderCloth = getOne(new QueryWrapper<OrderCloth>().lambda().eq(OrderCloth::getOrderNo, orderNo));
        if (!ClothOrderStatusType.WAITING_FOR_PAY.getCode().equals(orderCloth.getOrderStatus())
                && !ClothOrderStatusType.CANCEL.getCode().equals(orderCloth.getOrderStatus())) {
            return R.fail("订单状态不正确，无法支付执行支付成功操作");
        }
        if (ClothOrderPayTimeType.take_cloth_pay.getCode().equals(orderCloth.getPayTimeType())) {//收衣付款
            orderCloth.setOrderStatus(ClothOrderStatusType.WASHING.getCode());
        } else {//取衣付款
            orderCloth.setOrderStatus(ClothOrderStatusType.HAS_WASH.getCode());
        }
        updateById(orderCloth);
        return R.ok();
    }

    @Override
    public R payExpireOrCancelNotify(String orderNo) {
        OrderPayInfo orderPayInfo = orderPayInfoService.getOrderPayInfoByPayOrderNo(orderNo);
        if (orderPayInfo == null) {
            return R.fail("未查询到订单");
        }
        OrderCloth orderCloth = getOne(new QueryWrapper<OrderCloth>().lambda().eq(OrderCloth::getOrderNo, orderPayInfo.getOrderNo()));
        if (!ClothOrderStatusType.WAITING_FOR_PAY.getCode().equals(orderCloth.getOrderStatus())) {
            return R.fail("订单状态不正确，无法支付执行支付取消操作");
        }
        orderCloth.setOrderStatus(ClothOrderStatusType.CANCEL.getCode());
        updateById(orderCloth);
        return R.ok();
    }

    @Override
    public R refundSuccess(String refundNo, String orderNo) {
        OrderClothRefund orderClothRefund = orderClothRefundService.getOrderClothRefundByRefundNo(refundNo);
        orderClothRefund.setRefundStatus(OrderRefundStatus.REFUND_SUCCESS.getCode());
        orderClothRefund.setRefundTime(DateUtils.getNowDate());
        orderClothRefundService.updateById(orderClothRefund);

        if (orderNo == null) {
            orderNo = orderClothRefund.getOrderNo();
        }

        OrderCloth orderCloth = getOne(new QueryWrapper<OrderCloth>().lambda().eq(OrderCloth::getOrderNo, orderNo));
        if (orderCloth == null) {
            throw new ServiceException("未查询到订单");
        }
        if (orderCloth.getRefundStatus() == OrderRefundStatus.REFUND_SUCCESS.getCode()) {//退款状态不正确，直接跳过
            return R.ok();
        }


        orderCloth.setRefundTime(DateUtils.getNowDate());
        orderCloth.setRefundStatus(OrderRefundStatus.REFUND_SUCCESS.getCode());
        updateById(orderCloth);

        orderClothItemService.update(new UpdateWrapper<OrderClothItem>().lambda()
                .set(OrderClothItem::getFlowStatus, ClothOrderFlowStatus.refund.getCode())
                .eq(OrderClothItem::getOrderId, orderCloth.getId()));

        List<OrderClothItem> orderClothItems = orderClothItemService.list(new QueryWrapper<OrderClothItem>().lambda()
                .eq(OrderClothItem::getOrderId, orderCloth.getId()));
        orderClothItemFlowRecordService.addRecordBatch(orderClothItems, ClothOrderFlowStatus.refund.getCode());
        return R.ok();
    }

    @Override
    public R refundClosed(String orderNo) {
        OrderCloth orderCloth = getOne(new QueryWrapper<OrderCloth>().lambda().eq(OrderCloth::getOrderNo, orderNo));
        if (orderCloth == null) {
            throw new ServiceException("未查询到订单");
        }

        orderCloth.setRefundStatus(OrderRefundStatus.REFUND_SUCCESS.getCode());
        updateById(orderCloth);
        return R.ok();
    }

    @Override
    public R refundError(String orderNo) {
        OrderCloth orderCloth = getOne(new QueryWrapper<OrderCloth>().lambda().eq(OrderCloth::getOrderNo, orderNo));
        if (orderCloth == null) {
            throw new ServiceException("未查询到订单");
        }

        orderCloth.setRefundStatus(OrderRefundStatus.ERROR.getCode());
        updateById(orderCloth);
        return R.ok();
    }

    @Override
    public R<Page<OrderClothQueryVO>> findPage(LambdaQueryWrapper<OrderCloth> queryWrapper, PageVO pageVO) {
        Page<OrderCloth> page = page(new Page<OrderCloth>(pageVO.getPageNum(), pageVO.getPageSize())
                , queryWrapper);
        if (page.getRecords().size() == 0) {
            Page<OrderClothQueryVO> orderClothQueryVOPage = new Page<>();
            orderClothQueryVOPage.setTotal(page.getTotal());
            return R.ok(orderClothQueryVOPage);
        }
        Map<Long, AppUser> appUserMap = appUserService.list(new QueryWrapper<AppUser>().lambda()
                .in(AppUser::getId, page.getRecords().stream().map(OrderCloth::getAppUserId)
                        .collect(Collectors.toSet()))).stream().collect(Collectors.toMap(AppUser::getId, AppUser -> AppUser));

        Map<Long, AppUser> sendClothUserMap = new HashMap<>();
        if (page.getRecords().stream().filter(orderCloth -> orderCloth.getSendClothAppUserId() != null).map(OrderCloth::getAppUserId).collect(Collectors.toSet()).size() > 0) {
            sendClothUserMap = appUserService.list(new QueryWrapper<AppUser>().lambda()
                            .in(AppUser::getId, page.getRecords().stream().filter(orderCloth -> orderCloth.getSendClothAppUserId() != null)
                                    .map(OrderCloth::getAppUserId).collect(Collectors.toSet())))
                    .stream().collect(Collectors.toMap(AppUser::getId, AppUser -> AppUser));
        }

        List<OrderClothQueryVO> orderClothQueryVOS = new ArrayList<>();
        for (OrderCloth record : page.getRecords()) {
            OrderClothQueryVO orderClothQueryVO = new OrderClothQueryVO();
            BeanUtils.copyProperties(record, orderClothQueryVO);
            if (appUserMap.containsKey(record.getAppUserId())) {
                orderClothQueryVO.setAppUserName(appUserMap.get(record.getAppUserId()).getRealName());
                orderClothQueryVO.setAppUserPhoneNumber(appUserMap.get(record.getAppUserId()).getPhoneNumber());
            }
            if (record.getSendClothAppUserId() != null && sendClothUserMap.containsKey(record.getSendClothAppUserId())) {
                AppUserVO appUserVO = new AppUserVO();
                BeanUtils.copyProperties(sendClothUserMap.get(record.getSendClothAppUserId()), appUserVO);
                orderClothQueryVO.setSendClothUserVO(appUserVO);
            }
            orderClothQueryVOS.add(orderClothQueryVO);
        }

        //如果为总部查询，需要带上组织信息返回
        if (SourceType.MANAGER.getCode().equals(SecurityUtils.getLoginUser().getSourceType())) {
            Map<Long, SysOrg> storeOrgMap = new HashMap<>();
            Map<Long, SysOrg> factoryOrgMap = new HashMap<>();
            if (page.getRecords().stream().filter(orderCloth -> SourceType.STORE.getCode()
                    .equals(orderCloth.getSourceType())).collect(Collectors.toList()).size() > 0) {
                storeOrgMap = sysOrgService.list(new QueryWrapper<SysOrg>().lambda().eq(SysOrg::getSourceType
                                , SourceType.STORE.getCode()).in(SysOrg::getId, page.getRecords().stream()
                                .map(OrderCloth::getOrgId).collect(Collectors.toSet()))).stream()
                        .collect(Collectors.toMap(SysOrg::getId, SysOrg -> SysOrg));
            }
            if (page.getRecords().stream().filter(orderCloth -> SourceType.FACTORY.getCode()
                    .equals(orderCloth.getSourceType())).collect(Collectors.toList()).size() > 0) {
                factoryOrgMap = sysOrgService.list(new QueryWrapper<SysOrg>().lambda().eq(SysOrg::getSourceType
                                , SourceType.FACTORY.getCode()).in(SysOrg::getId, page.getRecords().stream()
                                .map(OrderCloth::getOrgId).collect(Collectors.toSet()))).stream()
                        .collect(Collectors.toMap(SysOrg::getId, SysOrg -> SysOrg));
            }
            for (OrderClothQueryVO orderClothQueryVO : orderClothQueryVOS) {
                if (SourceType.STORE.getCode().equals(orderClothQueryVO.getSourceType())) {
                    orderClothQueryVO.setSysOrg(storeOrgMap.get(orderClothQueryVO.getOrgId()));
                } else if (SourceType.FACTORY.getCode().equals(orderClothQueryVO.getSourceType())) {
                    orderClothQueryVO.setSysOrg(factoryOrgMap.get(orderClothQueryVO.getOrgId()));
                }
            }
        }
        Page<OrderClothQueryVO> orderClothQueryVOPage = new Page<>();
        orderClothQueryVOPage.setRecords(orderClothQueryVOS);
        orderClothQueryVOPage.setTotal(page.getTotal());
        return R.ok(orderClothQueryVOPage);
    }

    @Override
    public List<OrderClothVO> findPage(OrderClothAppQueryDTO orderClothAppQueryDTO) {
        return baseMapper.findPage(orderClothAppQueryDTO, AuthHolder.userId());
    }

    @Override
    public OrderCloth collectCloth(OrderClothDTO orderClothDTO) throws Exception {
        OrderCloth orderCloth = null;
        if (SysBoolType.YES.getCode().equals(orderClothDTO.getIsAppointment())) {//匹配预约单号
            if (StringUtils.isEmpty(orderClothDTO.getOrderNo())) {
                throw new ServiceException("预约单号不能为空");
            }
            orderCloth = getOne(new QueryWrapper<OrderCloth>().lambda()
                    .eq(OrderCloth::getOrderNo, orderClothDTO.getOrderNo())
                    .eq(OrderCloth::getAppUserId, orderClothDTO.getAppUserId())
                    .eq(OrderCloth::getDelFlag, DeleteStatus.OK.getCode()), false);
            if (orderCloth == null) {
                throw new ServiceException("未查询到预约订单");
            }
        } else {//新建订单
            orderCloth = new OrderCloth();
            orderCloth.setCreateBy(SecurityUtils.getUsername());
            orderCloth.setCreateById(SecurityUtils.getUserId());
            orderCloth.setCreateTime(DateUtils.getNowDate());
            orderCloth.setAppUserId(orderClothDTO.getAppUserId());
            //新建为到店收衣方式
            orderCloth.setTakeClothWay(TakeOrSendClothWay.TOSTORE.getCode());
            //门店新建的订单
            orderCloth.setOrderType(ClothOrderType.normal.getCode());
            buildAppUserInfoOrder(orderCloth);
        }
        //配置订单基本数据
        buildClothOrderInfo(orderCloth, orderClothDTO);
        //配置订单洗衣速度
        buildClothSpeedIntoOrder(orderCloth);
        //配置组织信息
        buildOrgIntoOrder(orderCloth);
        saveOrUpdate(orderCloth);

        List<OrderClothItem> orderClothItems = buildOrderClothItemData(orderClothDTO.getOrderClothItemDTOS(), orderCloth);

        //配置工厂洗衣费等费率
//        buildSettlement(orderCloth,orderClothItems);

        //所有的数据处理完后，将订单的总金额进行更新
        buildOrderTotalPrice(orderCloth, orderClothItems);

        //取衣时再付款，直接配置订单状态为清洗中
        if (ClothOrderPayTimeType.send_cloth_pay.getCode().equals(orderClothDTO.getPayTimeType())) {
            orderCloth.setOrderStatus(ClothOrderStatusType.WASHING.getCode());
        } else {
            orderCloth.setOrderStatus(ClothOrderStatusType.WAITING_FOR_PAY.getCode());
        }

        //取衣时再付款，直接配置订单状态为清洗中
//        if(ClothOrderPayTimeType.send_cloth_pay.getCode().equals(orderClothDTO.getPayTimeType())){
//            orderCloth.setOrderStatus(ClothOrderStatusType.WASHING.getCode());
//        }else{
//            //配置订单优惠券使用情况
//            buildOrderCoupon(orderCloth,orderClothItems,orderClothDTO.getOrderCouponDTOS());
//
//            //如果是现金或者余额支付，将订单状态修改为已支付，如果是余额，则扣减余额
//            if(PayType.BALANCE.getCode().equals(orderCloth.getPayType())){
//                orderCloth.setPayTime(DateUtils.getNowDate());
//                appUserBillMstrService.consumeRecord(ConsumeOrderDTO.buildOrderClothData(orderCloth));
//                orderCloth.setOrderStatus(ClothOrderStatusType.WASHING.getCode());
//            } else if(orderCloth.getPayType().equals(PayType.CASH.getCode())){
//                orderCloth.setPayTime(DateUtils.getNowDate());
//                orderCloth.setOrderStatus(ClothOrderStatusType.WASHING.getCode());
//            }else{
//                //线上支付，需要返回支付信息
//                orderCloth.setOrderStatus(ClothOrderStatusType.WAITING_FOR_PAY.getCode());
//                payService.faceToFacePay(PayOrderFaceToFaceDTO.buildClothOrderPayData(orderCloth,orderClothDTO.getAuthCode()));
//            }
//        }
        orderClothItemService.updateBatchById(orderClothItems);
        updateById(orderCloth);
        return orderCloth;
    }

    /**
     * 退款
     *
     * @param orderId
     * @param remark
     */
    @Override
    public void refundOrderApply(Long orderId, String remark) {
        LambdaQueryWrapper<OrderCloth> queryWrapper = new QueryWrapper<OrderCloth>().lambda()
                .eq(OrderCloth::getId, orderId);
        if (!SourceType.MANAGER.getCode().equals(SecurityUtils.getLoginUser().getSourceType())) {
            queryWrapper.eq(OrderCloth::getSourceType, SecurityUtils.getLoginUser().getSourceType())
                    .eq(OrderCloth::getOrgId, SecurityUtils.getLoginUser().getOrgId());
        }
        OrderCloth orderCloth = getOne(queryWrapper);
        if (orderCloth == null) {
            throw new ServiceException("未查询到订单");
        }
        OrderClothRefund orderClothRefund = new OrderClothRefund();
        BeanUtils.copyProperties(orderCloth, orderClothRefund);
        orderClothRefund.setId(null);
        orderClothRefund.setRefundNo(orderNoUtils.getClothOrderNo());
        orderClothRefund.setRefundAmount(orderCloth.getRefundAmount());
        orderClothRefund.setRefundApplyTime(DateUtils.getNowDate());
        orderClothRefund.setRefundReason(remark);
        orderClothRefund.setRefundStatus(OrderRefundStatus.REFUND_APPLYING.getCode());
        orderClothRefundService.save(orderClothRefund);

        orderCloth.setRefundStatus(OrderRefundStatus.REFUNDING.getCode());
        orderCloth.setRefundAmount(orderCloth.getPayAmount());
        baseMapper.updateById(orderCloth);

        //执行退款逻辑
        if (orderCloth.getPayType().equals(PayType.CASH.getCode())) {
            refundSuccess(orderClothRefund.getRefundNo(), orderCloth.getOrderNo());
        }
        if (orderCloth.getPayType().equals(PayType.BALANCE.getCode())) {
            //充值卡支付退单
            Boolean res = rechargePasswordCardService.orderRefundByBalance(orderClothRefund.getOrderNo(), orderClothRefund.getRefundAmount());
            if (res) {
                refundSuccess(orderClothRefund.getRefundNo(), orderCloth.getOrderNo());
            }
        }
        if (orderCloth.getPayType().equals(PayType.WECHAT.getCode()) || orderCloth.getPayType().equals(PayType.ALIPAY.getCode())) {
            PayRefundDTO payRefundDTO = new PayRefundDTO(orderCloth.getPayType(), orderCloth.getOrderNo(), orderClothRefund.getRefundAmount(), orderClothRefund.getRefundNo(), orderCloth.getOutTradeOrderNo(), remark);
            //执行微信退款逻辑
            payRefundDTO.setTotalAmount(orderCloth.getPayAmount());
            RefundResponseDTO refundResponse = payService.refundApply(payRefundDTO);

            if (refundResponse.getRefundResult().equals(PayResult.success.getCode())) {
                refundSuccess(orderClothRefund.getRefundNo(), orderCloth.getOrderNo());
            } else if (refundResponse.getRefundResult().equals(PayResult.fail.getCode())) {
                orderClothRefund.setRefundStatus(OrderRefundStatus.ERROR.getCode());
                orderClothRefund.setRemark(refundResponse.getPayMsg());
                orderClothRefundService.updateById(orderClothRefund);

                orderCloth.setRefundStatus(OrderRefundStatus.ERROR.getCode());
                baseMapper.updateById(orderCloth);
            } else {
                //增加到延迟支付查询队列
                DelayMessage delayMessage = new DelayMessage(payRefundDTO.getOutRequestNo(), DelayTagsEnum.ORDER_REUND_DELAY_QUEUE_TASK.getCode(), JSONUtil.toJsonStr(payRefundDTO));
                //暂不执行
                delayQueueCache.addDelayJob(delayMessage, RefundQueryTimesEnum.getDelayTime(delayMessage.getPollingNum()));
            }
        }
    }


    @Override
    public OrderCloth getOrderClothByOrderNo(String orderNo) {
        return getOne(new QueryWrapper<OrderCloth>().lambda().eq(OrderCloth::getOrderNo, orderNo));
    }

    @Override
    public OrderPayResultVO clothOrderPay(OrderClothPayDTO orderClothPayDTO) {
        OrderCloth orderCloth = getOrderClothByOrderNo(orderClothPayDTO.getOrderNo());
        if (orderCloth == null) {
            throw new ServiceException("未查询到订单");
        }
        if (orderCloth.getPayStatus().equals(PayStatus.HAS_PAY.getCode())) {
            throw new ServiceException("订单已支付");
        }
        if (!orderCloth.getPayAmount().equals(orderCloth.getPayAmount())) {
            throw new ServiceException("订单金额有误");
        }
        if (orderClothPayDTO.getPayType().equals(PayType.CASH.getCode())) {
            orderCloth.setPayType(PayType.CASH.getCode());
            if (orderCloth.getOrderStatus().equals(ClothOrderStatusType.WAITING_FOR_PAY.getCode())) {
                orderCloth.setOrderStatus(ClothOrderStatusType.WASHING.getCode());
            }
            orderCloth.setPayStatus(PayStatus.HAS_PAY.getCode());
            this.updateById(orderCloth);
            return OrderPayResultVO.paySuccess(orderCloth.getOrderNo());
        }
        if (orderClothPayDTO.getPayType().equals(PayType.WECHAT.getCode())) {
            String payType = null;
            try {
                payType = PayCodeUtils.getPayTypeByCode(orderClothPayDTO.getAuthCode());
            } catch (ServiceException e) {
                return OrderPayResultVO.payError(e.getMessage());
            }
            orderCloth.setPayType(payType);
            this.updateById(orderCloth);
            try {
                //创建支付订单，防止出现错误
                OrderPayInfo orderPayInfo = orderPayInfoService.createOrderPayInfo(orderCloth.getOrderNo(), orderCloth.getPayAmount(), orderCloth.getPayType());
                //优先增加到延迟队列
                DelayMessage delayMessage = new DelayMessage(orderPayInfo.getPayOrderNo(), DelayTagsEnum.ORDER_PAY_DELAY_QUEUE.getCode(), JSONUtil.toJsonStr(orderPayInfo));
                //暂不执行
                delayMessage.setIsRun(0);
                delayQueueCache.addDelayJob(delayMessage, PayQueryTimesEnum.getDelayTime(delayMessage.getPollingNum()));

                PayResponseDTO payResponseDTO = payService.faceToFacePay(PayOrderFaceToFaceDTO.createRechargeOrderPayData(orderPayInfo.getPayOrderNo(), orderPayInfo.getPayAmount(), orderPayInfo.getPayType(), orderClothPayDTO.getAuthCode()));
                if (payResponseDTO.getPayResult().equals(PayResult.success.getCode())) {
                    orderCloth.setPayStatus(PayStatus.HAS_PAY.getCode());
                    this.updateById(orderCloth);
                    delayQueueCache.deleteDelayJob(orderPayInfo.getPayOrderNo());
                    return OrderPayResultVO.paySuccess(orderCloth.getOrderNo());
                } else if (payResponseDTO.getPayResult().equals(PayResult.fail.getCode())) {
                    delayQueueCache.deleteDelayJob(orderPayInfo.getPayOrderNo());
                    return OrderPayResultVO.payError(payResponseDTO.getPayMsg());
                } else {
                    //更新开始执行查询
                    delayMessage.setIsRun(1);
                    delayQueueCache.addDelayJob(delayMessage, PayQueryTimesEnum.getDelayTime(delayMessage.getPollingNum()));
                    return OrderPayResultVO.payWait(orderCloth.getOrderNo());
                }
            } catch (Exception e) {
                e.printStackTrace();
                return OrderPayResultVO.payError("扫收款码支付失败");
            }
        }
        //会员余额支付
        if (orderClothPayDTO.getPayType().equals(PayType.BALANCE.getCode())) {
            orderCloth.setPayType(PayType.BALANCE.getCode());
            RechargeCardPayDTO rechargeCardPayDTO = new RechargeCardPayDTO(orderCloth.getAppUserId(), orderCloth.getOrgId(), orderCloth.getOrderNo(), orderCloth.getPayAmount(), OrderType.cloth.getCode());
            rechargePasswordCardService.orderPayByBalance(rechargeCardPayDTO);
            orderCloth.setPayStatus(PayStatus.HAS_PAY.getCode());
            this.updateById(orderCloth);
            return OrderPayResultVO.paySuccess(orderCloth.getOrderNo());
        }
        return OrderPayResultVO.payError("请重新支付");
    }

    private void buildSettlement(OrderCloth orderCloth, List<OrderClothItem> orderClothItems) {
        SysSettlementRate factoryRate = sysSettlementRateService.getOne(new QueryWrapper<SysSettlementRate>()
                .lambda().eq(SysSettlementRate::getSourceType, SourceType.FACTORY.getCode())
                .eq(SysSettlementRate::getOrgId, orderCloth.getFactoryId()));

        SysSettlementRate storeRate = null;
        if (orderCloth.getSourceType().equals(SourceType.STORE.getCode())) {
            storeRate = sysSettlementRateService.getOne(new QueryWrapper<SysSettlementRate>()
                    .lambda().eq(SysSettlementRate::getSourceType, orderCloth.getSourceType())
                    .eq(SysSettlementRate::getOrgId, orderCloth.getOrgId()));
        }

        for (OrderClothItem orderClothItem : orderClothItems) {
            if (orderCloth.getSourceType().equals(SourceType.STORE.getCode())) {
                orderClothItem.setFactorySettlementRate(storeRate.getFactoryRate());
            } else {
                orderClothItem.setFactorySettlementRate(factoryRate.getFactoryRate());
            }

            orderClothItem.setMaterialRate(factoryRate.getMaterialRate());
            orderClothItem.setManageRate(factoryRate.getManageRate());
            if (orderClothItem.getFactorySettlementRate() == null) {
                orderClothItem.setFactorySettlementAmount(BigDecimal.ZERO);
            } else {
                orderClothItem.setFactorySettlementAmount(orderClothItem.getTotalPrice().multiply(orderClothItem.getFactorySettlementRate()));
            }
            if (orderClothItem.getMaterialRate() == null) {
                orderClothItem.setMaterialAmount(BigDecimal.ZERO);
            } else {
                orderClothItem.setMaterialAmount(orderClothItem.getFactorySettlementAmount().multiply(orderClothItem.getMaterialRate()));
            }
            if (orderClothItem.getManageRate() == null) {
                orderClothItem.setManageAmount(BigDecimal.ZERO);
            } else {
                orderClothItem.setManageAmount(orderClothItem.getFactorySettlementAmount().multiply(orderClothItem.getManageRate()));
            }
        }
    }

    private void buildOrderCoupon(OrderCloth orderCloth, List<OrderClothItem> orderClothItems, List<OrderCouponDTO> orderCouponDTOS) {
        if (orderCouponDTOS == null || orderCouponDTOS.size() == 0) {
            return;
        }
        Map<Long, AppCouponItem> appCouponItemMap = appCouponItemService.list(new QueryWrapper<AppCouponItem>().lambda()
                        .eq(AppCouponItem::getAppUserId, orderCloth.getAppUserId())
                        .in(AppCouponItem::getId,
                                orderCouponDTOS.stream().map(OrderCouponDTO::getId).collect(Collectors.toSet())))
                .stream().collect(Collectors.toMap(AppCouponItem::getId, AppCouponItem -> AppCouponItem));
        BigDecimal discountAmount = BigDecimal.ZERO;
        List<OrderClothCouponRelation> orderClothCouponRelations = new ArrayList<>();
        List<OrderClothItemCouponRelation> orderClothItemCouponRelations = new ArrayList<>();
        for (OrderCouponDTO orderCouponDTO : orderCouponDTOS) {
            OrderClothCouponRelation orderClothCouponRelation = new OrderClothCouponRelation();
            orderClothCouponRelation.setOrderId(orderCloth.getId());
            orderClothCouponRelation.setOrderNo(orderCloth.getOrderNo());
            orderClothCouponRelation.setCouponItemId(orderCouponDTO.getId());
            orderClothCouponRelation.buildCreateData();
            orderClothCouponRelations.add(orderClothCouponRelation);

            for (OrderCouponClothDTO orderCouponClothDTO : orderCouponDTO.getOrderCouponClothDTOS()) {
                OrderClothItemCouponRelation orderClothItemCouponRelation = new OrderClothItemCouponRelation();
                orderClothItemCouponRelation.setClothId(orderClothItems.get(orderCouponClothDTO.getClothIndex()).getClothItemId());
                orderClothItemCouponRelation.setOrderClothItemId(orderClothItems.get(orderCouponClothDTO.getClothIndex()).getId());
                orderClothItemCouponRelation.setCouponItemId(orderCouponDTO.getId());
                orderClothItemCouponRelation.setOrderId(orderCloth.getId());
                orderClothItemCouponRelation.setOrderNo(orderCloth.getOrderNo());
                orderClothItemCouponRelation.setDiscountPrice(orderCouponClothDTO.getDeductAmount());
                orderClothItemCouponRelation.buildCreateData();
                orderClothItemCouponRelations.add(orderClothItemCouponRelation);
                orderClothItems.get(orderCouponClothDTO.getClothIndex()).setPayPrice(orderClothItems.get(orderCouponClothDTO.getClothIndex())
                        .getPayPrice().subtract(orderCouponClothDTO.getDeductAmount()));
                discountAmount = discountAmount.add(orderClothItemCouponRelation.getDiscountPrice());
            }
        }

        orderClothCouponRelationService.saveBatch(orderClothCouponRelations);
        orderClothItemCouponRelationService.saveBatch(orderClothItemCouponRelations);

        orderCloth.setCouponDeductAmount(discountAmount);
        orderCloth.setPayAmount(orderCloth.getOrderAmount().subtract(orderCloth.getCouponDeductAmount())
                .subtract(orderCloth.getCashDeductAmount()));

        //优惠券使用完后，将优惠券修改为已使用状态
        appCouponItemService.update(new UpdateWrapper<AppCouponItem>()
                .lambda().set(AppCouponItem::getIsUsed, SysBoolType.YES.getCode())
                .set(AppCouponItem::getUsedStoreId, SecurityUtils.getLoginUser().getOrgId())
                .set(AppCouponItem::getUsedTime, DateUtils.getNowDate())
                .eq(AppCouponItem::getAppUserId, orderCloth.getAppUserId())
                .in(AppCouponItem::getId, orderCouponDTOS.stream().map(OrderCouponDTO::getId)
                        .collect(Collectors.toSet())));
    }

    /**
     * @param orderCloth      衣服订单
     * @param orderClothItems 订单衣服明细
     */
    private void buildOrderTotalPrice(OrderCloth orderCloth, List<OrderClothItem> orderClothItems) {
        BigDecimal totalPrice = BigDecimal.ZERO;
        for (OrderClothItem orderClothItem : orderClothItems) {
            totalPrice = totalPrice.add(orderClothItem.getTotalPrice());
        }

        int freeDeliveryNum = 0;//免费的配送次数
        if (totalPrice.doubleValue() >= 100) {
            freeDeliveryNum++;
        }
        if (totalPrice.doubleValue() >= 200) {
            freeDeliveryNum++;
        }
        orderCloth.setOrderClothPrice(totalPrice);

        //上门收衣
        if (orderCloth.getTakeClothWay().equals(TakeOrSendClothWay.DELIVERY.getCode())) {
            if (freeDeliveryNum > 0) {
                freeDeliveryNum--;
            } else {
                totalPrice.add(new BigDecimal(sysConfigService.selectConfigByKey(SysConfigKey.OrderClothDeliveryPrice.getCode())));
            }
        }
        orderCloth.setOrderAmount(totalPrice);
        orderCloth.setPayAmount(orderCloth.getOrderAmount());
    }

    /**
     * 封装订单衣服详情数据
     *
     * @param orderClothItemDTOS
     */
    private List<OrderClothItem> buildOrderClothItemData(List<OrderClothItemDTO> orderClothItemDTOS, OrderCloth orderCloth) {
        Map<Long, ClothSpeed> clothSpeedMap = clothSpeedService.list(new QueryWrapper<ClothSpeed>().lambda()
                        .eq(ClothSpeed::getDelFlag, DeleteStatus.OK.getCode())
                        .eq(ClothSpeed::getStatus, StatusType.OK.getCode())).stream()
                .collect(Collectors.toMap(ClothSpeed::getId, ClothSpeed -> ClothSpeed));
        Map<Long, ClothWashMode> clothWashModeMap = clothWashModeService.list(new QueryWrapper<ClothWashMode>().lambda()
                        .eq(ClothWashMode::getDelFlag, DeleteStatus.OK.getCode())
                        .eq(ClothWashMode::getStatus, StatusType.OK.getCode())).stream()
                .collect(Collectors.toMap(ClothWashMode::getId, ClothWashMode -> ClothWashMode));

        Set<Long> clothFlawIds = new HashSet<>();
        Set<Long> clothColorIds = new HashSet<>();
        Set<Long> clothCraftIds = new HashSet<>();
        orderClothItemDTOS.forEach(clothItemDTO -> {
            clothFlawIds.addAll(clothItemDTO.getOrderClothFlawDTOS().stream()
                    .map(OrderClothFlawDTO::getClothFlawId).collect(Collectors.toSet()));
            clothColorIds.addAll(clothItemDTO.getOrderClothColorDTOS().stream()
                    .map(OrderClothColorDTO::getClothColorId).collect(Collectors.toSet()));
            clothCraftIds.addAll(clothItemDTO.getOrderClothCraftDTOS().stream()
                    .map(OrderClothCraftDTO::getClothCraftId).collect(Collectors.toSet()));
        });
        Map<Long, ClothFlaw> clothFlawMap = clothFlawService.list(new QueryWrapper<ClothFlaw>().lambda()
                        .eq(ClothFlaw::getDelFlag, DeleteStatus.OK.getCode())
                        .eq(ClothFlaw::getStatus, StatusType.OK.getCode())
                        .in(ClothFlaw::getId, clothFlawIds))
                .stream()
                .collect(Collectors.toMap(ClothFlaw::getId, ClothFlaw -> ClothFlaw));
        Map<Long, ClothFlawType> clothFlawTypeMap = clothFlawTypeService.list(new QueryWrapper<ClothFlawType>().lambda()
                        .eq(ClothFlawType::getDelFlag, DeleteStatus.OK.getCode())
                        .eq(ClothFlawType::getStatus, StatusType.OK.getCode())).stream()
                .collect(Collectors.toMap(ClothFlawType::getId, ClothFlawType -> ClothFlawType));
        Map<Long, ClothColor> clothColorMap = clothColorService.list(new QueryWrapper<ClothColor>().lambda()
                        .eq(ClothColor::getDelFlag, DeleteStatus.OK.getCode())
                        .eq(ClothColor::getStatus, StatusType.OK.getCode())
                        .in(ClothColor::getId, clothColorIds))
                .stream()
                .collect(Collectors.toMap(ClothColor::getId, ClothColor -> ClothColor));
        Map<Long, ClothCraft> clothCraftMap = new HashMap<>();
        if (clothCraftIds.size() > 0) {
            clothCraftMap = clothCraftService.list(new QueryWrapper<ClothCraft>().lambda()
                            .eq(ClothCraft::getDelFlag, DeleteStatus.OK.getCode())
                            .eq(ClothCraft::getStatus, StatusType.OK.getCode())
                            .in(ClothCraft::getId, clothCraftIds))
                    .stream().collect(Collectors.toMap(ClothCraft::getId, ClothCraft -> ClothCraft));
        }
        List<OrderClothItem> orderClothItems = new ArrayList<>();
        for (OrderClothItemDTO orderClothItemDTO : orderClothItemDTOS) {
            OrderClothItem orderClothItem = new OrderClothItem();
            orderClothItem.setOrderId(orderCloth.getId());
            orderClothItem.setOrderNo(orderCloth.getOrderNo());
            orderClothItem.setAppUserId(orderCloth.getAppUserId());
            orderClothItem.setOrgId(orderCloth.getOrgId());
            orderClothItem.setSourceType(orderCloth.getSourceType());
            orderClothItem.setFactoryId(orderCloth.getFactoryId());
            orderClothItem.setWashCode(orderNoUtils.getClothWashCode());
            orderClothItem.setClothItemId(orderClothItemDTO.getClothItemId());
            orderClothItem.setClothItemName(orderClothItemDTO.getClothItemName());
            orderClothItem.setClothBrandId(orderClothItemDTO.getClothBrandId());
            orderClothItem.setClothBrandName(orderClothItemDTO.getClothBrandName());
            orderClothItem.setClothSpeedId(orderClothItemDTO.getClothSpeedId());
            orderClothItem.setFlowStatus(ClothOrderFlowStatus.waitingForWash.getCode());
            orderClothItem.setClothSpeedName(clothSpeedMap.get(orderClothItemDTO.getClothSpeedId()).getName());
            orderClothItem.setClothMultiple(clothSpeedMap.get(orderClothItemDTO.getClothSpeedId()).getMultiple());
            orderClothItem.setClothWashDayNum(clothSpeedMap.get(orderClothItemDTO.getClothSpeedId()).getDayNum());
            orderClothItem.setPlanSendClothTime(DateUtils.addDays(new Date()
                    , clothSpeedMap.get(orderClothItemDTO.getClothSpeedId()).getDayNum()));
            if (orderCloth.getPlanSendToUserTime() == null || orderCloth.getPlanSendToUserTime().getTime() < orderClothItem.getPlanSendClothTime().getTime()) {
                orderCloth.setPlanSendToUserTime(orderClothItem.getPlanSendClothTime());
            }
            orderClothItem.setPrice(orderClothItemDTO.getDefaultPrice());
            if (orderClothItemDTO.getClothWashModeId() != null) {
                orderClothItem.setClothWashModeId(orderClothItemDTO.getClothWashModeId());
                orderClothItem.setClothWashModeName(clothWashModeMap.get(orderClothItemDTO.getClothWashModeId()).getName());
            }

            orderClothItem.setPics(orderClothItemDTO.getPics());
            orderClothItem.setIsHedging(orderClothItemDTO.getIsHedging());
            orderClothItem.setHedgingPrice(orderClothItemDTO.getHedgingPrice());
            orderClothItem.setIsCustomPrice(orderClothItemDTO.getIsCustomPrice());
            orderClothItem.setSpecialPrice(buildOrderClothItemSpecialPrice(orderClothItemDTO, clothSpeedMap.get(orderClothItemDTO.getClothSpeedId())));
            orderClothItem.setTotalPrice(orderClothItem.getPrice().add(orderClothItem.getSpecialPrice()));
            if (SysBoolType.YES.getCode().equals(orderClothItem.getIsHedging())) {
                orderClothItem.setTotalPrice(orderClothItem.getTotalPrice().add(orderClothItem.getHedgingPrice()
                        .multiply(new BigDecimal(sysConfigService.selectConfigByKey(SysConfigKey.OrderClothHedgingRate.getCode())))));
            }
            orderClothItem.setPayPrice(orderClothItem.getTotalPrice());
            orderClothItem.setRemark(orderClothItemDTO.getRemark());
            orderClothItem.buildCreateData();
            orderClothItems.add(orderClothItem);
        }
        orderClothItemService.saveBatch(orderClothItems);

        //衣服瑕疵
        List<OrderClothFlaw> orderClothFlaws = new ArrayList<>();
        //衣服颜色
        List<OrderClothColor> orderClothColors = new ArrayList<>();
        //衣服工艺
        List<OrderClothCraft> orderClothCrafts = new ArrayList<>();
        //衣服类型
        List<OrderClothType> orderClothTypes = new ArrayList<>();
        //衣服附件
        List<OrderClothAdjunct> orderClothAdjuncts = new ArrayList<>();
        for (int i = 0; i < orderClothItems.size(); i++) {
            for (OrderClothFlawDTO orderClothFlawDTO : orderClothItemDTOS.get(i).getOrderClothFlawDTOS()) {
                OrderClothFlaw orderClothFlaw = new OrderClothFlaw();
                orderClothFlaw.setClothFlawId(orderClothFlawDTO.getClothFlawId());
                orderClothFlaw.setClothFlawName(clothFlawMap.get(orderClothFlawDTO.getClothFlawId()).getName());
                orderClothFlaw.setClothFlawTypeId(clothFlawMap.get(orderClothFlawDTO.getClothFlawId()).getFlawTypeId());
                orderClothFlaw.setClothFlawTypeName(clothFlawTypeMap.get(clothFlawMap
                        .get(orderClothFlawDTO.getClothFlawId()).getFlawTypeId()).getName());
                orderClothFlaw.buildCreateData();
                orderClothFlaw.setOrderId(orderCloth.getId());
                orderClothFlaw.setOrderClothId(orderClothItems.get(i).getId());
                orderClothFlaws.add(orderClothFlaw);
            }

            for (OrderClothColorDTO orderClothColorDTO : orderClothItemDTOS.get(i).getOrderClothColorDTOS()) {
                OrderClothColor orderClothColor = new OrderClothColor();
                orderClothColor.setClothColorId(orderClothColorDTO.getClothColorId());
                orderClothColor.setClothColorName(clothColorMap.get(orderClothColorDTO.getClothColorId()).getName());
                orderClothColor.setClothColorCode(clothColorMap.get(orderClothColorDTO.getClothColorId()).getCode());
                orderClothColor.setClothColorType(clothColorMap.get(orderClothColorDTO.getClothColorId()).getColorType());
                orderClothColor.setImgUrl(clothColorMap.get(orderClothColorDTO.getClothColorId()).getImgUrl());
                orderClothColor.setOrderId(orderCloth.getId());
                orderClothColor.setOrderClothId(orderClothItems.get(i).getId());
                orderClothColor.buildCreateData();
                orderClothColors.add(orderClothColor);
            }

            for (OrderClothCraftDTO orderClothCraftDTO : orderClothItemDTOS.get(i).getOrderClothCraftDTOS()) {
                OrderClothCraft orderClothCraft = new OrderClothCraft();
                orderClothCraft.setClothCraftId(orderClothCraftDTO.getClothCraftId());
                orderClothCraft.setClothCraftName(clothCraftMap.get(orderClothCraftDTO.getClothCraftId()).getCraftName());
                orderClothCraft.setPrice(orderClothCraftDTO.getPrice());
                orderClothCraft.setOrderId(orderCloth.getId());
                orderClothCraft.setOrderClothId(orderClothItems.get(i).getId());
                orderClothCraft.buildCreateData();
                orderClothCrafts.add(orderClothCraft);
            }

            for (OrderClothTypeDTO orderClothTypeDTO : orderClothItemDTOS.get(i).getOrderClothTypeDTOS()) {
                OrderClothType orderClothType = new OrderClothType();
                BeanUtils.copyProperties(orderClothTypeDTO, orderClothType);
                orderClothType.setOrderId(orderCloth.getId());
                orderClothType.setOrderClothId(orderClothItems.get(i).getId());
                orderClothType.buildCreateData();
                orderClothTypes.add(orderClothType);
            }

            for (OrderClothAdjunctDTO orderClothAdjunctDTO : orderClothItemDTOS.get(i).getOrderClothAdjunctDTOS()) {
                OrderClothAdjunct orderClothAdjunct = new OrderClothAdjunct();
                BeanUtils.copyProperties(orderClothAdjunctDTO, orderClothAdjunct);
                orderClothAdjunct.setAdjunctNo(orderNoUtils.getClothWashAdjustCode());
                orderClothAdjunct.setOrderId(orderCloth.getId());
                orderClothAdjunct.setOrderClothId(orderClothItems.get(i).getId());
                orderClothAdjunct.buildCreateData();
                orderClothAdjuncts.add(orderClothAdjunct);
            }
        }
        orderClothFlawService.saveBatch(orderClothFlaws);
        orderClothColorService.saveBatch(orderClothColors);
        orderClothCraftService.saveBatch(orderClothCrafts);
        orderClothTypeService.saveBatch(orderClothTypes);
        orderClothAdjunctService.saveBatch(orderClothAdjuncts);

        return orderClothItems;
    }

    private BigDecimal buildOrderClothItemSpecialPrice(OrderClothItemDTO orderClothItemDTO, ClothSpeed clothSpeed) {
        BigDecimal specialPrice = BigDecimal.ZERO;
        if (SysBoolType.YES.getCode().equals(orderClothItemDTO.getIsHedging())) {
            specialPrice = specialPrice.add(orderClothItemDTO.getHedgingPrice().multiply(new BigDecimal(0.01)));
        }
        for (OrderClothCraftDTO orderClothCraftDTO : orderClothItemDTO.getOrderClothCraftDTOS()) {
            specialPrice = specialPrice.add(orderClothCraftDTO.getPrice());
        }
        if (clothSpeed.getMultiple().subtract(BigDecimal.ONE).doubleValue() > 0) {
            specialPrice = specialPrice.add(orderClothItemDTO.getDefaultPrice().multiply(clothSpeed.getMultiple().subtract(BigDecimal.ONE)));
        }
        return specialPrice;
    }

    /**
     * 配置订单基本数据
     *
     * @param orderCloth
     * @param orderClothDTO
     */
    private void buildClothOrderInfo(OrderCloth orderCloth, OrderClothDTO orderClothDTO) {
        if (StringUtils.isEmpty(orderCloth.getOrderNo())) {
            orderCloth.setOrderNo(orderNoUtils.getClothOrderNo());
        }
        //如果为空则默认普洗
        if (orderClothDTO.getSpeedId() == null) {
            orderCloth.setClothSpeedId(ClothSpeedType.NORMAL_WASH.getId());
        }
        orderCloth.setPayType(orderClothDTO.getPayType());
        orderCloth.setClothSpeedId(orderClothDTO.getSpeedId());
        if (orderClothDTO.getSpeedId() == null) {
            orderCloth.setClothSpeedId(ClothSpeedType.NORMAL_WASH.getId());
        }
        orderCloth.setOrderStatus(ClothOrderStatusType.APPOINTMENT.getCode());
        orderCloth.setCashDeductAmount(orderClothDTO.getCashDeductAmount() == null ? BigDecimal.ZERO : orderClothDTO.getCashDeductAmount());
        orderCloth.setIsSpecial(StringUtils.isEmpty(orderClothDTO.getIsSpecial()) ? SysBoolType.NO.getCode() : orderClothDTO.getIsSpecial());
        orderCloth.setSetPriceTime(DateUtils.getNowDate());
        orderCloth.setRemark(orderClothDTO.getRemark());
        orderCloth.setOrderClothCount(orderClothDTO.getOrderClothItemDTOS().size());
        if (!SysBoolType.YES.getCode().equals(orderClothDTO.getIsAppointment())) {
            orderCloth.setOrderSource(OrderSourceType.OFFLINE.getCode());
        }
        orderCloth.setPayTimeType(orderClothDTO.getPayTimeType());
        orderCloth.setPayStatus(PayStatus.WAITING_TO_PAY.getCode());
    }

    /**
     * 配置订单洗衣速度
     *
     * @param orderCloth
     */
    private void buildClothSpeedIntoOrder(OrderCloth orderCloth) {
        ClothSpeed clothSpeed = clothSpeedService.getOne(new QueryWrapper<ClothSpeed>().lambda()
                .eq(ClothSpeed::getId, orderCloth.getClothSpeedId())
                .eq(ClothSpeed::getDelFlag, DeleteStatus.OK.getCode())
                .eq(ClothSpeed::getStatus, StatusType.OK.getCode()), false);
        orderCloth.setClothSpeedName(clothSpeed.getName());
    }

    /**
     * 配置组织信息
     *
     * @param orderCloth
     */
    private void buildOrgIntoOrder(OrderCloth orderCloth) {
        orderCloth.setSourceType(SecurityUtils.getLoginUser().getSourceType());
        orderCloth.setOrgId(SecurityUtils.getLoginUser().getOrgId());
        if (SourceType.STORE.getCode().equals(orderCloth.getSourceType())) {
            SysStore sysStore = sysStoreService.getOne(new QueryWrapper<SysStore>().lambda()
                    .eq(SysStore::getId, orderCloth.getOrgId())
                    .eq(SysStore::getStatus, StatusType.OK.getCode())
                    .eq(SysStore::getDelFlag, DeleteStatus.OK.getCode()), false);
            if (sysStore == null) {
                throw new ServiceException("未查询到门店");
            }
            orderCloth.setFactoryId(sysStore.getFactoryId());
        } else {
            orderCloth.setFactoryId(SecurityUtils.getLoginUser().getOrgId());
        }
    }

    /**
     * 配置用户信息
     *
     * @param orderCloth
     */
    private void buildAppUserInfoOrder(OrderCloth orderCloth) {
        AppUser appUser = appUserService.getOne(new QueryWrapper<AppUser>().lambda().eq(AppUser::getId, orderCloth.getAppUserId()), false);
        orderCloth.setContactName(appUser.getRealName());
        orderCloth.setContactPhone(appUser.getPhoneNumber());
    }
    //</editor-folder>

    /**
     * 查询洗衣订单
     *
     * @param id 洗衣订单主键
     * @return 洗衣订单
     */
    @Override
    public OrderCloth selectOrderClothById(Long id) {
        return baseMapper.selectOrderClothById(id);
    }

    /**
     * 查询洗衣订单列表
     *
     * @param orderCloth 洗衣订单
     * @return 洗衣订单
     */
    @Override
    public List<OrderCloth> selectOrderClothList(OrderCloth orderCloth) {
        return baseMapper.selectOrderClothList(orderCloth);
    }

    /**
     * 新增洗衣订单
     *
     * @param orderCloth 洗衣订单
     * @return 结果
     */
    @Override
    public int insertOrderCloth(OrderCloth orderCloth) {
        orderCloth.setCreateTime(DateUtils.getNowDate());
        return baseMapper.insert(orderCloth);
    }

    /**
     * 修改洗衣订单
     *
     * @param orderCloth 洗衣订单
     * @return 结果
     */
    @Override
    public int updateOrderCloth(OrderCloth orderCloth) {
        orderCloth.setUpdateTime(DateUtils.getNowDate());
        return baseMapper.updateById(orderCloth);
    }

    /**
     * 批量删除洗衣订单
     *
     * @param ids 需要删除的洗衣订单主键
     * @return 结果
     */
    @Override
    public int deleteOrderClothByIds(Long[] ids) {
        return baseMapper.deleteOrderClothByIds(ids);
    }

    /**
     * 删除洗衣订单信息
     *
     * @param id 洗衣订单主键
     * @return 结果
     */
    @Override
    public int deleteOrderClothById(Long id) {
        return baseMapper.deleteOrderClothById(id);
    }

    /**
     * 查询待上挂洗衣订单衣服明细列表
     */
    @Override
    public List<ClothHangerOrderRelationVO> getNoHangerOrderClothList() {
        return null;
    }

    /**
     * 查询上挂洗衣订单衣服明细
     */
    @Override
    public ClothHangerOrderRelationVO getOrderClothInfoByWashCode(String washCode) {
        return null;
    }

    @Override
    public List<OrderClothRecordVO> getDeliveryOrderRecordList(AppDeliveryManListQueryDTO appDeliveryManListQueryDTO) {
        return baseMapper.getDeliveryOrderRecordList(appDeliveryManListQueryDTO);
    }

    @Override
    public List<OrderClothAppointmentVO> getAppointmentClothOrderList(OrderAppointmentDTO2 orderAppointmentDTO2) {
        if (!SourceType.MANAGER.getCode().equals(SecurityUtils.getLoginUser().getSourceType())) {
            orderAppointmentDTO2.setOrgId(SecurityUtils.getLoginUser().getOrgId());
        }
        /** 预约状态（1=待接单，2=待上门，3=已取物，4=待配送，5=配送中，9=已完成，100=已取消） */
        if (ClothAppointmentStatus.APPOINTMENT.getCode().equals(orderAppointmentDTO2.getAppointmentStatus()) ||
                ClothAppointmentStatus.WAITING_TO_DOOR.getCode().equals(orderAppointmentDTO2.getAppointmentStatus()) ||
                ClothAppointmentStatus.HAS_TAKING.getCode().equals(orderAppointmentDTO2.getAppointmentStatus())
        ) {
            orderAppointmentDTO2.setTakeClothWay(TakeOrSendClothWay.DELIVERY.getCode());
        }

        if (ClothAppointmentStatus.WAITING_TO_SEND.getCode().equals(orderAppointmentDTO2.getAppointmentStatus()) ||
                ClothAppointmentStatus.SENDING.getCode().equals(orderAppointmentDTO2.getAppointmentStatus()) ||
                ClothAppointmentStatus.FINISH.getCode().equals(orderAppointmentDTO2.getAppointmentStatus())
        ) {
            orderAppointmentDTO2.setSendClothWay(TakeOrSendClothWay.DELIVERY.getCode());
        }

        List<OrderClothAppointmentVO> orderClothAppointmentVOList = baseMapper.getAppointmentClothOrderList(orderAppointmentDTO2);
        for (OrderClothAppointmentVO orderClothAppointmentVO : orderClothAppointmentVOList) {
            orderClothAppointmentVO.setOrderClothAddress(orderClothAddressService.getByorderSn(orderClothAppointmentVO.getOrderNo()));
        }
        return orderClothAppointmentVOList;
    }

    /**
     * 财务统计-经营日报-衣服订单
     *
     * @param orderFinancialDayQueryDTO
     * @return
     */
    @Override
    public OrderFinancialQueryVO listFinancialStatisticsByClothOrderDay(OrderFinancialDayQueryDTO orderFinancialDayQueryDTO) {
        OrderFinancialQueryVO orderFinancialQueryVO = new OrderFinancialQueryVO();
        OrderFinancialDayQueryDTO today = new OrderFinancialDayQueryDTO();
        today.setBeginCreateTime(DateUtils.getDate());
        today.setEndCreateTime(DateUtils.getDate());
        // 统计今日洗衣数据
        this.handleTodayDataByClothOrder(orderFinancialQueryVO, today);
        // 统计今日商品数据
        this.handleTodayDataByGoodsOrder(orderFinancialQueryVO, today);
        // 统计今日充值数据
        this.handleTodayDataByRechargeOrder(orderFinancialQueryVO, today);
        // 查询列表数据
        this.handleListDataByDay(orderFinancialQueryVO, orderFinancialDayQueryDTO);
        return orderFinancialQueryVO;
    }

    private void handleTodayDataByClothOrder(OrderFinancialQueryVO orderFinancialQueryVO, OrderFinancialDayQueryDTO today) {
        // 查询今日洗衣订单
        List<OrderClothFinancialVO> todayData = baseMapper.listFinancialStatisticsByClothOrderToday(today,
                SecurityUtils.getLoginUser().getOrgId(),
                SecurityUtils.getLoginUser().getSourceType());
        this.buildClothData(orderFinancialQueryVO, todayData);
    }

    private void buildClothData(OrderFinancialQueryVO orderFinancialQueryVO, List<OrderClothFinancialVO> data) {
        if (CollUtil.isEmpty(data)) {
            orderFinancialQueryVO.setTodayOrderAmount(BigDecimal.ZERO);
            orderFinancialQueryVO.setTodayOnlinePayAmount(BigDecimal.ZERO);
            orderFinancialQueryVO.setTodayCardAmount(BigDecimal.ZERO);
            orderFinancialQueryVO.setTodayCashAmount(BigDecimal.ZERO);
            orderFinancialQueryVO.setTodayCouponAmount(BigDecimal.ZERO);
            orderFinancialQueryVO.setTodayOrderClothCount(0);
            return;
        }
        // 今日订单金额
        orderFinancialQueryVO.setTodayOrderAmount(data.stream()
                .map(OrderClothFinancialVO::getOrderAmount)
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add));
        // 今日券消费
        orderFinancialQueryVO.setTodayCouponAmount(data.stream()
                .map(OrderClothFinancialVO::getCouponAmount)
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add));
        // 今日现金消费
        orderFinancialQueryVO.setTodayCashAmount(data.stream()
                .filter(vo -> PayType.CASH.getCode().equals(vo.getPayType()))
                .map(OrderClothFinancialVO::getPayAmount)
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add));
        // 今日会员卡消费
        orderFinancialQueryVO.setTodayCardAmount(data.stream()
                .filter(vo -> PayType.BALANCE.getCode().equals(vo.getPayType()))
                .map(OrderClothFinancialVO::getPayAmount)
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add));
        // 今日支付宝/微信消费
        orderFinancialQueryVO.setTodayOnlinePayAmount(data.stream()
                .filter(vo -> PayType.WECHAT.getCode().equals(vo.getPayType()) || PayType.ALIPAY.getCode().equals(vo.getPayType()))
                .map(OrderClothFinancialVO::getPayAmount)
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add));
        // 今日收衣件数
        orderFinancialQueryVO.setTodayOrderClothCount(data.stream()
                .map(OrderClothFinancialVO::getOrderClothCount)
                .filter(Objects::nonNull)
                .reduce(0, Integer::sum));
    }

    private void handleTodayDataByRechargeOrder(OrderFinancialQueryVO orderFinancialQueryVO, OrderFinancialDayQueryDTO today) {
        orderRechargeService.listFinancialStatisticsByRechargeOrderToday(orderFinancialQueryVO, today);
    }

    private void handleTodayDataByGoodsOrder(OrderFinancialQueryVO orderFinancialQueryVO, OrderFinancialDayQueryDTO today) {
        // 查询今日商品订单
        orderGoodsService.listFinancialStatisticsByGoodsOrderToday(orderFinancialQueryVO, today);
    }

    private void handleListDataByDay(OrderFinancialQueryVO orderFinancialQueryVO, OrderFinancialDayQueryDTO orderFinancialDayQueryDTO) {
        // 查询洗衣列表数据
        List<OrderClothFinancialVO> clothFinancialVOS = baseMapper.listFinancialStatisticsByClothOrderDay(orderFinancialDayQueryDTO,
                SecurityUtils.getLoginUser().getOrgId(),
                SecurityUtils.getLoginUser().getSourceType());
        orderFinancialQueryVO.setOrderClothFinancialVOList(clothFinancialVOS);
        orderFinancialQueryVO.setClothTotal(baseMapper.countFinancialStatisticsByClothOrderDay(orderFinancialDayQueryDTO,
                SecurityUtils.getLoginUser().getOrgId(),
                SecurityUtils.getLoginUser().getSourceType()));

        // 查询商品列表数据
        List<OrderGoodsFinancialVO> goodsFinancialVOS = orderGoodsService.listFinancialStatisticsByGoodsOrderDay(orderFinancialDayQueryDTO);
        orderFinancialQueryVO.setGoodsOrderFinancialVOList(goodsFinancialVOS);
        orderFinancialQueryVO.setGoodsTotal(orderGoodsService.countFinancialStatisticsByGoodsOrderDay(orderFinancialDayQueryDTO));
    }

    /**
     * 财务统计-经营月报-衣服订单
     *
     * @param orderFinancialMonthQueryDTO
     * @return
     */
    @Override
    public OrderFinancialQueryVO listFinancialStatisticsByClothOrderMonth(OrderFinancialMonthQueryDTO orderFinancialMonthQueryDTO) {
        OrderFinancialQueryVO orderFinancialQueryVO = new OrderFinancialQueryVO();
        // 统计本月洗衣数据
        this.handleMtdDataByClothOrder(orderFinancialQueryVO);
        // 统计本月商品数据
        this.handleMtdDataByGoodsOrder(orderFinancialQueryVO);
        // 统计本月充值数据
        this.handleMtdDataByRechargeOrder(orderFinancialQueryVO);
        // 查询列表数据
        this.handleListDataByMonth(orderFinancialQueryVO, orderFinancialMonthQueryDTO);

        return orderFinancialQueryVO;
    }

    /**
     * 财务统计-工厂洗衣明细统计-衣服订单
     */
    @Override
    public OrderClothFactoryClothQueryVO listPayFinancialStatisticsByClothOrderFactory(OrderFinancialFactoryClothQueryDTO orderFinancialFactoryClothQueryDTO) {
        OrderClothFactoryClothQueryVO orderClothFactoryClothQueryVO = new OrderClothFactoryClothQueryVO();
        Long orgId = SecurityUtils.getLoginUser().getOrgId();
        String sourceType = SecurityUtils.getLoginUser().getSourceType();
        // 设置查询条件
        LambdaQueryWrapper<OrderClothItem> queryWrapper = new QueryWrapper<OrderClothItem>().lambda()
                .eq(OrderClothItem::getOrgId, orgId)
                .eq(OrderClothItem::getSourceType, sourceType)
                .ne(OrderClothItem::getFlowStatus, ClothOrderFlowStatus.refund.getCode())
                .orderByDesc(BaseEntity::getCreateTime);
        if (orderFinancialFactoryClothQueryDTO.getBeginCreateTime() != null && orderFinancialFactoryClothQueryDTO.getEndCreateTime() != null) {
            queryWrapper.ge(BaseEntity::getCreateTime, orderFinancialFactoryClothQueryDTO.getBeginCreateTime());
            queryWrapper.lt(BaseEntity::getCreateTime, DateUtils.addDays(orderFinancialFactoryClothQueryDTO.getEndCreateTime(), 1));
        }
        if (orderFinancialFactoryClothQueryDTO.getFactoryId() != null) {
            queryWrapper.eq(OrderClothItem::getFactoryId, orderFinancialFactoryClothQueryDTO.getFactoryId());
        }
        queryWrapper.orderByDesc(BaseEntity::getCreateTime);
        // 设置统计明细 全量数据，不用加limit
        List<OrderClothItem> orderClothItemAll = orderClothItemService.list(queryWrapper);
        if (CollUtil.isNotEmpty(orderClothItemAll)) {
            // 设置 总计消费金额
            orderClothFactoryClothQueryVO.setTotalPayMoney(orderClothItemAll.stream()
                    .map(OrderClothItem::getTotalPrice)
                    .filter(Objects::nonNull)
                    .reduce(BigDecimal.ZERO, BigDecimal::add));
            // 设置 总计工厂结算金额
            orderClothFactoryClothQueryVO.setTotalStatementMoney(
                    orderClothItemAll.stream().map(vo -> vo.getTotalPrice().multiply(vo.getFactorySettlementRate()))
                            .reduce(BigDecimal.ZERO, BigDecimal::add)
            );
            // 设置 总件数
            orderClothFactoryClothQueryVO.setTotalOrderClothCount(orderClothItemAll.size());
            orderClothFactoryClothQueryVO.setTotal(orderClothItemAll.size());
        }
        // 设置列表分页
        queryWrapper.last("limit " + orderFinancialFactoryClothQueryDTO.getStartRow() + "," + orderFinancialFactoryClothQueryDTO.getPageSize());
        List<OrderClothItem> orderClothItems = orderClothItemService.list(queryWrapper);
        if (CollUtil.isEmpty(orderClothItems)) {
            return orderClothFactoryClothQueryVO;
        }
        List<OrderClothFactoryClothItemVO> orderClothFactoryClothItemVOList = new ArrayList<>();
        for (OrderClothItem orderClothItem : orderClothItems) {
            // 设置门店的工厂费率
            BigDecimal rate = orderClothItem.getFactorySettlementRate();
            OrderClothFactoryClothItemVO vo = new OrderClothFactoryClothItemVO();
            BeanUtils.copyProperties(orderClothItem, vo);
            if (vo.getTotalPrice() == null) {
                vo.setTotalStatementPrice(BigDecimal.ZERO);
            } else {
                vo.setTotalStatementPrice(vo.getTotalPrice().multiply(rate));
            }
            vo.setStatementRate(rate);
            orderClothFactoryClothItemVOList.add(vo);
        }
        orderClothFactoryClothQueryVO.setOrderClothFactoryClothItemVOList(orderClothFactoryClothItemVOList);
        return orderClothFactoryClothQueryVO;
    }

    private void handleMtdDataByClothOrder(OrderFinancialQueryVO orderFinancialQueryVO) {
        List<OrderClothFinancialVO> MtdData = baseMapper.listFinancialStatisticsByClothOrderMTD(SecurityUtils.getLoginUser().getOrgId(), SecurityUtils.getLoginUser().getSourceType());
        this.buildClothData(orderFinancialQueryVO, MtdData);
    }

    private void handleMtdDataByGoodsOrder(OrderFinancialQueryVO orderFinancialQueryVO) {
        // 查询今日商品订单
        orderGoodsService.listFinancialStatisticsByGoodsOrderMTD(orderFinancialQueryVO);
    }

    private void handleMtdDataByRechargeOrder(OrderFinancialQueryVO orderFinancialQueryVO) {
        orderRechargeService.listFinancialStatisticsByRechargeOrderMTD(orderFinancialQueryVO);
    }

    private void handleListDataByMonth(OrderFinancialQueryVO orderFinancialQueryVO, OrderFinancialMonthQueryDTO orderFinancialMonthQueryDTO) {
        // 查询洗衣列表数据
        List<OrderClothFinancialVO> clothFinancialVOS = baseMapper.listFinancialStatisticsByClothOrderMonth(orderFinancialMonthQueryDTO,
                SecurityUtils.getLoginUser().getOrgId(),
                SecurityUtils.getLoginUser().getSourceType());
        orderFinancialQueryVO.setOrderClothFinancialVOList(clothFinancialVOS);
        orderFinancialQueryVO.setClothTotal(baseMapper.countFinancialStatisticsByClothOrderMonth(orderFinancialMonthQueryDTO,
                SecurityUtils.getLoginUser().getOrgId(),
                SecurityUtils.getLoginUser().getSourceType()));

        // 查询商品列表数据
        List<OrderGoodsFinancialVO> goodsFinancialVOS = orderGoodsService.listFinancialStatisticsByGoodsOrderMonth(orderFinancialMonthQueryDTO);
        orderFinancialQueryVO.setGoodsOrderFinancialVOList(goodsFinancialVOS);
        orderFinancialQueryVO.setGoodsTotal(orderGoodsService.countFinancialStatisticsByGoodsOrderMonth(orderFinancialMonthQueryDTO));
    }

}
