package com.doumee.service.business.impl; 
 | 
  
 | 
import com.doumee.core.constants.Constants; 
 | 
import com.doumee.core.constants.ResponseStatus; 
 | 
import com.doumee.core.exception.BusinessException; 
 | 
import com.doumee.core.model.PageData; 
 | 
import com.doumee.core.model.PageWrap; 
 | 
import com.doumee.core.utils.DateUtil; 
 | 
import com.doumee.core.utils.Utils; 
 | 
import com.doumee.core.wx.WxMiniConfig; 
 | 
import com.doumee.core.wx.WxPayProperties; 
 | 
import com.doumee.dao.business.WxBillDetailMapper; 
 | 
import com.doumee.dao.business.WxBillMapper; 
 | 
import com.doumee.dao.business.model.Goodsorder; 
 | 
import com.doumee.dao.business.model.WxBill; 
 | 
import com.doumee.dao.business.model.WxBillDetail; 
 | 
import com.doumee.service.business.WxBillService; 
 | 
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 
 | 
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; 
 | 
import com.baomidou.mybatisplus.core.metadata.IPage; 
 | 
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 
 | 
import com.github.binarywang.wxpay.bean.request.WxPayDownloadBillRequest; 
 | 
import com.github.binarywang.wxpay.bean.result.WxPayBillInfo; 
 | 
import com.github.binarywang.wxpay.bean.result.WxPayBillResult; 
 | 
import com.github.binarywang.wxpay.exception.WxPayException; 
 | 
import lombok.Synchronized; 
 | 
import org.apache.commons.lang3.StringUtils; 
 | 
import org.checkerframework.checker.units.qual.C; 
 | 
import org.springframework.beans.factory.annotation.Autowired; 
 | 
import org.springframework.scheduling.annotation.Async; 
 | 
import org.springframework.stereotype.Service; 
 | 
import org.springframework.transaction.annotation.Transactional; 
 | 
import org.springframework.util.CollectionUtils; 
 | 
  
 | 
import java.math.BigDecimal; 
 | 
import java.math.RoundingMode; 
 | 
import java.util.*; 
 | 
  
 | 
/** 
 | 
 * Service实现 
 | 
 * @author 江蹄蹄 
 | 
 * @date 2023/09/27 18:08 
 | 
 */ 
 | 
@Service 
 | 
public class WxBillServiceImpl implements WxBillService { 
 | 
  
 | 
    @Autowired 
 | 
    private WxBillMapper wxBillMapper; 
 | 
    @Autowired 
 | 
    private WxBillDetailMapper wxBillDetailMapper; 
 | 
    @Override 
 | 
    public String create(WxBill wxBill) { 
 | 
        wxBillMapper.insert(wxBill); 
 | 
        return wxBill.getId(); 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    public void deleteById(String id) { 
 | 
        wxBillMapper.deleteById(id); 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    public void delete(WxBill wxBill) { 
 | 
        UpdateWrapper<WxBill> deleteWrapper = new UpdateWrapper<>(wxBill); 
 | 
        wxBillMapper.delete(deleteWrapper); 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    public void deleteByIdInBatch(List<String> ids) { 
 | 
        if (CollectionUtils.isEmpty(ids)) { 
 | 
            return; 
 | 
        } 
 | 
        wxBillMapper.deleteBatchIds(ids); 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    public void updateById(WxBill wxBill) { 
 | 
        wxBillMapper.updateById(wxBill); 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    public void updateByIdInBatch(List<WxBill> wxBills) { 
 | 
        if (CollectionUtils.isEmpty(wxBills)) { 
 | 
            return; 
 | 
        } 
 | 
        for (WxBill wxBill: wxBills) { 
 | 
            this.updateById(wxBill); 
 | 
        } 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    public WxBill findById(String id) { 
 | 
        return wxBillMapper.selectById(id); 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    public WxBill findOne(WxBill wxBill) { 
 | 
        QueryWrapper<WxBill> wrapper = new QueryWrapper<>(wxBill); 
 | 
        return wxBillMapper.selectOne(wrapper.last(" limit 1")); 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    public List<WxBill> findList(WxBill wxBill) { 
 | 
        QueryWrapper<WxBill> wrapper = new QueryWrapper<>(wxBill); 
 | 
        return wxBillMapper.selectList(wrapper); 
 | 
    } 
 | 
    @Override 
 | 
    public  List<WxBill> getTotalBill(WxBill param) { 
 | 
        //获取汇总统计 
 | 
        WxBill bill = getTotalDataByDate(param); 
 | 
        WxBill bill1 = initBillData();//记录交易实收统计数据 
 | 
        bill1.setSumBill(bill.getSumBill());//订单数量 
 | 
        bill1.setSumTotalFee(bill.getSumTotalFee());//交易金额 
 | 
        bill1.setSumCmmsAmt(bill.getSumCmmsAmt());//交易手续费 
 | 
        bill1.setSumSuccessFee(bill.getSumSuccessFee());//成功交易金额 
 | 
  
 | 
        WxBill bill2 = initBillData();//记录退款统计数据 
 | 
        bill2.setSumRefundBill(bill.getSumRefundBill());//退款笔数 
 | 
        bill2.setSumRefundCmmsAmt(bill.getSumRefundCmmsAmt());//退款手续费 
 | 
        bill2.setSumRefundFee(bill.getSumRefundFee());//退款金额 
 | 
  
 | 
        WxBill bill3 = initBillData(); 
 | 
        bill3.setSumBill(bill.getSumBill()); 
 | 
        bill3.setSumSuccessFee(bill.getSumSuccessFee()); 
 | 
        bill3.setSumCmmsAmt(bill.getSumCmmsAmt()); 
 | 
        bill3.setSumTotalFee(bill.getSumTotalFee()); 
 | 
        bill3.setSumRefundBill(bill.getSumRefundBill());//退款笔数 
 | 
        bill3.setSumRefundCmmsAmt(Constants.formatDecimalNum(bill.getSumRefundCmmsAmt()).add(Constants.formatDecimalNum(bill.getSumCmmsAmt())));//手续费 
 | 
        bill3.setSumRefundFee(bill.getSumRefundFee());//退款金额 
 | 
        bill3.setTotal(bill.getTotal()); 
 | 
  
 | 
        QueryWrapper<WxBillDetail> queryWrapper = new QueryWrapper<>(); 
 | 
        queryWrapper.lambda().ge(param.getStartDate() !=null,WxBillDetail::getPid,DateUtil.getShortDateStr(param.getStartDate())); 
 | 
        queryWrapper.lambda().le(param.getEndDate() !=null,WxBillDetail::getPid,DateUtil.getShortDateStr(param.getEndDate())); 
 | 
        queryWrapper.lambda().ne(WxBillDetail::getAppid, WxMiniConfig.wxPayV2Service.getConfig().getSubAppId());//非自行车收入统计 
 | 
        queryWrapper.lambda().groupBy(WxBillDetail::getBillStatus); 
 | 
        queryWrapper.select( "count(id) as sum_bill" 
 | 
                ,"sum(settlement_total_fee) as settlement_total_fee" 
 | 
                ,"sum(refund_fee) as refund_fee" 
 | 
                ,"sum(cmms_amt) as cmms_amt" ,"bill_status"); 
 | 
        List<WxBillDetail> detailList = wxBillDetailMapper.selectList(queryWrapper); 
 | 
        WxBill bill4 = initBillData();//记录交易实收统计数据 
 | 
        if(detailList!=null){ 
 | 
            for(WxBillDetail detail : detailList){ 
 | 
                if(StringUtils.equals(detail.getBillStatus(), "SUCCESS")){ 
 | 
                    //实收数据 
 | 
                    bill4.setSumBill( detail.getSumBill());//交易笔数 
 | 
                    bill4.setSumSuccessFee(Constants.formatDecimalNum(detail.getSettlementTotalFee()));//交易金额 
 | 
                    bill4.setSumCmmsAmt(Constants.formatDecimalNum(detail.getCmmsAmt()));//交易手续费 
 | 
                } else if(StringUtils.equals(detail.getBillStatus(), "REFUND") || StringUtils.equals(detail.getBillStatus(), "REVOKED")){ 
 | 
                    //退款数据 
 | 
                    bill4.setSumRefundBill(Constants.formatIntegerNum(bill4.getSumRefundBill())+detail.getSumBill());//退款笔数 
 | 
                    bill4.setSumRefundFee(Constants.formatDecimalNum(bill4.getSumRefundFee()).add(Constants.formatDecimalNum(detail.getRefundFee()))); 
 | 
                    bill4.setSumRefundCmmsAmt(Constants.formatDecimalNum(bill4.getSumRefundCmmsAmt()).add(Constants.formatDecimalNum(Constants.formatDecimalNum(detail.getCmmsAmt()))));//退款手续费 
 | 
                } 
 | 
            } 
 | 
            //结算金额 
 | 
            bill4.setTotal(bill4.getSumSuccessFee() 
 | 
                    .subtract(bill4.getSumRefundFee()) 
 | 
                    .subtract(bill4.getSumCmmsAmt()) 
 | 
                    .subtract(bill4.getSumRefundCmmsAmt())); 
 | 
        } 
 | 
  
 | 
        List<WxBill> list = new ArrayList<>(); 
 | 
        list.add(bill1);//实收交易 
 | 
        list.add(bill2);//退款汇总 
 | 
        list.add(bill3);//实收退款总计 
 | 
        list.add(bill4);//非自行车收入 
 | 
        return list; 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    public PageData<WxBill> findPage(PageWrap<WxBill> pageWrap) { 
 | 
        IPage<WxBill> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity()); 
 | 
        QueryWrapper<WxBill> queryWrapper = new QueryWrapper<>(); 
 | 
        Utils.MP.blankToNull(pageWrap.getModel()); 
 | 
        if (pageWrap.getModel().getId() != null) { 
 | 
            queryWrapper.lambda().eq(WxBill::getId, pageWrap.getModel().getId()); 
 | 
        } 
 | 
        if (pageWrap.getModel().getSumBill() != null) { 
 | 
            queryWrapper.lambda().eq(WxBill::getSumBill, pageWrap.getModel().getSumBill()); 
 | 
        } 
 | 
        if (pageWrap.getModel().getSumRefundBill() != null) { 
 | 
            queryWrapper.lambda().eq(WxBill::getSumRefundBill, pageWrap.getModel().getSumRefundBill()); 
 | 
        } 
 | 
        if (pageWrap.getModel().getSumSuccessFee() != null) { 
 | 
            queryWrapper.lambda().eq(WxBill::getSumSuccessFee, pageWrap.getModel().getSumSuccessFee()); 
 | 
        } 
 | 
        if (pageWrap.getModel().getSumRefundFee() != null) { 
 | 
            queryWrapper.lambda().eq(WxBill::getSumRefundFee, pageWrap.getModel().getSumRefundFee()); 
 | 
        } 
 | 
        if (pageWrap.getModel().getSumCouponRefundFee() != null) { 
 | 
            queryWrapper.lambda().eq(WxBill::getSumCouponRefundFee, pageWrap.getModel().getSumCouponRefundFee()); 
 | 
        } 
 | 
        if (pageWrap.getModel().getSumCmmsAmt() != null) { 
 | 
            queryWrapper.lambda().eq(WxBill::getSumCmmsAmt, pageWrap.getModel().getSumCmmsAmt()); 
 | 
        } 
 | 
        if (pageWrap.getModel().getSumTotalFee() != null) { 
 | 
            queryWrapper.lambda().eq(WxBill::getSumTotalFee, pageWrap.getModel().getSumTotalFee()); 
 | 
        } 
 | 
        if (pageWrap.getModel().getSumApplyRefundFee() != null) { 
 | 
            queryWrapper.lambda().eq(WxBill::getSumApplyRefundFee, pageWrap.getModel().getSumApplyRefundFee()); 
 | 
        } 
 | 
        if (pageWrap.getModel().getSumRefundCmmsAmt() != null) { 
 | 
            queryWrapper.lambda().eq(WxBill::getSumRefundCmmsAmt, pageWrap.getModel().getSumRefundCmmsAmt()); 
 | 
        } 
 | 
        if (pageWrap.getModel().getTotal() != null) { 
 | 
            queryWrapper.lambda().eq(WxBill::getTotal, pageWrap.getModel().getTotal()); 
 | 
        } 
 | 
        if (pageWrap.getModel().getBikeFee() != null) { 
 | 
            queryWrapper.lambda().eq(WxBill::getBikeFee, pageWrap.getModel().getBikeFee()); 
 | 
        } 
 | 
        queryWrapper.lambda().ge(pageWrap.getModel().getStartDate() !=null,WxBill::getId,DateUtil.getShortDateStr(pageWrap.getModel().getStartDate())); 
 | 
        queryWrapper.lambda().le(pageWrap.getModel().getEndDate() !=null,WxBill::getId,DateUtil.getShortDateStr(pageWrap.getModel().getEndDate())); 
 | 
        //按照时间升序显示 
 | 
        queryWrapper.lambda().orderByAsc(WxBill::getId); 
 | 
       /* for(PageWrap.SortData sortData: pageWrap.getSorts()) { 
 | 
            if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) { 
 | 
                queryWrapper.orderByDesc(sortData.getProperty()); 
 | 
            } else { 
 | 
                queryWrapper.orderByAsc(sortData.getProperty()); 
 | 
            } 
 | 
        }*/ 
 | 
        return PageData.from(wxBillMapper.selectPage(page, queryWrapper),getTotalDataByDate(pageWrap.getModel())); 
 | 
    } 
 | 
  
 | 
    private WxBill getTotalDataByDate(WxBill model) { 
 | 
        QueryWrapper<WxBill> param = new QueryWrapper<>(); 
 | 
        param.lambda().ge(model.getStartDate() !=null,WxBill::getId,DateUtil.getShortDateStr(model.getStartDate())); 
 | 
        param.lambda().le(model.getEndDate() !=null,WxBill::getId,DateUtil.getShortDateStr(model.getEndDate())); 
 | 
        param.select("sum(sum_bill) as sum_bill" 
 | 
                ,"sum(sum_refund_bill) as sum_refund_bill" 
 | 
                ,"sum(sum_success_fee) as sum_success_fee" 
 | 
                ,"sum(sum_refund_fee) as sum_refund_fee" 
 | 
                ,"sum(sum_cmms_amt) as sum_cmms_amt" 
 | 
                ,"sum(sum_total_fee) as sum_total_fee" 
 | 
                ,"sum(sum_apply_refund_fee) as sum_apply_refund_fee" 
 | 
                ,"sum(sum_total_fee) as sum_total_fee" 
 | 
                ,"sum(total) as total" 
 | 
                ,"sum(sum_refund_cmms_amt) as sum_refund_cmms_amt" 
 | 
                ,"sum(bike_fee) as bike_fee" 
 | 
                ); 
 | 
        WxBill bill = wxBillMapper.selectOne(param.last("limit 1")); 
 | 
        if(bill == null){ 
 | 
            bill = initBillData(); 
 | 
  
 | 
        } 
 | 
        return bill; 
 | 
    } 
 | 
  
 | 
    public static WxBill initBillData(){ 
 | 
        WxBill bill = new WxBill(); 
 | 
        bill.setSumBill(0); 
 | 
        bill.setSumTotalFee(new BigDecimal(0.00)); 
 | 
        bill.setSumSuccessFee(new BigDecimal(0.00)); 
 | 
        bill.setSumRefundFee(new BigDecimal(0.00)); 
 | 
        bill.setSumCouponRefundFee(new BigDecimal(0.00)); 
 | 
        bill.setSumApplyRefundFee(new BigDecimal(0.00)); 
 | 
        bill.setSumCmmsAmt(new BigDecimal(0.00)); 
 | 
        bill.setSumRefundBill(0); 
 | 
        bill.setSumRefundCmmsAmt(new BigDecimal(0.00)); 
 | 
        bill.setTotal(new BigDecimal(0.00)); 
 | 
        bill.setBikeFee(new BigDecimal(0.00)); 
 | 
        return bill; 
 | 
    } 
 | 
    @Override 
 | 
    public long count(WxBill wxBill) { 
 | 
        QueryWrapper<WxBill> wrapper = new QueryWrapper<>(wxBill); 
 | 
        return wxBillMapper.selectCount(wrapper); 
 | 
    } 
 | 
    @Override 
 | 
    @Transactional(rollbackFor = {BusinessException.class,Exception.class}) 
 | 
    @Synchronized//单例执行 
 | 
    public void getWxBill(Date ydate ) { 
 | 
        isValidDate(ydate); 
 | 
        // 获取交易账单数据 
 | 
        WxPayDownloadBillRequest request = new WxPayDownloadBillRequest(); 
 | 
        String billDate = DateUtil.getShortDateStr(ydate); 
 | 
//        Date ydate = DateUtil.addDaysToDate(new Date(), -1); 
 | 
        request.setBillDate(billDate); 
 | 
        request.setBillType("SUCCESS"); 
 | 
        request.setSubMchId(WxMiniConfig.wxProperties.getSubMchId()); 
 | 
  
 | 
        WxPayBillResult response = null; 
 | 
        try { 
 | 
            response = WxMiniConfig.wxPayV2Service.downloadBill(request); 
 | 
        }catch (WxPayException e){ 
 | 
  
 | 
        } 
 | 
        request.setBillType("REFUND"); 
 | 
        //请求退款单交易记录汇总数据 
 | 
        WxPayBillResult responseRefund = null; 
 | 
        try { 
 | 
            responseRefund = WxMiniConfig.wxPayV2Service.downloadBill(request); 
 | 
        }catch (WxPayException e){ 
 | 
  
 | 
        } 
 | 
        WxBill bill = initBillData(); 
 | 
        //日期作为主键 
 | 
        bill.setId(billDate); 
 | 
        List<WxBillDetail> detailList = new ArrayList<>(); 
 | 
        if(response !=null){ 
 | 
//                List<WxPayBillInfo> detailList = response.getBillInfoList(); 
 | 
            int totalRefund = 0; 
 | 
            BigDecimal totalRefundAmt = new BigDecimal(0.00); 
 | 
            bill.setSumBill(Integer.parseInt(response.getTotalRecord())); 
 | 
            //订单总金额 
 | 
            bill.setSumTotalFee(formatStringToDecimal(response.getTotalAmount())); 
 | 
            //应结订单总金额 
 | 
            bill.setSumSuccessFee(formatStringToDecimal(response.getTotalFee())); 
 | 
            //交易总手续费金额 
 | 
            bill.setSumCmmsAmt(formatStringToDecimal(response.getTotalPoundageFee())); 
 | 
            detailList.addAll(getDetialModelByInfo(bill,response.getBillInfoList())); 
 | 
        } 
 | 
        if(responseRefund != null){ 
 | 
            //退款单总数累计进入 
 | 
//                bill.setSumBill(bill.getSumBill()+(Integer.parseInt(response.getTotalRecord())); 
 | 
            bill.setSumRefundBill(Integer.parseInt(responseRefund.getTotalRecord()));//退款的订单数 
 | 
            //退款总金额 
 | 
            bill.setSumRefundFee(formatStringToDecimal(responseRefund.getTotalRefundFee())); 
 | 
            //退款总金额 
 | 
            bill.setSumApplyRefundFee(formatStringToDecimal(responseRefund.getTotalAppliedRefundFee())); 
 | 
            bill.setSumRefundCmmsAmt(formatStringToDecimal(responseRefund.getTotalPoundageFee()));//退款总手续费 
 | 
            bill.setSumCouponRefundFee(formatStringToDecimal(responseRefund.getTotalCouponFee()));//退款总金额 
 | 
            detailList.addAll(getDetialModelByInfo(bill,responseRefund.getBillInfoList())); 
 | 
        } 
 | 
        wxBillMapper.delete(new UpdateWrapper<WxBill>().lambda().eq( WxBill::getId, bill.getId())); 
 | 
        wxBillDetailMapper.delete(new UpdateWrapper<WxBillDetail>().lambda().eq( WxBillDetail::getPid, bill.getId())); 
 | 
  
 | 
//        getTotalAndIncome(bill,ydate);//统计结算金额和自行车收入 
 | 
        //总结算金额(收款金额-收款手续费-退款金额-退款手续费(负数)) 
 | 
        bill.setTotal(bill.getSumSuccessFee().subtract(bill.getSumCmmsAmt()).subtract(bill.getSumRefundFee()).subtract(bill.getSumRefundCmmsAmt())); 
 | 
//        //自行车收入(收款金额-收款手续费-退款金额-退款手续费(负数)) 
 | 
//        bill.setBikeFee(bill.getSumSuccessFee().subtract(bill.getSumRefundFee())); 
 | 
        wxBillMapper.insert(bill); 
 | 
        if(detailList.size()>0){ 
 | 
            wxBillDetailMapper.insertBatch(detailList); 
 | 
        } 
 | 
    } 
 | 
  
 | 
    private boolean isValidDate(Date ydate) { 
 | 
        if(ydate == null  ){ 
 | 
            //时间不能为空 
 | 
            throw  new BusinessException(ResponseStatus.BAD_REQUEST); 
 | 
        } 
 | 
        int days =  DateUtil.daysBetweenDates(new Date(),ydate); 
 | 
        if(days< 1){ 
 | 
            //只能同步昨天之前的数据 
 | 
            throw  new BusinessException(ResponseStatus.BAD_REQUEST); 
 | 
        } 
 | 
        if( days == 1){ 
 | 
            //只能同步昨天10之前的数据 
 | 
            Calendar caln = Calendar.getInstance(); 
 | 
            caln.setTime(ydate); 
 | 
            if(caln.get(Calendar.HOUR_OF_DAY)  > 10){ 
 | 
                throw  new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,最近同步时间只能截止到昨天10点前!"); 
 | 
            } 
 | 
        } 
 | 
        return true; 
 | 
    } 
 | 
  
 | 
    private void getTotalAndIncome(WxBill bill,Date date) { 
 | 
        QueryWrapper<Goodsorder> queryWrapper = new QueryWrapper<>(); 
 | 
        queryWrapper.apply("to_char(create_date, 'yyyy-MM-dd') = {0}", date); 
 | 
        queryWrapper.lambda().eq(Goodsorder::getIsdeleted, Constants.ZERO); 
 | 
        queryWrapper.lambda().eq(Goodsorder::getStatus, Constants.goodsorderStatus.over);//已結算 
 | 
        queryWrapper.select("sum(money) as totalMoney","sum(close_money) as totalCloseMoney"); 
 | 
    } 
 | 
  
 | 
    private  List<WxBillDetail> getDetialModelByInfo(WxBill bill, List<WxPayBillInfo> billInfoList) { 
 | 
        List<WxBillDetail> detailList = new ArrayList<>(); 
 | 
        if(billInfoList!=null){ 
 | 
            for (int i = 0; i <billInfoList.size(); i++) { 
 | 
                WxPayBillInfo info =billInfoList.get(i); 
 | 
                if((StringUtils.equals(info.getTradeType(),"REFUND" )||StringUtils.equals(info.getTradeType(),"REVOKED" )) && !StringUtils.equals(info.getRefundState(),"SUCCESS" )){ 
 | 
                    //如果是非成功的退款数据,不进行同步 
 | 
                    continue; 
 | 
                } 
 | 
                WxBillDetail detail = new WxBillDetail(); 
 | 
                detail.setId(UUID.randomUUID().toString()); 
 | 
                detail.setPid(bill.getId()); 
 | 
                detail.setBillDate(DateUtil.getDateFromString2(info.getTradeTime()));//交易时间 
 | 
                detail.setAppid(info.getAppId());//公众账号ID 
 | 
                detail.setMchId(info.getMchId());//商户号 
 | 
                detail.setSubMchid(info.getSubMchId());//特约商户号 
 | 
                detail.setDeviceInfo(info.getDeviceInfo());//设备 
 | 
  
 | 
                detail.setTransactionId(info.getTransactionId());//微信订单号 
 | 
                detail.setOutTradeNo(info.getOutTradeNo());//商户订单号 
 | 
                detail.setOpenid(info.getOpenId());//用户标识 
 | 
                detail.setBillType(info.getTradeType());//交易类型 
 | 
                detail.setBillStatus(info.getTradeState());//交易状态 
 | 
                detail.setBankType(info.getBankType());//付款银行 
 | 
                detail.setFeeType(info.getFeeType());//货币种类 
 | 
                detail.setSettlementTotalFee(formatStringToDecimal(info.getTotalFee()));//应结订单金额 
 | 
                detail.setCouponFee(formatStringToDecimal(info.getCouponFee()));//代金券金额 
 | 
                detail.setRefundId(info.getRefundId());//微信退款单号 
 | 
                detail.setOutRefundNo(info.getOutRefundNo());//商户退款单号 
 | 
                detail.setRefundFee(formatStringToDecimal(info.getSettlementRefundFee()));//退款金额 
 | 
                detail.setCouponRefundFee(formatStringToDecimal(info.getCouponRefundFee()));//充值券退款金额 
 | 
                detail.setRefundType(info.getRefundChannel());//退款类型 
 | 
                detail.setRefundSuccessStatus(info.getRefundState());//退款状态 
 | 
                detail.setBody(info.getBody());//商品名称 
 | 
                detail.setAttach(info.getAttach());//商户数据包 
 | 
                detail.setCmmsAmt(formatStringToDecimal(info.getPoundage()));//手续费 
 | 
                detail.setRate(formatStringToDecimal(info.getPoundageRate().replace("%", "")));//费率 
 | 
                detail.setTotalFee(formatStringToDecimal(info.getTotalAmount()));//订单金额 
 | 
                detail.setApplyRefundFee(formatStringToDecimal(info.getAppliedRefundAmount()));//申请退款金额 
 | 
                detail.setRateRemark(info.getFeeRemark());//费率备注 
 | 
                detail.setRefundSuccessDate(DateUtil.getDateFromString2(info.getRefundSuccessTime()));//成功退款时间 
 | 
                detail.setRefundApplyDate(DateUtil.getDateFromString2(info.getRefundTime())); //申请退款时间 
 | 
                //计算自行车收入,匹配来自自行车小程序的所有支付成功和退款成功的金额,作为自行车收入(累计收款金额-累计退款成功金额) 
 | 
                if(StringUtils.equals(detail.getAppid(), WxMiniConfig.wxPayV2Service.getConfig().getSubAppId())){ 
 | 
                    //自行车收入累计收款金额(支付成功总金额-退款总金额) 
 | 
                    if(StringUtils.equals(info.getTradeState(),"SUCCESS")){ 
 | 
                        //如果是交易 
 | 
                        bill.setBikeFee(bill.getBikeFee().add(detail.getSettlementTotalFee())); 
 | 
                        bill.setBikeFee(bill.getBikeFee().subtract(detail.getCmmsAmt()) ); 
 | 
                    }else  if(StringUtils.equals(info.getTradeState(),"REFUND" ) || StringUtils.equals(info.getTradeState(),"REVOKED" )){ 
 | 
                        //如果退款成功,扣除退款金额 
 | 
                        bill.setBikeFee(bill.getBikeFee().subtract(detail.getRefundFee()) ); 
 | 
                        bill.setBikeFee(bill.getBikeFee().subtract(detail.getCmmsAmt()) ); 
 | 
                    } 
 | 
                } 
 | 
                detailList.add(detail); 
 | 
            } 
 | 
        } 
 | 
        return detailList; 
 | 
    } 
 | 
  
 | 
    public static BigDecimal formatStringToDecimal(String str){ 
 | 
        if(str == null){ 
 | 
            return  new BigDecimal(0.00); 
 | 
        } 
 | 
        return new BigDecimal(Double.parseDouble(str)); 
 | 
    } 
 | 
} 
 |