package com.younike.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.younike.common.config.AmqpDelayedConfig;
import com.younike.common.core.domain.AjaxResult;
import com.younike.common.core.domain.entity.SysUser;
import com.younike.common.core.redis.RedisCache;
import com.younike.common.exception.GlobalException;
import com.younike.common.exception.ServiceException;
import com.younike.common.utils.DateUtil;
import com.younike.common.utils.DateUtils;
import com.younike.common.utils.bean.BeanUtils;
import com.younike.common.utils.geo.DistanceUtil;
import com.younike.common.utils.id.GoodsIndexGenerate;
import com.younike.common.utils.id.IDUtils;
import com.younike.common.utils.id.RandomCodeGenerate;
import com.younike.common.utils.sms.AliSmsUtil;
import com.younike.common.utils.sms.AliTemplateCode;
import com.younike.hlpay.constant.PayType;
import com.younike.hlpay.dto.PaymentParam;
import com.younike.hlpay.dto.*;
import com.younike.hlpay.service.IPayService;
import com.younike.hlpay.util.Disguiser;
import com.younike.system.domain.*;
import com.younike.system.domain.vo.*;
import com.younike.system.enums.*;
import com.younike.system.mapper.*;
import com.younike.system.param.*;
import com.younike.system.service.*;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.time.*;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.BiFunction;
import java.util.stream.Collectors;

import static com.younike.common.constant.Constants.EXPIRE_TIME_MINUTES;
import static com.younike.common.constant.Constants.PREFIX_NO_PAY_ORDER;
import static com.younike.hlpay.constant.HeliPayContants.HLB_ADD_PAY_SUFFIX;
import static com.younike.hlpay.constant.HeliPayContants.HLB_MOD_PAY_SUFFIX;
import static java.math.BigDecimal.ROUND_HALF_UP;
import static java.math.BigDecimal.ZERO;

/**
 * 订单主Service业务层处理
 *
 * @author elev
 * @date 2022-01-07
 */
@Service
@Log4j2
public class OrderServiceImpl implements IOrderService {
    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private IOrderModifyService orderModifyService;

    @Autowired
    private OrderAddressMapper orderAddressMapper;

    @Autowired
    private SysConfigMapper sysConfigMapper;

    @Autowired
    private SysCodeMapper sysCodeMapper;

    @Autowired
    private SysDictDataMapper sysDictDataMapper;

    @Autowired
    private OrderRefundMapper orderRefundMapper;

    @Autowired
    private MerchantMapper merchantMapper;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private ServerTimeMapper serverTimeMapper;

    @Autowired
    private IServerTimeSectionService serverTimeSectionService;

    /**
     * 会员地址
     */
    @Autowired
    private MemberAddressMapper memberAddressMapper;

    /**
     * 商品数据
     */
    @Autowired
    private GoodsMapper goodsMapper;

    /**
     * 订单商品
     */
    @Autowired
    private OrderGoodsMapper orderGoodsMapper;

    @Autowired
    private MemberMapper memberMapper;

    @Autowired
    private IntegralRecordMapper integralRecordMapper;

    @Autowired
    private SysUserMapper sysUserMapper;


    /**
     * 服务人员
     */
    @Autowired
    private IServerUserService serverUserService;

    /**
     * 订单服务人员
     */
    @Autowired
    private IOrderGoodsServerService orderGoodsServerService;
    /**
     * 订单记录
     */
    @Autowired
    private IOrderRecordService orderRecordService;

    @Autowired
    private CategoryMapper categoryMapper;
    /**商家*/
    @Autowired
    private IMerchantService merchantService;

    @Autowired
    private CoinService coinService;
    @Autowired
    private ServerTimeSectionMapper serverTimeSectionMapper;
    @Autowired
    private IOrderRefundService orderRefundService;

    @Autowired
    private ISysCodeService sysCodeService;

    @Autowired
    private IServerTimeBookService serverTimeBookService;

    @Autowired
    private GoodsCommentMapper goodsCommentMapper;

    @Autowired
    private IMemberService memberService;
    @Autowired
    private OrderRecordMapper orderRecordMapper;

    @Autowired
    private GoodsImageMapper goodsImageMapper;

    @Value("${wechat.xcx.openidUrl}")
    private String xcxOpenIdUrl;

    @Value("${wechat.xcx.appid}")
    private String xcxAppId;

    @Value("${wechat.xcx.secret}")
    private String xcxAppSecret;

    @Autowired
    private IPayService payService;

    @Autowired
    private IOrderPaymentService orderPaymentService;

    @Autowired
    private IMerchantSettleInfoService merchantSettleInfoService;

    /**
     * 商家结算
     */
    @Autowired
    private IMerchantSettleInfoService settleInfoService;


    /**发布需求*/
    @Autowired
    private IPublishService publishService;

    /**需求报价*/
    @Autowired
    private IPublishQuoteService publishQuoteService;

    /**需求服务地址*/
    @Autowired
    private IPublishAddressService publishAddressService;

    /**需求资源*/
    @Autowired
    private IPublishImageService publishImageService;

    /**
     * 商品资源
     */
    @Autowired
    private IGoodsImageService goodsImageService;

    @Autowired
    private IGoodsServerService goodsServerService;

    @Autowired
    private AmqpTemplate rabbitTemplate;

    /**
     * 团购商品规格
     */
    @Autowired
    private IGoodsSpecificationService iGoodsSpecificationService;

    /**
     * 团购核销记录
     *
     * @param orderRefund
     * @return
     */
    @Autowired
    private IOrderVerificationRecordService orderVerificationRecordService;

    @Autowired
    private UjdChangeRecordMapper ujdChangeRecordMapper;

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private AliSmsUtil smsUtil;

    @Autowired
    private IAccessPasscodeService merchantAccessPasscodeService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult doRefund(OrderRefund orderRefund) {
        if (orderRefund == null || StringUtils.isEmpty(orderRefund.getStatus()) || StringUtils.isEmpty(orderRefund.getRefundResult())) {
            return AjaxResult.error("参数错误");
        }
        log.info("订单退款数据: " + JSONObject.toJSONString(orderRefund));
        OrderRefund oldRefund = orderRefundService.selectOrderRefundByOrderRefundId(orderRefund.getOrderRefundId());
        if (oldRefund == null) {
            return AjaxResult.error("退款数据不存在");
        }
        if (!OrderRefundStateEnum.PLATFORM_INTERVENTION.getCode().equals(oldRefund.getStatus())) {
            return AjaxResult.error("退款数据状态为已处理");
        }

        OrderRefund updateRefund = new OrderRefund();
        updateRefund.setOrderRefundId(orderRefund.getOrderRefundId());
        updateRefund.setStatus(orderRefund.getStatus());
//        updateRefund.setRefundReply(orderRefund.getRefundReply());
        updateRefund.setRefundResult(orderRefund.getRefundResult());
        updateRefund.setUpdateTime(LocalDateTime.now());
        // 根据订单退款信息查询订单信息
        Order order = orderMapper.selectOrderByOrderId(orderRefund.getOrderId());

        Order updateOrder = new Order();
        updateOrder.setOrderId(oldRefund.getOrderId());
        if (OrderRefundStateEnum.PLATFORM_REJECTS.getCode().equals(updateRefund.getStatus())) {
            // 平台驳回
            updateOrder.setOrderState(OrderStateEnum.REJECTED.getCode());
        } else if (OrderRefundStateEnum.PLATFORM_REFUNDS.getCode().equals(updateRefund.getStatus())) {
            // 平台同意  orderRefund里的refundMoney 为实际退款金额
            updateRefund.setRefundMoney(orderRefund.getRefundMoney());
            // 更新订单状态为已退款 回调时更新
//            updateOrder.setOrderState(OrderStateEnum.REFUNDED.getCode());
            if (order == null) {
                return AjaxResult.error("未查询到退款订单数据!");
            }
            // 暂时不支持部分退款，所以将orderRefund里的refundMoney改成payMoney
            if (updateRefund.getRefundMoney() == null) {
                return AjaxResult.error("退款金额不能为空!");
            }
            if (new BigDecimal("0.01").compareTo(updateRefund.getRefundMoney()) > 0) {
                return AjaxResult.error("退款金额不能小余0.01!");
            }
            if (updateRefund.getRefundMoney().compareTo(order.getTotalAmount()) > 0) {
                return AjaxResult.error("退款金额不能大于实付金额!");
            }
        } else if (OrderRefundStateEnum.MERCHANT_REFUNDS.getCode().equals(updateRefund.getStatus())) {
            // 商家同意  orderRefund里的refundMoney 为实际退款金额
            updateRefund.setRefundMoney(orderRefund.getRefundMoney());
            // 更新订单状态为已退款 回调时更新
//            updateOrder.setOrderState(OrderStateEnum.REFUNDED.getCode());
            if (order == null) {
                return AjaxResult.error("未查询到退款订单数据!");
            }
            // 校验退款金额
            if (updateRefund.getRefundMoney() == null) {
                return AjaxResult.error("退款金额不能为空!");
            }
            if (new BigDecimal("0.01").compareTo(updateRefund.getRefundMoney()) > 0) {
                return AjaxResult.error("退款金额不能小余0.01!");
            }
            if (updateRefund.getRefundMoney().compareTo(order.getTotalAmount()) > 0) {
                return AjaxResult.error("退款金额不能大于实付金额!");
            }
        } else {
            return AjaxResult.error("数据异常");
        }
        try {
            // 退款被驳回时，更新订单及订单退款信息
            if (OrderRefundStateEnum.PLATFORM_REJECTS.getCode().equals(updateRefund.getStatus())) {
                // 更新订单状态为已拒绝退款
                this.updateOrder(updateOrder);
                // 更新订单退款信息
                orderRefundService.updateOrderRefund(updateRefund);
                // 保存订单追踪记录数据
                log.warn("...申请退款被平台拒绝--开始保存订单追踪记录...");
                OrderRecord record = new OrderRecord();
                record.setPreState(OrderStateEnum.PENDING_REFUNDED.getCode());
                record.setOrderId(order.getOrderId());
                record.setNowState(OrderStateEnum.REJECTED.getCode());
                record.setOperateInfo("平台已拒绝退款");
                if (orderRecordService.insertOrderRecord(record) < 1) {
                    log.error("申请退款被平台拒绝--添加订单追踪信息失败");
                    throw new ServiceException("添加订单追踪信息失败");
                }
                log.warn("...申请退款被平台拒绝--保存订单追踪记录结束...");
            }
            // 同意退款时，更新订单退款信息
            if (OrderRefundStateEnum.MERCHANT_REFUNDS.getCode().equals(updateRefund.getStatus())
                    || OrderRefundStateEnum.PLATFORM_REFUNDS.getCode().equals(updateRefund.getStatus())) {
                // 更新订单退款信息
                orderRefundService.updateOrderRefund(updateRefund);
//                //更新退款状态为处理中
//                oldRefund.setStatus("005");
//                orderRefundService.updateOrderRefund(oldRefund);
            }
        } catch (Exception e) {
            log.error("更新订单及订单退款信息发生错误: " + e.getMessage());
            e.printStackTrace();
            throw new ServiceException("更新订单及订单退款信息发生错误!");
        }

        // 同意退款，处理外部退款逻辑(订单及订单退款信息等在退款成功回调方法里去更新)
        if (OrderRefundStateEnum.MERCHANT_REFUNDS.getCode().equals(updateRefund.getStatus())
                || OrderRefundStateEnum.PLATFORM_REFUNDS.getCode().equals(updateRefund.getStatus())) {
            log.warn("...订单退款业务开始...");
//            Member member = memberService.selectMemberByMemberId(order.getMemberId());
//            Merchant merchant = merchantService.selectMerchantByMerchantId(order.getMerchantId());
            MerchantSettleInfo merchantSettleInfo = merchantSettleInfoService.selectMerchantSettleInfoByMerchantId(order.getMerchantId());
//            if (member == null) {
//                throw new GlobalException("获取下单用户信息失败");
//            }
//            if (merchant == null) {
//                throw new GlobalException("获取商家信息失败");
//            }
            // TODO 2022.4.19 商户邮箱暂时使用优鲜信的(其他商家未开通合利宝账号)
            if (merchantSettleInfo == null || StringUtils.isEmpty(merchantSettleInfo.getEmail())) {
                throw new GlobalException("获取商户邮箱失败");
            }

            // 退优金豆
//            FamilyParam familyParam = new FamilyParam();
//            // 设置 关联id
//            familyParam.setTargetId(order.getOrderId().toString());
//            // 设置 积分变动类型（001-消费 002-退款 003-抵扣 004-评价订单新增）
//            familyParam.setCode("002");
//            familyParam.setPhone(member.getPhone());
//            // 设置 备注（商家名称）
//            familyParam.setOperation(merchant.getMerchantName());
//            // 恢复扣除的积分数量
//            familyParam.setNum(new BigDecimal(order.getBeanAmount()));
//
//            String integralId = coinService.increasePoints(familyParam);
//            if (StringUtils.isBlank(integralId)) {
//                throw new GlobalException("退回优金豆失败");
//            }
            // 查询订单是否修改过
            OrderModify orderModify = orderModifyService.getLatestRecord(order.getOrderId());
            String orderId = String.valueOf(order.getOrderId());
            if (orderModify != null && orderModify.getModifyIndex() != null) {
                orderId = orderId + HLB_MOD_PAY_SUFFIX + orderModify.getModifyIndex();
            }
            // 总支付金额
            BigDecimal totalAmount = order.getTotalAmount();
            // 实际需要退款金额
            BigDecimal actualRefundMoney = updateRefund.getRefundMoney();
            // 订单可退金额
            BigDecimal orderRefundMoney = BigDecimal.ZERO;
            // 追加可退金额
            BigDecimal addRefundMoney = BigDecimal.ZERO;
            // 原订单支付金额
            BigDecimal originOrderPayMoney = BigDecimal.ZERO;
            // 计算可退金额
            if (order.getAddAmount() != null && order.getAddPayStatus() == 1) {
                orderRefundMoney = totalAmount.subtract(order.getAddAmount());
                originOrderPayMoney = orderRefundMoney;
            } else {
                orderRefundMoney = totalAmount;
                originOrderPayMoney = orderRefundMoney;
            }
            // 实际退款金额大于订单金额
            if (actualRefundMoney.compareTo(orderRefundMoney) > 0) {
                addRefundMoney = actualRefundMoney.subtract(orderRefundMoney);
            }
            // 实际退款金额小于或等于订单金额
            if (actualRefundMoney.compareTo(orderRefundMoney) <= 0) {
                orderRefundMoney = actualRefundMoney;
            }
            log.warn("订单退款金额orderRefundMoney=" + orderRefundMoney);
            if (orderRefundMoney.compareTo(BigDecimal.ZERO) > 0) {
                // 是否分账
                boolean isSplitBill = originOrderPayMoney.compareTo(BigDecimal.ZERO) > 0 &&
                        order.getShopAmount().compareTo(originOrderPayMoney) != 0;
                // 退回第一次下单实际支付金额 TODO 商家邮箱待定（是否使用优鲜信邮箱） order.getOrderAmount() 是否表示实际支付金额 待确认
                payService.orderRefund(orderId, merchantSettleInfo.getEmail(), orderRefundMoney , order.getShopAmount(), order.getPayWay(), isSplitBill);
            }
            log.warn("追加退款金额addRefundMoney=" + addRefundMoney);
            // 退回追加支付金额
            if (addRefundMoney.compareTo(BigDecimal.ZERO) > 0) {
                // 查询订单商品信息
//                OrderGoods orderGoods = orderGoodsMapper.selectOrderGoodsByOrderId(order.getOrderId());
                // 查询订单支付信息
                OrderPayment orderPayment = orderPaymentService.selectOrderPaymentByOrderId(order.getOrderId());
                String addOrderId = String.valueOf(order.getOrderId());
//                // 家政追加服务支付
//                if (orderGoods != null && orderGoods.getAddCounts() != null && "001".equals(order.getOrderType())) {
//                    addOrderId = addOrderId + HLB_ADD_PAY_SUFFIX + orderGoods.getAddCounts();
//                }
                // 维修追加服务支付
                if (orderPayment != null && orderPayment.getAddCountIndex() != null) {
                    addOrderId = addOrderId + HLB_ADD_PAY_SUFFIX + orderPayment.getAddCountIndex();
                }
                log.warn("...退回追加金额--业务开始...");
                // 是否分账
                boolean isSplitBill = order.getAddAmount().compareTo(order.getAddShopAmount()) != 0;
                // 计算出来的数值如果过小，可能会为0
                BigDecimal addShopAmount = (addRefundMoney.divide(order.getAddAmount(), 6, ROUND_HALF_UP).multiply(order.getAddShopAmount())).setScale(2, ROUND_HALF_UP);
                // 退回追加支付金额
                payService.orderRefund(addOrderId, merchantSettleInfo.getEmail(), addRefundMoney, addShopAmount, order.getAddPayWay(), isSplitBill);
                log.warn("...退回追加金额--业务结束...");
            }
            log.warn("...订单退款业务结束...");
        }
        return AjaxResult.success();
    }

    @Override
    public List<OrderVo> orderList(OrderQueryParam param) {


        List<OrderVo> orderVoList = orderMapper.orderList(param);
        if (CollectionUtils.isEmpty(orderVoList)) {
            return orderVoList;
        }

        for (OrderVo orderVo : orderVoList) {
            if ("1".equals(orderVo.getMerchantType())) {
                // 个人商家 查询用户名
                SysUser sysUser = sysUserMapper.selectSysUserById(orderVo.getAdminId());
                if (sysUser != null) {
                    orderVo.setMerchantNameJoin(sysUser.getNickName());
                }
            }
            if("003".equals(param.getOrderType())) {
                // 次数
                if (orderVo.getGroupTimes() != null && orderVo.getGroupRemainingTimes() != null) {
                    orderVo.setTimes(orderVo.getGroupRemainingTimes() + "/" + orderVo.getGroupTimes());
                }
            }
        }
        return orderVoList;
    }

    /**
     * 查询订单主
     *
     * @param orderId 订单主主键
     * @return 订单主
     */
    @Override
    public Order selectOrderByOrderId(Long orderId) {
        Order order = orderMapper.selectOrderByOrderId(orderId);
        if (Objects.isNull(order)){
            throw new ServiceException("订单不存在或已被删除");
        }
        return order;
    }

    /**
     * 查询订单主列表
     *
     * @param order 订单主
     * @return 订单主
     */
    @Override
    public List<Order> selectOrderList(Order order) {
        return orderMapper.selectOrderList(order);
    }

    /**
     * 新增订单主
     *
     * @param order 订单主
     * @return 结果
     */
    @Override
    public int insertOrder(Order order) {
        order.setCreateTime(LocalDateTime.now());
        return orderMapper.insertOrder(order);
    }

    /**
     * 修改订单主
     *
     * @param order 订单主
     * @return 结果
     */
    @Override
    public int updateOrder(Order order) {
        order.setUpdateTime(LocalDateTime.now());
        return orderMapper.updateOrder(order);
    }


    /**
     * 批量删除订单主
     *
     * @param orderIds 需要删除的订单主主键
     * @return 结果
     */
    @Override
    public int deleteOrderByOrderIds(Long[] orderIds) {
        return orderMapper.deleteOrderByOrderIds(orderIds);
    }

    /**
     * 删除订单主信息
     *
     * @param orderId 订单主主键
     * @return 结果
     */
    @Override
    public int deleteOrderByOrderId(Long orderId) {
        return orderMapper.deleteOrderByOrderId(orderId);
    }

    /**
     * 修改订单主
     *
     * @param order 订单主
     * @return 结果
     */
    @Override
    public int updateOrderCustom(Order order) {
        // todo 如果是待服务   1.需要获取当前经纬度存下来
        // todo              2.判断距离客户地址是否200米范围内 ，若在范围内才允许更改状态
        //配送范围
//        BigDecimal maxDeliverDistance = BigDecimal.valueOf(merchant.getServiceDistance());

        //根据订单id查订单数据
        Order order1 = orderMapper.selectOrderId(order.getOrderId());
        if(ObjectUtils.isEmpty(order1)){
            return 996;
        }

        OrderRecord orderRecord = new OrderRecord();
        if("002".equals(order.getOrderState())){
            if(!"001".equals(order1.getOrderState())){
                return 997;
            }
            orderRecord.setPreState("001");
            boolean isSameDay = false;
            if(!ObjectUtils.isEmpty(order.getAppointmentStartTime())){
                //今天和服务时间是否为同一天
                isSameDay = DateUtils.isSameDay(Date.from( order.getAppointmentStartTime().atZone( ZoneId.systemDefault()).toInstant()),new Date());
            }
            if(!isSameDay){
                //今天和服务时间不为同一天
                return 998;
            }

            order.setServiceStartTime(new Date());
            BigDecimal maxDeliverDistance = new BigDecimal(sysConfigMapper.checkConfigKeyUnique("home.server.maxDistance").getConfigValue());
            //商家与会员距离
            BigDecimal shortestDistance = null;
            OrderAddress orderAddress = orderAddressMapper.selectOrderAddressByOrderId(order.getOrderId());
            // 计算距离
            shortestDistance = DistanceUtil.getShortestDistance(order.getServiceLatitude(),
                    order.getServiceLongitude(), orderAddress.getAddressLatitude(), orderAddress.getAddressLongitude());

            //验证坐标是否超出范围
            if(shortestDistance.compareTo(maxDeliverDistance)>0){
                //超出配送范围
                return 999;
            }
        }
        if("003".equals(order.getOrderState())){
            if(!"002".equals(order1.getOrderState())){
                return 997;
            }
            order.setServiceEndTime(new Date());
            orderRecord.setPreState("002");
        }

        //根据订单id查询最近一条订单记录数据
        orderRecord.setOrderId(order.getOrderId());
        orderRecord.setNowState(order.getOrderState());
        orderRecord.setOperateInfo(sysCodeService.getDecodeValue("003",order.getOrderState()));
        if(orderRecordService.insertOrderRecord(orderRecord)<1){
            throw new ArithmeticException("添加订单追踪信息失败");
        }

        order.setUpdateTime(LocalDateTime.now());
//        order.setUpdateBy(getUsername());
        int updateOrderCustom = orderMapper.updateOrderCustom(order);

        // 服务开始发送短信通知
        if (OrderStateEnum.IN_SERVICE.getCode().equals(order.getOrderState())) {
            try {
                // 查询订单商品信息
                OrderGoods orderGoods = orderGoodsMapper.selectOrderGoodsByOrderId(order.getOrderId());
                if (ObjectUtils.isEmpty(orderGoods))  {
                    log.error("服务开始发送短信通知--未查询到订单商品信息，订单编号orderIndex=" + order1.getOrderIndex());
                } else {
                    // 查询服务人员信息
                    ServerUserListVo serverUser = serverUserService.getByServerId(orderGoods.getServerId());
                    // 查询订单商家信息
                    Merchant merchant = merchantService.getMerchantByMerchantId(order1.getMerchantId());
                    // 查询订单顾客信息
                    Member member = memberService.selectMemberByMemberId(order1.getMemberId());

                    // 服务开始短信通知顾客
                    if (serverUser != null && StringUtils.isNotBlank(serverUser.getPhone())) {
                        if (member != null && StringUtils.isNotBlank(member.getPhone())) {
                            JSONObject param = new JSONObject();
                            param.put("orderindex", order1.getOrderIndex());
                            param.put("staff", serverUser.getNikeName());
                            param.put("phone", serverUser.getPhone());
                            log.warn("服务开始短信通知顾客--短信发送参数:" + JSONObject.toJSONString(param));
                            log.warn("服务开始短信通知顾客--短信接收手机号:" + member.getPhone());
                            SendSmsResponse sendSmsResponse = smsUtil.sendSms(member.getPhone(), param, AliTemplateCode.ORDER_SERVICE_START_NOTIFY_MEMBER_CODE);
                            log.warn("服务开始短信通知顾客--短信返回结果:" + JSONObject.toJSONString(sendSmsResponse));
                        } else {
                            log.error("服务开始短信通知顾客--未查询到顾客信息!顾客ID=" + order1.getMemberId());
                        }
                    } else {
                        log.error("服务开始短信通知顾客--未查询到商家服务人员信息!服务人员ID=" + orderGoods.getServerId());
                    }
                    // 服务开始短信通知商家
                    if (merchant != null && StringUtils.isNotBlank(merchant.getMerchantPhone())) {
                        if (member != null && StringUtils.isNotBlank(member.getPhone())) {
                            JSONObject param = new JSONObject();
                            param.put("orderindex", order1.getOrderIndex());
                            param.put("phone", member.getPhone());
                            param.put("startTime", DateUtil.formatDate(DateUtil.localDateTimeToDate(order1.getAppointmentStartTime()), "yyyy-MM-dd HH:mm"));
                            param.put("endTime", DateUtil.formatDate(DateUtil.localDateTimeToDate(order1.getAppointmentEndTime()), "yyyy-MM-dd HH:mm"));
                            if (serverUser != null && StringUtils.isNotBlank(serverUser.getNikeName())) {
                                param.put("staff", serverUser.getNikeName());
                            } else {
                                log.error("服务开始短信通知商家--未查询到服务人员信息!服务人员ID=" + orderGoods.getServerId());
                            }
                            log.warn("服务开始短信通知商家--短信发送参数:" + JSONObject.toJSONString(param));
                            log.warn("服务开始短信通知商家--短信接收手机号:" + merchant.getMerchantPhone());
                            SendSmsResponse sendSmsResponse = smsUtil.sendSms(merchant.getMerchantPhone(), param, AliTemplateCode.ORDER_SERVICE_START_NOTIFY_MERCHANT_CODE);
                            log.warn("服务开始短信通知商家--短信返回结果:" + JSONObject.toJSONString(sendSmsResponse));
                        } else {
                            log.error("服务开始短信通知商家--未查询到顾客信息!顾客ID=" + order1.getMemberId());
                        }
                    } else {
                        log.error("服务开始短信通知商家--未查询到商家信息!商家ID=" + order1.getMerchantId());
                    }
                }
            } catch (Exception e) {
                log.error("服务开始--短信通知发送失败!错误信息error=" + e.getMessage());
            }
        }
        // 服务结束发送短信通知
        if (OrderStateEnum.PENDING_CONFIRMED.getCode().equals(order.getOrderState())) {
            try {
                // 查询订单顾客信息
                Member member = memberService.selectMemberByMemberId(order1.getMemberId());
                // 服务结束短信通知顾客
                if (member != null && StringUtils.isNotBlank(member.getPhone())) {
                    JSONObject param = new JSONObject();
                    param.put("orderindex", order1.getOrderIndex());
                    log.warn("服务结束短信通知顾客--短信发送参数:" + JSONObject.toJSONString(param));
                    log.warn("服务结束短信通知顾客--短信接收手机号:" + member.getPhone());
                    SendSmsResponse sendSmsResponse = smsUtil.sendSms(member.getPhone(), param, AliTemplateCode.ORDER_SERVICE_END_NOTIFY_MEMBER_CODE);
                    log.warn("服务结束短信通知顾客--短信返回结果:" + JSONObject.toJSONString(sendSmsResponse));
                } else {
                    log.error("服务结束短信通知顾客--未查询到顾客信息!顾客ID=" + order1.getMemberId());
                }

                // 查询订单商家信息
                Merchant merchant = merchantService.getMerchantByMerchantId(order1.getMerchantId());
                // 服务结束短信通知商家
                if (merchant != null && StringUtils.isNotBlank(merchant.getMerchantPhone())) {
                    JSONObject param = new JSONObject();
                    param.put("orderindex", order1.getOrderIndex());
                    log.warn("服务结束短信通知商家--短信发送参数:" + JSONObject.toJSONString(param));
                    log.warn("服务结束短信通知商家--短信接收手机号:" + merchant.getMerchantPhone());
                    SendSmsResponse sendSmsResponse = smsUtil.sendSms(merchant.getMerchantPhone(), param, AliTemplateCode.ORDER_SERVICE_END_NOTIFY_MERCHANT_CODE);
                    log.warn("服务结束短信通知商家--短信返回结果:" + JSONObject.toJSONString(sendSmsResponse));
                } else {
                    log.error("服务结束短信通知商家--未查询到商家信息!商家ID=" + order1.getMerchantId());
                }
            } catch (Exception e) {
                log.error("服务结束--短信通知发送失败!错误信息error=" + e.getMessage());
            }
        }

        return updateOrderCustom;
    }

    /**
     * 查询近days天的特定订单状态（orderStates）订单列表
     *
     * @param days 天数
     * @param orderStates 订单状态
     * @return 订单列表
     */
    @Override
    public List<OrderStat> listLastOrders(int days, String[] orderStates) {
        return orderMapper.listLastOrders(days, StringUtils.join(orderStates, ","));
    }

    @Override
    public List<GoodsServerDimension> statisticGoodsServerDimension(int days, String[] orderStates) {
        return orderMapper.statisticGoodsServerDimension(days, StringUtils.join(orderStates, ","));
    }

    /**
     * 查询会员端订单分页列表
     *
     * @param order
     * @return
     */
    @Override
    public List<MemberOrderVo> listMemberOrderByOrderState(Order order) {
        String[] orderStateArr = new String[]{};
        if (StringUtils.isNotEmpty(order.getOrderState())) {
            orderStateArr = order.getOrderState().split(",");
        }

        // 查询会员订单列表
        List<MemberOrderVo> memberOrderVoList = orderMapper.listMemberOrderByOrderState(order, Arrays.asList(orderStateArr));
        if (StringUtils.isNotEmpty(order.getOrderState()) && Objects.equals("004", order.getOrderState())) {
            // 筛选出待评价订单
            memberOrderVoList = memberOrderVoList.stream()
                    .filter(vo -> Objects.equals("001", vo.getCommentState())).collect(Collectors.toList());
        }
        // 查询订单状态等字典值
        if (CollectionUtils.isNotEmpty(memberOrderVoList)) {
            for (MemberOrderVo vo : memberOrderVoList) {
                // 是否追评(默认为0-否)
                vo.setIsAddComment("0");
                // 获取订单状态名称
                vo.setOrderStateName(OrderStateEnum.getDescription(vo.getOrderState()));
                // 获取家政等级名称
                vo.setServerLevelName(ServerLevelEnum.getDescription(vo.getServerLevel()));
                // 处理其他商品单位名称
                if (Objects.equals(vo.getGoodsUnit(), "999")) {
                    vo.setGoodsUnitName(vo.getOtherUnit());
                }
//                } else {
//                    String goodsUnitName = sysDictDataMapper.selectDictLabel("goods_unit", vo.getGoodsUnit());
//                    vo.setGoodsUnitName(goodsUnitName);
//                }
                // 查询评价id
                if (Objects.equals(vo.getCommentState(), "002")) {
                    GoodsComment goodsComment = goodsCommentMapper.getByOrderId(vo.getOrderId());
                    if (goodsComment != null) {
                        vo.setCommentId(goodsComment.getCommontId());
                        vo.setIsAddComment(StringUtils.isBlank(goodsComment.getReContent()) ? "0" : "1");
                    }
                }
                // 查询商品图片列表
                List<GoodsImage> goodsImageList = goodsImageMapper.goodsImageList(Arrays.asList(vo.getGoodsId()));
                vo.setGoodsImageList(goodsImageList);
                // 查询商家类型
                Merchant merchant = merchantService.selectMerchantByMerchantId(vo.getMerchantId());
                vo.setMerchantType(merchant == null ? null : merchant.getMerchantType());
                if(!ObjectUtils.isEmpty(merchant) && merchant.getMerchantType()==1){
                    //查询个人商家的数据
                    SysUser sysUser = sysUserService.selectSysUserById(merchant.getAdminId());
                    if(!ObjectUtils.isEmpty(sysUser)){
                        vo.setMerchantName(sysUser.getNickName());
                    }
                }
                // 查询评价可得优金豆数量
                Goods goods = goodsMapper.selectGoodsByGoodsId(vo.getGoodsId());
                vo.setCoin(goods == null ? ZERO : goods.getCoin());
            }
        }
        return memberOrderVoList;
    }

    /**
     * 根据订单金额和追加服务金额计算店铺可得
     *
     * @param order
     */
    @Override
    public void calculateShopAmount(Order order) {
        BigDecimal totalAmount = order.getTotalAmount();
        if (Objects.isNull(totalAmount)) {
            throw new ServiceException("订单金额不能为空");
        }
        if (Objects.isNull(order.getMerchantId())) {
            throw new ServiceException("订单所属商户不能为空");
        }
        Merchant merchant = merchantMapper.selectMerchantByMerchantId(order.getMerchantId());
        BigDecimal platformPercent = new BigDecimal(Optional.ofNullable(
                sysConfigMapper.checkConfigKeyUnique("platform.commission.rate").getConfigValue()).orElse("0"));
        BigDecimal recommenderPercent = Objects.isNull(merchant.getAgentId()) ? ZERO : new BigDecimal(Optional.ofNullable(
                sysConfigMapper.checkConfigKeyUnique("recommender.commission.rate").getConfigValue()).orElse("0"));
        BiFunction<BigDecimal, BigDecimal, BigDecimal> divideBy = (amount, percent) ->
                amount.multiply(percent).divide(new BigDecimal(100), 2, ROUND_HALF_UP);

        // 1. 计算总金额的分成费用
        BigDecimal platformAmount = divideBy.apply(totalAmount, platformPercent);
        BigDecimal recommenderAmount = divideBy.apply(totalAmount, recommenderPercent);
        BigDecimal shopAmount = totalAmount.subtract(platformAmount).subtract(recommenderAmount);
        log.warn("下单-店铺可得金额:" + shopAmount);
        order.setShopAmount(shopAmount);
        order.setRecommenderAmount(recommenderAmount);
        // 2. 计算追加服务的分成费用
        BigDecimal addAmount = order.getAddAmount();
        if (Objects.isNull(addAmount)) {
            addAmount = Objects.isNull(order.getMaintenanceAmount()) ? ZERO : order.getMaintenanceAmount();
        }
        BigDecimal addPlatformAmount = divideBy.apply(addAmount, platformPercent);
        BigDecimal addRecommenderAmount = divideBy.apply(addAmount, recommenderPercent);
        BigDecimal addShopAmount = addAmount.subtract(addPlatformAmount).subtract(addRecommenderAmount);
        order.setAddShopAmount(addShopAmount);
        order.setAddRecommenderAmount(addRecommenderAmount);
    }

    /**
     * 会员下单
     *
     * @param param
     * @return
     */
    @Override
    @Transactional
    public AjaxResult addOrder(OrderParam param) {

        Merchant merchant = merchantService.selectMerchantByMerchantId(param.getMerchantId());
        if (ObjectUtils.isEmpty(merchant)) {
            //抛出异常
            throw new ArithmeticException("商家不存在");
        }
        // 使用优金豆抵扣
        if (param.getGoodsCoin() != null) {
            if(param.getGoodsCoin() > 500){
                throw new ArithmeticException("优金豆使用不得超过500");
            }

            // 如果使用优金豆，调用远程接口减少用户优金豆数量
            if (param.getGoodsCoin() > 0) {
                FamilyParam familyParam = new FamilyParam();
                familyParam.setNum(BigDecimal.valueOf(-param.getGoodsCoin()));
                familyParam.setPhone(param.getPhone());
                String jsonCode = coinService.increasePoints(familyParam);
                if (!jsonCode.equals("200")) {
                    throw new ArithmeticException("预约失败，优金豆扣除失败");
                }
            }
        }

        BigDecimal multiply = new BigDecimal(param.getGoodsCounts()).multiply(param.getSingleTime());
        LocalDateTime appointmentEndTime = recordAppointmentInfo(param.getAppointmentStartTime(), multiply, param.getServerId(), merchant.getAllowCompose());

        //创建订单对象
        Order order = new Order();
        BeanUtils.copyProperties(param, order);
        // 生成订单id
        Long orderId = IDUtils.nextLongId();
        order.setOrderId(orderId);
        // 生成订单编号
        order.setOrderIndex(redisCache.getOrderIndexByRedis());
        order.setBeanAmount(Integer.valueOf(String.valueOf(param.getGoodsCoin())));
        param.setAppointmentEndTime(appointmentEndTime);

        order.setCreateTime(LocalDateTime.now());
        order.setUpdateTime(LocalDateTime.now());
        order.setOrderState(OrderStateEnum.PENDING_PAYMENT.getCode());
        order.setCommentState(CommentStateEnum.PENDING_COMMENT.getCode());

        // 使用优惠券
        if (param.getMemberCouponId() != null) {
            // 若使用了优惠券，则处理优惠券对应逻辑(暂时无优惠券使用逻辑)
            order.setCouponAmount(param.getCouponAmount());
        }
        // 平台抽成百分比
        BigDecimal percentage = new BigDecimal(sysConfigMapper.checkConfigKeyUnique("platform.commission.rate").getConfigValue());
        // 商家可得到 实付总价减去平台抽成
        BigDecimal shopAmount = param.getTotalAmount()
                .subtract(
                        param.getTotalAmount().multiply(percentage)
                                .divide(new BigDecimal(100),2, ROUND_HALF_UP));
        // 判断优金豆抵扣金额(使用优金豆的抵扣金额已经加到商家保证金里，此处不再重复计算店铺可得2022.04.02)
//        if (order.getBeanAmount() != null) {
//            shopAmount.add(new BigDecimal(order.getBeanAmount()).divide(new BigDecimal(100)));
//            order.setCouponAmount(new BigDecimal(order.getBeanAmount()).divide(new BigDecimal(100)));
//        }
        order.setShopAmount(shopAmount);
        log.warn("预约下单-店铺可得金额:" + shopAmount);

        order.setMerchantName(merchant.getMerchantName());
        order.setAppointmentEndTime(appointmentEndTime);
        if (orderMapper.addOrder(order) < 1) {
            throw new ArithmeticException("添加订单失败");
        }
//        //生成订单编号
//        String index = OrderIndexGenerate.getIndexByOrderId(order.getOrderId());
//        //更新数据
//        order.setOrderIndex(index);
//        order.setUpdateTime(LocalDateTime.now());
//        if (orderMapper.updateOrderCustom(order) < 1) {
//            throw new ArithmeticException("更新订单编号失败");
//        }

        //order表添加数据
        //order_address 订单地址添加
        //根据地址id查询地址数据
        MemberAddress memberAddress = memberAddressMapper.selectMemberAddressByAddressId(param.getAddressId());
        if (ObjectUtils.isEmpty(memberAddress)) {
            //抛出异常
            throw new ArithmeticException("没有此会员地址");
        }

        //商家与会员距离
        BigDecimal shortestDistance = null;
        // 计算距离
        shortestDistance = DistanceUtil.getShortestDistance( merchant.getLatitude(), merchant.getLongitude(),memberAddress.getLatitude(),
                memberAddress.getLongitude());

        BigDecimal maxDeliverDistance =null;
        if(merchant.getServiceDistance()==null){
            maxDeliverDistance = new BigDecimal(sysConfigMapper.checkConfigKeyUnique("home.server.distance").getConfigValue());

        }else {
            maxDeliverDistance  = new BigDecimal(String.valueOf(merchant.getServiceDistance()));
        }

        //验证坐标是否超出范围
        if(shortestDistance.compareTo(maxDeliverDistance)>0){
            //超出配送范围
            throw new ArithmeticException("下单失败订单地址超出服务范围");
        }


        //订单服务地址表
        OrderAddress orderAddress = new OrderAddress();
        BeanUtils.copyProperties(memberAddress, orderAddress);
        orderAddress.setCreateTime(LocalDateTime.now());
        orderAddress.setUpdateTime(LocalDateTime.now());
        orderAddress.setOrderId(order.getOrderId());
        orderAddress.setAddressLongitude(memberAddress.getLongitude());
        orderAddress.setAddressLatitude(memberAddress.getLatitude());
        if (orderAddressMapper.insertOrderAddress(orderAddress) < 1) {
            throw new ArithmeticException("添加订单服务地址表失败");
        }
        //查询商品数据
        Goods goods = goodsMapper.selectGoodsByGoodsId(param.getGoodsId());
        if (ObjectUtils.isEmpty(goods)) {
            throw new ArithmeticException("商品不存在");
        }
        if (goods.getIsSale() == 2) {
            throw new ArithmeticException("商品已售空");
        }
        if (goods.getIsSale() == 0) {
            throw new ArithmeticException("商品未上架");
        }
        //order_goods 订单商品添加数据
        OrderGoods orderGoods = new OrderGoods();
        BeanUtils.copyProperties(goods, orderGoods);
        orderGoods.setOrderId(order.getOrderId());
        orderGoods.setServerId(param.getServerId());
        orderGoods.setGoodsCounts(param.getGoodsCounts());
        orderGoods.setPrice(param.getPrice());
        orderGoods.setCreateTime(LocalDateTime.now());
        orderGoods.setUpdateTime(LocalDateTime.now());
        if (orderGoodsMapper.insertOrderGoods(orderGoods) < 1) {
            throw new ArithmeticException("添加订单商品失败");
        }

        //查询服务人员数据
        ServerUser serverUser = serverUserService.selectServerUserByServerId(param.getServerId());
        if (ObjectUtils.isEmpty(serverUser)) {
            throw new ArithmeticException("服务人员不存在");
        }
        //order_goodes_server 订单服务人员添加数据
        OrderGoodsServer orderGoodsServer = new OrderGoodsServer();
        BeanUtils.copyProperties(param, orderGoodsServer);
        //订单id
        orderGoodsServer.setOrderId(order.getOrderId());
        //商品名称
        orderGoodsServer.setGoodsName(goods.getName());
        //商品服务人员单价
        orderGoodsServer.setGoodsServerPrice(param.getPrice());
        //商品单位
        orderGoodsServer.setGoodsUnit(goods.getGoodsUnit());
        //服务人员姓名
        orderGoodsServer.setServerName(serverUser.getRealName());
        //服务人员性别
        orderGoodsServer.setServerSex(serverUser.getSex());
        //工龄
        orderGoodsServer.setServerAge(serverUser.getAge());
        //服务人员头像
        orderGoodsServer.setServerAvatar(serverUser.getAvatar());
        //创建时间
        orderGoodsServer.setCreateTime(LocalDateTime.now());
        orderGoodsServer.setUpdateTime(LocalDateTime.now());
        if (orderGoodsServerService.insertOrderGoodsServer(orderGoodsServer) < 1) {
            throw new ArithmeticException("添加订单服务人员关联数据失败");
        }

        //order_record 添加订单记录
        OrderRecord orderRecord = new OrderRecord();
        orderRecord.setOrderId(order.getOrderId());
        orderRecord.setPreState("000");
        orderRecord.setNowState("000");
        orderRecord.setCreateTime(LocalDateTime.now());
        orderRecord.setUpdateTime(LocalDateTime.now());
        orderRecord.setOperateInfo(sysCodeService.getDecodeValue("003","000"));
        if (orderRecordService.insertOrderRecord(orderRecord) < 1) {
            throw new ArithmeticException("添加订单记录失败");
        }
        log.info("创建订单：未支付：" + order.getOrderId());
        rabbitTemplate.convertAndSend(AmqpDelayedConfig.EXCHANGE_NAME, AmqpDelayedConfig.QUEUE_NAME, PREFIX_NO_PAY_ORDER + order.getOrderId(), message -> {
            message.getMessageProperties().setHeader("x-delay", EXPIRE_TIME_MINUTES * 60 * 1000);
            log.info("创建订单：创建延迟消息：" + AmqpDelayedConfig.QUEUE_NAME);
            return message;
        });
        return AjaxResult.success(order);
    }

    /**
     * 保存预约信息，并返回服务的结束时间
     * @param start 服务预约开始时间
     * @param cost 服务时长
     * @param serverId 服务人员id
     * @param allowCompose 是否允许组合时间段配置 0：否，1：是
     * @return 预约结束时间
     */
    @Override
    public LocalDateTime recordAppointmentInfo(LocalDateTime start, BigDecimal cost, Long serverId, Integer allowCompose) {
        // 1. 获取需要的配置信息
        ServerTime serverTime = serverTimeMapper.selectServerTimeByServerId(serverId);
        if(ObjectUtils.isEmpty(serverTime)){
            throw new ServiceException("服务人员查无服务时间");
        }

        // 1. 获取该日期该服务人员的服务时间配置
        DayOfWeek startDay = start.getDayOfWeek();
        Integer dayOfWeek = DayOfWeek.SUNDAY.equals(startDay) ? 0: startDay.getValue();
        List<ServerTimeSection> sectionList = serverTimeSectionService.selectSectionBy(dayOfWeek, serverId);
        if (CollectionUtils.isEmpty(sectionList)){
            throw new ServiceException("未找到服务人员的时间配置信息");
        }

        LocalDateTime appointmentEndTime = start.plusMinutes((long)(cost.doubleValue() * 60));
        ServerTimeSection prev = null;
        for (ServerTimeSection serverTimeSection: sectionList){
            if (Objects.isNull(prev)){
                prev = serverTimeSection;
                continue;
            }
            LocalTime currentStart = serverTimeSection.getHoursFrom();
            LocalTime prevEnd = prev.getHoursEnd();
            if (start.toLocalTime().isBefore(prevEnd) && appointmentEndTime.toLocalTime().isAfter(prevEnd)){
                if(allowCompose == 0){
                    throw new ServiceException("超出可预约的时间范围");
                }
                long breakTime = (currentStart.getHour() - prevEnd.getHour()) * 60 + (currentStart.getMinute() - prevEnd.getMinute());
                appointmentEndTime = appointmentEndTime.plusMinutes(breakTime);
            }

        }
        if (appointmentEndTime.toLocalTime().isAfter(sectionList.get(sectionList.size()-1).getHoursEnd())){
            throw new ServiceException("超出可预约的时间范围");
        }

        BigDecimal serverGrap = serverTime.getServerGrap();
        LocalDateTime serverEndTime = appointmentEndTime.plusMinutes((long)(serverGrap.doubleValue() * 60));
        // 服务人员预约时间段列表
        if (serverEndTime.getDayOfMonth() > start.getDayOfMonth()){
            serverEndTime = serverEndTime.minusDays(1L).withHour(23).withMinute(30);
        }
        List<ServerTimeBook> serverTimeBookList = serverTimeBookService
                .selectAvailableServerTimeBookList(serverId, start.toLocalDate(),
                        start.toLocalTime(), serverEndTime.toLocalTime());
         if (CollectionUtils.isEmpty(serverTimeBookList)){
            throw new ServiceException("不存在可预约的时间段（请确认该时间是否在该服务人员今天往后一周的工作时间内）");
        }
        for (ServerTimeBook serverTimeBook : serverTimeBookList) {
            if (serverTimeBook.getBooked() == 1) {
                throw new ServiceException("预约时间段中存在已被预约时间段");
            }
            if (serverTimeBook.getStartTime().compareTo(appointmentEndTime.toLocalTime()) >= 0) {
                // 服务间隔时间，不可约（2）
                serverTimeBook.setBooked(2);
            } else {
                serverTimeBook.setBooked(1);
            }
        }
        serverTimeBookService.updateServerTimeBooks(serverTimeBookList);
        return appointmentEndTime;
    }


    /**
     * 查询会员订单详情
     *
     * @param orderId
     * @return
     */
    @Override
    public MemberOrderDetailVo getMemberOrderByOrderId(Long orderId) {
        // 查询会员订单详情
        MemberOrderDetailVo memberOrderDetailVo = orderMapper.getMemberOrderByOrderId(orderId);
        if (memberOrderDetailVo == null) {
            return null;
        }
        // 是否追评(默认为0-否)
        memberOrderDetailVo.setIsAddComment("0");
        // 获取商家电话
        Merchant merchant = merchantMapper.selectMerchantByMerchantId(memberOrderDetailVo.getMerchantId());
        //商家头像
        memberOrderDetailVo.setMerchantAvatar(merchant.getAvatar());
        memberOrderDetailVo.setMerchantPhone(merchant == null ? StringUtils.EMPTY : merchant.getMerchantPhone());
        memberOrderDetailVo.setMerchantType(merchant == null ? null : merchant.getMerchantType());
        if(!ObjectUtils.isEmpty(merchant) && merchant.getMerchantType() ==1){
            SysUser sysUser = sysUserService.selectSysUserById(merchant.getAdminId());
            if(!ObjectUtils.isEmpty(sysUser)) {
                memberOrderDetailVo.setMerchantName(sysUser.getNickName());
            }
        }
        // 获取订单状态名称
        memberOrderDetailVo.setOrderStateName(OrderStateEnum.getDescription(memberOrderDetailVo.getOrderState()));
        // 获取家政等级名称
        memberOrderDetailVo.setServerLevelName(ServerLevelEnum.getDescription(memberOrderDetailVo.getServerLevel()));
        // 获取服务类别名称
        if (!Objects.isNull(memberOrderDetailVo.getCateId())) {
            Category category = categoryMapper.selectCategoryByCategoryId(memberOrderDetailVo.getCateId());
            memberOrderDetailVo.setCateName(category == null ? StringUtils.EMPTY : category.getCategoryName());
            if (!Objects.isNull(category) && !Objects.isNull(category.getParentId())) {
                // 查询父级分类名称
                Category parentCategory = categoryMapper.selectCategoryByCategoryId(Long.valueOf(category.getParentId()));
                memberOrderDetailVo.setParentCateName(parentCategory == null ? StringUtils.EMPTY : parentCategory.getCategoryName());
            }
        }
        // 获取商品单位名称

        // 处理其他商品单位名称
        if (Objects.equals(memberOrderDetailVo.getGoodsUnit(), "999")) {
            memberOrderDetailVo.setGoodsUnitName(memberOrderDetailVo.getOtherUnit());
        }

//        if (StringUtils.isNotBlank(memberOrderDetailVo.getGoodsUnit())) {
//            String goodsUnitName = sysDictDataMapper.selectDictLabel("goods_unit", memberOrderDetailVo.getGoodsUnit());
//            memberOrderDetailVo.setGoodsUnitName(goodsUnitName);
//        }
        // 已申请退款/已退款
        if (Objects.equals(OrderStateEnum.PENDING_REFUNDED.getCode(), memberOrderDetailVo.getOrderState())
                || Objects.equals(OrderStateEnum.REFUNDED.getCode(), memberOrderDetailVo.getOrderState())
                || Objects.equals(OrderStateEnum.REJECTED.getCode(), memberOrderDetailVo.getOrderState())) {
            // 查询退款信息
            OrderRefund orderRefund = orderRefundMapper.getByOrderId(orderId);
            if (orderRefund != null) {
                memberOrderDetailVo.setPayMoney(orderRefund.getPayMoney());
                memberOrderDetailVo.setRefundReason(orderRefund.getRefundReason());
                memberOrderDetailVo.setRefundMoney(orderRefund.getRefundMoney());
                memberOrderDetailVo.setRefundState(orderRefund.getStatus());
                memberOrderDetailVo.setRefundStateName(OrderRefundStateEnum.getDescription(orderRefund.getStatus()));
                memberOrderDetailVo.setRefundResult(orderRefund.getRefundResult());
            }
        }
        // 查询评价id
        if (Objects.equals(memberOrderDetailVo.getCommentState(), "002")) {
            GoodsComment goodsComment = goodsCommentMapper.getByOrderId(orderId);
            if (goodsComment != null) {
                memberOrderDetailVo.setCommentId(goodsComment.getCommontId());
                memberOrderDetailVo.setIsAddComment(StringUtils.isBlank(goodsComment.getReContent()) ? "0" : "1");
            }
        }
        // 查询商品信息，获取商品是否下架
        Goods goods = goodsMapper.selectGoodsByGoodsId(memberOrderDetailVo.getGoodsId());
        if (goods == null || goods.getIsSale() == 0) {
            memberOrderDetailVo.setIsGoodsClosed("1");
        } else {
            memberOrderDetailVo.setIsGoodsClosed("0");
            if (!"001".equals(merchant.getBusinessState())) {
                memberOrderDetailVo.setIsGoodsClosed("1");
            }
        }
        // 查询商品图片列表
        List<GoodsImage> goodsImageList = goodsImageMapper.goodsImageList(Arrays.asList(memberOrderDetailVo.getGoodsId()));
        memberOrderDetailVo.setGoodsImageList(goodsImageList);

        if ("003".equals(memberOrderDetailVo.getOrderType())) {
            //查询订单核销记录
            OrderVerificationRecord orderVerificationRecord = new OrderVerificationRecord();
            orderVerificationRecord.setOrderId(orderId);
            orderVerificationRecord.setDelFlag("0");

            List<OrderVerificationRecord> orderVerificationRecordList = orderVerificationRecordService.selectOrderVerificationRecordList(orderVerificationRecord);
            if (orderVerificationRecordList.size() > 0) {
                memberOrderDetailVo.setOrderVerificationRecordList(orderVerificationRecordList);
            }
        } else {
            //商品服务人员关联数据
            GoodsServer goodsServer = new GoodsServer();
            goodsServer.setServerId(memberOrderDetailVo.getServerId());
            goodsServer.setGoodsId(memberOrderDetailVo.getGoodsId());
            List<GoodsServer> goodsServers = goodsServerService.selectGoodsServerList(goodsServer);
            if (goodsServers.size() < 1) {
                memberOrderDetailVo.setIsGoodsClosed("1");
            }
        }
        //判断订单状态为003、004待确认、已完成状态，订单结束时间是否超过七天
        if("003".equals(memberOrderDetailVo.getOrderState())||"004".equals(memberOrderDetailVo.getOrderState())){
            memberOrderDetailVo.setControlShow(true);
            if(!ObjectUtils.isEmpty(memberOrderDetailVo.getServiceEndTime())) {
                //取出结束时间加七天与当前时间比较
                LocalDateTime localDateTime = LocalDateTime.ofInstant(memberOrderDetailVo.getServiceEndTime().toInstant(), ZoneId.systemDefault()).plusDays(7);
                //判断结束时间在当前时间前
                memberOrderDetailVo.setControlShow(localDateTime.isAfter(LocalDateTime.now()));
            }
        }

        return memberOrderDetailVo;
    }

    /**
     * 订单支付
     * @param param
     * @return
     */
    @Override
    @Transactional
    public AjaxResult payment(PaymentParam param) {
        // 获取修改信息
        OrderModify current = orderModifyService.getLatestRecord(param.getOrderId());
        if (Objects.nonNull(current)){
            param.setModifyIndex(current.getModifyIndex());
        }

        PaymentDto paymentDto = new PaymentDto();
        // 查询支付支付串
        OrderPayment orderPayment = orderPaymentService.selectOrderPaymentByOrderId(param.getOrderId());
        if (orderPayment != null) {
            // 支付方式code(001微信，002支付宝)
            if ("001".equals(param.getPayWay()) && orderPayment.getWxPayStr() != null) {
                paymentDto.setPayInfo(orderPayment.getWxPayStr());
                return AjaxResult.success(paymentDto);
            }

            if ("002".equals(param.getPayWay()) && orderPayment.getAliPayStr() != null) {
                paymentDto.setPayInfo(orderPayment.getAliPayStr());
                return AjaxResult.success(paymentDto);
            }
        }
        //订单支付标志
        param.setAddType(0);
        log.info("合利宝预支付，请求参数 " + JSON.toJSONString(param));
        String qrcode = null;
        //根据订单id查询订单数据
        Order order = orderMapper.selectOrderByOrderId(param.getOrderId());
        if(ObjectUtils.isEmpty(order)){
            return AjaxResult.error("订单不存在");
        }

        // 校验传入的实际支付金额和订单的实际支付金额是否一致
        if (param.getTotalAmount().compareTo(order.getTotalAmount()) != 0) {
            return AjaxResult.error("实际支付金额与订单实际所需支付金额不一致");
        }
        // 校验实际支付金额 + 优惠金额 + 优金豆抵扣金额 与订单金额是否一致
        BigDecimal verifyAmount = param.getTotalAmount();
        // 若存在优惠金额(优惠券金额) 2022.04.01下午确认
        if (order.getCouponAmount() != null && order.getCouponAmount().compareTo(BigDecimal.ZERO) > 0) {
            verifyAmount = verifyAmount.add(order.getCouponAmount());
        }
        // 若存在优金豆抵扣金额
        if (order.getBeanAmount() != null && order.getBeanAmount() > 0) {
            verifyAmount = verifyAmount.add(BigDecimal.valueOf(order.getBeanAmount()).divide(BigDecimal.valueOf(100)).setScale(2));
        }
        if (verifyAmount.compareTo(order.getOrderAmount()) != 0) {
            return AjaxResult.error("付款总金额与订单金额不符");
        }

//        if(param.getTotalAmount().compareTo(order.getOrderAmount()) != 0){
//            return AjaxResult.error("付款金额与订单金额不符");
//        }
        //验证订单状态000（提交订单待支付）
        if(!"000".equals(order.getOrderState())){
            return AjaxResult.error("订单非支付状态");
        }
        //查询订单商品的商家信息
        Merchant merchant = merchantMapper.selectMerchantByMerchantId(order.getMerchantId());
        if(ObjectUtils.isEmpty(merchant)){
            return AjaxResult.error("商品商家不存在");
        }
        param.setMerchantType(merchant.getMerchantType());
        //商家
        if(merchant.getMerchantType().equals(0)){
            //查询商家合利宝邮箱
            MerchantSettleInfo merchantSettleInfo = settleInfoService.selectMerchantSettleInfoByMerchantId(merchant.getMerchantId());
            if(ObjectUtils.isEmpty(merchantSettleInfo)) {
                return AjaxResult.error("商品合利宝账户不存在");
            }
            param.setEmail(merchantSettleInfo.getEmail());
        }

        //平台抽成百分比
        BigDecimal percaent = new BigDecimal(sysConfigMapper.checkConfigKeyUnique("platform.commission.rate").getConfigValue());
        BigDecimal shopAmount= order.getTotalAmount().subtract(order.getTotalAmount().multiply(percaent).divide(new BigDecimal(100),2, ROUND_HALF_UP));
       //判断有无使用优金豆，如果有，加上优金豆优惠金额
        //判断优金豆抵扣金额
        if(order.getBeanAmount()!=null){
            shopAmount.add(new BigDecimal(order.getBeanAmount()).divide(new BigDecimal(100)));
        }
        //商家可得金额
        param.setShopAmount(shopAmount);

        //进行支付
        // 001微信 002支付宝
        if("001".equals(param.getPayWay()) && StringUtils.equals(param.getPayType(), PayType.APPLET.name())){
            // 获取用户openId
            String openId = getOpenId(param.getCode());
            if (StringUtils.isBlank(openId)) {
                return AjaxResult.error("OpenId获取异常");
            }

            Map<String, Object> resultMap = payService.hlbPay(param, openId);

            // 支付返回结果
            if (resultMap != null && (Integer) resultMap.get("statusCode") == HttpStatus.SC_OK) {
                String resultMsg = (String) resultMap.get("response");
                AppPayPublicOrderResponseVo orderResponseVo = JSONObject.parseObject(resultMsg, AppPayPublicOrderResponseVo.class);
                if (StringUtils.isBlank(orderResponseVo.getRt10_payInfo())) {
                    return AjaxResult.error(orderResponseVo.getRt3_retMsg());
                }

                //更新订单信息后
                order.setUpdateTime(LocalDateTime.now());
                order.setPayWay(param.getPayWay());
                if(orderMapper.updateOrderCustom(order)<0){
                    throw new ArithmeticException("更新订单信息失败");
                }
                paymentDto.setPayInfo(orderResponseVo.getRt10_payInfo());
                paymentDto.setSign(orderResponseVo.getSign());
                if (orderPayment == null ) {
                    orderPayment = new OrderPayment();
                    orderPayment.setOrderId(param.getOrderId());
                    orderPayment.setWxPayStr(orderResponseVo.getRt10_payInfo());
                    orderPaymentService.insertOrderPayment(orderPayment);
                } else {
                    orderPayment.setWxPayStr(orderResponseVo.getRt10_payInfo());
                    orderPaymentService.updateOrderPayment(orderPayment);
                }
                return AjaxResult.success(paymentDto);
            }
        }else if("002".equals(param.getPayWay()) && StringUtils.equals(param.getPayType(), PayType.SDK.name())){
            log.info("APP（SDK）预下单 -- 支付宝");
            Map<String, Object> resultMap = payService.hlbPay(param, null);

            String resultMsg = (String) resultMap.get("response");
            CreateOrderResponseVo orderResponseVo = JSONObject.parseObject(resultMsg, CreateOrderResponseVo.class);
            qrcode = orderResponseVo.getRt8_qrcode();
            if (StringUtils.isBlank(qrcode)) {
                return AjaxResult.error(orderResponseVo.getRt3_retMsg());
            }

            //更新订单信息后
            order.setUpdateTime(LocalDateTime.now());
            order.setPayWay(param.getPayWay());
            if(orderMapper.updateOrderCustom(order)<0){
                throw new ArithmeticException("更新订单信息失败");
            }

            paymentDto.setPayInfo(orderResponseVo.getRt8_qrcode());
            paymentDto.setSign(orderResponseVo.getSign());
            if (orderPayment == null ) {
                orderPayment = new OrderPayment();
                orderPayment.setOrderId(param.getOrderId());
                orderPayment.setAliPayStr(orderResponseVo.getRt8_qrcode());
                orderPaymentService.insertOrderPayment(orderPayment);
            } else {
                orderPayment.setAliPayStr(orderResponseVo.getRt8_qrcode());
                orderPaymentService.updateOrderPayment(orderPayment);
            }
            return AjaxResult.success(paymentDto);
        }
            return AjaxResult.error("支付方式不正确");
    }

    /**
     * 申请平台退款
     * @param param
     * @return
     */
    @Override
    @Transactional
    public AjaxResult applyForRefund(OredrRefundParam param) {
        //根据订单id查询订单数据
        Order order = orderMapper.selectOrderByOrderId(param.getOrderId());
        if (ObjectUtils.isEmpty(order)) {
            return AjaxResult.error("订单不存在");
        }
        // 订单更新前状态
        String oldOrderState = order.getOrderState();
        //判断订单状态是已完成 2022.05.09讨论后产品说取消此逻辑，改为下单时间超过一个月不可退
//        if ("004".equals(order.getOrderState()) && order.getServiceEndTime() != null) {
//            // 校验订单完成时间是否已经超过24小时(即一天)
//            Date current = new Date();
//            Date finalRefundDate = DateUtil.addDateDays(order.getServiceEndTime(), 1);
//            if (current.after(finalRefundDate)) {
//                return AjaxResult.error("订单完成时间已超过24小时,不可退款!");
//            }
//        }
        if (order.getCreateTime() != null) {
            // 校验订单下单时间是否已经超过一个月
            Date current = new Date();
            Date createDate = Date.from(order.getCreateTime().atZone(ZoneId.systemDefault()).toInstant());
            Date finalRefundDate = DateUtil.addDateMonths(createDate, 1);
            if (current.after(finalRefundDate)) {
                return AjaxResult.error("订单下单时间已超过一个月,不可退款!");
            }
        }
        //查询申请退款记录
        OredrRefundParam refund = orderRefundService.selectOrderId(param.getOrderId());
        if (!ObjectUtils.isEmpty(refund)) {
            return AjaxResult.error("请务重复提交申请");
        }
        // 更新订单状态为已申请退款
        order.setOrderState(OrderStateEnum.PENDING_REFUNDED.getCode());
        order.setUpdateTime(LocalDateTime.now());
        if (orderMapper.updateOrderCustom(order) < 0) {
            throw new ArithmeticException("更新订单信息失败");
        }

        //根据订单id查询最近一条订单记录数据
        OrderRecord orderRecord = orderRecordService.selectRefunfd(order.getOrderId());
        OrderRecord record = new OrderRecord();
        if(!ObjectUtils.isEmpty(orderRecord)){
            record.setPreState(orderRecord.getNowState());
        } else {
            record.setPreState(oldOrderState);
        }
        record.setOrderId(order.getOrderId());
        record.setNowState("005");
        record.setOperateInfo(sysCodeService.getDecodeValue("003","005"));
        if(orderRecordService.insertOrderRecord(record)<1){
            throw new ArithmeticException("添加订单追踪信息失败");
        }

        // 添加一条退款处理
        OredrRefundParam oredrRefundParam = new OredrRefundParam();
        BeanUtils.copyProperties(param,oredrRefundParam);
        // 需要退回金额是实际付款金额
        oredrRefundParam.setPayMoney(order.getTotalAmount());
        // 退款状态
        oredrRefundParam.setStatus(OrderRefundStateEnum.PLATFORM_INTERVENTION.getCode());
        if(orderRefundService.insertOrderRefund(oredrRefundParam)<1){
            throw new ArithmeticException("添加退款处理记录失败");
        }

        // 顾客申请退款发送短信通知
        try {
            // 查询订单商家信息
            Merchant merchantByMerchantId = merchantService.getMerchantByMerchantId(order.getMerchantId());
            if (merchantByMerchantId != null) {
                // 顾客申请退款短信通知商家
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("orderindex", order.getOrderIndex());
                jsonObject.put("amount", oredrRefundParam.getPayMoney());
                log.warn("顾客申请退款短信通知商家--短信发送参数:" + JSONObject.toJSONString(jsonObject));
                log.warn("顾客申请退款短信通知商家--短信接收手机号:" + merchantByMerchantId.getMerchantPhone());
                SendSmsResponse sendSmsResponse = smsUtil.sendSms(merchantByMerchantId.getMerchantPhone(), jsonObject, AliTemplateCode.MEMBER_APPLY_REFUND_NOTIFY_MERCHANT_CODE);
                log.warn("顾客申请退款短信通知商家--短信返回结果:" + JSONObject.toJSONString(sendSmsResponse));
            } else {
                log.error("顾客申请退款--未查询到商家信息!订单编号orderIndex="+order.getOrderIndex());
            }
            // 查询平台客服电话
            SysConfig sysConfig = sysConfigMapper.checkConfigKeyUnique("home.complaint.hotline");
            String serviceHotline = sysConfig == null ? null : sysConfig.getConfigValue();
            if (StringUtils.isNotBlank(serviceHotline) && merchantByMerchantId != null) {
                // 顾客申请退款短信通知平台客服
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("shopname", merchantByMerchantId.getMerchantName());
                jsonObject.put("orderindex", order.getOrderIndex());
                jsonObject.put("amount", oredrRefundParam.getPayMoney());
                log.warn("顾客申请退款短信通知平台客服--短信发送参数:" + JSONObject.toJSONString(jsonObject));
                log.warn("顾客申请退款短信通知平台客服--短信接收手机号:" + serviceHotline);
                SendSmsResponse sendSmsResponse = smsUtil.sendSms(serviceHotline, jsonObject, AliTemplateCode.MEMBER_APPLY_REFUND_NOTIFY_PLATFORM_CUSTOMER_SERVICE_CODE);
                log.warn("顾客申请退款短信通知平台客服--短信返回结果:" + JSONObject.toJSONString(sendSmsResponse));
            } else {
                log.error("顾客申请退款--未查询到平台客服电话/商家信息!订单编号orderIndex=" + order.getOrderIndex());
            }
        } catch (Exception e) {
            log.error("顾客申请退款--发送短信通知出现错误!错误信息error=" + e.getMessage());
        }

        return AjaxResult.success();
    }

    /**
     * 取消订单
     * @param param
     * @return
     */
    @Override
    @Transactional
    public AjaxResult cancal (OredrRefundParam param) {
        //根据订单id查询订单数据
        Order order = orderMapper.selectOrderByOrderId(param.getOrderId());
        if(ObjectUtils.isEmpty(order)){
            return AjaxResult.error("订单不存在");
        }
        if(!"000".equals(order.getOrderState())){
            return AjaxResult.error("订单待服务，不可取消");
        }
        if(! publishService.cancelPublishOrder(param.getOrderId())){
            throw new ArithmeticException("更改服务状态失败");
        }
        order.setOrderState("099");
        order.setUpdateTime(LocalDateTime.now());
        if(orderMapper.updateOrderCustom(order)<=0){
            throw new ArithmeticException("更新订单信息失败");
        }
        //根据订单id查询最近一条订单记录数据
        OrderRecord orderRecord = orderRecordService.selectRefunfd(order.getOrderId());
        OrderRecord record = new OrderRecord();
        if(!ObjectUtils.isEmpty(orderRecord)){
            record.setPreState(orderRecord.getNowState());
        }
        record.setOrderId(order.getOrderId());
        record.setNowState("099");
        record.setOperateInfo(sysCodeService.getDecodeValue("003","099"));
        if(orderRecordService.insertOrderRecord(record)<1){
            throw new ArithmeticException("添加订单追踪信息失败");
        }

        if(!publishService.cancelPublishOrder(param.getOrderId())){
            throw new ArithmeticException("更改服务状态失败");
        }

        // 如果使用优金豆或者优惠券，调用远程接口恢复用户优金豆数量
        if (order.getBeanAmount() != null && order.getBeanAmount() > 0) {
            // 查询会员信息
            Member member = memberMapper.selectMemberByMemberId(order.getMemberId());
            if (member != null) {
                FamilyParam familyParam = new FamilyParam();
                familyParam.setNum(BigDecimal.valueOf(order.getBeanAmount()));
                familyParam.setPhone(member.getPhone());
                familyParam.setCode(BeanPointCodeEnum.REFUNDS.getCode());
                String jsonCode = coinService.increasePoints(familyParam);
                if (Objects.equals(jsonCode, "200")) {
                    // 优金豆增加成功
                    IntegralRecord integralRecord = new IntegralRecord();
                    integralRecord.setChange(order.getBeanAmount());
                    integralRecord.setReason(BeanPointCodeEnum.REFUNDS.getCode());
                    integralRecord.setResult(1);
                    integralRecord.setMsg(JSON.toJSONString(familyParam));
                    int insertIntegralRecord = integralRecordMapper.insertIntegralRecord(integralRecord);
                    if (insertIntegralRecord <= 0) {
                        log.error("订单取消优金豆增加成功，但是优金豆积分变动记录insert失败!integralRecord=" + JSON.toJSONString(integralRecord));
                    }
                } else {
                    // 优金豆增加失败
                    IntegralRecord integralRecord = new IntegralRecord();
                    integralRecord.setChange(order.getBeanAmount());
                    integralRecord.setReason(BeanPointCodeEnum.REFUNDS.getCode());
                    integralRecord.setResult(0);
                    integralRecord.setMsg(JSON.toJSONString(familyParam));
                    int insertIntegralRecord = integralRecordMapper.insertIntegralRecord(integralRecord);
                    if (insertIntegralRecord <= 0) {
                        log.error("订单取消优金豆增加失败，并且优金豆积分变动记录insert失败!integralRecord=" + JSON.toJSONString(integralRecord));
                    }
                }
            } else {
                log.error("订单取消增加优金豆时通过会员id未查询到会员信息!memberId=" + order.getMemberId());
            }
        }

        //判断订单是否是团购订单
        if("003".equals(order.getOrderType())){
            return AjaxResult.success();
        }
        // 取消已预定记录
        cancelBook(order);
        return AjaxResult.success();
    }

    /**
     * 取消已预定记录
     */
    @Override
    public void cancelBook(Order order) {
        OrderGoodsServer orderGoodsServer = orderGoodsServerService.selectOrderGoodsServerByOrderId(order.getOrderId());
        if (orderGoodsServer == null) {
            return;
        }
        Long serverId = orderGoodsServer.getServerId();
        ServerTime serverTime = serverTimeMapper.selectServerTimeByServerId(serverId);
        LocalDateTime endTime = order.getAppointmentEndTime().plusMinutes(serverTime.getServerGrap().multiply(BigDecimal.valueOf(60)).longValue());
        // 防止结束时间到了第二天查不出数据
        if (endTime.getDayOfMonth() > order.getAppointmentStartTime().getDayOfMonth()){
            endTime = endTime.minusDays(1L).withHour(23).withMinute(30);
        }
        List<ServerTimeBook> serverTimeBookList = serverTimeBookService
                .selectAvailableServerTimeBookList(serverId, order.getAppointmentStartTime().toLocalDate(),
                        order.getAppointmentStartTime().toLocalTime(), endTime.toLocalTime());
        for (ServerTimeBook serverTimeBook : serverTimeBookList) {
            serverTimeBook.setBooked(0);
        }
        serverTimeBookService.updateServerTimeBooks(serverTimeBookList);
    }

    /**
     * 追加服务
     * @param param
     * @return
     */
    @Override
    @Transactional
    public AjaxResult addServer(OrderParam param) {
        PaymentDto paymentDto = new PaymentDto();
        // 查询支付支付串
        OrderPayment orderPayment = orderPaymentService.selectOrderPaymentByOrderId(param.getOrderId());
        log.warn("支付字符串--wx-> " + orderPayment.getWxAddPayStr() + "--ali-> " + orderPayment.getAliAddPayStr());
//        if (orderPayment != null) {
            // 支付方式code(001微信，002支付宝)
//            if ("001".equals(param.getPayWay()) && orderPayment.getWxAddPayStr() != null) {
//                paymentDto.setPayInfo(orderPayment.getWxAddPayStr());
//                return AjaxResult.success(paymentDto);
//            }
//
//            if ("002".equals(param.getPayWay()) && orderPayment.getAliAddPayStr() != null) {
//                paymentDto.setPayInfo(orderPayment.getAliAddPayStr());
//                return AjaxResult.success(paymentDto);
//            }
//        }

        String qrcode = null;
        // 回调付款参数
        PaymentParam paymentParam = new PaymentParam();

        //根据订单id查询订单数据
        MemberOrderDetailVo order = orderMapper.getMemberOrderByOrderId(param.getOrderId());
        if(ObjectUtils.isEmpty(order)){
            return AjaxResult.error("订单不存在");
        }
        //参数存储
        //服务人员id
        param.setServerId(order.getServerId());
        //单次服务标准时长
        param.setSingleTime(order.getSingleTime());

        //追加时间（小时）
//        BigDecimal multiply = new BigDecimal(param.getAddCounts()).multiply(param.getSingleTime());
        //计算追加时长
        //付款
        Order orderAdd = new Order();
        orderAdd.setOrderId(param.getOrderId());
        //追加服务数量
        orderAdd.setAddAmount(param.getAddAmount());
        //付款方式
        orderAdd.setAddPayWay(param.getAddPayWay());
        //商家可得金额进行更改
        //平台抽成百分比
        BigDecimal percentage = new BigDecimal(sysConfigMapper.checkConfigKeyUnique("platform.commission.rate").getConfigValue());
        //商家可得到 实付总价减去平台抽成
        BigDecimal addShopAmount= param.getAddAmount()
                .subtract(
                        param.getAddAmount().multiply(percentage)
                                .divide(new BigDecimal(100),2, ROUND_HALF_UP));
        orderAdd.setUpdateTime(LocalDateTime.now());
        //更新订单数据
        if(orderMapper.updateOrderCustom(orderAdd)<1){
            throw new ArithmeticException("订单更新失败");
        }

        //查询订单商品的商家信息
        Merchant merchant = merchantMapper.selectMerchantByMerchantId(order.getMerchantId());
        if(ObjectUtils.isEmpty(merchant)){
            return AjaxResult.error("商品商家不存在");
        }
        //商家
        if(merchant.getMerchantType().equals(0)){
            //查询商家合利宝邮箱
            MerchantSettleInfo merchantSettleInfo = settleInfoService.selectMerchantSettleInfoByMerchantId(merchant.getMerchantId());
            if(ObjectUtils.isEmpty(merchantSettleInfo)) {
                return AjaxResult.error("商品合利宝账户不存在");
            }
            //商家邮箱
            paymentParam.setEmail(merchantSettleInfo.getEmail());
        }
        OrderGoods orderGoods = orderGoodsMapper.selectOrderGoodsByOrderId(order.getOrderId());
        if(ObjectUtils.isEmpty(orderGoods)){
            throw new ArithmeticException("订单商品表不存在失败");
        }

        //追加服务金额
        paymentParam.setTotalAmount(param.getAddAmount());
        paymentParam.setOrderId(order.getOrderId());
        paymentParam.setBizType(param.getBizType());
        paymentParam.setPayType(param.getPayType());
        paymentParam.setMerchantType(merchant.getMerchantType());
        //订单支付标志
        paymentParam.setAddType(1);
        //商家可得金额
        paymentParam.setShopAmount(addShopAmount);
        //追加服务次数
        if (orderPayment == null ) {
            paymentParam.setAddCountIndex(0);
        } else {
            paymentParam.setAddCountIndex(orderPayment.getAddCountIndex()+1);
        }


        String paramString = JSONObject.toJSONString(param);
        //数据缓存到redis
        redisCache.setCacheObject(order.getOrderId()+HLB_ADD_PAY_SUFFIX,paramString,60, TimeUnit.MINUTES);
        log.error("payment-param--> " + JSONObject.toJSONString(paymentParam));
        //进行支付
        // 001微信 002支付宝
        if("001".equals(param.getAddPayWay()) && StringUtils.equals(param.getPayType(), PayType.APPLET.name())){
            // 获取用户openId
            String openId = getOpenId(param.getCode());
            if (StringUtils.isBlank(openId)) {
                return AjaxResult.error("OpenId获取异常");
            }
            Map<String, Object> resultMap = payService.hlbPay(paymentParam, openId);
            log.error("wechat----> result--> " + resultMap);
            // 支付结果
            if (resultMap != null && (Integer) resultMap.get("statusCode") == HttpStatus.SC_OK) {
                String resultMsg = (String) resultMap.get("response");
                AppPayPublicOrderResponseVo orderResponseVo = JSONObject.parseObject(resultMsg, AppPayPublicOrderResponseVo.class);
                if (StringUtils.isBlank(orderResponseVo.getRt10_payInfo())) {
                    return AjaxResult.error(orderResponseVo.getRt3_retMsg());
                }
                paymentDto.setPayInfo(orderResponseVo.getRt10_payInfo());
                paymentDto.setSign(orderResponseVo.getSign());
                if (orderPayment == null ) {
                    orderPayment = new OrderPayment();
                    orderPayment.setOrderId(param.getOrderId());
                    orderPayment.setWxAddPayStr(orderResponseVo.getRt10_payInfo());
                    orderPayment.setAddCountIndex(0);
                    orderPaymentService.insertOrderPayment(orderPayment);
                } else {
                    orderPayment.setWxAddPayStr(orderResponseVo.getRt10_payInfo());
                    orderPayment.setAddCountIndex(orderPayment.getAddCountIndex()+1);
                    orderPaymentService.updateOrderPayment(orderPayment);
                }

                return AjaxResult.success(paymentDto);

            }
        }else if("002".equals(param.getAddPayWay()) && StringUtils.equals(param.getPayType(), PayType.SDK.name())){
//            log.info("APP（SDK）预下单 -- 支付宝");
            Map<String, Object> resultMap = payService.hlbPay(paymentParam, null);
            log.error("ali--result--> " + resultMap);
            String resultMsg = (String) resultMap.get("response");
            CreateOrderResponseVo orderResponseVo = JSONObject.parseObject(resultMsg, CreateOrderResponseVo.class);
            qrcode = orderResponseVo.getRt8_qrcode();
            if (StringUtils.isBlank(qrcode)) {
                return AjaxResult.error(orderResponseVo.getRt3_retMsg());
            }
            paymentDto.setPayInfo(orderResponseVo.getRt8_qrcode());
            paymentDto.setSign(orderResponseVo.getSign());
            if (orderPayment == null ) {
                orderPayment = new OrderPayment();
                orderPayment.setOrderId(param.getOrderId());
                orderPayment.setAliAddPayStr(orderResponseVo.getRt8_qrcode());
                orderPayment.setAddCountIndex(0);
                orderPaymentService.insertOrderPayment(orderPayment);
            } else {
                orderPayment.setAliAddPayStr(orderResponseVo.getRt8_qrcode());
                orderPayment.setAddCountIndex(orderPayment.getAddCountIndex()+1);
                orderPaymentService.updateOrderPayment(orderPayment);
            }
            return AjaxResult.success(paymentDto);
        }
        return AjaxResult.error("支付方式不正确");



/**
        OrderGoods orderGoods = orderGoodsMapper.selectOrderGoodsByOrderId(param.getOrderId());
        if(ObjectUtils.isEmpty(orderGoods)){
            throw new ArithmeticException("订单商品表不存在失败");
        }
        orderGoods.setAddCounts(param.getAddCounts());
        orderGoods.setUpdateTime(LocalDateTime.now());
        if(orderGoodsMapper.updateOrderGoods(orderGoods)<1){
            throw new ArithmeticException("订单商品表更新失败");
        }

        //订单变更记录
        //根据订单id查询最近一条订单记录数据
        OrderRecord orderRecord = orderRecordService.selectRefunfd(order.getOrderId());
        OrderRecord record = new OrderRecord();
        if(!ObjectUtils.isEmpty(orderRecord)){
            record.setPreState(orderRecord.getNowState());
            record.setNowState(orderRecord.getNowState());
        }
        record.setOrderId(order.getOrderId());
        record.setOperateInfo("追加服务");
        if(orderRecordService.insertOrderRecord(record)<1){
            throw new ArithmeticException("添加订单追踪信息失败");
        }
        return AjaxResult.success();
*/
    }

    /**
     * 确认完成
     * @param param
     * @return
     */
    @Override
    @Transactional
    public AjaxResult affirm(OredrRefundParam param) {
        //根据订单id查询订单数据
        Order order = orderMapper.selectOrderByOrderId(param.getOrderId());
        if(ObjectUtils.isEmpty(order)){
            return AjaxResult.error("订单不存在");
        }
        if(!"003".equals(order.getOrderState())){
            return AjaxResult.error("订单不可点击完成");
        }
        order.setUpdateTime(LocalDateTime.now());
        order.setOrderState("004");
        //更新订单数据
        if(orderMapper.updateOrderCustom(order)<1){
            throw new ArithmeticException("订单更新失败");
        }

        //根据订单id查询最近一条订单记录数据
        OrderRecord orderRecord = orderRecordService.selectRefunfd(order.getOrderId());
        OrderRecord record = new OrderRecord();
        if(!ObjectUtils.isEmpty(orderRecord)){
            record.setPreState(orderRecord.getNowState());
        }
        record.setOrderId(order.getOrderId());
        record.setNowState("004");
        record.setOperateInfo(sysCodeService.getDecodeValue("003","004"));
        if(orderRecordService.insertOrderRecord(record)<1){
            throw new ArithmeticException("添加订单追踪信息失败");
        }
        if(! publishService.cancelPublishOrder(param.getOrderId())){
            throw new ArithmeticException("更改服务状态失败");
        }

        return AjaxResult.success();
    }

    /**
     * 取消申请平台介入
     * @param param
     * @return
     */
    @Override
    public AjaxResult cancelRefund(OrderParam param) {
        // 根据订单id查询订单数据
        Order order = orderMapper.selectOrderByOrderId(param.getOrderId());
        if(ObjectUtils.isEmpty(order)){
            return AjaxResult.error("订单不存在");
        }
        // 查询订单退款记录
        OredrRefundParam refund = orderRefundService.selectOrderId(param.getOrderId());
        if(ObjectUtils.isEmpty(refund)){
            return AjaxResult.error("退款申请不存在");
        }
        if(!Objects.equals(OrderStateEnum.PENDING_REFUNDED.getCode(), order.getOrderState())){
            return AjaxResult.error("退款申请已处理，不可取消");
        }

        // 根据订单id查询最近一条订单记录数据
        OrderRecord orderRecord = orderRecordService.selectRefunfd(order.getOrderId());
        order.setUpdateTime(LocalDateTime.now());
        order.setOrderState(orderRecord == null ? OrderStateEnum.FINISHED.getCode() : orderRecord.getPreState());
        // 更新订单数据
        if(orderMapper.updateOrderCustom(order) < 1){
            throw new ServiceException("订单更新失败");
        }

        // 逻辑删除退款记录
        OrderRefund orderRefund = new OrderRefund();
        orderRefund.setOrderRefundId(refund.getOrderRefundId());
        orderRefund.setIsDel(1);
        if(orderRefundService.updateOrderRefund(orderRefund) < 1){
            throw new ServiceException("取消申请平台介入失败");
        }
        // 新增订单追踪记录
        OrderRecord record = new OrderRecord();
        record.setOrderId(order.getOrderId());
        record.setPreState(OrderStateEnum.PENDING_REFUNDED.getCode());
        record.setNowState(order.getOrderState());
        record.setOperateInfo("客户取消退款申请");
        if(orderRecordService.insertOrderRecord(record) < 1){
            throw new ServiceException("添加订单追踪信息失败");
        }
        return AjaxResult.success();

    }

    /**
     * @param settleDate 结算截止时间
     */
    @Override
    public Map<Long, List<Order>> selectPreSettleOrders(Date settleDate) {
        List<Order> list = orderMapper.selectPreSettleOrders(settleDate);
        if (list != null && list.size() > 0) {
            return list.stream().collect(Collectors.groupingBy(Order::getMerchantId));
        }
        return null;
    }

    @Override
    public boolean updateBatchById(List<Order> updated) {
        return orderMapper.updateBatchById(updated);
    }

    @Override
    public MerchantDashboardVO dashboard(Long merchantId) {
        // 1. 获取今日订单统计数据
        MerchantDashboardVO result = orderMapper.statisticsToday(merchantId);

        // 2. 统计近30天的订单
        List<OrderStatisticsVO> orderStatisticsVOList = orderMapper.statisticsByMonth(merchantId);
        result.setOrderStatisticsList(orderStatisticsVOList);

        // 3. 获取服务人员订单数top5
        List<ServerUserVo> serverUserVoList = orderMapper.getTopServerUser(merchantId);
        result.setServerUserList(serverUserVoList);

        return result;
    }

    /**
     * 根据订单id查询订单支付状态
     */
    @Override
    public AjaxResult payState(Long orderId) {
        Order order = orderMapper.selectOrderId(orderId);
        if(ObjectUtils.isEmpty(order)){
            return AjaxResult.success("订单不存在",false);
        }
        if(order.getIsSettle()==0){
            return AjaxResult.success("待支付",true);
        }
        return AjaxResult.success("订单已支付",false);
    }

    /**
     * 支付回调
     * @param body
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String  payCd(NotifyResponseVo body) {
        String assemblyRespOriSign = null;
        try {
            assemblyRespOriSign = com.younike.hlpay.util.BeanUtils.getSignedByPresetParameter(
                    body, NotifyResponseVo.NEED_SIGN_PARAMS);

        } catch (Exception e) {
            // return "fail 系统内部错误" + e.getMessage();// 反馈处理结果
            log.error("系统内部错误" + e.getMessage());
            return "failed";
        }
        log.info("组装返回结果签名串：" + assemblyRespOriSign);
        String responseSign = body.getSign();
        log.info("响应签名：" + responseSign);
        String checkSign = Disguiser
                .disguiseMD5(assemblyRespOriSign.trim());
        log.info("验证签名：" + checkSign);

        if (checkSign.equals(responseSign)) {
            // 验证签名成功
            log.info("验证签名成功");
            // 校验支付信息
            String rt2_orderId = body.getRt2_orderId();
            String[] split = rt2_orderId.split("-");
            String orderId = split[1];
            Order order = orderMapper.selectOrderByOrderId(Long.valueOf(orderId));
            //判断是否是追加服务
            if (split.length == 4 && split[2].equals("ADD")) {
                log.info("...进入追加服务处理逻辑...");
                //家政
                if ("001".equals(order.getOrderType())) {
                    //取出缓存数据
                    String cacheObject = redisCache.getCacheObject(order.getOrderId() + HLB_ADD_PAY_SUFFIX);
                    OrderParam orderParam = JSONObject.parseObject(cacheObject, OrderParam.class);

                    //追加时间（小时）
                    BigDecimal multiply = new BigDecimal(orderParam.getAddCounts()).multiply(orderParam.getSingleTime());
                    //平台抽成百分比
                    BigDecimal percaent = new BigDecimal(sysConfigMapper.checkConfigKeyUnique("platform.commission.rate").getConfigValue());
                    //商家可得追加服务金额
                    BigDecimal addShopAmount= order.getAddAmount().subtract(order.getAddAmount().multiply(percaent).divide(new BigDecimal(100),2, ROUND_HALF_UP));
                    //支付成功后
                    order.setUpdateTime(LocalDateTime.now());
                    order.setAddShopAmount(addShopAmount);
                    order.setTotalAmount(order.getTotalAmount().add(order.getAddAmount()));
                    order.setAddPayStatus(1);
                    //追加结束时长
                    order.setAppointmentEndTime(order.getAppointmentEndTime().plusHours(multiply.longValue()));

                    if(orderMapper.updateOrderCustom(order)<0){
                        log.error("支付回调 -- 更新订单信息失败");
                        throw new ArithmeticException("更新订单信息失败");
                    }

                    OrderGoods orderGoods = orderGoodsMapper.selectOrderGoodsByOrderId(order.getOrderId());
                    if(ObjectUtils.isEmpty(orderGoods)){
                        log.error("支付回调 -- 订单商品表不存在失败");
                        throw new ArithmeticException("订单商品表不存在失败");
                    }
                    orderGoods.setAddCounts(orderParam.getAddCounts());
                    orderGoods.setUpdateTime(LocalDateTime.now());
                    if(orderGoodsMapper.updateOrderGoods(orderGoods)<1){
                        log.error("支付回调 -- 订单商品表更新失败");
                        throw new ArithmeticException("订单商品表更新失败");
                    }

                    //订单变更记录
                    //根据订单id查询最近一条订单记录数据
                    OrderRecord orderRecord = orderRecordService.selectRefunfd(order.getOrderId());
                    OrderRecord record = new OrderRecord();
                    if(!ObjectUtils.isEmpty(orderRecord)){
                        record.setPreState(orderRecord.getNowState());
                        record.setNowState(orderRecord.getNowState());
                    }
                    record.setOrderId(order.getOrderId());
                    record.setOperateInfo("追加服务");
                    if(orderRecordService.insertOrderRecord(record)<1){
                        log.error("支付回调 -- 添加订单追踪信息失败");
                        throw new ArithmeticException("添加订单追踪信息失败");
                    }
                    // 追加服务发送短信通知
                    try {
                        // 查询订单商家信息
                        Merchant merchantByMerchantId = merchantService.getMerchantByMerchantId(order.getMerchantId());
                        if (merchantByMerchantId != null && StringUtils.isNotBlank(merchantByMerchantId.getMerchantPhone())) {
                            log.info("...进入家政追加服务短信通知商家处理逻辑...");
                            // 家政追加服务短信通知商家
                            JSONObject param = new JSONObject();
                            param.put("orderindex", order.getOrderIndex());
                            param.put("add_count", orderParam.getAddCounts());
                            param.put("add_amount", order.getAddAmount());
                            log.warn("家政追加服务短信通知商家--短信发送参数:" + JSONObject.toJSONString(param));
                            log.warn("家政追加服务短信通知商家--短信接收手机号:" + merchantByMerchantId.getMerchantPhone());
                            SendSmsResponse sendSmsResponse = smsUtil.sendSms(merchantByMerchantId.getMerchantPhone(), param, AliTemplateCode.ORDER_SERVICE_ADD_NOTIFY_MERCHANT_CODE);
                            log.warn("家政追加服务短信通知商家--短信返回结果:" + JSONObject.toJSONString(sendSmsResponse));
                        } else {
                            log.error("支付回调追加服务发送短信通知商家--未查询到商家信息!订单编号orderIndex=" + order.getOrderIndex());
                        }
                    } catch (Exception e) {
                        log.error("支付回调--追加服务短信通知发送失败!错误信息error=" + e.getMessage());
                    }

                    log.info("支付回调 -- success");
                    return "success";
                } else if ("002".equals(order.getOrderType())) {
                    //支付成功
                    order.setAddPayStatus(1);
                    //更新实付金额数据
                    //实付金额
                    order.setTotalAmount(order.getMaintenanceAmount().add(order.getTotalAmount()));
                    order.setUpdateTime(LocalDateTime.now());
                    if(orderMapper.updateOrderCustom(order)<1){
                        log.error("支付回调 -- 更新订单信息失败");
                        throw new ArithmeticException("更新订单信息失败");
                    }
                    OrderRecord orderRecord = orderRecordService.selectRefunfd(order.getOrderId());
                    OrderRecord record = new OrderRecord();
                    if(!ObjectUtils.isEmpty(orderRecord)){
                        record.setPreState(orderRecord.getNowState());
                        record.setNowState(orderRecord.getNowState());
                    }
                    record.setOrderId(order.getOrderId());
                    record.setOperateInfo("维修/配件费付款成功");
                    if(orderRecordService.insertOrderRecord(record)<1){
                        log.error("支付回调 -- 添加订单追踪信息失败");
                        throw new ArithmeticException("添加订单追踪信息失败");
                    }

                    // 收取维修/配件费短信通知
                    try {
                        // 查询订单商家信息
                        Merchant merchantByMerchantId = merchantService.getMerchantByMerchantId(order.getMerchantId());
                        if (merchantByMerchantId != null && StringUtils.isNotBlank(merchantByMerchantId.getMerchantPhone())) {
                            log.info("...进入收取维修/配件费短信通知商家处理逻辑...");
                            // 收取维修/配件费短信通知商家
                            JSONObject param = new JSONObject();
                            param.put("orderindex", order.getOrderIndex());
                            param.put("maintenance_amount", order.getMaintenanceAmount());
                            log.warn("收取维修/配件费短信通知商家--短信发送参数:" + JSONObject.toJSONString(param));
                            log.warn("收取维修/配件费短信通知商家--短信接收手机号:" + merchantByMerchantId.getMerchantPhone());
                            SendSmsResponse sendSmsResponse = smsUtil.sendSms(merchantByMerchantId.getMerchantPhone(), param, AliTemplateCode.ORDER_CHARGE_MAINTENANCE_OR_PARTS_FEE_NOTIFY_MERCHANT_CODE);
                            log.warn("收取维修/配件费短信通知商家--短信返回结果:" + JSONObject.toJSONString(sendSmsResponse));
                        } else {
                            log.error("支付回调收取维修/配件费发送短信通知--未查询到商家信息!订单编号orderIndex=" + order.getOrderIndex());
                        }
                    } catch (Exception e) {
                        log.error("支付回调--收取维修/配件费短信通知发送失败!错误信息error=" + e.getMessage());
                    }
                    log.info("支付回调 -- success");
                    return "success";
                }
            }

            //平台抽成百分比
            BigDecimal percaent = new BigDecimal(sysConfigMapper.checkConfigKeyUnique("platform.commission.rate").getConfigValue());
            BigDecimal shopAmount= order.getTotalAmount().subtract(order.getTotalAmount().multiply(percaent).divide(new BigDecimal(100),2, ROUND_HALF_UP));
            //支付成功后
            order.setUpdateTime(LocalDateTime.now());
            order.setOrderState("001");
            order.setShopAmount(shopAmount);
            order.setIsSettle(1);
            if(orderMapper.updateOrderCustom(order)<0){
                log.error("支付回调 -- 更新订单信息失败");
                throw new ServiceException("更新订单信息失败");
            }
            //根据订单id查询最近一条订单记录数据
            OrderRecord orderRecord = orderRecordService.selectRefunfd(order.getOrderId());
            OrderRecord record = new OrderRecord();
            if (!ObjectUtils.isEmpty(orderRecord)) {
                record.setPreState(orderRecord.getNowState());
            }
            record.setOrderId(order.getOrderId());
            record.setNowState("001");
            record.setOperateInfo(sysCodeService.getDecodeValue("003", "001"));
            if (orderRecordService.insertOrderRecord(record) < 1) {
                log.error("支付回调 -- 添加订单追踪信息失败");
                throw new ServiceException("添加订单追踪信息失败");
            }

            try {
                log.warn("支付成功回调--订单类型:" + order.getOrderType());
                // 预订和维修服务支付完成后生成门岗通行证
                if ("001".equals(order.getOrderType()) || "002".equals(order.getOrderType())) {
                    log.warn("...支付成功回调生成门岗二维码业务处理--开始...");
                    AccessPasscodeParam accessPasscodeParam = new AccessPasscodeParam();
                    accessPasscodeParam.setOrderId(order.getOrderId());
                    accessPasscodeParam.setOrderIndex(order.getOrderIndex());
                    accessPasscodeParam.setMerchantId(order.getMerchantId());
                    accessPasscodeParam.setMemberId(order.getMemberId());
                    merchantAccessPasscodeService.saveAccessPasscode(accessPasscodeParam);
                    log.warn("...支付成功回调生成门岗二维码业务处理--结束...");
                }
            } catch (Exception e) {
                log.error("会员预订和维修服务订单支付成功-生成门岗通行证失败!orderId=" + order.getOrderId());
                e.printStackTrace();
            }

            try {
                // 判断订单是否使用优金豆
                if (order.getBeanAmount() != null && order.getBeanAmount() > 0) {
                    //查询商家信息
                    Merchant merchant = merchantMapper.selectMerchantByMerchantId(order.getMerchantId());
                    if (ObjectUtils.isEmpty(merchant)) {
                        throw new GlobalException("商家不存在");
                    }
                    UjdChangeRecord ujdChangeRecord = new UjdChangeRecord();
                    //查询服务数据
                    Goods goods = goodsMapper.selectOrderId(orderId);
                    if (!ObjectUtils.isEmpty(goods)) {
                        ujdChangeRecord.setGoodsId(goods.getGoodsId());
                        ujdChangeRecord.setGoodsIndex(goods == null ? "-" : goods.getGoodsIndex());
                        ujdChangeRecord.setGoodsName(goods == null ? "-" : goods.getName());
                    }
                    //商家增加保证金
                    // 增加优金豆变动记录
                    ujdChangeRecord.setChangeQty(order.getBeanAmount());
                    ujdChangeRecord.setChangeType(UjdChangeTypeEnum.MEMBER_USE_UJD_MAKE_ORDER.getCode());
                    ujdChangeRecord.setChangeProperty("1");
                    ujdChangeRecord.setChangeTime(LocalDateTime.now());
                    ujdChangeRecord.setMerchantId(merchant.getMerchantId());
                    ujdChangeRecord.setMerchantIndex(com.younike.common.utils.StringUtils.isEmpty(merchant.getMerchantIndex()) ? "-" : merchant.getMerchantIndex());
                    ujdChangeRecord.setMerchantName(merchant.getMerchantName());
                    ujdChangeRecord.setTradeNo(order.getOrderIndex());

                    // 个人商家，查询用户名称
                    if (Objects.equals(merchant.getMerchantType(), 1)) {
                        SysUser sysUser = sysUserService.selectSysUserById(merchant.getAdminId());
                        ujdChangeRecord.setMerchantName(sysUser == null ? "-" : sysUser.getNickName());
                    }
                    int ujdChangeRecordInsertResult = ujdChangeRecordMapper.insertUjdChangeRecord(ujdChangeRecord);
                    if (ujdChangeRecordInsertResult <= 0) {
                        log.error("会员订单支付成功-优金豆变动记录保存失败!ujdChangeRecord=" + JSON.toJSONString(ujdChangeRecord));
                    }
                    // 更新商家优金豆数量
                    BigDecimal bigDecimal = new BigDecimal(Integer.parseInt(order.getBeanAmount().toString())).divide(new BigDecimal("100"));
                    if (ObjectUtils.isEmpty(merchant.getBondMoney())) {
                        merchant.setBondMoney(bigDecimal);
                    } else {
                        merchant.setBondMoney(merchant.getBondMoney().add(bigDecimal));
                    }
                    int updateMerchant = merchantService.updateMerchant(merchant);
                    if (updateMerchant < 1) {
                        log.error("订单支付回调 -- 更新商家保证金失败");
                    }
                }
            } catch (Exception e) {
                log.error("订单支付回调 -- 增加优金豆变动记录及更新商家保证金出现错误");
                log.error("错误信息 -- " + e.getMessage());
                e.printStackTrace();
            }

            // 发送短信通知
            try {
                // 查询订单商品信息
                OrderGoods orderGoods = orderGoodsMapper.selectOrderGoodsByOrderId(order.getOrderId());
                if (ObjectUtils.isEmpty(orderGoods))  {
                    log.error("支付回调发送短信通知--未查询到订单商品信息，订单编号orderIndex=" + order.getOrderIndex());
                } else {
                    // 查询商品分类名称
                    if (!Objects.isNull(orderGoods.getCateId())) {
                        // 服务类型
                        String serviceType = StringUtils.EMPTY;
                        Category category = categoryMapper.selectCategoryByCategoryId(orderGoods.getCateId());
                        serviceType = category == null || StringUtils.isBlank(category.getCategoryName()) ? null : category.getCategoryName();
                        if (!Objects.isNull(category) && !Objects.isNull(category.getParentId())) {
                            // 查询父级分类名称
                            Category parentCategory = categoryMapper.selectCategoryByCategoryId(Long.valueOf(category.getParentId()));
                            serviceType = parentCategory == null || StringUtils.isBlank(parentCategory.getCategoryName()) ? serviceType : serviceType + "-" + parentCategory.getCategoryName();
                        }
                        // 查询服务人员信息
                        ServerUserListVo serverUser = serverUserService.getByServerId(orderGoods.getServerId());
                        // 查询订单商家信息
                        Merchant merchantByMerchantId = merchantService.getMerchantByMerchantId(order.getMerchantId());

                        // 团购服务订单短信通知商家
                        if ("003".equals(order.getOrderType())) {
                            log.info("...进入团购服务订单短信通知商家...");
                            if (merchantByMerchantId != null) {
                                JSONObject param = new JSONObject();
                                param.put("servicetype", serviceType);
                                log.warn("团购服务订单短信通知商家--短信发送参数:" + JSONObject.toJSONString(param));
                                log.warn("团购服务订单短信通知商家--短信接收手机号:" + merchantByMerchantId.getMerchantPhone());
                                SendSmsResponse sendSmsResponse = smsUtil.sendSms(merchantByMerchantId.getMerchantPhone(), param, AliTemplateCode.MEMBER_MAKE_GROUP_ORDER_NOTIFY_MERCHANT_CODE);
                                log.warn("团购服务订单短信通知商家--短信返回结果" + JSON.toJSONString(sendSmsResponse));
                            } else {
                                log.error("支付回调团购服务订单短信通知商家--未查询到商家信息!订单编号orderIndex=" + order.getOrderIndex());
                            }
                        }
                        // 预订服务订单短信通知
                        if ("001".equals(order.getOrderType()) || "002".equals(order.getOrderType())) {
                            log.info("...进入预订服务订单短信通知...");
                            if (merchantByMerchantId != null) {
                                log.info("...进入预订服务订单短信通知商家...");
                                // 预订服务订单短信通知商家
                                JSONObject param = new JSONObject();
                                param.put("servicetype", serviceType);
                                param.put("staff", serverUser == null ? StringUtils.EMPTY : serverUser.getNikeName());
                                param.put("phone", serverUser == null ? StringUtils.EMPTY : serverUser.getPhone());
                                param.put("ordertime", DateUtil.formatDate(DateUtil.localDateTimeToDate(order.getAppointmentStartTime()), "yyyy-MM-dd HH:mm"));
                                log.warn("预订服务订单短信通知商家--短信发送参数:" + JSONObject.toJSONString(param));
                                log.warn("预订服务订单短信通知商家--短信接收手机号:" + merchantByMerchantId.getMerchantPhone());
                                SendSmsResponse sendSmsResponse = smsUtil.sendSms(merchantByMerchantId.getMerchantPhone(), param, AliTemplateCode.MEMBER_MAKE_ORDER_NOTIFY_MERCHANT_CODE);
                                log.warn("预订服务订单短信通知商家--短信返回结果" + JSON.toJSONString(sendSmsResponse));
                            } else {
                                log.error("支付回调预订服务订单短信通知商家--未查询到商家信息!订单编号orderIndex=" + order.getOrderIndex());
                            }

                            // 预订服务订单短信通知服务人员
                            if (serverUser != null && StringUtils.isNotBlank(serverUser.getPhone())) {
                                log.info("...进入预订服务订单短信通知服务人员...");
                                JSONObject jsonParam = new JSONObject();
                                jsonParam.put("servicetype", serviceType);
                                jsonParam.put("ordertime", DateUtil.formatDate(DateUtil.localDateTimeToDate(order.getAppointmentStartTime()), "yyyy-MM-dd HH:mm"));
                                log.warn("预订服务订单短信通知服务人员--短信发送参数:" + JSONObject.toJSONString(jsonParam));
                                log.warn("预订服务订单短信通知服务人员--短信接收手机号:" + serverUser.getPhone());
                                SendSmsResponse sendSmsResponse = smsUtil.sendSms(serverUser.getPhone(), jsonParam, AliTemplateCode.MEMBER_MAKE_ORDER_NOTIFY_SERVER_USER_CODE);
                                log.warn("预订服务订单短信通知服务人员--短信返回结果" + JSON.toJSONString(sendSmsResponse));
                            } else {
                                log.error("支付回调预订服务订单短信通知服务人员--未查询到商家服务人员信息!服务人员ID=" + orderGoods.getServerId());
                            }
                        }
                    } else {
                        log.error("支付回调发送短信通知--未查询到订单商品分类ID信息，分类cateId=" + orderGoods.getCateId());
                    }
                }
            } catch (Exception e) {
                log.error("支付回调--短信通知发送失败!错误信息error=" + e.getMessage());
            }

            log.info("支付回调 -- success");
            return "success";
        }
        log.error("支付回调 -- 验证签名失败");
        return "failed";
    }

    /**
     * 查询会员订单查询追加服务支付结果
     * @param orderId
     * @return
     */
    @Override
    public AjaxResult addServerCb(Long orderId) {
        Order order = orderMapper.selectOrderId(orderId);

        if(ObjectUtils.isEmpty(order)){
            return AjaxResult.success("订单不存在",false);
        }
        if(order.getAddPayStatus() == null || order.getAddPayStatus()==0){
            return AjaxResult.success("待支付",true);
        }
        return AjaxResult.success("订单已支付",false);
    }

    /**
     * 查询会员端未支付订单分页列表
     *
     * @param orderState
     * @return
     */
    @Override
    public List<Order> listMemberOrderOfPendingPayment(String orderState) {
        return orderMapper.listMemberOrderOfPendingPayment(orderState);
    }

    /**
     * 查询会员端待确认订单列表
     *
     * @param orderState
     * @return
     */
    @Override
    public List<Order> listMemberOrderOfPendingConfirm(String orderState) {
        return orderMapper.listMemberOrderOfPendingConfirm(orderState);
    }

    /**
     * 更新订单状态
     *
     * @param orderList
     */
    @Override
    public void updateOrderState(List<Order> orderList) {
        orderMapper.updateOrderState(orderList);
    }
    /**
     * 发布需求：预约提交订单
     * @param param
     * @return
     */
    @Override
    @Transactional
    public AjaxResult addPublishOrder(OrderPublishParam param) {

        //根据需求id查询需求
        Publish publish = publishService.selectPublishByPublishId(param.getPublishId());
        //需求id不为空
           if(ObjectUtils.isEmpty(publish)){
               throw new ArithmeticException("需求不存在");
           }
        //判断发布状态是否为待预约
        if(!"001".equals(publish.getPublishState())){
            throw new ArithmeticException("当前需求不可预约");
        }
        //根据需求id查服务地址
       MemberAddress memberAddress = memberAddressMapper.selectMemberAddressByPublishId(param.getPublishId());
        if(ObjectUtils.isEmpty(memberAddress)){
            throw new ArithmeticException("服务地址不存在");
        }
        //根据需求id查询需求资源数据
        PublishImage publishImage = new PublishImage();
        publishImage.setPublishId(param.getPublishId());
        List<PublishImage> publishImageList = publishImageService.selectPublishImageList(publishImage);
         //根据报价id查询报价数据
        PublishQuote publishQuote = publishQuoteService.selectPublishQuoteByQuoteId(param.getQuoteId());
        if(ObjectUtils.isEmpty(publishQuote)){
            throw new ArithmeticException("报价不存在");
        }
        //查询商家数据
        Merchant merchant = merchantService.selectMerchantByMerchantId(publishQuote.getMerchantId());
        if (ObjectUtils.isEmpty(merchant)) {
            //抛出异常
            throw new ArithmeticException("商家不存在");
        }
        //商家与会员距离
        BigDecimal shortestDistance = null;
        // 计算距离
        shortestDistance = DistanceUtil.getShortestDistance( merchant.getLatitude(), merchant.getLongitude(),memberAddress.getLatitude(),
                memberAddress.getLongitude());

        BigDecimal maxDeliverDistance =null;
        if(merchant.getServiceDistance()==null){
            maxDeliverDistance = new BigDecimal(sysConfigMapper.checkConfigKeyUnique("home.server.distance").getConfigValue());

        }else {
            maxDeliverDistance  = new BigDecimal(String.valueOf(merchant.getServiceDistance()));
        }

        //验证坐标是否超出范围
        if(shortestDistance.compareTo(maxDeliverDistance)>0){
            //超出配送范围
            throw new ArithmeticException("下单失败订单地址超出服务范围");
        }

        //服务总时长为  total_time.getTotalTime
        BigDecimal multiply=publishQuote.getTotalTime();

        // 记录预约信息
        LocalDateTime appointmentEndTime = this.recordAppointmentInfo(param.getAppointmentStartTime(), multiply, publishQuote.getServerUserId(), merchant.getAllowCompose());

        //查询服务人员预约参数
        OrderParam orderParam = new OrderParam();
        orderParam.setAppointmentEndTime(param.getAppointmentEndTime());
        orderParam.setAppointmentStartTime(appointmentEndTime);
        orderParam.setServerId(publishQuote.getServerUserId());

        //创建商品
        Goods goods= new Goods();
        //店铺id为服务人员店铺id
        goods.setMerchantId(publishQuote.getMerchantId());
        //分类id为发布需求分类id
        goods.setCateId(publish.getCateId());
        goods.setName(publish.getName());
        //服务内容为商品描述
        goods.setGoodsIndex(GoodsIndexGenerate.getGoodsIndex());
        goods.setServiceDesc(publish.getPublishDesc());
        goods.setGoodsUnit(publishQuote.getQuoteUnit());
        goods.setOtherUnit(publishQuote.getOtherUnit());
        goods.setSingleTime(publishQuote.getSingleTime());
        //是否上架 0未上架 1已上架 2已售完
        goods.setIsSale(2);
        goods.setOneOff(1);
        goods.setCreateTime(LocalDateTime.now());
       if(goodsMapper.insertGoods(goods)<1){
           throw new ArithmeticException("创建商品失败");
       }
       //判断需求资源是否为空
       if(!ObjectUtils.isEmpty(publishImageList) && publishImageList.size()>0){
           List<GoodsImage> goodsImages = new ArrayList<>();

           publishImageList.forEach( image -> {
               //只存储图片资源
               if("001".equals(image.getType())) {
                   GoodsImage goodsImage = new GoodsImage();
                   BeanUtils.copyProperties(image, goodsImage);
                   goodsImage.setGoodsId(String.valueOf(goods.getGoodsId()));
                   goodsImages.add(goodsImage);
               }
           });
           //批量添加数据
           if (goodsImages.size() > 0) {
               goodsImageService.insertBatch(goodsImages);
           }

       }

       //添加商品服务人员信息数据
        GoodsServer goodsServer = new GoodsServer();
       goodsServer.setGoodsId(goods.getGoodsId());
       goodsServer.setServerId(publishQuote.getServerUserId());
       goodsServer.setGoodsServerPrice(publishQuote.getSinglePrice());
       goodsServer.setCreateTime(LocalDateTime.now());
       if(goodsServerService.insertGoodsServer(goodsServer)<1){
           throw new ArithmeticException("创建商品服务人员信息失败");
       }

        Order order = new Order();
        BeanUtils.copyProperties(param, order);
        //用户
        order.setMemberId(publish.getMemberId());
        order.setMerchantId(merchant.getMerchantId());
        order.setMerchantName(merchant.getMerchantName());
        order.setCreateTime(LocalDateTime.now());
        // 生成订单id
        Long orderId = IDUtils.nextLongId();
        order.setOrderId(orderId);
        // 生成订单编号
        order.setOrderIndex(redisCache.getOrderIndexByRedis());
        //订单状态
        order.setOrderState(OrderStateEnum.PENDING_PAYMENT.getCode());
        // 评价状态
        order.setCommentState(CommentStateEnum.PENDING_COMMENT.getCode());
        //订单类型
        //根据分类id查询
        Category category = categoryMapper.selectCategoryByCategoryId(publish.getCateId());
        if(ObjectUtils.isEmpty(category)){
            throw new ArithmeticException("分类不存在");
        }
        if(category.getBizType() == 1){
            order.setOrderType("001");
        }
        if(category.getBizType() == 2){
            order.setOrderType("002");
        }

        //平台抽成百分比
        BigDecimal percentage = new BigDecimal(sysConfigMapper.checkConfigKeyUnique("platform.commission.rate").getConfigValue());
        //商家可得到 实付总价减去平台抽成
        BigDecimal shopAmount= param.getTotalAmount()
                .subtract(
                        param.getTotalAmount().multiply(percentage)
                                .divide(new BigDecimal(100),2, ROUND_HALF_UP));
        // 判断优金豆抵扣金额(使用优金豆的抵扣金额已经加到商家保证金里，此处不再重复计算店铺可得2022.04.02)
//        if (order.getBeanAmount() != null) {
//            shopAmount.add(new BigDecimal(order.getBeanAmount()).divide(new BigDecimal(100)));
//        }
        order.setShopAmount(shopAmount);
        log.warn("发布任务预约下单-店铺可得金额:" + shopAmount);
        //预约结束时间
        order.setAppointmentEndTime(param.getAppointmentStartTime().plusMinutes((long)(multiply.doubleValue() * 60)));
        if (orderMapper.addOrder(order) < 1) {
            throw new ArithmeticException("添加订单失败");
        }
//        //生成订单编号
//        String index = OrderIndexGenerate.getIndexByOrderId(order.getOrderId());
//        //更新数据
//        order.setOrderIndex(index);
//        order.setUpdateTime(LocalDateTime.now());
//        if (orderMapper.updateOrderCustom(order) < 1) {
//            throw new ArithmeticException("更新订单编号失败");
//        }

        //订单服务地址表
        OrderAddress orderAddress = new OrderAddress();
        BeanUtils.copyProperties(memberAddress, orderAddress);
        orderAddress.setCreateTime(LocalDateTime.now());
        orderAddress.setUpdateTime(LocalDateTime.now());
        orderAddress.setOrderId(order.getOrderId());
        orderAddress.setAddressLongitude(memberAddress.getLongitude());
        orderAddress.setAddressLatitude(memberAddress.getLatitude());
        if (orderAddressMapper.insertOrderAddress(orderAddress) < 1) {
            throw new ArithmeticException("添加订单服务地址表失败");
        }

        //order_goods 订单商品添加数据
        OrderGoods orderGoods = new OrderGoods();
        BeanUtils.copyProperties(goods, orderGoods);
        orderGoods.setOrderId(order.getOrderId());
        orderGoods.setServerId(publishQuote.getServerUserId());
        orderGoods.setGoodsCounts(publishQuote.getQuoteCounts());
        orderGoods.setPrice(publishQuote.getSinglePrice());
        orderGoods.setCreateTime(LocalDateTime.now());
        orderGoods.setUpdateTime(LocalDateTime.now());
        orderGoods.setPublishId(param.getPublishId());
        if (orderGoodsMapper.insertOrderGoods(orderGoods) < 1) {
            throw new ArithmeticException("添加订单商品失败");
        }

        //查询服务人员数据
        ServerUser serverUser = serverUserService.selectServerUserByServerId(publishQuote.getServerUserId());
        if (ObjectUtils.isEmpty(serverUser)) {
            throw new ArithmeticException("服务人员不存在");
        }
        //order_goodes_server 订单服务人员添加数据
        OrderGoodsServer orderGoodsServer = new OrderGoodsServer();
        //订单id
        orderGoodsServer.setOrderId(order.getOrderId());
        //服务人员id
        orderGoodsServer.setServerId(publishQuote.getServerUserId());
        //单次服务标准时长
        orderGoodsServer.setSingleTime(publishQuote.getSingleTime());
        //数量
        orderGoodsServer.setGoodsCounts(publishQuote.getQuoteCounts());
        //商品id
        orderGoodsServer.setGoodsId(goods.getGoodsId());
        //商品名称
        orderGoodsServer.setGoodsName(publish.getName());
        //商品服务人员单价
        orderGoodsServer.setGoodsServerPrice(publishQuote.getSinglePrice());
        //商品单位
        orderGoodsServer.setGoodsUnit(publishQuote.getQuoteUnit());
        //服务人员姓名
        orderGoodsServer.setServerName(serverUser.getNikeName());
        //服务人员性别
        orderGoodsServer.setServerSex(serverUser.getSex());
        //工龄
        orderGoodsServer.setServerAge(serverUser.getAge());
        //服务人员头像
        orderGoodsServer.setServerAvatar(serverUser.getAvatar());
        //所属商铺
        orderGoodsServer.setMerchantId(serverUser.getMerchantId().toString());
        //创建时间
        orderGoodsServer.setCreateTime(LocalDateTime.now());
        orderGoodsServer.setUpdateTime(LocalDateTime.now());
        if (orderGoodsServerService.insertOrderGoodsServer(orderGoodsServer) < 1) {
            throw new ArithmeticException("添加订单服务人员关联数据失败");
        }

        //order_record 添加订单记录
        OrderRecord orderRecord = new OrderRecord();
        orderRecord.setOrderId(order.getOrderId());
        orderRecord.setPreState("000");
        orderRecord.setNowState("000");
        orderRecord.setCreateTime(LocalDateTime.now());
        orderRecord.setUpdateTime(LocalDateTime.now());
        orderRecord.setOperateInfo(sysCodeService.getDecodeValue("003","000"));
        if (orderRecordService.insertOrderRecord(orderRecord) < 1) {
            throw new ArithmeticException("添加订单记录失败");
        }

        //发布需求表进行变更
        //发布状态
        publish.setPublishState("002");
        publish.setBidMerchantId(publishQuote.getMerchantId());
        publish.setBidServerUserId(publishQuote.getServerUserId());
        publish.setUpdateTime(LocalDateTime.now());
        if(publishService.updatePublish(publish)<1){
            throw new ArithmeticException("发布需求状态更改失败");
        }

        if(param.getGoodsCoin()!=null) {
            if(param.getGoodsCoin()>500){
                throw new ArithmeticException("优金豆使用不得超过500");
            }
            //如果使用优金豆或者优惠券，调用远程接口减少用户优金豆数量
            if (param.getGoodsCoin() > 0) {
                FamilyParam familyParam = new FamilyParam();
                familyParam.setNum(BigDecimal.valueOf(-param.getGoodsCoin()));
                familyParam.setPhone(param.getPhone());
                String jsonCode = coinService.increasePoints(familyParam);
                if (!jsonCode.equals("200")) {
                    throw new ArithmeticException("预约失败，优金豆扣除失败");
                }
            }
        }
        log.info("创建订单：未支付：" + order.getOrderId());
        rabbitTemplate.convertAndSend(AmqpDelayedConfig.EXCHANGE_NAME, AmqpDelayedConfig.QUEUE_NAME, PREFIX_NO_PAY_ORDER + order.getOrderId(), message -> {
            message.getMessageProperties().setHeader("x-delay", EXPIRE_TIME_MINUTES * 60 * 1000);
            log.info("创建订单：创建延迟消息：" + AmqpDelayedConfig.QUEUE_NAME);
            return message;
        });

        return AjaxResult.success(order);

    }

    @Override
    public OrderVo selectPublishInfo(Long orderId) {
        return orderMapper.selectPublishInfo(orderId);
    }

    /**
     * 收取维修配件费
     * @param param
     * @return
     */
    @Override
    @Transactional
    public AjaxResult maintenanceServer(OrderParam param) {
        //根据订单id查询订单数据
        Order order = orderMapper.selectOrderByOrderId(param.getOrderId());
        if(ObjectUtils.isEmpty(order)){
            throw new ArithmeticException("订单不存在");
        }
        if(!"002".equals(order.getOrderType())){
            throw new ArithmeticException("订单非维修订单，不可进行收取维修配件费用");
        }
        if(order.getMaintenanceAmount() != null){
            throw new ArithmeticException("不可重复进行收取维修配件费用");
        }
        //维修配件费金额与追加服务费金额相同
        order.setAddAmount(param.getMaintenanceAmount());
        //平台抽成百分比
        BigDecimal percaent = new BigDecimal(sysConfigMapper.checkConfigKeyUnique("platform.commission.rate").getConfigValue());
        //商家可得追加服务金额
        BigDecimal addShopAmount= order.getAddAmount().subtract(order.getAddAmount().multiply(percaent).divide(new BigDecimal(100),2, ROUND_HALF_UP));
        order.setUpdateTime(LocalDateTime.now());
        order.setAddShopAmount(addShopAmount);
        order.setMaintenanceAmount(param.getMaintenanceAmount());
        order.setMaintenanceRemark(param.getMaintenanceRemark());
        order.setAddPayStatus(0);

       if(orderMapper.updateOrderCustom(order)<1){
           throw new ArithmeticException("收取维修配件费失败");
       }

        //订单变更记录
        //根据订单id查询最近一条订单记录数据
        OrderRecord orderRecord = orderRecordService.selectRefunfd(order.getOrderId());
        OrderRecord record = new OrderRecord();
        if(!ObjectUtils.isEmpty(orderRecord)){
            record.setPreState(orderRecord.getNowState());
            record.setNowState(orderRecord.getNowState());
        }
        record.setOrderId(order.getOrderId());
        record.setOperateInfo("收取维修/配件费");
        if(orderRecordService.insertOrderRecord(record)<1){
            throw new ArithmeticException("添加订单追踪信息失败");
        }
        return AjaxResult.success();
    }

    /**
     * 支付维修配件费
     * @param param
     * @return
     */
    @Override
    public AjaxResult addMaintenanceServer(OrderParam param) {
        PaymentDto paymentDto = new PaymentDto();
        // 查询支付支付串
        OrderPayment orderPayment = orderPaymentService.selectOrderPaymentByOrderId(param.getOrderId());
        log.warn("支付字符串--wx-> " + orderPayment.getWxAddPayStr() + "--ali-> " + orderPayment.getAliAddPayStr());
//        if (orderPayment != null) {
//            // 支付方式code(001微信，002支付宝)
//            if ("001".equals(param.getPayWay()) && orderPayment.getWxAddPayStr() != null) {
//                paymentDto.setPayInfo(orderPayment.getWxAddPayStr());
//                return AjaxResult.success(paymentDto);
//            }
//
//            if ("002".equals(param.getPayWay()) && orderPayment.getAliAddPayStr() != null) {
//                paymentDto.setPayInfo(orderPayment.getAliAddPayStr());
//                return AjaxResult.success(paymentDto);
//            }
//        }
        String qrcode = null;
        //回调付款参数
        PaymentParam paymentParam = new PaymentParam();
        paymentParam.setOrderId(param.getOrderId());
        //根据订单id查询订单数据
        MemberOrderDetailVo order = orderMapper.getMemberOrderByOrderId(param.getOrderId());
        if(ObjectUtils.isEmpty(order)){
            return AjaxResult.error("订单不存在");
        }
        //平台抽成百分比
        BigDecimal percentage = new BigDecimal(sysConfigMapper.checkConfigKeyUnique("platform.commission.rate").getConfigValue());
        //商家可得到 实付总价减去平台抽成
        BigDecimal addShopAmount= order.getAddAmount()
                .subtract(
                        order.getAddAmount().multiply(percentage)
                                .divide(new BigDecimal(100),2, ROUND_HALF_UP));
        //支付价格
        paymentParam.setTotalAmount(order.getMaintenanceAmount());
        //订单支付标志
        paymentParam.setAddType(1);
        // 2022年2月17日 新增参数
        paymentParam.setBizType(param.getBizType());
        paymentParam.setPayType(param.getPayType());
        paymentParam.setShopAmount(addShopAmount);
        //追加服务次数
        if (orderPayment == null ) {
            paymentParam.setAddCountIndex(0);
        } else {
            paymentParam.setAddCountIndex(orderPayment.getAddCountIndex()+1);
        }

        //查询订单商品的商家信息
        Merchant merchant = merchantMapper.selectMerchantByMerchantId(order.getMerchantId());
        if(ObjectUtils.isEmpty(merchant)){
            return AjaxResult.error("商品商家不存在");
        }
        //商家
        if(merchant.getMerchantType().equals(0)){
            //查询商家合利宝邮箱
            MerchantSettleInfo merchantSettleInfo = settleInfoService.selectMerchantSettleInfoByMerchantId(merchant.getMerchantId());
            if(ObjectUtils.isEmpty(merchantSettleInfo)) {
                return AjaxResult.error("商品合利宝账户不存在");
            }
            //商家邮箱
            paymentParam.setEmail(merchantSettleInfo.getEmail());
        }
        paymentParam.setMerchantType(merchant.getMerchantType());
        OrderGoods orderGoods = orderGoodsMapper.selectOrderGoodsByOrderId(order.getOrderId());
        if(ObjectUtils.isEmpty(orderGoods)){
            throw new GlobalException("订单商品表不存在失败");
        }
        Order order1 = new Order();
        order1.setOrderId(order.getOrderId());
        order1.setAddPayWay(param.getAddPayWay());
        order1.setUpdateTime(LocalDateTime.now());
        order1.setAddShopAmount(addShopAmount);
        if (orderMapper.updateOrderCustom(order1) < 1) {
            throw new GlobalException("支付方式更新失败");
        }
        log.warn("payment-param--> " + JSONObject.toJSONString(paymentParam));
        // 进行支付 001微信 002支付宝
        if("001".equals(param.getAddPayWay()) && StringUtils.equals(param.getPayType(), PayType.APPLET.name())){
            // 获取用户openId
            String openId = getOpenId(param.getCode());
            if (StringUtils.isBlank(openId)) {
                return AjaxResult.error("微信支付OpenId获取异常");
            }
            Map<String, Object> resultMap = payService.hlbPay(paymentParam, openId);
            log.warn("wechat----> result--> " + resultMap);
            // 支付结果
            if (resultMap != null && (Integer) resultMap.get("statusCode") == HttpStatus.SC_OK) {
                String resultMsg = (String) resultMap.get("response");
                AppPayPublicOrderResponseVo orderResponseVo = JSONObject.parseObject(resultMsg, AppPayPublicOrderResponseVo.class);
                if (StringUtils.isBlank(orderResponseVo.getRt10_payInfo())) {
                    return AjaxResult.error(orderResponseVo.getRt3_retMsg());
                }
                paymentDto.setPayInfo(orderResponseVo.getRt10_payInfo());
                paymentDto.setSign(orderResponseVo.getSign());
                if (orderPayment == null ) {
                    orderPayment = new OrderPayment();
                    orderPayment.setOrderId(param.getOrderId());
                    orderPayment.setWxAddPayStr(orderResponseVo.getRt10_payInfo());
                    orderPayment.setAddCountIndex(0);
                    orderPaymentService.insertOrderPayment(orderPayment);
                } else {
                    orderPayment.setWxAddPayStr(orderResponseVo.getRt10_payInfo());
                    orderPayment.setAddCountIndex(orderPayment.getAddCountIndex()+1);
                    orderPaymentService.updateOrderPayment(orderPayment);
                }
                return AjaxResult.success(paymentDto);
            }
        } else if ("002".equals(param.getAddPayWay()) && StringUtils.equals(param.getPayType(), PayType.SDK.name())) {
            Map<String, Object> resultMap = payService.hlbPay(paymentParam, null);
            log.warn("ali--result--> " + resultMap);
            String resultMsg = (String) resultMap.get("response");
            CreateOrderResponseVo orderResponseVo = JSONObject.parseObject(resultMsg, CreateOrderResponseVo.class);
            qrcode = orderResponseVo.getRt8_qrcode();
            if (StringUtils.isBlank(qrcode)) {
                return AjaxResult.error(orderResponseVo.getRt3_retMsg());
            }
            paymentDto.setPayInfo(orderResponseVo.getRt8_qrcode());
            paymentDto.setSign(orderResponseVo.getSign());
            if (orderPayment == null ) {
                orderPayment = new OrderPayment();
                orderPayment.setOrderId(param.getOrderId());
                orderPayment.setAliAddPayStr(orderResponseVo.getRt8_qrcode());
                orderPayment.setAddCountIndex(0);
                orderPaymentService.insertOrderPayment(orderPayment);
            } else {
                orderPayment.setAliAddPayStr(orderResponseVo.getRt8_qrcode());
                orderPayment.setAddCountIndex(orderPayment.getAddCountIndex()+1);
                orderPaymentService.updateOrderPayment(orderPayment);
            }
            return AjaxResult.success(paymentDto);
        }
        return AjaxResult.error("支付方式不正确");
    }

    /**
     * 取消收取维修配件费
     * @param param
     * @return
     */
    @Override
    public AjaxResult cancelMaintenanceServer(OrderParam param) {
        //根据订单id查询数据
        Order order = orderMapper.selectOrderByOrderId(param.getOrderId());
        if(ObjectUtils.isEmpty(order)){
            return AjaxResult.error("订单不存在");
        }
        if(!"002".equals(order.getOrderType())){
            return AjaxResult.error("非维修订单，无配件费");
        }
        if(ObjectUtils.isEmpty(order.getAddPayStatus()) || order.getAddPayStatus()== 0) {

            //更新order数据
            order.setUpdateTime(LocalDateTime.now());
            if (orderMapper.cancelMaintenanceServer(order) < 1) {
                throw new GlobalException("取消收费失败");
            }
            //查询最新订单变更记录
            //订单变更记录
            //根据订单id查询最近一条订单记录数据
            OrderRecord orderRecord = orderRecordService.selectRefunfd(order.getOrderId());
            OrderRecord record = new OrderRecord();
            if (!ObjectUtils.isEmpty(orderRecord)) {
                record.setPreState(orderRecord.getNowState());
                record.setNowState(orderRecord.getNowState());
            }
            record.setOrderId(order.getOrderId());
            record.setOperateInfo("取消收取维修/配件费");
            if (orderRecordService.insertOrderRecord(record) < 1) {
                throw new GlobalException("添加订单追踪信息失败");
            }
            return AjaxResult.success();
        }
        return AjaxResult.error("维修配件费已经付款，不可取消");
    }

    /**
     * 查询个体户结算订单信息
     *
     * @param settleStartDate
     * @param settleEndDate
     * @return
     */
    @Override
    public Map<Long, List<Order>> listPersonalMerchantSettleOrder(LocalDate settleStartDate, LocalDate settleEndDate) {
        List<Order> orderList = orderMapper.listPersonalMerchantSettleOrder(settleStartDate, settleEndDate);
        if (CollectionUtils.isNotEmpty(orderList)) {
            return orderList.stream().collect(Collectors.groupingBy(Order::getMerchantId));
        }
        return null;
    }

    /*
     * 查询预定订单结算信息
     * @param settleStartDate
     * @param settleEndDate
     * @return
     */
    @Override
    public Map<Long, List<Order>> listMerchantReserveSettleOrder(LocalDate settleStartDate, LocalDate settleEndDate) {
        List<Order> orderList = orderMapper.listMerchantReserveSettleOrder(settleStartDate, settleEndDate);
        if (CollectionUtils.isNotEmpty(orderList)) {
            return orderList.stream().collect(Collectors.groupingBy(Order::getMerchantId));
        }
        return null;
    }

    /**
     * 根据服务id查询是否有订单非已取消与已退款状态
     *
     * @param goodsId
     * @return
     */
    @Override
    public List<Order> adminDeleteGoods(Long goodsId) {
        return orderMapper.adminDeleteGoods(goodsId);
    }

    /**
     * 根据服务人员id查询服务人员是否有未完成的订单
     *
     * @param serverIds
     * @return
     */
    @Override
    public List<Order> merchanServerUserId(Long[] serverIds) {
        return orderMapper.merchanServerUserId(serverIds);
    }

    /**
     * 团购服务：预约提交订单
     *
     * @param param
     * @return
     */
    @Override
    @Transactional
    public AjaxResult addGroupOrder(OrderGroupParam param) {
        // 查询验证服务数据
        Goods goods = goodsMapper.selectGoodsByGoodsId(param.getGoodsId());
        if (ObjectUtils.isEmpty(goods)) {
            throw new ArithmeticException("商品不存在");
        }
        if (goods.getIsSale() == 2) {
            throw new ArithmeticException("商品已售空");
        }
        if (goods.getIsSale() == 0) {
            throw new ArithmeticException("商品未上架");
        }

        // 判断商品是否限购
        if (goods.getMaxNum() > 0) {
            // 查询该用户购买该服务的次数
            List<Order> list = orderMapper.getCountOrder(param);
            if (list.size() >= goods.getMaxNum()) {
                throw new ArithmeticException("限购商品超出限购数量，不可下单");
            }
        }

        Merchant merchant = merchantService.selectMerchantByMerchantId(param.getMerchantId());
        if (ObjectUtils.isEmpty(merchant)) {
            //抛出异常
            throw new ArithmeticException("商家不存在");
        }
        //根据地址id查询地址数据
        MemberAddress memberAddress = memberAddressMapper.selectMemberAddressByAddressId(param.getAddressId());
        if (ObjectUtils.isEmpty(memberAddress)) {
            //抛出异常
            throw new ArithmeticException("没有此会员地址");
        }
        //商家与会员距离
        BigDecimal shortestDistance = null;
        // 计算距离
        shortestDistance = DistanceUtil.getShortestDistance(merchant.getLatitude(), merchant.getLongitude(), memberAddress.getLatitude(),
                memberAddress.getLongitude());

        //最大配送距离
        BigDecimal maxDeliverDistance = null;
        if (merchant.getServiceDistance() == null) {
            maxDeliverDistance = new BigDecimal(sysConfigMapper.checkConfigKeyUnique("home.server.distance").getConfigValue());

        } else {
            maxDeliverDistance = new BigDecimal(String.valueOf(merchant.getServiceDistance()));
        }
        //验证坐标是否超出范围
        if (shortestDistance.compareTo(maxDeliverDistance) > 0) {
            //超出配送范围
            throw new ArithmeticException("下单失败订单地址超出服务范围");
        }

        // 查询服务规格信息
        GoodsSpecification goodsSpecification = iGoodsSpecificationService.selectGoodsSpecificationByGoodsSpecificationId(param.getGoodsSpecificationId());
        if (ObjectUtils.isEmpty(goodsSpecification)) {
            throw new ArithmeticException("服务规格不存在，请重新下单");
        }
        if (!param.getGoodsId().equals(goodsSpecification.getGoodsId())) {
            throw new ArithmeticException("服务规格不存在，请重新下单");
        }

        // 使用优金豆抵扣（用户抵扣的优金豆在支付完成时会增加到商家的保证金里2022.04.02）
        if (param.getBeanAmount() != null) {
            if (param.getBeanAmount() > 500) {
                throw new ArithmeticException("优金豆使用不得超过500");
            }
            //如果使用优金豆或者优惠券，调用远程接口减少用户优金豆数量
            if (param.getBeanAmount() > 0) {
                FamilyParam familyParam = new FamilyParam();
                familyParam.setNum(BigDecimal.valueOf(-param.getBeanAmount()));
                familyParam.setPhone(param.getPhone());
                String jsonCode = coinService.increasePoints(familyParam);
                if (!jsonCode.equals("200")) {
                    throw new ArithmeticException("预约失败，优金豆扣除失败");
                }
            }
            // 优惠金额(指的是优惠券金额，暂时没使用到优惠券，所以无优惠金额逻辑 2022.04.02)
//            BigDecimal coupoAmount = new BigDecimal(param.getBeanAmount()).divide(new BigDecimal(100));
//            order.setCouponAmount(coupoAmount);
        }

        // 构建订单对象
        Order order = new Order();
        BeanUtils.copyProperties(param, order);
        // 生成订单id
        Long oederId = IDUtils.nextLongId();
        order.setOrderId(oederId);
        // 生成订单编号
        order.setOrderIndex(redisCache.getOrderIndexByRedis());
        order.setMerchantName(merchant.getMerchantName());
        order.setOrderType("003");
        order.setOrderState(OrderStateEnum.PENDING_PAYMENT.getCode());
        order.setCommentState(CommentStateEnum.PENDING_COMMENT.getCode());
        order.setOrderAmount(goodsSpecification.getCurrentPrice());
        // 实际支付金额
        BigDecimal totalAmount = order.getOrderAmount();
        // 若存在优惠金额
        if (order.getCouponAmount() != null && order.getCouponAmount().compareTo(BigDecimal.ZERO) > 0) {
            totalAmount = totalAmount.subtract(order.getCouponAmount()).setScale(2, ROUND_HALF_UP);
        }
        // 若存在优金豆抵扣金额
        if (order.getBeanAmount() != null && order.getBeanAmount() > 0) {
            totalAmount = totalAmount.subtract(BigDecimal.valueOf(order.getBeanAmount()).divide(BigDecimal.valueOf(100)).setScale(2));
        }
        order.setTotalAmount(totalAmount);
        // 有效期（当前时间加上有效期天+1）
        if(goods.getExpirationDateValue() > 0) {
            order.setVerificationCodeEffectiveDate(LocalDateTime.now().plusDays(goods.getExpirationDateValue()));
        }
        //生成订单核销码 order_verification_code
        order.setOrderVerificationCode(RandomCodeGenerate.getOrderVerificationCode());

        order.setGroupTimes(goodsSpecification.getTimes());
        order.setGroupRemainingTimes(goodsSpecification.getTimes());
        order.setCreateTime(LocalDateTime.now());
        order.setUpdateTime(LocalDateTime.now());
        //分账数据计算
        this.calculateShopAmount(order);
        log.warn("团购下单-店铺可得金额:" + order.getShopAmount());

        if (orderMapper.insertOrder(order) < 1) {
            throw new ArithmeticException("创建订单失败");
        }
//        //生成订单编号
//        String index = OrderIndexGenerate.getIndexByOrderId(order.getOrderId());
//        //更新数据
//        order.setOrderIndex(index);
//        order.setUpdateTime(LocalDateTime.now());
//        if (orderMapper.updateOrderCustom(order) < 1) {
//            throw new ArithmeticException("更新订单编号失败");
//        }

        //订单服务地址表
        OrderAddress orderAddress = new OrderAddress();
        BeanUtils.copyProperties(memberAddress, orderAddress);
        orderAddress.setCreateTime(LocalDateTime.now());
        orderAddress.setUpdateTime(LocalDateTime.now());
        orderAddress.setOrderId(order.getOrderId());
        orderAddress.setAddressLongitude(memberAddress.getLongitude());
        orderAddress.setAddressLatitude(memberAddress.getLatitude());
        if (orderAddressMapper.insertOrderAddress(orderAddress) < 1) {
            throw new ArithmeticException("添加订单服务地址表失败");
        }

        //order_goods 订单商品添加数据
        OrderGoods orderGoods = new OrderGoods();
        BeanUtils.copyProperties(goods, orderGoods);
        orderGoods.setOrderId(order.getOrderId());
        orderGoods.setServerId(param.getServerId());
        orderGoods.setGoodsCounts(1);
        orderGoods.setPrice(goodsSpecification.getCurrentPrice());
        orderGoods.setGoodsSpecificationId(param.getGoodsSpecificationId());
        orderGoods.setCreateTime(LocalDateTime.now());
        orderGoods.setUpdateTime(LocalDateTime.now());
        if (orderGoodsMapper.insertOrderGoods(orderGoods) < 1) {
            throw new ArithmeticException("添加订单商品失败");
        }

        //order_record 添加订单记录
        OrderRecord orderRecord = new OrderRecord();
        orderRecord.setOrderId(order.getOrderId());
        orderRecord.setPreState("000");
        orderRecord.setNowState("000");
        orderRecord.setCreateTime(LocalDateTime.now());
        orderRecord.setUpdateTime(LocalDateTime.now());
        orderRecord.setOperateInfo(sysCodeService.getDecodeValue("003", "000"));
        if (orderRecordService.insertOrderRecord(orderRecord) < 1) {
            throw new ArithmeticException("添加订单记录失败");
        }
        log.info("创建订单：未支付：" + order.getOrderId());
        rabbitTemplate.convertAndSend(AmqpDelayedConfig.EXCHANGE_NAME, AmqpDelayedConfig.QUEUE_NAME, PREFIX_NO_PAY_ORDER + order.getOrderId(), message -> {
            message.getMessageProperties().setHeader("x-delay", EXPIRE_TIME_MINUTES * 60 * 1000);
            log.info("创建订单：创建延迟消息：" + AmqpDelayedConfig.QUEUE_NAME);
            return message;
        });
        return AjaxResult.success(order);

    }

    /**
     * 查询会员团购订单详情
     *
     * @param orderId
     * @return
     */
    @Override
    @Transactional
    public MemberOrderDetailVo getMemberGroupOrderByOrderId(Long orderId) {
        MemberOrderDetailVo memberOrderDetailVo = this.getMemberOrderByOrderId(orderId);
        if (memberOrderDetailVo == null) {
            return new MemberOrderDetailVo();
        }

        /**
         * 订单状态为001、002、003、004、007
         * 查询核销记录
         */
        if ("001".equals(memberOrderDetailVo.getOrderState()) || "002".equals(memberOrderDetailVo.getOrderState()) ||
                "003".equals(memberOrderDetailVo.getOrderState()) || "004".equals(memberOrderDetailVo.getOrderState())
                || "007".equals(memberOrderDetailVo.getOrderState())) {
            OrderVerificationRecord orderVerificationRecord = new OrderVerificationRecord();
            orderVerificationRecord.setOrderId(orderId);
            orderVerificationRecord.setAppointmentTime(LocalDateTime.now());
//        orderVerificationRecord.setAppointmentStatus("001");
            List<OrderVerificationRecord> orderVerificationRecordList = orderVerificationRecordService.selectOrderVerificationRecordList(orderVerificationRecord);
            if (orderVerificationRecordList.size() > 0) {
                //预约时间
                memberOrderDetailVo.setAppointmentTime(orderVerificationRecordList.get(0).getAppointmentTime());
                memberOrderDetailVo.setAppointmentStatus("001");
            } else {
                memberOrderDetailVo.setAppointmentStatus("002");
            }
        }

        //判断核销记录是否为空
        if(!ObjectUtils.isEmpty(memberOrderDetailVo.getOrderVerificationRecordList())) {
            //当核销记录不为空的时候判断当前核销码是否使用过
            for (OrderVerificationRecord ovr:memberOrderDetailVo.getOrderVerificationRecordList()) {
                if(memberOrderDetailVo.getOrderVerificationCode().equals(ovr.getOrderVerificationCode())){
                    Order order = new Order();
                    order.setOrderId(memberOrderDetailVo.getOrderId());
                    order.setOrderVerificationCode(RandomCodeGenerate.getOrderVerificationCode());
                    if (orderMapper.updateOrderCustom(order) < 1) {
                        throw new ArithmeticException("更新核销码失败");
                    }
                    memberOrderDetailVo.setOrderVerificationCode(order.getOrderVerificationCode());
                }
            }
        }
        return memberOrderDetailVo;

    }

    /**
     * 校验团购限购
     *
     * @param param
     * @return
     */
    @Override
    public AjaxResult getCountOrder(OrderGroupParam param) {
        /**
         * 查询验证服务数据
         */
        Goods goods = goodsMapper.selectGoodsByGoodsId(param.getGoodsId());
        if (ObjectUtils.isEmpty(goods)) {
            throw new ArithmeticException("商品不存在");
        }
        if (goods.getIsSale() == 2) {
            throw new ArithmeticException("商品已售空");
        }
        if (goods.getIsSale() == 0) {
            throw new ArithmeticException("商品未上架");
        }

        /**
         * 判断商品是否限购
         */
        if (goods.getMaxNum() > 0) {
            /**
             * 查询该用户购买该服务的次数
             */
            List<Order> list = orderMapper.getCountOrder(param);
            if (list.size() >= goods.getMaxNum()) {
                return AjaxResult.success(false);
            }
        }
        return AjaxResult.success(true);
    }

    /**
     * 根据服务id以及服务人员id查询订单
     *
     * @param goods
     * @return
     */
    @Override
    public List<Order> goodsVerify(GoodsServerVO goods) {
        return orderMapper.goodsVerify(goods);

    }

    /**
     * 会员预订单服务下单
     *
     * @param bookOrderParam
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult addBookOrder(BookOrderParam bookOrderParam) {
        // 查询商家信息
        Merchant merchant = merchantService.selectMerchantByMerchantId(bookOrderParam.getMerchantId());
        if (Objects.isNull(merchant)) {
            return AjaxResult.error("未查询到商家信息，不可下单！");
        }

        // 校验优金豆抵扣数量
        if (bookOrderParam.getGoodsCoin() != null) {
            if (bookOrderParam.getGoodsCoin() > 500) {
                return AjaxResult.error("优金豆使用数量不得超过500");
            }
            // 如果使用优金豆，调用远程接口减少用户优金豆数量
            if (bookOrderParam.getGoodsCoin() > 0) {
                FamilyParam familyParam = new FamilyParam();
                familyParam.setNum(BigDecimal.valueOf(-bookOrderParam.getGoodsCoin()));
                familyParam.setPhone(bookOrderParam.getPhone());
                String jsonCode = coinService.increasePoints(familyParam);
                if (!"200".equals(jsonCode)) {
                    throw new GlobalException("用户优金豆扣除失败导致预约下单失败！");
                }
            }
        }

        // 计算总服务时长及预约结束时间
        BigDecimal totalServiceTime = BigDecimal.valueOf(bookOrderParam.getGoodsCounts()).multiply(bookOrderParam.getSingleTime());
        LocalDateTime appointmentEndTime = recordAppointmentInfo(bookOrderParam.getAppointmentStartTime(), totalServiceTime, bookOrderParam.getServerId(), merchant.getAllowCompose());

        // 创建订单对象
        Order order = new Order();
        BeanUtils.copyProperties(bookOrderParam, order);
        // 生成订单id
        Long orderId = IDUtils.nextLongId();
        order.setOrderId(orderId);
        // 生成订单编号
        order.setOrderIndex(redisCache.getOrderIndexByRedis());
        order.setBeanAmount(Integer.valueOf(String.valueOf(bookOrderParam.getGoodsCoin())));

        bookOrderParam.setAppointmentEndTime(appointmentEndTime);

        order.setCreateTime(LocalDateTime.now());
        order.setUpdateTime(LocalDateTime.now());
        order.setOrderState(OrderStateEnum.PENDING_PAYMENT.getCode());
        order.setCommentState(CommentStateEnum.PENDING_COMMENT.getCode());

        // 使用优惠券
        if (bookOrderParam.getMemberCouponId() != null) {
            // 若使用了优惠券，则处理优惠券对应逻辑(暂时无优惠券使用逻辑)
            order.setCouponAmount(bookOrderParam.getCouponAmount());
        }
        // 平台抽成百分比
        BigDecimal percentage = new BigDecimal(sysConfigMapper.checkConfigKeyUnique("platform.commission.rate").getConfigValue());
        // 商家可得到 实付总价减去平台抽成
        BigDecimal shopAmount = bookOrderParam.getTotalAmount()
                .subtract(
                        bookOrderParam.getTotalAmount().multiply(percentage)
                                .divide(new BigDecimal(100),2, ROUND_HALF_UP));
        order.setShopAmount(shopAmount);

        order.setMerchantName(merchant.getMerchantName());
        order.setAppointmentEndTime(appointmentEndTime);
        if (orderMapper.addOrder(order) < 1) {
            throw new ArithmeticException("添加订单失败");
        }
//        //生成订单编号
//        String index = OrderIndexGenerate.getIndexByOrderId(order.getOrderId());
//        //更新数据
//        order.setOrderIndex(index);
//        order.setUpdateTime(LocalDateTime.now());
//        if (orderMapper.updateOrderCustom(order) < 1) {
//            throw new ArithmeticException("更新订单编号失败");
//        }

        //order表添加数据
        //order_address 订单地址添加
        //根据地址id查询地址数据
        MemberAddress memberAddress = memberAddressMapper.selectMemberAddressByAddressId(bookOrderParam.getAddressId());
        if (ObjectUtils.isEmpty(memberAddress)) {
            //抛出异常
            throw new ArithmeticException("没有此会员地址");
        }

        //商家与会员距离
        BigDecimal shortestDistance = null;
        // 计算距离
        shortestDistance = DistanceUtil.getShortestDistance( merchant.getLatitude(), merchant.getLongitude(),memberAddress.getLatitude(),
                memberAddress.getLongitude());

        BigDecimal maxDeliverDistance =null;
        if(merchant.getServiceDistance()==null){
            maxDeliverDistance = new BigDecimal(sysConfigMapper.checkConfigKeyUnique("home.server.distance").getConfigValue());

        }else {
            maxDeliverDistance  = new BigDecimal(String.valueOf(merchant.getServiceDistance()));
        }

        //验证坐标是否超出范围
        if(shortestDistance.compareTo(maxDeliverDistance)>0){
            //超出配送范围
            throw new ArithmeticException("下单失败订单地址超出服务范围");
        }

        //订单服务地址表
        OrderAddress orderAddress = new OrderAddress();
        BeanUtils.copyProperties(memberAddress, orderAddress);
        orderAddress.setCreateTime(LocalDateTime.now());
        orderAddress.setUpdateTime(LocalDateTime.now());
        orderAddress.setOrderId(order.getOrderId());
        orderAddress.setAddressLongitude(memberAddress.getLongitude());
        orderAddress.setAddressLatitude(memberAddress.getLatitude());
        if (orderAddressMapper.insertOrderAddress(orderAddress) < 1) {
            throw new ArithmeticException("添加订单服务地址表失败");
        }
        //查询商品数据
        Goods goods = goodsMapper.selectGoodsByGoodsId(bookOrderParam.getGoodsId());
        if (ObjectUtils.isEmpty(goods)) {
            throw new ArithmeticException("商品不存在");
        }
        if (goods.getIsSale() == 2) {
            throw new ArithmeticException("商品已售空");
        }
        if (goods.getIsSale() == 0) {
            throw new ArithmeticException("商品未上架");
        }
        //order_goods 订单商品添加数据
        OrderGoods orderGoods = new OrderGoods();
        BeanUtils.copyProperties(goods, orderGoods);
        orderGoods.setOrderId(order.getOrderId());
        orderGoods.setServerId(bookOrderParam.getServerId());
        orderGoods.setGoodsCounts(bookOrderParam.getGoodsCounts());
        orderGoods.setPrice(bookOrderParam.getPrice());
        orderGoods.setCreateTime(LocalDateTime.now());
        orderGoods.setUpdateTime(LocalDateTime.now());
        if (orderGoodsMapper.insertOrderGoods(orderGoods) < 1) {
            throw new ArithmeticException("添加订单商品失败");
        }

        //查询服务人员数据
        ServerUser serverUser = serverUserService.selectServerUserByServerId(bookOrderParam.getServerId());
        if (ObjectUtils.isEmpty(serverUser)) {
            throw new ArithmeticException("服务人员不存在");
        }
        //order_goodes_server 订单服务人员添加数据
        OrderGoodsServer orderGoodsServer = new OrderGoodsServer();
        BeanUtils.copyProperties(bookOrderParam, orderGoodsServer);
        //订单id
        orderGoodsServer.setOrderId(order.getOrderId());
        //商品名称
        orderGoodsServer.setGoodsName(goods.getName());
        //商品服务人员单价
        orderGoodsServer.setGoodsServerPrice(bookOrderParam.getPrice());
        //商品单位
        orderGoodsServer.setGoodsUnit(goods.getGoodsUnit());
        //服务人员姓名
        orderGoodsServer.setServerName(serverUser.getRealName());
        //服务人员性别
        orderGoodsServer.setServerSex(serverUser.getSex());
        //工龄
        orderGoodsServer.setServerAge(serverUser.getAge());
        //服务人员头像
        orderGoodsServer.setServerAvatar(serverUser.getAvatar());
        //创建时间
        orderGoodsServer.setCreateTime(LocalDateTime.now());
        orderGoodsServer.setUpdateTime(LocalDateTime.now());
        if (orderGoodsServerService.insertOrderGoodsServer(orderGoodsServer) < 1) {
            throw new ArithmeticException("添加订单服务人员关联数据失败");
        }

        //order_record 添加订单记录
        OrderRecord orderRecord = new OrderRecord();
        orderRecord.setOrderId(order.getOrderId());
        orderRecord.setPreState("000");
        orderRecord.setNowState("000");
        orderRecord.setCreateTime(LocalDateTime.now());
        orderRecord.setUpdateTime(LocalDateTime.now());
        orderRecord.setOperateInfo(sysCodeService.getDecodeValue("003","000"));
        if (orderRecordService.insertOrderRecord(orderRecord) < 1) {
            throw new ArithmeticException("添加订单追踪记录失败");
        }
        log.info("创建订单：未支付：" + order.getOrderId());
        rabbitTemplate.convertAndSend(AmqpDelayedConfig.EXCHANGE_NAME, AmqpDelayedConfig.QUEUE_NAME, PREFIX_NO_PAY_ORDER + order.getOrderId(), message -> {
            message.getMessageProperties().setHeader("x-delay", EXPIRE_TIME_MINUTES * 60 * 1000);
            log.info("创建订单：创建延迟消息：" + AmqpDelayedConfig.QUEUE_NAME);
            return message;
        });
        return AjaxResult.success(order);
    }

//    查询团购订单结算信息
    @Override
    public Map<Long, List<OrderVo>> listMerchantGroupSettleOrder(LocalDate settleStartDate, LocalDate settleEndDate) {
        List<OrderVo> orderList = orderMapper.listMerchantGroupSettleOrder(settleStartDate, settleEndDate);
        if (CollectionUtils.isNotEmpty(orderList)) {
            return orderList.stream().collect(Collectors.groupingBy(OrderVo::getMerchantId));
        }
        return null;
    }

    /**
     * 合利宝订单退款回调
     *
     * @param body
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String refundCb(NotifyRefundResponseVo body) {
        String assemblyRespOriSign = null;
        try {
            assemblyRespOriSign = com.younike.hlpay.util.BeanUtils.getSignedByPresetParameter(
                    body, NotifyRefundResponseVo.NEED_SIGN_PARAMS);
        } catch (Exception e) {
            log.error("系统内部错误: " + e.getMessage());
            return "failed";
        }

        log.info("组装返回结果签名串：" + assemblyRespOriSign);
        String responseSign = body.getSign();
        log.info("响应签名：" + responseSign);
        String checkSign = Disguiser
                .disguiseMD5(assemblyRespOriSign.trim());

        log.info("验证签名：" + checkSign);
        if (checkSign.equals(responseSign)) {
            // 验证签名成功
            log.info("验证签名成功");
            // 校验支付信息
            String rt2_orderId = body.getRt2_orderId();
            String[] split = rt2_orderId.split("-");
            String orderId = split[1];
            // 追加支付的回调不需继续执行以下程序
            if (split.length == 4 && split[2].equals("ADD")) {
                return "success";
            }
            Order order = orderMapper.selectOrderByOrderId(Long.valueOf(orderId));
            if (order == null) {
                log.error("合利宝退款回调 -- 未查询到退款订单信息");
                throw new ServiceException("未查询到退款订单信息");
            }
            // 判断订单状态是否被更新为已退款
            if (OrderStateEnum.REFUNDED.getCode().equals(order.getOrderState())) {
                log.warn("合利宝退款已成功回调过一次 -- 不需再次执行");
                return "success";
            }
            // 退款成功后 更新订单状态为已退款
            order.setUpdateTime(LocalDateTime.now());
            order.setOrderState(OrderStateEnum.REFUNDED.getCode());
            if (orderMapper.updateOrderCustom(order) < 0) {
                log.error("合利宝退款回调 -- 更新订单信息失败");
                throw new ServiceException("更新订单信息失败");
            }
            // 更新订单退款信息
            OrderRefund orderRefund = orderRefundService.selectOrderRefundByOrderId(String.valueOf(order.getOrderId()));
            if (orderRefund == null) {
                log.error("合利宝退款回调 -- 未查询到订单退款信息");
                throw new ServiceException("更新订单退款信息失败");
            }
            // 退款成功后 更新退款状态
            orderRefund.setUpdateTime(LocalDateTime.now());
//            orderRefund.setStatus(OrderRefundStateEnum.PLATFORM_REFUNDS.getCode());
            orderRefund.setOrderRefundFlag("1");
            orderRefund.setAddRefundFlag("1");
            if (orderRefundMapper.updateOrderRefund(orderRefund) < 0) {
                log.error("合利宝退款回调 -- 更新订单退款信息失败");
                throw new ServiceException("更新订单退款信息失败");
            }

            // 保存订单追踪记录数据
            log.warn("...开始保存订单追踪记录...");
            OrderRecord record = new OrderRecord();
            record.setPreState(OrderStateEnum.PENDING_REFUNDED.getCode());
            record.setOrderId(order.getOrderId());
            record.setNowState(OrderStateEnum.REFUNDED.getCode());
            // 商家退款
            if (OrderRefundStateEnum.MERCHANT_REFUNDS.getCode().equals(orderRefund.getStatus())) {
                record.setOperateInfo("商家已退款");
            }
            // 平台退款
            if (OrderRefundStateEnum.PLATFORM_REFUNDS.getCode().equals(orderRefund.getStatus())) {
                record.setOperateInfo("平台已退款");
            }
            if (orderRecordService.insertOrderRecord(record) < 1) {
                log.error("合利宝退款回调 -- 添加订单追踪信息失败");
                throw new ServiceException("添加订单追踪信息失败");
            }
            log.warn("...保存订单追踪记录结束...");

            // 非团购订单需取消预订记录（且是待服务的订单，即服务开始时间为空）
            if (!"003".equals(order.getOrderType()) && order.getServiceStartTime() == null) {
                log.warn("...待服务订单退款后取消订单预约记录开始...");
                // 取消订单预定记录
                this.cancelBook(order);
                log.warn("...待服务订单退款后取消订单预约记录结束...");
            }

            // 判断订单是否使用优金豆
            if (order.getBeanAmount() != null && order.getBeanAmount() > 0) {
                // 查询顾客信息
                Member member = memberMapper.selectMemberByMemberId(order.getMemberId());
                if (ObjectUtils.isEmpty(member)) {
                    log.error("合利宝退款回调 -- 更新顾客优金豆-未查询到顾客信息");
                    throw new ServiceException("未查询到顾客信息!memberId=" + order.getMemberId());
                }
                // 查询商家信息
                Merchant merchant = merchantMapper.selectMerchantByMerchantId(order.getMerchantId());
                if (ObjectUtils.isEmpty(merchant)) {
                    log.error("合利宝退款回调 -- 更新商家保证金-未查询到商家信息");
                    throw new ServiceException("未查询到商家信息!merchantId=" + order.getMerchantId());
                }
                try {
                    // 退顾客优金豆
                    FamilyParam familyParam = new FamilyParam();
                    // 设置 关联id
                    familyParam.setTargetId(order.getOrderId().toString());
                    // 设置 积分变动类型（001-消费 002-退款 003-抵扣 004-评价订单新增）
                    familyParam.setCode("002");
                    familyParam.setPhone(member.getPhone());
                    // 设置 备注（商家名称）
                    familyParam.setOperation(merchant.getMerchantName());
                    // 恢复扣除的积分数量
                    familyParam.setNum(new BigDecimal(order.getBeanAmount()));
                    String integralId = coinService.increasePoints(familyParam);
                    if (StringUtils.isBlank(integralId)) {
                        log.error("合利宝退款回调 -- 退回顾客优金豆失败");
                    }
                } catch (Exception e) {
                    log.error("合利宝退款回调 -- 退回顾客优金豆出现错误");
                    log.error("错误信息 -- " + e.getMessage());
                    e.printStackTrace();
                }

                try {
                    // 增加优金豆变动记录
                    UjdChangeRecord ujdChangeRecord = new UjdChangeRecord();
                    // 查询服务数据
                    Goods goods = goodsMapper.selectOrderId(orderId);
                    if (!ObjectUtils.isEmpty(goods)) {
                        ujdChangeRecord.setGoodsId(goods.getGoodsId());
                        ujdChangeRecord.setGoodsIndex(goods.getGoodsIndex());
                        ujdChangeRecord.setGoodsName(goods.getName());
                    }
                    ujdChangeRecord.setChangeQty(order.getBeanAmount());
                    ujdChangeRecord.setChangeType(UjdChangeTypeEnum.MEMBER_REFUND_RETURN_UJD.getCode());
                    ujdChangeRecord.setChangeProperty("0");
                    ujdChangeRecord.setChangeTime(LocalDateTime.now());
                    ujdChangeRecord.setMerchantId(merchant.getMerchantId());
                    ujdChangeRecord.setMerchantIndex(com.younike.common.utils.StringUtils.isEmpty(merchant.getMerchantIndex()) ? "-" : merchant.getMerchantIndex());
                    ujdChangeRecord.setMerchantName(merchant.getMerchantName());
                    ujdChangeRecord.setTradeNo(order.getOrderIndex());
                    // 个人商家，查询用户名称
                    if (Objects.equals(merchant.getMerchantType(), 1)) {
                        SysUser sysUser = sysUserService.selectSysUserById(merchant.getAdminId());
                        ujdChangeRecord.setMerchantName(sysUser == null ? "-" : sysUser.getNickName());
                    }
                    int ujdChangeRecordInsertResult = ujdChangeRecordMapper.insertUjdChangeRecord(ujdChangeRecord);
                    if (ujdChangeRecordInsertResult <= 0) {
                        log.error("合利宝退款回调 -- 优金豆变动记录保存失败!ujdChangeRecord=" + JSON.toJSONString(ujdChangeRecord));
                    }
                    // 更新商家优金豆数量
                    if (!ObjectUtils.isEmpty(merchant.getBondMoney())) {
                        BigDecimal bigDecimal = new BigDecimal(Integer.parseInt(order.getBeanAmount().toString())).divide(new BigDecimal("100"));
                        merchant.setBondMoney(merchant.getBondMoney().subtract(bigDecimal).setScale(2, ROUND_HALF_UP));
                    }
                    int updateMerchant = merchantService.updateMerchant(merchant);
                    if (updateMerchant < 1) {
                        log.error("合利宝退款回调 -- 更新商家保证金失败");
                    }
                } catch (Exception e) {
                    log.error("合利宝退款回调 -- 增加优金豆变动记录及更新商家保证金出现错误");
                    log.error("错误信息 -- " + e.getMessage());
                    e.printStackTrace();
                }
            }

            // 发送短信通知
            try {
                // 若由平台进行退款，在退款后给商家发送短信通知
                if (OrderRefundStateEnum.PLATFORM_REFUNDS.getCode().equals(orderRefund.getStatus())) {
                    log.warn("...合利宝平台退款成功短信通知商家...");
                    // 查询订单商家信息
                    Merchant merchantByMerchantId = merchantService.getMerchantByMerchantId(order.getMerchantId());
                    // 合利宝退款回调短信通知商家
                    if (merchantByMerchantId != null) {
                        JSONObject param = new JSONObject();
                        param.put("orderindex", order.getOrderIndex());
                        log.warn("合利宝退款成功短信通知商家--短信发送参数:" + JSONObject.toJSONString(param));
                        log.warn("合利宝退款成功短信通知商家--短信接收手机号:" + merchantByMerchantId.getMerchantPhone());
                        SendSmsResponse sendSmsResponse = smsUtil.sendSms(merchantByMerchantId.getMerchantPhone(), param, AliTemplateCode.PLATFORM_REFUND_NOTIFY_MERCHANT_CODE);
                        log.warn("合利宝退款成功短信通知商家--短信返回结果" + JSON.toJSONString(sendSmsResponse));
                    } else {
                        log.error("合利宝退款回调成功短信通知商家--未查询到商家信息!商家ID=" + order.getMerchantId());
                    }
                }

                // 查询订单顾客信息
                Member member = memberService.selectMemberByMemberId(order.getMemberId());
                // 合利宝退款回调短信通知顾客
                if (member != null && StringUtils.isNotBlank(member.getPhone())) {
                    JSONObject param = new JSONObject();
                    param.put("orderindex", order.getOrderIndex());
                    param.put("amount", orderRefund.getRefundMoney());
                    log.warn("合利宝退款回调成功短信通知顾客--短信发送参数:" + JSONObject.toJSONString(param));
                    log.warn("合利宝退款回调成功短信通知顾客--短信接收手机号:" + member.getPhone());
                    SendSmsResponse sendSmsResponse = smsUtil.sendSms(member.getPhone(), param, AliTemplateCode.PLATFORM_REFUND_NOTIFY_MEMBER_CODE);
                    log.warn("合利宝退款回调成功短信通知顾客--短信返回结果:" + JSONObject.toJSONString(sendSmsResponse));
                } else {
                    log.error("合利宝退款回调成功短信通知顾客--未查询到顾客信息!顾客ID=" + order.getMemberId());
                }
            } catch (Exception e) {
                log.error("合利宝退款回调--短信通知发送失败!错误信息error=" + e.getMessage());
            }

            log.info("合利宝退款回调 -- success");
            return "success";
        }
        log.error("合利宝退款回调 -- 验证签名失败");
        return "failed";
    }

    /**
     * 查询超过三天未处理的订单数据，包括商家以及商家联系电话
     * @param order
     * @return
     */
    @Override
    public List<OvertimeOrderVo> overtimeOrder(Order order) {
        return orderMapper.overtimeOrder(order);
    }

    /**
     * 查询已过期的待服务团购订单列表
     *
     * @param orderState
     * @return
     */
    @Override
    public List<Order> listExpiredGroupOrderOfPendingService(String orderState) {
        return orderMapper.listExpiredGroupOrderOfPendingService(orderState);
    }

    /**
     *
     * 查询所有「已完成」「已拒绝退款」「已退款，部分退款」预定订单，以商家进行分组
     * @param settleStartDate
     * @param settleEndDate
     * @return
     */
    @Override
    public Map<Long, List<Order>> listMerchantReserveRefundSettleOrder(LocalDate settleStartDate, LocalDate settleEndDate) {

        ArrayList<Order> orderList = new ArrayList<>();

        List<Order> orders = orderMapper.listMerchantReserveSettleOrder(settleStartDate, settleEndDate);

       // 查询所有「已退款，部分退款」预定订单，以商家进行分组
        List<Order> orderList1 = orderMapper.listMerchantReserveRefundSettleOrder(settleStartDate, settleEndDate);

        if(orders.size()>0){
            for (Order o:orders) {
                orderList.add(o);
            }
        }
        if(orderList1.size()>0){
            for (Order o:orderList1) {
                orderList.add(o);
            }
        }

        if (CollectionUtils.isNotEmpty(orderList)) {
            return orderList.stream().collect(Collectors.groupingBy(Order::getMerchantId));
        }
        return null;
    }


    /**
     * 查询今日订单数据
     *
     * @return
     */
    @Override
    public TodayOrderVO getTodayOrderData() {
        return orderMapper.getTodayOrderData();
    }

    /**
     * 查询本周Top5商家订单数据
     *
     * @return
     */
    @Override
    public List<MerchantOrderOfWeekVO> getTopFiveMerchantOrderData() {
        return orderMapper.getTopFiveMerchantOrderData();
    }

    /**
     * 查询近30天订单数据
     *
     * @return
     */
    @Override
    public List<OrderStatisticsVO> getOrderDataByMonth() {
        return orderMapper.getOrderDataByMonth();
    }

    /**
     * 获取微信OpenID
     *
     * @param code 微信授权code
     */
    private String getOpenId(String code) {
        //微信的接口url地址
        String url = xcxOpenIdUrl + "?appid=" + xcxAppId +
                "&secret=" + xcxAppSecret + "&js_code=" + code + "&grant_type=authorization_code";
        RestTemplate restTemplate = new RestTemplate();
        //进行网络请求,访问url接口
        ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, null, String.class);
        if (responseEntity.getStatusCode() == org.springframework.http.HttpStatus.OK) {
            String sessionData = responseEntity.getBody();
            //下面是把拿到的json字符串转成 json对象
            com.alibaba.fastjson.JSONObject jsStr = com.alibaba.fastjson.JSONObject.parseObject(sessionData);
            //解析从微信服务器获得的openid和session_key;获取用户的唯一标识
            return jsStr.getString("openid");
        }
        log.error("获取OpenId失败, code：" + code + "，\n 返回："  + JSON.toJSONString(responseEntity));
        return null;
    }
}
