ruoyi-admin/pom.xml
@@ -32,11 +32,11 @@ <version>31.1-jre</version> <!-- 请根据需要选择合适的版本 --> </dependency> <!-- spring-boot-devtools --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> <!-- 表示依赖不会传递 --> </dependency> <!-- <dependency>--> <!-- <groupId>org.springframework.boot</groupId>--> <!-- <artifactId>spring-boot-devtools</artifactId>--> <!-- <optional>true</optional> <!– 表示依赖不会传递 –>--> <!-- </dependency>--> <!-- swagger3--> <dependency> ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBankFlowController.java
@@ -6,6 +6,7 @@ import com.alibaba.excel.event.AnalysisEventListener; import com.ruoyi.common.basic.PageInfo; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.WebUtils; import com.ruoyi.system.importExcel.TBankFlowImportExcel; import com.ruoyi.system.model.TBankFlow; @@ -15,10 +16,7 @@ import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse; @@ -113,6 +111,14 @@ System.err.println("银行流水返回结果导出失败"); } } @GetMapping("getByBankSerialNumber") public R<List<TBankFlow>> searchByBankSerialNumber(@RequestParam String bankSerialNumber){ List<TBankFlow> tBankFlows = flowService.searchByBankSerialNumber(bankSerialNumber); return R.ok(tBankFlows); } } ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBillController.java
@@ -4,10 +4,13 @@ import com.ruoyi.common.basic.PageInfo; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.system.dto.*; import com.ruoyi.system.model.TBill; import com.ruoyi.system.model.TBillConfirm; import com.ruoyi.system.model.TBillDetail; import com.ruoyi.system.query.TBillQuery; import com.ruoyi.system.service.TBillConfirmService; import com.ruoyi.system.service.TBillDetailService; import com.ruoyi.system.service.TBillService; import io.swagger.annotations.Api; @@ -39,6 +42,8 @@ @Autowired TBillDetailService tBillDetailService; @Autowired TBillConfirmService tBillConfirmService; @PreAuthorize("@ss.hasPermi('system:bill:list')") @PostMapping("list") @@ -58,7 +63,10 @@ @ApiOperation("通过ID查找详情") @GetMapping("getDetailById") public R<TBillDto> getDetailById(@Validated @NotEmpty String id){ public R<TBillDto> getDetailById(@RequestParam String id){ if (StringUtils.isEmpty(id)){ return R.fail(); } TBillDto dto = tBillService.getDetailByBillId(id); if (dto.getBillType().equals("3")){ List<TBillDetail> details = tBillDetailService.getByBillId(id); @@ -66,6 +74,10 @@ if (detail.getLiveType()==1)dto.setWater(detail); //水费 else dto.setElect(detail); //电费 } } if (StringUtils.isNotEmpty(dto.getConfirmId())){ TBillConfirm confirm = tBillConfirmService.getById(dto.getConfirmId()); dto.setConfirm(confirm); } return R.ok(dto); } @@ -96,11 +108,14 @@ return R.ok(failNum); } @PreAuthorize("@ss.hasPermi('system:bill:cashPay')") @ApiOperation("收款") @PostMapping("cashPay") public R cashPay(@RequestBody OfflinePayDto offlinePayDto){ public R cashPay(@RequestBody CachPayDto cachPayDto){ tBillService.cashPay(cachPayDto); return null; } @@ -108,5 +123,7 @@ } ruoyi-common/src/main/resources/META-INF/spring.factories
New file @@ -0,0 +1,2 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.ruoyi.common.config.SmsConfig ruoyi-system/src/main/java/com/ruoyi/system/dto/CachPayDto.java
New file @@ -0,0 +1,33 @@ package com.ruoyi.system.dto; import com.ruoyi.system.model.TBankFlow; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.io.Serializable; import java.math.BigDecimal; /** * 收款对象 */ @Data public class CachPayDto implements Serializable { @ApiModelProperty(value = "支付类型:1.银行、2.现金") private Integer payType; @ApiModelProperty(value = "账单ID") private String billId; @ApiModelProperty(value = "金额") private BigDecimal amount; @ApiModelProperty(value = "付款人姓名") private String payer; @ApiModelProperty(value = "银行支付的付款凭证") private String voucher; @ApiModelProperty("银行支付的银行流水") private TBankFlow tBankFlow; } ruoyi-system/src/main/java/com/ruoyi/system/dto/OfflinePayCheckDto.java
@@ -1,6 +1,7 @@ package com.ruoyi.system.dto; import com.fasterxml.jackson.annotation.JsonFormat; import com.ruoyi.system.model.TBankFlow; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -19,6 +20,11 @@ @ApiModelProperty("账单ID列表,管理员处理后的") @NotEmpty(message = "账单列表不能为空") private List<String> billIds; @ApiModelProperty(value = "账单ID") @NotEmpty(message = "账单ID不能为空") private String billId; @ApiModelProperty("实际支付金额") @NotNull(message = "实际支付金额不能为空") private BigDecimal amount; @@ -27,14 +33,15 @@ @NotNull(message = "确认单ID不能为空") private String confirmId; @ApiModelProperty("银行流水号,用于生成流水") @NotEmpty(message = "银行流水号不能为空") private String bankSerilNum; @ApiModelProperty("支付人") private String payer; @ApiModelProperty("支付时间") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private LocalDateTime payTime; @ApiModelProperty("支付凭证") private String voucher; @ApiModelProperty("银行流水") private TBankFlow tBankFlow; } ruoyi-system/src/main/java/com/ruoyi/system/dto/OfflinePayDto.java
@@ -27,6 +27,7 @@ @ApiModelProperty(value = "账单列表") @NotEmpty(message = "账单ID不能为空") private List<String> billIds; /** * 凭证文件ID */ @@ -39,4 +40,6 @@ private Date payTime; } ruoyi-system/src/main/java/com/ruoyi/system/dto/TBillDto.java
@@ -1,6 +1,7 @@ package com.ruoyi.system.dto; import com.ruoyi.system.model.TBill; import com.ruoyi.system.model.TBillConfirm; import com.ruoyi.system.model.TBillDetail; import lombok.Data; @@ -40,5 +41,9 @@ * 电费 */ private TBillDetail elect; /** * 线下打款确认单 */ private TBillConfirm confirm; } ruoyi-system/src/main/java/com/ruoyi/system/service/TBillService.java
@@ -2,10 +2,7 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.common.basic.PageInfo; import com.ruoyi.system.dto.OfflinePayCheckDto; import com.ruoyi.system.dto.SmsByBillDto; import com.ruoyi.system.dto.TBillDto; import com.ruoyi.system.dto.TbillSaveDto; import com.ruoyi.system.dto.*; import com.ruoyi.system.model.TBill; import com.ruoyi.system.query.TBillQuery; import com.taxi591.bankapi.dto.ChargeBillRequest; @@ -84,4 +81,6 @@ Integer sendMailBatchByBillIds(SmsByBillDto dto); TBillDto getDetailByBillId(@NotEmpty String id); Boolean cashPay(CachPayDto offlinePayDto); } ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBankFlowServiceImpl.java
@@ -9,6 +9,7 @@ import com.ruoyi.system.importExcel.TBankFlowImportExcel; import com.ruoyi.system.mapper.TBankFlowMapper; import com.ruoyi.system.model.TBankFlow; import com.ruoyi.system.model.TBill; import com.ruoyi.system.model.TFlowManagement; import com.ruoyi.system.query.TBankFlowQuery; import com.ruoyi.system.query.TFlowManagementQuery; @@ -74,8 +75,12 @@ @Override public List<TBankFlow> searchByBankSerialNumber(String bankSerialNumber) { LambdaQueryWrapper<TBankFlow> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.like(StringUtils.isNotEmpty(bankSerialNumber),TBankFlow::getBankSerialNumber,bankSerialNumber); return this.baseMapper.selectList(queryWrapper); queryWrapper.like(StringUtils.isNotEmpty(bankSerialNumber),TBankFlow::getBankSerialNumber,bankSerialNumber) .orderByDesc(TBankFlow::getPayTime); PageInfo<TBankFlow> pageInfo = new PageInfo<>(1, 20); pageInfo = this.baseMapper.selectPage(pageInfo, queryWrapper); return pageInfo.getRecords(); } @Override ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBillServiceImpl.java
@@ -11,10 +11,7 @@ import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.TencentMailUtil; import com.ruoyi.common.utils.uuid.UUID; import com.ruoyi.system.dto.OfflinePayCheckDto; import com.ruoyi.system.dto.SmsByBillDto; import com.ruoyi.system.dto.TBillDto; import com.ruoyi.system.dto.TbillSaveDto; import com.ruoyi.system.dto.*; import com.ruoyi.system.mapper.TBillMapper; import com.ruoyi.system.model.*; import com.ruoyi.system.query.TBillQuery; @@ -242,32 +239,50 @@ } @Override @Transactional(rollbackFor = Exception.class) public boolean checkOfflinePay(OfflinePayCheckDto dto) { List<TBill> tBills = listByIds(dto.getBillIds()); TBillConfirm confirm = tBillConfirmService.getById(dto.getConfirmId()); lockAndUpdateByAmountBatch(tBills,dto.getAmount(),(bill)->{ TFlowManagement save = new TFlowManagement(); save.setPayType(3); save.setPayer(dto.getPayer()); save.setPayTime(dto.getPayTime()==null?DateUtils.dateToLocalDateTime(confirm.getPayTime()):dto.getPayTime()); save.setBankSerialNumber(dto.getBankSerilNum()); save.setFlowType(2); save.setPaymentBillId(bill.getId()); save.setDeductionMoney(bill.getDeductionMoney()); save.setFlowMoney(dto.getAmount()); save.setRemainingMoney(bill.getOutstandingMoney()); save.setPreOutstand(bill.getPreOutstand()); tFlowManagementService.save(save); }); TBankFlow bankFlow = new TBankFlow(); bankFlow.setPayType(3); bankFlow.setPayer(dto.getPayer()); bankFlow.setPayTime(dto.getPayTime()==null?DateUtils.dateToLocalDateTime(confirm.getPayTime()):dto.getPayTime()); bankFlow.setBankSerialNumber(dto.getBankSerilNum()); bankFlow.setFlowMoney(dto.getAmount()); bankFlow.setFlowStatus(1); tBankFlowService.save(bankFlow); return false; TBankFlow bankflow = tBankFlowService.getById(dto.getTBankFlow().getId()); TBillDto bill = getDetailByBillId(dto.getBillId()); if (bankflow.getRemainingMoney().compareTo(BigDecimal.ZERO)<=0){ throw new ServiceException("该流水已无可抵扣剩余金额"); } if (bankflow.getRemainingMoney().compareTo(dto.getAmount())<0){ throw new ServiceException("实付金额不能高于于流水可抵扣剩余金额"); } //如果实付金额大于欠费金额 if (dto.getAmount().compareTo(bill.getOutstandingMoney())>=0){ throw new ServiceException("实付金额不能高于该账单欠费金额"); } TBill billSave = new TBill(); billSave.setId(bill.getId()); billSave.setPayFeesMoney(dto.getAmount()); billSave.setBankSerialNumber(dto.getTBankFlow().getBankSerialNumber()); billSave.setPayFeesTime(dto.getTBankFlow().getPayTime()); billSave.setVoucher(dto.getVoucher()); billSave.setPayFeesType(2); TBill back = lockAndUpdateInfo(billSave, 2); //更新银行流水的已抵扣金额和剩余可抵扣金额 TBankFlow saveBankFlow = new TBankFlow(); saveBankFlow.setId(bankflow.getId()); saveBankFlow.setDeductionMoney(bankflow.getDeductionMoney().add(dto.getAmount())); saveBankFlow.setRemainingMoney(bankflow.getRemainingMoney().subtract(dto.getAmount())); tBankFlowService.updateById(saveBankFlow); //存流水 TFlowManagement save = new TFlowManagement(); save.setPayType(3); save.setPayer(dto.getPayer()); save.setPayTime(dto.getTBankFlow().getPayTime()); save.setBankSerialNumber(dto.getTBankFlow().getBankSerialNumber()); save.setFlowType(2); save.setPaymentBillId(back.getId()); save.setDeductionMoney(back.getDeductionMoney()); save.setFlowMoney(dto.getAmount()); save.setRemainingMoney(back.getOutstandingMoney()); save.setPreOutstand(back.getPreOutstand()); tFlowManagementService.save(save); return true; } @Override @@ -376,7 +391,7 @@ TBill save = new TBill(); save.setId(bill.getId()); try { smsUtil.sendSms(bill.getPhone(), "", new String[]{""}); smsUtil.sendSms(bill.getPhone(), "2365726", new String[]{bill.getPartyTwoName()}); save.setSmsStatus(1); }catch (ServiceException e){ failNum++; @@ -394,9 +409,9 @@ int failNum = 0; for (String billId : dto.getBillIds()) { TBillDto bill = getDetailByBillId(billId); if (bill.getSmsLastTime()!=null && (System.currentTimeMillis()-bill.getSmsLastTime().getTime()<mailUtil.getPro().getBillMailDelayPeriod()*60*1000L)){ throw new ServiceException("有账单最近一次发送的时间是:"+DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,bill.getSmsLastTime())); if (bill.getMailLastTime()!=null && (System.currentTimeMillis()-bill.getMailLastTime().getTime()<mailUtil.getPro().getBillMailDelayPeriod()*60*1000L)){ throw new ServiceException("有账单最近一次发送的时间是:"+DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,bill.getMailLastTime())); } if (StringUtils.isEmpty(bill.getEmail())){ failNum++; @@ -422,5 +437,62 @@ return getBaseMapper().selectDetailByBillId(billId); } /** * 收款、类型可能是现金、银行 * @param dto * @return */ @Transactional(rollbackFor = Exception.class) @Override public Boolean cashPay(CachPayDto dto) { TBill back = null; TBankFlow bankflow = null; if (dto.getPayType()==1){ bankflow = tBankFlowService.getById(dto.getTBankFlow().getId()); TBillDto bill = getDetailByBillId(dto.getBillId()); if (bankflow.getRemainingMoney().compareTo(BigDecimal.ZERO)<=0){ throw new ServiceException("该流水已无可抵扣剩余金额"); } if (bankflow.getRemainingMoney().compareTo(dto.getAmount())<0){ throw new ServiceException("实付金额不能高于于流水可抵扣剩余金额"); } //如果实付金额大于欠费金额 if (dto.getAmount().compareTo(bill.getOutstandingMoney())>=0){ throw new ServiceException("实付金额不能高于该账单欠费金额"); } } TBillDto bill = getDetailByBillId(dto.getBillId()); TBill billSave = new TBill(); billSave.setId(bill.getId()); billSave.setPayFeesMoney(dto.getAmount()); billSave.setBankSerialNumber(dto.getTBankFlow().getBankSerialNumber()); billSave.setPayFeesTime(dto.getTBankFlow().getPayTime()); billSave.setVoucher(dto.getVoucher()); billSave.setPayFeesType(2); back = lockAndUpdateInfo(billSave, 2); if (dto.getPayType()==1){ //更新银行流水的已抵扣金额和剩余可抵扣金额 TBankFlow saveBankFlow = new TBankFlow(); saveBankFlow.setId(bankflow.getId()); saveBankFlow.setDeductionMoney(bankflow.getDeductionMoney().add(dto.getAmount())); saveBankFlow.setRemainingMoney(bankflow.getRemainingMoney().subtract(dto.getAmount())); tBankFlowService.updateById(saveBankFlow); } //存流水 TFlowManagement save = new TFlowManagement(); save.setPayType(3); save.setPayer(dto.getPayer()); save.setPayTime(dto.getTBankFlow().getPayTime()); save.setBankSerialNumber(dto.getTBankFlow().getBankSerialNumber()); save.setFlowType(dto.getPayType()==1?2:1); save.setPaymentBillId(back.getId()); save.setDeductionMoney(back.getDeductionMoney()); save.setFlowMoney(dto.getAmount()); save.setRemainingMoney(back.getOutstandingMoney()); save.setPreOutstand(back.getPreOutstand()); tFlowManagementService.save(save); return true; } }