package com.yc.ship.module.trade.controller.admin.order;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.yc.ship.framework.common.pojo.CommonResult;
import com.yc.ship.framework.common.pojo.PageResult;
import com.yc.ship.framework.common.util.collection.CollectionUtils;
import com.yc.ship.framework.common.util.collection.MapUtils;
import com.yc.ship.framework.common.util.object.BeanUtils;
import com.yc.ship.framework.ip.core.utils.AreaUtils;
import com.yc.ship.framework.operatelog.core.annotations.OperateLog;
import com.yc.ship.framework.security.core.LoginUser;
import com.yc.ship.module.product.api.dto.CategoryRespDTO;
import com.yc.ship.module.product.api.dto.ProductSpuRespDTO;
import com.yc.ship.module.product.controller.admin.voyage.vo.VoyageRespVO;
import com.yc.ship.module.product.dal.dataobject.voyage.VoyageDO;
import com.yc.ship.module.product.service.voyage.VoyageService;
import com.yc.ship.module.resource.api.ship.ShipApi;
import com.yc.ship.module.resource.api.ship.dto.ShipRespDTO;
import com.yc.ship.module.trade.api.contract.dto.group.WindowCreateOrderGroup;
import com.yc.ship.module.trade.controller.admin.order.vo.order.*;
import com.yc.ship.module.trade.controller.admin.order.vo.otc.PrintRespVO;
import com.yc.ship.module.trade.controller.admin.order.vo.refund.*;
import com.yc.ship.module.trade.controller.app.otc.vo.AppTradeOrderPageReqVO;
import com.yc.ship.module.trade.controller.app.otc.vo.AppTradeOrderRespVO;
import com.yc.ship.module.trade.dal.dataobject.contract.ContractDO;
import com.yc.ship.module.trade.dal.dataobject.insurance.InsuranceDO;
import com.yc.ship.module.trade.dal.dataobject.order.TradeDetailBaseDO;
import com.yc.ship.module.trade.dal.dataobject.order.TradeOrderCountryDO;
import com.yc.ship.module.trade.dal.dataobject.order.TradeOrderRoomModelDO;
import com.yc.ship.module.trade.dal.dataobject.order.TradeOrderTotalDO;
import com.yc.ship.module.trade.framework.annotation.PlatTenantEnv;
import com.yc.ship.module.trade.framework.annotation.RequestDecryption;
import com.yc.ship.module.trade.framework.annotation.TradeRateLimit;
import com.yc.ship.module.trade.service.order.*;
import com.yc.ship.module.trade.service.otc.AppOtcTradeOrderService;
import com.yc.ship.module.trade.service.otc.OtcTradeOrderService;
import com.yc.ship.module.trade.service.pay.TradeOrderPayService;
import com.yc.ship.module.trade.utils.AgencyAuthUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import static com.yc.ship.framework.common.pojo.CommonResult.success;
import static com.yc.ship.framework.operatelog.core.enums.OperateTypeEnum.*;


/***
 *&#064;Description  旅行社交易服务
 *@author qsl
 *&#064;date  2025/8/13 17:14
 */
@Validated
@RestController
@Slf4j
@RequestMapping("/travl/trade")
@Tag(name = "旅行社交易服务")
public class OtcTradeOrderController {

    @Resource
    private OtcTradeOrderService otcTradeOrderService;
    @Resource
    private AdminTradeOrderService adminTradeOrderService;
    @Resource
    private AgencyAuthUtils agencyAuthUtils;
    @Resource
    private AppOtcTradeOrderService appOtcTradeOrderService;

    @Resource
    private TradeOrderService tradeOrderService;

    @Resource
    private TradeOrderTotalService tradeOrderTotalService;

    @Resource
    private TradeOrderCountryService tradeOrderCountryService;

    @Resource
    private VoyageService voyageService;

    @Resource
    private ShipApi shipApi;

    @Resource
    private TradeOrderPayService tradeOrderPayService;

    @Resource
    private TradeOrderRoomModelService tradeOrderRoomModelService;

    @RequestDecryption
    @PostMapping("/travl/createOtcOrder")
    @Operation(summary = "win-旅行社游船订单创建")
    @OperateLog(type = TRADE)
    @TradeRateLimit(name = "createOtcOrder", limitNum = 2, limitTime = 5)
    public CommonResult<?> createOtcOrder(@Validated(value = WindowCreateOrderGroup.class) @RequestBody TradeOrderOtcCreateVO createVO) {
        return otcTradeOrderService.createOtcOrder(agencyAuthUtils.getAgencyLoginUser(), createVO);
    }

    @RequestDecryption
    @PostMapping("/travl/createMoveOrder")
    @Operation(summary = "win-旅行社游船订单搬单创建")
    @OperateLog(type = TRADE)
    public CommonResult<?> createMoveOrder(@Validated(value = WindowCreateOrderGroup.class) @RequestBody TradeOrderOtcCreateVO createVO) {
        createVO.setMoveOrder(true);
        return otcTradeOrderService.createOtcOrder(agencyAuthUtils.getAgencyLoginUser(), createVO);
    }

    @RequestDecryption
    @GetMapping("/travl/getOrderById")
    @Operation(summary = "win-旅行社游船订单获取")
    @OperateLog(type = TRADE)
    public CommonResult<?> getOrderById(@RequestParam Long orderId) {
        return otcTradeOrderService.getOrderById(orderId);
    }

    @GetMapping("/travl/getRole")
    @Operation(summary = "win-旅行社游船订单获取")
    @OperateLog(type = TRADE)
    public CommonResult<?> getRole() {
        LoginUser agencyLoginUser = agencyAuthUtils.getAgencyLoginUser();
        if (agencyLoginUser != null && agencyLoginUser.getDistributorId() != null) {
            return success(1);
        }
        return success(2);
    }


    @RequestDecryption
    @PostMapping("/travl/motifyOtcOrder")
    @Operation(summary = "win-旅行社游船订单修改")
    @OperateLog(type = TRADE)
    public CommonResult<?> motifyOtcOrder(@Validated(value = WindowCreateOrderGroup.class) @RequestBody TradeOrderOtcCreateVO createVO) {
        return otcTradeOrderService.motifyOtcOrder(agencyAuthUtils.getAgencyLoginUser(), createVO);
    }

    @RequestDecryption
    @PostMapping("/travl/createOtcFisrtOrder")
    @Operation(summary = "win-旅行社游船订单创建-预定单")
    @OperateLog(type = TRADE)
    @TradeRateLimit(name = "createOtcFisrtOrder", limitNum = 2, limitTime = 5)
    public CommonResult<?> createOtcFisrtOrder(@Validated(value = WindowCreateOrderGroup.class) @RequestBody TradeOrderOtcCreateVO createVO) {
        createVO.setIsYd(1);
        return otcTradeOrderService.createOtcOrder(agencyAuthUtils.getAgencyLoginUser(), createVO);
    }

    @RequestDecryption
    @PostMapping("/travl/payOrder")
    @Operation(summary = "win-旅行社下单支付订单")
    @OperateLog(type = TRADE)
    public CommonResult<PayOrderRespVO> windowPayOrder(@Valid @RequestBody PayOrderReqVO payOrderReqVO) {
        log.error("windowPayOrder:{}", JSON.toJSONString(payOrderReqVO));
        return otcTradeOrderService.windowPayOrder(agencyAuthUtils.getAgencyLoginUser(), payOrderReqVO);
    }

    @GetMapping("/travl/queryOrderStatus")
    @Operation(summary = "win-查询订单状态")
    @OperateLog(type = API)
    @PlatTenantEnv
    public CommonResult<?> queryOrderStatus(@RequestParam Long orderId) {
        return otcTradeOrderService.queryOrderStatus(orderId);
    }

    @GetMapping("/travl/queryOrderAudit")
    @Operation(summary = "win-查询订单审核信息")
    @OperateLog(type = API)
    @PlatTenantEnv
    public CommonResult<?> queryOrderAudit(@RequestParam Long orderId) {
        return otcTradeOrderService.queryOrderAudit(orderId);
    }

    @GetMapping("/travl/orderAudit")
    @Operation(summary = "win-订单审核")
    @OperateLog(type = API)
    @PlatTenantEnv
    public CommonResult<?> orderAudit(@RequestParam Long orderId, @RequestParam Integer auditStatus) {
        return otcTradeOrderService.orderAudit(orderId, auditStatus);
    }

    @GetMapping("/payOrderQuery")
    @Operation(summary = "支付反查，0待支付(轮询) 1已支付 2未支付 8888已支付等待结果(轮询) ")
    @OperateLog(type = TRADE)
    @PlatTenantEnv
    public CommonResult<?> payOrderQuery(@RequestParam Long payOrderId) {
        return tradeOrderPayService.payOrderQuery(payOrderId);
    }

    @GetMapping("/orderRead")
    @Operation(summary = "订单审阅")
    @OperateLog(type = TRADE)
    @PlatTenantEnv
    public CommonResult<?> orderRead(@RequestParam Long orderId) {
        return otcTradeOrderService.orderRead(orderId);
    }

    @PostMapping("/window/orderList")
    @OperateLog(type = API)
    @Operation(summary = "win-平台订单列表[分页]", description = "根据条件查询订单列表")
    @PlatTenantEnv
    public CommonResult<PageResult<TradeOrderRespNewVO>> getTradeOrderPage(@Valid @RequestBody TradeOrderPageReqVO pageReqVO) {
        PageResult<TradeOrderRespVO> platOrderPage = tradeOrderService.getPlatOrderPage(pageReqVO);
        PageResult<TradeOrderRespNewVO> page = BeanUtils.toBean(platOrderPage, TradeOrderRespNewVO.class);
        List<TradeOrderRespNewVO> list = page.getList();
        //处理游轮名称
        List<Long> shipIds = CollectionUtils.convertList(list, TradeOrderRespNewVO::getShipId);
        Map<Long, ShipRespDTO> shipMap = shipApi.queryShip(shipIds);

        //国籍数据
        List<Long> orderIds = CollectionUtils.convertList(list, TradeOrderRespNewVO::getId);
        List<TradeOrderCountryDO> countryList = tradeOrderCountryService.getListByOrderIds(orderIds);
        List<TradeOrderRoomModelDO> roomModelList = tradeOrderRoomModelService.getListByOrderIds(orderIds);
        List<TradeOrderCountryBaseVO> countRespVOList = BeanUtils.toBean(countryList, TradeOrderCountryBaseVO.class);
        List<TradeOrderRoomModelVO> roomModeVOList = BeanUtils.toBean(roomModelList, TradeOrderRoomModelVO.class);
        countRespVOList.forEach(item -> {
            if (item.getCountryId() != null) {
                item.setCountryName(AreaUtils.format2Str(item.getCountryId()));
            }
        });
        Map<Long, List<TradeOrderCountryBaseVO>> countryMap = CollectionUtils.convertMultiMap(countRespVOList, TradeOrderCountryBaseVO::getOrderId);
        Map<Long, List<TradeOrderRoomModelVO>> roomModelMap = CollectionUtils.convertMultiMap(roomModeVOList, TradeOrderRoomModelVO::getOrderId);

        //订单汇总数据
        List<TradeOrderTotalDO> tradeOrderTotalDOList = tradeOrderTotalService.getByOrderIds(orderIds);
        List<TradeOrderTotalVO> tradeOrderTotalVOList = BeanUtils.toBean(tradeOrderTotalDOList, TradeOrderTotalVO.class);
        Map<Long, TradeOrderTotalVO> orderTotalVoMap = CollectionUtils.convertMap(tradeOrderTotalVOList, TradeOrderTotalVO::getOldOrderId);

        //航次信息
        List<Long> voyageIds = CollectionUtils.convertList(list, TradeOrderRespNewVO::getVoyageId);
        List<VoyageDO> voyageList = voyageService.getList(voyageIds);
        List<VoyageRespVO> voyageRespVOList = BeanUtils.toBean(voyageList, VoyageRespVO.class);
        Map<Long, VoyageRespVO> voyageRespVoMap = CollectionUtils.convertMap(voyageRespVOList, VoyageRespVO::getId);

        if (!list.isEmpty()) {
            list.forEach(item -> {
                MapUtils.findAndThen(shipMap, item.getShipId(), ship -> item.setShipName(ship.getName()));
                MapUtils.findAndThen(countryMap, item.getId(), item::setCountryList);
                MapUtils.findAndThen(roomModelMap, item.getId(), item::setRoomModelList);
                MapUtils.findAndThen(orderTotalVoMap, item.getId(), totalVO -> {
                    item.setSummary(totalVO);
                    item.setPersonStat(totalVO.getAdultTotalNum() + "大" + (totalVO.getChildTotalNum() + totalVO.getBabyTotalNum()) + "小");
                });
                MapUtils.findAndThen(voyageRespVoMap, item.getVoyageId(), item::setVoyage);
                if (item.getVisitors() != null && !item.getVisitors().isEmpty()) {
                    item.setTotalPerson(item.getVisitors().size());
                } else {
                    item.setTotalPerson(0);
                }

                Map<String, List<TradeOrderRoomModelVO>> roomDesc = item.getRoomModelList().stream().collect(Collectors.groupingBy(p -> p.getRoomModelName() + "(" + p.getFloor() + "F)"));
                AtomicReference<String> roomDescStr = new AtomicReference<>("");
                roomDesc.forEach((key, value) -> roomDescStr.set(roomDescStr.get() + " " + value.size() + "*" + key));
                item.setRoomModelDetails(roomDescStr.get().trim());
            });
        }
        return success(page);
    }

    @PostMapping("/window/getOrderCount")
    @OperateLog(type = API)
    @Operation(summary = "win-平台订单列表[分页]", description = "根据条件查询订单列表")
    @PlatTenantEnv
    public CommonResult<?> getOrderCount(@Valid @RequestBody TradeOrderPageReqVO pageReqVO) {
        String totalDesc = tradeOrderService.getOrderCount(pageReqVO);
        return success(totalDesc);
    }


    @PostMapping("/window/paidOrderList")
    @Operation(summary = "win-已支付订单列表[分页]", description = "根据条件查询订单列表")
    @OperateLog(type = API)
    public CommonResult<PageResult<TradeOrderRespVO>> getPaidOrderList(@Valid @RequestBody TradeOrderPageReqVO pageReqVO) {
        return success(otcTradeOrderService.getPaidOrderPage(pageReqVO));
    }


    @GetMapping("/window/orderInfo")
    @OperateLog(type = API)
    @Operation(summary = "win-订单详情", description = "根据订单id查询订单详情")
    @PlatTenantEnv
    public CommonResult<TradeOrderRespVO> getOrderInfo(@Valid @RequestParam("id") Long id) {
        return success(otcTradeOrderService.getOrderInfo(id));
    }

    @GetMapping("/window/orderInfoNew")
    @OperateLog(type = API)
    @Operation(summary = "win-订单详情", description = "根据订单id查询订单详情")
    @PlatTenantEnv
    public CommonResult<TradeOrderRespNewVO> getOrderInfoNew(@Valid @RequestParam("id") Long id) {
        return success(otcTradeOrderService.getOrderInfoNew(id));
    }

    @GetMapping("/window/orderConfirmation")
    @OperateLog(type = API)
    @Operation(summary = "win-订单确认单", description = "根据订单id查询订单确认单")
    @PlatTenantEnv
    public CommonResult<TradeOrderConfirmationVO> getOrderConfirmation(@Valid @RequestParam("id") Long id) {
        return success(otcTradeOrderService.getOrderConfirmation(id));
    }

    @PostMapping("/travl/refund")
    @Operation(summary = "win-旅行社退款")
    @OperateLog(type = TRADE)
    public CommonResult<TradeRefundCreateRespVO> windowRefund(@Valid @RequestBody TradeRefundCreateReqVO refundCreateReqVO) {
        return adminTradeOrderService.refund(agencyAuthUtils.getAgencyLoginUser(), refundCreateReqVO);
    }

    @PostMapping("/refund/calculateRefundAmount")
    @Operation(summary = "退款计算")
    @OperateLog(type = API)
    @PlatTenantEnv
    public CommonResult<TradeRefundCalculateRespVO> calculateRefundAmount(@Valid @RequestBody TradeRefundCreateReqVO refundCreateReqVO) {
        return adminTradeOrderService.calculateRefundAmount(agencyAuthUtils.getAgencyLoginUser(), refundCreateReqVO);
    }

    @PostMapping("/cancelRefund")
    @Operation(summary = "取消退款，只能取消退款中，且供应商退款失败的")
    @OperateLog(type = API)
    @PlatTenantEnv
    public CommonResult<?> cancelRefund(@RequestParam("refundId") Long refundId) {
        return adminTradeOrderService.cancelRefund(refundId);
    }

    @GetMapping("/cancelOrder")
    @Operation(summary = "取消订单，只能取消预定、确定没有付款的订单")
    @OperateLog(type = API)
    @PlatTenantEnv
    public CommonResult<?> cancelOrder(@Valid @RequestParam("id") Long id) {
        return adminTradeOrderService.cancelOrder(id);
    }

    @GetMapping("/cancelAuto")
    @Operation(summary = "审核撤回订单")
    @OperateLog(type = API)
    @PlatTenantEnv
    public CommonResult<?> cancelAuto(@Valid @RequestParam("id") Long id) {
        return otcTradeOrderService.cancelAuto(id);
    }

    @PostMapping("/refund/refundOrderList")
    @Operation(summary = "退单列表", description = "根据条件查询退单列表")
    @OperateLog(type = API)
    @PlatTenantEnv
    public CommonResult<PageResult<RefundRespVO>> getRefundRecordPage(@Valid @RequestBody RefundPageReqVO pageReqVO) {
        return success(otcTradeOrderService.getRefundRecordPage(pageReqVO));
    }

    @RequestDecryption
    @PostMapping("/refundAudit")
    @Operation(summary = "退款审核")
    @OperateLog(type = API)
    public CommonResult<?> refundAudit(@Valid @RequestBody TradeRefundAuditReqVO refundAuditReqVO) {
        return adminTradeOrderService.refundAudit(agencyAuthUtils.getAgencyLoginUser(), refundAuditReqVO);
    }

    @GetMapping("/refund/refundDetailList")
    @Operation(summary = "退单批次详情", description = "根据退单id查询退单批次详情")
    @OperateLog(type = API)
    @PlatTenantEnv
    public CommonResult<List<RefundDetailRespVO>> getRefundBatchDetails(@Valid @RequestParam("id") Long id) {
        return success(otcTradeOrderService.getRefundBatchDetails(id));
    }


    @GetMapping("/refund/refundRecordList")
    @Operation(summary = "退款记录[分页]", description = "根据条件查询退款记录")
    @OperateLog(type = API)
    @PlatTenantEnv
    public CommonResult<PageResult<RefundRecordRespVO>> getPageRefundRecord(@Valid RefundRecordPageReqVO pageReqVO) {
        return success(otcTradeOrderService.getPageRefundRecord(pageReqVO));
    }

    /**
     * 退款记录如果长时间处于退款中，可以向支付平台反查
     */
    @GetMapping("/refundQuery")
    @Operation(summary = "退款中-退款查询(向支付平台)")
    @OperateLog(type = API)
    public CommonResult<?> refundQuery(@Valid Long refundRecordId) {
        return adminTradeOrderService.refundQuery(refundRecordId);
    }

    @PostMapping("/refundByRecord")
    @Operation(summary = "根据退款记录再发发起退款")
    @OperateLog(type = API)
    public CommonResult<?> refundByRecord(Long refundRecordId) {
        return adminTradeOrderService.refundByRecord(agencyAuthUtils.getAgencyLoginUser(), refundRecordId);
    }

    /**
     * 退款单如果处于长时间处于等待退款（因mq消息失败了）、或者供应商退款失败。可手动发起退款给游客
     */
    @PostMapping("/manualRefund")
    @Operation(summary = "人工退款")
    @OperateLog(type = API)
    public CommonResult<?> manualRefund(Long refundId) {

        return adminTradeOrderService.manualRefund(agencyAuthUtils.getAgencyLoginUser(), refundId);
    }

    @GetMapping("/window/orderDetailInfo")
    @Operation(summary = "win-门票详情", description = "根据订单id查询门票详情")
    @OperateLog(type = API)
    @PlatTenantEnv
    public CommonResult<List<TradeDetailBaseDO>> getDetailInfo(@Valid @RequestParam("id") Long id) {
        return success(otcTradeOrderService.getDetailInfo(id));
    }

    @PostMapping("/payOuterOrder")
    @Operation(summary = "外部订单支付")
    @OperateLog(type = TRADE)
    public CommonResult<PayOrderRespVO> payOuterOrder(@Valid @RequestBody PayOrderReqVO payOrderReqVO) {
        return tradeOrderPayService.payOuterOrder(payOrderReqVO);
    }

    @GetMapping("/categoryOrSpu")
    @Operation(summary = "sell-产品分组和产品数据")
    @OperateLog(type = API)
    public CommonResult<List<CategoryRespDTO>> categoryOrSpu(String type, String travelDate) {
        return success(otcTradeOrderService.getCategoryOrSpuList(type, travelDate));
    }

    @GetMapping("/categoryAndSpuAll")
    @Operation(summary = "sell-产品分组和产品数据")
    @OperateLog(type = API)
    public CommonResult<List<CategoryRespDTO>> categoryAndSpuAll(String type, String travelDate) {
        return success(otcTradeOrderService.getCategoryAndSpuAll(type, travelDate));
    }


    @GetMapping("/productSupInfo")
    @Operation(summary = "sell-产品详情")
    @OperateLog(type = API)
    public CommonResult<ProductSpuRespDTO> productSpu(@Valid @RequestParam("id") Long id, @RequestParam("date") String date, @RequestParam(value = "planId", required = false) String planId) {
        //查看日期是否存在
        if (date.isEmpty()) {
            date = DateUtil.format(new Date(), DatePattern.NORM_DATE_PATTERN);
        }
        return success(otcTradeOrderService.getProductSpuDTO(id, date, planId));
    }

    @GetMapping("/plat/productSupInfo")
    @Operation(summary = "sell-产品详情")
    @OperateLog(type = API)
    public CommonResult<ProductSpuRespDTO> platProductSpu(@Valid @RequestParam("id") Long id, @RequestParam("date") String date, @RequestParam(value = "planId", required = false) String planId
            , @RequestParam("distributorId") Long distributorId) {
        //查看日期是否存在
        if (date.isEmpty()) {
            date = DateUtil.format(new Date(), DatePattern.NORM_DATE_PATTERN);
        }
        return success(otcTradeOrderService.getProductSpuDTO(id, date, planId, distributorId));
    }


    @GetMapping("/getOrderContract")
    @Operation(summary = "sell-查询保合同")
    @OperateLog(type = API)
    public CommonResult<List<ContractDO>> getContract(@Valid @RequestParam("orderId") Long orderId) {
        return success(otcTradeOrderService.getContract(orderId));
    }

    @GetMapping("/getOrderInsurance")
    @Operation(summary = "sell-查询保险")
    @OperateLog(type = API)
    public CommonResult<List<InsuranceDO>> getInsurance(@Valid @RequestParam("orderId") Long orderId) {
        return success(otcTradeOrderService.getInsurance(orderId));
    }

    @GetMapping("/orderPrintData")
    @Operation(summary = "sell-通过订单查询打印模板")
    @OperateLog(type = API)
    public CommonResult<List<PrintRespVO>> getOrderPrintData(@Valid @RequestParam("orderId") Long orderId) {
        return success(otcTradeOrderService.getOrderPrintData(orderId));
    }

    @PostMapping("/window/queryCanInvoicedOrder")
    @OperateLog(type = API)
    @Operation(summary = "win-订单列表[分页]", description = "根据条件查询可开票订单列表")
    @PlatTenantEnv
    public CommonResult<PageResult<TradeOrderRespVO>> queryCanInvoicedOrderPage(@Valid @RequestBody TradeOrderPageReqVO pageReqVO) {
        return success(otcTradeOrderService.queryCanInvoicedOrderPage(pageReqVO));
    }

    @PostMapping("/window/queryPlatCanInvoicedOrder")
    @OperateLog(type = API)
    @Operation(summary = "win-订单列表[分页]", description = "根据条件查询可开票订单列表")
    @PlatTenantEnv
    public CommonResult<PageResult<TradeOrderRespVO>> queryPlatCanInvoicedOrder(@Valid @RequestBody TradeOrderPageReqVO pageReqVO) {
        return success(otcTradeOrderService.queryPlatCanInvoicedOrder(pageReqVO));
    }

    @GetMapping("/orderRuleOrUserDetails")
    @Operation(summary = "win-订单规格和游客信息详情", description = "根据订单id查询订单规格和游客信息详情")
    @OperateLog(type = API)
    @PlatTenantEnv
    public CommonResult<TradeOrderRespVO> getOrderRuleOrUserDetails(@Valid @RequestParam("id") Long id) {
        return success(otcTradeOrderService.orderRuleOrUserDetails(id));
    }

    @PostMapping("/getOrderListByMemberId")
    @Operation(summary = "根据会员id查询订单列表[分页]", description = "根据条件查询订单列表")
    @OperateLog(type = API)
    public CommonResult<PageResult<AppTradeOrderRespVO>> getOrderListPageByMemberId(@Valid @RequestBody AppTradeOrderPageReqVO pageReqVO) {
        return appOtcTradeOrderService.miniTradeOrderPage(pageReqVO);
    }

    @GetMapping("/getPayAmount")
    @Operation(summary = "待支付时获取支付金额")
    @OperateLog(type = API)
    @PlatTenantEnv
    public CommonResult<OrderPayAmountRespVO> getPayAmount(@Valid @RequestParam("id") Long id) {
        return success(otcTradeOrderService.getPayAmount(id));
    }


    /**
     * 导出确认单
     */
    @GetMapping("/export-order-confirmation")
    @Operation(summary = "导出确认单 Excel")
    @OperateLog(type = EXPORT, enable = false)
    public void exportOrderBillExcel(Long id, Double totalMoney, HttpServletResponse response) throws IOException {
        File tempFile = otcTradeOrderService.createConfirmaction(id, totalMoney);
        response.setContentType("application/vnd.ms-excel");
        response.setHeader("Content-Disposition", "attachment; filename=" + tempFile.getName());
        InputStream is = Files.newInputStream(tempFile.toPath());
        IOUtils.copy(is, response.getOutputStream());
    }
}
