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 deleteWrapper = new UpdateWrapper<>(wxBill); wxBillMapper.delete(deleteWrapper); } @Override public void deleteByIdInBatch(List ids) { if (CollectionUtils.isEmpty(ids)) { return; } wxBillMapper.deleteBatchIds(ids); } @Override public void updateById(WxBill wxBill) { wxBillMapper.updateById(wxBill); } @Override public void updateByIdInBatch(List 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 wrapper = new QueryWrapper<>(wxBill); return wxBillMapper.selectOne(wrapper.last(" limit 1")); } @Override public List findList(WxBill wxBill) { QueryWrapper wrapper = new QueryWrapper<>(wxBill); return wxBillMapper.selectList(wrapper); } @Override public List 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 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().getAppId());//非自行车收入统计 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 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 list = new ArrayList<>(); list.add(bill1);//实收交易 list.add(bill2);//退款汇总 list.add(bill3);//实收退款总计 list.add(bill4);//非自行车收入 return list; } @Override public PageData findPage(PageWrap pageWrap) { IPage page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity()); QueryWrapper 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 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 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"); 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 detailList = new ArrayList<>(); if(response !=null){ // List 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().lambda().eq( WxBill::getId, bill.getId())); wxBillDetailMapper.delete(new UpdateWrapper().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 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 getDetialModelByInfo(WxBill bill, List billInfoList) { List detailList = new ArrayList<>(); if(billInfoList!=null){ for (int i = 0; i