package com.fs.his.service.impl;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.TimeUnit;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.fs.common.constant.FsConstants;
import com.fs.common.core.domain.AjaxResult;
import com.fs.common.core.domain.R;
import com.fs.common.core.redis.RedisCache;
import com.fs.common.exception.CustomException;
import com.fs.common.utils.DateUtils;
import com.fs.common.utils.SecurityUtils;
import com.fs.common.utils.ServletUtils;
import com.fs.common.utils.StringUtils;
import com.fs.common.utils.ip.IpUtils;
import com.fs.common.utils.poi.ExcelUtil;
import com.fs.company.domain.Company;
import com.fs.company.domain.CompanyUser;
import com.fs.company.mapper.CompanyUserMapper;
import com.fs.company.vo.CompanyMoneyLogsExportVO;
import com.fs.core.config.WxPayProperties;
import com.fs.core.utils.OrderCodeUtils;
import com.fs.event.TemplateBean;
import com.fs.event.TemplateEvent;
import com.fs.event.TemplateListenEnum;
import com.fs.his.config.FsSysConfig;
import com.fs.his.domain.*;
import com.fs.his.dto.PackageConfigDTO;
import com.fs.his.dto.PayConfigDTO;
import com.fs.his.dto.StoreOrderProductDTO;
import com.fs.his.enums.FsPackageOrderStatusEnum;
import com.fs.his.mapper.*;
import com.fs.his.param.*;
import com.fs.his.service.*;
import com.fs.his.utils.ConfigUtil;
import com.fs.his.utils.HttpUtil;
import com.fs.his.utils.PhoneUtil;
import com.fs.his.vo.FsPackageOrderExcelVO;
import com.fs.his.vo.FsPackageOrderListUVO;
import com.fs.his.vo.FsPackageOrderListVO;
import com.fs.his.vo.FsPackageOrderVO;
import com.fs.huifuPay.domain.HuiFuCreateOrder;
import com.fs.huifuPay.domain.HuifuCreateOrderResult;
import com.fs.huifuPay.service.HuiFuService;
import com.fs.system.domain.SysConfig;
import com.fs.ybPay.config.PayConfig;
import com.fs.ybPay.domain.CreateWxOrderResult;
import com.fs.ybPay.domain.OrderResult;
import com.fs.ybPay.dto.OrderQueryDTO;
import com.fs.ybPay.dto.RefundDTO;
import com.fs.ybPay.dto.WxJspayDTO;
import com.fs.ybPay.service.IPayService;
import com.fs.system.mapper.SysConfigMapper;
import com.fs.system.service.ISysConfigService;
import com.fs.tzBankPay.TzBankService.TzBankService;
import com.fs.tzBankPay.config.TzBankConfig;
import com.fs.tzBankPay.doman.*;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayRefundQueryResult;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

/**
 * 套餐订单Service业务层处理
 *
 * @author fs
 * @date 2023-08-25
 */
@Service
public class FsPackageOrderServiceImpl implements IFsPackageOrderService
{
    Logger logger= LoggerFactory.getLogger(getClass());
    @Autowired
    private WxPayService wxPayService;
    @Autowired
    private WxPayProperties wxPayProperties;
    @Autowired
    IPayService payService;
    @Autowired
    private ConfigUtil configUtil;
    @Autowired
    private FsPackageOrderMapper fsPackageOrderMapper;

    @Autowired
    private FsPackageMapper fsPackageMapper;

    @Autowired
    private FsPatientMapper fsPatientMapper;

    @Lazy
    @Autowired
    IFsStoreOrderService storeOrderService;
    @Autowired
    private TzBankService tzBankService;
    @Autowired
    private FsDoctorMapper doctorMapper;
    @Autowired
    private HuiFuService huiFuService;
    @Autowired
    private FsInquiryOrderMapper inquiryOrderMapper;
    @Autowired
    RedisCache redisCache;
    @Autowired
    private IFsUserService userService;
    @Autowired
    private IFsInquiryOrderService inquiryOrderService;
    @Autowired
    SysConfigMapper sysConfigMapper;
    @Autowired
    private IFsUserAddressService userAddressService;

    @Autowired
    private IFsUserCouponService userCouponService;
    @Autowired
    private IFsCouponService couponService;
    @Autowired
    private ISysConfigService configService;

    @Autowired
    private IFsStorePaymentService storePaymentService;

    @Autowired
    private FsStorePaymentMapper fsStorePaymentMapper;

    @Autowired
    private FsInquiryOrderMapper fsInquiryOrderMapper;

    @Autowired
    private IFsStoreOrderService fsStoreOrderService;
    @Autowired
    private CompanyUserMapper companyUserMapper;
    @Autowired
    private IPayService ybPayService;
    @Autowired
    private IFsUserService fsUserService;

    /**
     * 查询套餐订单
     *
     * @param orderId 套餐订单主键
     * @return 套餐订单
     */
    @Override
    public FsPackageOrder selectFsPackageOrderByOrderId(Long orderId)
    {
        return fsPackageOrderMapper.selectFsPackageOrderByOrderId(orderId);
    }

    @Override
    public FsPackageOrderVO selectFsPackageOrderByOrderIdVO(Long orderId) {
        return fsPackageOrderMapper.selectFsPackageOrderByOrderIdVO(orderId);
    }

    /**
     * 查询套餐订单列表
     *
     * @param fsPackageOrder 套餐订单
     * @return 套餐订单
     */
    @Override
    public List<FsPackageOrder> selectFsPackageOrderList(FsPackageOrder fsPackageOrder)
    {
        return fsPackageOrderMapper.selectFsPackageOrderList(fsPackageOrder);
    }

    /**
     * 新增套餐订单
     *
     * @param fsPackageOrder 套餐订单
     * @return 结果
     */
    @Override
    public int insertFsPackageOrder(FsPackageOrder fsPackageOrder)
    {
        fsPackageOrder.setCreateTime(DateUtils.getNowDate());
        return fsPackageOrderMapper.insertFsPackageOrder(fsPackageOrder);
    }

    /**
     * 修改套餐订单
     *
     * @param fsPackageOrder 套餐订单
     * @return 结果
     */
    @Override
    public int updateFsPackageOrder(FsPackageOrder fsPackageOrder)
    {
        return fsPackageOrderMapper.updateFsPackageOrder(fsPackageOrder);
    }

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

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

    @Override
    public List<FsPackageOrderListVO> selectFsPackageOrderListVO(FsPackageOrderParam fsPackageOrder) {
        return fsPackageOrderMapper.selectFsPackageOrderListVO(fsPackageOrder);
    }

    @Override
    public Integer PackageOrderRefund(Long orderId) {
        FsPackageOrder fsPackageOrder = fsPackageOrderMapper.selectFsPackageOrderByOrderId(orderId);
        FsPackage fsPackage = fsPackageMapper.selectFsPackageByPackageId(fsPackageOrder.getPackageId());
        if (fsPackageOrder.getStatus()!=2&&fsPackageOrder.getStatus()!=3){
            throw  new CustomException("非法操作");
        }
        if (fsPackage.getStatus()==1){
            LocalDate today = LocalDate.now();
            LocalDate dateToCompare = fsPackageOrder.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
            Duration duration = Duration.between(dateToCompare.atStartOfDay(), today.atStartOfDay());
            if (duration.toDays() > 3){
                throw new CustomException("咨询包超过三天无法退款");
            }
        }
        //退款操作
        List<FsStorePayment> payments = fsStorePaymentMapper.selectFsStorePaymentByPay(3,orderId);
        if(payments!=null&&payments.size()==1){
            //
            FsStorePayment payment=payments.get(0);
            RefundParam tzBankResult = new RefundParam();
            // 使用set方法为对象的字段赋值
            //商户原支付订单号
            tzBankResult.setOldPayOutOrderNo("package"+payment.getPayCode());
            // 商户退款订单号 对接平台系统里自己生成的退款订单号
            tzBankResult.setRefundOrderNo("refund"+payment.getPayCode());
            // 交易发送时间 yyyyMMddHHmmss
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            tzBankResult.setTrxSendTime(sdf.format(new Date()));
            // 退款金额
            tzBankResult.setRefundOrdTransAmt(payment.getPayMoney().doubleValue());
            TzBankResult<com.fs.tzBankPay.doman.RefundResult> result = tzBankService.refund(tzBankResult);
            if(result.getBody().getRefundOrdStatus().equals("90")){
                FsStorePayment paymentMap=new FsStorePayment();
                paymentMap.setPaymentId(payment.getPaymentId());
                paymentMap.setStatus(-1);
                paymentMap.setRefundTime(DateUtils.getNowDate());
                paymentMap.setRefundMoney(payment.getPayMoney());
                fsStorePaymentMapper.updateFsStorePayment(paymentMap);
            }
        }
        fsPackageOrder.setStatus(-2);
        return fsPackageOrderMapper.updateFsPackageOrder(fsPackageOrder);
    }

    @Override
    public R confirmOrder(FsPackageOrderConfirmParam param) {
        String uuid = IdUtil.randomUUID();
        redisCache.setCacheObject("packageOrderKey:"+uuid,uuid,200, TimeUnit.MINUTES);
        return R.ok().put("orderKey",uuid);
    }



    @Override
    public R computeOrder(FsPackageOrderComputeParam param) {
        FsPackageOrder order = fsPackageOrderMapper.selectFsPackageOrderByOrderId(param.getOrderId());
        if(order==null){
            return R.error("订单不存在");
        }
        if(order.getStatus()!= FsPackageOrderStatusEnum.STATUS_1.getValue()){
            return R.error("订单状态不正确");
        }
        if (order.getUserCouponId()!=null&&order.getUserCouponId()>0){
            param.setUserCouponId(order.getUserCouponId());
        }
        FsUser user=userService.selectFsUserByUserId(order.getUserId());
        if (param.getType()==1) {
            if(user!=null&& StringUtils.isNotEmpty(user.getMaOpenId())){
                param.setCompanyId(order.getCompanyId());
                param.setCompanyUserId(order.getUserId());
                param.setStoreId(order.getStoreId());
                Map<String,Object> moneys=computeOrderMoney(order.getTotalPrice(),param);
                return R.ok().put("moneys",moneys);
            }
            else{
                return R.error("用户OPENID不存在");
            }
        }else if (param.getType()==2){
            if(user!=null){
                param.setCompanyId(order.getCompanyId());
                param.setCompanyUserId(order.getUserId());
                param.setStoreId(order.getStoreId());
                Map<String,Object> moneys=computeOrderMoney(order.getTotalPrice(),param);
                return R.ok().put("moneys",moneys);
            }
            else{
                return R.error("用户不存在");
            }
        }else {
            return R.error("无效的类型参数");
        }
    }
    public Map<String,Object> computeOrderMoney(BigDecimal orderPrice,FsPackageOrderComputeParam param){
        Map<String,Object> moneys=new HashMap<>();
        BigDecimal payPrice=orderPrice;
        BigDecimal payMoney=new BigDecimal(0);
        BigDecimal payRemain=new BigDecimal(0);
        BigDecimal payDelivery=new BigDecimal(0);
        BigDecimal discountMoney=new BigDecimal(0);
        String json=configService.selectConfigByKey("his.package");
        PackageConfigDTO configDTO=JSONUtil.toBean(json, PackageConfigDTO.class);
        if(param.getUserCouponId()!=null&&param.getUserCouponId()>0l){
            FsUserCoupon userCoupon=userCouponService.selectFsUserCouponById(param.getUserCouponId());
            if(userCoupon==null){

            }
            if(userCoupon.getStatus()!=0){

            }
            FsCoupon coupon=couponService.selectFsCouponByCouponId(userCoupon.getCouponId());
            if(coupon.getCouponType().equals(1)){
                if(coupon.getMinPrice().compareTo(orderPrice)==1){

                }
                if(coupon.getPrice().compareTo(orderPrice)>=0){
                    payPrice=new BigDecimal(0);
                    discountMoney=coupon.getPrice();
                }
                else{
                    payPrice=orderPrice.subtract(coupon.getPrice());
                    discountMoney=coupon.getPrice();


                }
            }
            else if(coupon.getCouponType().equals(2)){
                payPrice=new BigDecimal(0);
                discountMoney=orderPrice;

            }
            else if(coupon.getCouponType().equals(3)){


            }
            else if(coupon.getCouponType().equals(4)){
                payPrice= orderPrice.multiply(coupon.getRate()).divide(new BigDecimal(100));
                discountMoney=coupon.getPrice().subtract(orderPrice);

            }
            else if(coupon.getCouponType().equals(5)){
                if(coupon.getMinPrice().compareTo(orderPrice)==1){

                }
                if(coupon.getPrice().compareTo(orderPrice)>=0){
                    payPrice=new BigDecimal(0);
                    discountMoney=coupon.getPrice();
                }
                else{
                    payPrice=orderPrice.subtract(coupon.getPrice());
                    discountMoney=coupon.getPrice();


                }

            }
        }
        else{
            payPrice=orderPrice;
            discountMoney=new BigDecimal(0);
        }

        if(payPrice.compareTo(new BigDecimal(0))==1){
            if(param.getPayType().equals(1)){
                //全款
                payMoney=payPrice;
                payRemain=new BigDecimal(0);
                payDelivery=new BigDecimal(0);

            }
            else if (param.getPayType().equals(2)){
                //代收
                payMoney= payPrice.multiply(new BigDecimal((100-configDTO.getPayRate()))).divide(new BigDecimal(100));
                payMoney=new BigDecimal(payMoney.setScale(0, BigDecimal.ROUND_HALF_UP).longValue());
                payRemain=payPrice.subtract(payMoney);
                payDelivery=new BigDecimal(0);
                if(payRemain.compareTo(new BigDecimal(0))==0){
                    throw  new CustomException("代收金额应大于0");
                }
            }
            else if(param.getPayType().equals(3)){
                //货到付款
                payMoney=configDTO.getPayDelivery();
                payPrice=payPrice.add(configDTO.getPayDelivery());
                payRemain=payPrice.subtract(configDTO.getPayDelivery());
                payDelivery=configDTO.getPayDelivery();
            }
        }
        moneys.put("payPrice",payPrice);
        moneys.put("payMoney",payMoney);
        moneys.put("payRemain",payRemain);
        moneys.put("payDelivery",payDelivery);
        moneys.put("discountMoney",discountMoney);
        List<StoreOrderProductDTO> gifts=new ArrayList<>();
        if(configDTO.getGiftStoreId()!=null&&param.getStoreId()!=null&&configDTO.getGiftStoreId().equals(param.getStoreId())&&param.getPayType()==1&&param.getCompanyId()!=null&&param.getCompanyUserId()!=null&&param.getCompanyId()>0&&payPrice.compareTo(configDTO.getGiftPrice())>=0){
            gifts=configDTO.getGift();
        }
        if(configDTO.getGiftStoreId()!=null&&param.getStoreId()!=null&&configDTO.getGiftStoreId().equals(param.getStoreId())&&param.getPayType()==2&&param.getCompanyId()!=null&&param.getCompanyUserId()!=null&&param.getCompanyId()>0&&payPrice.compareTo(configDTO.getGiftPrice())>=0){
            gifts=configDTO.getDeliveryGift();
        }
        moneys.put("gifts",gifts);
        return moneys;
    }
    @Override
    public R createOrder(FsPackageOrderCreateParam param) {
        FsUser user=userService.selectFsUserByUserId(param.getUserId());
        if(user.getStatus()!=1){
            return R.error("非法用户操作");
        }
        FsPatient patient=null;
        if(param.getPatientId()!=null){
            patient=fsPatientMapper.selectFsPatientByPatientId(param.getPatientId());
        }else {
            return R.error("请提交患者信息");
        }

        FsPackage fsPackage=fsPackageMapper.selectFsPackageByPackageId(param.getPackageId());
        if(fsPackage.getStatus().equals(0)){
            return R.error("套餐名已下架");
        }
        FsDoctor doctor=null;
        if(param.getDoctorId()!=null){
            doctor=doctorMapper.selectFsDoctorByDoctorId(param.getDoctorId());
            if(doctor==null||doctor.getStatus().equals(0)){
                return R.error("此医生已停用");
            }
            Integer orderCount=inquiryOrderMapper.checkAcceptOrder(param.getDoctorId(),param.getUserId());
            if(orderCount>0){
                return R.error("您正在咨询此医生,请先结束当前订单");
            }
        }
        if (fsPackage.getIsShow()==0){
            if (param.getCompanyId()==null||param.getCompanyUserId()==null){
                return R.error("商品信息过期");
            }
            CompanyUser companyUser = companyUserMapper.selectCompanyUserById(param.getCompanyUserId());
            if (companyUser==null){
                return R.error("商品信息过期");
            }

        }


        Integer num = fsPackage.getNum();
        if (num!=0){
            int i = fsPackageMapper.selectFsPackageListByUser(param.getUserId(), fsPackage.getPackageId());
            if (i>=num){
                return R.error("超过限购次数");
            }
        }
        if (patient==null){
            return R.error("请提交患者信息");
        }
        FsPackageOrder  order=new FsPackageOrder();
        String orderSn =  OrderCodeUtils.getOrderSn();
        if(StringUtils.isEmpty(orderSn)){
            return R.error("订单生成失败，请重试");
        }
        order.setOrderSn(orderSn);
        order.setStoreId(fsPackage.getStoreId());
        order.setUserId(param.getUserId());
        order.setDoctorId(param.getDoctorId());
        order.setPackageId(param.getPackageId());
        order.setPackageName(fsPackage.getPackageName());
        order.setTotalPrice(fsPackage.getTotalPrice());
        order.setIcdCode(fsPackage.getIcdCode());
        order.setPayPrice(fsPackage.getTotalPrice());
        order.setPayMoney(fsPackage.getTotalPrice());
        order.setIsPay(0);
        order.setPackageSecondName(fsPackage.getSecondName());
        order.setDoctorRemark(fsPackage.getDoctorRemark());
        order.setFollowTempId(fsPackage.getFollowTempId());
        if (param.getSource()!=null){
            order.setSource(param.getSource());
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.package");
        Map<String, Object> config = (Map<String, Object>) JSON.parse(sysConfig.getConfigValue());
        Integer followRate = (Integer)config.get("followRate");
        calendar.add(Calendar.DAY_OF_MONTH, followRate);
        order.setFollowTime(calendar.getTime());
        order.setFollowRate(followRate);
        order.setPackageSubType(fsPackage.getPackageSubType());
        order.setDays(fsPackage.getCycle());
        order.setStatus(1);
        order.setStartTime(new Date());
        order.setCompanyUserId(param.getCompanyUserId());
        if (param.getCompanyUserId()!=null){
            CompanyUser companyUser = companyUserMapper.selectCompanyUserById(param.getCompanyUserId());
            if (companyUser!=null){
                order.setDeptId(companyUser.getDeptId());
            }
        }
        order.setCompanyId(param.getCompanyId());
        Calendar c = Calendar.getInstance();
        c.setTime(order.getStartTime());
        c.add(Calendar.DAY_OF_MONTH, fsPackage.getCycle());
        order.setFinishTime(c.getTime());
        order.setFormJson(param.getFormJson());
        order.setPackageJson(JSONUtil.toJsonStr(fsPackage));
        order.setCreateTime(new Date());
        if(patient!=null){
            order.setPatientJson(JSONUtil.toJsonStr(patient));
        }
        order.setInquiryCostPrice(fsPackage.getInquiryCostPrice());
        order.setProductCostPrice(fsPackage.getProductCostPrice());
        order.setTotalCostPrice(fsPackage.getTotalCostPrice());
        order.setCycle(fsPackage.getCycle());
        order.setCostDiscountMoney(fsPackage.getTotalCostPrice().subtract(fsPackage.getTotalPrice()));
        if(fsPackageOrderMapper.insertFsPackageOrder(order)>0){
            String redisKey = String.valueOf(StrUtil.format("{}{}", FsConstants.REDIS_PACKAGE_ORDER_UNPAY, order.getOrderId()));
            redisCache.setCacheObject(redisKey,order.getOrderId(),30, TimeUnit.MINUTES);
            return R.ok().put("order",order);
        }
        else{
            return R.error("创建失败");
        }
    }

    @Override
    @Transactional
    public R payOrder(FsPackageOrderPayParam param) {
        //回滚事务
        //     TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        //     return return R.error("");
        //更新订单状态
        FsPackageOrder order=fsPackageOrderMapper.selectFsPackageOrderByOrderId(param.getOrderId());
        if(!order.getStatus().equals(FsPackageOrderStatusEnum.STATUS_1.getValue())){
            return R.error("非法操作");
        }
        if (param.getPayType()==null){
            return R.error("非法操作");
        }
        FsPackageOrder fsPackageOrder = new FsPackageOrder();
        fsPackageOrder.setOrderId(order.getOrderId());

        if(param.getAddressId()!=null&&param.getAddressId()>0){
            FsUserAddress address=userAddressService.selectFsUserAddressByAddressId(param.getAddressId());
            if(address!=null){
                Map<String, String> myMap = new HashMap<>();
                myMap.put("userName", address.getRealName().trim());
                myMap.put("userPhone", address.getPhone().trim());
                myMap.put("userAddress", address.getProvince()+" "+address.getCity()+" "+address.getDistrict()+" "+address.getDetail());
//                String noAdd="南通市,镇江市,淮安市,江阴市,金华市,驻马店市";
//                String[] split = noAdd.split(",");
//                for (String s : split) {
//                    if (s.equals(address.getCity())){
//                        return R.error("此地区暂不支持配送");
//                    }
//                }
//                if ("民权县".equals(address.getDistrict())){
//                    return R.error("此地区暂不支持配送");
//                }
                String addressString = JSON.toJSONString(myMap);
                fsPackageOrder.setAddressJson(addressString);
            }
        }

        FsPackageOrderComputeParam computeParam=new FsPackageOrderComputeParam();
        BeanUtil.copyProperties(param,computeParam);
        if (order.getUserCouponId()!=null&&order.getUserCouponId()>0){
            computeParam.setUserCouponId(order.getUserCouponId());
        }

        if (param.getUserCouponId()!=null&&param.getUserCouponId()>0){
            FsUserCoupon userCoupon=userCouponService.selectFsUserCouponById(param.getUserCouponId());
            FsCoupon coupon=couponService.selectFsCouponByCouponId(userCoupon.getCouponId());
            if(coupon.getMinPrice().compareTo(order.getPayPrice())==1){
                return R.error("优惠劵最低金额大于订单金额");
            }
            userCoupon.setUseTime(new Date());
            userCoupon.setBusinessId(order.getOrderId());
            userCoupon.setBusinessType(3);
            userCoupon.setStatus(1);
            userCouponService.updateFsUserCoupon(userCoupon);
        }


        Map<String,Object> moneys=computeOrderMoney(order.getTotalPrice(),computeParam);
        fsPackageOrder.setPayMoney((BigDecimal)moneys.get("payMoney"));
        fsPackageOrder.setPayPrice((BigDecimal)moneys.get("payPrice"));
        fsPackageOrder.setPayDelivery((BigDecimal)moneys.get("payDelivery"));
        if (param.getUserCouponId()!=null&&param.getUserCouponId()>0){
            fsPackageOrder.setUserCouponId(param.getUserCouponId());

        }
        fsPackageOrder.setDiscountMoney((BigDecimal)moneys.get("discountMoney"));
        fsPackageOrder.setPayRemain((BigDecimal)moneys.get("payRemain"));
        fsPackageOrder.setPayType(param.getPayType());
        fsPackageOrderMapper.updateFsPackageOrder(fsPackageOrder);
        return R.ok();

    }

    @Override
    @Transactional
    public R payConfirm(String orderSn,String payCode, String tradeNo,String payType,Integer type) {
//        Object savePoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint();
//        try {
        logger.info("进入订单");
        FsPackageOrder order=null;
        if(type.equals(1)){
            FsStorePayment storePayment = fsStorePaymentMapper.selectFsStorePaymentByPaymentCode(payCode);
            if (storePayment!=null){
                if(storePayment.getStatus().equals(0)){
                    FsStorePayment paymentMap=new FsStorePayment();
                    paymentMap.setPaymentId(storePayment.getPaymentId());
                    paymentMap.setStatus(1);
                    paymentMap.setPayTime(new Date());
                    paymentMap.setTradeNo(tradeNo);
                    if(payType.equals(PayType.微信小程序支付.getCode())){
                        paymentMap.setPayTypeCode(PayType.微信小程序支付.name());
                    }
                    else if(payType.equals(PayType.支付宝条码支付.getCode())){
                        paymentMap.setPayTypeCode(PayType.支付宝条码支付.name());
                    }
                    if (storePayment.getPayMode().equals("yb")){
                        OrderQueryDTO orderQueryDTO = new OrderQueryDTO();
                        orderQueryDTO.setUpOrderId(tradeNo);
                        OrderResult orderResult = ybPayService.getOrder(orderQueryDTO);
                        paymentMap.setBankSerialNo(orderResult.getBankOrderId());
                        paymentMap.setBankTransactionId(orderResult.getBankTrxId());
                    }
                    logger.info("更新支付记录");
                    fsStorePaymentMapper.updateFsStorePayment(paymentMap);
                    order=fsPackageOrderMapper.selectFsPackageOrderByOrderId(Long.parseLong(storePayment.getBusinessId()));
                }
            }
            else{
                logger.info("支付单号不存在:"+payCode);
                return R.error("支付单号不存在");
            }
        }
        else if(type.equals(2)){
            order=fsPackageOrderMapper.selectFsPackageOrderByOrderSn(orderSn);
        }
        if(!order.getStatus().equals(FsPackageOrderStatusEnum.STATUS_1.getValue())&&!order.getStatus().equals(FsPackageOrderStatusEnum.STATUS_NE1.getValue())){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return R.error("非法操作");
        }
//        FsStorePayment storePayment = fsStorePaymentMapper.selectFsStorePaymentByPaymentTradeNo(tradeNo);
//        storePayment.setStatus(1);
//        storePayment.setPayTime(new Date());
//        OrderQueryDTO orderQueryDTO = new OrderQueryDTO();
//        orderQueryDTO.setUpOrderId(tradeNo);
//        OrderResult payOrder = payService.getOrder(orderQueryDTO);
//        storePayment.setPayMoney(new BigDecimal(payOrder.getPayMoney()));
//        storePayment.setBankTransactionId(payOrder.getBankTrxId());
//        storePayment.setBankSerialNo(payOrder.getBankOrderId());
//
//        storePaymentService.updateFsStorePayment(storePayment);


        FsPackageOrder map = new FsPackageOrder();
        map.setOrderId(order.getOrderId());
        map.setIsPay(1);
        map.setStatus(FsPackageOrderStatusEnum.STATUS_2.getValue());
        map.setPayTime(new Date());
        map.setPrescribePrice(order.getTotalPrice());
        fsPackageOrderMapper.updateFsPackageOrder(map);


        logger.info("更改套餐包订单记录");
        //写入药品订单 写入问诊订单
        //写入订单
        Map<String,Object> packageJson = (Map)JSON.parse(order.getPackageJson());
        Integer packageSubType = (Integer)packageJson.get("packageSubType");
        if (packageSubType!=3){
            inquiryOrderService.createOrderByPackageOrder(order);
        }
        if (packageSubType!=1){
            storeOrderService.createOrderByPackageOrder(order);
            logger.info("创建订单");
        }
        FsUser fsUser = fsUserService.selectFsUserByUserId(order.getUserId());
        if (fsUser.getIsBuy()==null||fsUser.getIsBuy()==0){
            FsUser u = new FsUser();
            u.setUserId(order.getUserId());
            u.setIsBuy(1);
            fsUserService.updateFsUser(u);
        }
        //新用户首次下单公域成功
//        if (order.getCompanyUserId()==null){
//            fsUserNewTaskService.performTaskThree(fsUser.getUserId(),fsUser.getIntegral(),order.getOrderId());
//        }
        return R.ok();
//        }catch (Exception e){
//            logger.info("台州银行支付错误:"+e.getMessage());
//            TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);
//            FsStorePaymentError err = new FsStorePaymentError();
//            err.setOrderNo(orderSn);
//            err.setOrderFlowNo(tradeNo);
//            err.setStatus(0);
//            err.setMsg(e.getMessage());
//            err.setCreateTime(DateUtils.getNowDate());
//            fsStorePaymentErrorMapper.insertFsStorePaymentError(err);
//            return R.error();
//        }
    }

    @Override
    public List<FsPackageOrderListUVO> selectFsPackageOrderListUVO(FsPackageOrderListUParam param) {
        return  fsPackageOrderMapper.selectFsPackageOrderListUVO(param);
    }

    @Override
    public List<FsStorePayment> selectFsPackagePaymentByOrderId(Long orderId) {
        return  fsPackageOrderMapper.selectFsPackagePaymentByOrderId(orderId);
    }

    @Override
    public List<FsPackageOrderExcelVO> selectFsPackageOrderExcelListVO(FsPackageOrderParam fsPackageOrder) {
        List<FsPackageOrderExcelVO> list = fsPackageOrderMapper.selectFsPackageOrderExcelListVO(fsPackageOrder);

        String configValue = sysConfigMapper.selectConfigByConfigKey("his.package").getConfigValue();
        Map<String, Object> config = (Map<String, Object>) JSON.parse(configValue);
        Integer followRate = (Integer)config.get("followRate");
        for (FsPackageOrderExcelVO vo : list) {
            vo.setFollowRate(followRate);
        }
        return list;
    }
    @Transactional
    @Override
    public Integer PackageInquiryOrderRefund(Long orderId) {
        FsPackageOrder fsPackageOrder = fsPackageOrderMapper.selectFsPackageOrderByOrderId(orderId);
        FsPackage fsPackage = fsPackageMapper.selectFsPackageByPackageId(fsPackageOrder.getPackageId());
        if (fsPackageOrder.getStatus()!=2&&fsPackageOrder.getStatus()!=3){
            throw  new CustomException("非法操作");
        }
        FsInquiryOrder fsInquiryOrder = fsInquiryOrderMapper.selectFsInquiryOrderByOrderId(fsPackageOrder.getInquiryOrderId());
        if (fsInquiryOrder==null){
            throw  new CustomException("问诊订单不存在");
        }

            List<FsStorePayment> payments = fsStorePaymentMapper.selectFsStorePaymentByPay(3,orderId);
            if(payments!=null&&payments.size()==1){
                FsStorePayment payment=payments.get(0);
                String json=configService.selectConfigByKey("his.pay");
                if(payment.getPayMode().equals("wx")){
                    WxPayConfig payConfig = new WxPayConfig();
                    payConfig.setAppId(wxPayProperties.getAppId());
                    payConfig.setMchId(wxPayProperties.getMchId());
                    payConfig.setKeyPath(wxPayProperties.getKeyPath());
                    payConfig.setMchKey(wxPayProperties.getMchKey());
                    payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                    payConfig.setSubMchId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                    wxPayService.setConfig(payConfig);
                    WxPayRefundRequest refundRequest = new WxPayRefundRequest();
                    refundRequest.setOutTradeNo("package-"+payment.getPayCode());
                    refundRequest.setOutRefundNo("package-"+payment.getPayCode());
                    refundRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(payment.getPayMoney().toString()));
                    refundRequest.setRefundFee(WxPayUnifiedOrderRequest.yuanToFen(payment.getPayMoney().toString()));
                    try {
                        WxPayRefundResult refundResult = wxPayService.refund(refundRequest);
                        WxPayRefundQueryResult refundQueryResult = wxPayService.refundQuery("", refundResult.getOutTradeNo(), refundResult.getOutRefundNo(), refundResult.getRefundId());
                        if(refundQueryResult!=null&&refundQueryResult.getResultCode().equals("SUCCESS")){
                            FsStorePayment paymentMap=new FsStorePayment();
                            paymentMap.setPaymentId(payment.getPaymentId());
                            paymentMap.setStatus(-1);
                            paymentMap.setRefundTime(DateUtils.getNowDate());
                            paymentMap.setRefundMoney(payment.getPayMoney());
                            fsStorePaymentMapper.updateFsStorePayment(paymentMap);
                        }
                        else {
                            throw new CustomException("退款请求失败"+refundQueryResult.getReturnMsg());
                        }
                    } catch (WxPayException e) {
                        throw new CustomException("退款请求失败"+e.getReturnMsg());
                    }
                }
                else if(payment.getPayMode().equals("yb")){
                    //易宝
                    RefundDTO refundDTO=new RefundDTO();
                    refundDTO.setRefundMoney(payment.getPayMoney().toString());
                    refundDTO.setLowRefundNo("package-"+payment.getPayCode());
                    refundDTO.setUpOrderId(payment.getTradeNo());
                    com.fs.ybPay.domain.RefundResult result=payService.refund(refundDTO);
                    if(result.getState().equals("5")){
                        FsStorePayment paymentMap=new FsStorePayment();
                        paymentMap.setPaymentId(payment.getPaymentId());
                        paymentMap.setStatus(-1);
                        paymentMap.setRefundTime(DateUtils.getNowDate());
                        paymentMap.setRefundMoney(payment.getPayMoney());
                        fsStorePaymentMapper.updateFsStorePayment(paymentMap);
                    }
                }
                else if(payment.getPayMode().equals("tz")){
                    RefundParam tzBankResult = new RefundParam();
                    // 使用set方法为对象的字段赋值
                    //商户原支付订单号
                    tzBankResult.setOldPayOutOrderNo("package"+payment.getPayCode());
                    // 商户退款订单号 对接平台系统里自己生成的退款订单号
                    tzBankResult.setRefundOrderNo("package"+payment.getPayCode());
                    // 交易发送时间 yyyyMMddHHmmss
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
                    tzBankResult.setTrxSendTime(sdf.format(new Date()));
                    // 退款金额
                    tzBankResult.setRefundOrdTransAmt(payment.getPayMoney().doubleValue());
                    TzBankResult<com.fs.tzBankPay.doman.RefundResult> result = tzBankService.refund(tzBankResult);
                    if(result.getBody().getRefundOrdStatus().equals("90")){
                        FsStorePayment paymentMap=new FsStorePayment();
                        paymentMap.setPaymentId(payment.getPaymentId());
                        paymentMap.setStatus(-1);
                        paymentMap.setRefundTime(DateUtils.getNowDate());
                        paymentMap.setRefundMoney(payment.getPayMoney());
                        fsStorePaymentMapper.updateFsStorePayment(paymentMap);
                    }
                }
            }
            fsPackageOrder.setStatus(-2);
            fsPackageOrder.setRefundStatus(2);
            fsPackageOrderMapper.updateFsPackageOrder(fsPackageOrder);
            fsInquiryOrder.setStatus(-2);
            return  fsInquiryOrderMapper.updateFsInquiryOrder(fsInquiryOrder);
        //退款操作
    }

    @Override
    public Integer PackageStoreOrderRefund(Long orderId) {
        FsPackageOrder fsPackageOrder = fsPackageOrderMapper.selectFsPackageOrderByOrderId(orderId);
        if (fsPackageOrder.getStatus()!=2&&fsPackageOrder.getStatus()!=3){
            throw  new CustomException("非法操作");
        }
        FsStoreOrder fsStoreOrder = fsStoreOrderService.selectFsStoreOrderByOrderId(fsPackageOrder.getStoreOrderId());
        if (fsStoreOrder==null){
            throw  new CustomException("商品订单不存在");
        }
        FsStoreOrderSalesParam fsStoreOrderSalesParam = new FsStoreOrderSalesParam();
        fsStoreOrderSalesParam.setOrderId(fsPackageOrder.getStoreOrderId());
        return fsStoreOrderService.afterSales(fsStoreOrderSalesParam);
    }

    @Override
    @Transactional
    public R payment(FsPackageOrderDoPayParam param) {
        //回滚事务
        //     TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        //     return return R.error("");
        //更新订单状态
        FsPackageOrder fsPackageOrder=fsPackageOrderMapper.selectFsPackageOrderByOrderId(param.getOrderId());
        if(!fsPackageOrder.getStatus().equals(FsPackageOrderStatusEnum.STATUS_1.getValue())){
            return R.error("非法操作");
        }
        if (fsPackageOrder.getPayType()==null||fsPackageOrder.getAddressJson()==null||fsPackageOrder.getAddressJson()==""){
            FsPackageOrderCancelParam fsPackageOrderCancelParam = new FsPackageOrderCancelParam();
            fsPackageOrderCancelParam.setOrderId(param.getOrderId());

            return R.error("非法操作");
        }

        FsUser user=userService.selectFsUserByUserId(param.getUserId());
        if(user!=null&& StringUtils.isNotEmpty(user.getMaOpenId())){
            if(fsPackageOrder.getPayMoney().compareTo(new BigDecimal(0))==1){
                String json = configService.selectConfigByKey("his.pay");
                PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
                String payCode =  OrderCodeUtils.getOrderSn();
                if(StringUtils.isEmpty(payCode)){
                    return R.error("订单生成失败，请重试");
                }
                FsStorePayment storePayment=new FsStorePayment();
                storePayment.setStatus(0);
                storePayment.setPayMode(payConfigDTO.getType());
                storePayment.setBusinessCode(fsPackageOrder.getOrderSn());
                storePayment.setPayCode(payCode);
                storePayment.setPayMoney(fsPackageOrder.getPayMoney());
                storePayment.setCreateTime(new Date());
                storePayment.setPayTypeCode("weixin");
                storePayment.setBusinessType(3);
                storePayment.setCompanyId(fsPackageOrder.getCompanyId());
                storePayment.setCompanyUserId(fsPackageOrder.getCompanyUserId());
                storePayment.setRemark("套餐包订单支付");
                storePayment.setOpenId(user.getMaOpenId());
                storePayment.setUserId(user.getUserId());
                storePayment.setStoreId(fsPackageOrder.getStoreId());
                storePayment.setBusinessId(fsPackageOrder.getOrderId().toString());
                if(storePaymentService.insertFsStorePayment(storePayment)>0){
                    if (payConfigDTO.getType().equals("wx")) {
                        //创建微信订单
                        WxPayConfig payConfig = new WxPayConfig();
                        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
                        FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
                        payConfig.setAppId(fsPayConfig.getAppId());
                        payConfig.setMchId(fsPayConfig.getWxMchId());
                        payConfig.setMchKey(fsPayConfig.getWxMchKey());
                        payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                        payConfig.setSubMchId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                        payConfig.setKeyPath(null);
                        payConfig.setNotifyUrl(wxPayProperties.getNotifyUrl());
                        wxPayService.setConfig(payConfig);
                        WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
                        orderRequest.setOpenid(user.getMaOpenId());//公众号支付提供用户openid
                        orderRequest.setBody("套餐包订单支付");
                        orderRequest.setOutTradeNo("package-" + storePayment.getPayCode());
                        orderRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(storePayment.getPayMoney().toString()));//测试
                        //orderRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(money));//测试
                        orderRequest.setTradeType("JSAPI");
                        orderRequest.setSpbillCreateIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
                        //调用统一下单接口，获取"预支付交易会话标识"
                        try {
                            WxPayMpOrderResult orderResult = wxPayService.createOrder(orderRequest);
                            return R.ok().put("data", orderResult).put("type", "wx").put("isPay", 0);
                        } catch (WxPayException e) {
                            e.printStackTrace();
                            throw new CustomException("支付失败" + e.getMessage());
                        }
                    } else if (payConfigDTO.getType().equals("yb")) {
                        WxJspayDTO p = new WxJspayDTO();
                        // 使用setter方法为对象赋值
                        p.setPayMoney(storePayment.getPayMoney().toString());
                        p.setLowOrderId("package-" + storePayment.getPayCode());
                        p.setBody("套餐包订单支付");
                        p.setIsMinipg("1");
                        p.setOpenId(user.getMaOpenId());
                        p.setAttach("");
                        p.setStoreid("0");
                        CreateWxOrderResult wxOrder = payService.createWxOrder(p);
                        logger.info("易宝返回"+wxOrder);
                        if (wxOrder.getStatus().equals("100")) {
                            FsStorePayment mt=new FsStorePayment();
                            mt.setPaymentId(storePayment.getPaymentId());
                            mt.setTradeNo(wxOrder.getUpOrderId());
                            fsStorePaymentMapper.updateFsStorePayment(mt);
                            return R.ok().put("isPay", 0).put("data", wxOrder).put("type", "yb");
                        } else {
                            throw new CustomException("支付失败");
                        }
                    } else if (payConfigDTO.getType().equals("tz")) {
                        PayCreateOrder o = new PayCreateOrder();
                        o.setOrderNo("package" + storePayment.getPayCode()); // 业务系统订单号
                        o.setTrxAmt(storePayment.getPayMoney().doubleValue()); // 交易金额
                        o.setBusinessCstNo(fsPackageOrder.getUserId().toString()); // 业务平台客户号
                        String phone="";
                        if (user.getPhone()!=null&&user.getPhone().length()>4){
                            phone=user.getPhone().substring(user.getPhone().length()-4);
                            if (user.getPhone().length()>11){
                                o.setPayerMobileNo(PhoneUtil.decryptPhone(user.getPhone()));
                            }else {
                                o.setPayerMobileNo(user.getPhone());
                            }
                        }
                        o.setPayerName("微信用户"+phone);
                        o.setGoodsInfo("套餐包订单支付"); // 订单信息
                        o.setOpenId(user.getMaOpenId());
                        o.setOrderType(3);
                        o.setOrderId(fsPackageOrder.getOrderId().toString());
                        TzBankResult<PayCreateOrderResult> result = tzBankService.createOrder(o);
                        FsStorePayment mt=new FsStorePayment();
                        mt.setPaymentId(storePayment.getPaymentId());
                        mt.setTradeNo(result.getBody().getOrderFlowNo());
                        fsStorePaymentMapper.updateFsStorePayment(mt);
                        return R.ok().put("isPay", 0).put("data", result).put("type", "tz");
                    }else if (payConfigDTO.getType().equals("hf")) {
                        logger.info("创建汇付订单");
                        HuiFuCreateOrder o = new HuiFuCreateOrder();
                        o.setTradeType("T_MINIAPP");
                        o.setOpenid(user.getMaOpenId());
                        o.setReqSeqId("package-"+storePayment.getPayCode());
                        o.setTransAmt(storePayment.getPayMoney().toString());
                        o.setGoodsDesc("套餐包订单支付");
                        HuifuCreateOrderResult result = huiFuService.createOrder(o);
                        logger.info("创建汇付支付："+result);
                        FsStorePayment mt=new FsStorePayment();
                        mt.setPaymentId(storePayment.getPaymentId());
                        mt.setTradeNo(result.getHf_seq_id());
                        storePaymentService.updateFsStorePayment(mt);
                        return R.ok().put("isPay", 0).put("data", result).put("type", "hf");
                    }
                }
            }
            else{
                this.payConfirm(fsPackageOrder.getOrderSn(),"","","",2);
                return R.ok().put("isPay",1);
            }
        }
        else{
            return R.error("用户OPENID不存在");
        }
        return R.error();
    }

    @Override
    @Transactional
    public R cancel(FsPackageOrderCancelParam param) {
        FsPackageOrder order=fsPackageOrderMapper.selectFsPackageOrderByOrderId(param.getOrderId());
        if(!order.getStatus().equals(FsPackageOrderStatusEnum.STATUS_1.getValue())){
            return R.error("非法操作");
        }
        else{
            FsPackageOrder map=new FsPackageOrder();
            map.setOrderId(param.getOrderId());
            map.setStatus(-1);
            fsPackageOrderMapper.updateFsPackageOrder(map);
            if (order.getUserCouponId()!=null&&order.getUserCouponId()>0){
                FsUserCoupon coupon=userCouponService.selectFsUserCouponById(order.getUserCouponId());
                if(coupon.getStatus().equals(1)){
                    FsUserCoupon userCoupon=new FsUserCoupon();
                    userCoupon.setId(order.getUserCouponId());
                    userCoupon.setStatus(0);
                    userCouponService.updateFsUserCoupon(userCoupon);

                }

            }
            return R.ok();
        }
    }


    public byte[] getWxaCodeUnLimit(Long orderId) {
        FsSysConfig sysConfig = configUtil.getSysConfig();
        String url="https://api.weixin.qq.com/cgi-bin/stable_token";
        HashMap<String, String> map = new HashMap<>();
        map.put("grant_type","client_credential");
        map.put("appid",sysConfig.getAppid());
        map.put("secret",sysConfig.getSecret());


        String accessToken = HttpUtil.endApi(url, null, map);
        Map<String, String> accessTokenMap  = new Gson().fromJson(accessToken, new TypeToken<Map<String, Object>>(){}.getType());
        String codeUrl="https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token="+accessTokenMap.get("access_token");
        HashMap<String, String> jsonMap = new HashMap<>();
        jsonMap.put("page","pages_order/packageOrderDetails");
        jsonMap.put("scene","orderId="+ orderId);
        System.out.println(orderId);
        //正式版为 "release"，体验版为 "trial"，开发版为 "develop"
        jsonMap.put("env_version","release");
        byte[] bytes = HttpUtil.getWechatQrcodeByHttpURL(codeUrl, jsonMap);
        return bytes;
    }

    @Override
    public R aliPayment(FsPackageOrderDoPayParam param) {
        //更新订单状态
        FsPackageOrder fsPackageOrder=fsPackageOrderMapper.selectFsPackageOrderByOrderId(param.getOrderId());
        if(!fsPackageOrder.getStatus().equals(FsPackageOrderStatusEnum.STATUS_1.getValue())){
            return R.error("非法操作");
        }
        //如果存在优惠券  判断优惠券是否已使用
        FsUser user=userService.selectFsUserByUserId(param.getUserId());
        if(user!=null){
            if(fsPackageOrder.getPayMoney().compareTo(new BigDecimal(0))==1){
                String payCode =  OrderCodeUtils.getOrderSn();
                if(StringUtils.isEmpty(payCode)){
                    return R.error("订单生成失败，请重试");
                }
                String json = configService.selectConfigByKey("his.pay");
                PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
                FsStorePayment storePayment=new FsStorePayment();
                storePayment.setStatus(0);
                storePayment.setPayMode(payConfigDTO.getType());
                storePayment.setBusinessCode(fsPackageOrder.getOrderSn());
                storePayment.setPayCode(payCode);
                storePayment.setPayMoney(fsPackageOrder.getPayMoney());
                storePayment.setCreateTime(new Date());
                storePayment.setPayTypeCode("alipay");
                storePayment.setBusinessType(3);
                storePayment.setCompanyId(fsPackageOrder.getCompanyId());
                storePayment.setCompanyUserId(fsPackageOrder.getCompanyUserId());
                storePayment.setRemark("套餐包订单支付");
//                storePayment.setOpenId(user.getMpOpenId());
                storePayment.setUserId(user.getUserId());
                storePayment.setStoreId(fsPackageOrder.getStoreId());
                storePayment.setBusinessId(fsPackageOrder.getOrderId().toString());
                if(storePaymentService.insertFsStorePayment(storePayment)>0){

                    if (payConfigDTO.getType().equals("yb")) {
                        return R.error("支付暂不可用!");
                    } else if (payConfigDTO.getType().equals("tz")) {
                        PayCreateOrder o = new PayCreateOrder();
                        o.setOrderNo("package" + storePayment.getPayCode()); // 业务系统订单号
                        o.setTrxAmt(storePayment.getPayMoney().doubleValue()); // 交易金额
                        o.setBusinessCstNo(fsPackageOrder.getUserId().toString()); // 业务平台客户号
                        String phone="";
                        if (user.getPhone()!=null&&user.getPhone().length()>4){
                            phone=user.getPhone().substring(user.getPhone().length()-4);
                        }
                        o.setPayerName("微信用户"+phone);
                        o.setGoodsInfo("套餐包订单支付"); // 订单信息
//                        o.setOpenId(user.getMpOpenId());
                        o.setOrderType(3);
                        o.setOrderId(fsPackageOrder.getOrderId().toString());
                        o.setPayType(Arrays.asList(PayType.支付宝条码支付.getCode()));
                        TzBankResult<PayCreateOrderResult> result = tzBankService.createOrder(o);
                        FsStorePayment mt=new FsStorePayment();
                        mt.setPaymentId(storePayment.getPaymentId());
                        mt.setTradeNo(result.getBody().getOrderFlowNo());
                        fsStorePaymentMapper.updateFsStorePayment(mt);
                        return R.ok().put("isPay", 0).put("data", result).put("type", "tz");
                    }else if (payConfigDTO.getType().equals("hf")) {
                        logger.info("创建汇付订单");
                        HuiFuCreateOrder o = new HuiFuCreateOrder();
                        o.setTradeType("A_NATIVE");
                        o.setReqSeqId("package-"+storePayment.getPayCode());
                        o.setTransAmt(storePayment.getPayMoney().toString());
                        o.setGoodsDesc("套餐包订单支付");
                        HuifuCreateOrderResult result = huiFuService.createOrder(o);
                        logger.info("创建汇付支付："+result);
                        FsStorePayment mt=new FsStorePayment();
                        mt.setPaymentId(storePayment.getPaymentId());
                        mt.setTradeNo(result.getHf_seq_id());
                        storePaymentService.updateFsStorePayment(mt);
                        return R.ok().put("isPay", 0).put("data", result).put("type", "hf");
                    }
                }
            }
            else{
                this.payConfirm(fsPackageOrder.getOrderSn(),"","","",2);
                return R.ok().put("isPay",1);
            }
        }
        else{
            return R.error("用户不存在");
        }
        return R.error();
    }

    @Override
    public R H5WxPayment(FsPackageOrderDoPayParam param) {
        //更新订单状态
        FsPackageOrder fsPackageOrder=fsPackageOrderMapper.selectFsPackageOrderByOrderId(param.getOrderId());
        if(!fsPackageOrder.getStatus().equals(FsPackageOrderStatusEnum.STATUS_1.getValue())){
            return R.error("非法操作");
        }
        //如果存在优惠券  判断优惠券是否已使用
        FsUser user=userService.selectFsUserByUserId(param.getUserId());
        if(user!=null&& StringUtils.isNotEmpty(user.getMpOpenId())){
            if(fsPackageOrder.getPayMoney().compareTo(new BigDecimal(0))==1){
                String json = configService.selectConfigByKey("his.pay");
                PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
                String payCode =  OrderCodeUtils.getOrderSn();
                if(StringUtils.isEmpty(payCode)){
                    return R.error("订单生成失败，请重试");
                }
                FsStorePayment storePayment=new FsStorePayment();
                storePayment.setStatus(0);
                storePayment.setPayMode(payConfigDTO.getType());
                storePayment.setBusinessCode(fsPackageOrder.getOrderSn());
                storePayment.setPayCode(payCode);
                storePayment.setPayMoney(fsPackageOrder.getPayMoney());
                storePayment.setCreateTime(new Date());
                storePayment.setPayTypeCode("微信");
                storePayment.setBusinessType(3);
                storePayment.setCompanyId(fsPackageOrder.getCompanyId());
                storePayment.setCompanyUserId(fsPackageOrder.getCompanyUserId());
                storePayment.setRemark("套餐包订单支付");
                storePayment.setOpenId(user.getMpOpenId());
                storePayment.setUserId(user.getUserId());
                storePayment.setStoreId(fsPackageOrder.getStoreId());
                storePayment.setBusinessId(fsPackageOrder.getOrderId().toString());
                if(storePaymentService.insertFsStorePayment(storePayment)>0){
                    if (payConfigDTO.getType().equals("yb")) {
                        return R.error("支付暂不可用!");
                    } else if (payConfigDTO.getType().equals("tz")) {
                        PayCreateOrder o = new PayCreateOrder();
                        o.setOrderNo("package" + storePayment.getPayCode()); // 业务系统订单号
                        o.setTrxAmt(storePayment.getPayMoney().doubleValue()); // 交易金额
                        o.setBusinessCstNo(fsPackageOrder.getUserId().toString()); // 业务平台客户号
                        String phone="";
                        if (user.getPhone()!=null&&user.getPhone().length()>4){
                            phone=user.getPhone().substring(user.getPhone().length()-4);
                        }
                        o.setPayerName("微信用户"+phone);
                        o.setGoodsInfo("套餐包订单支付"); // 订单信息
                        o.setOpenId(user.getMpOpenId());
                        o.setOrderType(3);
                        o.setOrderId(fsPackageOrder.getOrderId().toString());
                        o.setPayType(Arrays.asList(PayType.微信公众号.getCode()));
                        TzBankResult<PayCreateOrderResult> result = tzBankService.createOrder(o);
                        FsStorePayment mt=new FsStorePayment();
                        mt.setPaymentId(storePayment.getPaymentId());
                        mt.setTradeNo(result.getBody().getOrderFlowNo());
                        fsStorePaymentMapper.updateFsStorePayment(mt);
                        return R.ok().put("isPay", 0).put("data", result).put("type", "tz");
                    }else if (payConfigDTO.getType().equals("hf")) {
                        logger.info("创建汇付订单");
                        HuiFuCreateOrder o = new HuiFuCreateOrder();
                        o.setTradeType("T_JSAPI");
                        o.setOpenid(user.getMpOpenId());
                        o.setReqSeqId("package-"+storePayment.getPayCode());
                        o.setTransAmt(storePayment.getPayMoney().toString());
                        o.setGoodsDesc("套餐包订单支付");
                        HuifuCreateOrderResult result = huiFuService.createOrder(o);
                        logger.info("创建汇付支付："+result);
                        FsStorePayment mt=new FsStorePayment();
                        mt.setPaymentId(storePayment.getPaymentId());
                        mt.setTradeNo(result.getHf_seq_id());
                        storePaymentService.updateFsStorePayment(mt);
                        return R.ok().put("isPay", 0).put("data", result).put("type", "hf");
                    }

                }
            }
            else{
                this.payConfirm(fsPackageOrder.getOrderSn(),"","","",2);
                return R.ok().put("isPay",1);
            }
        }
        else{
            return R.error("用户OPENID不存在");
        }
        return R.error();
    }

    @Override
    public R h5AliPayment(FsPackageOrderDoPayParam param) {
        //更新订单状态
        FsPackageOrder fsPackageOrder=fsPackageOrderMapper.selectFsPackageOrderByOrderId(param.getOrderId());
        if(!fsPackageOrder.getStatus().equals(FsPackageOrderStatusEnum.STATUS_1.getValue())){
            return R.error("非法操作");
        }
        //如果存在优惠券  判断优惠券是否已使用
        FsUser user=userService.selectFsUserByUserId(param.getUserId());
        if(user!=null){
            if(fsPackageOrder.getPayMoney().compareTo(new BigDecimal(0))==1){
                String payCode =  OrderCodeUtils.getOrderSn();
                if(StringUtils.isEmpty(payCode)){
                    return R.error("订单生成失败，请重试");
                }
                String json = configService.selectConfigByKey("his.pay");
                PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
                FsStorePayment storePayment=new FsStorePayment();
                storePayment.setStatus(0);
                storePayment.setPayMode(payConfigDTO.getType());
                storePayment.setBusinessCode(fsPackageOrder.getOrderSn());
                storePayment.setPayCode(payCode);
                storePayment.setPayMoney(fsPackageOrder.getPayMoney());
                storePayment.setCreateTime(new Date());
                storePayment.setPayTypeCode("alipay");
                storePayment.setBusinessType(3);
                storePayment.setCompanyId(fsPackageOrder.getCompanyId());
                storePayment.setCompanyUserId(fsPackageOrder.getCompanyUserId());
                storePayment.setRemark("套餐包订单支付");
                storePayment.setOpenId(user.getMpOpenId());
                storePayment.setUserId(user.getUserId());
                storePayment.setStoreId(fsPackageOrder.getStoreId());
                storePayment.setBusinessId(fsPackageOrder.getOrderId().toString());
                if(storePaymentService.insertFsStorePayment(storePayment)>0){

                    if (payConfigDTO.getType().equals("yb")) {
                        return R.error("支付暂不可用!");
                    } else if (payConfigDTO.getType().equals("tz")) {
                        PayCreateOrder o = new PayCreateOrder();
                        o.setOrderNo("package" + storePayment.getPayCode()); // 业务系统订单号
                        o.setTrxAmt(storePayment.getPayMoney().doubleValue()); // 交易金额
                        o.setBusinessCstNo(fsPackageOrder.getUserId().toString()); // 业务平台客户号
                        String phone="";
                        if (user.getPhone()!=null&&user.getPhone().length()>4){
                            phone=user.getPhone().substring(user.getPhone().length()-4);
                        }
                        o.setPayerName("微信用户"+phone);
                        o.setGoodsInfo("套餐包订单支付"); // 订单信息
                        o.setOpenId(user.getMpOpenId());
                        o.setOrderType(3);
                        o.setOrderId(fsPackageOrder.getOrderId().toString());
                        o.setPayType(Arrays.asList(PayType.支付宝条码支付.getCode()));
                        TzBankResult<PayCreateOrderResult> result = tzBankService.createOrder(o);
                        FsStorePayment mt=new FsStorePayment();
                        mt.setPaymentId(storePayment.getPaymentId());
                        mt.setTradeNo(result.getBody().getOrderFlowNo());
                        fsStorePaymentMapper.updateFsStorePayment(mt);
                        return R.ok().put("isPay", 0).put("data", result).put("type", "tz");
                    }else if (payConfigDTO.getType().equals("hf")) {
                        logger.info("创建汇付订单");
                        HuiFuCreateOrder o = new HuiFuCreateOrder();
                        o.setTradeType("A_NATIVE");
                        o.setReqSeqId("package-"+storePayment.getPayCode());
                        o.setTransAmt(storePayment.getPayMoney().toString());
                        o.setGoodsDesc("套餐包订单支付");
                        HuifuCreateOrderResult result = huiFuService.createOrder(o);
                        logger.info("创建汇付支付："+result);
                        FsStorePayment mt=new FsStorePayment();
                        mt.setPaymentId(storePayment.getPaymentId());
                        mt.setTradeNo(result.getHf_seq_id());
                        storePaymentService.updateFsStorePayment(mt);
                        return R.ok().put("isPay", 0).put("data", result).put("type", "hf");
                    }



                }
            }
            else{
                this.payConfirm(fsPackageOrder.getOrderSn(),"","","",2);
                return R.ok().put("isPay",1);
            }
        }
        else{
            return R.error("用户不存在");
        }
        return R.error();
    }

    @Override
    public Integer selectFsPackageOrderCount(Integer status,Long userId) {
        return fsPackageOrderMapper.selectFsPackageOrderCount(status,userId);
    }

    @Override
    public Boolean isEntityNull(FsPackageOrderParam param) {
        if (param == null) {
            return true; // 整个实体对象为null
        }
        Integer status = param.getStatus();
        param.setStatus(null);
        Class<? extends FsPackageOrderParam> entityClass = param.getClass();
        Field[] fields = entityClass.getDeclaredFields();
        try {
            for (Field field : fields) {
                field.setAccessible(true);
                Object value = field.get(param);
                if (value != null) {
                    return false; // 实体对象中有字段不为null
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        param.setStatus(status);
        return true; // 实体对象内所有字段为null
    }

    @Override
    public Long selectFsPackageOrderExcelListVOCount(FsPackageOrderParam fsPackageOrder) {
        return fsPackageOrderMapper.selectFsPackageOrderExcelListVOCount(fsPackageOrder);
    }
    @Autowired
    private IFsExportTaskService exportTaskService;
    @Async
    @Override
    public void exportData(FsPackageOrderParam fsPackageOrder) {
        List<FsPackageOrderExcelVO> list = fsPackageOrderMapper.selectFsPackageOrderExcelListVO(fsPackageOrder);

        String configValue = sysConfigMapper.selectConfigByConfigKey("his.package").getConfigValue();
        Map<String, Object> config = (Map<String, Object>) JSON.parse(configValue);
        Integer followRate = (Integer)config.get("followRate");
        for (FsPackageOrderExcelVO vo : list) {
            vo.setFollowRate(followRate);
        }
        ExcelUtil<FsPackageOrderExcelVO> util = new ExcelUtil<FsPackageOrderExcelVO>(FsPackageOrderExcelVO.class);
        AjaxResult result= util.exportExcel(list, "套餐包导出");
        FsExportTask task=exportTaskService.selectFsExportTaskByTaskId(fsPackageOrder.getTaskId());
        task.setFinishTime(new Date());
        task.setStatus(1);
        task.setFileUrl(result.get("msg").toString());
        exportTaskService.updateFsExportTask(task);
    }

    @Override
    public FsPackage selectFsPackageByOrderId(Long packageOrderId) {
        return fsPackageOrderMapper.selectFsPackageByOrderId(packageOrderId);
    }

    @Override
    public R addPackageOrder(FsPackageOrderAddParam param) {
        FsPatient patient=null;
        if(param.getPatientId()!=null){
            patient=fsPatientMapper.selectFsPatientByPatientId(param.getPatientId());
        }else {
            return R.error("请提交患者信息");
        }
        FsPackage fsPackage=fsPackageMapper.selectFsPackageByPackageId(param.getPackageId());
        if(fsPackage.getStatus().equals(0)){
            return R.error("套餐名已下架");
        }


        if (fsPackage.getIsShow()==0&&param.getCompanyId()==null){
            return R.error("商品信息过期");
        }
        Integer num = fsPackage.getNum();
        if (num!=0){
            int i = fsPackageMapper.selectFsPackageListByUser(param.getUserId(), fsPackage.getPackageId());
            if (i>=num){
                return R.error("超过限购次数");
            }
        }
        if (patient==null){
            return R.error("请提交患者信息");
        }
        FsPackageOrder  order=new FsPackageOrder();
        String orderSn =  OrderCodeUtils.getOrderSn();
        if(StringUtils.isEmpty(orderSn)){
            return R.error("订单生成失败，请重试");
        }
        order.setOrderSn(orderSn);
        order.setStoreId(fsPackage.getStoreId());
        order.setUserId(param.getUserId());
        order.setPackageId(param.getPackageId());
        order.setPackageName(fsPackage.getPackageName());
        order.setTotalPrice(fsPackage.getTotalPrice());
        order.setIcdCode(fsPackage.getIcdCode());
        order.setPayPrice(fsPackage.getTotalPrice());
        order.setPayMoney(fsPackage.getTotalPrice());
        order.setIsPay(0);
        order.setPackageSecondName(fsPackage.getSecondName());
        order.setDoctorRemark(fsPackage.getDoctorRemark());
        order.setFollowTempId(fsPackage.getFollowTempId());
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.package");
        Map<String, Object> config = (Map<String, Object>) JSON.parse(sysConfig.getConfigValue());
        Integer followRate = (Integer)config.get("followRate");
        calendar.add(Calendar.DAY_OF_MONTH, followRate);
        order.setFollowTime(calendar.getTime());
        order.setFollowRate(followRate);
        order.setPackageSubType(fsPackage.getPackageSubType());
        order.setDays(fsPackage.getCycle());
        order.setStatus(1);
        order.setStartTime(new Date());
        order.setCompanyUserId(param.getCompanyUserId());
        if (param.getCompanyUserId()!=null){
            CompanyUser companyUser = companyUserMapper.selectCompanyUserById(param.getCompanyUserId());
            if (companyUser!=null){
                order.setDeptId(companyUser.getDeptId());
            }
        }
        order.setCompanyId(param.getCompanyId());
        Calendar c = Calendar.getInstance();
        c.setTime(order.getStartTime());
        c.add(Calendar.DAY_OF_MONTH, fsPackage.getCycle());
        order.setFinishTime(c.getTime());
        order.setFormJson("[{\"title\":\"您是否已在线下就诊，且对所购买的药品无过敏或不良反应？\",\"options\":[{\"name\":\"是，我线下就诊过\",\"value\":1,\"color\":\"green\"},{\"name\":\"无，从未就诊\",\"value\":0,\"color\":\"red\"}],\"option\":\"是，我线下就诊过\"},{\"title\":\"您是否已详细阅读药物说明，确认自己符合药物适用人群，并了解用药方法、用药禁忌等信息?\",\"options\":[{\"name\":\"是，我已充分了解\",\"value\":1,\"color\":\"green\"},{\"name\":\"否，未阅读\",\"value\":0,\"color\":\"red\"}],\"option\":\"是，我已充分了解\"}]");
        order.setPackageJson(JSONUtil.toJsonStr(fsPackage));
        order.setCreateTime(new Date());
        if(patient!=null){
            order.setPatientJson(JSONUtil.toJsonStr(patient));
        }
        order.setInquiryCostPrice(fsPackage.getInquiryCostPrice());
        order.setProductCostPrice(fsPackage.getProductCostPrice());
        order.setTotalCostPrice(fsPackage.getTotalCostPrice());
        order.setCycle(fsPackage.getCycle());
        order.setCostDiscountMoney(fsPackage.getTotalCostPrice().subtract(fsPackage.getTotalPrice()));

        FsUserAddress address=userAddressService.selectFsUserAddressByAddressId(param.getAddressId());
        if(address!=null){
            Map<String, String> myMap = new HashMap<>();
            myMap.put("userName", address.getRealName().trim());
            myMap.put("userPhone", address.getPhone().trim());
            myMap.put("userAddress", address.getProvince()+" "+address.getCity()+" "+address.getDistrict()+" "+address.getDetail());
            String addressString = JSON.toJSONString(myMap);
            order.setAddressJson(addressString);
        }else {
            return R.error("地址错误");
        }


        FsPackageOrderComputeParam computeParam=new FsPackageOrderComputeParam();
        BeanUtil.copyProperties(param,computeParam);

        Map<String,Object> moneys=computeOrderMoney(order.getTotalPrice(),computeParam);
        order.setPayMoney((BigDecimal)moneys.get("payMoney"));
        order.setPayPrice((BigDecimal)moneys.get("payPrice"));
        order.setPayDelivery((BigDecimal)moneys.get("payDelivery"));
        order.setDiscountMoney((BigDecimal)moneys.get("discountMoney"));
        order.setPayRemain((BigDecimal)moneys.get("payRemain"));
        order.setPayType(param.getPayType());

        if(fsPackageOrderMapper.insertFsPackageOrder(order)>0){
            String redisKey = String.valueOf(StrUtil.format("{}{}", FsConstants.REDIS_PACKAGE_ORDER_UNPAY, order.getOrderId()));
            redisCache.setCacheObject(redisKey,order.getOrderId(),30, TimeUnit.MINUTES);
            return R.ok().put("order",order);
        }
        else{
            return R.error("创建失败");
        }
    }
}
