package com.gxwebsoft.shop.controller;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.gxwebsoft.cms.entity.Ad;
import com.gxwebsoft.common.core.config.ConfigProperties;
import com.gxwebsoft.common.core.exception.BusinessException;
import com.gxwebsoft.common.core.security.JwtUtil;
import com.gxwebsoft.common.core.utils.CommonUtil;
import com.gxwebsoft.common.core.utils.RedisUtil;
import com.gxwebsoft.common.core.utils.RequestUtil;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.system.entity.Area;
import com.gxwebsoft.common.system.entity.FileRecord;
import com.gxwebsoft.common.system.entity.Role;
import com.gxwebsoft.common.system.service.AreaService;
import com.gxwebsoft.shop.entity.*;
import com.gxwebsoft.shop.service.*;
import com.gxwebsoft.shop.param.OrderParam;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.shop.service.impl.KuaiDi100Impl;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.gxwebsoft.shop.consts.OrderPayType.*;

import com.wechat.pay.java.service.partnerpayments.model.TransactionAmount;

/**
 * 订单控制器
 *
 * @author 科技小王子
 * @since 2024-05-14 13:20:04
 */
@Api(tags = "订单管理")
@RestController
@RequestMapping("/api/shop/order")
public class OrderController extends BaseController {
    @Resource
    private OrderService orderService;
    @Resource
    private OrderInfoService orderInfoService;
    @Resource
    private OrderGoodsService orderGoodsService;
    @Resource
    private CartService cartService;
    @Resource
    private RequestUtil requestUtil;
    @Resource
    private ExpressService expressService;
    @Resource
    private OrderDeliveryService orderDeliveryService;
    @Resource
    private UserAddressService userAddressService;
    @Resource
    private ExpressTemplateService expressTemplateService;
    @Resource
    private UserBalanceInMerchantService userBalanceInMerchantService;
    @Resource
    private UserGoodsInMerchantService userGoodsInMerchantService;
    @Resource
    private KuaiDi100Impl kuaiDi100;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private DealerCapitalService dealerCapitalService;
    @Resource
    private AreaService areaService;
    @Resource
    private CouponService couponService;
    @Resource
    private UserCouponService userCouponService;
    @Resource
    private SelfTakeService selfTakeService;

    @Autowired
    private WeChatController weChatController;
    @Autowired
    private MerchantService merchantService;
    @Autowired
    private WxPayNotifyNbgController wxPayNotifyNbgController;

    @Value("${config.upload-path}")
    private String uploadPath;
    @Value("${config.server-url}")
    private String serverUrl;
    @Resource
    private ConfigProperties config;

    @PostMapping("/data")
    public ApiResult<?> data() {
        Map<String, Integer> data = new HashMap<>();
        int toBePaid = 0, toBeReceived = 0, toBeDelivery = 0, outtakeUserToBeDone = 0, outtakeUserToPay = 0;
        toBePaid = orderService.count(new LambdaQueryWrapper<Order>().eq(Order::getUserId, getLoginUserId())
                .eq(Order::getType, 0)
                .eq(Order::getPayStatus, 0));

        toBeReceived = orderService.count(new LambdaQueryWrapper<Order>().eq(Order::getUserId, getLoginUserId())
                .eq(Order::getType, 0)
                .eq(Order::getPayStatus, 1).eq(Order::getDeliveryStatus, 20));

        toBeDelivery = orderService.count(new LambdaQueryWrapper<Order>().eq(Order::getUserId, getLoginUserId())
                .eq(Order::getType, 0)
                .eq(Order::getPayStatus, 1).eq(Order::getDeliveryStatus, 10));
        outtakeUserToBeDone = orderService.count(new LambdaQueryWrapper<Order>().eq(Order::getUserId, getLoginUserId())
                .eq(Order::getType, 1)
                .eq(Order::getPayStatus, 1).eq(Order::getOrderStatus, 0));
        outtakeUserToPay = orderService.count(new LambdaQueryWrapper<Order>().eq(Order::getUserId, getLoginUserId())
                .eq(Order::getType, 1)
                .eq(Order::getPayStatus, 0).eq(Order::getOrderStatus, 0));
        data.put("toBePaid", toBePaid);
        data.put("toBeReceived", toBeReceived);
        data.put("toBeDelivery", toBeDelivery);
        data.put("outtakeUserToBeDone", outtakeUserToBeDone);
        data.put("outtakeUserToPay", outtakeUserToPay);
        return success(data);
    }

    @PostMapping("/data-for-admin")
    public ApiResult<?> dataForAdmin() {
        Map<String, BigDecimal> data = new HashMap<>();
        BigDecimal totalIncome = BigDecimal.ZERO, todayIncome = BigDecimal.ZERO;
        List<Order> orderList = orderService.list(new LambdaQueryWrapper<Order>().eq(Order::getPayStatus, 1));
        if (!orderList.isEmpty())
            totalIncome = orderList.stream().map(Order::getTotalPrice).reduce(BigDecimal::add).get();
        for (Order order : orderList) {
            if (order.getCreateTime().after(DateUtil.beginOfDay(DateUtil.date())) && order.getCreateTime().before(DateUtil.endOfDay(DateUtil.date()))) {
                todayIncome = todayIncome.add(order.getTotalPrice());
            }
        }
        data.put("totalIncome", totalIncome);
        data.put("todayIncome", todayIncome);
        return success(data);
    }

    @ApiOperation("分页查询订单")
    @GetMapping("/page")
    public ApiResult<PageResult<Order>> page(OrderParam param) {
        // 使用关联查询
        if (getLoginUser() != null) {
            param.setLoginUser(getLoginUser());
        }
        return success(orderService.pageRel(param));
    }

    @ApiOperation("查询全部订单")
    @GetMapping()
    public ApiResult<List<Order>> list(OrderParam param) {
        // 使用关联查询
        System.out.println(getLoginUser());
        if (param.getListForExpress() != null) {
            Merchant merchant = merchantService.getByUserId(getLoginUserId());
            if (merchant != null) param.setMerchantId(merchant.getMerchantId());
        }
        return success(orderService.listRel(param));
    }

    @ApiOperation("根据id查询订单")
    @GetMapping("/{id}")
    public ApiResult<Order> get(@PathVariable("id") Integer id) {
        Order order = orderService.getByIdRel(id);
        if (getLoginUser() != null) {
            User parentUser = requestUtil.getParent(getLoginUserId());
            for (OrderGoods orderGoods : order.getGoodsList()) {
                Goods goods = orderGoods.getGoods();
                BigDecimal originPrice = goods.getPrice();
                goods.setPrice(goods.getSalePrice());
                // 会员
//                if (parentUser != null) {
                if (goods.getPriceGift()) goods.setShowGift(true);
//                    goods.setPrice(originPrice);
//                }
//                if (getLoginUser().getGradeId().equals(33)) {
//                    if (goods.getDealerGift()) goods.setShowGift(true);
//                }
                // 会员店
//                if (getLoginUser().getGradeId() > 30 && goods.getBuyingPriceOpen().equals(1)) {
//                    goods.setPrice(goods.getBuyingPrice());
////                    if (goods.getPriceGift()) goods.setShowGift(true);
//                }
            }
        }
        if (order.getDeliveryType().equals(0)) {
            OrderDelivery orderDelivery = orderDeliveryService.getByOrderId(order.getOrderId());
            if (orderDelivery != null) {
                orderDelivery.setExpress(expressService.getById(orderDelivery.getExpressId()));
                order.setOrderDelivery(orderDelivery);
            }
        }
        if (order.getType().equals(0)) {
            if (order.getDeliveryType().equals(1) && order.getSelfTakeMerchantId() != null) {
//                Merchant merchant = merchantService.getById(order.getSelfTakeMerchantId());
                SelfTake selfTake = selfTakeService.getByIdRel(order.getSelfTakeMerchantId());
                order.setSelfTake(selfTake);
            }
        } else if (order.getType().equals(1)) {
            Merchant merchant = merchantService.getById(order.getMerchantId());
            order.setMerchant(merchant);
        }
        return success(order);
    }

    @ApiOperation("会员店未发货数量")
    @PostMapping("/shopUnExpressNum")
    public ApiResult<?> shopUnExpressNum() {
        final User loginUser = getLoginUser();
        if (loginUser == null) {
            return fail("请先登录", null);
        }
        int num = 0;
        if (loginUser.getGradeId() > 30) {
            num = orderService.shopUnExpressNum(loginUser.getMerchantId());
        }
        return success(num);
    }

    @ApiOperation("根据orderNo查询订单")
    @GetMapping("/getByOrderNo/{orderNo}")
    public ApiResult<Order> getByOrderNo(@PathVariable("orderNo") String orderNo) {
        final User loginUser = getLoginUser();
        if (loginUser == null) {
            return fail("请先登录", null);
        }

        final Order order = orderService.getByOutTradeNo(orderNo);
        if (order != null) {
            final List<OrderInfo> orderInfoList = orderInfoService.list(new LambdaQueryWrapper<OrderInfo>().eq(OrderInfo::getOrderId, order.getOrderId()));
            order.setOrderInfo(orderInfoList);
        }
        return success(order);
    }


    @PreAuthorize("hasAuthority('shop:order:verification')")
    @ApiOperation("根据orderNo核销订单")
    @GetMapping("/verification/{orderNo}")
    public ApiResult<Order> verification(@PathVariable("orderNo") String orderNo, HttpServletRequest request) {
        final User loginUser = getLoginUser();
        if (loginUser == null) {
            return fail("请先登录", null);
        }

        final Set<String> collect = loginUser.getRoles().stream().map(Role::getRoleCode).collect(Collectors.toSet());
        final boolean merchant = Arrays.asList(collect).contains("merchant");
        final boolean merchantClerk = Arrays.asList(collect).contains("merchantClerk");

        if (merchant || merchantClerk) {
            System.out.println("merchant = " + merchant);
            System.out.println("merchantClerk = " + merchantClerk);
            final Order order = orderService.getByOutTradeNo(orderNo);
            if (order != null) {
                final List<OrderInfo> orderInfoList = orderInfoService.list(new LambdaQueryWrapper<OrderInfo>().eq(OrderInfo::getOrderId, order.getOrderId()));
                order.setOrderInfo(orderInfoList);
            }
            return success(order);
        }
        return fail("核销失败", null);
    }

    @ApiOperation("下单")
    @PostMapping()
    public ApiResult<?> save(@RequestBody Order order, HttpServletRequest request) throws Exception {
        String access_token = JwtUtil.getAccessToken(request);
        // 记录当前登录用户id
        User loginUser = getLoginUser();
        if (loginUser == null) {
            return fail("请先登录");
        }
        // 微信openid(必填)
        if (StrUtil.isBlank(loginUser.getOpenid())) {
            return fail("微信openid(必填)");
        }
        // 商品描述(必填)
        if (StrUtil.isBlank(order.getComments())) {
            return fail("商品描述(必填)");
        }
        // 微信支付(商品金额不能为0)
        if (order.getPayType().equals(PAY_TYPE_WECHAT)) {
            if (order.getTotalPrice().compareTo(BigDecimal.ZERO) == 0) {
                return fail("商品金额不能为0");
            }
        }

        // 已下过订单
        if (order.getOrderId() != null) {
            Order order1 = orderService.getByIdRel(order.getOrderId());
            order1.setPayType(order.getPayType());
            order1.setOpenid(loginUser.getOpenid());
            order1.setOrderNo(Long.toString(IdUtil.getSnowflakeNextId()));
            order1.setAccessToken(access_token);
            order1.setLoginUser(loginUser);
            order1.setPayUserId(loginUser.getUserId());
            // 调起支付
            return onPay(request, order1);
        }

        // 创建订单
        long timeMillis = System.currentTimeMillis();
        long orderNo = IdUtil.getSnowflakeNextId();
        String name = loginUser.getRealName();
        String phone = loginUser.getPhone();
        String address = "";
        if (order.getRealName() != null) {
            name = order.getRealName();
        }
        if (order.getPhone() != null) {
            phone = order.getPhone();
        }
        if (order.getAddress() != null) {
            address = order.getAddress();
        }
        if (order.getAddressId() != null) {
            UserAddress userAddress = userAddressService.getById(order.getAddressId());
            if (userAddress != null) {
                name = userAddress.getName();
                phone = userAddress.getPhone();
                address = userAddress.getFullAddress();
                Area province = areaService.areaInfoByName(userAddress.getProvince(), 1);
                if (province != null) {
                    order.setProvinceId(province.getId());
                    Area city = areaService.areaInfoByName(userAddress.getCity(), 2, province.getId());
                    if (city != null) {
                        Area region = areaService.areaInfoByName(userAddress.getRegion(), 3, city.getId());
                        order.setCityId(city.getId());
                        if (region != null) {
                            order.setRegionId(region.getId());
                        }
                    }
                }
            }
        }

        if (order.getAddressId() != null && order.getType() < 3 && order.getDeliveryType() != null && order.getDeliveryType().equals(0)) {
            UserAddress userAddress = userAddressService.getById(order.getAddressId());
            if (userAddress == null) return fail("请选择收货地址");
            for (OrderGoods orderGoods : order.getGoodsList()) {
                orderGoods.setTotalNum(orderGoods.getCartNum());
            }
//            BigDecimal expressAmount = expressTemplateService.calExpressAmount(order.getGoodsList(), userAddress);
//            order.setExpressPrice(expressAmount);
//            order.setTotalPrice(expressAmount.add(order.getTotalPrice()));
        }

        if (order.getAddress() != null && order.getMerchantId() != null && order.getType().equals(1) && order.getDeliveryType() != null && order.getDeliveryType().equals(0)) {
            order.setExpressMerchantId(order.getMerchantId());
            order.setExpressMerchantName(order.getMerchantName());
        }

        order.setOrderNo(Long.toString(orderNo));
        order.setUserId(loginUser.getUserId());
        order.setOpenid(loginUser.getOpenid());
        order.setRealName(name);
        order.setPhone(phone);
        order.setAddress(address);
        order.setUserId(loginUser.getUserId());
        order.setLoginUser(loginUser);
        order.setPayUserId(loginUser.getUserId());
        order.setAccessToken(access_token);
        order.setExpirationTime(DateUtil.offset(DateUtil.date(), DateField.MINUTE, 1));
        if (order.getOrderInfo() != null) {
            order.setTotalNum(order.getOrderInfo().size());
        }
        if (order.getGoodsList() != null) {
            order.setTotalNum(order.getGoodsList().size());
        }
        if (order.getDeliveryType() != null && order.getDeliveryType().equals(1)) {
            order.setSelfTakeCode(RandomUtil.randomString(4));
        }

        if (order.getCouponId() != null && order.getCouponId() > 0) {
            UserCoupon userCoupon = userCouponService.getById(order.getCouponId());
            if (userCoupon == null) return fail("优惠券不存在");
            if (userCoupon.getUsed().equals(1)) return fail("该优惠券已使用");
            Coupon coupon = couponService.getById(userCoupon.getCouponId());
            if (coupon == null) return fail("优惠券不存在");
            if (coupon.getStartAmount().compareTo(order.getTotalPrice()) > 0)
                return fail("优惠券不满足使用条件");
            order.setReducePrice(coupon.getReduceAmount());
            order.setPayPrice(order.getTotalPrice().subtract(coupon.getReduceAmount()));
        }

        if (order.getBalance() != null && order.getBalance().compareTo(BigDecimal.ZERO) > 0) {
            RequestUtil requestUtil = new RequestUtil();
            requestUtil.setTenantId(order.getTenantId().toString());
            User user = requestUtil.getByUserIdWithoutLogin(order.getUserId());
            if (user != null && user.getBalance().compareTo(order.getBalance()) < 0) {
                return fail("余额不足");
            }
            order.setBalance(order.getBalance());
            order.setReducePrice(order.getBalance());
            order.setPayPrice(order.getTotalPrice().subtract(order.getBalance()));
        }

        if (orderService.save(order)) {
            // 商城订单
            if (ObjectUtil.isNotEmpty(order.getGoodsList())) {
                order.getGoodsList().forEach(d -> {
                    d.setOrderId(order.getOrderId());
                    d.setTimeFlag(timeMillis);
                    d.setVersion(10);
                    d.setDateTime(DateUtil.date());
                    d.setUserId(getLoginUser().getUserId());
                    d.setExpirationTime(order.getExpirationTime());
                    d.setTotalNum(d.getCartNum());
                });
                orderGoodsService.saveBatch(order.getGoodsList());
            }
            // 预定订单
            if (ObjectUtil.isNotEmpty(order.getOrderInfo())) {
                if (ObjectUtil.isNotEmpty(order.getOrderInfo())) {
                    order.getOrderInfo().forEach(d -> {
                        d.setOrderId(order.getOrderId());
                        d.setTimeFlag(timeMillis);
                        d.setVersion(10);
                        d.setUserId(getLoginUser().getUserId());
                        d.setDateTime(d.getDateTime());
                        d.setExpirationTime(order.getExpirationTime());
                        d.setTenantId(order.getTenantId());
                    });
                    orderInfoService.saveBatch(order.getOrderInfo());
                }
            }
            // 调起支付
            return onPay(request, order);
        }
        return fail("下单失败");
    }

    private ApiResult<?> onPay(HttpServletRequest request, Order order) throws Exception {
        // 余额支付
        if (order.getPayType().equals(PAY_TYPE_BALANCE)) {
            order.setAccessToken(order.getAccessToken());
            final User loginUser = order.getLoginUser();
            if (loginUser.getBalance().compareTo(order.getPayPrice()) < 0) {
                throw new BusinessException("余额不足");
            }
            if (order.getNotClearData() == null) {
                // 清空购物车
                final Set<Integer> cartIds = order.getGoodsList().stream().map(OrderGoods::getGoodsId).collect(Collectors.toSet());
                cartService.remove(new LambdaQueryWrapper<Cart>().eq(Cart::getUserId, order.getUserId()).in(Cart::getGoodsId, cartIds));
                // 外卖订单
                if (!order.getMerchantId().equals(0)) {
                    cartService.remove(new LambdaQueryWrapper<Cart>().eq(Cart::getUserId, order.getUserId()).eq(Cart::getType, 1));
                }
            }
            final TransactionAmount amount = new TransactionAmount();
            amount.setTotal(order.getPayPrice().multiply(new BigDecimal(100)).intValue());
            amount.setCurrency("CNY");
            wxPayNotifyNbgController.doPay(new Transaction() {{
                setOutTradeNo(order.getOrderNo());
                setTransactionId(order.getOrderNo());
                setAmount(amount);
            }});
//            uni
            return success("下单成功", requestUtil.balancePay(order));
        }

        //  微信统一下单接口
        if (order.getPayType().equals(PAY_TYPE_WECHAT)) {
            // 清空购物车
            if (order.getNotClearData() == null) {
                final Set<Integer> cartIds = order.getGoodsList().stream().map(OrderGoods::getGoodsId).collect(Collectors.toSet());
                cartService.remove(new LambdaQueryWrapper<Cart>().eq(Cart::getUserId, order.getUserId()).in(Cart::getGoodsId, cartIds));
                // 外卖订单
                if (order.getMerchantId() != null && !order.getMerchantId().equals(0) && order.getType() < 3) {
                    cartService.remove(new LambdaQueryWrapper<Cart>().eq(Cart::getUserId, order.getUserId()).eq(Cart::getType, 1));
                }
            }
            // 完全抵扣
            if (order.getPayPrice().compareTo(BigDecimal.ZERO) == 0) {
                final TransactionAmount amount = new TransactionAmount();
                amount.setTotal(order.getPayPrice().multiply(new BigDecimal(100)).intValue());
                amount.setCurrency("CNY");
                if (order.getCouponId() != null  && order.getCouponId() > 0) {
                    UserCoupon userCoupon = userCouponService.getById(order.getCouponId());
                    if (userCoupon != null) {
                        userCoupon.setOrderId(order.getOrderId());
                        userCoupon.setUsed(1);
                        userCoupon.setUsedTime(LocalDateTime.now());
                        userCouponService.updateById(userCoupon);
                    }
                }
                if (order.getBalance() != null && order.getBalance().compareTo(BigDecimal.ZERO) > 0) {
                    RequestUtil requestUtil = new RequestUtil();
                    requestUtil.setTenantId(order.getTenantId().toString());
                    User user = requestUtil.getByUserIdWithoutLogin(order.getUserId());
                    if (user != null) {
                        user.setBalance(user.getBalance().subtract(order.getBalance()));
                        requestUtil.updateUserBalanceWithoutLogin(user);
                    }
                }
                wxPayNotifyNbgController.doPay(new Transaction() {{
                    setOutTradeNo(order.getOrderNo());
                    setTransactionId(order.getOrderNo());
                    setAmount(amount);
                }});
            }
            return success("下单成功", orderService.createWxOrder(order));
        }

        //  门店余额
        if (order.getPayType().equals(PAY_TYPE_MERCHANT_BALANCE)) {
            UserBalanceInMerchant userBalanceInMerchant = userBalanceInMerchantService.getBalance(order.getMerchantId(), order.getUserId());
            if (userBalanceInMerchant == null || userBalanceInMerchant.getBalance().compareTo(order.getTotalPrice()) < 0) {
                return fail("余额不足");
            }
            userBalanceInMerchant.setBalance(userBalanceInMerchant.getBalance().subtract(order.getTotalPrice()));
            userBalanceInMerchantService.updateById(userBalanceInMerchant);
            final TransactionAmount amount = new TransactionAmount();
            amount.setTotal(order.getTotalPrice().multiply(new BigDecimal(100)).intValue());
            amount.setCurrency("CNY");
            wxPayNotifyNbgController.doPay(new Transaction() {{
                setOutTradeNo(order.getOrderNo());
                setTransactionId(order.getOrderNo());
                setAmount(amount);
            }});
            return success("支付成功", true);
        }

        return fail("支付失败");
    }

    @ApiOperation("自提")
    @PostMapping("/self-take")
    public ApiResult<?> selfTake(@RequestBody Order order, HttpServletRequest request) {
        String access_token = JwtUtil.getAccessToken(request);
        Order order1 = orderService.getById(order.getOrderId());
//        if (!order1.getSelfTakeCode().equals(order.getSelfTakeCode())) return fail("自提码不正确");
        if (order1.getOrderStatus().equals(1)) return fail("订单已完成");
        order1.setOrderStatus(1);
        order1.setDoneTime(new Date());
        orderService.updateById(order1);
        orderService.doSettle(order1.getOrderId());
        return success("提货成功");
    }

    @ApiOperation("商城发货订单确认收货")
    @PostMapping("/delivery-confirm")
    public ApiResult<?> deliveryConfirm(@RequestBody Order order, HttpServletRequest request) {
        String access_token = JwtUtil.getAccessToken(request);
        Order order1 = orderService.getById(order.getOrderId());
        if (order1.getOrderStatus().equals(1)) return fail("订单已完成");
        order1.setOrderStatus(1);
        order1.setDoneTime(new Date());
        orderService.updateById(order1);
        orderService.doSettle(order1.getOrderId());
        return success("确认收货成功");
    }

    @ApiOperation("外卖确认收货")
    @PostMapping("/out-take-confirm")
    public ApiResult<?> outTakeConfirm(@RequestBody Order order, HttpServletRequest request) {
        String access_token = JwtUtil.getAccessToken(request);
        Order order1 = orderService.getById(order.getOrderId());
        if (order1.getOrderStatus().equals(1)) return fail("订单已完成");
        order1.setOrderStatus(1);
        order1.setHasTakeGift(order.getHasTakeGift());
        order1.setHasTakeGift(order.getHasTakeGift());
        order1.setDoneTime(new Date());
        orderService.updateById(order1);
        orderService.doSettle(order1.getOrderId());
        return success("外卖确认收货");
    }

    @ApiOperation("物流查询")
    @PostMapping("/express-poll")
    public ApiResult<?> expressPoll(@RequestBody OrderDelivery orderDelivery) throws Exception {
        String res;
        if (redisUtil.get("express_" + orderDelivery.getExpressNo()) == null) {
            Express express = expressService.getById(orderDelivery.getExpressId());
            Order order = orderService.getById(orderDelivery.getOrderId());
            res = kuaiDi100.pollList(express.getKuaidi100Code(), orderDelivery.getExpressNo(), order.getPhone());
            redisUtil.set("express_" + orderDelivery.getExpressNo(), res, 1L, TimeUnit.HOURS);
        } else res = redisUtil.get("express_" + orderDelivery.getExpressNo());
        return success(res);
    }

    @ApiOperation("修改订单")
    @PutMapping()
    public ApiResult<?> update(@RequestBody Order order) {
        if (order.getOrderStatus().equals(2)) {
            order.setExpirationTime(DateUtil.date());
            orderInfoService.update(new LambdaUpdateWrapper<OrderInfo>().eq(OrderInfo::getOrderId, order.getOrderId()).set(OrderInfo::getExpirationTime, DateUtil.date()));
        }
        if (orderService.updateById(order)) {
            return success("操作成功");
        }
        return fail("操作失败");
    }

    @ApiOperation("删除订单")
    @DeleteMapping("/{id}")
    public ApiResult<?> remove(@PathVariable("id") Integer id) {
        if (orderService.removeById(id)) {
            return success("删除成功");
        }
        return fail("删除失败");
    }

    @ApiOperation("批量添加订单")
    @PostMapping("/batch")
    public ApiResult<?> saveBatch(@RequestBody List<Order> list) {
        if (orderService.saveBatch(list)) {
            return success("添加成功");
        }
        return fail("添加失败");
    }

    @ApiOperation("批量修改订单")
    @PutMapping("/batch")
    public ApiResult<?> removeBatch(@RequestBody BatchParam<Order> batchParam) {
        if (batchParam.update(orderService, "order_id")) {
            return success("修改成功");
        }
        return fail("修改失败");
    }

    @ApiOperation("批量删除订单")
    @DeleteMapping("/batch")
    public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
        if (orderService.removeByIds(ids)) {
            return success("删除成功");
        }
        return fail("删除失败");
    }

    @PostMapping("/export-for-supplier")
    public ApiResult<?> exportForSupplier() throws IOException {
        List<Merchant> supplierList = merchantService.list(new LambdaQueryWrapper<Merchant>().eq(Merchant::getShopType, "供应商"));
        String filename = "excel/供应商报表.xlsx";
        String path = uploadPath + filename;
        SXSSFWorkbook workbook = new SXSSFWorkbook();
        //创建工作表单
        SXSSFSheet sheet = workbook.createSheet();
        String[] headers = {"名称", "订单号", "订单金额", "是否已结算"};

        SXSSFRow row0 = sheet.createRow(0);
        for (int i = 0; i < headers.length; i++) {
            row0.createCell(i).setCellValue(headers[i]);
        }
        if (!supplierList.isEmpty()) {
            List<DealerCapital> dealerCapitalList = dealerCapitalService.list(
                    new LambdaQueryWrapper<DealerCapital>()
                            .eq(DealerCapital::getFlowType, 10)
                            .in(DealerCapital::getUserId, supplierList.stream().map(Merchant::getUserId).toList())
            );
            List<Order> orderList = orderService.listByIds(dealerCapitalList.stream().map(DealerCapital::getOrderId).toList());
            for (DealerCapital dealerCapital : dealerCapitalList) {
                Merchant merchant = supplierList.stream().filter(d -> d.getUserId().equals(dealerCapital.getUserId())).findFirst().orElse(null);
                Order order = orderList.stream().filter(item -> item.getOrderId().equals(dealerCapital.getOrderId())).findFirst().orElse(null);
                SXSSFRow row = sheet.createRow(sheet.getLastRowNum() + 1);
                row.createCell(0).setCellValue(merchant != null ? merchant.getMerchantName() : "");
                row.createCell(1).setCellValue(order != null ? order.getOrderNo() : "");
                row.createCell(2).setCellValue(dealerCapital.getMoney().toString() + "元");
                row.createCell(3).setCellValue(dealerCapital.getStatus().equals(0) ? "未结算" : "已结算");
            }
        }
        FileOutputStream output = new FileOutputStream(path);
        workbook.write(output);
        output.flush();

        FileRecord result = new FileRecord();
        result.setCreateUserId(getLoginUserId());
        result.setName("供应商报表");
        result.setPath(filename);
        result.setUrl(config.getServerUrl() + "/file/" + filename);
        return success(result);
    }

    @PostMapping("/export-for-cash")
    public ApiResult<?> exportForCash() throws IOException {
        String filename = "excel/提现报表.xlsx";
        String path = uploadPath + filename;
        SXSSFWorkbook workbook = new SXSSFWorkbook();
        //创建工作表单
        SXSSFSheet sheet = workbook.createSheet();
        String[] headers = {"名称", "提现金额"};

        SXSSFRow row0 = sheet.createRow(0);
        for (int i = 0; i < headers.length; i++) {
            row0.createCell(i).setCellValue(headers[i]);
        }
        List<DealerCapital> dealerCapitalList = dealerCapitalService.list(
                new LambdaQueryWrapper<DealerCapital>()
                        .eq(DealerCapital::getFlowType, 20)
        );
        for (DealerCapital dealerCapital : dealerCapitalList) {
            Merchant merchant = merchantService.getByUserId(dealerCapital.getUserId());
            SXSSFRow row = sheet.createRow(sheet.getLastRowNum() + 1);
            row.createCell(1).setCellValue(merchant != null ? merchant.getMerchantName() : "");
            row.createCell(2).setCellValue(dealerCapital.getMoney().toString() + "元");
        }
        FileOutputStream output = new FileOutputStream(path);
        workbook.write(output);
        output.flush();

        FileRecord result = new FileRecord();
        result.setCreateUserId(getLoginUserId());
        result.setName("提现报表");
        result.setPath(filename);
        result.setUrl(config.getServerUrl() + "/file/" + filename);
        return success(result);
    }
}
