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

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
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.address.dao.AddressDao;
import com.sqx.modules.address.entity.Address;
import com.sqx.modules.address.service.AddressService;
import com.sqx.modules.app.dao.UserDao;
import com.sqx.modules.app.entity.UserEntity;
import com.sqx.modules.app.entity.UserMoneyDetails;
import com.sqx.modules.app.entity.queryRiderVo;
import com.sqx.modules.app.service.UserMoneyDetailsService;
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.datacentre.query.DataCenterQuery;
import com.sqx.modules.errand.dao.ErrandEvaluateDao;
import com.sqx.modules.errand.dao.TbIndentDao;
import com.sqx.modules.errand.dao.TransferRecordDao;
import com.sqx.modules.errand.dto.OrderRiderDeliveryDTO;
import com.sqx.modules.errand.dto.RiderDeliveryDTO;
import com.sqx.modules.errand.dto.RiderTransferByOrderIdDTO;
import com.sqx.modules.errand.dto.RiderTransferOrderDTO;
import com.sqx.modules.errand.dto.WaitForAcceptOrderQueryDTO;
import com.sqx.modules.errand.entity.ErrandAddress;
import com.sqx.modules.errand.entity.ErrandEvaluate;
import com.sqx.modules.errand.entity.ErrandRedPacket;
import com.sqx.modules.errand.entity.TbIndent;
import com.sqx.modules.errand.entity.TbIndentSmsSendLog;
import com.sqx.modules.errand.entity.TransferRecordEntity;
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.errand.util.LonLatUtil;
import com.sqx.modules.errand.vo.ShopWaitAcceptOrderVO;
import com.sqx.modules.errand.vo.queryOrderInfoVo;
import com.sqx.modules.goods.dao.GoodsShopDao;
import com.sqx.modules.goods.dao.GoodsShopRelevancyDao;
import com.sqx.modules.goods.entity.GoodsShop;
import com.sqx.modules.goods.entity.GoodsShopRelevancy;
import com.sqx.modules.goods.service.GoodsShopService;
import com.sqx.modules.message.entity.MessageInfo;
import com.sqx.modules.message.service.MessageService;
import com.sqx.modules.order.dao.OrderGoodsDao;
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.pay.controller.app.AliPayController;
import com.sqx.modules.pay.dao.PayDetailsDao;
import com.sqx.modules.pay.entity.PayDetails;
import com.sqx.modules.pay.service.WxService;
import com.sqx.modules.riderStation.entity.RiderStation;
import com.sqx.modules.riderStation.service.RiderStationService;
import com.sqx.modules.shop.service.ShopMessageService;
import com.sqx.modules.utils.HttpClientUtil;
import com.sqx.modules.utils.SenInfoCheckUtil;
import lombok.extern.slf4j.Slf4j;
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.gavaghan.geodesy.Ellipsoid;
import org.gavaghan.geodesy.GlobalCoordinates;
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 javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Random;

@Service
@Slf4j
public class TbIndentServiceImpl extends ServiceImpl<TbIndentDao, TbIndent> implements TbIndentService {

    @Autowired
    private TbIndentDao tbIndentDao;
    @Autowired
    private GoodsShopDao goodsShopDao;
    @Autowired
    private AddressDao addressDao;
    @Autowired
    private CommonInfoService commonInfoService;
    @Autowired
    private UserService userService;
    @Autowired
    private UserMoneyDetailsService userMoneyDetailsService;
    @Autowired
    private ErrandEvaluateDao errandEvaluateDao;
    @Autowired
    private OrderGoodsDao orderGoodsDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private PayDetailsDao payDetailsDao;
    @Autowired
    private WxService wxService;

    @Autowired
    private RiderStationService riderStationService;
    @Autowired
    private AliPayController aliPayController;
    @Lazy
    @Autowired
    private AppOrderService appOrderService;
    @Autowired
    private MessageService messageService;
    @Autowired
    private GoodsShopRelevancyDao goodsShopRelevancyDao;
    @Autowired
    private ShopMessageService shopMessageService;
    @Autowired
    private TransferRecordDao transferRecordDao;

    @Resource
    private TbIndentSmsTemplateService smsTemplateService;
    @Resource
    private TbIndentSmsSendLogService smsSendLogService;

    @Resource
    private RedissonClient redissonClient;
    @Resource
    private PlatformTransactionManager transactionManager;

    @Autowired
    private GoodsShopService goodsShopService;

    @Autowired
    private AddressService addressService;

    @Override
    public TbIndent findIndentByPayOrdersNo(String ordersNo) {
        return baseMapper.selectOne(new QueryWrapper<TbIndent>().eq("pay_orders_no", ordersNo));
    }

    @Override
    public void sendNewIndentMsg(TbIndent indent) {
        try {
            //开关 是否开启推送
            String value1 = commonInfoService.findOne(340).getValue();
            if ("是".equals(value1)) {
                //新订单通知
                //查询附近指定公里范围内的骑手
                String value = commonInfoService.findOne(339).getValue();
                String lat, lng;
                if ("1".equals(indent.getIndentType()) || "2".equals(indent.getIndentType())) {
                    lat = String.valueOf(indent.getShopLat());
                    lng = String.valueOf(indent.getShopLng());
                } else {
                    lat = String.valueOf(indent.getUserLat());
                    lng = String.valueOf(indent.getUserLng());
                }
                BigDecimal multiply = new BigDecimal(value).multiply(BigDecimal.valueOf(1000));
                List<UserEntity> userEntityList = userDao.selectRiderUserByOnLineFlag(String.valueOf(multiply), lng, lat);
                if (userEntityList.size() > 0) {
                    String templateId = commonInfoService.findOne(338).getValue();
                    for (UserEntity userEntity : userEntityList) {
                        if (userEntity.getIsSendMsg() == null || userEntity.getIsSendMsg() == 1) {
                            String indentType;
                            if ("1".equals(indent.getIndentType())) {
                                indentType = "帮我送";
                            } else if ("2".equals(indent.getIndentType())) {
                                indentType = "帮我取";
                            } else if ("3".equals(indent.getIndentType())) {
                                indentType = "同城帮买";
                            } else if ("4".equals(indent.getIndentType())) {
                                indentType = "同城服务";
                            } else {
                                indentType = "外卖";
                            }
                            if (StrUtil.isNotEmpty(userEntity.getRiderOpenId())) {
                                List<String> msgList = new ArrayList<>();
                                //1：帮我送；2：帮我取；3：同城帮买；4：同城服务
                                msgList.add(indentType);
                                if ("5".equals(indent.getIndentType())) {
                                    TbOrder order = appOrderService.selectOrderByNum(indent.getIndentNumber());
                                    msgList.add(String.valueOf(order.getPayMoney()));
                                } else {
                                    msgList.add(String.valueOf(indent.getIndentMoney()));
                                }

                                String address;
                                if ("1".equals(indent.getIndentType()) || "2".equals(indent.getIndentType())) {
                                    address = indent.getShopProvince() + indent.getShopCity() + indent.getShopDistrict() + indent.getShopAddressDetail();
                                } else {
                                    address = indent.getUserProvince() + indent.getUserCity() + indent.getUserDistrict() + indent.getUserAddressDetail();
                                }
                                if (address.length() > 15) {
                                    address = address.substring(0, 15) + "...";
                                }
                                msgList.add(address);
                                msgList.add(indent.getCreateTime());
                                SenInfoCheckUtil.sendRiderMsg(userEntity.getRiderOpenId(), templateId, msgList, 6);
                            }
                            if (StrUtil.isNotEmpty(userEntity.getRiderClientid())) {
                                userService.pushToSingleRider("新订单通知", indentType, userEntity.getRiderClientid());
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("新订单骑手通知异常：" + e.getMessage(), e);
        }

    }

    @Override
    public Result findNewIndent(Long userId, String receivingPettern, Integer page, Integer limit, double riderLng, double riderLat, String indentType, String buyType) {
        Page<TbIndent> pages = new Page<>(page, limit);
        IPage<TbIndent> indent = null;
        if (receivingPettern.equals("1")) {
            CommonInfo one = commonInfoService.findOne(274);
            Integer value = Integer.valueOf(one.getValue());
            double distances = value;
            indent = baseMapper.findNewIndent(pages, riderLng, riderLat, distances, indentType);
            for (int i = 0; i < indent.getRecords().size(); i++) {
                if ("4".equals(indent.getRecords().get(i).getIndentType())) {
                    Result distance = distance(riderLng, riderLat, indent.getRecords().get(i).getUserLng(), indent.getRecords().get(i).getUserLat());
                    Object data = distance.get("data");
                    indent.getRecords().get(i).setDistancess(Double.valueOf(data.toString()));
                }
            }
        } else if ("2".equals(receivingPettern)) {
            String address = getCurrentCityByLngAndLat(riderLng, riderLat);

            indent = baseMapper.findNewIndentcity(pages, riderLng, riderLat, address, indentType);
            for (int i = 0; i < indent.getRecords().size(); i++) {
                if ("4".equals(indent.getRecords().get(i).getIndentType())) {
                    Result distance = distance(riderLng, riderLat, indent.getRecords().get(i).getUserLng(), indent.getRecords().get(i).getUserLat());
                    Object data1 = distance.get("data");
                    indent.getRecords().get(i).setDistancess(Double.valueOf(data1.toString()));
                }
            }
        }
        return Result.success().put("data", new PageUtils(indent));
    }

    @Override
    public synchronized Result insertIndent(TbOrder order) {
        Integer integer = tbIndentDao.selectCount(new QueryWrapper<TbIndent>().eq("order_id", order.getOrderId()));
        if (integer >= 1) {
            return Result.error("请勿重复生成订单！");
        }
        GoodsShop goodsShop = shopMessageService.getShopInfoById(order.getShopId());

        TbIndent tbIndent = new TbIndent();
        tbIndent.setItemCodeFlag(1);
        tbIndent.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        tbIndent.setOrderId(order.getOrderId());
        tbIndent.setIndentType("5");
        tbIndent.setIndentNumber(order.getOrderNumber());
        tbIndent.setShopName(goodsShop.getShopName());
        tbIndent.setShopPhone(goodsShop.getPhone());
        tbIndent.setShopProvince(goodsShop.getProvince());
        tbIndent.setShopCity(goodsShop.getCity());
        tbIndent.setShopDistrict(goodsShop.getDistrict());
        tbIndent.setShopLng(goodsShop.getShopLng());
        tbIndent.setShopLat(goodsShop.getShopLat());

        // 新增，订单支付顺序号
        if (ObjectUtil.isNotNull(order.getOrderSequence())) {
            tbIndent.setOrderPaySequence(order.getOrderSequence());
        }

        tbIndent.setShopAddressDetail(goodsShop.getDetailedAddress());
        if (order.getOrderType() == 2) {
            Address address;
            String addressStr = order.getAddress();
            if (StrUtil.isNotBlank(addressStr)) {
                address = JSONUtil.toBean(addressStr, Address.class);
            } else {
                address = addressDao.selectById(order.getAddressId());
            }

            tbIndent.setUserName(address.getUserName());
            tbIndent.setUserPhone(address.getUserPhone());
            tbIndent.setUserProvince(address.getProvince());
            tbIndent.setUserCity(address.getCity());
            tbIndent.setUserDistrict(address.getDistrict());
            tbIndent.setUserLng(address.getLng());
            tbIndent.setUserLat(address.getLat());
            tbIndent.setUserAddressDetail(address.getAddressDetail());
        }

        tbIndent.setOrderCode(order.getOrderCode());
        tbIndent.setRemarks(order.getRemark());
        BigDecimal errandMoney = goodsShop.getErrandMoney();
        BigDecimal platformMoney = BigDecimal.ZERO;
        if (errandMoney != null && errandMoney.doubleValue() > 0) {
            //平台扣除骑手佣金 具体金额
            String value = commonInfoService.findOne(333).getValue();
            //平台佣金
            platformMoney = new BigDecimal(value);
            //骑手最终可得金额
            errandMoney = errandMoney.subtract(platformMoney);
        }
        tbIndent.setErrandMoney(errandMoney);
        tbIndent.setRiderMoney(errandMoney);
        tbIndent.setPlatformMoney(platformMoney);
        // 配送订单，直接改为2
        if (goodsShop.getAutoSendOrder() == 0) {
            tbIndent.setIndentState("2");
        } else {
            tbIndent.setIndentState("11");
        }
        tbIndent.setUserId(order.getUserId());
        tbIndent.setShopId(order.getShopId());
        baseMapper.insert(tbIndent);

        log.info("订单类型："+order.getOrderType()+",跑腿订单状态："+tbIndent.getIndentState());
        if (order.getOrderType() == 2 && !"11".equals(tbIndent.getIndentState())) {
            //            创建快跑者订单
            log.info("第一次创建快跑者订单");
            String responseBody = creatSpeedRunnerOrder(order);
            if (ObjectUtils.isNotEmpty(responseBody)) {
                String tradeNo = getOrderTradeNo(responseBody);
                log.info("第一次创建订单获取的快跑者返回订单号：" + tradeNo);
                if (ObjectUtils.isNotEmpty(tradeNo)) {
                    order.setTradeNo(tradeNo);
                    appOrderService.updateById(order);
                } else {
                    log.info("第二次创建快跑者订单");
                    String responseBody2 = creatSpeedRunnerOrder(order);
                    if (ObjectUtils.isNotEmpty(responseBody2)) {
                        String tradeNo2 = getOrderTradeNo(responseBody2);
                        log.info("第二次创建订单获取的快跑者返回订单号：" + tradeNo2);
                        if (ObjectUtils.isNotEmpty(tradeNo2)) {
                            order.setTradeNo(tradeNo2);
                            appOrderService.updateById(order);
                        }
                    }
                }

            } else {
                log.info("创建快跑者订单的返回信息为空，第二次创建");
                String responseBody2 = creatSpeedRunnerOrder(order);
                String tradeNo = getOrderTradeNo(responseBody2);
                log.info("第二次创建订单获取的快跑者返回订单号：" + tradeNo);
                if (ObjectUtils.isNotEmpty(tradeNo)) {
                    order.setTradeNo(tradeNo);
                    appOrderService.updateById(order);
                }
            }
        }


        return Result.success();
    }


    public String creatSpeedRunnerOrder(TbOrder tbOrder){
//               获取店铺信息
        GoodsShop goodsShop = goodsShopService.getById(tbOrder.getShopId());
//               获取餐品信息
        List<OrderGoods> orderGoodsList = orderGoodsDao.selectList(new QueryWrapper<OrderGoods>()
                .eq("order_id", tbOrder.getOrderId()));
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < orderGoodsList.size(); i++) {
            OrderGoods orderGoods = orderGoodsList.get(i);
            double goodsPrice = orderGoods.getGoodsPrice().doubleValue();
            Integer goodsNum = orderGoods.getGoodsNum();
            String goodsName = orderGoods.getGoodsName();
            if (i == 0) {
                stringBuilder.append(goodsName).append("(").append(goodsPrice).append("x").append(goodsNum).append(")");
            } else {
                stringBuilder.append(",").append(goodsName).append("(").append(goodsPrice).append("x").append(goodsNum).append(")");

            }
        }
//               获取用户收货地址
        Address address = addressService.getById(tbOrder.getAddressId());

        JSONObject body = new JSONObject();
        String shopId = tbOrder.getShopId()+"";
        if (ObjectUtils.isNotEmpty(shopId)) {
            try {
                shopId = URLEncoder.encode(shopId, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
        }
        body.put("shop_id", shopId);

        String shopName = goodsShop.getShopName();
        if (ObjectUtils.isNotEmpty(shopName)) {
            try {
                shopName = URLEncoder.encode(shopName, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
//            shopName=shopName.replaceAll("\\+","-");
        }
        body.put("shop_name", shopName);

        String phone = goodsShop.getPhone();
        if (ObjectUtils.isNotEmpty(phone)) {
            try {
                phone = URLEncoder.encode(phone, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
        }
        body.put("shop_tel", phone);


        String detailedAddress = goodsShop.getDetailedAddress();
        if (ObjectUtils.isNotEmpty(detailedAddress)) {
            try {
                detailedAddress = URLEncoder.encode(detailedAddress, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
//            detailedAddress=detailedAddress.replaceAll("\\+","-");
        }
        body.put("shop_address", detailedAddress);


        String shopTag  =goodsShop.getShopLng() + "," + goodsShop.getShopLat();
        if (ObjectUtils.isNotEmpty(detailedAddress)) {
            try {
                shopTag = URLEncoder.encode(shopTag, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
        }
        body.put("shop_tag", shopTag);


//        将+变成-
        String orderContent = stringBuilder.toString();
        if (ObjectUtils.isNotEmpty(orderContent)) {
            try {
                orderContent=orderContent.replaceAll("\\t", " ");
                orderContent = URLEncoder.encode(orderContent, "UTF-8");
//                orderContent=orderContent.replaceAll("🦆","");
//                orderContent=orderContent.replaceAll("（双拼）","");
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
//            orderContent=orderContent.replaceAll("\\+","-");
        }
        body.put("order_content", orderContent);


        String remark = tbOrder.getRemark();
        if (ObjectUtils.isNotEmpty(remark)) {
            try {
                remark=remark.replaceAll("\\r\\n|\\n|\\r", " ");
                remark = URLEncoder.encode(remark, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
//            remark=remark.replaceAll("\\+","-");
        }
        body.put("order_note", remark);

        String orderSequence = tbOrder.getOrderSequence();
        if (ObjectUtils.isNotEmpty(orderSequence)) {
            try {
                orderSequence =URLEncoder.encode(orderSequence, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
        }
        body.put("order_mark", orderSequence);


        body.put("order_from", shopName+ "#" + orderSequence);


        String payTime = tbOrder.getPayTime();
        if (ObjectUtils.isNotEmpty(payTime)) {
            try {
                payTime = URLEncoder.encode(payTime, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
        }
        body.put("order_time", payTime);


        String userName = address.getUserName();
        if (ObjectUtils.isNotEmpty(userName)) {
            try {
                userName = URLEncoder.encode(userName, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
//            userName=userName.replaceAll("\\+","-");
        }
        body.put("customer_name", userName);

        String userPhone = tbOrder.getPhone();
        if (ObjectUtils.isNotEmpty(userPhone)) {
            try {
                userPhone = URLEncoder.encode(userPhone, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
        }
        body.put("customer_tel", userPhone);


        String addressDetail = address.getAddressDetail();
        if (ObjectUtils.isNotEmpty(addressDetail)) {
            try {
                addressDetail = URLEncoder.encode(addressDetail, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }

//            addressDetail=addressDetail.replaceAll("\\+","-");
        }
        body.put("customer_address", addressDetail);


        String customerTag=address.getLng() + "," + address.getLat();
        if (ObjectUtils.isNotEmpty(customerTag)) {
            try {
                customerTag = URLEncoder.encode(customerTag, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
        }
        body.put("customer_tag", customerTag);


        String orderNumber = tbOrder.getOrderNumber();
        if (ObjectUtils.isNotEmpty(orderNumber)) {
            try {
                orderNumber = URLEncoder.encode(orderNumber, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
        }
        body.put("order_no", orderNumber);

        String payMoney = tbOrder.getPayMoney().toPlainString();
        if (ObjectUtils.isNotEmpty(payMoney)) {
            try {
                payMoney = URLEncoder.encode(payMoney, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
        }
        body.put("order_price",payMoney);
        body.put("pay_status", 0);

        log.info("body信息：" + body);

//               版本
        String version = "1";
//               时间戳
        long currentTimeMillis = System.currentTimeMillis();
        long currentTimeSeconds = currentTimeMillis / 1000;
        String timestamp = String.valueOf(currentTimeSeconds);
        log.info("timestamp: "+timestamp);
//               唯一标识符
        String ticket = "83f0ff99-7c8e-47e8-8802-bd3754414a52";
//               团队token
        String teamToken = "Q444DMV4LT8WSGRW";
//               开发者中心的开发密钥
        String devKey = "31RRHA4O165VFN9W2DAPDYDH8N83BT12";

        JSONObject body2 = new JSONObject();
//        String shopId = tbOrder.getShopId()+"";
        body2.put("shop_id", tbOrder.getShopId()+"");

//        String shopName = goodsShop.getShopName();
        body2.put("shop_name", goodsShop.getShopName());

//        String phone = goodsShop.getPhone();
        body2.put("shop_tel", goodsShop.getPhone());

//        String detailedAddress = goodsShop.getDetailedAddress();
        body2.put("shop_address", goodsShop.getDetailedAddress());


//        String shopTag  =goodsShop.getShopLng() + "," + goodsShop.getShopLat();
        body2.put("shop_tag", goodsShop.getShopLng() + "," + goodsShop.getShopLat());


//        将+变成-
        String orderContent2 = stringBuilder.toString();
        if (ObjectUtils.isNotEmpty(orderContent2)) {
            orderContent2=orderContent2.replaceAll("\\t", " ");
        }

        body2.put("order_content", orderContent2);


        String remark2 = tbOrder.getRemark();
        if (ObjectUtils.isNotEmpty(remark2)) {
            remark2=remark2.replaceAll("\\r\\n|\\n|\\r", " ");

            // 方法2：使用Java 8+的\\R正则表达式;
        }
        body2.put("order_note", remark2);

//        String orderSequence = tbOrder.getOrderSequence();
        body2.put("order_mark", tbOrder.getOrderSequence());


        body2.put("order_from", goodsShop.getShopName()+ "#" + tbOrder.getOrderSequence());


//        String payTime = tbOrder.getPayTime();

        body2.put("order_time", tbOrder.getPayTime());


//        String userName = address.getUserName();

        body2.put("customer_name", address.getUserName());

//        String userPhone = address.getUserPhone();

        body2.put("customer_tel", tbOrder.getPhone());


//        String addressDetail = address.getAddressDetail();
        body2.put("customer_address", address.getAddressDetail());


//        String customerTag=address.getLng() + "," + address.getLat();
        body2.put("customer_tag", address.getLng() + "," + address.getLat());


//        String orderNumber = tbOrder.getOrderNumber();

        body2.put("order_no", tbOrder.getOrderNumber());

//        String payMoney = tbOrder.getPayMoney().toPlainString();
        body2.put("order_price",tbOrder.getPayMoney().toPlainString());
        body2.put("pay_status", 0);
        log.info("body2信息：" + body2);
//               获取签名
        String sign = SignUtil.getSign(body2.toString(), devKey, teamToken, ticket, currentTimeSeconds, 1);
        String responseBody="";
        try {
            log.info("创建快跑者订单");
            CloseableHttpClient client = HttpClients.createDefault();
            // 创建httppost
            HttpPost httpPost = new HttpPost("https://open.keloop.cn/open/order/createOrder");
            String params = "version=" + version + "&timestamp=" + timestamp + "&ticket=" + ticket + "&team_token=" + teamToken + "&dev_key=" + devKey + "&sign=" + sign + "&body=" + body.toString(); // 注意：这里不需要手动编码，HttpClient会处理它。
            System.out.println("params = " + params);
            StringEntity entity = new StringEntity(params, StandardCharsets.UTF_8);
            entity.setContentType("application/x-www-form-urlencoded"); // 设置Content-Type为application/x-www-form-urlencoded，但不是必须的，HttpClient会自动设置。
            httpPost.setEntity(entity);
            responseBody = EntityUtils.toString(client.execute(httpPost).getEntity());
            log.info("创建结果："+responseBody);
        }catch (Exception e){
            e.printStackTrace();
//            throw new RuntimeException("responseBody");
        }
        return responseBody;
    }

    public String getOrderTradeNo(String responseBody){
        com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSONObject.parseObject(responseBody);
        Integer code = jsonObject.getInteger("code");
        String tradeNo="";
        if (ObjectUtils.isNotEmpty(code)) {
            if (code==200) {
                JSONObject data = jsonObject.getJSONObject("data");
                tradeNo = data.getString("trade_no");
            }
        }
        return tradeNo;
    }

    //根据双方经纬度计算距离
    @Override
    public Result distance(double ol, double od, double dl, double dd) {
        GlobalCoordinates source = new GlobalCoordinates(ol, od);
        GlobalCoordinates target = new GlobalCoordinates(dl, dd);
        Integer meter = (int) LonLatUtil.getDistanceMeter(source, target, Ellipsoid.Sphere);
        return Result.success().put("data", meter);
    }

    @Transactional
    @Override
    public Result addUserAddress(Long userId, ErrandAddress errandAddress) {
        String datetime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        if ("1".equals(errandAddress.getAddressDefault())) {
            tbIndentDao.updateDefault(userId);
        }
        errandAddress.setUserId(userId);
        errandAddress.setCreateTime(datetime);
        tbIndentDao.addUserAddress(errandAddress);
        return Result.success().put("data", errandAddress.getAddressId());
    }

    @Transactional
    @Override
    public Result updateAddress(Long userId, ErrandAddress errandAddress) {
        if ("1".equals(errandAddress.getAddressDefault())) {
            tbIndentDao.updateDefault(userId);
        }
        String datetime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        tbIndentDao.updateAddress(userId, errandAddress.getUserName(), errandAddress.getUserPhone(), errandAddress.getAddress(), errandAddress.getAddressDetail(),
                errandAddress.getAddressLongitude(), errandAddress.getAddressLatitude(), datetime, errandAddress.getAddressDefault(), errandAddress.getAddressId());

        return Result.success();
    }

    @Override
    public Result findUserAddress(Long userId) {
        List<ErrandAddress> userAddress = tbIndentDao.findUserAddress(userId);
        return Result.success().put("data", userAddress);
    }

    @Override
    public Result findAddressById(Long userId, Integer addressId) {
        ErrandAddress addressById = tbIndentDao.findAddressById(userId, addressId);
        return Result.success().put("data", addressById);
    }

    @Transactional
    @Override
    public Result addDefaultAddress(Long userId, Integer addressId) {
        tbIndentDao.updateDefault(userId);
        tbIndentDao.addDefaultAddress(userId, addressId);

        return Result.success();
    }

    @Override
    public Result delUserAddress(Long userId, Integer addressId) {
        tbIndentDao.delUserAddress(userId, addressId);
        return Result.success();
    }

    @Override
    public TbIndent basicsMoney(TbIndent indent) {
        BigDecimal price1 = new BigDecimal(0);
        if (indent.getIndentType().equals("1") || indent.getIndentType().equals("2")) {
            //帮我送的初始订单价格计算
            //根据距离和重量计算具体价格/admin/dataCentre
            Integer aitemWeight = 1;
            if ("25斤以内".equals(indent.getItemWeight())) {
                aitemWeight = Integer.parseInt(commonInfoService.findOne(343).getValue());
            } else if ("26-30斤".equals(indent.getItemWeight())) {
                aitemWeight = Integer.parseInt(commonInfoService.findOne(344).getValue());
            } else if ("31-40斤".equals(indent.getItemWeight())) {
                aitemWeight = Integer.parseInt(commonInfoService.findOne(345).getValue());
            } else if ("41-50斤".equals(indent.getItemWeight())) {
                aitemWeight = Integer.parseInt(commonInfoService.findOne(346).getValue());
            }
            CommonInfo one = commonInfoService.findOne(276);
            Double a = indent.getDistance() * aitemWeight / Double.valueOf(one.getValue());
            CommonInfo oneUser = commonInfoService.findOne(277);
            Double value = Double.valueOf(oneUser.getValue());
            if (a < value) {
                a = value;
            }
            //初始订单价格;
            price1 = BigDecimal.valueOf(a);//20
            //计算保价费
            //判断用户是否需要保价费
            if ("50元以下".equals(indent.getItemValue())) {
                indent.setCargoInsurance(new BigDecimal(commonInfoService.findOne(347).getValue()));
            } else if ("50-150元".equals(indent.getItemValue())) {
                indent.setCargoInsurance(new BigDecimal(commonInfoService.findOne(348).getValue()));
            } else if ("150-350元".equals(indent.getItemValue())) {
                indent.setCargoInsurance(new BigDecimal(commonInfoService.findOne(349).getValue()));
            } else if ("350-500元".equals(indent.getItemValue())) {
                indent.setCargoInsurance(new BigDecimal(commonInfoService.findOne(350).getValue()));
            } else if ("500-1000元".equals(indent.getItemValue())) {
                indent.setCargoInsurance(new BigDecimal(commonInfoService.findOne(351).getValue()));
            }
            // price1 = price1.add(indent.getCargoInsurance());
            //计算骑手的跑腿费
            CommonInfo oneUser1 = commonInfoService.findOne(278);
            Double value1 = Double.valueOf(oneUser1.getValue());
            BigDecimal multiply = BigDecimal.valueOf(a).multiply(BigDecimal.valueOf(value1));
            //跑腿费四舍五入保存两位小数
            BigDecimal bigDecimal = multiply.setScale(2, BigDecimal.ROUND_HALF_DOWN);
            indent.setErrandMoney(bigDecimal);
        } else if (indent.getIndentType().equals("3")) {
            CommonInfo one = commonInfoService.findOne(279);
            //计算用户要支付的跑腿费
            Double a = indent.getDistance() / Double.valueOf(one.getValue());
            //如果本订单支付价格不足10元，则提升到10元
            CommonInfo oneUser = commonInfoService.findOne(280);
            Double value = Double.valueOf(oneUser.getValue());
            if (a < value) {
                a = value;
            }
            //计算用户需支付金额
            price1 = price1.add(BigDecimal.valueOf(a));
            //计算骑手的跑腿费（为该订单跑腿费的1/2）
            CommonInfo oneUser1 = commonInfoService.findOne(281);
            Double value1 = Double.valueOf(oneUser1.getValue());
            BigDecimal multiply = (BigDecimal.valueOf(a)).multiply(BigDecimal.valueOf(value1));
            //四舍五入保存两位小数
            BigDecimal bigDecimal = multiply.setScale(2, BigDecimal.ROUND_HALF_DOWN);
            indent.setErrandMoney(bigDecimal);
        } else if (indent.getIndentType().equals("4")) {
            //同城服务的初始订单价格
            CommonInfo oneUser = commonInfoService.findOne(282);
            Double value = Double.valueOf(oneUser.getValue());
            price1 = price1.add(BigDecimal.valueOf(value));
            //计算同城师傅上门费
            CommonInfo oneUser1 = commonInfoService.findOne(283);
            Double value1 = Double.valueOf(oneUser1.getValue());
            BigDecimal multiply = (BigDecimal.valueOf(value)).multiply(BigDecimal.valueOf(value1));
            //四舍五入保存两位小数
            BigDecimal bigDecimal = multiply.setScale(2, BigDecimal.ROUND_HALF_DOWN);
            indent.setErrandMoney(bigDecimal);
        }
        price1 = price1.setScale(2, BigDecimal.ROUND_HALF_DOWN);

        indent.setIndentBasicsMoney(price1);
        //计算用户取消订单要扣除的违约金
        CommonInfo oneUser = commonInfoService.findOne(284);
        String valueUser = oneUser.getValue();
        BigDecimal userFine = price1.multiply(new BigDecimal(valueUser)).setScale(2, BigDecimal.ROUND_HALF_DOWN);
        indent.setUserFine(userFine);
        //计算骑手取消订单要扣除的违约金
        CommonInfo riderOne = commonInfoService.findOne(285);
        String valueRider = riderOne.getValue();
        BigDecimal riderFine = indent.getErrandMoney().multiply(new BigDecimal(valueRider)).setScale(2, BigDecimal.ROUND_HALF_DOWN);
        indent.setRiderFine(riderFine);
        return indent;
    }

    @Transactional
    @Override
    public Result addIndentBuy(TbIndent indent) {
        BigDecimal price1 = basicsMoney(indent).getIndentBasicsMoney();
        if (indent.getRedPacketId() != null) {
            //根据红包id查询红包 判断红包是否是自己的  是否使用  金额是否满足
            ErrandRedPacket red = tbIndentDao.findRed(indent.getRedPacketId());
            if (red.getUserId().equals(indent.getUserId()) &&//判断红包是否是登录用户的
                    (red.getRedPacketType().equals(indent.getIndentType()) || red.getRedPacketType().equals("0")) &&//判断该订单能否使用该红包
                    red.getDeleteFlag().equals("0") &&//判断红包是否已被使用过
                    red.getExpirationTime().after(new Date()) &&//判断红包是否已经过期
                    red.getMinimumAmount().compareTo(price1) != 1) {//判断订单价格是否大于红包最小使用额度
                //把红包改为已使用
                tbIndentDao.delRedPacket(indent.getRedPacketId());
                //红包可用，用刚才计算的价格减去红包金额
                price1 = price1.subtract(red.getRedPacketAmount());
                if (price1.doubleValue() <= 0) {
                    price1 = BigDecimal.valueOf(0.01);
                }
            } else {
                return Result.error("红包使用异常，请刷新重试！");
            }
        }
        if (("1".equals(indent.getIndentType()) || "2".equals(indent.getIndentType())) && indent.getCargoInsuranceFlag() == 0) {
            //用户选择要保价费，则给订单基础价格加上保价费
            price1 = price1.add(indent.getCargoInsurance());
        } else if (("1".equals(indent.getIndentType()) || "2".equals(indent.getIndentType())) && indent.getCargoInsuranceFlag() == 1) {
            //用户默认不要保价费，则不改变订单价格，并将保价费改为0
            indent.setCargoInsurance(new BigDecimal(0));
        }
        if (indent.getIndentType().equals("3") && indent.getPrepayMoney() != null) {
            //帮我买订单再加上商品预付费
            price1 = price1.add(indent.getPrepayMoney());
        }
        if (indent.getTip() != null) {
            //加小费
            price1 = price1.add(indent.getTip());
        }
        //最终订单价格
        indent.setIndentMoney(price1);
        //生成取货码
        if (("1".equals(indent.getIndentType()) || "2".equals(indent.getIndentType()) || "3".equals(indent.getIndentType())) && indent.getItemCodeFlag() == 0) {
            int a = (int) ((Math.random() * 9 + 1) * 10000);
            indent.setOrderCode(String.valueOf(a));
        }
        //生成订单号
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String format = sdf.format(new Date());
        Random random = new Random();
        int i = (int) ((Math.random() * 9 + 1) * 10000);
        String indentNumber = format + i;
        indent.setIndentNumber(indentNumber);
        indent.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        //用户生成订单，默认为未支付状态
        indent.setIndentState("0");
        //计算骑手本单收入（配送费+小费）
        indent.setRiderMoney(indent.getErrandMoney());
        if (indent.getTip() != null) {
            BigDecimal riderMoney = indent.getErrandMoney().add(indent.getTip());
            indent.setRiderMoney(riderMoney);
        }
        //计算骑手本单收入（+商品费）
        if (indent.getPrepayMoney() != null) {
            BigDecimal riderMoney = indent.getRiderMoney().add(indent.getPrepayMoney());
            indent.setRiderMoney(riderMoney);
        }
        //计算平台本单收入（订单价格-骑手跑腿费-商品费）
        BigDecimal subtract = indent.getIndentMoney().subtract(indent.getErrandMoney());
        if (indent.getPrepayMoney() == null) {
            indent.setPrepayMoney(BigDecimal.valueOf(0));
        }
        if ("3".equals(indent.getIndentType())) {
            subtract = subtract.subtract(indent.getPrepayMoney());
        }
        indent.setPlatformMoney(subtract);
        //前端传了默认的支付方式，在后端改为null
        indent.setModeOfPayment(null);
        tbIndentDao.insert(indent);
        TbIndent indent1 = tbIndentDao.selectIndentByIndentNumber(indentNumber);
        return Result.success().put("data", indent1);
    }

    @Override
    public TbIndent findIndentByIndentNumber(String indentNumber) {
        return baseMapper.selectIndentByIndentNumber(indentNumber);
    }

    @Override
    public PageUtils findNewIndent(WaitForAcceptOrderQueryDTO queryDTO) {
        Page<TbIndent> pages = new Page<>(queryDTO.getPage(), queryDTO.getLimit());

        String receivingPattern = queryDTO.getReceivingPattern();

        IPage<TbIndent> indent;
        // 接单模式 1近单模式，2同城模式
        if (ObjectUtil.equal(receivingPattern, "1")) {
            CommonInfo one = commonInfoService.findOne(274);
            queryDTO.setDistances(Double.valueOf(one.getValue()));
            indent = baseMapper.findNewIndentByDistances(pages, queryDTO);
        } else {
//            String city = getCurrentCityByLngAndLat(queryDTO.getRiderLng(), queryDTO.getRiderLat());
//            queryDTO.setCity(city);

            indent = baseMapper.findNewIndentByCity(pages, queryDTO);
        }

        // indentType为4时调用distance()重新计算距离步骤去除

        return new PageUtils(indent);
    }

    @Override
    public PageUtils findNewIndentGroupByShop(WaitForAcceptOrderQueryDTO queryDTO) {
        Page<ShopWaitAcceptOrderVO> pages = new Page<>(queryDTO.getPage(), queryDTO.getLimit());

        String receivingPattern = queryDTO.getReceivingPattern();

        IPage<ShopWaitAcceptOrderVO> indent;
        // 接单模式 1近单模式，2同城模式
        if (ObjectUtil.equal(receivingPattern, "1")) {
            CommonInfo one = commonInfoService.findOne(274);
            queryDTO.setDistances(Double.valueOf(one.getValue()));
            indent = baseMapper.findNewIndentByDistancesGroupByShop(pages, queryDTO);
        } else {
            // 如果city为空，则根据骑手经纬度获取当前城市
            if (StrUtil.isBlank(queryDTO.getCity())) {
                String city = getCurrentCityByLngAndLat(queryDTO.getRiderLng(), queryDTO.getRiderLat());
                queryDTO.setCity(city);
            }

            indent = baseMapper.findNewIndentByCityGroupByShop(pages, queryDTO);
        }
        return new PageUtils(indent);
    }

    /**
     * 获取当前经纬度所在城市
     *
     * @param lng 经度 xxx.yyyy
     * @param lat 纬度 xx.yyyy
     * @return 城市名称
     */
    private String getCurrentCityByLngAndLat(Double lng, Double lat) {
        String way = commonInfoService.findOne(416).getValue();
        String city = null;
        try {
            if ("1".equals(way)) {
                //根据骑手经纬度获取骑手所在城市
                CommonInfo one = commonInfoService.findOne(235);
                String url = "https://apis.map.qq.com/ws/geocoder/v1/";
                Map<String, String> maps = new HashMap<>();
                maps.put("location", lat + "," + lng);
                maps.put("key", one.getValue());
                String data = HttpClientUtil.doGet(url, maps);
                JSONObject jsonObject = JSON.parseObject(data);
                log.error("jsonObject的值：" + jsonObject);
                String status = jsonObject.getString("status");
                if ("0".equals(status)) {
                    JSONObject result = jsonObject.getJSONObject("result");
                    JSONObject adInfo = result.getJSONObject("ad_info");
                    if (adInfo != null) {
                        city = String.valueOf(adInfo.get("city"));
                    }
                }
            } else {
                String value = commonInfoService.findOne(417).getValue();
                String url = "http://api.tianditu.gov.cn/geocoder";
                Map<String, String> param = new HashMap<>();
                JSONObject postStr = new JSONObject();
                postStr.put("lon", lng);
                postStr.put("lat", lat);
                postStr.put("ver", "1");
                param.put("postStr", postStr.toJSONString());
                param.put("type", "geocode");
                param.put("tk", value);
                String s = HttpClientUtil.doGet(url, param);
                JSONObject jsonObject = JSONObject.parseObject(s);
                String status = jsonObject.getString("status");
                if ("0".equals(status)) {
                    JSONObject result = jsonObject.getJSONObject("result");
                    JSONObject addressComponent = result.getJSONObject("addressComponent");
                    city = addressComponent.getString("city");
                }
            }

        } catch (Exception e) {
            throw new SqxException("获取当前用户位置失败，失败原因：【" + e.getMessage() + "】");
        }

        if (ObjectUtil.isNull(city)) {
            throw new SqxException("获取当前用户位置失败");
        }

        return city;
    }


    @Override
    public Result indentReceiving(Long userId, String indentNumber) {
        //判断骑手状态是否被封号
        UserEntity userEntity1 = userService.selectUserById(userId);
        if (userEntity1.getStatus() != 1) {
            return Result.error("您的帐号已被封禁，请联系客服解封！");
        }
        //判断骑手保证金是否大于可接单金额
        UserEntity userMessage = userService.selectUserById(userId);
        String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        CommonInfo one1 = commonInfoService.findOne(273);
        Double cashDeposit = Double.valueOf(one1.getValue());
        if (userMessage.getCashDeposit().compareTo(BigDecimal.valueOf(cashDeposit)) > 0 || userMessage.getCashDeposit().compareTo(BigDecimal.valueOf(cashDeposit)) == 0) {
            //判断骑手是否超过最大接单数量
            String maxNumStr = commonInfoService.findOne(342).getValue();
            Integer maxNum = Integer.parseInt(maxNumStr);
            int i = tbIndentDao.selectIndentByRiderUserCount(userId);
            if (i >= maxNum) {
                return Result.error("您已达最大接单数量，请先完成订单后再进行接单");
            }

            TbIndent tbIndent;
            RLock lock = redissonClient.getLock(String.format(RedisKey.UPDATE_INDENT_LOCK, indentNumber));
            lock.lock();
            try {
                tbIndent = tbIndentDao.findIndentByNumber(indentNumber);
                log.error("抢单：" + userId + "     " + tbIndent.getIndentState());
                if (!"2".equals(tbIndent.getIndentState())) {
                    return Result.error("订单已被抢走！");
                }
                if ("5".equals(tbIndent.getIndentType())) {
                    tbIndentDao.indentReceiv(userId, indentNumber, format, "4");
                    TransferRecordEntity tr = new TransferRecordEntity();
                    tr.setUserId(userEntity1.getUserId());
                    tr.setUserName(userEntity1.getUserName());
                    tr.setUserPhone(userEntity1.getPhone());
                    tr.setOrderId(tbIndent.getOrderId());
                    tr.setReceveTime(format);
                    //获取站点内容
                    RiderStation station = riderStationService.stationById(userEntity1.getRiderStationId());
                    log.error("第一次接单station1：" + new Gson().toJson(station));
                    if(station != null){
                        log.error("第一次接单station2：" + new Gson().toJson(station));
                        tr.setStationName(station.getStationName());
                        log.error("第一次接单station3：" + new Gson().toJson(tr));
                    }
                    tr.setDeleteFlag(0);
                    transferRecordDao.insert(tr);
                } else {
                    TbOrder tbOrder = appOrderService.getById(tbIndent.getOrderId());
                    if (!Integer.valueOf(2).equals(tbOrder.getOrderTypeExtra())) {
                        return Result.error("当前订单为商家自配订单，您无法接单！");
                    }

                    tbIndentDao.indentReceiving(userId, indentNumber, format);
                    TransferRecordEntity tr = new TransferRecordEntity();
                    tr.setUserId(userEntity1.getUserId());
                    tr.setUserName(userEntity1.getUserName());
                    tr.setUserPhone(userEntity1.getPhone());
                    tr.setOrderId(tbIndent.getOrderId());
                    tr.setReceveTime(format);
                    //获取站点内容
                    RiderStation station = riderStationService.stationById(userEntity1.getRiderStationId());
                    log.error("第一次接单station：" + new Gson().toJson(station));
                    if(station != null){
                        log.error("第一次接单station2：" + new Gson().toJson(station));
                        tr.setStationName(station.getStationName());
                        log.error("第一次接单station3：" + new Gson().toJson(tr));
                    }
                    tr.setDeleteFlag(0);
                    transferRecordDao.insert(tr);
                }



            } finally {
                lock.unlock();
            }

            MyGlobalThreadPool.execute(() -> {
                try {
                    //消息推送（以前写的在下面放着）
                    CommonInfo five = commonInfoService.findOne(310);
                    List<String> msgList = new ArrayList<>();
                    msgList.add("接单项目");
                    msgList.add(userEntity1.getNickName());
                    msgList.add(format);
                    msgList.add("接单成功，请及时取货！");
                    SenInfoCheckUtil.sendRiderMsg(userEntity1.getRiderOpenId(), five.getValue(), msgList, 4);
                    userService.pushToSingleRider("接单成功", "您已接单成功，请及时派送", userEntity1.getRiderClientid());

                    //用户推送
                    CommonInfo msg = commonInfoService.findOne(269);
                    UserEntity userEntity = userService.selectUserById(tbIndent.getUserId());
                    MessageInfo messageInfo = new MessageInfo();
                    messageInfo.setContent("骑手已接单");
                    messageInfo.setTitle("订单状态通知");
                    messageInfo.setState(String.valueOf(5));
                    messageInfo.setUserName(userEntity.getUserName());
                    messageInfo.setUserId(String.valueOf(userEntity.getUserId()));
                    messageInfo.setCreateAt(DateUtils.format(new Date()));
                    messageInfo.setIsSee("0");
                    messageService.saveBody(messageInfo);

                    List<String> msgListUser = new ArrayList<>();
                    String value = commonInfoService.findOne(12).getValue();
                    msgListUser.add("骑手已接单");
                    msgListUser.add(tbIndent.getIndentNumber());
                    if (tbIndent.getOrderId() != null) {
                        TbOrder order = appOrderService.getById(tbIndent.getOrderId());
                        if (order != null) {
                            Long shopId = order.getShopId();
                            GoodsShop goodsShop = goodsShopDao.selectById(shopId);
                            msgListUser.add(goodsShop.getShopName());
                        } else {
                            msgListUser.add(value);
                        }
                    } else {
                        msgListUser.add(value);
                    }
                    msgListUser.add(DateUtils.format(new Date()));

                    SenInfoCheckUtil.sendMsg(userEntity.getOpenId(), msg.getValue(), msgListUser, 1);

                    if (tbIndent.getOrderId() != null) {
                        TbOrder order = appOrderService.getById(tbIndent.getOrderId());
                        String shopTemplate = commonInfoService.findOne(354).getValue();
                        List<String> msgListShop = new ArrayList<>();
                        msgListShop.add(tbIndent.getIndentNumber());
                        msgListShop.add("骑手接单");
                        msgListShop.add(DateUtils.format(new Date()));
                        GoodsShop goodsShop = goodsShopDao.selectById(order.getShopId());
                        UserEntity shopUser = userService.selectUserById(goodsShop.getUserId());

                        SenInfoCheckUtil.sendShopMsg(shopUser.getShopOpenId(), shopTemplate, msgListShop, 9);
                    }
                } catch (Exception e) {
                    log.error("订单编号：{}，骑手接单成功信息发送失败，失败原因：{}", indentNumber, e);
                }
            });
        } else {
            return Result.error("你的保证金不足，请缴纳保证金后再接单");
        }
        return Result.success();
    }

    public void checkRider(Long riderUserId) {
        // 判断骑手状态是否被封号
        UserEntity riderUser = userService.selectUserById(riderUserId);
        if (riderUser.getStatus() != 1) {
            throw new SqxException("骑手的帐号已被封禁，请联系客服解封！");
        }

        // 判断骑手保证金是否大于可接单金额
        CommonInfo one1 = commonInfoService.findOne(273);
        Double cashDeposit = Double.valueOf(one1.getValue());
        if (riderUser.getCashDeposit().compareTo(BigDecimal.valueOf(cashDeposit)) < 0) {
            throw new SqxException("骑手的保证金不足，请缴纳保证金后再接单");
        }

        // 判断骑手是否超过最大接单数量
        String maxNumStr = commonInfoService.findOne(342).getValue();
        Integer maxNum = Integer.parseInt(maxNumStr);
        if (tbIndentDao.selectIndentByRiderUserCount(riderUserId) >= maxNum) {
            throw new SqxException("您已达最大接单数量，请先完成订单后再进行接单");
        }
    }

    @Override
    public Result orderIndentReceiving(Long riderUserId, String acquireCode) {
        // 检查骑手
        checkRider(riderUserId);

        // 根据收单码查询订单
        TbIndent tbIndent = getByOrderId(acquireCode);

        String receiveTimeStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        UserEntity riderUser = userService.selectUserById(riderUserId);

        RLock lock = redissonClient.getLock(String.format(RedisKey.UPDATE_INDENT_LOCK, tbIndent.getIndentNumber()));
        lock.lock();
        try {
            // 再次查询订单
            tbIndent = getById(tbIndent.getIndentId());
            if (!"2".equals(tbIndent.getIndentState())) {
                throw new SqxException("订单已被抢走！");
            }

            // 更改订单状态
            TbIndent newIndent = new TbIndent();
            newIndent.setIndentId(tbIndent.getIndentId());
            newIndent.setIndentState("4"); // 4：骑手已取货/购买
            newIndent.setRiderUserId(riderUserId);
            newIndent.setReceivingTime(receiveTimeStr);
            updateById(newIndent);

            // 插入转单记录记录
            TransferRecordEntity tr = new TransferRecordEntity();
            tr.setUserId(riderUserId);
            tr.setUserName(riderUser.getUserName());
            tr.setUserPhone(riderUser.getPhone());
            tr.setOrderId(tbIndent.getOrderId());
            tr.setReceveTime(receiveTimeStr);
            RiderStation station = riderStationService.stationById(riderUser.getRiderStationId());  // 获取站点内容
            if(station != null){
                tr.setStationName(station.getStationName());
            }
            tr.setDeleteFlag(0);
            transferRecordDao.insert(tr);
        } finally {
            lock.unlock();
        }

        // 发送骑手接单消息
        sendOrderReceivingMsg(tbIndent, riderUser);

        return Result.success();
    }

    private void sendOrderReceivingMsg(TbIndent tbIndent, UserEntity riderUser) {
        MyGlobalThreadPool.execute(() -> {
            try {
                List<String> msgList = new ArrayList<>();
                msgList.add("接单项目");
                msgList.add(riderUser.getNickName());
                msgList.add(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
                msgList.add("接单成功，请及时取货！");
                CommonInfo five = commonInfoService.findOne(310);
                userService.pushToSingleRider("接单成功", "您已接单成功，请及时派送", riderUser.getRiderClientid());
                SenInfoCheckUtil.sendRiderMsg(riderUser.getRiderOpenId(), five.getValue(), msgList, 4);

                MessageInfo messageInfo = new MessageInfo();
                messageInfo.setContent("骑手已接单");
                messageInfo.setTitle("订单状态通知");
                messageInfo.setState(String.valueOf(5));
                messageInfo.setCreateAt(DateUtils.format(new Date()));
                messageInfo.setIsSee("0");
                UserEntity userEntity = userService.selectUserById(tbIndent.getUserId());
                messageInfo.setUserName(userEntity.getUserName());
                messageInfo.setUserId(String.valueOf(userEntity.getUserId()));
                messageService.saveBody(messageInfo);

                List<String> msgListUser = new ArrayList<>();
                String value = commonInfoService.findOne(12).getValue();
                if (tbIndent.getOrderId() != null) {
                    TbOrder order = appOrderService.getById(tbIndent.getOrderId());
                    if (order != null) {
                        Long shopId = order.getShopId();
                        GoodsShop goodsShop = goodsShopDao.selectById(shopId);
                        msgListUser.add(goodsShop.getShopName());
                    } else {
                        msgListUser.add(value);
                    }
                } else {
                    msgListUser.add(value);
                }
                msgListUser.add("骑手已接单");
                msgListUser.add(tbIndent.getIndentNumber());
                msgListUser.add(DateUtils.format(new Date()));
                CommonInfo msg = commonInfoService.findOne(269);
                SenInfoCheckUtil.sendMsg(userEntity.getOpenId(), msg.getValue(), msgListUser, 1);

                if (tbIndent.getOrderId() != null) {
                    TbOrder order = appOrderService.getById(tbIndent.getOrderId());
                    String shopTemplate = commonInfoService.findOne(354).getValue();
                    List<String> msgListShop = new ArrayList<>();
                    msgListShop.add(tbIndent.getIndentNumber());
                    msgListShop.add("骑手接单");
                    msgListShop.add(DateUtils.format(new Date()));
                    GoodsShop goodsShop = goodsShopDao.selectById(order.getShopId());
                    UserEntity shopUser = userService.selectUserById(goodsShop.getUserId());

                    SenInfoCheckUtil.sendShopMsg(shopUser.getShopOpenId(), shopTemplate, msgListShop, 9);
                }
            } catch (Exception e) {
                log.error("订单编号：{}，骑手接单成功信息发送失败，失败原因：{}", tbIndent.getIndentNumber(), e);
            }
        });
    }

    @Override
    public Result riderBuyGoods(TbIndent indent) {
        if ("4".equals(indent.getIndentState())) {
            TbIndent tbIndent = baseMapper.selectById(indent.getIndentId());
            if (!"3".equals(tbIndent.getIndentState())) {
                return Result.error("订单状态变更，请刷新页面后重试！");
            }
            //用户推送
            CommonInfo msg = commonInfoService.findOne(269);
            UserEntity userEntity = userService.selectUserById(tbIndent.getUserId());
            if (userEntity != null) {

                MessageInfo messageInfo = new MessageInfo();
                messageInfo.setContent("骑手已取货，正在为您配送");
                messageInfo.setTitle("订单状态通知");
                messageInfo.setState(String.valueOf(5));
                messageInfo.setUserName(userEntity.getUserName());
                messageInfo.setUserId(String.valueOf(userEntity.getUserId()));
                messageInfo.setCreateAt(DateUtils.format(new Date()));
                messageInfo.setIsSee("0");
                messageService.saveBody(messageInfo);


                List<String> msgList = new ArrayList<>();
                String value = commonInfoService.findOne(12).getValue();
                msgList.add("骑手已取货");
                msgList.add(tbIndent.getIndentNumber());
                if (tbIndent.getOrderId() != null) {
                    TbOrder order = appOrderService.getById(tbIndent.getOrderId());
                    if (order != null) {
                        Long shopId = order.getShopId();
                        GoodsShop goodsShop = goodsShopDao.selectById(shopId);
                        msgList.add(goodsShop.getShopName());
                    } else {
                        msgList.add(value);
                    }
                } else {
                    msgList.add(value);
                }
                msgList.add(DateUtils.format(new Date()));
                SenInfoCheckUtil.sendMsg(userEntity.getOpenId(), msg.getValue(), msgList, 1);
            }
        }
        tbIndentDao.updateById(indent);
        return Result.success();
    }

    @Override
    public Result findRiderIndent(Long userId, Integer page, Integer limit, String indentState, String keyword) {
        Page<TbIndent> pages = new Page<>(page, limit);
        PageUtils pageUtils = new PageUtils(tbIndentDao.findRiderIndent(pages, userId, indentState, keyword));
        return Result.success().put("data", pageUtils);
    }

    @Override
    public Result findRiderIndentByIds(Long userId, Integer page, Integer limit, List<String> indentIds) {
        Page<queryOrderInfoVo> pages = new Page<>(page, limit);
        PageUtils pageUtils = new PageUtils(tbIndentDao.findRiderIndentByIds(pages, userId, indentIds));
        return Result.success().put("data", pageUtils);
    }

    @Override
    public TbIndent indentMessage(String indentNumber, double riderLng, double riderLat) {
        TbIndent tbIndent = tbIndentDao.indentRiderMessage(indentNumber, riderLng, riderLat);
        return tbIndent;
    }

    @Override
    public TbIndent indentMessageByOrderId(Long orderId, double riderLng, double riderLat) {
        TbIndent tbIndent = tbIndentDao.indentMessageByOrderId(orderId, riderLng, riderLat);
        return tbIndent;
    }

    @Override
    public void transferOfOrder(Long userId, RiderTransferOrderDTO transferOrderDTO) {
        // 获取待转单
        TbIndent indent = getTransferOrder(userId, transferOrderDTO);
        UserEntity indentuserEntity = userService.selectUserById(indent.getRiderUserId());
        if(indentuserEntity == null){
            throw new SqxException("订单骑手已失效，无法发起转单！");
        }

        // 获取新的骑手
        UserEntity userEntity = getNewRicher(userId, transferOrderDTO);
        if(userEntity == null){
            throw new SqxException("被转单骑手已失效，无法发起转单！");
        }

        if(userEntity.getRiderStationId().intValue() != indentuserEntity.getRiderStationId().intValue()){
            throw new SqxException("无法选择其他站点骑手进行转单操作！");
        }

        // 开始转单
        indent.setRiderUserId(userEntity.getUserId());
        indent.setIsRider(1);
        updateById(indent);
        log.info("测试是否进入转单3");
        String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        TransferRecordEntity tr = new TransferRecordEntity();
        tr.setUserId(userEntity.getUserId());
        tr.setUserName(userEntity.getUserName());
        tr.setUserPhone(userEntity.getPhone());
        tr.setOrderId(indent.getOrderId());
        tr.setReceveTime(format);
        tr.setStationName(userEntity.getStationName());
        tr.setDeleteFlag(0);
        log.info("测试是否进入转单4，tr:"+ new Gson().toJson(tr));
        int insertCount = transferRecordDao.insert(tr);
        log.info("测试是否进入转单5,insertCount："+insertCount);
        // 消息通知
        noticeAfterTransfer(indent);
    }

    @Override
    public void transferByOrderId(Long userId, RiderTransferByOrderIdDTO transferOrderDTO) {
        // 获取待转单
        TbIndent indent = getTransferByOrderId(userId, transferOrderDTO);
        RiderTransferOrderDTO data = new RiderTransferOrderDTO();
        data.setPhone(transferOrderDTO.getPhone());
        data.setRealName(transferOrderDTO.getRealName());
        // 获取新的骑手
        UserEntity userEntity = getNewRicher(userId, data);

        // 开始转单
        indent.setRiderUserId(userEntity.getUserId());
        indent.setIsRider(1);
        updateById(indent);

        // 消息通知
        noticeAfterTransfer(indent);
    }

    /**
     * 获取待转单配送单
     *
     * @param currentUserId    当前用户
     * @param transferOrderDTO
     * @return
     */
    private TbIndent getTransferByOrderId(Long currentUserId, RiderTransferByOrderIdDTO transferOrderDTO) {
        // 开始转单

        TbIndent indent = baseMapper.selectOne(new QueryWrapper<TbIndent>().eq("order_id", transferOrderDTO.getAcquireCode()));
        if (ObjectUtil.isNull(indent)) {
            throw new SqxException("无效的配送单id");
        }

        if (!indent.getRiderUserId().equals(currentUserId)) {
            throw new SqxException("不能操作非自己的订单");
        }

        if (!"3".equals(indent.getIndentState()) && !"4".equals(indent.getIndentState())) {
            throw new SqxException("订单状态发生变更，请刷新后重试！");
        }

        return indent;
    }


    //region
    @Override
    public Result orderRiderDelivery(Long userId, OrderRiderDeliveryDTO orderDeliveryDTO) {
        String acquireCode = orderDeliveryDTO.getAcquireCode();
        TbIndent indentOrder = tbIndentDao.findIndentByOrderId(acquireCode);
        if (ObjectUtil.isNull(indentOrder)) {
            throw new SqxException("扫码无效的跑腿订单id");
        }

        // 判断是否为当前骑手订单
        if (!Objects.equals(indentOrder.getRiderUserId(), userId)) {
            throw new SqxException("不能完成非本人订单！");
        }

        // 如果是外卖订单
        if (ObjectUtil.equal(indentOrder.getIndentType(), "5")) {
            orderHandTakeoutOrder(indentOrder, userId, orderDeliveryDTO);
        }

        RLock lock = redissonClient.getLock(String.format(RedisKey.UPDATE_INDENT_LOCK, indentOrder.getIndentNumber()));
        lock.lock();
        try {
            indentOrder = tbIndentDao.selectById(indentOrder.getIndentId());

            // 4：骑手已取货/购买 只有订单在4状态下才可以完成订单
            if (!"4".equals(indentOrder.getIndentState())) {
                throw new SqxException("订单状态已变更，请刷新页面后重试！");
            }

            log.info("骑手通过收单码完成订单：订单id【{}】", indentOrder.getOrderId());
            appOrderService.accomplishOrder(indentOrder.getOrderId(), 1);
        } catch (Exception e) {
            log.error("完成订单异常：{}", e.getMessage(), e);
            throw new SqxException(e.getMessage());
        } finally {
            lock.unlock();
        }

        return Result.success();
    }

    /**
     * 处理外卖订单
     *
     * @param indentOrder 跑腿订单
     * @param userId      当前用户id
     * @param deliveryDTO 送达信息
     */
    private void orderHandTakeoutOrder(TbIndent indentOrder, Long userId, OrderRiderDeliveryDTO deliveryDTO) {
        Long smsTemplateId = deliveryDTO.getSmsTemplateId();
        if (ObjectUtil.isNull(smsTemplateId)) {
            throw new SqxException("短信模板id不能为空");
        }

        MyGlobalThreadPool.execute(() -> {
            try {
                // 收货人手机
                String userPhone = indentOrder.getUserPhone();
                // 当前骑手
                UserEntity riderUser = userService.selectUserById(userId);

                // 发送短信并记录短信发送记录
                TbIndentSmsSendLog tbIndentSmsSendLog = smsSendLogService.getSendSuccessByOrderId(indentOrder.getIndentId());
                if(tbIndentSmsSendLog != null){
                    log.error("外卖跑腿订单id【{}】短信已发送成功,短信id【{}】",tbIndentSmsSendLog.getOrderId(),tbIndentSmsSendLog.getId());
                    return;
                }
                SmsSendResult smsSendResult = smsTemplateService.sendSms(smsTemplateId, riderUser, userPhone);
                // sourceType 1骑手、2商家
                smsSendLogService.saveLog(indentOrder.getIndentId(), "1", smsSendResult);
            } catch (Exception e) {
                log.error("订单：{}，完成跑腿订单成功通知发送失败，失败原因：{}", e);
            }
        });
    }
    //endregion

    @Override
    public void riderUploadDeliveryImg(Long userId, String indentNumber, String imgs) {
        TbIndent indentOrder = tbIndentDao.findIndentByNumber(indentNumber);
        if (ObjectUtil.isNull(indentOrder)) {
            throw new SqxException("无效的跑腿订单id");
        }

        TbOrder tbOrder = appOrderService.getById(indentOrder.getOrderId());
        tbOrder.setDeliveryImgs(imgs);
        appOrderService.updateById(tbOrder);
    }

    @Override
    public TbIndent getByOrderId(String orderId) {
        // 根据收单码查询订单
        TbIndent tbIndent = tbIndentDao.findIndentByOrderId(orderId);
        if (ObjectUtil.isNull(tbIndent)) {
            throw new SqxException("无效的收单码");
        }
        return tbIndent;
    }

    @Override
    @Transactional(propagation = Propagation.SUPPORTS)
    public void sysCancelOrder(String indentNumber) {
        TbIndent tbIndent = tbIndentDao.findIndentByNumber(indentNumber);
        if (ObjectUtil.isNotNull(tbIndent)) {
            TbIndent newIndent = new TbIndent();
            newIndent.setIndentId(tbIndent.getIndentId());
            newIndent.setIndentState("10");
            tbIndentDao.updateById(newIndent);

//            撤销快跑者订单
            TbOrder tbOrder = appOrderService.getOne(new QueryWrapper<TbOrder>().eq("order_number", indentNumber));
            if (ObjectUtils.isNotEmpty(tbOrder)&&ObjectUtils.isNotEmpty(tbOrder.getTradeNo())) {
                log.info("第一次撤销快跑者订单："+tbOrder.getTradeNo());
                String responseBody = cancelSpeedRunnerOrder(tbOrder.getTradeNo());
                if (ObjectUtils.isNotEmpty(responseBody)) {
                    JSONObject jsonObject = JSONObject.parseObject(responseBody);
                    Integer code = jsonObject.getInteger("code");
                    if (code!=200) {
                        log.info("第二次撤销快跑者订单："+tbOrder.getTradeNo());
                        String responseBody2 = cancelSpeedRunnerOrder(tbOrder.getTradeNo());
                    }
                }else {
                    log.info("第一次撤销结果为空，第二次撤销快跑者订单："+tbOrder.getTradeNo());
                    String responseBody2 = cancelSpeedRunnerOrder(tbOrder.getTradeNo());
                }
            }
        }
    }
    public String cancelSpeedRunnerOrder(String tradeNo){

        com.alibaba.fastjson.JSONObject body = new com.alibaba.fastjson.JSONObject();
        body.put("trade_no", tradeNo);

        log.info("body信息：" + body);

//               版本
        String version = "1";
//               时间戳
        long currentTimeMillis = System.currentTimeMillis();
        long currentTimeSeconds = currentTimeMillis / 1000;
        String timestamp = String.valueOf(currentTimeSeconds);
//               唯一标识符
        String ticket = "83f0ff99-7c8e-47e8-8802-bd3754414a52";
//               团队token
        String teamToken = "Q444DMV4LT8WSGRW";
//               开发者中心的开发密钥
        String devKey = "31RRHA4O165VFN9W2DAPDYDH8N83BT12";

//               获取签名
        String sign = com.sqx.common.utils.SignUtil.getSign(body.toString(), devKey, teamToken, ticket, currentTimeSeconds, 1);
        String responseBody="";
        try {
            log.info("撤销快跑者订单");
            CloseableHttpClient client = HttpClients.createDefault();
            // 创建httppost
            HttpPost httpPost = new HttpPost("https://open.keloop.cn/open/order/cancelOrder");
            String params = "version=" + version + "&timestamp=" + timestamp + "&ticket=" + ticket + "&team_token=" + teamToken + "&dev_key=" + devKey + "&sign=" + sign + "&body=" + body.toString(); // 注意：这里不需要手动编码，HttpClient会处理它。
            StringEntity entity = new StringEntity(params, StandardCharsets.UTF_8);
            entity.setContentType("application/x-www-form-urlencoded"); // 设置Content-Type为application/x-www-form-urlencoded，但不是必须的，HttpClient会自动设置。
            httpPost.setEntity(entity);
            responseBody = EntityUtils.toString(client.execute(httpPost).getEntity());
            log.info("撤销结果："+responseBody);
        }catch (Exception e){
            e.printStackTrace();
        }
        return responseBody;
    }
    @Override
    public Result finalizeOrder(Long userId, TbIndent indentOrder) {
        if (ObjectUtil.isNull(indentOrder)) {
            throw new SqxException("扫码无效的跑腿订单id");
        }

        // 判断是否为当前骑手订单
        if (!Objects.equals(indentOrder.getRiderUserId(), userId)) {
//            不为本人则需要调用转单接口
            log.info("不为接单本人，需转单");
            log.info("当前骑手id："+indentOrder.getRiderUserId()+",需要更换的骑手id:"+userId);
            UserEntity userEntity = userService.getById(userId);
            indentOrder.setRiderUserId(userEntity.getUserId());
            indentOrder.setIsRider(1);
            updateById(indentOrder);
            log.info("测试是否进入转单3");
            String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
            TransferRecordEntity tr = new TransferRecordEntity();
            tr.setUserId(userEntity.getUserId());
            tr.setUserName(userEntity.getUserName());
            tr.setUserPhone(userEntity.getPhone());
            tr.setOrderId(indentOrder.getOrderId());
            tr.setReceveTime(format);
            tr.setStationName(userEntity.getStationName());
            tr.setDeleteFlag(0);
            log.info("测试是否进入转单4，tr:"+ new Gson().toJson(tr));
            int insertCount = transferRecordDao.insert(tr);
            log.info("测试是否进入转单5,insertCount："+insertCount);
//            throw new SqxException("不能完成非本人订单！");
        }

        RLock lock = redissonClient.getLock(String.format(RedisKey.UPDATE_INDENT_LOCK, indentOrder.getIndentNumber()));
        lock.lock();
        try {
            indentOrder = tbIndentDao.selectById(indentOrder.getIndentId());

            // 4：骑手已取货/购买 只有订单在4状态下才可以完成订单
//            if (!"4".equals(indentOrder.getIndentState())) {
////                throw new SqxException("订单状态已变更，请刷新页面后重试！");
////            }

            log.info("骑手通过收单码完成订单：订单id【{}】", indentOrder.getOrderId());
            appOrderService.accomplishOrder(indentOrder.getOrderId(), 1);
        } catch (Exception e) {
            log.error("完成订单异常：{}", e.getMessage(), e);
            throw new SqxException(e.getMessage());
        } finally {
            lock.unlock();
        }

        return Result.success();
    }

    @Transactional
    @Override
    public Result riderCancleIndent(String indentNumber, Integer type) {
        TbIndent tbIndent = baseMapper.selectOne(new QueryWrapper<TbIndent>().eq("indent_number", indentNumber));
        Long userId = tbIndent.getRiderUserId();
        UserEntity userInfo = userService.selectUserById(userId);
        CommonInfo one = commonInfoService.findOne(275);
        BigDecimal riderFine = tbIndent.getErrandMoney().multiply(BigDecimal.valueOf(Double.valueOf(one.getValue())));
        if (type == 1) {
            if (userInfo.getCashDeposit().doubleValue() <= riderFine.doubleValue()) {
                return Result.error("您的保证金不足，不能取消该订单！");
            }
        }
        //把订单改为未接单状态
        tbIndentDao.riderCancleIndent(userId, indentNumber);
        //返回订单对象
        //骑手取消订单后，从骑手的保证金里暂扣罚金
        BigDecimal cashDeposit = userInfo.getCashDeposit().subtract(riderFine);
        tbIndentDao.updateRiderCashDeposit(cashDeposit, userId);
        //将扣款明细添加到钱包明细表里
        UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
        userMoneyDetails.setMoney(riderFine);
        userMoneyDetails.setUserId(userId);
        userMoneyDetails.setContent("骑手取消订单扣除保证金：" + riderFine);
        userMoneyDetails.setTitle("骑手取消接单");
        userMoneyDetails.setType(2);
        userMoneyDetails.setClassify(1);
        userMoneyDetails.setState(2);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = simpleDateFormat.format(new Date());
        userMoneyDetails.setCreateTime(time);
        userMoneyDetailsService.save(userMoneyDetails);

        //用户推送
        CommonInfo msg = commonInfoService.findOne(269);
        UserEntity userEntity = userService.selectUserById(tbIndent.getUserId());

        if (userEntity != null) {

            MessageInfo messageInfo = new MessageInfo();
            messageInfo.setContent("骑手取消接单，正在为您重新匹配骑手");
            messageInfo.setTitle("订单状态通知");
            messageInfo.setState(String.valueOf(5));
            messageInfo.setUserName(userEntity.getUserName());
            messageInfo.setUserId(String.valueOf(userEntity.getUserId()));
            messageInfo.setCreateAt(DateUtils.format(new Date()));
            messageInfo.setIsSee("0");
            messageService.saveBody(messageInfo);

            List<String> msgList = new ArrayList<>();
            String value = commonInfoService.findOne(12).getValue();
            msgList.add("骑手已取消");
            msgList.add(tbIndent.getIndentNumber());
            if (tbIndent.getOrderId() != null) {
                TbOrder order = appOrderService.getById(tbIndent.getOrderId());
                if (order != null) {
                    Long shopId = order.getShopId();
                    GoodsShop goodsShop = goodsShopDao.selectById(shopId);
                    msgList.add(goodsShop.getShopName());
                } else {
                    msgList.add(value);
                }
            } else {
                msgList.add(value);
            }
            msgList.add(time);
            SenInfoCheckUtil.sendMsg(userEntity.getOpenId(), msg.getValue(), msgList, 1);

            if (tbIndent.getOrderId() != null) {
                TbOrder order = appOrderService.getById(tbIndent.getOrderId());
                String shopTemplate = commonInfoService.findOne(354).getValue();
                List<String> msgListShop = new ArrayList<>();
                msgListShop.add(tbIndent.getIndentNumber());
                msgListShop.add("骑手取消");
                msgListShop.add(DateUtils.format(new Date()));
                GoodsShop goodsShop = goodsShopDao.selectById(order.getShopId());
                UserEntity shopUser = userService.selectUserById(goodsShop.getUserId());
                SenInfoCheckUtil.sendShopMsg(shopUser.getShopOpenId(), shopTemplate, msgListShop, 9);
            }

        }

        return Result.success();
    }

    @Override
    public Result riderDelivery(Long userId, RiderDeliveryDTO deliveryDTO) {
        // 添加拍照发短信逻辑
        // 因为原有的确认送达方法代码比较凌乱，且不好重新封装，所以这里就在原有确认收货方法之前添加拍照发短信逻辑
        String indentNumber = deliveryDTO.getIndentNumber();
        TbIndent indentOrder = tbIndentDao.findIndentByNumber(indentNumber);
        if (ObjectUtil.isNull(indentOrder)) {
            throw new SqxException("无效的跑腿订单id");
        }

        TransactionStatus status = null;
        RLock lock = redissonClient.getLock(String.format(RedisKey.UPDATE_INDENT_LOCK, indentNumber));
        lock.lock();
        try {
            status = transactionManager.getTransaction(new DefaultTransactionDefinition());
            // 如果是外卖订单
            if (ObjectUtil.equal(indentOrder.getIndentType(), "5")) {
                 handTakeoutOrder(indentOrder, userId, deliveryDTO);
            }

            Result result = finshOrder(userId, indentNumber, deliveryDTO.getItemCode());

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

    /**
     * 处理外卖订单
     *
     * @param indentOrder 跑腿订单
     * @param userId      当前用户id
     * @param deliveryDTO 送达信息
     */
    private void handTakeoutOrder(TbIndent indentOrder, Long userId, RiderDeliveryDTO deliveryDTO) {
        // 6表示跑腿订单处于已完成状态
        //锁内用锁外数据进行判断会拿等待锁前的数据判断
        if ("6".equals(indentOrder.getIndentState())) {
            return;
        }
        Long smsTemplateId = deliveryDTO.getSmsTemplateId();
        if (ObjectUtil.isNull(smsTemplateId)) {
            throw new SqxException("短信模板id不能为空");
        }

        // 收货人手机
        String userPhone = indentOrder.getUserPhone();
        // 当前骑手
        UserEntity riderUser = userService.getById(userId);

        if (StrUtil.isBlank(userPhone)) {
            log.error("外卖跑腿订单【{}】收货人手机号码为空...", deliveryDTO.getIndentNumber());
            return;
        }

        if (ObjectUtil.isNull(riderUser) || StrUtil.isBlank(riderUser.getPhone())) {
            log.error("外卖跑腿订单【{}】当前骑手id【{}】骑手不存在，或当前骑手手机号码为空...", deliveryDTO.getIndentNumber(), userId);
            return;
        }

        // 订单新增送达图片
        String imgs = deliveryDTO.getImgs();
        if (StrUtil.isNotBlank(imgs)) {
            TbOrder tbOrder = appOrderService.getById(indentOrder.getOrderId());
            tbOrder.setDeliveryImgs(imgs);
            appOrderService.updateById(tbOrder);
        }
        TbIndentSmsSendLog tbIndentSmsSendLog=smsSendLogService.getSendSuccessByOrderId(indentOrder.getIndentId());
//        有发送成功记录则不再发送
        if(tbIndentSmsSendLog!=null){
            log.error("外卖跑腿订单【{}】短信已发送成功,短信id【{}】", deliveryDTO.getIndentNumber(),tbIndentSmsSendLog.getId());
            return;
        }
        // 发送短信并记录短信发送记录
        SmsSendResult smsSendResult = smsTemplateService.sendSms(smsTemplateId, riderUser, userPhone);
        // sourceType 1骑手、2商家
        smsSendLogService.saveLog(indentOrder.getIndentId(), "1", smsSendResult);
    }

    @Transactional
    public Result finshOrder(Long userId, String indentNumber, String itemCode) {
        String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        TbIndent indentByNumber = tbIndentDao.findIndentByNumber(indentNumber);
        if ("6".equals(indentByNumber.getIndentState())) {
            return Result.success();
        }
        if ("4".equals(indentByNumber.getIndentState())) {
            if ("5".equals(indentByNumber.getIndentType())) {
                log.info("骑手完成订单2：" + indentByNumber.getOrderId());
                appOrderService.accomplishOrder(indentByNumber.getOrderId(), 1);
            } else {
                if (indentByNumber.getItemCodeFlag() != null && indentByNumber.getItemCodeFlag() == 0) {
                    if (indentByNumber.getOrderCode().equals(itemCode)) {
                        tbIndentDao.riderDelivery(indentByNumber.getIndentId(), date);
                        finshIndent(userId, indentNumber);
                    } else {
                        return Result.error("收货码错误！");
                    }
                } else {
                    tbIndentDao.riderDelivery(indentByNumber.getIndentId(), date);
                    finshIndent(userId, indentNumber);
                }
            }

            return Result.success();
        }
        return Result.error("订单已完成！");
    }


    @Override
    public Result userDelivery(Long userId, String indentNumber) {
        String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        RLock lock = redissonClient.getLock(String.format(RedisKey.UPDATE_INDENT_LOCK, indentNumber));
        lock.lock();
        try {
            TbIndent indentByNumber = tbIndentDao.findIndentByNumber(indentNumber);
            tbIndentDao.userDelivery(userId, indentNumber, date);
            finshIndent(userId, indentNumber);
            log.info("操作完成订单5：" + indentByNumber.getOrderId());
            appOrderService.accomplishOrder(indentByNumber.getOrderId(), 1);
            return Result.success();
        } finally {
            lock.unlock();
        }
    }

    @Override
    public Result userEvaluate(ErrandEvaluate errandEvaluate) {
        errandEvaluateDao.insert(errandEvaluate);
        return Result.success();
    }

    @Override
    public Result findallIndent(Integer page, Integer limit, Long userId, Long riderUserId, Long shopId, Integer indentType, String ordersNo, Integer status, String riderPhone) {
        Page<TbIndent> pages = new Page<>(page, limit);
        PageUtils pageUtils = new PageUtils(tbIndentDao.findallIndent(pages, userId, riderUserId, shopId, indentType, ordersNo, status, riderPhone));
        return Result.success().put("data", pageUtils);
    }

    @Override
    @Transactional
    public void finshIndent(Long userId, String indentNumber) {
        //用户确认送达以后，将配送费加到骑手余额账户
        TbIndent tbIndent = tbIndentDao.selectIndentByIndentNumber(indentNumber);

        // 骑手id为空表示当前订单没有骑手接单，这里直接记录日志后返回，防止后续订单完成逻辑不能正常完成
        if (ObjectUtil.isNull(tbIndent.getRiderUserId())) {
            log.error("订单编号：{}对应骑手id为空，跳过骑手收益计算逻辑...", indentNumber);
            return;
        }

        UserEntity userMessage = userService.selectUserById(tbIndent.getRiderUserId());
        BigDecimal balance = userMessage.getBalance().add(tbIndent.getRiderMoney());
        tbIndentDao.updateRiderBalance(balance, tbIndent.getRiderUserId());
        // 将接单明细添加到钱包明细表里
        UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
        userMoneyDetails.setMoney(tbIndent.getRiderMoney());
        userMoneyDetails.setUserId(tbIndent.getRiderUserId());
        userMoneyDetails.setTitle("[接单收入]接单ID：" + tbIndent.getIndentNumber());
        userMoneyDetails.setContent("接单收入:" + tbIndent.getRiderMoney());
        userMoneyDetails.setType(1);
        userMoneyDetails.setClassify(3);
        userMoneyDetails.setState(2);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        userMoneyDetails.setCreateTime(simpleDateFormat.format(new Date()));
        userMoneyDetailsService.save(userMoneyDetails);

        MyGlobalThreadPool.execute(() -> {
            try {
                String riderTemplate = commonInfoService.findOne(311).getValue();
                List<String> msgList = new ArrayList<>();
                msgList.add(indentNumber);
                msgList.add(tbIndent.getCreateTime());
                msgList.add("已完成");
                msgList.add(DateUtils.format(new Date()));
                UserEntity riderUser = userService.selectUserById(tbIndent.getRiderUserId());
                SenInfoCheckUtil.sendRiderMsg(riderUser.getRiderOpenId(), riderTemplate, msgList, 2);
            } catch (Exception e) {
                log.error("订单：{}，订单支付成功通知发送失败，失败原因：{}", e);
            }
        });
    }

    @Override
    public Result findAllIndent(String indentType, String phone, String indentState, Integer page, Integer limit, String date, String dateType, String riderPhone) {
        Page<TbIndent> pages = new Page<>(page, limit);
        PageUtils pageUtils = new PageUtils(baseMapper.findAllIndent(pages, indentType, phone, indentState, date, dateType, riderPhone));
        return Result.success().put("data", pageUtils);
    }

    @Override
    public Result findAllIndents(String indentType, String phone, String indentState, Integer page, Integer limit, String date, String dateType, String riderPhone) {
        Page<TbIndent> pages = new Page<>(page, limit);
        PageUtils pageUtils = new PageUtils(baseMapper.findAllIndents(pages, indentType, phone, indentState, date, dateType, riderPhone));
        return Result.success().put("data", pageUtils);
    }

    @Override
    public Result IndentCenter(Integer page, Integer limit, String indentType, String indentNumber, String indentState, String phone, String date, String dateType) {
        Page<TbIndent> pages = new Page<>(page, limit);
        PageUtils pageUtils = new PageUtils(baseMapper.IndentCenter(pages, indentType, indentNumber, indentState, phone, date, dateType));
        return Result.success().put("data", pageUtils);
    }

    @Override
    public Result updateIndentState(String indentNumber, String indentState) {
        baseMapper.updateIndentState(indentNumber, indentState);
        return Result.success();
    }

    @Override
    public Result adminSoldOutIndent(String indentNumber) {
        baseMapper.adminSoldOutIndent(indentNumber);
        return Result.success();
    }

    @Override
    public Result findDataCenter() {
        String format = new SimpleDateFormat("yyyy-MM-dd 00:00:00").format(new Date());
        HashMap dataCenter = new HashMap();
        //总用户数
        int allCount = tbIndentDao.findAllCount();
        //今日新增用户数
        int dayAddUser = tbIndentDao.findDayAddUser(new SimpleDateFormat("yyyy-MM-dd 00:00:00").format(new Date()));
        //本月新增用户数
        int monthAddUser = tbIndentDao.findMonthAddUser(new SimpleDateFormat("yyyy-MM-01 00:00:00").format(new Date()));
        //本年新增用户数
        int yearAddUser = tbIndentDao.findYearAddUser(new SimpleDateFormat("yyyy-01-01 00:00:00").format(new Date()));
        //今日收入
        BigDecimal dayIncome = tbIndentDao.findDayIncome(new SimpleDateFormat("yyyy-MM-dd 00:00:00").format(new Date()));
        //本月收入
        BigDecimal monthIncome = tbIndentDao.findMonthIncome(new SimpleDateFormat("yyyy-MM-01 00:00:00").format(new Date()));
        //本年收入
        BigDecimal yearIncome = tbIndentDao.findYearIncome(new SimpleDateFormat("yyyy-01-01 00:00:00").format(new Date()));
        //今日接单数量
        int indentCount = tbIndentDao.findIndentCount(new SimpleDateFormat("yyyy-MM-dd 00:00:00").format(new Date()));
        dataCenter.put("allCount", allCount);
        dataCenter.put("dayAddUser", dayAddUser);
        dataCenter.put("monthAddUser", monthAddUser);
        dataCenter.put("yearAddUser", yearAddUser);
        dataCenter.put("dayIncome", dayIncome);
        dataCenter.put("monthIncome", monthIncome);
        dataCenter.put("yearIncome", yearIncome);
        dataCenter.put("indentCount", indentCount);
        return Result.success().put("data", dataCenter);
    }

    @Override
    public Result taskAnalysis(DataCenterQuery oldQuery, String indentState) {
        DataCenterQuery query=DateUtils.dateStrEndTime(oldQuery);
        HashMap hashMap = new HashMap();
        //发单总金额
        BigDecimal billMoney = tbIndentDao.billMoney(query);
        //接单总金额
        BigDecimal receivingMoney = tbIndentDao.receivingMoney(query);
        //发单数量
        int billCount = tbIndentDao.billCount(query);
        //接单数量
        int reveivingCount = tbIndentDao.reveivingCount(query);
        //任务收入分析
        Page<TbIndent> pages = new Page<>(query.getPage(), query.getLimit());
        PageUtils taskAnalysisMoney = new PageUtils(baseMapper.taskAnalysisMoney(pages, query, indentState));
        hashMap.put("billMoney", billMoney);
        hashMap.put("receivingMoney", receivingMoney);
        hashMap.put("billCount", billCount);
        hashMap.put("reveivingCount", reveivingCount);
        hashMap.put("taskAnalysisMoney", taskAnalysisMoney);
        return Result.success().put("data", hashMap);
    }

    @Override
    public Result selectOrderByStatus(DataCenterQuery oldQuery) {
        HashMap hashMap = new HashMap();
        DataCenterQuery query=DateUtils.dateStrEndTime(oldQuery);
        //全部
        int i = tbIndentDao.selectOrderByStatus(query, null);
        // 付款
        int i1 = tbIndentDao.selectOrderByStatus(query, 2);
        // 接单
        int i2 = tbIndentDao.selectOrderByStatus(query, 3);
        // 进行中
        int i3 = tbIndentDao.selectOrderByStatus(query, 4);
        // 已完成
        int i4 = tbIndentDao.selectOrderByStatus(query, 6);
        //用户已取消
        int i5 = tbIndentDao.selectOrderByStatus(query, 8);
        //骑手已取消
        int i6 = tbIndentDao.selectOrderByStatus(query, 9);
        //平台取消
        int i7 = tbIndentDao.selectOrderByStatus(query, 10);
        hashMap.put("i", i);
        hashMap.put("i1", i1);
        hashMap.put("i2", i2);
        hashMap.put("i3", i3);
        hashMap.put("i4", i4);
        hashMap.put("i5", i5 + i6 + i7);
        return Result.success().put("data", hashMap);
    }

    @Override
    public List<TbIndent> findIndentsByIds(List<Long> ids) {
        QueryWrapper<TbIndent> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("indent_id",ids);
        List<TbIndent> result = baseMapper.selectList(queryWrapper);
        return result;
    }

    @Override
    public Result findIncome(Long userId, String date, String dateType, Integer page, Integer limit) {
        HashMap hashMap = new HashMap();
        //收益统计
        BigDecimal incomeday = tbIndentDao.findAdminIncomeday(userId, date, dateType);
        BigDecimal prepayMoney = tbIndentDao.findPrepayMoney(userId, date, dateType);
        BigDecimal subtract = incomeday.subtract(prepayMoney);
        //接单数量
        int indentCount = tbIndentDao.findAdminIndentCount(userId, date, dateType);
        //接单详情
        Page<TbIndent> pages = new Page<>(page, limit);
        PageUtils pageUtils = new PageUtils(tbIndentDao.selectIndentById(pages, userId, date, dateType));

        hashMap.put("incomeday", subtract);
        hashMap.put("indentCount", indentCount);
        hashMap.put("pageUtils", pageUtils);
        return Result.success().put("data", hashMap);
    }

    @Override
    public Result findUserIndent(Long userId, Integer page, Integer limit, String indentState) {
        Page<TbIndent> pages = new Page<>(page, limit);

        return Result.success().put("data", new PageUtils(tbIndentDao.findUserIndent(pages, userId, indentState)));
    }

    @Override
    public TbIndent userIndentMessage(String indentNumber) {

        return tbIndentDao.indentMessage(indentNumber);
    }

    @Override
    public Result find5KmRider(double lng, double lat) {
        List<UserEntity> kmRider = tbIndentDao.find5KmRider(lng, lat);
        return Result.success().put("data", kmRider);
    }

    @Override
    public Result updateCoordinate(Long userId, double lng, double lat) {
        tbIndentDao.updateCoordinate(userId, lng, lat);
        return Result.success();
    }

    @Override
    public UserEntity findUserInfoById(Long userId) {

        return tbIndentDao.findUserInfoById(userId);
    }

    @Transactional
    @Override
    public Result getNewUserRedPacket(Long userId) {
        //查看该用户是否是新用户
        UserEntity userInfoById = userDao.selectUserById(userId);
        if (1 == userInfoById.getNewUserFlag()) {
            ErrandRedPacket redPacket = new ErrandRedPacket();
            //如果是新用户，则可以领取新人红包
            //红包数额
            CommonInfo one = commonInfoService.findOne(297);
            BigDecimal redPacketAmount = new BigDecimal(one.getValue());
            //红包数量
            CommonInfo one1 = commonInfoService.findOne(298);
            Integer integer = Integer.valueOf(one1.getValue());
            //红包过期时间
            CommonInfo one2 = commonInfoService.findOne(299);
            Integer integer1 = Integer.valueOf(one2.getValue());

            Date date = new Date();
            Date addDate = addDate(integer1);
            String expirationTime = new SimpleDateFormat("yyyy-MM-dd").format(addDate);
            String createTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
            redPacket.setRedPacketType("0");
            redPacket.setRedPacketTitle("跑腿专用红包");
            redPacket.setMinimumAmount(new BigDecimal(0));
            for (int i = 0; i < integer; i++) {
                userDao.addRedPacket(userId, redPacket.getRedPacketType(), redPacket.getMinimumAmount(), redPacketAmount, redPacket.getRedPacketTitle(), expirationTime, createTime);
            }
            //修改用户为非新用户
            int i = userDao.updateOldUser(userId);
            return Result.success();
        }
        return Result.error("本福利仅新用户可领取！");
    }


    public static Date addDate(int num) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, num);
        Date date = calendar.getTime();
        return date;
    }

    @Override
    public List<ErrandRedPacket> findAllRedPacket(Long userId) {
        String expirationTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        return tbIndentDao.findAllRedPacket(userId, expirationTime);
    }

    @Override
    public List<ErrandRedPacket> findRedPacket(Long userId, TbIndent indent) {

        return tbIndentDao.findRedPacket(userId, indent.getIndentType(), indent.getIndentBasicsMoney(), new Date());
    }

    @Transactional
    @Override
    public Result userCancleIndent(Long userId, String indentNumber) {
        //返回订单对象
        TbIndent indent1 = tbIndentDao.indentMessage(indentNumber);
        if ("2".equals(indent1.getIndentState())) {
            //退款给用户余额
            PayDetails payDetails = payDetailsDao.selectByOrderId(indent1.getIndentNumber());
            if (payDetails.getType().equals(4)) {
                String code = AliPayController.alipayRefund(payDetails);
                if (StrUtil.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("退款失败！");
                }
            } else {
                boolean flag = wxService.wxRefund(payDetails);
                if (!flag) {
                    return Result.error("退款失败，请联系客服！");
                }
            }
        }
        int i = tbIndentDao.userCancleIndent(userId, indentNumber, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        //将红包修改为未使用状态
        if (indent1.getRedPacketId() != null) {
            tbIndentDao.updateRedPaclet(indent1.getRedPacketId());
        }
        if (indent1.getOrderId() != null) {
            TbOrder order = appOrderService.getById(indent1.getOrderId());

            MessageInfo messageInfo1 = new MessageInfo();
            messageInfo1.setTitle("用户取消订单");
            messageInfo1.setCreateAt(DateUtils.format(new Date()));
            messageInfo1.setContent("用户取消订单，订单号：" + order.getOrderNumber());
            messageInfo1.setShopId(order.getShopId());
            messageInfo1.setReadFlag(2);
            messageInfo1.setIsSee("1");
            messageService.save(messageInfo1);

            List<OrderGoods> orderGoodsList = orderGoodsDao.selectList(new QueryWrapper<OrderGoods>().eq("order_id", indent1.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", order.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().put("data", indent1);
    }

    /**
     * 转单后通知
     *
     * @param indent
     */
    @Override
    public void noticeAfterTransfer(TbIndent indent,queryRiderVo user) {
        CommonInfo one = commonInfoService.findOne(335);
        List<String> msgList = new ArrayList<>();
        msgList.add(0, indent.getIndentNumber());
        String indentState = indent.getIndentState();
        if ("3".equals(indentState)) {
            msgList.add(1, "已接单");
        } else if ("4".equals(indentState)) {
            msgList.add(1, "已取货");
        } else {
            msgList.add(1, "进行中");
        }
        msgList.add(2, "骑手已更换，新骑手将尽快为您送达");
        msgList.add(3, DateUtils.format(new Date()));
        if (StrUtil.isNotEmpty(user.getOpenId())) {
            MyGlobalThreadPool.execute(() -> {
                try {
                    SenInfoCheckUtil.sendMsg(user.getOpenId(), one.getValue(), msgList, 5);
                } catch (Exception e) {
                    log.error("订单：{}，转单成功通知发送失败，失败原因：{}", e);
                }
            });

        }

        if (StrUtil.isNotEmpty(user.getOpenId())) {
            MyGlobalThreadPool.execute(() -> {
                try {
                    userService.pushToSingle("更换骑手", "骑手已更换，新骑手将尽快为您送达", user.getClientid());
                } catch (Exception e) {
                    log.error("订单：{}，骑手已更换通知发送失败，失败原因：{}", e);
                }
            });

        }
    }

    /**
     * 转单后通知
     *
     * @param indent
     */
    private void noticeAfterTransfer(TbIndent indent) {
        CommonInfo one = commonInfoService.findOne(335);
        UserEntity user = userService.getById(indent.getUserId());
        List<String> msgList = new ArrayList<>();
        msgList.add(0, indent.getIndentNumber());
        String indentState = indent.getIndentState();
        if ("3".equals(indentState)) {
            msgList.add(1, "已接单");
        } else if ("4".equals(indentState)) {
            msgList.add(1, "已取货");
        } else {
            msgList.add(1, "进行中");
        }
        msgList.add(2, "骑手已更换，新骑手将尽快为您送达");
        msgList.add(3, DateUtils.format(new Date()));
        if (StrUtil.isNotEmpty(user.getOpenId())) {
            MyGlobalThreadPool.execute(() -> {
                try {
                    SenInfoCheckUtil.sendMsg(user.getOpenId(), one.getValue(), msgList, 5);
                } catch (Exception e) {
                    log.error("订单：{}，转单成功通知发送失败，失败原因：{}", e);
                }
            });

        }

        if (StrUtil.isNotEmpty(user.getOpenId())) {
            MyGlobalThreadPool.execute(() -> {
                try {
                    userService.pushToSingle("更换骑手", "骑手已更换，新骑手将尽快为您送达", user.getClientid());
                } catch (Exception e) {
                    log.error("订单：{}，骑手已更换通知发送失败，失败原因：{}", e);
                }
            });

        }
    }

    /**
     * 获取待转单配送单
     *
     * @param currentUserId    当前用户
     * @param transferOrderDTO
     * @return
     */
    private TbIndent getTransferOrder(Long currentUserId, RiderTransferOrderDTO transferOrderDTO) {
        // 开始转单
        TbIndent indent = getById(transferOrderDTO.getIndentId());
        if (ObjectUtil.isNull(indent)) {
            throw new SqxException("无效的配送单id");
        }

        if (!indent.getRiderUserId().equals(currentUserId)) {
            throw new SqxException("不能操作非自己的订单");
        }

        if (!"3".equals(indent.getIndentState()) && !"4".equals(indent.getIndentState())) {
            throw new SqxException("订单状态发生变更，请刷新后重试！");
        }

        return indent;
    }

    /**
     * 获取新骑手
     *
     * @param currentUserId    当前用户id
     * @param transferOrderDTO dto
     * @return 新骑手
     */
    private UserEntity getNewRicher(Long currentUserId, RiderTransferOrderDTO transferOrderDTO) {
        String phone = transferOrderDTO.getPhone();
        String realName = transferOrderDTO.getRealName();

        UserEntity userEntity = null;
        if (StrUtil.isNotBlank(phone)) {
            userEntity = userService.queryByPhone(phone);
        } else {
            List<UserEntity> userEntities = userService.queryByRealName(realName);
            if (userEntities.size() > 1) {
                throw new SqxException("根据姓名查到了多个骑手，请输入手机号码精确查询");
            }
            if (userEntities.size() == 1) {
                userEntity = userEntities.get(0);
            }
        }

        if (userEntity == null) {
            throw new SqxException("用户不存在");
        }

        if (currentUserId == userEntity.getUserId()) {
            throw new SqxException("不能转单给自己！");
        }

        // 校验当前骑手实名认证、保证金等信息
        CommonInfo one1 = commonInfoService.findOne(273);
        Double cashDeposit = Double.parseDouble(one1.getValue());
        if (!"1".equals(userEntity.getCheckCertification())) {
            throw new SqxException("骑手未进行实名认证！");
        }

        if (userEntity.getCashDeposit().doubleValue() < cashDeposit) {
            throw new SqxException("骑手保证金不足！");
        }

        //获取站点内容
        RiderStation station = riderStationService.stationById(userEntity.getRiderStationId());
        if(station != null){
            userEntity.setStationName(station.getStationName());
        }

        return userEntity;
    }

    /**
     * 获取新骑手
     *
     * @param riderUserId    被转单骑手id
     * @return 新骑手
     */
    @Override
    public queryRiderVo getNewRicherCheck(Long riderUserId) {
        queryRiderVo userEntity = userService.queryRider(riderUserId);

        if (userEntity == null) {
            throw new SqxException("用户不存在");
        }

        // 校验当前骑手实名认证、保证金等信息
        CommonInfo one1 = commonInfoService.findOne(273);
        Double cashDeposit = Double.parseDouble(one1.getValue());
        if (!"1".equals(userEntity.getCheckCertification())) {
            throw new SqxException("骑手未进行实名认证！");
        }

        if (userEntity.getCashDeposit().doubleValue() < cashDeposit) {
            throw new SqxException("骑手保证金不足！");
        }

        return userEntity;
    }

    @Override
    public PageUtils selectIndentPage(Integer page, Integer limit, String acquireCode, Long userId) {
        IPage<TbIndent> pages = new Page<>(page, limit);
        QueryWrapper<TbIndent> queryWrapper = new QueryWrapper();
        queryWrapper.eq("order_id", acquireCode);
        IPage<TbIndent> result = baseMapper.selectPage(pages, queryWrapper);
        return new PageUtils(result);
    }

    @Override
    public Result checkIndent(Long userId, String orderId) {
        try {
            //判断骑手状态是否被封号
            UserEntity userEntity1 = userService.selectUserById(userId);
            if (userEntity1.getStatus() != 1) {
                return Result.error("您的帐号已被封禁，请联系客服解封！");
            }
            //判断骑手保证金是否大于可接单金额
            UserEntity userMessage = userService.selectUserById(userId);
            String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
            CommonInfo one1 = commonInfoService.findOne(273);
            Double cashDeposit = Double.valueOf(one1.getValue());
            if (userMessage.getCashDeposit().compareTo(BigDecimal.valueOf(cashDeposit)) > 0 || userMessage.getCashDeposit().compareTo(BigDecimal.valueOf(cashDeposit)) == 0) {
                //  tbIndentDao.indentReceiving(userId, indentNumber, format);
                //判断骑手是否超过最大接单数量
                String maxNumStr = commonInfoService.findOne(342).getValue();
                Integer maxNum = Integer.parseInt(maxNumStr);
                int i = tbIndentDao.selectIndentByRiderUserCount(userId);
                if (i >= maxNum) {
                    return Result.error("您已达最大接单数量，请先完成订单后再进行接单");
                }
                TbIndent tbIndent = tbIndentDao.findIndentByOrderId(orderId);
                log.error("抢单：" + userId + "     " + tbIndent.getIndentState());
                if (!"2".equals(tbIndent.getIndentState()) && tbIndent.getOrderId().intValue() != Integer.valueOf(orderId).intValue()) {
                    return Result.error("订单已被抢走！");
                }
            } else {
                return Result.error("你的保证金不足，请缴纳保证金后再接单");
            }
            return Result.success();
        } catch (Exception e) {
            e.printStackTrace();
            log.error("骑手接单 异常：" + e.getMessage(), e);
        }
        return Result.error("系统繁忙，请稍后再试！");
    }
}





/*//小程序消息推送
            UserEntity userEntity = userService.selectUserById(indentByNumber.getUserId());
            UserEntity riderEntity = userService.selectUserById(userId);
            CommonInfo one = commonInfoService.findOne(268);
            List<String> msgList=new ArrayList<>();
            //服务项目
            String indentType="";
            if("1".equals(indentByNumber.getIndentType())){
                indentType = "帮我送";
            }else if("2".equals(indentByNumber.getIndentType())){
                indentType = "帮我取";
            }else if("3".equals(indentByNumber.getIndentType())){
                indentType = "同城帮买";
            }else if("4".equals(indentByNumber.getIndentType())){
                indentType = "同城服务";
            }
            msgList.add(0,indentType);
            //接单人员
            String nickName = userMessage.getNickName();
            msgList.add(1,nickName);
            //接单时间
            msgList.add(2,format);
            //备注
            String content="";
            if("1".equals(indentByNumber.getIndentType())||"2".equals(indentByNumber.getIndentType())){
                content = indentByNumber.getRemarks();
            }else if("3".equals(indentByNumber.getIndentType())){
                content = indentByNumber.getProductDetails();
            }else if("4".equals(indentByNumber.getIndentType())){
                content = indentByNumber.getServiceDetails();
            }
            if(content.length()>20){
                content=content.substring(0,15)+"...";
            }
            msgList.add(3,content);
            SenInfoCheckUtil.sendMsg(userEntity.getOpenId(),one.getValue(),msgList,1);
            SenInfoCheckUtil.sendMsg(riderEntity.getOpenId(),one.getValue(),msgList,1);
            //app端用户消息推送
            if(StringUtils.isNotEmpty(userEntity.getClientid())){
                String title = "";
                if("1".equals(indentByNumber.getIndentType())){
                    title = "帮我送";
                }else if("2".equals(indentByNumber.getIndentType())){
                    title = "帮我取";
                }else if("3".equals(indentByNumber.getIndentType())){
                    title = "同城帮买";
                }else if("4".equals(indentByNumber.getIndentType())){
                    title = "同城服务";
                }
                String contents = "亲爱的顾客，诚邀您为本次服务进行评价";
                userService.pushToSingle(title, contents, userEntity.getClientid());
            }
            //app端骑手消息推送
            if(StringUtils.isNotEmpty(riderEntity.getClientid())){
                String title = "";
                if("1".equals(indentByNumber.getIndentType())){
                    title = "帮我送";
                }else if("2".equals(indentByNumber.getIndentType())){
                    title = "帮我取";
                }else if("3".equals(indentByNumber.getIndentType())){
                    title = "同城帮买";
                }else if("4".equals(indentByNumber.getIndentType())){
                    title = "同城服务";
                }
                String contents = "订单已完成，服务费将在稍后返回到您的账户";
                userService.pushToSingle(title, contents, riderEntity.getClientid());
            }*/
