package com.sqx.modules.order.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.converters.longconverter.LongStringConverter;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
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.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ekyong.www.pay.pay.qrcode.api.RhtQrcodePayApi;
import com.ekyong.www.pay.pay.qrcode.bean.QrcodeQueryRequestBean;
import com.ekyong.www.pay.pay.qrcode.bean.QrcodeQueryResponseBean;
import com.github.wxpay.sdk.WXPay;
import com.sqx.common.constant.RedisKey;
import com.sqx.common.exception.SqxException;
import com.sqx.common.sms.SmsSendResult;
import com.sqx.common.utils.*;
import com.sqx.modules.activity.entity.ActivityPartRecord;
import com.sqx.modules.activity.service.ActivityPartRecordService;
import com.sqx.modules.activity.service.ActivityService;
import com.sqx.modules.activity.vo.OrderSuitActivityVO;
import com.sqx.modules.address.dao.AddressDao;
import com.sqx.modules.address.entity.Address;
import com.sqx.modules.address.service.AddressService;
import com.sqx.modules.app.dao.UserBrowseDao;
import com.sqx.modules.app.dao.UserDao;
import com.sqx.modules.app.dao.UserMoneyDao;
import com.sqx.modules.app.dao.UserMoneyDetailsDao;
import com.sqx.modules.app.entity.UserBrowse;
import com.sqx.modules.app.entity.UserEntity;
import com.sqx.modules.app.entity.UserMoney;
import com.sqx.modules.app.entity.UserMoneyDetails;
import com.sqx.modules.app.service.UserMoneyService;
import com.sqx.modules.app.service.UserService;
import com.sqx.modules.common.entity.CommonInfo;
import com.sqx.modules.common.service.CommonInfoService;
import com.sqx.modules.coupon.dao.TbCouponUserDao;
import com.sqx.modules.coupon.entity.TbCouponUser;
import com.sqx.modules.datacentre.entity.SysUserShop;
import com.sqx.modules.errand.dao.TbIndentDao;
import com.sqx.modules.errand.entity.TbIndent;
import com.sqx.modules.errand.entity.TbIndentSmsSendLog;
import com.sqx.modules.errand.service.TbIndentService;
import com.sqx.modules.errand.service.TbIndentSmsSendLogService;
import com.sqx.modules.errand.service.TbIndentSmsTemplateService;
import com.sqx.modules.goods.dao.GoodsDao;
import com.sqx.modules.goods.dao.GoodsShopDao;
import com.sqx.modules.goods.dao.GoodsShopRelevancyDao;
import com.sqx.modules.goods.dao.GoodsSkuDao;
import com.sqx.modules.goods.entity.Goods;
import com.sqx.modules.goods.entity.GoodsShop;
import com.sqx.modules.goods.entity.GoodsShopRelevancy;
import com.sqx.modules.goods.entity.GoodsSku;
import com.sqx.modules.goods.service.GoodsShopService;
import com.sqx.modules.integral.dao.UserIntegralDao;
import com.sqx.modules.integral.dao.UserIntegralDetailsDao;
import com.sqx.modules.integral.entity.UserIntegralDetails;
import com.sqx.modules.message.dao.MessageInfoDao;
import com.sqx.modules.message.entity.MessageInfo;
import com.sqx.modules.order.controller.query.GoodsSkuQuery;
import com.sqx.modules.order.controller.vo.GoodsSkuSalesCountVO;
import com.sqx.modules.order.dao.AppOrderDao;
import com.sqx.modules.order.dao.EvaluateDao;
import com.sqx.modules.order.dao.OrderGoodsDao;
import com.sqx.modules.order.dto.OrderFinishByShopDTO;
import com.sqx.modules.order.dto.OrderQueryDto;
import com.sqx.modules.order.entity.Evaluate;
import com.sqx.modules.order.entity.EvaluateRider;
import com.sqx.modules.order.entity.OrderGoods;
import com.sqx.modules.order.entity.TbOrder;
import com.sqx.modules.order.service.AppOrderService;
import com.sqx.modules.order.service.EvaluateRiderService;
import com.sqx.modules.pay.config.WXConfig;
import com.sqx.modules.pay.config.WechatPayConfig;
import com.sqx.modules.pay.controller.app.AliPayController;
import com.sqx.modules.pay.dao.PayDetailsDao;
import com.sqx.modules.pay.dto.GetPayParamDTO;
import com.sqx.modules.pay.dto.PayOrderDTO;
import com.sqx.modules.pay.entity.PayDetails;
import com.sqx.modules.pay.enums.PayChannelEnum;
import com.sqx.modules.pay.enums.PaySceneEnum;
import com.sqx.modules.pay.enums.PayStateEnums;
import com.sqx.modules.pay.service.NewPayService;
import com.sqx.modules.pay.service.PayDetailsService;
import com.sqx.modules.pay.service.WxErrService;
import com.sqx.modules.pay.vo.AliPayTransactionsParam;
import com.sqx.modules.pay.vo.PayTransactionsVO;
import com.sqx.modules.shop.entity.ShopType;
import com.sqx.modules.shop.service.ShopMessageService;
import com.sqx.modules.shop.service.ShopTypeService;
import com.sqx.modules.sys.entity.SysUserEntity;
import com.sqx.modules.sys.service.SysUserService;
import com.sqx.modules.utils.SenInfoCheckUtil;
import com.sqx.modules.utils.excel.ExcelData;
import com.sqx.modules.utils.fieYun.FeiYunUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.shiro.SecurityUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class AppAppOrderServiceImpl extends ServiceImpl<AppOrderDao, TbOrder> implements AppOrderService {

    @Autowired
    private AppOrderDao appOrderDao;
    @Autowired
    private GoodsDao goodsDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private CommonInfoService commonInfoService;
    @Autowired
    private UserService userService;
    @Autowired
    private AppOrderService orderService;
    @Autowired
    private PayDetailsService payDetailsService;
    @Autowired
    private OrderGoodsDao orderGoodsDao;
    @Autowired
    private GoodsSkuDao goodsSkuDao;
    @Autowired
    private TbCouponUserDao tbCouponUserDao;
    @Autowired
    private GoodsShopDao goodsShopDao;
    @Autowired
    private MessageInfoDao messageInfoDao;
    @Autowired
    private GoodsShopRelevancyDao goodsShopRelevancyDao;
    @Autowired
    private UserMoneyDao userMoneyDao;
    @Autowired
    private WxErrService wxErrService;
    @Autowired
    private UserMoneyDetailsDao userMoneyDetailsDao;
    @Autowired
    private EvaluateDao evaluateDao;
    @Autowired
    private TbIndentService tbIndentService;
    @Autowired
    private UserMoneyService userMoneyService;
    @Autowired
    private TbIndentDao tbIndentDao;
    @Autowired
    private UserBrowseDao userBrowseDao;
    @Autowired
    private PayDetailsDao payDetailsDao;
    @Autowired
    private AddressService addressService;
    @Autowired
    private ShopMessageService shopMessageService;
    @Lazy
    @Autowired
    private ActivityService activityService;
    @Autowired
    private ActivityPartRecordService activityPartRecordService;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private TbIndentSmsSendLogService smsSendLogService;
    @Autowired
    private TbIndentSmsTemplateService smsTemplateService;
    @Autowired
    private NewPayService newPayService;
    @Autowired
    private AliPayController aliPayController;
    @Autowired
    private PlatformTransactionManager transactionManager;
    @Autowired
    private UserIntegralDao userIntegralDao;
    @Autowired
    private UserIntegralDetailsDao userIntegralDetailsDao;

    @Autowired
    private EvaluateRiderService evaluateRiderService;
    @Autowired
    private ShopTypeService shopTypeService;

    @Autowired
    private GoodsShopService goodsShopService;

    @Resource
    private RedissonClient redissonClient;

    private final static String RHT_PAY_BASE_URL = "https://api.ekbuyclub.com";

    private static final DateTimeFormatter DTF = DateTimeFormatter.ofPattern(DateUtils.TIME_PATTERN1);

    @Override
    public int updateOrderPrint(Long orderId) {
        UpdateWrapper wrapper = new UpdateWrapper<>();
        wrapper.eq("order_id", orderId);
        wrapper.set("is_print", 1);
        int result = appOrderDao.update(null, wrapper);
        return result;
    }


    @Override
    public void insertOrder(Long userId, Long shopId, Long goodsId, Integer num, Long skuId, String skuMessage, Integer orderType) {
        // 判断当前时间是否在店铺营业范围内
        if (!isShopBusinessTime(shopId)) {
            throw new SqxException("店铺已打烊！");
        }

        //先判断该商品的库存是否足够
        GoodsShopRelevancy goodsShopRelevancy = goodsShopRelevancyDao.selectOne(new QueryWrapper<GoodsShopRelevancy>().eq("shop_id", shopId).eq("goods_id", goodsId));
        if (goodsShopRelevancy.getInventory() < num) {
            throw new SqxException("该商品库存不足！");
        }

        RLock lock = redissonClient.getLock(String.format(RedisKey.INSERT_ORDER_LOCK, userId, shopId));
        lock.lock();
        TransactionStatus status = null;
        try {
            TbOrder order = appOrderDao.selectOne(new QueryWrapper<TbOrder>().eq("user_id", userId).eq("shop_id", shopId).eq("status", 1));
            Goods goods = goodsDao.selectById(goodsId);
            String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());

            // 开启编程式事务
            status = transactionManager.getTransaction(new DefaultTransactionDefinition());
            if (order == null) {
                UserEntity userEntity = userDao.selectById(userId);
                TbOrder tbOrder = new TbOrder();
                tbOrder.setUserId(userId);
                tbOrder.setUserName(userEntity.getUserName());
                tbOrder.setPhone(userEntity.getPhone());
                tbOrder.setOrderNumber(getGeneralOrder());
                tbOrder.setIsPay(0);
                tbOrder.setDeleteFlag(0);
                tbOrder.setStatus(1);
                tbOrder.setShopId(shopId);
                //创建订单，订单发起人就是该登录用户
                tbOrder.setParentUserId(userId);
                tbOrder.setCreateTime(format);
                tbOrder.setAddGoodsTime(format);
                appOrderDao.insertOrder(tbOrder);

                TbOrder tbOrder1 = new TbOrder();
                tbOrder1.setOrderId(tbOrder.getOrderId());
                tbOrder1.setParentId(tbOrder.getOrderId());
                appOrderDao.updateById(tbOrder1);
                //添加订单-商品表
                Long orderId = tbOrder.getOrderId();
                OrderGoods orderGoods = new OrderGoods();
                orderGoods.setOrderId(orderId);
                orderGoods.setGoodsName(goods.getGoodsName());
                orderGoods.setSkuId(skuId);
                GoodsSku goodsSku = goodsSkuDao.selectById(skuId);
                orderGoods.setGoodsPrice(goodsSku.getSkuPrice());
                orderGoods.setSkuMessage(skuMessage);
                orderGoods.setGoodsNum(num);
                orderGoods.setGoodsPack(goods.getPackMoney());
                orderGoods.setGoodsPicture(goods.getGoodsCover());
                orderGoods.setGoodsId(goods.getGoodsId());
                orderGoods.setUserId(userId);
                orderGoodsDao.insert(orderGoods);
            } else {
                //添加订单-商品表
                Long orderId = order.getOrderId();
                OrderGoods orderGoods = orderGoodsDao.selectOne(new QueryWrapper<OrderGoods>().eq("order_id", orderId).eq("goods_id", goods.getGoodsId()).eq("sku_id", skuId).eq("user_id", userId));
                if (orderGoods != null) {
//                    当前默认加1
//                    orderGoods.setGoodsNum(orderGoods.getGoodsNum() + 1);

                    orderGoods.setGoodsNum(orderGoods.getGoodsNum() + num);
                    orderGoodsDao.updateById(orderGoods);
                } else {
                    orderGoods = new OrderGoods();
                    orderGoods.setOrderId(orderId);
                    orderGoods.setGoodsName(goods.getGoodsName());
                    orderGoods.setSkuId(skuId);
                    GoodsSku goodsSku = goodsSkuDao.selectById(skuId);
                    orderGoods.setGoodsPrice(goodsSku.getSkuPrice());
                    orderGoods.setSkuMessage(skuMessage);
                    orderGoods.setGoodsNum(num);
                    orderGoods.setGoodsPack(goods.getPackMoney());
                    orderGoods.setGoodsPicture(goods.getGoodsCover());
                    orderGoods.setGoodsId(goods.getGoodsId());
                    orderGoods.setUserId(userId);
                    orderGoodsDao.insert(orderGoods);
                }
                //修改订单表最后一次添加商品的时间
                TbOrder tbOrder1 = new TbOrder();
                tbOrder1.setOrderId(orderId);
                tbOrder1.setAddGoodsTime(format);
                appOrderDao.updateById(tbOrder1);
            }

            // 在锁中提交事务
            transactionManager.commit(status);
        } catch (Exception e) {
            if (ObjectUtil.isNotNull(status)) {
                transactionManager.rollback(status);
            }
        } finally {
            lock.unlock();
        }
    }

    /**
     * 判断店铺当前时间是否营业时间范围内
     *
     * @param shopId 店铺id
     * @return boolean
     */
    private boolean isShopBusinessTime(Long shopId) {
        GoodsShop goodsShop = shopMessageService.getShopInfoById(shopId);
        if (goodsShop == null) {
            throw new SqxException("无效的店铺id");
        }
        String businessHours = goodsShop.getBusinessHours();
        String lockHours = goodsShop.getLockHours();

        // 营业时间和闭店时间有一个为空，则直接返回true，默认全天营业
        if (StringUtils.isEmpty(businessHours) || StringUtils.isEmpty(lockHours)) {
            return true;
        }

        LocalTime now = LocalTime.now();

        return now.isAfter(LocalTime.parse(businessHours)) && now.isBefore(LocalTime.parse(lockHours));
    }

    @Override
    public Result shareTheBill(Long userId, Long shopId) {
        // 判断当前时间是否在店铺营业范围内
        if (!isShopBusinessTime(shopId)) {
            return Result.error("店铺已打烊！");
        }

        TbOrder tbOrder2 = appOrderDao.selectOne(new QueryWrapper<TbOrder>()
                .eq("user_id", userId).eq("shop_id", shopId).eq("status", 1));
        if (tbOrder2 == null) {
            String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
            UserEntity userEntity = userDao.selectById(userId);
            TbOrder tbOrder = new TbOrder();
            tbOrder.setUserId(userId);
            tbOrder.setUserName(userEntity.getUserName());
            tbOrder.setPhone(userEntity.getPhone());
            tbOrder.setOrderNumber(getGeneralOrder());
            tbOrder.setIsPay(0);
            tbOrder.setDeleteFlag(0);
            tbOrder.setStatus(1);
            tbOrder.setShopId(shopId);
            //创建订单，订单发起人就是该登录用户
            tbOrder.setParentUserId(userId);
            tbOrder.setCreateTime(format);
            tbOrder.setAddGoodsTime(format);
            appOrderDao.insertOrder(tbOrder);
            Long orderId = tbOrder.getOrderId();
            TbOrder tbOrder1 = new TbOrder();
            tbOrder1.setOrderId(tbOrder.getOrderId());
            tbOrder1.setParentId(tbOrder.getOrderId());
            appOrderDao.updateById(tbOrder1);
            return Result.success().put("data", orderId);
        }
        return Result.success().put("data", tbOrder2.getOrderId());
    }

    @Override
    public Result selectShareTheBill(Long userId, Long orderId) {
        HashMap hashMap = new HashMap();
        TbOrder tbOrder = appOrderDao.selectById(orderId);
        if (tbOrder == null) {
            return Result.success();
        }
        List<OrderGoods> parentShareTheBill = orderGoodsDao.selectParentShareTheBill(orderId, tbOrder.getUserId());
        List<OrderGoods> orderGoodsList = orderGoodsDao.selectShareTheBill(orderId, tbOrder.getUserId());
        GoodsShop goodsShop = goodsShopDao.selectById(tbOrder.getShopId());
        hashMap.put("parentShareTheBill", parentShareTheBill);
        hashMap.put("orderGoodsList", orderGoodsList);
        hashMap.put("goodsShop", goodsShop);
        return Result.success().put("data", hashMap);
    }

    @Override
    public Result deleteByGoods(Long userId, Long id) {
        orderGoodsDao.delete(new QueryWrapper<OrderGoods>().eq("id", id).eq("user_id", userId));
        return Result.success();
    }

    @Override
    public Result deleteShareTheBill(Long userId, Long orderId) {
        orderGoodsDao.delete(new QueryWrapper<OrderGoods>().eq("order_id", orderId).eq("user_id", userId));
        return Result.success();
    }

    @Override
    public Result deleteOrder(Long userId, Long orderId) {
        TbOrder order = appOrderDao.selectById(orderId);
        if (order.getIsPay() == 1) {
            return Result.error("拼单已经支付，无法取消！");
        }
        appOrderDao.delete(new QueryWrapper<TbOrder>().eq("user_id", userId).eq("order_id", orderId));
        return Result.success();
    }

    @Override
    public IPage<Evaluate> getEvaluateList(Evaluate evaluate, Integer page, Integer limit) {
        Page<Evaluate> pages;
        if (page != null && limit != null) {
            pages = new Page<>(page, limit);
        } else {
            pages = new Page<>();
        }
        return evaluateDao.getEvaluateList(pages, evaluate);
    }

    @Override
    public Result deleteEvaluateById(Long userId, Long id) {

        Evaluate evaluate = evaluateDao.selectById(id);
        if (!evaluate.getUserId().equals(userId)) {
            return Result.error("你无权操作此评论");
        } else {
            return Result.upStatus(evaluateDao.deleteById(id));
        }
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public TbOrder prepareOrder(Long userId, PayOrderDTO payOrderDTO) {
        //        获取三大运营商的店铺id
        List<Long> shopList = new ArrayList<>();
        QueryWrapper<ShopType> wrapperShopType = new QueryWrapper<>();
        wrapperShopType.eq("shop_type_name", "三大运营商");
        ShopType shopType = shopTypeService.getOne(wrapperShopType);
        if (ObjectUtils.isNotEmpty(shopType)) {
            QueryWrapper<GoodsShop> wrapperGoodShop = new QueryWrapper<>();
            wrapperGoodShop.eq("shop_type_id", shopType.getId());
            List<GoodsShop> goodsShops = goodsShopService.list(wrapperGoodShop);
            for (GoodsShop goodsShop : goodsShops) {
                Long shopId = goodsShop.getShopId();
                shopList.add(shopId);
            }
        }
        // 获取订单信息
        TbOrder parentOrder = appOrderDao.selectById(payOrderDTO.getParentId());
        if (parentOrder == null) {
            throw new SqxException("无效的订单id");
        }
        if (shopList.contains(parentOrder.getShopId())) {
            if (ObjectUtils.isEmpty(payOrderDTO.getIdCard())) {
                throw new SqxException("请输入身份证号");
            }else {
                //        将身份证号设置到订单里
                parentOrder.setIdCard(payOrderDTO.getIdCard());
            }
        }

        if (parentOrder.getIsPay() == 1) {
            throw new SqxException("当前订单已支付，请勿重复支付！");
        }

        log.info("preOrder==>[{}]，开始订单准备工作...", parentOrder.getOrderId());

        // 获取店铺信息
        // 注意：调用shopMessageService获取店铺信息，这个service对店铺的抽成比例有特殊处理（历史代码就是如此/(ㄒoㄒ)/~~）
        GoodsShop goodsShop = shopMessageService.selectShopId(parentOrder.getShopId());
        // 给支付的时候商品描述用
        parentOrder.setShopName(goodsShop.getShopName());

        // // 设置订单类型
        // parentOrder.setOrderType(payOrderDTO.getOrderType());

        // 校验订单类型
        checkOrderType(parentOrder, payOrderDTO, goodsShop);

        // 校验订单信息
        checkOrderGoods(parentOrder);

        // 计算订单总价格（包含总打包费）和总打包费
        calcOrderPriceAndPack(parentOrder);

        // 校验地址、配送费信息
        checkAddress(parentOrder, payOrderDTO.getAddressId(), goodsShop);

        // 检查活动优惠信息
        checkActivity(payOrderDTO.getActivityId(), parentOrder);

        // 校验优惠券信息
        checkCoupon(parentOrder, userId);

        // 计算店铺收益
        calcShopIncome(parentOrder, goodsShop);

        log.info("preOrder==>[{}]，订单准备工作运行完成...", parentOrder.getOrderId());

        return parentOrder;
    }

    /**
     * 校验订单类型
     */
    private void checkOrderType(TbOrder order, PayOrderDTO payOrderDTO, GoodsShop goodsShop) {
        Integer orderType = payOrderDTO.getOrderType();

        String reservationFlag = payOrderDTO.getReservationFlag();
        if (StrUtil.equals(reservationFlag, Constant.YES)) {
            if (ObjectUtil.isNull(payOrderDTO.getExpectDeliveryTime())) {
                throw new SqxException("预约订单期望送达时间不能为空");
            }

            // 判断店铺是否开启预约接单
            if (!Integer.valueOf(Constant.YES).equals(goodsShop.getReservationOpenFlag())) {
                throw new SqxException("当前店铺未开启预约接单");
            }
        } else {
            // 判断店铺营业时间
            if (!isShopBusinessTime(goodsShop.getShopId())) {
                throw new SqxException("店铺已打烊！");
            }
        }

        // 2 外卖订单
        if (orderType == 2) {
            // 店铺是否开启自动派单 0开启 1关闭
            Integer autoSendOrder = goodsShop.getAutoSendOrder() == 0 ? 0 : 1;

            // 设置订单类型拓展 1上门 2骑手配送 3商家配送
            if (autoSendOrder == 1) {
                order.setOrderTypeExtra(3);
            } else {
                order.setOrderTypeExtra(2);
            }
        } else {
            order.setOrderTypeExtra(1);
        }

        // 骑手配送订单
        if (2 == order.getOrderTypeExtra()) {
            // 骑手工作时间段
            String workingHoursOfRider = commonInfoService.findOne(422).getValue();
            String[] split = workingHoursOfRider.split("-");
            String startTimeStr = split[0];
            String endTimeStr = split[1];

            LocalTime startTime = LocalTime.parse(startTimeStr, DTF);
            LocalTime endTime = LocalTime.parse(endTimeStr, DTF);
            LocalTime nowTime = LocalTime.now();

            // 非骑手上班期间且不是预定订单则进行错误提示
            if (nowTime.isAfter(endTime) || nowTime.isBefore(startTime)) {
                if (!StrUtil.equals(reservationFlag, Constant.YES)) {
                    throw new SqxException("当前时间不能直接下单，请选择预约下单");
                }
            }
        }

        // 设置订单是否预约单及期望送达时间
        order.setReservationFlag(reservationFlag);
        order.setExpectDeliveryTime(payOrderDTO.getExpectDeliveryTime());

        // 设置订单类型
        order.setOrderType(orderType);
    }

    /**
     * 检查活动信息
     *
     * @param activityId  活动id
     * @param parentOrder 订单信息
     */
    private void checkActivity(Long activityId, TbOrder parentOrder) {
        OrderSuitActivityVO orderBestActivity = null;

        // 获取当前订单适用的活动列表
        List<OrderSuitActivityVO> suitActivityList = activityService.getOrderSuitActivity(parentOrder.getOrderId());

        if (ObjectUtil.isNotNull(activityId)) {
            orderBestActivity = suitActivityList.stream().filter(e -> e.getActivityId().equals(activityId)).findFirst().orElseThrow(() -> new SqxException("订单不适用当前活动"));
        } else {
            if (CollUtil.isNotEmpty(suitActivityList)) {
                orderBestActivity = suitActivityList.get(0);
            }
        }

        if (ObjectUtil.isNotNull(orderBestActivity)) {
            // 支付金额减去活动优惠金额
            parentOrder.setPayMoney(parentOrder.getPayMoney().subtract(new BigDecimal(orderBestActivity.getDiscountAmount())));

            log.info("preOrder==>[{}]，订单匹配到优惠活动，活动名称[{}]，活动优惠金额[{}]",
                    parentOrder.getOrderId(), orderBestActivity.getActivityTitle(), orderBestActivity.getDiscountAmount());
            log.info("preOrder==>[{}]，订单参加优惠活动，优惠后应付金额[{}]",
                    parentOrder.getOrderId(), parentOrder.getPayMoney());

            // 保存活动参与信息
            activityPartRecordService.saveByOrderAndSuitActivityVO(parentOrder, orderBestActivity);
        }
    }

    @Override
    public void subStock(TbOrder tbOrder) {
        Long shopId1 = tbOrder.getShopId();
        Long orderId = tbOrder.getOrderId();
        List<OrderGoods> orderGoodsList = orderGoodsDao.selectList(
                new QueryWrapper<OrderGoods>()
                        .eq("order_id", orderId));
        for (int a = 0; a < orderGoodsList.size(); a++) {
            Integer goodsNum = orderGoodsList.get(a).getGoodsNum();
            Long goodsId = orderGoodsList.get(a).getGoodsId();
            GoodsShopRelevancy goodsShopRelevancy = goodsShopRelevancyDao.selectOne(
                    new QueryWrapper<GoodsShopRelevancy>()
                            .eq("shop_id", shopId1)
                            .eq("goods_id", goodsId));
            GoodsShopRelevancy goodsShopRelevancy1 = new GoodsShopRelevancy();
            goodsShopRelevancy1.setId(goodsShopRelevancy.getId());

            //加销量
            goodsShopRelevancy1.setSales(goodsShopRelevancy.getSales() + goodsNum);

            //减库存
            goodsShopRelevancy1.setInventory(goodsShopRelevancy.getInventory() - goodsNum);
            goodsShopRelevancyDao.updateById(goodsShopRelevancy1);
            goodsShopDao.updateShopSales(1, goodsNum, goodsShopRelevancy.getShopId());
        }
    }

    @Override
    public void updateOrderAfterPaySuccess(TbOrder order) {
        String currentTimeStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        order.setOrderCode(generateOrderCode());
        order.setIsPay(1);
        order.setPayTime(currentTimeStr);

        // 店铺信息
        GoodsShop goodsShop = shopMessageService.getShopInfoById(order.getShopId());

        // 小程序推送设置
        CommonInfo mpPushConfig = commonInfoService.findOne(269);

        // 用户信息
        UserEntity userEntity = userDao.selectById(order.getUserId());

        // 是否自动接单
        boolean autoAccept = goodsShop.getAutoAcceptOrder() != null && goodsShop.getAutoAcceptOrder() == 0;
        // 是否预约订单
        boolean reservationFlag = StrUtil.equals(order.getReservationFlag(), Constant.YES);

        // 店铺自动接单且当前订单不是预约订单
        if (autoAccept && !reservationFlag) {
            // 6制作中
            order.setStatus(6);
            order.setShopReceivingTime(currentTimeStr);
        } else {
            // 7商家待接单
            order.setStatus(7);
        }

        RLock lock = redissonClient.getLock(String.format(RedisKey.UPDATE_ORDER_LOCK, order.getOrderId()));
        lock.lock();
        TransactionStatus status = null;
        try {
            // 开启编程式事务
            status = transactionManager.getTransaction(new DefaultTransactionDefinition());

            // 更新订单状态及订单序号
            updateOrderStatusAndSequence(order);

            // 扣减库存
            this.subStock(order);

            // 优惠券变成已使用状态
            updateCouponState(order);

            // 如果是支付宝或者微信支付，用户钱包新增消费记录
            addConsumeRecordInUserMoneyDetail(order);

            // 已接单状态的订单生成跑腿订单
            if (order.getStatus() == 6) {
                // 如果是外卖订单,则生成一个跑腿的订单
                tbIndentService.insertIndent(order);

                // 发送商家接单通知
                MyGlobalThreadPool.execute(() -> {
                    try {
                        sendOrderAcceptMessage(order, goodsShop, mpPushConfig, userEntity);
                    } catch (Exception e) {
                        log.error("订单：{}，商家接单通知发送失败，失败原因：{}", order.getOrderId(), e);
                    }
                });
            }

            // 在锁中提交事务
            transactionManager.commit(status);
        } catch (Exception e) {
            if (ObjectUtil.isNotNull(status)) {
                transactionManager.rollback(status);
            }
            log.error("订单【{}】支付成功状态修改失败，异常信息【{}】", order.getOrderId(), e.getMessage());
            throw new SqxException("订单状态修改失败，" + e);
        } finally {
            lock.unlock();
        }

        // 添加消息记录并且进行推送
        MyGlobalThreadPool.execute(() -> {
            try {
                addOrderMessageAndPush(order, goodsShop, mpPushConfig, userEntity);
            } catch (Exception e) {
                log.error("订单：{}，订单支付成功通知发送失败，失败原因：{}", order.getOrderId(), e);
            }
        });

        // 订单已接单或者当前订单为预约订单时打印小票
        if (order.getStatus() == 6 || reservationFlag) {
            // 打印小票
            if (StringUtils.isNotEmpty(goodsShop.getSnCode())) {
                MyGlobalThreadPool.execute(() -> {
                    try {
                        // 设置订单商品
                        List<OrderGoods> orderGoodsList = orderGoodsDao.selectList(new QueryWrapper<OrderGoods>().eq("order_id", order.getOrderId()));
                        order.setOrderGoodsList(orderGoodsList);

                        // 设置店铺名称
                        order.setShopName(goodsShop.getShopName());

                        FeiYunUtils.print(goodsShop.getSnCode(), null, order, null);
                    } catch (Exception e) {
                        log.error("订单：{}，小票打印失败，失败原因：{}", order.getOrderId(), e);
                    }
                });
            }
        }
    }

    @Override
    public void finishOrderByShop(OrderFinishByShopDTO orderFinishByShopDTO) {
        Long orderId = orderFinishByShopDTO.getOrderId();
        RLock lock = redissonClient.getLock(String.format(RedisKey.FINISH_ORDER_LOCK, orderId));
        lock.lock();
        try {
            TbOrder order = getById(orderId);

            if (ObjectUtil.isNull(order)) {
                throw new SqxException("无效的订单id");
            }
            if (order.getAutoSendOrder() != null && order.getAutoSendOrder() == 0) {
                throw new SqxException("当前订单为自动派单，不能手动完成！");
            }

            if (order.getStatus().equals(4)) {
                return;
            }

            Long shopId = order.getShopId();
            SysUserEntity currentUser = (SysUserEntity) SecurityUtils.getSubject().getPrincipal();
            List<SysUserShop> sysUserShops = sysUserService.selectShopId(currentUser.getUserId());
            if (CollUtil.isEmpty(sysUserShops) || !sysUserShops.stream().filter(e -> e.getShopId().longValue() == shopId.longValue()).findFirst().isPresent()) {
                throw new SqxException("没有操作权限，只能操作完成自己店铺订单！");
            }

            if (Constant.YES.equals(orderFinishByShopDTO.getSendSmsFlag())) {
                TbIndent indent = tbIndentService.getOne(new QueryWrapper<TbIndent>().eq("order_id", orderId));
                if (ObjectUtil.isNull(indent)) {
                    return;
                }

                // 如果是外卖订单
                if (ObjectUtil.equal(indent.getIndentType(), "5")) {
                    Long smsTemplateId = orderFinishByShopDTO.getSmsTemplateId();
                    if (ObjectUtil.isNull(smsTemplateId)) {
                        throw new SqxException("短信模板id不能为空");
                    }

                    // 收货人手机
                    String userPhone = indent.getUserPhone();

                    if (StrUtil.isBlank(userPhone)) {
                        return;
                    }

                    // 店铺信息
                    GoodsShop goodsShop = goodsShopDao.selectById(shopId);
                    // 查询短信发送费用
                    CommonInfo commonInfo = commonInfoService.findOne(421);
                    // 店铺钱包
                    UserMoney userMoney = userMoneyService.selectUserMoneyByUserId(goodsShop.getUserId());
                    if (userMoney.getMoney().compareTo(new BigDecimal(commonInfo.getValue())) < 0) {
                        throw new SqxException("当前店铺余额不够，短信发送失败！");
                    }

                    // 发送短信并记录短信发送记录
                    SmsSendResult smsSendResult = smsTemplateService.sendSms(smsTemplateId, goodsShop.getPhone(), goodsShop.getShopName(), goodsShop.getShopId(), userPhone);

                    // sourceType 1骑手、2商家
                    smsSendLogService.saveLog(indent.getIndentId(), "2", smsSendResult);
                }
            }

            if (StrUtil.isNotBlank(orderFinishByShopDTO.getImgs())) {
                order.setDeliveryImgs(orderFinishByShopDTO.getImgs());
                updateById(order);
            }

            log.info("商户自配完成订单：{},订单状态：{}", orderId, order.getStatus());
            accomplishOrder(orderId, 1);
        } finally {
            lock.unlock();
        }
    }

    @Override
    public void addReceiveImg(Long orderId, String img) {
        TbOrder order = getById(orderId);

        if (ObjectUtil.isNull(order)) {
            throw new SqxException("无效的订单id");
        }

        order = new TbOrder();
        order.setOrderId(orderId);
        order.setDeliveryImgs(img);
        updateById(order);
    }

    @Override
    public List<Long> getCurWaitReceivingOrderIds() {
        return baseMapper.selectCurWaitReceivingOrderIds();
    }

    @Override
    public List<OrderGoods> getOrderGoods(Long orderId) {
        return orderGoodsDao.selectList(new QueryWrapper<OrderGoods>().eq("order_id", orderId));
    }

    @Override
    public int countByShopIdAndUserId(Long shopId, Long userId, Long orderId) {
        LambdaQueryWrapper<TbOrder> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(TbOrder::getShopId, shopId);
        queryWrapper.eq(TbOrder::getUserId, userId);
        queryWrapper.ne(ObjectUtil.isNotNull(orderId), TbOrder::getOrderId, orderId);
        // 订单已支付
        queryWrapper.eq(TbOrder::getIsPay, 1);
        // // 5 订单已取消
        // queryWrapper.ne(TbOrder::getStatus, 5);
        return this.count(queryWrapper);
    }

    @Override
    public int countByShopIdAndActivityIdAndUserIdAndCurDate(Long shopId, Long activityId, Long userId, Long orderId) {
        return baseMapper.countByShopIdAndActivityIdAndUserIdAndCurDate(shopId, activityId, userId, orderId);
    }

    /**
     * 用户钱包新增消费记录
     *
     * @param order 订单信息
     */
    private void addConsumeRecordInUserMoneyDetail(TbOrder order) {
        // 本来就是钱包支付的，前面已经记录了钱包消费记录，这里不要重复记录
        if (order.getPayType() == 2) {
            return;
        }

        userMoneyService.addConsumeRecord(order);
    }

    /**
     * 发送订单接单消息
     *
     * @param order        订单信息
     * @param goodsShop    店铺信息
     * @param mpPushConfig 小程序推送设置
     * @param userEntity   用户信息
     */
    private void sendOrderAcceptMessage(TbOrder order, GoodsShop goodsShop, CommonInfo mpPushConfig, UserEntity userEntity) {
        List<String> msgList = new ArrayList<>();
        String shopName = goodsShop.getShopName();
        String orderNum1 = order.getOrderNumber();
        msgList.add("商家已接单");
        msgList.add(orderNum1);
        msgList.add(shopName);
        msgList.add(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        userService.pushToSingle("商家已接单", "亲爱的用户您好，商家已接单，请耐心等待！", userEntity.getClientid());

        SenInfoCheckUtil.sendMsg(userEntity.getOpenId(), mpPushConfig.getValue(), msgList, 1);
    }

    /**
     * 添加订单消息并推送消息
     *
     * @param order        订单信息
     * @param goodsShop    店铺信息
     * @param mpPushConfig 小程序推送设置
     * @param userEntity   用户信息
     */
    private void addOrderMessageAndPush(TbOrder order, GoodsShop goodsShop, CommonInfo mpPushConfig, UserEntity userEntity) {
        String currentDateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        // 用户消息
        MessageInfo userMessageInfo = new MessageInfo();

        userMessageInfo.setTitle("下单");
        userMessageInfo.setContent("恭喜您，下单成功！");
        userMessageInfo.setCreateAt(currentDateStr);
        userMessageInfo.setUserId(order.getUserId().toString());
        userMessageInfo.setUserName(userEntity.getUserName());
        messageInfoDao.insert(userMessageInfo);

        // 商家消息
        MessageInfo shopMessageInfo = new MessageInfo();
        shopMessageInfo.setTitle("有新订单");
        shopMessageInfo.setCreateAt(currentDateStr);
        shopMessageInfo.setContent("有新订单，请及时处理！");
        shopMessageInfo.setShopId(order.getShopId());
        shopMessageInfo.setReadFlag(2);
        shopMessageInfo.setIsSee("2");
        messageInfoDao.insert(shopMessageInfo);


        // 商户消息模板
        CommonInfo shopTemplate = commonInfoService.findOne(352);
        UserEntity shopUser = userService.selectUserById(goodsShop.getUserId());

        // 用户端消息推送
        List<String> userMsgList = new ArrayList<>();
        userMsgList.add("下单成功");
        userMsgList.add(order.getOrderCode());
        userMsgList.add(goodsShop.getShopName());
        userMsgList.add(currentDateStr);
        SenInfoCheckUtil.sendMsg(userEntity.getOpenId(), mpPushConfig.getValue(), userMsgList, 1);

        // 无个推
        // userService.pushToSingle("下单成功", "亲爱的用户您好，您已下单成功，请等待商家接单！", userEntity.getClientid());

        // 商户端消息推送
        List<String> shopMsgShopList = new ArrayList<>();
        shopMsgShopList.add(order.getOrderNumber());
        shopMsgShopList.add(order.getPayMoney().toString());
        shopMsgShopList.add(order.getPayTime());
        shopMsgShopList.add("生意来了，立即去接单>");
        if (StringUtils.isNotEmpty(shopUser.getShopOpenId())) {
            SenInfoCheckUtil.sendShopMsg(shopUser.getShopOpenId(), shopTemplate.getValue(), shopMsgShopList, 7);
        }
        if (StringUtils.isNotEmpty(shopUser.getShopClientId())) {
            userService.pushToSingleShop("下单成功", "生意来了，立即去接单>", shopUser.getShopClientId());
        }
    }

    /**
     * 更新优惠券状态 更新订单状态
     *
     * @param order 订单信息
     */
    private void updateCouponState(TbOrder order) {
        if (order.getCouponId() != null) {
            TbCouponUser tbCouponUser = new TbCouponUser();
            tbCouponUser.setId(order.getCouponId());
            tbCouponUser.setStatus(1);
            tbCouponUserDao.updateById(tbCouponUser);
        }
    }

    /**
     * 生成取餐号
     *
     * @return 订单号
     */
    private String generateOrderCode() {
        String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        TbOrder preOrder = orderGoodsDao.selectByPayTime(format);

        String orderCode;
        if (preOrder == null) {
            String a = new SimpleDateFormat("yyyyMMdd").format(new Date());
            orderCode = a + "001";
        } else {
            Long a = Long.parseLong(preOrder.getOrderCode()) + 1;
            orderCode = a.toString();
        }

        return orderCode;
    }

    /**
     * 计算店铺收益 店铺订单收益=订单应付金额+订单使用的优惠券金额-跑腿费用
     *
     * @param order     订单信息
     * @param goodsShop 店铺信息
     */
    private void calcShopIncome(TbOrder order, GoodsShop goodsShop) {
        BigDecimal shopRate = goodsShop.getShopRate();
        BigDecimal sumMoney = order.getPayMoney();

        sumMoney = sumMoney.add(order.getCouponMoney());
        if (order.getAutoSendOrder() == 0) {
            sumMoney = sumMoney.subtract(goodsShop.getErrandMoney());
        }

        BigDecimal shopMoney = sumMoney.multiply(shopRate);
        order.setShopIncomeMoney(shopMoney.setScale(2, BigDecimal.ROUND_DOWN));

        log.info("preOrder==>[{}]，订单计算店铺预计收益，商家佣金比例[{}]，本单用户应付金额[{}]，本单店铺预计收益[{}]",
                order.getOrderId(), shopRate, sumMoney, order.getShopIncomeMoney());
    }

    /**
     * 校验订单优惠券信息
     *
     * @param order 订单信息
     * @return 使用的优惠券金额
     */
    private void checkCoupon(TbOrder order, Long userId) {
        if (order.getCouponId() == null) {
            order.setCouponMoney(BigDecimal.ZERO);

            return;
        }

        TbCouponUser tbCouponUser = tbCouponUserDao.selectById(order.getCouponId());
        // 订单应付金额
        BigDecimal payMoney = order.getPayMoney();

        if (!tbCouponUser.getUserId().equals(userId)) {
            throw new SqxException("优惠券与登录用户不匹配");
        }
        if (tbCouponUser.getStatus() != 0) {
            throw new SqxException("该优惠券已失效");
        }
        if (tbCouponUser.getMinMoney().doubleValue() > payMoney.doubleValue()) {
            throw new SqxException("订单金额不足，无法使用该优惠券");
        }
        if (tbCouponUser.getShopId() != 0 && !tbCouponUser.getShopId().equals(order.getShopId())) {
            throw new SqxException("优惠券使用错误，请刷新后重试");
        }

        BigDecimal couponUserMoney = tbCouponUser.getMoney();
        payMoney = payMoney.subtract(couponUserMoney);
        //如果使用红包后，订单价格小于0，则改为0.01元
        if (payMoney.doubleValue() <= 0) {
            payMoney = new BigDecimal("0.01");
        }

        // 更新订单总金额
        order.setPayMoney(payMoney);

        order.setCouponMoney(couponUserMoney);

        log.info("preOrder==>[{}]，订单匹配到优惠券，优惠券ID[{}]，优惠卷金额[{}]",
                order.getOrderId(), order.getCouponId(), couponUserMoney);
        log.info("preOrder==>[{}]，订单使用优惠券后应付金额[{}]",
                order.getOrderId(), order.getPayMoney());
    }

    /**
     * 校验配送范围、配送费
     *
     * @param order     订单信息
     * @param addressId 用户收货地址id
     * @param goodsShop 店铺信息
     */
    private void checkAddress(TbOrder order, Long addressId, GoodsShop goodsShop) {
        // 如果时外卖订单
        if (order.getOrderType() == 2) {
            if (addressId == null) {
                throw new SqxException("请填写地址地址！");
            }
            Address address = addressService.getById(addressId);

            // 计算用户位置到商户位置的距离，并判断是否在配送范围内
            double distance = DistanceUtil.distance(goodsShop.getShopLat(), goodsShop.getShopLng(), address.getLat(), address.getLng());
            if (distance > goodsShop.getDistributionDistance()) {
                throw new SqxException("超出商家配送范围，无法点餐！");
            }

            // 店铺是否开启配送费满减 0是 1否
            Integer enableFullReductionFlag = goodsShop.getEnableFullReductionFlag() != null ? goodsShop.getEnableFullReductionFlag() : 1;
            // 店铺跑腿费
            BigDecimal shopErrandMoney = goodsShop.getErrandMoney() != null ? goodsShop.getErrandMoney() : BigDecimal.ZERO;
            // 减免配送费最小订单金额
            BigDecimal exemptMinMoney = goodsShop.getExemptMinMoney() != null ? goodsShop.getExemptMinMoney() : BigDecimal.ZERO;
            // 店铺是否开启自动派单 0开启 1关闭
            Integer autoSendOrder = goodsShop.getAutoSendOrder() == 0 ? 0 : 1;

            // 店铺开启了配送费满减
            if (enableFullReductionFlag == 0) {
                if (shopErrandMoney.doubleValue() > 0
                        && order.getPayMoney().doubleValue() < exemptMinMoney.doubleValue()) {
                    // 跑腿费加入订单总金额
                    order.setPayMoney(order.getPayMoney().add(shopErrandMoney));
                    order.setErrandMoneyIsShop("本单未达到商家满减金额，跑腿费由用户承担");
                } else {
                    order.setErrandMoneyIsShop("本单已达到商家满减金额，跑腿费由商家承担");
                    // 店铺关闭自动派单，则为商家自己配送订单，跑腿金额设置为0
                    if (autoSendOrder == 1) {
                        shopErrandMoney = BigDecimal.ZERO;
                    }
                }
            }
            // 店铺未开启配送费满减
            else {
                // 跑腿费加入订单总金额
                order.setPayMoney(order.getPayMoney().add(shopErrandMoney));
                order.setErrandMoneyIsShop("商家未开启配送费满减，跑腿费由用户承担");
            }

            order.setErrandMoney(shopErrandMoney);

            // 判断订单金额是否大于最低起送金额
            if (goodsShop.getMinimumDelivery() == null) {
                goodsShop.setMinimumDelivery(BigDecimal.valueOf(0));
            }

            if (order.getPayMoney().doubleValue() < goodsShop.getMinimumDelivery().doubleValue()) {
                throw new SqxException("订单金额未满足最低起送金额！");
            }

            // 设置地址信息
            String addressJson = JSONObject.toJSONString(address);
            order.setAddress(addressJson);
            order.setAddressId(addressId);

            // 设置是否自动派单
            order.setAutoSendOrder(autoSendOrder);
        } else {
            // 设置是否自动派单 自取订单autoSendOrder设置为1
            order.setAutoSendOrder(1);

            // 跑腿费设置为0
            order.setErrandMoney(BigDecimal.ZERO);
        }

        log.info("preOrder==>[{}]，订单跑腿费计算结束，跑腿费[{}]，当前订单应付总价[{}]",
                order.getOrderId(), order.getErrandMoney(), order.getPayMoney());
    }

    /**
     * 计算商品总价格和商品总打包费
     *
     * @param parentOrder 订单信息
     */
    private void calcOrderPriceAndPack(TbOrder parentOrder) {
        log.info("preOrder==>[{}]，开始计算订单金额", parentOrder.getOrderId());

        // 商品总打包费 初始为0
        BigDecimal goodsPack = BigDecimal.valueOf(0);
        // 商品总价格 初始为0，商品总价格包含总打包费
        BigDecimal payMoney = BigDecimal.valueOf(0);
        List<TbOrder> orderList = selectOrderByParentId(parentOrder.getOrderId());
        if (orderList.size() == 0) {
            throw new SqxException("订单不存在，请刷新后重试！");
        }
        for (int i = 0; i < orderList.size(); i++) {
            Long orderId = orderList.get(i).getOrderId();
            List<OrderGoods> orderGoodsList = orderGoodsDao.selectList(
                    new QueryWrapper<OrderGoods>()
                            .eq("order_id", orderId));
            for (int a = 0; a < orderGoodsList.size(); a++) {
                OrderGoods orderGoods = orderGoodsList.get(a);
                BigDecimal goodsNum = new BigDecimal(orderGoods.getGoodsNum());
                BigDecimal goodsPrice = orderGoods.getGoodsPrice();
                BigDecimal goodsPacks = orderGoods.getGoodsPack();

                // 当前子订单总打包费
                BigDecimal sumGoodsPack = goodsNum.multiply(goodsPacks);
                // 当前子订单总商品价格
                BigDecimal multiply1 = goodsNum.multiply(goodsPrice);
                // 当前子订单总打包费计入父订单总打包费
                goodsPack = goodsPack.add(sumGoodsPack);
                // 当前子订单总商品价格计入父订单总商品价格
                payMoney = payMoney.add(multiply1);
                // 当前子订单总打包费计入入父订单总商品价格
                payMoney = payMoney.add(sumGoodsPack);

                log.info("preOrder==>[{}]，订单商品[{}]，单价[{}]，打包价[{}]，数量[{}]",
                        parentOrder.getOrderId(), orderGoods.getGoodsName(), goodsPrice, goodsPacks, goodsNum);
                log.info("preOrder==>[{}]，订单商品[{}]小计，商品小计[{}]，打包价小计[{}]",
                        parentOrder.getOrderId(), orderGoods.getGoodsName(), multiply1, sumGoodsPack);
                log.info("preOrder==>[{}]，订单累计，当前商品[{}]加入后，订单总价[{}]，其中打包总价[{}]",
                        parentOrder.getOrderId(), orderGoods.getGoodsName(), payMoney, goodsPack);
            }
        }

        // 订单设置订单总金额
        parentOrder.setPayMoney(payMoney);
        parentOrder.setPackMoney(goodsPack);

        log.info("preOrder==>[{}]，订单价格计算结束，订单总价[{}]，其中打包总价[{}]",
                parentOrder.getOrderId(), payMoney, goodsPack);
    }

    private void checkOrderGoods(TbOrder order) {
        Long orderId = order.getOrderId();
        // 获取订单商品信息
        List<OrderGoods> orderGoodsList = orderGoodsDao.selectList(
                new QueryWrapper<OrderGoods>()
                        .eq("order_id", orderId));
        for (int b = 0; b < orderGoodsList.size(); b++) {
            OrderGoods orderGoods = orderGoodsList.get(b);
            Long goodsId = orderGoods.getGoodsId();
            Goods goods = goodsDao.selectById(goodsId);
            if (goods == null || goods.getStatus().equals(1)) {
                // TODO ？？感觉有问题？？
                orderGoodsDao.deleteById(orderGoods.getId());
                throw new SqxException("商品：" + orderGoods.getGoodsName() + ",不存在，请刷新后重试！");
            }

            GoodsShopRelevancy goodsShopRelevancy = goodsShopRelevancyDao.selectOne(
                    new QueryWrapper<GoodsShopRelevancy>()
                            .eq("goods_id", goodsId)
                            .eq("shop_id", order.getShopId()));
            int i = goodsShopRelevancyDao.selectGoodsCount(orderId, goodsId);
            if (goodsShopRelevancy.getInventory() < i) {
                throw new SqxException("库存不足");
            }
        }
    }

    @Override
    public Result joinOrder(Long userId, Long orderId, Long shopId, Long goodsId, Integer num, Long skuId, String skuMessage) {
        // 判断当前时间是否在店铺营业范围内
        if (!isShopBusinessTime(shopId)) {
            return Result.error("店铺已打烊！");
        }

        //先判断该商品的库存是否足够
        GoodsShopRelevancy goodsShopRelevancy = goodsShopRelevancyDao.selectOne(new QueryWrapper<GoodsShopRelevancy>()
                .eq("shop_id", shopId).eq("goods_id", goodsId));
        if (goodsShopRelevancy.getInventory() < num) {
            return Result.error("该商品库存不足！");
        }
        Goods goods = goodsDao.selectById(goodsId);
        OrderGoods orderGoods = orderGoodsDao.selectOne(new QueryWrapper<OrderGoods>().eq("order_id", orderId).eq("goods_id", goods.getGoodsId()).eq("sku_id", skuId).eq("user_id", userId));
        if (orderGoods != null) {
            orderGoods.setGoodsNum(orderGoods.getGoodsNum() + 1);
            orderGoodsDao.updateById(orderGoods);
        } else {
            //添加订单-商品表
            orderGoods = new OrderGoods();
            orderGoods.setOrderId(orderId);
            orderGoods.setGoodsName(goods.getGoodsName());
            orderGoods.setSkuId(skuId);
            orderGoods.setGoodsPrice(goods.getGoodsMoney());
            orderGoods.setSkuMessage(skuMessage);
            orderGoods.setGoodsNum(num);
            orderGoods.setGoodsPack(goods.getPackMoney());
            orderGoods.setGoodsPicture(goods.getGoodsCover());
            orderGoods.setGoodsId(goods.getGoodsId());
            orderGoods.setUserId(userId);
            orderGoodsDao.insert(orderGoods);
        }

        return Result.success();
    }


    @Transactional
    @Override
    public Result buyGoods(Long userId, Long shopId, Long goodsId, Integer num, Long skuId, String skuMessage, Integer orderType) {
        // 判断当前时间是否在店铺营业范围内
        if (!isShopBusinessTime(shopId)) {
            return Result.error("店铺已打烊！");
        }

        //先判断该商品的库存是否足够
        GoodsShopRelevancy goodsShopRelevancy = goodsShopRelevancyDao.selectOne(new QueryWrapper<GoodsShopRelevancy>().eq("shop_id", shopId).eq("goods_id", goodsId));
        if (goodsShopRelevancy.getInventory() < num) {
            return Result.error("该商品库存不足！");
        }
        Goods goods = goodsDao.selectById(goodsId);
        UserEntity userEntity = userDao.selectById(userId);
        TbOrder tbOrder = new TbOrder();
        tbOrder.setUserId(userId);
        tbOrder.setUserName(userEntity.getUserName());
        tbOrder.setPhone(userEntity.getPhone());
        tbOrder.setOrderNumber(getGeneralOrder());
        tbOrder.setIsPay(0);
        tbOrder.setDeleteFlag(0);
        tbOrder.setStatus(2);
        tbOrder.setShopId(shopId);
        //创建订单，订单发起人就是该登录用户
        tbOrder.setParentUserId(userId);
        //   tbOrder.setPackMoney(goods.getPackMoney());
        //  tbOrder.setOrderType(orderType);
        tbOrder.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        /*if (orderType == 2) {
            CommonInfo one = commonInfoService.findOne(123);
            Double value = Double.valueOf(one.getValue());
            tbOrder.setErrandMoney(BigDecimal.valueOf(value));
        }*/
        appOrderDao.insertOrder(tbOrder);

        OrderGoods orderGoods = new OrderGoods();
        orderGoods.setOrderId(tbOrder.getOrderId());
        orderGoods.setGoodsName(goods.getGoodsName());
        orderGoods.setSkuId(skuId);
        GoodsSku goodsSku = goodsSkuDao.selectById(skuId);
        orderGoods.setGoodsPrice(goodsSku.getSkuPrice());
        orderGoods.setSkuMessage(skuMessage);
        orderGoods.setGoodsNum(num);
        orderGoods.setGoodsPack(goods.getPackMoney());
        orderGoods.setGoodsPicture(goods.getGoodsCover());
        orderGoods.setGoodsId(goods.getGoodsId());
        orderGoods.setUserId(userId);
        orderGoodsDao.insert(orderGoods);

        BigDecimal multiply = orderGoods.getGoodsPrice().multiply(new BigDecimal(num));
        TbOrder tbOrder1 = new TbOrder();
        tbOrder1.setOrderId(tbOrder.getOrderId());
        tbOrder1.setParentId(tbOrder.getOrderId());
        tbOrder1.setPayMoney(multiply);
        appOrderDao.updateById(tbOrder1);
        return Result.success().put("data", tbOrder.getOrderId());
    }

    @Override
    public Result echoOrder(Long userId, Long shopId, Long goodsId) {
        TbOrder tbOrder = appOrderDao.selectOne(new QueryWrapper<TbOrder>().eq("user_id", userId).eq("shop_id", shopId).eq("status", 1));
        if (tbOrder == null) {
            return Result.error("用户在该商铺没有订单");
        }
        Long orderId = tbOrder.getOrderId();
        List<OrderGoods> orderGoodsList = orderGoodsDao.selectList(new QueryWrapper<OrderGoods>().eq("order_id", orderId).eq("goods_id", goodsId));
        return Result.success().put("data", orderGoodsList);
    }




    /*public Result insertOrder1(Long userId, Long shopId, Long goodsId, Integer num, Long skuId, String skuMessage, Integer orderType) {
        //判断该用户在该商店有没有订单，没有的话创建订单，有的话加入订单
        List<TbOrder> tbOrder1 = appOrderDao.selectList(new QueryWrapper<TbOrder>()
                .eq("user_id", userId).eq("shop_id", shopId).eq("status", 1));

        if(tbOrder1==null) {
            Goods goods = goodsDao.selectById(goodsId);
            UserEntity userEntity = userDao.selectById(userId);
            net.sf.json.JSONObject goodsJson = net.sf.json.JSONObject.fromObject(goods);

            TbOrder order = new TbOrder();
            order.setUserId(userId);
            order.setUserName(userEntity.getUserName());
            order.setPhone(userEntity.getPhone());
            order.setOrderNumber(getGeneralOrder());
            order.setIsPay(0);
            order.setDeleteFlag(0);
            order.setStatus(1);
        //    order.setNum(num);
            order.setShopId(shopId);
            //创建订单，订单发起人就是该登录用户
            order.setParentUserId(userId);
            order.setPackMoney(goods.getPackMoney());
            order.setOrderType(orderType);
            order.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            if (orderType == 2) {
                CommonInfo one = commonInfoService.findOne(121);
                Double value = Double.valueOf(one.getValue());
                order.setErrandMoney(BigDecimal.valueOf(value));
            }
            appOrderDao.insertOrder(order);
            TbOrder tbOrder = new TbOrder();
            tbOrder.setOrderId(order.getOrderId());
            tbOrder.setParentId(order.getOrderId());
            appOrderDao.updateById(tbOrder);
        }
        return Result.success();
    }*/


    @Override
    public TbOrder selectOrderByNum(String orderNum) {
        TbOrder tbOrder = appOrderDao.selectOne(new QueryWrapper<TbOrder>().eq("order_number", orderNum));
        //插入优惠券金额
        if (tbOrder.getCouponId() != null) {
            TbCouponUser tbCouponUser = tbCouponUserDao.selectById(tbOrder.getCouponId());
            tbOrder.setCouponMoney(tbCouponUser.getMoney());
        }
        return tbOrder;
    }

    @Override
    public Result selectAllOrder(Integer page, Integer limit, Integer status, String phone, Long shopId, String userName, String orderNumber, Integer orderType, String shopName, String transactionId) {
        Page<TbOrder> pages = new Page<>(page, limit);
        IPage<TbOrder> tbOrderIPage = appOrderDao.selectOrder(pages, status, phone, shopId, userName, orderNumber, orderType, shopName, transactionId);
        for (int i = 0; i < tbOrderIPage.getRecords().size(); i++) {
            List<OrderGoods> orderGoodsList = orderGoodsDao.selectList(new QueryWrapper<OrderGoods>()
                    .eq("order_id", tbOrderIPage.getRecords().get(i).getOrderId()));
            tbOrderIPage.getRecords().get(i).setOrderGoodsList(orderGoodsList);
            //todo
            /*BigDecimal packMoney = BigDecimal.valueOf(0);
            for (int a = 0; a < orderGoodsList.size(); a++) {
                packMoney = packMoney.add(tbOrderIPage.getRecords().get(i).getPackMoney());
            }
            tbOrderIPage.getRecords().get(i).setPackMoney(packMoney);*/
        }
        PageUtils pageUtils = new PageUtils(tbOrderIPage);
        return Result.success().put("data", pageUtils);
    }


    @Override
    public Result selectAllOrderAdmin(OrderQueryDto queryDto) {
        Page<TbOrder> pages = new Page<>(queryDto.getPage(), queryDto.getLimit());
//        pages.setOptimizeCountSql(false);
//        pages.setSearchCount(false);
//        pages.setTotal()

//        if (org.springframework.util.StringUtils.hasText(queryDto.getEndTime())) {
//            queryDto.setEndTime(queryDto.getEndTime() + " 23:59:59");
//        }
//         if (org.springframework.util.StringUtils.hasText(queryDto.getPayEndTime())) {
//             queryDto.setPayEndTime(queryDto.getPayEndTime() + " 23:59:59");
//         }
//        if (org.springframework.util.StringUtils.hasText(queryDto.getStartTime())) {
//            queryDto.setStartTime(queryDto.getStartTime() + " 00:00:00");
//        }
//         if (org.springframework.util.StringUtils.hasText(queryDto.getPayStartTime())) {
//             queryDto.setPayStartTime(queryDto.getPayStartTime() + " 00:00:00");
//         }
        IPage<TbOrder> tbOrderIPage = appOrderDao.selectAllOrderAdmin(pages, queryDto);
        for (int i = 0; i < tbOrderIPage.getRecords().size(); i++) {
            List<OrderGoods> orderGoodsList = orderGoodsDao.selectList(new QueryWrapper<OrderGoods>()
                    .eq("order_id", tbOrderIPage.getRecords().get(i).getOrderId()));
            tbOrderIPage.getRecords().get(i).setOrderGoodsList(orderGoodsList);
        }
        PageUtils pageUtils = new PageUtils(tbOrderIPage);
        return Result.success().put("data", pageUtils);
    }

    @Override
    public ExcelData excelAllOrderAdmin(OrderQueryDto queryDto) {
        if (org.springframework.util.StringUtils.hasText(queryDto.getEndTime())) {
            queryDto.setEndTime(queryDto.getEndTime() + " 23:59:59");
        }
        // if (org.springframework.util.StringUtils.hasText(queryDto.getPayEndTime())) {
        //     queryDto.setPayEndTime(queryDto.getPayEndTime() + " 23:59:59");
        // }
        if (org.springframework.util.StringUtils.hasText(queryDto.getStartTime())) {
            queryDto.setStartTime(queryDto.getStartTime() + " 00:00:00");
        }
        // if (org.springframework.util.StringUtils.hasText(queryDto.getPayStartTime())) {
        //     queryDto.setPayStartTime(queryDto.getPayStartTime() + " 00:00:00");
        // }
        List<TbOrder> tbOrderIPage = appOrderDao.excelAllOrderAdmin(queryDto);
//        for (int i = 0; i < tbOrderIPage.size(); i++) {
//            List<OrderGoods> orderGoodsList = orderGoodsDao.selectList(new QueryWrapper<OrderGoods>()
//                    .eq("order_id", tbOrderIPage.get(i).getOrderId()));
//            tbOrderIPage.get(i).setOrderGoodsList(orderGoodsList);
//        }
        ExcelData data = new ExcelData();
        data.setName("订单列表");
        List<String> titles = new ArrayList();
        titles.add("编号");
        titles.add("下单用户");
        titles.add("用户头像");
        titles.add("手机号");
        titles.add("商铺信息");
        titles.add("订单类型");
        titles.add("配送信息");
        titles.add("骑手昵称");
        titles.add("骑手电话");
        titles.add("骑手接单时间");
        titles.add("订单号");
        titles.add("内容");
        titles.add("商品总价（元）");
        titles.add("优惠金额（元）");
        titles.add("参与活动名称");
        titles.add("活动优惠金额（元）");
        titles.add("打包费（元/个 具体按照数量计算）");
        titles.add("跑腿费（元）");
        titles.add("支付金额（元）");
        titles.add("跑腿费说明");
        titles.add("订单备注");
        titles.add("支付时间");
        titles.add("支付方式");
        titles.add("取餐号");
        titles.add("状态");
        titles.add("是否转单");
        titles.add("骑手站点");
        titles.add("商铺类型名称");
        titles.add("优惠券类型");

        data.setTitles(titles);
        List<List<Object>> rows = new ArrayList();
        for (TbOrder order : tbOrderIPage) {
            List<Object> row = new ArrayList();
            row.add(order.getOrderId());
            row.add(order.getUserName());
            row.add(order.getAvatar());
            if (ObjectUtils.isNotEmpty(order.getPhone())) {
                row.add(order.getPhone().replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"));
            }else {
                row.add(order.getPhone());
            }
            StringBuffer stringBuffer = new StringBuffer();
            stringBuffer.append("店铺名称：").append(StringUtils.isNotBlank(order.getShopName()) ? order.getShopName() : "")
                    .append("\n").append("店铺电话：").append(StringUtils.isNotBlank(order.getShopPhone()) ? order.getShopPhone() : "")
                    .append("\n").append("店铺地址：").append(StringUtils.isNotBlank(order.getDetailedAddress()) ? order.getDetailedAddress() : "");
            row.add(stringBuffer.toString());
            if (order.getOrderTypeExtra() != null && order.getOrderTypeExtra() == 1) {
                row.add("到店取餐");
            } else if (order.getOrderTypeExtra() != null && order.getOrderTypeExtra() == 2) {
                row.add("外卖配送");
            } else if (order.getOrderTypeExtra() != null && order.getOrderTypeExtra() == 3) {
                row.add("商家配送");
            } else {
                row.add("");
            }
            if (StringUtils.isNotEmpty(order.getAddress())) {
                JSONObject jsonObject = JSONObject.parseObject(order.getAddress());

                stringBuffer = new StringBuffer();
                stringBuffer.append("订餐人：").append(jsonObject.getString("userName")).append("\n").append("订餐人电话：").append(jsonObject.getString("userPhone")).append("\n").append("订餐地址：").append(jsonObject.getString("addressDetail"));
                row.add(stringBuffer.toString());
            } else {
                row.add("-");
            }
            row.add(order.getRiderNickName());
            row.add(order.getRiderPhone());
            row.add(order.getReceivingTime());
            row.add(order.getOrderNumber());
//            stringBuffer=new StringBuffer();
//            BigDecimal sumGoodsPrice=BigDecimal.ZERO;
//            List<OrderGoods> orderGoodsList = order.getOrderGoodsList();
//            for(int i=0;i<orderGoodsList.size();i++){
//                OrderGoods orderGoods = orderGoodsList.get(i);
//                stringBuffer.append(i + 1).append(". 商品名：").append(orderGoods.getGoodsName()).append(",数量：").append(orderGoods.getGoodsNum()).append(",规格：").append(orderGoods.getSkuMessage());
//                if(orderGoods.getGoodsPrice()!=null && orderGoods.getGoodsNum()!=null){
//                    BigDecimal goodsPrice = orderGoods.getGoodsPrice().multiply(BigDecimal.valueOf(orderGoods.getGoodsNum()));
//                    sumGoodsPrice=sumGoodsPrice.add(goodsPrice);
//                }
//            }
            row.add(order.getDetail());
            row.add(order.getSumPrice());
            row.add(order.getCouponMoney());
            row.add(order.getActivityTitle());
            row.add(order.getActivityDiscountAmount());
            row.add(order.getPackMoney());
            row.add(order.getErrandMoney());
            row.add(order.getPayMoney());

            row.add(order.getErrandMoneyIsShop());
            row.add(order.getRemark());
            row.add(order.getPayTime());
            //支付方式  1微信支付  2余额支付  3支付宝支付
            if (order.getPayType() != null && order.getPayType() == 1) {
                row.add("微信支付");
            } else if (order.getPayType() != null && order.getPayType() == 2) {
                row.add("余额支付");
            } else if (order.getPayType() != null && order.getPayType() == 3) {
                row.add("支付宝支付");
            } else {
                row.add("");
            }

            row.add(order.getOrderCode());
            //订单状态 0待结算 1待支付 2直接购买（未支付） 7商家待接单 8商家拒绝接单 6制作中  3待取餐/派送中 4已完成 5已取消
            if (order.getStatus() != null && order.getStatus() == 0) {
                row.add("待结算");
            } else if (order.getStatus() != null && order.getStatus() == 1) {
                row.add("待支付");
            } else if (order.getStatus() != null && order.getStatus() == 2) {
                row.add("直接购买（未支付）");
            } else if (order.getStatus() != null && order.getStatus() == 3) {
                row.add("待取餐/派送中");
            } else if (order.getStatus() != null && order.getStatus() == 4) {
                row.add("已完成");
            } else if (order.getStatus() != null && order.getStatus() == 5) {
                row.add("已取消");
            } else if (order.getStatus() != null && order.getStatus() == 6) {
                row.add("制作中");
            } else if (order.getStatus() != null && order.getStatus() == 7) {
                row.add("商家待接单");
            } else if (order.getStatus() != null && order.getStatus() == 8) {
                row.add("商家拒绝接单");
            } else {
                row.add("");
            }
            if (order.getIsRider() != null && order.getIsRider() == 1) {
                row.add("是");
            } else {
                row.add("");
            }
            row.add(order.getStationName());
            row.add(order.getShopTypeName());
            row.add(order.getCouponTypeRemark());
            rows.add(row);
        }
        data.setRows(rows);
        return data;
    }


    @Override
    public Result selectOrderByUserId(Long userId, String date, String dateType) {
        HashMap hashMap = new HashMap();
        int count = appOrderDao.selectCountOrderByUserId(userId, date, dateType);
        BigDecimal bigDecimal = appOrderDao.selectSunMoneyByUserId(userId, date, dateType);
        hashMap.put("bigDecimal", bigDecimal);
        hashMap.put("count", count);
        return Result.success().put("data", hashMap);
    }

    @Override
    public Result selectOrderDetails(Integer page, Integer limit, Long userId) {
        Page<TbOrder> pages = new Page<>(page, limit);
        IPage<TbOrder> tbOrderIPage = appOrderDao.selectOrderDetails(pages, userId);
        for (int i = 0; i < tbOrderIPage.getRecords().size(); i++) {
            Long orderId = tbOrderIPage.getRecords().get(i).getOrderId();
            List<OrderGoods> orderGoodsList = orderGoodsDao.selectList(new QueryWrapper<OrderGoods>().eq("order_id", orderId));
            tbOrderIPage.getRecords().get(i).setOrderGoodsList(orderGoodsList);
        }


        PageUtils pageUtils = new PageUtils(tbOrderIPage);
        return Result.success().put("data", pageUtils);
    }

    @Override
    public Result waitTakeFood(Long userId, Integer orderType, Integer page, Integer limit, Integer status) {
        Page<TbOrder> pages = new Page<>(page, limit);
        IPage<TbOrder> tbOrderIPage = appOrderDao.waitTakeFood(pages, userId, orderType, status);
        List<TbOrder> records = tbOrderIPage.getRecords();
        int size = records.size();
        for (int i = 0; i < size; i++) {
            List<OrderGoods> orderGoodsList = orderGoodsDao.selectList(new QueryWrapper<OrderGoods>()
                    .eq("order_id", records.get(i).getOrderId()));
            tbOrderIPage.getRecords().get(i).setOrderGoodsList(orderGoodsList);
            //判断骑手是否接单 status13为待骑手接单
//            if (records.get(i).getOrderTypeExtra() == 2 && "2".equals(records.get(i).getIndentState())) {
//                tbOrderIPage.getRecords().get(i).setStatus(13);
//            }
        }
        PageUtils pageUtils = new PageUtils(tbOrderIPage);
        return Result.success().put("data", pageUtils);
    }

    @Override
    public List<TbOrder> selectOrderByParentId(Long parentId) {
        List<TbOrder> tbOrder = appOrderDao.selectList(new QueryWrapper<TbOrder>().eq("parent_id", parentId));
        return tbOrder;
    }

    @Override
    public Result selectOrderById(Long orderId) {
        TbOrder tbOrder = appOrderDao.selectByOrderId(orderId);

        if (ObjectUtil.isNull(tbOrder)) {
            throw new SqxException("无效的订单id");
        }

        int i = appOrderDao.selectCountOrderByTime(tbOrder.getPayTime(), tbOrder.getShopId());
        tbOrder.setCountOrder(i);
        if (tbOrder.getCouponId() != null) {
            TbCouponUser tbCouponUser = tbCouponUserDao.selectById(tbOrder.getCouponId());
            tbOrder.setCouponMoney(tbCouponUser.getMoney());
        }
        GoodsShop goodsShop = goodsShopDao.selectById(tbOrder.getShopId());
        if (goodsShop != null) {
            tbOrder.setShopName(goodsShop.getShopName());
            tbOrder.setShopPhone(goodsShop.getPhone());
        }
//        if (tbOrder.getOrderTypeExtra() == 2 && "2".equals(tbOrder.getIndentState())) {
//            tbOrder.setStatus(13);
//        }
        List<OrderGoods> orderGoodsList = orderGoodsDao.selectList(new QueryWrapper<OrderGoods>().eq("order_id", tbOrder.getOrderId()));
        tbOrder.setOrderGoodsList(orderGoodsList);
        TbIndent tbIndent = tbIndentService.getOne(new QueryWrapper<TbIndent>().eq("order_id", tbOrder.getOrderId()));
        if (ObjectUtils.isNotEmpty(tbIndent)) {
            tbOrder.setReceivingTime(tbIndent.getReceivingTime());
            tbOrder.setFinishTime(tbIndent.getFinishTime());
        }

        return Result.success().put("data", tbOrder);
    }

    @Override
    public TbOrder selectOrderByIds(Long orderId) {
        TbOrder tbOrder = appOrderDao.selectByOrderId(orderId);
        int i = appOrderDao.selectCountOrderByTime(tbOrder.getPayTime(), tbOrder.getShopId());
        tbOrder.setCountOrder(i);
        if (tbOrder.getCouponId() != null) {
            TbCouponUser tbCouponUser = tbCouponUserDao.selectById(tbOrder.getCouponId());
            tbOrder.setCouponMoney(tbCouponUser.getMoney());
        }
        List<OrderGoods> orderGoodsList = orderGoodsDao.selectList(new QueryWrapper<OrderGoods>().eq("order_id", tbOrder.getOrderId()));
        tbOrder.setOrderGoodsList(orderGoodsList);
        GoodsShop goodsShop = shopMessageService.getShopInfoById(tbOrder.getShopId());
        if (goodsShop != null) {
            tbOrder.setShopName(goodsShop.getShopName());
        }
        return tbOrder;
    }


    @Transactional
    @Override
    public Result updateGoodsNum(Long orderGoodsId, Integer type, Integer num, Long shopId) {
        // type = 1增加商品数  = 2 减少商品数
        OrderGoods orderGoods = orderGoodsDao.selectById(orderGoodsId);
        if (orderGoods == null) {
            return Result.error("系统繁忙，请稍后再试！");
        }
        GoodsShopRelevancy goodsShopRelevancy = goodsShopRelevancyDao.selectOne(new QueryWrapper<GoodsShopRelevancy>()
                .eq("shop_id", shopId)
                .eq("goods_id", orderGoods.getGoodsId()));

        if (type == 1 && goodsShopRelevancy.getInventory() <= orderGoods.getGoodsNum()) {
            return Result.error("该商品库存不足，不能再添加商品！");
        }
        if (type == 1) {
            OrderGoods orderGoods1 = new OrderGoods();
            orderGoods1.setId(orderGoodsId);
            orderGoods1.setGoodsNum(orderGoods.getGoodsNum() + num);
            orderGoodsDao.updateById(orderGoods1);
        } else {
            if (orderGoods.getGoodsNum() <= 1) {
                orderGoodsDao.deleteById(orderGoodsId);
            } else {
                OrderGoods orderGoods2 = new OrderGoods();
                orderGoods2.setId(orderGoodsId);
                orderGoods2.setGoodsNum(orderGoods.getGoodsNum() - num);
                orderGoodsDao.updateById(orderGoods2);
            }
        }
        return Result.success();
    }

    @Override
    public Result emptyShoppingTrolley(Long userId, Long shopId) {
        appOrderDao.delete(new QueryWrapper<TbOrder>().eq("user_id", userId).eq("shop_id", shopId).eq("status", 1));
        return Result.success();
    }

    @Override
    public Result employCoupon(Long userId, Long parentId, Long couponId) {
        TbOrder tbOrder = appOrderDao.selectById(parentId);
        TbCouponUser tbCouponUser = tbCouponUserDao.selectById(couponId);

        TbOrder tbOrder1 = new TbOrder();
        tbOrder1.setOrderId(tbOrder.getOrderId());
        tbOrder1.setCouponId(tbCouponUser.getId());
        appOrderDao.updateById(tbOrder1);
        return Result.success();
    }

    @Override
    public Result deleteCouponByOrderId(Long orderId) {
        appOrderDao.deleteCouponByOrderId(orderId);
        return Result.success();
    }

    @Override
    public Result print(Long orderId, Integer isAppend) {
        // 查询订单信息
        TbOrder tbOrder = selectOrderByIds(orderId);
        Long shopId = tbOrder.getShopId();

        // 查询店铺信息
        GoodsShop goodsShop = goodsShopDao.selectById(shopId);

        if (StringUtils.isNotEmpty(goodsShop.getSnCode())) {
            FeiYunUtils.print(goodsShop.getSnCode(), null, tbOrder, isAppend);
        } else {
            return Result.error("当前商家未绑定打印机！");
        }
        return Result.success();
    }

    @Transactional
    public Result updateOrders(TbOrder order) {
        String format1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        TbOrder tbOrder = selectOrderByIds(order.getOrderId());
        if (order.getStatus() == 6) {
            if (tbOrder.getStatus().equals(6)) {
                return Result.success();
            }

            if (tbOrder.getStatus() != 7) {
                throw new SqxException("订单状态异常，请刷新页面后重试！");
            }

            String reservationFlag = tbOrder.getReservationFlag();
            if (StrUtil.equals(reservationFlag, Constant.YES)) {
                Date now = new Date();
                Date expectDeliveryTime = tbOrder.getExpectDeliveryTime();
                if (ChronoUnit.SECONDS.between(now.toInstant(), expectDeliveryTime.toInstant()) > 3600) {
                    throw new SqxException("预约订单只能在期望送达时间前1小时内进行接单!");
                }
            }

            // 修改订单状态
            order.setStatus(6);
            //商家接单
            order.setShopReceivingTime(format1);

            // 生成跑腿订单
            tbIndentService.insertIndent(tbOrder);


            //设置小程序消息推送
            CommonInfo one = commonInfoService.findOne(269);
            List<String> msgList = new ArrayList<>();
            Long shopId = tbOrder.getShopId();
            GoodsShop goodsShop = shopMessageService.selectShopId(shopId);
            String shopName = goodsShop.getShopName();
            String orderNum1 = tbOrder.getOrderNumber();
            msgList.add("商家已接单");
            msgList.add(orderNum1);
            msgList.add(shopName);
            msgList.add(format1);
            UserEntity userEntity = userDao.selectById(tbOrder.getUserId());
            userService.pushToSingle("商家已接单", "亲爱的用户您好，商家已接单，请耐心等待！", userEntity.getClientid());

            //计算商户应得金额
            BigDecimal shopRate = goodsShop.getShopRate();
            BigDecimal sumMoney = tbOrder.getPayMoney();
            if (tbOrder.getCouponId() != null) {
                TbCouponUser tbCouponUser = tbCouponUserDao.selectById(tbOrder.getCouponId());
                sumMoney = tbOrder.getPayMoney().add(tbCouponUser.getMoney());
            }
            if (tbOrder.getAutoSendOrder() == 0) {
                //再减去商户需要支付的配送费
                sumMoney = sumMoney.subtract(goodsShop.getErrandMoney());
            }

            BigDecimal shopMoney = sumMoney.multiply(shopRate);
            shopMoney = (shopMoney.setScale(2, BigDecimal.ROUND_DOWN));
            tbOrder.setShopIncomeMoney(shopMoney);

            SenInfoCheckUtil.sendMsg(userEntity.getOpenId(), one.getValue(), msgList, 1);

            // 如果是预约订单，则不再打印小票（订单支付的时候已经打印过了）
            if (!StrUtil.equals(tbOrder.getReservationFlag(), Constant.YES)) {
                if (StringUtils.isNotEmpty(goodsShop.getSnCode())) {
                    FeiYunUtils.print(goodsShop.getSnCode(), null, tbOrder, null);
                }
            }
        } else if (order.getStatus() == 3) {
            if (tbOrder.getStatus().equals(3)) {
                return Result.success();
            }

            if (!tbOrder.getStatus().equals(6)) {
                throw new SqxException("当前订单制作完成失败，非制作中订单不能制作完成。【订单id：" + tbOrder.getOrderId() + "，订单状态：" + tbOrder.getStatus() + "】");
            }

            MessageInfo messageInfo = new MessageInfo();
            messageInfo.setTitle("餐品制作完成");
            if (tbOrder.getOrderType() == 1) {
                messageInfo.setContent("您的餐品已制作完成，请及时取餐");
            } else if (tbOrder.getOrderType() == 2) {
                messageInfo.setContent("您的餐品已制作完成，正在配送中");
                // 用户支付成功后，即创建跑腿状态为2的订单
                //如果是外卖订单,则修改外卖订单的状态
                // GoodsShop goodsShop = goodsShopDao.selectById(tbOrder.getShopId());
                // if (goodsShop.getAutoSendOrder() == 0) {
                //     TbIndent tbIndent = tbIndentDao.selectOne(new QueryWrapper<TbIndent>().eq("order_id", tbOrder.getOrderId()));
                //     TbIndent tbIndent1 = new TbIndent();
                //     tbIndent1.setIndentId(tbIndent.getIndentId());
                //     tbIndent1.setCreateTime(format1);
                //     tbIndent1.setIndentState("2");
                //     tbIndentService.updateById(tbIndent1);
                //     tbIndentService.sendNewIndentMsg(tbIndent);
                // }
            }
            messageInfo.setCreateAt(format1);
            messageInfo.setUserId(tbOrder.getUserId().toString());

            MyGlobalThreadPool.execute(() -> {
                try {
                    messageInfoDao.insert(messageInfo);
                    //设置小程序消息推送
                    CommonInfo one = commonInfoService.findOne(269);
                    List<String> msgList = new ArrayList<>();
                    Long shopId = tbOrder.getShopId();
                    GoodsShop goodsShop = goodsShopDao.selectById(shopId);
                    String shopName = goodsShop.getShopName();
                    String orderNum1 = tbOrder.getOrderNumber();

                    msgList.add("已制作完成");
                    msgList.add(orderNum1);
                    msgList.add(shopName);
                    msgList.add(format1);

                    UserEntity userEntity = userDao.selectById(tbOrder.getUserId());
                    SenInfoCheckUtil.sendMsg(userEntity.getOpenId(), one.getValue(), msgList, 1);
                    // userService.pushToSingle("制作完成", "亲爱的用户您好，您的订单已制作完成，请耐心等待配送！", userEntity.getClientid());
                } catch (Exception e) {
                    log.error("订单制作完成通知发送失败，订单id:" + order.getOrderId() + "，异常消息：" + e.getMessage());
                }
            });
        } else if (order.getStatus() == 4) {
            if (tbOrder.getStatus().equals(4)) {
                return Result.success();
            }
            log.info("操作完成订单4：" + order.getOrderId());
            Result result = this.accomplishOrder(order.getOrderId(), 1);
            if ("500".equals(String.valueOf(result.get("code")))) {
                return result;
            }
            //管理端完成订单，则消息通知用户
            MyGlobalThreadPool.execute(() -> {
                try {
                    MessageInfo messageInfo = new MessageInfo();
                    messageInfo.setTitle("订单完成");
                    messageInfo.setContent("您的订单已完成，欢迎下次光临");
                    messageInfo.setCreateAt(format1);
                    messageInfo.setUserId(tbOrder.getUserId().toString());
                    messageInfoDao.insert(messageInfo);
                    //设置小程序消息推送
                    CommonInfo one = commonInfoService.findOne(269);
                    List<String> msgList = new ArrayList<>();
                    Long shopId = tbOrder.getShopId();
                    GoodsShop goodsShop = goodsShopDao.selectById(shopId);
                    String shopName = goodsShop.getShopName();
                    String orderNum1 = tbOrder.getOrderNumber();
                    msgList.add("订单完成");
                    msgList.add(orderNum1);
                    msgList.add(shopName);
                    msgList.add(format1);
                    UserEntity userEntity = userDao.selectById(tbOrder.getUserId());
                    SenInfoCheckUtil.sendMsg(userEntity.getOpenId(), one.getValue(), msgList, 1);
                    // userService.pushToSingle("订单完成", "亲爱的用户您好，您的订单已完成，欢迎下次光临！", userEntity.getClientid());
                } catch (Exception e) {
                    log.error("订单完成通知发送失败，订单id:" + order.getOrderId() + "，异常消息：" + e.getMessage());
                }
            });
        } else if (order.getStatus() == 8) {
            if (tbOrder.getStatus().equals(8) || tbOrder.getStatus().equals(5)) {
                return Result.success();
            }

            if (tbOrder.getStatus() == 4) {
                throw new SqxException("订单处于完成状态，不允许退单");
            }

            UserEntity userEntity = userDao.selectById(tbOrder.getUserId());
            // 已支付判断支付方式
            if (tbOrder.getPayType() == 2) {
                //余额支付，直接退还钱包
                userMoneyDao.updateMayMoney(1, tbOrder.getUserId(), tbOrder.getPayMoney().doubleValue());
            } else if (tbOrder.getPayType() == 1) {
                PayDetails payDetails = payDetailsDao.selectByOrderId(tbOrder.getOrderNumber());
                boolean b = wechatPayRefund(payDetails);
                if (!b) {
                    return Result.error("退款失败，请联系客服！");
                }
            } else {
                PayDetails payDetails = payDetailsDao.selectByOrderId(tbOrder.getOrderNumber());
                String code = AliPayController.alipayRefund(payDetails);
                if (StringUtils.isNotBlank(code)) {
                    log.error(code);
                    JSONObject jsonObject = JSON.parseObject(code);
                    JSONObject alipay_trade_refund_response = jsonObject.getJSONObject("alipay_trade_refund_response");
                    String code1 = alipay_trade_refund_response.getString("code");
                    if (!"10000".equals(code1)) {
                        return Result.error("退款失败！" + alipay_trade_refund_response.getString("sub_msg"));
                    }
                } else {
                    return Result.error("退款失败！");
                }
            }
//            tbOrder.setStatus(5);
            //            退款状态需要改成8
            tbOrder.setStatus(8);
            appOrderDao.updateById(tbOrder);
            //添加退款记录
            UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
            userMoneyDetails.setUserId(tbOrder.getUserId());
            userMoneyDetails.setTitle("退款");
            userMoneyDetails.setType(1);
            userMoneyDetails.setClassify(3);
            userMoneyDetails.setState(2);
            userMoneyDetails.setMoney(tbOrder.getPayMoney());
            userMoneyDetails.setContent("商家拒绝接单，退款到账：" + tbOrder.getPayMoney() + "元，退款按原路返回");
            userMoneyDetails.setCreateTime(format1);
            userMoneyDetailsDao.insert(userMoneyDetails);
            //判断是否使用优惠券
            if (tbOrder.getCouponId() != null) {
                TbCouponUser tbCouponUser = tbCouponUserDao.selectById(tbOrder.getCouponId());
                tbCouponUser.setStatus(0);
                tbCouponUserDao.updateById(tbCouponUser);
            }

            // 取消跑腿订单
            tbIndentService.sysCancelOrder(tbOrder.getOrderNumber());

            //设置小程序消息推送
            CommonInfo one = commonInfoService.findOne(266);
            List<String> msgList = new ArrayList<>();
            msgList.add(tbOrder.getOrderNumber());
            msgList.add("商家拒绝接单订单");
            msgList.add(tbOrder.getPayMoney().toString());
            msgList.add(format1);
            SenInfoCheckUtil.sendMsg(userEntity.getOpenId(), one.getValue(), msgList, 3);
            userService.pushToSingle("下单失败", "抱歉，商家已拒绝接单，给您带来不便请谅解，如有疑问可联系客服！", userEntity.getClientid());

            List<OrderGoods> orderGoodsList = orderGoodsDao.selectList(new QueryWrapper<OrderGoods>().eq("order_id", tbOrder.getOrderId()));
            for (int a = 0; a < orderGoodsList.size(); a++) {
                OrderGoods orderGoods = orderGoodsList.get(a);
                Integer goodsNum = orderGoods.getGoodsNum();
                Long goodsId = orderGoodsList.get(a).getGoodsId();
                GoodsShopRelevancy goodsShopRelevancy = goodsShopRelevancyDao.selectOne(new QueryWrapper<GoodsShopRelevancy>()
                        .eq("shop_id", tbOrder.getShopId()).eq("goods_id", goodsId));
                GoodsShopRelevancy goodsShopRelevancy1 = new GoodsShopRelevancy();
                goodsShopRelevancy1.setId(goodsShopRelevancy.getId());
                goodsShopRelevancy1.setSales(goodsShopRelevancy.getSales() - goodsNum);//加销量
                goodsShopRelevancy1.setInventory(goodsShopRelevancy.getInventory() + goodsNum);//减库存
                goodsShopRelevancyDao.updateById(goodsShopRelevancy1);
                goodsShopDao.updateShopSales(2, goodsNum, goodsShopRelevancy.getShopId());
            }

            return Result.success("取消订单成功！");
        }
        order.setUpdateTime(format1);
        baseMapper.updateById(order);
        return Result.success();
    }

    /**
     * 微信支付退款
     *
     * @param payDetails 支付订单
     */
    private boolean wechatPayRefund(PayDetails payDetails) {
        boolean b;
        // tradeNo不为null表示是新支付，否则为原生微信支付
        if (StrUtil.isNotBlank(payDetails.getTradeNo())) {
            b = newPayService.wechatRefund(payDetails.getOrderId());
        } else {
            b = wxErrService.wxRefund(payDetails);
        }
        return b;
    }


    @Override
    public Result updateOrder(TbOrder order) {
        RLock lock = redissonClient.getLock(String.format(RedisKey.UPDATE_ORDER_LOCK, order.getOrderId()));
        lock.lock();
        try {
            return updateOrders(order);
        } finally {
            lock.unlock();
        }
    }

    /**
     * @param orderId
     * @param type    1用户操作 2自动任务超时直接完成订单
     * @return
     */
    @Override
    public Result accomplishOrder(Long orderId, Integer type) {
        TransactionStatus status = null;
        RLock lock = redissonClient.getLock(String.format(RedisKey.FINISH_ORDER_LOCK, orderId));
        lock.lock();
        try {
            status = transactionManager.getTransaction(new DefaultTransactionDefinition());

            Result result = doAccomplishOrders(orderId, type);

            transactionManager.commit(status);
            return result;
        } catch (Exception e) {
            if (ObjectUtil.isNotNull(status)) {
                transactionManager.rollback(status);
            }
            throw e;
        } finally {
            lock.unlock();
        }
    }

    /**
     * @param orderId
     * @param type    1用户操作 2自动任务超时直接完成订单
     * @return
     */
    public Result doAccomplishOrders(Long orderId, Integer type) {
        log.info("订单id:{}，类型：{}", orderId, type);
        TbOrder tbOrder = appOrderDao.selectById(orderId);
        if (tbOrder.getStatus().equals(4)) {
            log.warn("订单id【{}】，订单状态为【4】，属于已完成状态，直接返回", orderId);
            log.warn("订单id【{}】，accomplishOrders逻辑执行完成", orderId);
            return Result.success();
        }
        String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        TbIndent indent = tbIndentService.getOne(new QueryWrapper<TbIndent>().eq("order_id", orderId));
        if (tbOrder.getAutoSendOrder() != null && tbOrder.getAutoSendOrder().equals(0)) {
            if (type == 1) {
                if (indent == null || !"4".equals(indent.getIndentState())) {
                    log.warn("订单id【{}】,请等待骑手送达！", orderId);
                    return Result.error("请等待骑手送达！");
                }
            }

            // 修改跑腿订单的状态和给骑手佣金
            TbIndent newTbIndent = new TbIndent();
            newTbIndent.setIndentId(indent.getIndentId());
            newTbIndent.setIndentState("6");
            newTbIndent.setFinishTime(DateUtils.format(new Date()));
            tbIndentService.updateById(newTbIndent);

            tbIndentService.finshIndent(tbOrder.getUserId(), indent.getIndentNumber());
        }

        tbOrder.setStatus(4);
        log.info("订单id【{}】,开始计算商户应得金额", orderId);

        GoodsShop goodsShop = shopMessageService.selectShopId(tbOrder.getShopId());

        // 计算商户应得金额
        BigDecimal shopRate = goodsShop.getShopRate();
        BigDecimal sumMoney = tbOrder.getPayMoney();
        BigDecimal couponMoney = BigDecimal.ZERO;
        Long shopIds = -1L;
        if (tbOrder.getCouponId() != null) {
            TbCouponUser tbCouponUser = tbCouponUserDao.selectById(tbOrder.getCouponId());
            sumMoney = tbOrder.getPayMoney().add(tbCouponUser.getMoney());
            couponMoney = tbCouponUser.getMoney();
            shopIds = tbCouponUser.getShopId();
        }

        BigDecimal errandMoney = BigDecimal.ZERO;
        if (tbOrder.getOrderType() != 1) {
            //判断是否达到商家满减  如果达到商家满减 跑腿费让商家承担
            if (tbOrder.getAutoSendOrder() != null && tbOrder.getAutoSendOrder() == 0) {
                errandMoney = tbOrder.getErrandMoney();
                sumMoney = sumMoney.subtract(tbOrder.getErrandMoney());
            } else {
                sumMoney = sumMoney.subtract(tbOrder.getErrandMoney());
                errandMoney = tbOrder.getErrandMoney();
            }
        }

        // 店铺收入
        BigDecimal shopMoney = sumMoney.multiply(shopRate);
        shopMoney = shopMoney.setScale(2, BigDecimal.ROUND_DOWN);
        BigDecimal pingRate = sumMoney.subtract(shopMoney);

        // 商家配送短信服务费
        BigDecimal smsSendMoney = BigDecimal.ZERO;
        if (tbOrder.getAutoSendOrder() != null && tbOrder.getAutoSendOrder() == 1) {
            // 查询短信发送结果
            if (ObjectUtil.isNotNull(indent)) {
                TbIndentSmsSendLog smsSendLog = smsSendLogService.getSendSuccessByOrderId(indent.getIndentId());
                if (ObjectUtil.isNotNull(smsSendLog)) {
                    // 查询短信发送费用
                    CommonInfo commonInfo = commonInfoService.findOne(421);
                    smsSendMoney = new BigDecimal(commonInfo.getValue());

                    // 店铺收入-短信费用
                    shopMoney = shopMoney.subtract(smsSendMoney);
                }
            }
        }

        // 这里再判断 是否是商家优惠券  如果是商家优惠券  这笔钱商家承担
        if (shopIds != -1 && shopIds != 0) {
            shopMoney = shopMoney.subtract(couponMoney);
        }

        // 判断订单是否参与活动，如果参与活动，则优惠金额由商家承担
        ActivityPartRecord activityPartRecord = activityPartRecordService.getByOrderId(tbOrder.getOrderId());
        BigDecimal activityDiscountAmount = BigDecimal.ZERO;
        if (ObjectUtil.isNotNull(activityPartRecord)) {
            activityDiscountAmount = activityPartRecord.getDiscountAmount();
        }

        if (tbOrder.getAutoSendOrder() != null && tbOrder.getAutoSendOrder() == 1) {
            //如果达到商家满减 则商家不加上配送费
            if (!"本单已达到商家满减金额，跑腿费由商家承担".equals(tbOrder.getErrandMoneyIsShop())) {
                shopMoney = shopMoney.add(tbOrder.getErrandMoney());
            }
        } else {
            /*if("本单已达到商家满减金额，跑腿费由商家承担".equals(tbOrder.getErrandMoneyIsShop())){
                shopMoney=shopMoney.subtract(tbOrder.getErrandMoney());
            }*/
        }

        tbOrder.setShopIncomeMoney(shopMoney);
        appOrderDao.updateById(tbOrder);
        log.info("订单id【{}】,商户应得金额计算完毕", orderId);
        log.info("订单id【{}】,开始添加商户用户钱包收入记录", orderId);

        // 添加商户用户钱包收入记录
        UserMoneyDetails userMoneyDetails1 = new UserMoneyDetails();
        userMoneyDetails1.setShopId(goodsShop.getShopId());
        userMoneyDetails1.setTitle("商户订单收入，订单号：" + tbOrder.getOrderNumber());

        StringBuffer contentBuffer = new StringBuffer();
        // 订单金额
        BigDecimal orderAmount = tbOrder.getPayMoney().add(couponMoney).add(activityDiscountAmount);
        contentBuffer.append("订单金额:").append(orderAmount.setScale(2, BigDecimal.ROUND_DOWN));
        if (!couponMoney.equals(BigDecimal.ZERO)) {
            contentBuffer.append(",优惠券金额:").append(couponMoney.setScale(2, BigDecimal.ROUND_DOWN));
        }
        if (!activityDiscountAmount.equals(BigDecimal.ZERO)) {
            contentBuffer.append(",活动优惠金额:").append(activityDiscountAmount.setScale(2, BigDecimal.ROUND_DOWN));
        }

        contentBuffer.append(",用户实付金额:").append(tbOrder.getPayMoney()).append(",其中");

        if (tbOrder.getOrderType() != 1) {
            contentBuffer.append("跑腿费:").append(errandMoney.setScale(2, BigDecimal.ROUND_DOWN)).append("(").append(tbOrder.getErrandMoneyIsShop()).append(")").append(",");
        }

        contentBuffer.append("平台服务费:").append(pingRate.setScale(2, BigDecimal.ROUND_DOWN)).append(",");
        contentBuffer.append("短信服务费:").append(smsSendMoney.setScale(2, BigDecimal.ROUND_DOWN)).append(",");
        contentBuffer.append("到账金额:").append(shopMoney.setScale(2, BigDecimal.ROUND_DOWN));

        if (shopIds == 0) {
            contentBuffer.append("(本单为平台优惠券,平台补贴)");
        } else if (shopIds != -1) {
            contentBuffer.append("(本单为商家优惠券,商家补贴)");
        }

        userMoneyDetails1.setContent(contentBuffer.toString());

        userMoneyDetails1.setType(1);
        userMoneyDetails1.setClassify(3);
        userMoneyDetails1.setMoney(shopMoney);
        userMoneyDetails1.setCreateTime(format);
        userMoneyDetails1.setState(2);
        userMoneyDetailsDao.insert(userMoneyDetails1);
        log.info("订单id【{}】,商户用户钱包收入记录新增成功", orderId);

        //将用户支付的金额转入商户用户钱包
        userMoneyService.updateMoney(1, goodsShop.getUserId(), shopMoney.doubleValue());
        log.info("订单id【{}】,商户用户钱包收入更新成功", orderId);

        MyGlobalThreadPool.execute(() -> {
            try {
                // 计算积分
                String flag = commonInfoService.findOne(436).getValue();
                if ("1".equals(flag)) {
                    try {
                        UserIntegralDetails userIntegralDetails = new UserIntegralDetails();
                        String rules = commonInfoService.findOne(437).getValue();
                        String maxIntegral = commonInfoService.findOne(439).getValue();
                        String[] split = rules.split(",", 5);
                        int am1 = Integer.parseInt(split[0]);
                        int av1 = Integer.parseInt(split[1]);
                        int mx = Integer.parseInt(split[2]);
                        int am2 = Integer.parseInt(split[3]);
                        int av2 = Integer.parseInt(split[4]);
                        double amount = tbOrder.getPayMoney().doubleValue();
                        int intergral = 0;
                        if (amount > am1) {
                            if (amount < mx) {
                                intergral = intergral + (int) (amount / am1) * av1;
                            } else if (amount >= mx + am2) {
                                int count = (int) ((amount - mx) / am2);
                                intergral = intergral + (mx / am1) * av1 + count * av2;
                            } else {
                                intergral = intergral + (mx / am1) * av1;
                            }
                        }
                        int max = Math.min(Integer.parseInt(maxIntegral), intergral);
                        userIntegralDetails.setContent("完成订单获得积分");
                        userIntegralDetails.setClassify(4);
                        userIntegralDetails.setType(1);
                        userIntegralDetails.setNum(max);
                        userIntegralDetails.setOrderNumber(tbOrder.getOrderNumber());

                        userIntegralDetails.setCreateTime(format);
                        userIntegralDetails.setUserId(tbOrder.getUserId());
                        userIntegralDetailsDao.insert(userIntegralDetails);
                        // 添加积分
                        userIntegralDao.addUserIntegral(max, tbOrder.getUserId());
                    } catch (NumberFormatException e) {
                        log.error("订单{}====积分入账异常{}", orderId, e.getMessage());
                    }
                }

                // 用户通知
                MessageInfo messageInfo = new MessageInfo();
                messageInfo.setTitle("订单完成");
                messageInfo.setContent("您的订单已完成，欢迎下次光临");
                messageInfo.setCreateAt(format);
                messageInfo.setUserId(tbOrder.getUserId().toString());
                messageInfoDao.insert(messageInfo);
                //设置小程序消息推送
                CommonInfo one = commonInfoService.findOne(269);
                List<String> msgList = new ArrayList<>();

                String shopName = goodsShop.getShopName();
                String orderNum1 = tbOrder.getOrderNumber();
                msgList.add("订单完成");
                msgList.add(orderNum1);
                msgList.add(shopName);
                msgList.add(format);
                UserEntity userEntity = userDao.selectById(tbOrder.getUserId());

                SenInfoCheckUtil.sendMsg(userEntity.getOpenId(), one.getValue(), msgList, 1);

                // 商家通知
                String shopTemplate = commonInfoService.findOne(354).getValue();
                List<String> msgListShop = new ArrayList<>();
                msgListShop.add(indent.getIndentNumber());
                msgListShop.add("订单完成");
                msgListShop.add(DateUtils.format(new Date()));
                UserEntity shopUser = userService.selectUserById(goodsShop.getUserId());
                SenInfoCheckUtil.sendShopMsg(shopUser.getShopOpenId(), shopTemplate, msgListShop, 9);
            } catch (Exception e) {
                log.error("订单：{}，订单完成通知发送失败，失败原因：{}", e);
            }
        });

        log.info("订单id【{}】，accomplishOrders逻辑执行完成", orderId);
        return Result.success();
    }

    @Transactional
    @Override
    public Result insertEvaluate(Evaluate evaluate) {
        TbOrder tbOrder = new TbOrder();
        tbOrder.setCommentFlag(1);
        appOrderDao.update(tbOrder, new QueryWrapper<TbOrder>().eq("order_number", evaluate.getOrderNumber()));
//        判断是否有评价商家字段
        if (ObjectUtils.isNotEmpty(evaluate.getEvaluateMessage())&&ObjectUtils.isNotEmpty(evaluate.getScore())) {
            evaluate.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            evaluateDao.insert(evaluate);
            //重新计算并修改该商铺评分
            Evaluate evaluate1 = evaluateDao.selectScoreByShopId(evaluate.getShopId());
            Double score = evaluate1.getAllScore() / Double.valueOf(evaluate1.getEvaluatecount());
            GoodsShop goodsShop = new GoodsShop();
            goodsShop.setShopId(evaluate.getShopId());
            goodsShop.setShopScore(score);
            goodsShopDao.updateById(goodsShop);
        }
//        判断是否有评价骑手字段
        if (ObjectUtils.isNotEmpty(evaluate.getEvaluateRiderMessage())&&ObjectUtils.isNotEmpty(evaluate.getRiderScore())) {
//        添加骑手评价
            EvaluateRider evaluateRider = new EvaluateRider();
            evaluateRider.setUserId(evaluate.getUserId());
            evaluateRider.setOrderNumber(evaluate.getOrderNumber());
            evaluateRider.setShopId(evaluate.getShopId());
            evaluateRider.setRiderUserId(evaluate.getRiderUserId());
            evaluateRider.setEvaluateRiderMessage(evaluate.getEvaluateRiderMessage());
            evaluateRider.setRiderScore(evaluate.getRiderScore());
            evaluateRider.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            evaluateRiderService.save(evaluateRider);
        }
        return Result.success();
    }

    @Override
    public Result selectShoppingTrolley(Long userId) {
        List<TbOrder> tbOrderIPage = appOrderDao.selectShoppingTrolley(userId);
        for (int i = 0; i < tbOrderIPage.size(); i++) {
            Long orderId = tbOrderIPage.get(i).getOrderId();
            List<OrderGoods> orderGoods = orderGoodsDao.selectList(new QueryWrapper<OrderGoods>().eq("order_id", orderId));
            tbOrderIPage.get(i).setOrderGoodsList(orderGoods);
        }
        return Result.success().put("data", tbOrderIPage);
    }

    @Override
    public Result selectShoppingTrolleyByShopId(Long userId, Long shopId) {
        TbOrder tbOrders = appOrderDao.selectShoppingTrolleyByShopId(userId, shopId);
        List<OrderGoods> orderGoods = orderGoodsDao.selectList(new QueryWrapper<OrderGoods>().eq("order_id", tbOrders.getOrderId()));
        tbOrders.setOrderGoodsList(orderGoods);
        return Result.success().put("data", tbOrders);
    }


    @Override
    public Result userCancelOrder(Long orderId) {
        RLock lock = redissonClient.getLock(String.format(RedisKey.CANCEL_ORDER_LOCK, orderId));
        lock.lock();
        try {
            return userCancelOrders(orderId);
        } finally {
            lock.unlock();
        }
    }


    @Transactional
    public Result userCancelOrders(Long orderId) {
        String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        TbOrder tbOrder = appOrderDao.selectById(orderId);
        if (tbOrder.getStatus().equals(5) || tbOrder.getStatus().equals(8)) {
            return Result.success();
        }
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.MINUTE, -1);

        MessageInfo messageInfo1 = new MessageInfo();
        messageInfo1.setTitle("用户取消订单");
        messageInfo1.setCreateAt(DateUtils.format(new Date()));
        messageInfo1.setContent("用户取消订单，订单号：" + tbOrder.getOrderNumber());
        messageInfo1.setShopId(tbOrder.getShopId());
        messageInfo1.setReadFlag(2);
        messageInfo1.setIsSee("1");
        messageInfoDao.insert(messageInfo1);
        // if ((tbOrder.getStatus() == 6 && parse.getTime() > cal.getTime().getTime()) || (tbOrder.getStatus() == 7)) {
        if (tbOrder.getStatus() == 7) {
            UserEntity userEntity = userDao.selectById(tbOrder.getUserId());
            //已支付判断支付方式
            if (tbOrder.getPayType() == 2) {
                //余额支付，直接退还钱包
                userMoneyDao.updateMayMoney(1, tbOrder.getUserId(), tbOrder.getPayMoney().doubleValue());
            } else if (tbOrder.getPayType() == 1) {
                PayDetails payDetails = payDetailsDao.selectByOrderId(tbOrder.getOrderNumber());
                boolean b = wechatPayRefund(payDetails);
                if (!b) {
                    return Result.error("退款失败，请联系客服！");
                }
            } else {
                PayDetails payDetails = payDetailsDao.selectByOrderId(tbOrder.getOrderNumber());
                String code = AliPayController.alipayRefund(payDetails);
                if (StringUtils.isNotBlank(code)) {
                    log.error(code);
                    JSONObject jsonObject = JSON.parseObject(code);
                    JSONObject alipay_trade_refund_response = jsonObject.getJSONObject("alipay_trade_refund_response");
                    String code1 = alipay_trade_refund_response.getString("code");
                    if (!"10000".equals(code1)) {
                        return Result.error("退款失败！" + alipay_trade_refund_response.getString("sub_msg"));
                    }
                } else {
                    return Result.error("退款失败！");
                }
            }
            tbOrder.setStatus(5);
            appOrderDao.updateById(tbOrder);
            //添加退款记录
            UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
            userMoneyDetails.setUserId(tbOrder.getUserId());
            userMoneyDetails.setTitle("退款");
            userMoneyDetails.setType(1);
            userMoneyDetails.setClassify(3);
            userMoneyDetails.setState(2);
            userMoneyDetails.setMoney(tbOrder.getPayMoney());
            userMoneyDetails.setContent("退款到账：" + tbOrder.getPayMoney() + "元，退款按原路返回");
            userMoneyDetails.setCreateTime(format);
            userMoneyDetailsDao.insert(userMoneyDetails);
            //判断是否使用优惠券
            if (tbOrder.getCouponId() != null) {
                TbCouponUser tbCouponUser = tbCouponUserDao.selectById(tbOrder.getCouponId());
                tbCouponUser.setStatus(0);
                tbCouponUserDao.updateById(tbCouponUser);
            }
            //设置小程序消息推送
            CommonInfo one = commonInfoService.findOne(266);
            List<String> msgList = new ArrayList<>();
            msgList.add(tbOrder.getOrderNumber());
            msgList.add("用户取消订单");
            msgList.add(tbOrder.getPayMoney().toString());
            msgList.add(format);
            SenInfoCheckUtil.sendMsg(userEntity.getOpenId(), one.getValue(), msgList, 3);
            userService.pushToSingle("取消订单", "您已取消订单！", userEntity.getClientid());

            CommonInfo shopTemplate = commonInfoService.findOne(353);
            //商家通知
            List<String> msgShopList = new ArrayList<>();
            msgShopList.add(tbOrder.getOrderNumber());
            msgShopList.add(tbOrder.getPayMoney().toString());
            msgShopList.add("订单已取消，请前往查看>");

            Long shopId = tbOrder.getShopId();
            GoodsShop goodsShop = goodsShopDao.selectById(shopId);

            UserEntity shopUser = userService.selectUserById(goodsShop.getUserId());
            if (StringUtils.isNotEmpty(shopUser.getShopOpenId())) {
                SenInfoCheckUtil.sendShopMsg(shopUser.getShopOpenId(), shopTemplate.getValue(), msgShopList, 8);
            }
            if (StringUtils.isNotEmpty(shopUser.getShopClientId())) {
                userService.pushToSingleShop("取消订单", "订单已取消，请前往查看", shopUser.getShopClientId());
            }

            List<OrderGoods> orderGoodsList = orderGoodsDao.selectList(new QueryWrapper<OrderGoods>().eq("order_id", tbOrder.getOrderId()));
            for (int a = 0; a < orderGoodsList.size(); a++) {
                OrderGoods orderGoods = orderGoodsList.get(a);
                Integer goodsNum = orderGoods.getGoodsNum();
                Long goodsId = orderGoodsList.get(a).getGoodsId();
                GoodsShopRelevancy goodsShopRelevancy = goodsShopRelevancyDao.selectOne(new QueryWrapper<GoodsShopRelevancy>()
                        .eq("shop_id", tbOrder.getShopId()).eq("goods_id", goodsId));
                GoodsShopRelevancy goodsShopRelevancy1 = new GoodsShopRelevancy();
                goodsShopRelevancy1.setId(goodsShopRelevancy.getId());
                goodsShopRelevancy1.setSales(goodsShopRelevancy.getSales() - goodsNum);//加销量
                goodsShopRelevancy1.setInventory(goodsShopRelevancy.getInventory() + goodsNum);//减库存
                goodsShopRelevancyDao.updateById(goodsShopRelevancy1);
                goodsShopDao.updateShopSales(2, goodsNum, goodsShopRelevancy.getShopId());
            }

            // 取消跑腿订单
            tbIndentService.sysCancelOrder(tbOrder.getOrderNumber());

            return Result.success("取消订单成功！");
        }
        return Result.error("餐品正在制作中，无法退款！");
    }

    @Override
    public Result shopReplyEvaluate(String orderNumber, String shopReplyMessage) {
        Evaluate evaluate = new Evaluate();
        evaluate.setShopReplyMessage(shopReplyMessage);
        evaluateDao.update(evaluate, new QueryWrapper<Evaluate>().eq("order_number", orderNumber));
        return Result.success();
    }


    @Transactional
    @Override
    public Result deleteOrderList(List<Integer> orderId) {
        for (int i = 0; i < orderId.size(); i++) {
            baseMapper.deleteById(orderId.get(i));
        }
        return Result.success();
    }

    @Override
    public Result selectBuyGoods(Long userId, Long orderId) {
        //   TbOrder tbOrder = appOrderDao.selectOne(new QueryWrapper<TbOrder>().eq("order_id", orderId).eq("user_id", userId));
        TbOrder tbOrder = appOrderDao.selectBuyGoods(orderId, userId);
        List<OrderGoods> orderGoodsList = orderGoodsDao.selectList(new QueryWrapper<OrderGoods>().eq("order_id", tbOrder.getOrderId()));
        tbOrder.setOrderGoodsList(orderGoodsList);
        return Result.success().put("data", tbOrder);
    }

    @Override
    public Result adminCancelOrder(Long orderId) {
        RLock lock = redissonClient.getLock(String.format(RedisKey.CANCEL_ORDER_LOCK, orderId));
        lock.lock();
        try {
            return adminCancelOrders(orderId);
        } finally {
            lock.unlock();
        }
    }

    @Transactional
    public Result adminCancelOrders(Long orderId) {
        String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        TbOrder tbOrder = appOrderDao.selectById(orderId);
        if (tbOrder.getStatus() == 5 || tbOrder.getStatus() == 8) {
            return Result.success();
        }
        if (tbOrder.getIsPay() == 0) {
            //未支付直接取消
            TbOrder tbOrder1 = new TbOrder();
            tbOrder1.setOrderId(orderId);
            tbOrder1.setStatus(5);
            appOrderDao.updateById(tbOrder1);
        } else {
            if (tbOrder.getStatus() == 4) {
                throw new SqxException("订单处于完成状态，不允许退单");
            }

            UserEntity userEntity = userDao.selectById(tbOrder.getUserId());
            //已支付判断支付方式
            if (tbOrder.getPayType() == 2) {
                //余额支付，直接退还钱包
                userMoneyDao.updateMayMoney(1, tbOrder.getUserId(), tbOrder.getPayMoney().doubleValue());
            } else if (tbOrder.getPayType() == 1) {
                PayDetails payDetails = payDetailsDao.selectByOrderId(tbOrder.getOrderNumber());
                // 退款
                boolean b = wechatPayRefund(payDetails);
                if (!b) {
                    return Result.error("退款失败，请联系客服！");
                }
            } else {
                PayDetails payDetails = payDetailsDao.selectByOrderId(tbOrder.getOrderNumber());
                String code = AliPayController.alipayRefund(payDetails);
                if (StringUtils.isNotBlank(code)) {
                    log.error(code);
                    JSONObject jsonObject = JSON.parseObject(code);
                    JSONObject alipay_trade_refund_response = jsonObject.getJSONObject("alipay_trade_refund_response");
                    String code1 = alipay_trade_refund_response.getString("code");
                    if (!"10000".equals(code1)) {
                        return Result.error("退款失败！" + alipay_trade_refund_response.getString("sub_msg"));
                    }
                } else {
                    return Result.error("退款失败！");
                }
            }
//            tbOrder.setStatus(5);
            //            退款状态需要改成8
            tbOrder.setStatus(8);
            appOrderDao.updateById(tbOrder);

            // 取消跑腿订单
            tbIndentService.sysCancelOrder(tbOrder.getOrderNumber());

            //添加退款记录
            UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
            userMoneyDetails.setUserId(tbOrder.getUserId());
            userMoneyDetails.setTitle("退款");
            userMoneyDetails.setType(1);
            userMoneyDetails.setState(2);
            userMoneyDetails.setClassify(3);
            userMoneyDetails.setMoney(tbOrder.getPayMoney());
            userMoneyDetails.setContent("退款到账：" + tbOrder.getPayMoney() + "元，退款按原路返回");
            userMoneyDetails.setCreateTime(format);
            userMoneyDetailsDao.insert(userMoneyDetails);
            //判断是否使用优惠券
            if (tbOrder.getCouponId() != null) {
                TbCouponUser tbCouponUser = tbCouponUserDao.selectById(tbOrder.getCouponId());
                tbCouponUser.setStatus(0);
                tbCouponUserDao.updateById(tbCouponUser);
            }
            //设置小程序消息推送
            CommonInfo one = commonInfoService.findOne(266);
            List<String> msgList = new ArrayList<>();
            msgList.add(tbOrder.getOrderNumber());
            msgList.add("门店主动取消订单");
            msgList.add(tbOrder.getPayMoney().toString());
            msgList.add(format);
            SenInfoCheckUtil.sendMsg(userEntity.getOpenId(), one.getValue(), msgList, 3);
            userService.pushToSingle("下单失败", "亲爱的用户您好，商铺已取消您的订单，给您带来不便请谅解，如有疑问可联系客服！", userEntity.getClientid());

            CommonInfo shopTemplate = commonInfoService.findOne(353);
            //商家通知
            List<String> msgShopList = new ArrayList<>();
            msgShopList.add(tbOrder.getOrderNumber());
            msgShopList.add(tbOrder.getPayMoney().toString());
            msgShopList.add("订单已取消，请前往查看>");

            Long shopId = tbOrder.getShopId();
            GoodsShop goodsShop = goodsShopDao.selectById(shopId);

            UserEntity shopUser = userService.selectUserById(goodsShop.getUserId());
            if (StringUtils.isNotEmpty(shopUser.getShopOpenId())) {
                SenInfoCheckUtil.sendShopMsg(shopUser.getShopOpenId(), shopTemplate.getValue(), msgShopList, 8);
            }
            if (StringUtils.isNotEmpty(shopUser.getShopClientId())) {
                userService.pushToSingleShop("取消订单", "订单已取消，请前往查看", shopUser.getShopClientId());
            }

            List<OrderGoods> orderGoodsList = orderGoodsDao.selectList(new QueryWrapper<OrderGoods>().eq("order_id", orderId));
            for (int a = 0; a < orderGoodsList.size(); a++) {
                Integer goodsNum = orderGoodsList.get(a).getGoodsNum();
                Long goodsId = orderGoodsList.get(a).getGoodsId();
                GoodsShopRelevancy goodsShopRelevancy = goodsShopRelevancyDao.selectOne(new QueryWrapper<GoodsShopRelevancy>()
                        .eq("shop_id", tbOrder.getShopId()).eq("goods_id", goodsId));
                GoodsShopRelevancy goodsShopRelevancy1 = new GoodsShopRelevancy();
                goodsShopRelevancy1.setId(goodsShopRelevancy.getId());
                goodsShopRelevancy1.setSales(goodsShopRelevancy.getSales() - goodsNum);//加销量
                goodsShopRelevancy1.setInventory(goodsShopRelevancy.getInventory() + goodsNum);//减库存
                goodsShopRelevancyDao.updateById(goodsShopRelevancy1);
                goodsShopDao.updateShopSales(2, goodsNum, goodsShopRelevancy.getShopId());
            }

            // 打印退款小票
            try {
                tbOrder.setShopName(goodsShop.getShopName());
                FeiYunUtils.returnPrint(goodsShop.getSnCode(), tbOrder);
            } catch (Exception e) {
                log.error("订单：{}，退款小票打印失败", tbOrder.getOrderNumber());
            }
        }
        return Result.success();
    }


    @Override
    public Result selectOrderList(Long userId, Long shopId, Integer status, Integer orderType, Integer page, Integer limit) {
        HashMap hashMap = new HashMap();
        Page<TbOrder> pages = new Page(page, limit);
        IPage<TbOrder> tbOrderList = baseMapper.selectOrderList(pages, userId, status, orderType, shopId);
        BigDecimal money = new BigDecimal(0);
        ArrayList list = new ArrayList();
        for (int i = 0; i < tbOrderList.getRecords().size(); i++) {
            List<OrderGoods> orderGoodsList = orderGoodsDao.selectList(new QueryWrapper<OrderGoods>()
                    .eq("order_id", tbOrderList.getRecords().get(i).getOrderId()));
            for (int a = 0; a < orderGoodsList.size(); a++) {
                BigDecimal goodsPrice = orderGoodsList.get(a).getGoodsPrice();
                Integer goodsNum = orderGoodsList.get(a).getGoodsNum();
                BigDecimal multiply = goodsPrice.multiply(new BigDecimal(goodsNum));
                money = money.add(multiply);
            }
            list.add(orderGoodsList);
            tbOrderList.getRecords().get(i).setOrderGoodsList(list);
        }
        if (shopId != null && userId != null) {
            UserBrowse userBrowse = userBrowseDao.selectOne(new QueryWrapper<UserBrowse>().eq("user_id", userId).eq("by_browse_id", shopId).last("limit 1"));
            String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
            if (userBrowse != null) {
                userBrowse.setUpdateTime(format);
            } else {
                userBrowse = new UserBrowse();
                userBrowse.setUserId(userId);
                userBrowse.setByBrowseId(shopId);
                userBrowse.setUpdateTime(format);
                userBrowseDao.insert(userBrowse);
            }
        }
        PageUtils pageUtils = new PageUtils(tbOrderList);
        hashMap.put("pageUtils", pageUtils);
        hashMap.put("money", money);
        return Result.success().put("data", hashMap);
    }

    public String getGeneralOrder() {
        Date date = new Date();
        String newString = String.format("%0" + 4 + "d", (int) ((Math.random() * 9 + 1) * 1000));
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String format = sdf.format(date);
        return format + newString;
    }

    @Override
    public List<TbOrder> getProdIngOrders(LocalDateTime minusMinutes) {
        return baseMapper.selectMakeOrdersList(minusMinutes);
    }

    @Override
    public Result selectOrder(Long userId, Integer orderId, Integer page, Integer limit) {
        HashMap hashMap = new HashMap();
        Page<TbOrder> pages = new Page(page, limit);
        IPage<TbOrder> tbOrderList = baseMapper.selectOrderPage(pages, userId, orderId);
        BigDecimal money = new BigDecimal(0);
        ArrayList list = new ArrayList();
        for (int i = 0; i < tbOrderList.getRecords().size(); i++) {
            List<OrderGoods> orderGoodsList = orderGoodsDao.selectList(new QueryWrapper<OrderGoods>()
                    .eq("order_id", tbOrderList.getRecords().get(i).getOrderId()));
            for (int a = 0; a < orderGoodsList.size(); a++) {
                BigDecimal goodsPrice = orderGoodsList.get(a).getGoodsPrice();
                Integer goodsNum = orderGoodsList.get(a).getGoodsNum();
                BigDecimal multiply = goodsPrice.multiply(new BigDecimal(goodsNum));
                money = money.add(multiply);
            }
            list.add(orderGoodsList);
            tbOrderList.getRecords().get(i).setOrderGoodsList(list);
        }
        PageUtils pageUtils = new PageUtils(tbOrderList);
        hashMap.put("pageUtils", pageUtils);
        hashMap.put("money", money);
        return Result.success().put("data", hashMap);
    }

    @Override
    public Result updateTimeOutOrder(Long userId, Integer orderId) {
        RLock lock = redissonClient.getLock(String.format(RedisKey.TIME_OUT_LOCK, orderId));
        lock.lock();
        try {
            TbOrder tbOrder = baseMapper.selectById(orderId);
            if (ObjectUtils.isEmpty(tbOrder)) {
                return Result.error("该订单不存在");
            }
            Integer status = tbOrder.getStatus();
            if (status != 0) {
                return Result.error("当前订单不是待结算订单");
            }

            //region
            WXConfig config = new WXConfig();
//            当前都是小程序支付
            config.setAppId(commonInfoService.findOne(74).getValue());
            //微信商户key
            config.setKey(commonInfoService.findOne(250).getValue());
            //微信商户号mchId
            config.setMchId(commonInfoService.findOne(251).getValue());
            WXPay wxpay = new WXPay(config);

            WechatPayConfig wechatMchConfig = WechatPayConfig.builder()
                    .appId(commonInfoService.findOne(45).getValue())
                    .mchId(commonInfoService.findOne(434).getValue())
                    .mchKey(commonInfoService.findOne(435).getValue())
                    .h5Url(commonInfoService.findOne(19).getValue())
                    .build();

            PayDetails pd = payDetailsService.getByOrderNo(tbOrder.getOrderNumber());
            if (pd != null) {
                Integer state = pd.getState();
                if(0 == state){
                    //                    状态为待支付需要调用支付系统订单查询接口判断支付系统对应的订单状态
                    Map<String, String> data = new HashMap<>();
                    String orderNumber = tbOrder.getOrderNumber();
                    //商户订单号
                    data.put("out_trade_no", orderNumber);
                    Map<String, String> response = wxpay.orderQuery(data);
                    String trade_state = response.get("trade_state");
                    //SUCCESS—支付成功,REFUND—转入退款,NOTPAY—未支付,CLOSED—已关闭,REVOKED—已撤销（刷卡支付）,USERPAYING--用户支付中,PAYERROR--支付失败(其他原因，如银行返回失败)
                    if (ObjectUtils.isNotEmpty(trade_state)) {
                        if ("NOTPAY".equals(trade_state)) {
                            tbOrder.setStatus(5);
                        } else if ("SUCCESS".equals(trade_state)) {
                            tbOrder.setPayType(1);
                            orderService.updateOrderAfterPaySuccess(tbOrder);
                        }
                    } else {
                        RhtQrcodePayApi qrcodePay = new RhtQrcodePayApi(wechatMchConfig.getMchId(), wechatMchConfig.getMchKey(), RHT_PAY_BASE_URL);
                        QrcodeQueryRequestBean qqrb = new QrcodeQueryRequestBean();
                        qqrb.setTraceno(orderNumber);// 商户流水号
                        QrcodeQueryResponseBean response2 = qrcodePay.query(qqrb);
                        String respCode = response2.getRespCode();
                        log.info("超时任务处理订单【{}】查询支付结果，支付通知信息：{}", orderNumber, response2);
//                        0未支付，1支付成功，2支付失败，4退款中，5退款成功，6退款失败
                        if ("0".equals(respCode)) {
                            tbOrder.setStatus(5);
                        } else if ("1".equals(respCode)) {
                            PayDetails payDetails = payDetailsService.getByOrderNo(orderNumber);
                            if (!ObjectUtil.isNull(payDetails)) {
                                payDetails.setState(PayStateEnums.PAY_SUCCESS.getStateCode());
                                payDetails.setPayTime(response2.getTransDate() + " " + response2.getTransTime());
                                payDetails.setTradeNo(response2.getChannelOrderno());
                                payDetails.setRemark("Scheduled RHT PAY SUCCESS");
                                payDetailsService.updateDetail(payDetails);
                            } else {
                                log.error("超时任务处理订单【{}】支付成功，但未获取到支付订单！支付通知信息：{}", orderNumber, response2);
                            }
                            tbOrder.setPayType(1);
                            orderService.updateOrderAfterPaySuccess(tbOrder);
                        }

                    }
                }
            } else {
                tbOrder.setStatus(5);
            }

            //list为空不要执行
            if (tbOrder.getStatus().intValue() == 5) {
                baseMapper.updateById(tbOrder);
            }

            //endregion
            return Result.success();
        } catch (Exception e) {
            log.error("超时订单自动取消任务运行失败失败原因：{}", e.getMessage());
            return Result.error("自动取消订单异常");
        } finally {
            lock.unlock();

        }
    }

    @Override
    public PayTransactionsVO getTransactionsParam(Long userId, PayOrderDTO payOrderDTO) {
        TbOrder order = prepareOrder(userId, payOrderDTO);
        Integer status = order.getStatus();
        if (status == 0) {
            //            获取超时时间
            Long timeOut = order.getTimeOut();
            if (ObjectUtils.isNotEmpty(timeOut)) {
                long time = new Date().getTime();

                if (timeOut < time) {
                    throw new SqxException("订单已过期！");
                }
            }
        } else {

            // 支付时，订单状态改为 0
            order.setStatus(0);


//            超时时间15分钟
            Date date = new Date();
            long time1 = date.getTime() + 15 * 60 * 1000;
            order.setTimeOut(time1);
        }
        // 更新订单
        updateById(order);

        // 在同一时刻用户只能在同一家店铺执行一次下单操作 ？？
        RLock lock = redissonClient.getLock(String.format(RedisKey.INSERT_ORDER_LOCK, order.getUserId(), order.getShopId()));
        lock.lock();
        try {
            // 设置支付方式 1表示微信支付、4或5表示支付宝支付
            Integer type = payOrderDTO.getType();

            // 微信支付
            if (type == 1) {
                UserEntity userEntity = userService.queryByUserId(userId);

                GetPayParamDTO dto = GetPayParamDTO.builder()
                        .orderNo(order.getOrderNumber())
                        .orderDesc(order.getShopName())
                        .amount(order.getPayMoney().setScale(2, RoundingMode.HALF_UP))
                        .userId(userId)
                        .userThirdId(userEntity.getOpenId())
                        .payChannel(PayChannelEnum.WECHAT_JS_API)
                        .paySceneEnum(PaySceneEnum.ORDER_PAY)
                        .build();
                return newPayService.getWechatTransactionsParamVO(dto);
            }
            // 支付宝支付，暂时未重构先不管，copy原有代码
            else {
                Result result = aliPayController.payAppOrders(order.getPayMoney().doubleValue(), type, order.getUserId(), order.getOrderNumber(), 1);

                AliPayTransactionsParam transactionsParam = new AliPayTransactionsParam();
                transactionsParam.setBody(result.get("data").toString());
                return transactionsParam;
            }
        } finally {
            lock.unlock();
        }
    }

    @Override
    public Result selectAllOrderTotalPrice(OrderQueryDto queryDto) {
        if (org.springframework.util.StringUtils.hasText(queryDto.getEndTime())) {
            queryDto.setEndTime(queryDto.getEndTime() + " 23:59:59");
        }
        if (org.springframework.util.StringUtils.hasText(queryDto.getPayEndTime())) {
            queryDto.setPayEndTime(queryDto.getPayEndTime() + " 23:59:59");
        }
        if (org.springframework.util.StringUtils.hasText(queryDto.getStartTime())) {
            queryDto.setStartTime(queryDto.getStartTime() + " 00:00:00");
        }
        if (org.springframework.util.StringUtils.hasText(queryDto.getPayStartTime())) {
            queryDto.setPayStartTime(queryDto.getPayStartTime() + " 00:00:00");
        }
        BigDecimal totalPrice = appOrderDao.selectAllOrderTotalPrice(queryDto);

        return Result.success().put("data", totalPrice);
    }

    @Override
    public List<TbOrder> changeTimeOutOrder(long time) {
        return appOrderDao.changeTimeOutOrder(time);
    }

    @Override
    public PageUtils getGoodsSkuSalesCount(GoodsSkuQuery query) {
        Page<GoodsSkuSalesCountVO> pages = new Page<>(query.getPage(), query.getLimit());

        IPage<GoodsSkuSalesCountVO> page = baseMapper.getGoodsSkuSalesCount(pages, query);
        PageUtils pageUtils = new PageUtils(page);
        return pageUtils;
    }

    @Override
    public void exportGoodsSkuSalesCount(GoodsSkuQuery query) {
        Page<GoodsSkuSalesCountVO> pages = new Page<>(query.getPage(), query.getLimit());
        IPage<GoodsSkuSalesCountVO> page = baseMapper.getGoodsSkuSalesCount(pages, query);
        List<GoodsSkuSalesCountVO> records = page.getRecords();

        try {
            RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
            HttpServletResponse response = ((ServletRequestAttributes) requestAttributes).getResponse();
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            response.setCharacterEncoding("UTF-8");

            String excelName = "sku销售记录_";
            excelName += DateUtil.format(new Date(), "yyyyMMddHHmmss");
            String fileName = URLUtil.encode(excelName, "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");

            EasyExcel.write(response.getOutputStream(), GoodsSkuSalesCountVO.class)
                    .sheet("sheet1")
                    .registerConverter(new LongStringConverter())
                    .doWrite(records);
        } catch (IOException e) {
            log.error("sku销售记录导出失败：{}", e.getMessage());
            throw new SqxException("sku销售记录导出失败");
        }
    }

    /**
     * 更新订单状态和支付顺序
     *
     * @param order 订单信息
     */
    private void updateOrderStatusAndSequence(TbOrder order) {
        Long shopId = order.getShopId();
        RLock lock = redissonClient.getLock(String.format(RedisKey.ORDER_SEQUENCE_LOCK, shopId));
        lock.lock();
        try {
            int count = appOrderDao.countCurDayPayByShopId(shopId, order.getPayTime());
            order.setOrderSequence(String.format("%04d", count + 1));

            updateById(order);
        } finally {
            lock.unlock();
        }
    }


}
