package com.yiqi.admin.controller.order;

import cn.hutool.core.collection.CollUtil;
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.app.domain.*;
import com.yiqi.app.domain.vo.AppUserInfoVO;
import com.yiqi.app.service.*;
import com.yiqi.common.exception.ServiceException;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yiqi.common.annotation.Log;
import com.yiqi.common.constant.UrlConstants;
import com.yiqi.common.core.controller.BaseController;
import com.yiqi.common.core.domain.AjaxResult;
import com.yiqi.common.core.domain.BaseEntity;
import com.yiqi.common.core.domain.R;
import com.yiqi.common.core.page.TableDataInfo;
import com.yiqi.common.enums.*;
import com.yiqi.common.utils.*;
import com.yiqi.common.utils.poi.ExcelUtil;
import com.yiqi.core.domain.dto.wx.IntracityExpressAddOrderRequest;
import com.yiqi.core.domain.vo.ClothHangerOrderRelationVO;
import com.yiqi.core.domain.vo.wx.IntracityExpressCreateOrderResult;
import com.yiqi.core.service.ISysStoreIntracityExpressService;
import com.yiqi.order.domain.*;
import com.yiqi.order.domain.dto.*;
import com.yiqi.order.domain.vo.*;
import com.yiqi.order.service.*;
import com.yiqi.recharge.domain.RechargePasswordCard;
import com.yiqi.recharge.service.IRechargePasswordCardService;
import com.yiqi.system.domain.ManageFactory;
import com.yiqi.system.domain.SysOrg;
import com.yiqi.system.domain.SysSettlementRate;
import com.yiqi.system.domain.SysStore;
import com.yiqi.system.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 洗衣订单Controller
 *
 * @author ruoyi
 * @date 2023-10-06
 */
@Api(tags = "管理后台 - 洗衣订单")
@RestController
@RequestMapping(UrlConstants.managerApi + "/order/cloth")
public class OrderClothController extends BaseController {
    @Autowired
    private IOrderClothService orderClothService;
    @Autowired
    private ISysConfigService configService;
    @Autowired
    private IAppUserService appUserService;
    @Autowired
    private IOrderClothAddressService orderClothAddressService;
    @Autowired
    private IOrderClothItemService orderClothItemService;
    @Autowired
    private ISysSettlementRateService sysSettlementRateService;
    @Autowired
    private IOrderClothItemFlowRecordService orderClothItemFlowRecordService;
    @Autowired
    private IAppDeliveryManService appDeliveryManService;
    @Autowired
    private IAppDeliveryRelationService appDeliveryRelationService;
    @Autowired
    private IRechargePasswordCardService rechargePasswordCardService;
    @Autowired
    private IPayService payService;
    @Autowired
    private ISysConfigService sysConfigService;
    @Autowired
    private ISysOrgService sysOrgService;
    @Autowired
    private IOrderDeliveryService orderDeliveryService;
    @Autowired
    private IAppUserBillMstrService appUserBillMstrService;
    @Autowired
    private OrderNoUtils orderNoUtils;
    @Autowired
    private ISysStoreIntracityExpressService sysStoreIntracityExpressService;
    @Autowired
    private ISysStoreService sysStoreService;
    @Autowired
    private IThirdDeliveryService thirdDeliveryService;
    @Autowired
    private IManageFactoryService manageFactoryService;
    @Autowired
    private IAppUserAddressService appUserAddressService;

    @PreAuthorize("@ss.hasPermi('order:cloth:selectOrg')")
    @Transactional(rollbackFor = Exception.class)
    @ApiOperation("云洗订单分配工厂")
    @PostMapping(value = "/selectOrg")
    @Log(title = "云洗分配工厂", businessType = BusinessType.UPDATE)
    public R<OrderCloth> selectOrg(@RequestBody @Valid OrderClothSelectOrgDTO orderClothSelectOrgDTO) throws Exception {
        OrderCloth orderCloth = orderClothService.getOne(new QueryWrapper<OrderCloth>().lambda()
                .eq(OrderCloth::getOrderNo, orderClothSelectOrgDTO.getOrderNo()));
        if (!ClothOrderType.online.getCode().equals(orderCloth.getOrderType())
                && !ClothOrderType.thirdPart.getCode().equals(orderCloth.getOrderType())) {
            throw new ServiceException("该订单不是云洗订单，无法分配工厂");
        }
        orderCloth.setOrgId(orderClothSelectOrgDTO.getOrgId());
        orderCloth.setSourceType(orderClothSelectOrgDTO.getSourceType());
        orderCloth.setFactoryId(orderClothSelectOrgDTO.getOrgId());
        orderCloth.buildUpdateData();
        orderClothService.updateById(orderCloth);
        return R.ok();
    }

    @ApiOperation("根据订单编号获取订单状态")
    @GetMapping(value = "/getOrderStatusByOrderNo")
    public R<String> getOrderStatusByOrderNo(@RequestParam @ApiParam("订单编号") String orderNo) throws Exception {
        LambdaQueryWrapper<OrderCloth> queryWrapper = new QueryWrapper<OrderCloth>().lambda().eq(OrderCloth::getOrderNo, orderNo);
        if (SourceType.FACTORY.getCode().equals(SecurityUtils.getLoginUser().getSourceType())) {
            queryWrapper.eq(OrderCloth::getFactoryId, SecurityUtils.getLoginUser().getOrgId());
        }
        if (SourceType.STORE.getCode().equals(SecurityUtils.getLoginUser().getSourceType())) {
            queryWrapper.eq(OrderCloth::getOrgId, SecurityUtils.getLoginUser().getOrgId());
        }
        OrderCloth orderCloth = orderClothService.getOne(queryWrapper);
        if (orderCloth == null) {
            throw new ServiceException("为查询到订单");
        }

        return R.ok(orderCloth.getOrderStatus());
    }

    @Transactional(rollbackFor = Exception.class)
    @ApiOperation("衣服确认送达")
    @GetMapping(value = "/confirmSend")
    public R confirmSend(@RequestParam Long orderId) throws Exception {
        OrderCloth orderCloth = orderClothService.getOne(new QueryWrapper<OrderCloth>().lambda()
                .eq(OrderCloth::getId, orderId)
                .eq(OrderCloth::getOrgId, SecurityUtils.getLoginUser().getOrgId())
                .eq(OrderCloth::getSourceType, SecurityUtils.getLoginUser().getSourceType()));
        if (orderCloth == null) {
            throw new ServiceException("未查询到订单信息");
        }
        if (!ClothOrderStatusType.SENDING.getCode().equals(orderCloth.getOrderStatus())) {
            throw new ServiceException("当前订单状态为"
                    + EnumUtils.getEnumByType(orderCloth.getOrderStatus(), ClothOrderStatusType.class)
                    + "，无法进行确认送达操作");
        }
        orderCloth.setOrderStatus(ClothOrderStatusType.FINISH.getCode());
        orderClothService.updateById(orderCloth);
        orderClothItemService.update(new UpdateWrapper<OrderClothItem>().lambda()
                .set(OrderClothItem::getFlowStatus, ClothOrderFlowStatus.hasTake.getCode())
                .set(OrderClothItem::getTakeClothTime, DateUtils.getNowDate())
                .eq(OrderClothItem::getOrderId, orderId));
        List<OrderClothItem> orderClothItems = orderClothItemService.list(new QueryWrapper<OrderClothItem>()
                .lambda().eq(OrderClothItem::getOrderId, orderId));
        orderClothItemFlowRecordService.addRecordBatch(orderClothItems, ClothOrderFlowStatus.hasTake.getCode());
        return R.ok();
    }

    @Transactional(rollbackFor = Exception.class)
    @ApiOperation("第三方快递配送")
    @PostMapping(value = "/setThirdDelivery")
    public R setThirdDelivery(@RequestBody @Valid OrderClothThirdDeliverySendDTO orderClothThirdDeliverySendDTO) throws Exception {
        return R.ok("三方配送已弃用");
    }

    private DeliveryOrgInfoDTO getDeliveryInfoByOrg(Long orgId, String sourceType) {
        DeliveryOrgInfoDTO deliveryOrgInfoDTO = new DeliveryOrgInfoDTO();
        if (SourceType.STORE.getCode().equals(sourceType)) {
            SysStore store = sysStoreService.getOne(new QueryWrapper<SysStore>().lambda().eq(SysStore::getId, orgId));
            deliveryOrgInfoDTO = DeliveryOrgInfoDTO.buildDeliveryOrgInfoDTOByStore(store);
        }
        if (SourceType.FACTORY.getCode().equals(sourceType)) {
            ManageFactory factory = manageFactoryService.getOne(new QueryWrapper<ManageFactory>().lambda().eq(ManageFactory::getId, orgId));
            deliveryOrgInfoDTO = DeliveryOrgInfoDTO.buildDeliveryOrgInfoDTOByFactory(factory);
        }
        if (SourceType.MANAGER.getCode().equals(sourceType)) {
            deliveryOrgInfoDTO = DeliveryOrgInfoDTO.buildDeliveryOrgInfoDTOByHq();
        }
        return deliveryOrgInfoDTO;
    }

    @Transactional(rollbackFor = Exception.class)
    @ApiOperation("三方配送派单")
    @GetMapping(value = "/setIntracityExpress")
    public R setThirdExpress(@RequestParam String orderNo) throws Exception {
        OrderCloth orderCloth = orderClothService.getOne(new QueryWrapper<OrderCloth>().lambda()
                .eq(OrderCloth::getOrderNo, orderNo)
                .eq(OrderCloth::getOrgId, SecurityUtils.getLoginUser().getOrgId())
                .eq(OrderCloth::getSourceType, SecurityUtils.getLoginUser().getSourceType()));
        if (orderCloth == null) {
            throw new ServiceException("未查询到订单信息");
        }
        SysStore sysStore = sysStoreService.getOne(new QueryWrapper<SysStore>().lambda().eq(SysStore::getId, orderCloth.getOrgId()));
        if (sysStore == null) {
            throw new ServiceException("未查询到门店");
        }

        switch (EnumUtils.getEnumByType(orderCloth.getOrderStatus(), ClothOrderStatusType.class)) {
            case APPOINTMENT: {
                // 预约待取，进行取件发单
                OrderDelivery orderDelivery = orderDeliveryService.selectOrderDeliveryByOrderId(orderCloth.getOrderNo(), ClothOrderDeliveryType.collectCloth.getCode());
                orderDelivery.setDeliveryWay(ClothOrderDeliveryWay.intracityExpress.getCode());
                orderDelivery.setDeliveryStatus(OrderDeliveryStatusEnum.CREATE_ORDER_SUCCESS.getCode());
                BigDecimal fee = new BigDecimal(sysConfigService.selectConfigByKey(SysConfigKey.OrderClothDeliveryPrice.getCode()));
                orderDelivery.setFee(fee);
                orderDelivery.buildUpdateData();
                orderDeliveryService.updateById(orderDelivery);
                //更新订单
                orderCloth.buildUpdateData();
                orderCloth.setTakeClothTime(DateUtils.getNowDate());
                //  分配完配送员后，直接待定价，没有中间的流程
                orderCloth.setOrderStatus(ClothOrderStatusType.HAS_TAKING.getCode());
                orderClothService.updateById(orderCloth);
                return R.ok();
            }
            case WAITING_FOR_HANG: {
                // 待送衣-送衣发单
                // 1.获取收衣配送单
                OrderDelivery takeDelivery = orderDeliveryService.selectOrderDeliveryByOrderId(orderCloth.getOrderNo(), ClothOrderDeliveryType.collectCloth.getCode());
                OrderDelivery orderDelivery = new OrderDelivery(takeDelivery);
                orderDelivery.setDeliverySn(orderNoUtils.getDeliveryOrderNo());
                orderDelivery.setOrderSn(orderCloth.getOrderNo());
                orderDelivery.setClothOrderType(ClothOrderDeliveryType.takeCloth.getCode());
                orderDelivery.setCreateTime(DateUtils.getNowDate());
                orderDelivery.setDeliveryStatus(OrderDeliveryStatusEnum.CREATE_ORDER_SUCCESS.getCode());
                orderDelivery.setStoreId(orderCloth.getOrgId());
                orderDelivery.setDeliveryWay(ClothOrderDeliveryWay.intracityExpress.getCode());
                BigDecimal fee = new BigDecimal(sysConfigService.selectConfigByKey(SysConfigKey.OrderClothDeliveryPrice.getCode()));
                orderDelivery.setFee(fee);
                orderDelivery.buildCreateData();
                orderDeliveryService.save(orderDelivery);

                //更新订单
                orderCloth.buildUpdateData();
                orderCloth.setTakeClothTime(DateUtils.getNowDate());
                //  分配完配送员后，直接待评价，没有中间的流程
                orderCloth.setOrderStatus(ClothOrderStatusType.FINISH.getCode());
                orderClothService.updateById(orderCloth);

                return R.ok();
            }
            default: {
                throw new ServiceException("订单状态不正确，无法派单");
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @ApiOperation("同城配送派单")
    @GetMapping(value = "/setIntracityExpress1")
    public R setIntracityExpress1(@RequestParam String orderNo) throws Exception {
        OrderCloth orderCloth = orderClothService.getOne(new QueryWrapper<OrderCloth>().lambda()
                .eq(OrderCloth::getOrderNo, orderNo)
                .eq(OrderCloth::getOrgId, SecurityUtils.getLoginUser().getOrgId())
                .eq(OrderCloth::getSourceType, SecurityUtils.getLoginUser().getSourceType()));
        if (orderCloth == null) {
            throw new ServiceException("未查询到订单信息");
        }
        if (!orderCloth.getSourceType().equals(SourceType.STORE.getCode())) {
            throw new ServiceException("该订单不是门店订单，无法同城配送派单");
        }
        SysStore sysStore = sysStoreService.getOne(new QueryWrapper<SysStore>().lambda().eq(SysStore::getId, orderCloth.getOrgId()));
        if (sysStore == null) {
            throw new ServiceException("未查询到门店");
        }

        switch (EnumUtils.getEnumByType(orderCloth.getOrderStatus(), ClothOrderStatusType.class)) {
            case APPOINTMENT: {
                // 预约待取，进行取件发单
                throw new ServiceException("同城配送暂不支持上门取件");
            }
            case WAITING_TO_SEND: {
                // 待送衣-送衣发单
                // 1.获取收衣配送单
                OrderDelivery takeDelivery = orderDeliveryService.selectOrderDeliveryByOrderId(orderCloth.getOrderNo(), ClothOrderDeliveryType.collectCloth.getCode());
                OrderDelivery orderDelivery = new OrderDelivery(takeDelivery);
                orderDelivery.setDeliverySn(orderNoUtils.getDeliveryOrderNo());
                orderDelivery.setOrderSn(orderCloth.getOrderNo());
                orderDelivery.setClothOrderType(ClothOrderDeliveryType.takeCloth.getCode());
                orderDelivery.setCreateTime(DateUtils.getNowDate());
                orderDelivery.setDeliveryStatus(OrderDeliveryStatusEnum.WAIT_DELIVERY.getCode());
                orderDelivery.setStoreId(orderCloth.getOrgId());
                // 设置未同城配送订单
                orderDelivery.setDeliveryWay(ClothOrderDeliveryWay.intracityExpress.getCode());

                if (!ClothTakeWay.DELIVERY.getCode().equals(orderCloth.getSendClothWay())) {
                    throw new ServiceException("该订单客户未选择送货上门，无法分配配送员");
                }
                AppUser appUser = appUserService.getOne(new QueryWrapper<AppUser>().lambda().eq(AppUser::getId, orderCloth.getAppUserId()));
                IntracityExpressCreateOrderResult result = sysStoreIntracityExpressService
                        .addOrder(IntracityExpressAddOrderRequest
                                .build(orderCloth, orderDelivery, sysStore, appUser.getWxOpenId()));
                // 更新订单状态
                orderClothService.update(new UpdateWrapper<OrderCloth>().lambda()
                        .eq(OrderCloth::getId, orderCloth.getId())
                        .set(OrderCloth::getOrderStatus, ClothOrderStatusType.SENDING.getCode()));
                // 更新配送单状态
                orderDelivery.setDistance(String.valueOf(result.getDistance()));
                // 金额 分 -> 元
                orderDelivery.setFee(BigDecimal.valueOf(result.getFee()).divide(BigDecimal.valueOf(100), 2));
                orderDelivery.setFetchCode(result.getFetch_code());
                orderDelivery.setServiceTransId(result.getService_trans_id());
                orderDelivery.setTransOrderId(result.getTrans_order_id());
                orderDelivery.buildCreateData();
                orderDeliveryService.save(orderDelivery);

                if (result.getErrcode() != 0) {
                    throw new ServiceException("errorCode:" + result.getErrcode() + ";errorMsg:" + result.getErrmsg());
                }
                return R.ok(result);
            }
            default: {
                throw new ServiceException("订单状态不正确，无法派单");
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @ApiOperation("分配送衣配送员")
    @GetMapping(value = "/setSendDelivery")
    public R setSendDelivery(@RequestParam String orderNo, @RequestParam Long deliveryManId) throws Exception {
        OrderCloth orderCloth = orderClothService.getOne(new QueryWrapper<OrderCloth>().lambda()
                .eq(OrderCloth::getOrderNo, orderNo)
                .eq(OrderCloth::getOrgId, SecurityUtils.getLoginUser().getOrgId()));
        if (orderCloth == null) {
            throw new ServiceException("未查询到订单信息");
        }
        if (!ClothTakeWay.DELIVERY.getCode().equals(orderCloth.getSendClothWay())) {
            throw new ServiceException("该订单客户未选择送货上门，无法分配配送员");
        }
        if (!ClothOrderStatusType.WAITING_FOR_HANG.getCode().equals(orderCloth.getOrderStatus())) {
            throw new ServiceException("当前状态为"
                    + EnumUtils.getEnumByType(orderCloth.getOrderStatus(), ClothOrderStatusType.class).getInfo()
                    + "，无法分配配送员");
        }

        AppDeliveryMan appDeliveryMan = appDeliveryManService.getOne(new QueryWrapper<AppDeliveryMan>().lambda()
                .eq(AppDeliveryMan::getAppUserId, deliveryManId));
        if (appDeliveryMan == null) {
            throw new ServiceException("未查询到配送员信息");
        }
        if (appDeliveryRelationService.count(new QueryWrapper<AppDeliveryRelation>().lambda()
                .eq(AppDeliveryRelation::getAppUserId, deliveryManId)
                .eq(AppDeliveryRelation::getOrgId, SecurityUtils.getLoginUser().getOrgId())
                .eq(AppDeliveryRelation::getSourceType, SecurityUtils.getLoginUser().getSourceType())) == 0) {
            throw new ServiceException("该配送员没有此地区配送权限");
        }
        orderCloth.setSendClothAppUserId(deliveryManId);
        orderCloth.setSendClothWay(ClothOrderDeliveryWay.delivery.getCode());
        orderCloth.setOrderStatus(ClothOrderStatusType.FINISH.getCode());
        orderClothService.updateById(orderCloth);
        // 创建配送单信息
        // 1.获取收衣配送单
        OrderDelivery takeDelivery = orderDeliveryService.selectOrderDeliveryByOrderId(orderCloth.getOrderNo(), ClothOrderDeliveryType.collectCloth.getCode());
        OrderDelivery orderDelivery = new OrderDelivery(takeDelivery);
        orderDelivery.setDeliverySn(orderNoUtils.getDeliveryOrderNo());
        orderDelivery.setOrderSn(orderCloth.getOrderNo());
        orderDelivery.setClothOrderType(ClothOrderDeliveryType.takeCloth.getCode());
        orderDelivery.setCreateTime(DateUtils.getNowDate());
        orderDelivery.setDeliveryStatus(OrderDeliveryStatusEnum.CREATE_ORDER_SUCCESS.getCode());
        orderDelivery.setDeliveryWay(ClothOrderDeliveryWay.delivery.getCode());
        orderDelivery.setStoreId(orderCloth.getOrgId());
        orderDelivery.setDeliveryManId(deliveryManId);
        AppUser appUser = appUserService.selectAppUserById(deliveryManId);
        orderDelivery.setTransporterName(appUser.getRealName());
        orderDelivery.setTransporterPhone(appUser.getPhoneNumber());
        BigDecimal fee = new BigDecimal(sysConfigService.selectConfigByKey(SysConfigKey.OrderClothDeliveryPrice.getCode()));
        orderDelivery.setFee(fee);
        orderDelivery.buildCreateData();
        orderDeliveryService.save(orderDelivery);
        return R.ok();
    }

    @Transactional(rollbackFor = Exception.class)
    @ApiOperation("取衣")
    @GetMapping(value = "/takeCloth")
    public R takeCloth(@RequestParam String washCodes, @RequestParam Long orderId) throws Exception {
        OrderCloth orderCloth = orderClothService.getOne(new QueryWrapper<OrderCloth>().lambda()
                .eq(OrderCloth::getId, orderId)
                .eq(OrderCloth::getOrgId, SecurityUtils.getLoginUser().getOrgId())
                .eq(OrderCloth::getSourceType, SecurityUtils.getLoginUser().getSourceType()));
        if (orderCloth == null) {
            throw new ServiceException("未查询到订单信息");
        }
        if (ClothTakeWay.DELIVERY.getCode().equals(orderCloth.getSendClothWay())) {
            throw new ServiceException("该订单客户已选择送货上门，无法取衣");
        }
        if (!orderCloth.getPayStatus().equals(PayStatus.HAS_PAY.getCode())) {
            throw new ServiceException("订单未支付，无法取衣");
        }
        orderClothItemService.update(new UpdateWrapper<OrderClothItem>().lambda()
                .set(OrderClothItem::getFlowStatus, ClothOrderFlowStatus.hasTake.getCode())
                .set(OrderClothItem::getTakeClothTime, DateUtils.getNowDate())
                .eq(OrderClothItem::getOrderId, orderId).in(OrderClothItem::getWashCode, washCodes.split(",")));
        List<OrderClothItem> orderClothItems = orderClothItemService.list(new QueryWrapper<OrderClothItem>()
                .lambda().eq(OrderClothItem::getOrderId, orderId).in(OrderClothItem::getWashCode, washCodes.split(",")));
        orderClothItemFlowRecordService.addRecordBatch(orderClothItems, ClothOrderFlowStatus.hasTake.getCode());
        //判断订单是否全部取完
        orderClothService.checkAllOrderStatus(orderCloth.getId(), ClothOrderStatusType.WAITING_FOR_HANG.getCode());
        return R.ok();
    }

    @ApiOperation("根据订单编号订单明细")
    @GetMapping(value = "/getInfoByOrderNo")
    public R<OrderClothVO> getInfoByOrderNo(@RequestParam @ApiParam("订单编号") String orderNo) throws Exception {
        LambdaQueryWrapper<OrderCloth> queryWrapper = new QueryWrapper<OrderCloth>().lambda()
                .eq(OrderCloth::getOrderNo, orderNo);
        if (SourceType.FACTORY.getCode().equals(SecurityUtils.getLoginUser().getSourceType())) {
            queryWrapper.eq(OrderCloth::getFactoryId, SecurityUtils.getLoginUser().getOrgId());
        }
        if (SourceType.STORE.getCode().equals(SecurityUtils.getLoginUser().getSourceType())) {
            queryWrapper.eq(OrderCloth::getOrgId, SecurityUtils.getLoginUser().getOrgId());
        }
        OrderCloth orderCloth = orderClothService.getOne(queryWrapper);
        if (orderCloth == null) {
            throw new ServiceException("未查询到订单信息");
        }

        OrderClothVO orderClothVO = new OrderClothVO();
        BeanUtils.copyProperties(orderCloth, orderClothVO);
        orderClothVO.setSysOrg(sysOrgService.getOne(new QueryWrapper<SysOrg>().lambda().eq(SysOrg::getId, orderCloth.getOrgId())
                .eq(SysOrg::getSourceType, orderCloth.getSourceType())));

        orderClothVO.setOrderClothItemVOS(
                orderClothItemService.buildWeAppOrderClothItemDetail(
                        orderClothItemService.list(new QueryWrapper<OrderClothItem>().lambda()
                                .eq(OrderClothItem::getOrderId, orderCloth.getId()))));

        if (TakeOrSendClothWay.DELIVERY.getCode().equals(orderCloth.getTakeClothWay())
                || TakeOrSendClothWay.DELIVERY.getCode().equals(orderCloth.getSendClothWay())) {
            Map<String, OrderDelivery> orderDeliveryMap = orderDeliveryService.list(
                            new QueryWrapper<OrderDelivery>().lambda()
                                    .eq(OrderDelivery::getOrderSn, orderCloth.getOrderNo()))
                    .stream().collect(Collectors.toMap(OrderDelivery::getClothOrderType
                            , OrderDelivery -> OrderDelivery));
            if (TakeOrSendClothWay.DELIVERY.getCode().equals(orderCloth.getTakeClothWay())) {
                orderClothVO.setCollectClothDeliverInfo(orderDeliveryMap.get(ClothOrderDeliveryType.collectCloth.getCode()));
            }
            if (TakeOrSendClothWay.DELIVERY.getCode().equals(orderCloth.getSendClothWay())) {
                orderClothVO.setCollectClothDeliverInfo(orderDeliveryMap.get(ClothOrderDeliveryType.takeCloth.getCode()));
            }
        }
        return R.ok(orderClothVO);
    }

    @ApiOperation("根据订单编号获取预约订单明细")
    @GetMapping(value = "/getAppointmentInfoByOrderNo")
    public R<OrderCloth> getAppointmentInfoByOrderNo(@RequestParam @ApiParam("订单编号") String orderNo
            , @RequestParam @ApiParam("用户ID") Long appUserId) throws Exception {
        return R.ok(orderClothService.getOne(new QueryWrapper<OrderCloth>().lambda()
                .eq(OrderCloth::getOrderNo, orderNo)
                .eq(OrderCloth::getAppUserId, appUserId)
                .eq(OrderCloth::getOrderStatus, ClothOrderStatusType.APPOINTMENT.getCode())
                .eq(OrderCloth::getDelFlag, DeleteStatus.OK.getCode())));
    }

    @PreAuthorize("@ss.hasPermi('order:cloth:collectCloth')")
    @ApiOperation("创建收衣订单")
    @PostMapping(value = "/collectCloth")
    public R<OrderCloth> collectCloth(@Valid @RequestBody OrderClothDTO orderClothDTO) throws Exception {
        Long defaultWashSpeed = Long.parseLong(configService.selectConfigByKey(SysConfigKey.OrderClothDefaultSpeed.getCode()));
        if (orderClothDTO.getSpeedId() == null) {
            orderClothDTO.setSpeedId(defaultWashSpeed);
        }
        for (OrderClothItemDTO orderClothItemDTO : orderClothDTO.getOrderClothItemDTOS()) {
            if (orderClothItemDTO.getClothSpeedId() == null) {
                orderClothItemDTO.setClothSpeedId(defaultWashSpeed);
            }
        }
        return R.ok(orderClothService.collectCloth(orderClothDTO));
    }

    @Transactional(rollbackFor = Exception.class)
    @PreAuthorize("@ss.hasPermi('order:cloth:collectCloth')")
    @ApiOperation("订单付款")
    @PostMapping(value = "/clothOrderPay")
    public R<OrderPayResultVO> clothOrderPay(@Valid @RequestBody OrderClothPayDTO orderClothPayDTO) throws Exception {
        return R.ok(orderClothService.clothOrderPay(orderClothPayDTO));
    }

    @ApiOperation("根据订单编号获取订单状态")
    @GetMapping(value = "/getOrderPayResult")
    public R<OrderPayResultVO> getOrderPayResult(@RequestParam @ApiParam("订单编号") String orderNo) throws Exception {
        OrderCloth orderCloth = orderClothService.getOrderClothByOrderNo(orderNo);
        if (orderCloth == null) {
            throw new ServiceException("未查询到订单支付记录");
        }
        if (orderCloth.getPayStatus().equals(PayStatus.HAS_PAY.getCode())) {
            return R.ok(OrderPayResultVO.paySuccess(orderNo));
        }
        if (orderCloth.getPayStatus().equals(PayStatus.WAITING_TO_PAY.getCode())) {
            return R.ok(OrderPayResultVO.payWait(orderNo));
        }
        if (orderCloth.getPayStatus().equals(PayStatus.PAY_FAIL.getCode())) {
            return R.ok(OrderPayResultVO.payError("支付失败"));
        }
        return R.ok(OrderPayResultVO.payWait(orderNo));
    }

    @Transactional(rollbackFor = Exception.class)
    @ApiOperation("撤单")
    @GetMapping(value = "/refund")
    public R refundOrder(@RequestParam Long orderId) throws Exception {
        orderClothService.refundOrderApply(orderId, getLoginUser().getUsername() + "手动撤单");
        return R.ok(null, "撤单提交成功");
    }

    @PostMapping("/getSendClothOrderList")
    @ApiOperation(value = "查询取衣订单")
    public R<Page<OrderClothQueryVO>> getSendClothOrderList(@RequestBody OrderClothQueryDTO orderClothQueryDTO) throws Exception {
        LambdaQueryWrapper<OrderCloth> queryWrapper = new QueryWrapper<OrderCloth>().lambda()
                .eq(OrderCloth::getDelFlag, DeleteStatus.OK.getCode())
                .ne(OrderCloth::getRefundStatus, OrderRefundStatus.REFUND_SUCCESS.getCode());
        queryWrapper.eq(OrderCloth::getSourceType, SecurityUtils.getLoginUser().getSourceType());
        queryWrapper.eq(OrderCloth::getOrgId, SecurityUtils.getLoginUser().getOrgId());
        if (StringUtils.isNotEmpty(orderClothQueryDTO.getOrderStatus())) {
            queryWrapper.eq(OrderCloth::getOrderStatus, orderClothQueryDTO.getOrderStatus());
        } else {
            queryWrapper.and(orderClothLambdaQueryWrapper -> orderClothLambdaQueryWrapper
                    .eq(OrderCloth::getOrderStatus, ClothOrderStatusType.WASHING.getCode()).or()
                    .eq(OrderCloth::getOrderStatus, ClothOrderStatusType.HAS_WASH.getCode()).or()
                    .eq(OrderCloth::getOrderStatus, ClothOrderStatusType.WAITING_FOR_HANG.getCode()).or()
                    .eq(OrderCloth::getOrderStatus, ClothOrderStatusType.WAITING_TO_SEND.getCode()).or()
                    .eq(OrderCloth::getOrderStatus, ClothOrderStatusType.SENDING.getCode()).or());
        }
        if (StringUtils.isNotEmpty(orderClothQueryDTO.getOrderNo())) {
            queryWrapper.like(OrderCloth::getOrderNo, orderClothQueryDTO.getOrderNo());
        }
        if (orderClothQueryDTO.getBeginCreateTime() != null) {
            queryWrapper.ge(BaseEntity::getCreateTime, orderClothQueryDTO.getBeginCreateTime());
        }
        if (orderClothQueryDTO.getEndCreateTime() != null) {
            queryWrapper.lt(BaseEntity::getCreateTime, DateUtils.addDays(orderClothQueryDTO.getEndCreateTime(), 1));
        }
        if (StringUtils.isNotEmpty(orderClothQueryDTO.getAppUserPhoneNumber())) {
            AppUser appUser = appUserService.getOne(new QueryWrapper<AppUser>().lambda()
                    .eq(AppUser::getPhoneNumber, orderClothQueryDTO.getAppUserPhoneNumber()));
            if (appUser == null) {
                return R.ok(new Page<>());
            }
            queryWrapper.eq(OrderCloth::getAppUserId, appUser.getId());
        }
        if (StringUtils.isNotEmpty(orderClothQueryDTO.getUserId())) {
            queryWrapper.eq(OrderCloth::getAppUserId, orderClothQueryDTO.getUserId());
        }
        queryWrapper.orderByDesc(BaseEntity::getCreateTime);

        return orderClothService.findPage(queryWrapper, orderClothQueryDTO);
    }

    /**
     * 查询洗衣订单列表
     */
    @PreAuthorize("@ss.hasPermi('order:cloth:list')")
    @GetMapping("/list")
    @ApiOperation(value = "查询洗衣订单列表")
    public R list(OrderClothQueryDTO orderClothQueryDTO) throws Exception {
        LambdaQueryWrapper<OrderCloth> queryWrapper = new QueryWrapper<OrderCloth>().lambda()
                .eq(OrderCloth::getDelFlag, DeleteStatus.OK.getCode());
        if (SourceType.FACTORY.getCode().equals(SecurityUtils.getLoginUser().getSourceType())) {
            queryWrapper.eq(OrderCloth::getFactoryId, SecurityUtils.getLoginUser().getOrgId());
        }
        if (SourceType.STORE.getCode().equals(SecurityUtils.getLoginUser().getSourceType())) {
            queryWrapper.eq(OrderCloth::getOrgId, SecurityUtils.getLoginUser().getOrgId());
        }
        if (StringUtils.isNotEmpty(orderClothQueryDTO.getOrderType())) {
            queryWrapper.eq(OrderCloth::getOrderType, orderClothQueryDTO.getOrderType());
        }
        if (StringUtils.isNotEmpty(orderClothQueryDTO.getPayType())) {
            queryWrapper.eq(OrderCloth::getPayType, orderClothQueryDTO.getPayType());
        }
        if (StringUtils.isNotEmpty(orderClothQueryDTO.getPayStatus())) {
            queryWrapper.eq(OrderCloth::getPayStatus, orderClothQueryDTO.getPayStatus());
        }
        if (StringUtils.isNotEmpty(orderClothQueryDTO.getIsSelectOrg())) {
            if (SysBoolType.YES.getCode().equals(orderClothQueryDTO.getIsSelectOrg())) {
                queryWrapper.isNotNull(OrderCloth::getOrgId);
            } else {
                queryWrapper.isNull(OrderCloth::getOrgId);
            }
        }
        if (StringUtils.isNotEmpty(orderClothQueryDTO.getIsAppointment())) {
            queryWrapper.eq(OrderCloth::getIsAppointment, orderClothQueryDTO.getIsAppointment());
        }
        if (StringUtils.isNotEmpty(orderClothQueryDTO.getOrderStatus())) {
            if (ClothOrderStatusType.FINISH.getCode().equals(orderClothQueryDTO.getOrderStatus())) {
                queryWrapper.and(orderClothLambdaQueryWrapper -> orderClothLambdaQueryWrapper
                        .eq(OrderCloth::getOrderStatus, ClothOrderStatusType.WAITING_FOR_COMMENT.getCode())
                        .or().eq(OrderCloth::getOrderStatus, ClothOrderStatusType.FINISH.getCode()));
            } else {
                queryWrapper.eq(OrderCloth::getOrderStatus, orderClothQueryDTO.getOrderStatus());
            }
        }
        if (StringUtils.isNotEmpty(orderClothQueryDTO.getOrderSource())) {
            if ("0".equals(orderClothQueryDTO.getOrderSource())) {
                queryWrapper.ne(OrderCloth::getOrderSource, OrderSourceType.OFFLINE.getCode());
            } else {
                queryWrapper.eq(OrderCloth::getOrderSource, OrderSourceType.OFFLINE.getCode());
            }
        }
        if (StringUtils.isNotEmpty(orderClothQueryDTO.getOrderNo())) {
            queryWrapper.like(OrderCloth::getOrderNo, orderClothQueryDTO.getOrderNo());
        }
        if (orderClothQueryDTO.getBeginCreateTime() != null) {
            queryWrapper.ge(BaseEntity::getCreateTime, orderClothQueryDTO.getBeginCreateTime());
        }
        if (orderClothQueryDTO.getEndCreateTime() != null) {
            queryWrapper.lt(BaseEntity::getCreateTime, DateUtils.addDays(orderClothQueryDTO.getEndCreateTime(), 1));
        }
        if (StringUtils.isNotEmpty(orderClothQueryDTO.getAppUserPhoneNumber())) {
            AppUser appUser = appUserService.getOne(new QueryWrapper<AppUser>().lambda()
                    .eq(AppUser::getPhoneNumber, orderClothQueryDTO.getAppUserPhoneNumber()));
            if (appUser == null) {
                return R.ok(new Page<>());
            }
            queryWrapper.eq(OrderCloth::getAppUserId, appUser.getId());
        }
        if (StringUtils.isNotEmpty(orderClothQueryDTO.getUserId())) {
            queryWrapper.eq(OrderCloth::getAppUserId, orderClothQueryDTO.getUserId());
        }
        queryWrapper.orderByDesc(BaseEntity::getCreateTime);
        R<Page<OrderClothQueryVO>> page = orderClothService.findPage(queryWrapper, orderClothQueryDTO);
        return R.page(page.getData());
    }

    @PostMapping(value = "/getMemberOrderClothInfo")
    @ApiOperation(value = "获取会员洗衣订单信息")
    public R<Page<OrderClothQueryVO>> getMemberOrderClothInfo(@RequestBody MemberOrderQueryDTO memberOrderQueryDTO) {
        LambdaQueryWrapper<OrderCloth> queryWrapper = new QueryWrapper<OrderCloth>().lambda()
                .eq(OrderCloth::getDelFlag, DeleteStatus.OK.getCode())
                .eq(OrderCloth::getAppUserId, memberOrderQueryDTO.getAppUserId())
                .ne(OrderCloth::getRefundStatus, OrderRefundStatus.REFUND_SUCCESS.getCode());
        if (SourceType.STORE.getCode().equals(SecurityUtils.getLoginUser().getSourceType())) {
            queryWrapper.eq(OrderCloth::getSourceType, SourceType.STORE.getCode());
            queryWrapper.eq(OrderCloth::getOrgId, SecurityUtils.getLoginUser().getOrgId());
        }
        queryWrapper.orderByDesc(OrderCloth::getCreateTime);
        return orderClothService.findPage(queryWrapper, memberOrderQueryDTO);
    }

    /**
     * 导出洗衣订单列表
     */
    @PreAuthorize("@ss.hasPermi('order:cloth:export')")
    @Log(title = "洗衣订单", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    @ApiOperation(value = "导出洗衣订单列表")
    public void export(HttpServletResponse response, OrderClothQueryDTO orderClothQueryDTO) {
        LambdaQueryWrapper<OrderCloth> queryWrapper = new QueryWrapper<OrderCloth>().lambda()
                .eq(OrderCloth::getDelFlag, DeleteStatus.OK.getCode())
                .ne(OrderCloth::getRefundStatus, OrderRefundStatus.REFUND_SUCCESS.getCode());
        if (SourceType.FACTORY.getCode().equals(SecurityUtils.getLoginUser().getSourceType())) {
            queryWrapper.eq(OrderCloth::getFactoryId, SecurityUtils.getLoginUser().getOrgId());
        }
        if (SourceType.STORE.getCode().equals(SecurityUtils.getLoginUser().getSourceType())) {
            queryWrapper.eq(OrderCloth::getOrgId, SecurityUtils.getLoginUser().getOrgId());
        }
        if (StringUtils.isNotEmpty(orderClothQueryDTO.getOrderType())) {
            queryWrapper.eq(OrderCloth::getOrderType, orderClothQueryDTO.getOrderType());
        }
        if (StringUtils.isNotEmpty(orderClothQueryDTO.getIsSelectOrg())) {
            if (SysBoolType.YES.getCode().equals(orderClothQueryDTO.getIsSelectOrg())) {
                queryWrapper.isNotNull(OrderCloth::getOrgId);
            } else {
                queryWrapper.isNull(OrderCloth::getOrgId);
            }
        }
        queryWrapper.and(orderClothLambdaQueryWrapper -> orderClothLambdaQueryWrapper
                .eq(OrderCloth::getOrderStatus, ClothOrderStatusType.WAITING_FOR_PAY.getCode()).or()
                .eq(OrderCloth::getOrderStatus, ClothOrderStatusType.WASHING.getCode()).or()
                .eq(OrderCloth::getOrderStatus, ClothOrderStatusType.HAS_WASH.getCode()).or()
                .eq(OrderCloth::getOrderStatus, ClothOrderStatusType.WAITING_TO_SEND.getCode()).or()
                .eq(OrderCloth::getOrderStatus, ClothOrderStatusType.SENDING.getCode()).or()
                .eq(OrderCloth::getOrderStatus, ClothOrderStatusType.WAITING_FOR_COMMENT.getCode()).or()
                .eq(OrderCloth::getOrderStatus, ClothOrderStatusType.FINISH.getCode()));
        if (StringUtils.isNotEmpty(orderClothQueryDTO.getOrderStatus())) {
            if (ClothOrderStatusType.FINISH.getCode().equals(orderClothQueryDTO.getOrderStatus())) {
                queryWrapper.and(orderClothLambdaQueryWrapper -> orderClothLambdaQueryWrapper
                        .eq(OrderCloth::getOrderStatus, ClothOrderStatusType.WAITING_FOR_COMMENT.getCode())
                        .or().eq(OrderCloth::getOrderStatus, ClothOrderStatusType.FINISH.getCode()));
            } else {
                queryWrapper.eq(OrderCloth::getOrderStatus, orderClothQueryDTO.getOrderStatus());
            }
        }
        if (StringUtils.isNotEmpty(orderClothQueryDTO.getOrderSource())) {
            if ("0".equals(orderClothQueryDTO.getOrderSource())) {
                queryWrapper.ne(OrderCloth::getOrderSource, OrderSourceType.OFFLINE.getCode());
            } else {
                queryWrapper.eq(OrderCloth::getOrderSource, OrderSourceType.OFFLINE.getCode());
            }
        }
        if (StringUtils.isNotEmpty(orderClothQueryDTO.getOrderNo())) {
            queryWrapper.like(OrderCloth::getOrderNo, orderClothQueryDTO.getOrderNo());
        }
        if (orderClothQueryDTO.getBeginCreateTime() != null) {
            queryWrapper.ge(BaseEntity::getCreateTime, orderClothQueryDTO.getBeginCreateTime());
        }
        if (orderClothQueryDTO.getEndCreateTime() != null) {
            queryWrapper.lt(BaseEntity::getCreateTime, DateUtils.addDays(orderClothQueryDTO.getEndCreateTime(), 1));
        }
        if (StringUtils.isNotEmpty(orderClothQueryDTO.getAppUserPhoneNumber())) {
            AppUser appUser = appUserService.getOne(new QueryWrapper<AppUser>().lambda()
                    .eq(AppUser::getPhoneNumber, orderClothQueryDTO.getAppUserPhoneNumber()));
            if (appUser == null) {
                ExcelUtil<OrderClothQueryVO> util = new ExcelUtil<OrderClothQueryVO>(OrderClothQueryVO.class);
                util.exportExcel(response, new ArrayList<>(), "洗衣订单数据");
                return;
            }
            queryWrapper.eq(OrderCloth::getAppUserId, appUser.getId());
        }
        if (StringUtils.isNotEmpty(orderClothQueryDTO.getUserId())) {
            queryWrapper.eq(OrderCloth::getAppUserId, orderClothQueryDTO.getUserId());
        }
        queryWrapper.orderByDesc(BaseEntity::getCreateTime);
        // 最多50000条
        orderClothQueryDTO.setPageSize(50000);
        R<Page<OrderClothQueryVO>> page = orderClothService.findPage(queryWrapper, orderClothQueryDTO);
        List<OrderClothQueryVO> list = page.getData().getRecords();

        ExcelUtil<OrderClothQueryVO> util = new ExcelUtil<OrderClothQueryVO>(OrderClothQueryVO.class);
        util.exportExcel(response, list, "洗衣订单数据");
    }

    /**
     * 导出洗衣订单列表
     */
    @PreAuthorize("@ss.hasPermi('order:cloth:export')")
    @Log(title = "洗衣订单", businessType = BusinessType.EXPORT)
    @PostMapping("/exportByCloud")
    @ApiOperation(value = "导出云洗预约订单列表")
    public void exportByCloud(HttpServletResponse response, OrderAppointmentDTO2 orderAppointmentDTO2) {
        // 最多50000条
        orderAppointmentDTO2.setPageSizeExport(50000);
        List<OrderClothAppointmentVO> list = orderClothService.getAppointmentClothOrderList(orderAppointmentDTO2);
        ExcelUtil<OrderClothAppointmentVO> util = new ExcelUtil<OrderClothAppointmentVO>(OrderClothAppointmentVO.class);
        util.exportExcel(response, list, "云洗预约订单数据");
    }

    /**
     * 获取洗衣订单详细信息
     */
    @PreAuthorize("@ss.hasPermi('order:cloth:query')")
    @GetMapping(value = "/{id}")
    @ApiOperation(value = "获取洗衣订单详细信息")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return success(orderClothService.selectOrderClothById(id));
    }

    /**
     * 获取洗衣订单详细信息
     */
    @GetMapping(value = "/detail/{orderSn}")
    @ApiOperation(value = "获取洗衣订单详细信息")
    public R<OrderClothPrintVO> getDetailInfo(@PathVariable("orderSn") String orderSn) {
        OrderClothPrintVO orderClothPrintVO = new OrderClothPrintVO();
        OrderCloth orderCloth = orderClothService.getOrderClothByOrderNo(orderSn);
        com.yiqi.common.utils.bean.BeanUtils.copyProperties(orderCloth, orderClothPrintVO);
        AppUserInfoVO userInfo = appUserService.getAppUserInfoById(orderClothPrintVO.getAppUserId());
        OrderClothAddress orderClothAddress = orderClothAddressService.getByorderSn(orderClothPrintVO.getOrderNo());
        if (orderClothAddress != null) {
            userInfo.setAddress(orderClothAddress.getAddress());
            userInfo.setAddressDetail(orderClothAddress.getAddressDetail());
            userInfo.setProvince(orderClothAddress.getProvince());
            userInfo.setCity(orderClothAddress.getCity());
            userInfo.setArea(orderClothAddress.getArea());
        }
        userInfo.setContactName(orderClothPrintVO.getContactName());
        userInfo.setContactPhone(orderClothPrintVO.getContactPhone());
        orderClothPrintVO.setAppUserInfoVO(userInfo);
        //获取衣服明细
        List<OrderClothItemVO> orderClothItemList = orderClothItemService.queryClothItemByOrderId(orderClothPrintVO.getOrderNo());
        if (CollUtil.isEmpty(orderClothItemList)) {
            throw new ServiceException("未找到衣服明细");
        }
        orderClothPrintVO.setOrderClothItemVOS(orderClothItemList);
        orderClothPrintVO.setStoreName(sysStoreService.getStoreNameById(orderClothPrintVO.getOrgId()));
        return R.ok(orderClothPrintVO);
    }

    /**
     * 获取零售商品订单详细信息
     */
    @GetMapping(value = "/print/{id}")
    @ApiOperation(value = "洗衣订单打印")
    public R<OrderClothPrintVO> getPrintInfo(@PathVariable("id") Long id) {
        OrderClothPrintVO orderClothPrintVO = new OrderClothPrintVO();
        OrderCloth orderCloth = orderClothService.selectOrderClothById(id);
        com.yiqi.common.utils.bean.BeanUtils.copyProperties(orderCloth, orderClothPrintVO);
        AppUserInfoVO userInfo = appUserService.getAppUserInfoById(orderClothPrintVO.getAppUserId());
        OrderClothAddress orderClothAddress = orderClothAddressService.getByorderSn(orderClothPrintVO.getOrderNo());
        if (orderClothAddress != null) {
            userInfo.setAddress(orderClothAddress.getAddress());
            userInfo.setAddressDetail(orderClothAddress.getAddressDetail());
            userInfo.setProvince(orderClothAddress.getProvince());
            userInfo.setCity(orderClothAddress.getCity());
            userInfo.setArea(orderClothAddress.getArea());
        }
        userInfo.setContactName(orderClothPrintVO.getContactName());
        userInfo.setContactPhone(orderClothPrintVO.getContactPhone());
        orderClothPrintVO.setAppUserInfoVO(userInfo);
        //获取衣服明细
        List<OrderClothItemVO> orderClothItemList = orderClothItemService.queryClothItemByOrderId(orderClothPrintVO.getOrderNo());
        if (CollUtil.isEmpty(orderClothItemList)) {
            throw new ServiceException("未找到衣服明细");
        }
        orderClothPrintVO.setOrderClothItemVOS(orderClothItemList);
        RechargePasswordCard rechargePasswordCard = rechargePasswordCardService.selectTotalBalanceGroupByAppUser(orderClothPrintVO.getAppUserId(), null);
        if (orderClothPrintVO.getPayType().equals(PayType.BALANCE.getCode())) {
            orderClothPrintVO.setMemberBeforeBalance(CurrencyUtil.add(rechargePasswordCard.getTotalBalance(), orderClothPrintVO.getPayAmount()));
            orderClothPrintVO.setMemberAfterBalance(rechargePasswordCard.getTotalBalance());
            orderClothPrintVO.setMemberChangeAmount(orderClothPrintVO.getPayAmount());
        } else {
            orderClothPrintVO.setMemberBeforeBalance(rechargePasswordCard.getTotalBalance());
            orderClothPrintVO.setMemberAfterBalance(rechargePasswordCard.getTotalBalance());
            orderClothPrintVO.setMemberChangeAmount(BigDecimal.ZERO);
        }
        return R.ok(orderClothPrintVO);
    }

    /**
     * 删除洗衣订单
     */
    @PreAuthorize("@ss.hasPermi('order:cloth:remove')")
    @Log(title = "洗衣订单", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    @ApiOperation(value = "删除洗衣订单")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(orderClothService.deleteOrderClothByIds(ids));
    }


    /**
     * 查询待上挂洗衣订单衣服明细列表
     */
    @PreAuthorize("@ss.hasPermi('order:cloth:list')")
    @GetMapping("/getNoHangerOrderClothList")
    @ApiOperation(value = "查询待上挂洗衣订单衣服明细列表")
    public TableDataInfo getNoHangerOrderClothList() {
        startPage();
        List<ClothHangerOrderRelationVO> list = orderClothService.getNoHangerOrderClothList();
        return getDataTable(list);
    }

    /**
     * 获取洗衣订单详细信息
     */
    @PreAuthorize("@ss.hasPermi('order:cloth:query')")
    @GetMapping(value = "/getOrderClothInfoByWashCode")
    @ApiOperation(value = "获取洗衣订单详细信息")
    public AjaxResult getOrderClothInfoByWashCode(@RequestParam("washCode") String washCode) {
        return success(orderClothService.getOrderClothInfoByWashCode(washCode));
    }

    /**
     * 获取预约洗衣订单
     */
    @PostMapping(value = "/getAppointmentClothOrderList")
    @ApiOperation(value = "获取预约洗衣订单")
    public TableDataInfo getAppointmentClothOrderList(@RequestBody @Valid OrderAppointmentDTO2 orderAppointmentDTO2) {
        startPage();
        List<OrderClothAppointmentVO> list = orderClothService.getAppointmentClothOrderList(orderAppointmentDTO2);
        return getDataTable(list);
    }

    /**
     * 预约订单，设置派送员
     */
    @GetMapping(value = "/setDeliveryManByAppointment")
    @ApiOperation(value = "预约订单，设置派送员")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult setDeliveryManByAppointment(@RequestParam("deliveryId") String deliveryId,
                                                  @RequestParam("orderNo") String orderNo) {
        OrderCloth orderCloth = orderClothService.getOne(new QueryWrapper<OrderCloth>().lambda()
                .eq(OrderCloth::getOrderNo, orderNo)
                .eq(OrderCloth::getSourceType, SecurityUtils.getLoginUser().getSourceType())
                .eq(OrderCloth::getOrgId, SecurityUtils.getLoginUser().getOrgId()));
        if (orderCloth == null) {
            throw new ServiceException("未查询到订单");
        }
        if (!orderCloth.getOrderStatus().equals(ClothOrderStatusType.APPOINTMENT.getCode())
                && !orderCloth.getOrderStatus().equals(ClothOrderStatusType.WAITING_TO_DOOR.getCode())) {
            throw new ServiceException("当前订单状态为"
                    + EnumUtils.getEnumByType(orderCloth.getOrderStatus(), ClothOrderStatusType.class)
                    + "，无法进行上门收衣操作");
        }
        orderCloth.buildUpdateData();
        orderCloth.setTakeClothAppUserId(Long.parseLong(deliveryId));
        orderCloth.setTakeClothTime(DateUtils.getNowDate());
        //  分配完配送员后，直接待定价，没有中间的流程
        orderCloth.setOrderStatus(ClothOrderStatusType.HAS_TAKING.getCode());
        orderClothService.updateById(orderCloth);
        // 更新配送员id
        OrderDelivery orderDelivery = orderDeliveryService.selectOrderDeliveryByOrderId(orderCloth.getOrderNo(), ClothOrderDeliveryType.collectCloth.getCode());
        orderDelivery.setDeliveryManId(Long.valueOf(deliveryId));
        AppUser appUser = appUserService.selectAppUserById(Long.valueOf(deliveryId));
        orderDelivery.setTransporterName(appUser.getRealName());
        orderDelivery.setTransporterPhone(appUser.getPhoneNumber());
        orderDelivery.setDeliveryStatus(OrderDeliveryStatusEnum.CREATE_ORDER_SUCCESS.getCode());
        BigDecimal fee = new BigDecimal(sysConfigService.selectConfigByKey(SysConfigKey.OrderClothDeliveryPrice.getCode()));
        orderDelivery.setFee(fee);
        orderDelivery.buildUpdateData();
        orderDeliveryService.updateById(orderDelivery);
        return success();
    }

    /**
     * 预约订单，取消预约
     */
    @GetMapping(value = "/cancelAppointmentOrderByAppointment")
    @ApiOperation(value = "预约订单，取消预约")
    public AjaxResult cancelAppointmentOrderByAppointment(@RequestParam("orderNo") String orderNo) {
        OrderCloth orderCloth = new OrderCloth();
        orderCloth.buildUpdateData();
        orderCloth.setOrderStatus(ClothOrderStatusType.CANCEL.getCode());
        return success(orderClothService.update(orderCloth, new QueryWrapper<OrderCloth>().lambda().eq(OrderCloth::getOrderNo, orderNo)));
    }

    /**
     * 门店衣服订单-消费统计
     */
    @PreAuthorize("@ss.hasPermi('order:countConsume:list')")
    @PostMapping(value = "/listCountConsumeByClothOrder")
    @ApiOperation(value = "衣服订单-消费统计")
    public R<OrderClothCountConsumeQueryVO> listCountConsumeByClothOrder(@RequestBody @Valid OrderClothCountConsumeQueryDTO orderClothCountConsumeQueryDTO) {
        if (DateUtils.addMonths(orderClothCountConsumeQueryDTO.getBeginCreateTime(), 3).compareTo(orderClothCountConsumeQueryDTO.getEndCreateTime()) < 0) {
            throw new ServiceException("查询最大范围3个月的数据");
        }
        LambdaQueryWrapper<OrderCloth> queryWrapper = new QueryWrapper<OrderCloth>().lambda()
                .eq(OrderCloth::getDelFlag, DeleteStatus.OK.getCode())
                .ge(BaseEntity::getCreateTime, orderClothCountConsumeQueryDTO.getBeginCreateTime())
                .lt(BaseEntity::getCreateTime, DateUtils.addDays(orderClothCountConsumeQueryDTO.getEndCreateTime(), 1))
                .ne(OrderCloth::getRefundStatus, OrderRefundStatus.REFUND_SUCCESS.getCode())
                .notIn(OrderCloth::getOrderStatus,
                        ClothOrderStatusType.APPOINTMENT.getCode(),
                        ClothOrderStatusType.WAITING_TO_DOOR.getCode(),
                        ClothOrderStatusType.HAS_TO_DOOR.getCode(),
                        ClothOrderStatusType.HAS_TAKING.getCode(),
                        ClothOrderStatusType.CANCEL);
        if (SourceType.FACTORY.getCode().equals(SecurityUtils.getLoginUser().getSourceType())) {
            queryWrapper.eq(OrderCloth::getFactoryId, SecurityUtils.getLoginUser().getOrgId());
        }
        if (SourceType.STORE.getCode().equals(SecurityUtils.getLoginUser().getSourceType())) {
            queryWrapper.eq(OrderCloth::getOrgId, SecurityUtils.getLoginUser().getOrgId());
        }
        if (StringUtils.isNotEmpty(orderClothCountConsumeQueryDTO.getOrderNo())) {
            queryWrapper.like(OrderCloth::getOrderNo, orderClothCountConsumeQueryDTO.getOrderNo());
        }
//        if(orderClothCountConsumeQueryDTO.getBeginCreateTime() != null){
//            queryWrapper.ge(BaseEntity::getCreateTime, orderClothCountConsumeQueryDTO.getBeginCreateTime());
//        }
//        if(orderClothCountConsumeQueryDTO.getEndCreateTime() != null){
//            queryWrapper.lt(BaseEntity::getCreateTime, DateUtils.addDays(orderClothCountConsumeQueryDTO.getEndCreateTime(),1));
//        }
        if (orderClothCountConsumeQueryDTO.getUserId() != null) {
            queryWrapper.eq(OrderCloth::getAppUserId, orderClothCountConsumeQueryDTO.getUserId());
        }
        if (StringUtils.isNotEmpty(orderClothCountConsumeQueryDTO.getPhoneNumber())) {
            AppUser appUser = appUserService.getOne(new QueryWrapper<AppUser>().lambda()
                    .eq(AppUser::getPhoneNumber, orderClothCountConsumeQueryDTO.getPhoneNumber()));
            if (appUser == null) {
                return R.ok(new OrderClothCountConsumeQueryVO());
            }
            queryWrapper.eq(OrderCloth::getAppUserId, appUser.getId());
        }
        queryWrapper.orderByDesc(BaseEntity::getCreateTime);
        Page<OrderCloth> pageOrderCloth = orderClothService.page(new Page<>(orderClothCountConsumeQueryDTO.getPageNum()
                        , orderClothCountConsumeQueryDTO.getPageSize())
                , queryWrapper);
        List<OrderCloth> records = pageOrderCloth.getRecords();
        if (CollUtil.isEmpty(records)) {
            return R.ok(new OrderClothCountConsumeQueryVO());
        }
        OrderClothCountConsumeQueryVO orderClothCountConsumeQueryVO = new OrderClothCountConsumeQueryVO();
        orderClothCountConsumeQueryVO.setTotal(pageOrderCloth.getTotal());
        // 列表
        List<OrderClothCountConsumeVO> consumeVOS = new ArrayList<>();
        for (OrderCloth record : records) {
            OrderClothCountConsumeVO orderClothCountConsumeVO = new OrderClothCountConsumeVO();
            BeanUtils.copyProperties(record, orderClothCountConsumeVO);
            consumeVOS.add(orderClothCountConsumeVO);
        }
        List<AppUser> appUsers = appUserService.list(new QueryWrapper<AppUser>().lambda()
                .in(AppUser::getId, consumeVOS.stream().map(OrderClothCountConsumeVO::getAppUserId).collect(Collectors.toSet())));
        Map<Long, AppUser> appUserMap = appUsers.stream().collect(Collectors.toMap(AppUser::getId, AppUser -> AppUser));
        for (OrderClothCountConsumeVO consumeVO : consumeVOS) {
            consumeVO.setAlreadyPayAmount(consumeVO.getPayAmount());
            consumeVO.setUserName(appUserMap.get(consumeVO.getAppUserId()) != null ? appUserMap.get(consumeVO.getAppUserId()).getRealName() : null);
            consumeVO.setPhoneNumber(appUserMap.get(consumeVO.getAppUserId()) != null ? appUserMap.get(consumeVO.getAppUserId()).getPhoneNumber() : null);
            if (consumeVO.getEmployeeId() != null) {
                consumeVO.setEmployeeName(appUserMap.get(consumeVO.getEmployeeId()) != null ? appUserMap.get(consumeVO.getEmployeeId()).getRealName() : null);
            }
            if (SysBoolType.NO.getCode().equals(consumeVO.getHasPay())) {
                consumeVO.setAlreadyPayAmount(BigDecimal.ZERO);
            }
        }
        orderClothCountConsumeQueryVO.setOrderClothCountConsumeVOList(consumeVOS);

        // 相同条件下，查所有订单，并进行统计
        List<OrderCloth> allOrderCloths = orderClothService.list(queryWrapper);
        // 总计应付
        BigDecimal totalWillMoney = allOrderCloths.stream().map(OrderCloth::getPayAmount).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
        // 已支付金额
        BigDecimal totalAlreadyMoney = allOrderCloths.stream().filter(vo -> PayStatus.HAS_PAY.getCode().equals(vo.getPayStatus())).map(OrderCloth::getPayAmount).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);

        // 合计实收金额 = 总计应付 - 未支付金额
        BigDecimal totalNoPayMoney = totalWillMoney.subtract(totalAlreadyMoney);
        // 累计衣物件数
        Integer totalOrderClothCount = allOrderCloths.stream().map(OrderCloth::getOrderClothCount).filter(Objects::nonNull).reduce(0, Integer::sum);
        orderClothCountConsumeQueryVO.setTotalOrderClothCount(totalOrderClothCount);
        orderClothCountConsumeQueryVO.setTotalAlreadyMoney(totalAlreadyMoney);
        orderClothCountConsumeQueryVO.setTotalWillMoney(totalWillMoney);
        return R.ok(orderClothCountConsumeQueryVO);
    }

    /**
     * 门店衣服订单-未付款统计
     */
    @PreAuthorize("@ss.hasPermi('order:countNoConsume:list')")
    @PostMapping(value = "/listCountNoConsumeByClothOrder")
    @ApiOperation(value = "衣服订单-未付款统计")
    public R<OrderClothCountConsumeQueryVO> listCountNoConsumeByClothOrder(@RequestBody @Valid OrderClothCountConsumeQueryDTO orderClothCountConsumeQueryDTO) {
        if (DateUtils.addMonths(orderClothCountConsumeQueryDTO.getBeginCreateTime(), 3).compareTo(orderClothCountConsumeQueryDTO.getEndCreateTime()) < 0) {
            throw new ServiceException("查询最大范围3个月的数据");
        }
        LambdaQueryWrapper<OrderCloth> queryWrapper = new QueryWrapper<OrderCloth>().lambda()
                .eq(OrderCloth::getDelFlag, DeleteStatus.OK.getCode())
                .eq(OrderCloth::getPayStatus, PayStatus.PAY_FAIL.getCode())
                .ge(BaseEntity::getCreateTime, orderClothCountConsumeQueryDTO.getBeginCreateTime())
                .lt(BaseEntity::getCreateTime, DateUtils.addDays(orderClothCountConsumeQueryDTO.getEndCreateTime(), 1))
                .ne(OrderCloth::getRefundStatus, OrderRefundStatus.REFUND_SUCCESS.getCode());
        if (SourceType.FACTORY.getCode().equals(SecurityUtils.getLoginUser().getSourceType())) {
            queryWrapper.eq(OrderCloth::getFactoryId, SecurityUtils.getLoginUser().getOrgId());
        }
        if (SourceType.STORE.getCode().equals(SecurityUtils.getLoginUser().getSourceType())) {
            queryWrapper.eq(OrderCloth::getOrgId, SecurityUtils.getLoginUser().getOrgId());
        }
        if (StringUtils.isNotEmpty(orderClothCountConsumeQueryDTO.getOrderNo())) {
            queryWrapper.like(OrderCloth::getOrderNo, orderClothCountConsumeQueryDTO.getOrderNo());
        }
        if (orderClothCountConsumeQueryDTO.getUserId() != null) {
            queryWrapper.eq(OrderCloth::getAppUserId, orderClothCountConsumeQueryDTO.getUserId());
        }
        if (StringUtils.isNotEmpty(orderClothCountConsumeQueryDTO.getPhoneNumber())) {
            AppUser appUser = appUserService.getOne(new QueryWrapper<AppUser>().lambda()
                    .eq(AppUser::getPhoneNumber, orderClothCountConsumeQueryDTO.getPhoneNumber()));
            if (appUser == null) {
                return R.ok(new OrderClothCountConsumeQueryVO());
            }
            queryWrapper.eq(OrderCloth::getAppUserId, appUser.getId());
        }
        queryWrapper.orderByDesc(BaseEntity::getCreateTime);
        Page<OrderCloth> pageOrderCloth = orderClothService.page(new Page<>(orderClothCountConsumeQueryDTO.getPageNum()
                        , orderClothCountConsumeQueryDTO.getPageSize())
                , queryWrapper);
        List<OrderCloth> records = pageOrderCloth.getRecords();
        if (CollUtil.isEmpty(records)) {
            return R.ok(new OrderClothCountConsumeQueryVO());
        }
        OrderClothCountConsumeQueryVO orderClothCountConsumeQueryVO = new OrderClothCountConsumeQueryVO();
        orderClothCountConsumeQueryVO.setTotal(pageOrderCloth.getTotal());
        // 列表
        List<OrderClothCountConsumeVO> consumeVOS = new ArrayList<>();
        for (OrderCloth record : records) {
            OrderClothCountConsumeVO orderClothCountConsumeVO = new OrderClothCountConsumeVO();
            BeanUtils.copyProperties(record, orderClothCountConsumeVO);
            consumeVOS.add(orderClothCountConsumeVO);
        }
        List<AppUser> appUsers = appUserService.list(new QueryWrapper<AppUser>().lambda()
                .in(AppUser::getId, consumeVOS.stream().map(OrderClothCountConsumeVO::getAppUserId).collect(Collectors.toSet())));
        Map<Long, AppUser> appUserMap = appUsers.stream().collect(Collectors.toMap(AppUser::getId, AppUser -> AppUser));
        for (OrderClothCountConsumeVO consumeVO : consumeVOS) {
            consumeVO.setUserName(appUserMap.get(consumeVO.getAppUserId()) != null ? appUserMap.get(consumeVO.getAppUserId()).getRealName() : null);
            consumeVO.setPhoneNumber(appUserMap.get(consumeVO.getAppUserId()) != null ? appUserMap.get(consumeVO.getAppUserId()).getPhoneNumber() : null);
            if (consumeVO.getEmployeeId() != null) {
                consumeVO.setEmployeeName(appUserMap.get(consumeVO.getEmployeeId()) != null ? appUserMap.get(consumeVO.getEmployeeId()).getRealName() : null);
            }
//            if (SysBoolType.NO.getCode().equals(consumeVO.getHasPay())){
//                consumeVO.setPayAmount(BigDecimal.ZERO);
//            }
        }
        orderClothCountConsumeQueryVO.setOrderClothCountConsumeVOList(consumeVOS);

        // 相同条件下，查所有订单，并进行统计
        List<OrderCloth> allOrderCloths = orderClothService.list(queryWrapper);
        // 总计应付
        BigDecimal totalWillMoney = allOrderCloths.stream().map(OrderCloth::getPayAmount).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);

        // 累计衣物件数
        Integer totalOrderClothCount = allOrderCloths.stream().map(OrderCloth::getOrderClothCount).filter(Objects::nonNull).reduce(0, Integer::sum);
        orderClothCountConsumeQueryVO.setTotalOrderClothCount(totalOrderClothCount);
        orderClothCountConsumeQueryVO.setTotalAlreadyMoney(BigDecimal.ZERO);
        orderClothCountConsumeQueryVO.setTotalWillMoney(totalWillMoney);
        return R.ok(orderClothCountConsumeQueryVO);
    }

    /**
     * 门店财务统计-支付宝微信统计
     */
    @PreAuthorize("@ss.hasPermi('order:managePay:list')")
    @PostMapping(value = "/listFinancialStatisticsByOnlinePay")
    @ApiOperation(value = "财务统计-支付宝微信统计")
    public R<Page<OrderFinancialOnlinePayQueryVO>> listFinancialStatisticsByOnlinePay(@RequestBody OrderFinancialOnlinePayQueryDTO orderFinancialOnlinePayQueryDTO) {
        LambdaQueryWrapper<AppUserBillMstr> queryWrapper = new QueryWrapper<AppUserBillMstr>().lambda();
        queryWrapper.in(AppUserBillMstr::getPayType, PayType.WECHAT.getCode(), PayType.ALIPAY.getCode());
        if (orderFinancialOnlinePayQueryDTO.getBeginCreateTime() != null && orderFinancialOnlinePayQueryDTO.getEndCreateTime() != null) {
            queryWrapper.ge(BaseEntity::getCreateTime, orderFinancialOnlinePayQueryDTO.getBeginCreateTime());
            queryWrapper.lt(BaseEntity::getCreateTime, DateUtils.addDays(orderFinancialOnlinePayQueryDTO.getEndCreateTime(), 1));
        }
        if (!SourceType.MANAGER.getCode().equals(SecurityUtils.getLoginUser().getSourceType())) {
            queryWrapper.eq(AppUserBillMstr::getSourceType, SecurityUtils.getLoginUser().getSourceType());
            queryWrapper.eq(AppUserBillMstr::getOrgId, SecurityUtils.getLoginUser().getOrgId());
        }
        if (StringUtils.isNotEmpty(orderFinancialOnlinePayQueryDTO.getPayType())) {
            queryWrapper.eq(AppUserBillMstr::getPayType, orderFinancialOnlinePayQueryDTO.getPayType());
        }
        queryWrapper.orderByDesc(BaseEntity::getCreateTime);
        Page<AppUserBillMstr> pageOrderCloth = appUserBillMstrService.page(new Page<>(orderFinancialOnlinePayQueryDTO.getPageNum()
                        , orderFinancialOnlinePayQueryDTO.getPageSize())
                , queryWrapper);
        Page<OrderFinancialOnlinePayQueryVO> page = new Page<>();
        page.setTotal(pageOrderCloth.getTotal());
        if (CollUtil.isEmpty(pageOrderCloth.getRecords())) {
            page.setRecords(new ArrayList<>());
            return R.ok(page);
        }
        List<OrderFinancialOnlinePayQueryVO> list = new ArrayList<>();
        for (AppUserBillMstr record : pageOrderCloth.getRecords()) {
            OrderFinancialOnlinePayQueryVO orderFinancialOnlinePayQueryVO = new OrderFinancialOnlinePayQueryVO();
            BeanUtils.copyProperties(record, orderFinancialOnlinePayQueryVO);
            list.add(orderFinancialOnlinePayQueryVO);
        }
        page.setRecords(list);
        return R.ok(page);
    }


    /**
     * 工厂财务统计-经营日报-今日统计
     */
    @PreAuthorize("@ss.hasPermi('order:factoryManageDay:list')")
    @GetMapping(value = "/countFinancialStatisticsByFactoryWithToday")
    @ApiOperation(value = "工厂财务统计-经营日报-今日统计")
    public R<FactoryFinancialClothDayCountVO> countFinancialStatisticsByFactoryWithToday() {
        if (!SourceType.FACTORY.getCode().equals(SecurityUtils.getLoginUser().getSourceType())) {
            throw new ServiceException("非工厂机构，无权限查询工厂财务统计");
        }
        FactoryFinancialClothDayCountVO factoryFinancialClothDayCountVO = new FactoryFinancialClothDayCountVO();
        // 设置 统计时间
        factoryFinancialClothDayCountVO.setCountTime(DateUtils.getNowDate());

        LambdaQueryWrapper<OrderClothItem> queryWrapper = new QueryWrapper<OrderClothItem>().lambda()
                .eq(OrderClothItem::getFactoryId, SecurityUtils.getLoginUser().getOrgId())
                .ne(OrderClothItem::getFlowStatus, ClothOrderFlowStatus.refund.getCode());
        Date nowDate = DateUtils.getNowDate(DateUtils.YYYY_MM_DD);

        LambdaQueryWrapper<OrderClothItem> inQW = new LambdaQueryWrapper<>();
        BeanUtils.copyProperties(queryWrapper, inQW);
        inQW.ge(OrderClothItem::getInFactoryTime, nowDate);
        inQW.lt(OrderClothItem::getInFactoryTime, DateUtils.addDays(nowDate, 1));
        List<OrderClothItem> inOrderClothItemList = orderClothItemService.list(inQW);
        if (CollUtil.isNotEmpty(inOrderClothItemList)) {
            // 设置 入厂件数
            factoryFinancialClothDayCountVO.setCountClothIn(inOrderClothItemList.size());
        }
        LambdaQueryWrapper<OrderClothItem> outQW = new LambdaQueryWrapper<>();
        BeanUtils.copyProperties(queryWrapper, outQW);
        outQW.ge(OrderClothItem::getOutFactoryTime, nowDate);
        outQW.lt(OrderClothItem::getOutFactoryTime, DateUtils.addDays(nowDate, 1));
        List<OrderClothItem> outOrderClothItemList = orderClothItemService.list(outQW);
        if (CollUtil.isEmpty(outOrderClothItemList)) {
            return R.ok(factoryFinancialClothDayCountVO);
        }
        // 设置 出厂件数
        factoryFinancialClothDayCountVO.setCountClothOut(outOrderClothItemList.size());
        return R.ok(factoryFinancialClothDayCountVO);
    }

    /**
     * 工厂财务统计-经营日报-列表查询
     */
    @PreAuthorize("@ss.hasPermi('order:factoryManageDay:list')")
    @PostMapping(value = "/listFinancialStatisticsByFactoryWithToday")
    @ApiOperation(value = "工厂财务统计-经营日报-列表查询")
    public R<List<FactoryFinancialClothDayVO>> listFinancialStatisticsByFactoryWithToday(@RequestBody FactoryOrderFinancialDayQueryDTO factoryOrderFinancialDayQueryDTO) {
        if (!SourceType.FACTORY.getCode().equals(SecurityUtils.getLoginUser().getSourceType())) {
            throw new ServiceException("非工厂机构，无权限查询工厂财务统计");
        }
        if (factoryOrderFinancialDayQueryDTO.getBeginCreateTimeToInFactory() != null && factoryOrderFinancialDayQueryDTO.getEndCreateTimeToInFactory() != null) {
            if (DateUtils.addMonths(DateUtils.strToDate(factoryOrderFinancialDayQueryDTO.getBeginCreateTimeToInFactory()), 3)
                    .compareTo(DateUtils.strToDate(factoryOrderFinancialDayQueryDTO.getEndCreateTimeToInFactory())) < 0) {
                throw new ServiceException("入厂时间查询最大范围3个月的数据");
            }
            if (DateUtils.addYears(DateUtils.strToDate(factoryOrderFinancialDayQueryDTO.getBeginCreateTimeToInFactory()), 1)
                    .compareTo(DateUtils.getNowDate()) < 0) {
                throw new ServiceException("只能查询1年内的数据");
            }
        }
        return R.ok(orderClothItemService.listFinancialStatisticsByFactoryWithToday(factoryOrderFinancialDayQueryDTO));
    }


    /**
     * 工厂财务统计-经营统计
     */
    @PreAuthorize("@ss.hasPermi('order:factoryManageCount:list')")
    @PostMapping(value = "/countFinancialStatisticsByFactoryOperate")
    @ApiOperation(value = "工厂财务统计-经营统计")
    public R<FactoryStatisticsQueryVO> countFinancialStatisticsByFactoryOperate(@RequestBody FactoryStatisticsQueryDTO factoryStatisticsQueryDTO) {
        if (!SourceType.FACTORY.getCode().equals(SecurityUtils.getLoginUser().getSourceType())) {
            throw new ServiceException("非工厂机构，无权限查询工厂财务统计");
        }
        if (factoryStatisticsQueryDTO.getBeginCreateTime() != null && factoryStatisticsQueryDTO.getEndCreateTime() != null) {
            if (DateUtils.addMonths(DateUtils.strToDate(factoryStatisticsQueryDTO.getBeginCreateTime()), 3)
                    .compareTo(DateUtils.strToDate(factoryStatisticsQueryDTO.getEndCreateTime())) < 0) {
                throw new ServiceException("入厂时间查询最大范围3个月的数据");
            }
            if (DateUtils.addYears(DateUtils.strToDate(factoryStatisticsQueryDTO.getBeginCreateTime()), 1)
                    .compareTo(DateUtils.getNowDate()) < 0) {
                throw new ServiceException("只能查询1年内的数据");
            }
        }
        FactoryStatisticsQueryVO factoryStatisticsQueryVO = new FactoryStatisticsQueryVO();
        List<FactoryStatisticsListQueryVO> factoryStatisticsListQueryVOList = orderClothItemService.listFinancialStatisticsByFactoryOperate(factoryStatisticsQueryDTO);
        if (CollUtil.isEmpty(factoryStatisticsListQueryVOList)) {
            return R.ok(factoryStatisticsQueryVO);
        }
        int totalCloth = 0;
        BigDecimal totalStatementPrice = BigDecimal.ZERO;
        for (FactoryStatisticsListQueryVO vo : factoryStatisticsListQueryVOList) {
            totalCloth = totalCloth + vo.getCountTotalCloth();
            totalStatementPrice = totalStatementPrice.add(vo.getTotalStatementPrice());
        }
        factoryStatisticsQueryVO.setFactoryStatisticsListQueryVOList(factoryStatisticsListQueryVOList);
        // 设置顶部统计 - 衣物总数量
        factoryStatisticsQueryVO.setTotalCloth(totalCloth);
        // 设置顶部统计 - 结算总金额
        factoryStatisticsQueryVO.setTotalStatementPrice(totalStatementPrice);
        return R.ok(factoryStatisticsQueryVO);
    }

    /**
     * 工厂财务统计-经营明细
     */
    @PreAuthorize("@ss.hasPermi('order:factoryManageDetail:list')")
    @PostMapping(value = "/countFinancialStatisticsByFactoryOperateDetail")
    @ApiOperation(value = "工厂财务统计-经营明细")
    public R<Page<FactoryStatisticsDetailQueryVO>> countFinancialStatisticsByFactoryOperateDetail(@RequestBody FactoryStatisticsDetailQueryDTO factoryStatisticsDetailQueryDTO) {
        if (!SourceType.FACTORY.getCode().equals(SecurityUtils.getLoginUser().getSourceType())) {
            throw new ServiceException("非工厂机构，无权限查询工厂财务统计");
        }
        Page<FactoryStatisticsDetailQueryVO> page = new Page<>();
        List<FactoryStatisticsDetailQueryVO> factoryOperateDetailList = orderClothItemService.listFinancialStatisticsByFactoryOperateDetail(factoryStatisticsDetailQueryDTO);
        if (CollUtil.isEmpty(factoryOperateDetailList)) {
            return R.ok(page);
        }
        page.setRecords(factoryOperateDetailList);
        int count = orderClothItemService.countFinancialStatisticsByFactoryOperateDetail(factoryStatisticsDetailQueryDTO);
        page.setTotal(count);
        return R.ok(page);
    }

    @ApiOperation("计算配送费金额")
    @GetMapping(value = "/calculateDeliveryPirce")
    public R<Map> calculateDeliveryPirce(Long orderId, String sendWay) throws Exception {
        Map<String, Object> maps = orderClothService.calculateDeliveryFee(orderId, sendWay);
        return R.ok(maps);
    }

    public Map<Long, BigDecimal> getRateMap(Set<Long> orgList) {
        // 查询门店的工厂费率,未设置，就用默认的费率
        Map<Long, BigDecimal> orgRateMap = new HashMap<>();
        List<SysSettlementRate> settlementRateList = sysSettlementRateService.list(new QueryWrapper<SysSettlementRate>().lambda()
                .in(SysSettlementRate::getOrgId, orgList)
                .in(SysSettlementRate::getSourceType, SourceType.STORE.getCode()));
        if (CollUtil.isNotEmpty(settlementRateList)) {
            orgRateMap = settlementRateList.stream().collect(Collectors.toMap(SysSettlementRate::getOrgId, SysSettlementRate::getFactoryRate));
        }
        return orgRateMap;
    }
}
