✨ BFI财务单据、票务与资金接口对接Feign客户端与服务层实现

This commit is contained in:
刘泉佳
2026-09-16 18:34:00 +08:00
parent e55e72c5e2
commit 38cfaa511d
4 changed files with 762 additions and 0 deletions
@@ -71,4 +71,9 @@ public class BfiConstant {
* token 提前失效缓冲时长(毫秒),防止刚好过期
*/
public static final long TOKEN_EXPIRE_BUFFER_MILLIS = 120_000L;
/**
* A303-5 开票申请发票查询 接口编码,固定值
*/
public static final String INVOICE_APPLY_OPEN_API_CODE = "BILL.INVOICE.QUERY";
}
@@ -25,20 +25,41 @@
*/
package org.springblade.thirdparty.bfi.feign;
import feign.Response;
import org.springblade.thirdparty.bfi.config.BfiFeignClientConfig;
import org.springblade.thirdparty.bfi.constant.BfiConstant;
import org.springblade.thirdparty.bfi.pojo.dto.BfiApBillSaveBodyDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiArBillSaveBodyDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiClaimPushBodyDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiCustomerSaveBodyDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiInvoiceApplyOpenApiBodyDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiInvoiceApplySaveBodyDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiInvoiceAssignBodyDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiInvoiceDownloadDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiInvoicePoolQueryDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiPayApplyPushBodyDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiPayApplyQueryDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiPayApplySaveBodyDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiExchangeRateQueryDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiReceivedInvoiceQueryDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiReceivedInvoiceSaveBodyDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiTokenDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiVerifyTokenDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiWithdrawTokenDTO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiApBillVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiArBillVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiBillSaveResultVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiClaimAnnounceVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiCustomerVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiExchangeRateVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiInvoiceApplyVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiInvoicePoolVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiOpenApiResultVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiPageVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiPayApplyVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiPayBillVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiReceivedInvoiceVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiRecBillVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiResultVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiTokenVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiVerifyTokenVO;
@@ -68,6 +89,23 @@ public interface IBfiClient {
String PAY_APPLY_QUERY_URL = "${thirdParty.bfi.payApplyQueryUrl:/ierp/kapi/v2/awrp/ap/ap_payapply/query}";
String PRE_PAY_APPLY_SAVE_URL = "${thirdParty.bfi.prePayApplySaveUrl:/ierp/kapi/v2/awrp/ap/ap/ap_payapply/save}";
String PAY_BILL_QUERY_URL = "${thirdParty.bfi.payBillQueryUrl:/ierp/kapi/v2/awrp/cas/cas_paybill/query}";
String CUSTOMER_QUERY_URL = "${thirdParty.bfi.customerQueryUrl:/ierp/kapi/v2/awrp/basedata/bd_customer/query}";
String CUSTOMER_SAVE_URL = "${thirdParty.bfi.customerSaveUrl:/ierp/kapi/v2/awrp/basedata/bd_customer/save}";
String AP_BILL_SAVE_URL = "${thirdParty.bfi.apBillSaveUrl:/ierp/kapi/v2/awrp/ap/ap/ap_finapbill/save}";
String AP_BILL_QUERY_URL = "${thirdParty.bfi.apBillQueryUrl:/ierp/kapi/v2/awrp/ap/ap_finapbill/query}";
String AR_BILL_SAVE_URL = "${thirdParty.bfi.arBillSaveUrl:/ierp/kapi/v2/awrp/ar/ar/ar_finarbill/save}";
String AR_BILL_QUERY_URL = "${thirdParty.bfi.arBillQueryUrl:/ierp/kapi/v2/awrp/ar/ar_finarbill/query}";
String INVOICE_ASSIGN_URL = "${thirdParty.bfi.invoiceAssignUrl:/ierp/kapi/v2/awrp/ap/ap/ap_invoice/assign}";
String INVOICE_APPLY_SAVE_URL = "${thirdParty.bfi.invoiceApplySaveUrl:/ierp/kapi/v2/awrp/sim/sim_original_bill/save}";
String INVOICE_APPLY_QUERY_URL = "${thirdParty.bfi.invoiceApplyQueryUrl:/ierp/kapi/v2/awrp/sim/sim_original_bill/query}";
String INVOICE_APPLY_OPEN_API_URL = "${thirdParty.bfi.invoiceApplyOpenApiUrl:/ierp/kapi/app/sim/openApi}";
String RECEIVED_INVOICE_SAVE_URL = "${thirdParty.bfi.receivedInvoiceSaveUrl:/ierp/kapi/v2/awrp/ap/ap_invoice/cusBatchSave}";
String RECEIVED_INVOICE_QUERY_URL = "${thirdParty.bfi.receivedInvoiceQueryUrl:/ierp/kapi/v2/awrp/ap/ap_invoice/apinvoicequery}";
String REC_BILL_QUERY_URL = "${thirdParty.bfi.recBillQueryUrl:/ierp/kapi/v2/awrp/cas/cas_recbill/queryRecBill}";
String CLAIM_ANNOUNCE_QUERY_URL = "${thirdParty.bfi.claimAnnounceQueryUrl:/ierp/kapi/v2/awrp/cas/cas_claimannounce/query}";
String CLAIM_BILL_PUSH_URL = "${thirdParty.bfi.claimBillPushUrl:/ierp/kapi/v2/awrp/cas/cas/cas_claimbill/claimbillPush}";
String INVOICE_POOL_QUERY_URL = "${thirdParty.bfi.invoicePoolQueryUrl:/ierp/kapi/v2/awrp/rim/rim_invoice/query}";
String INVOICE_DOWNLOAD_URL = "${thirdParty.bfi.invoiceDownloadUrl:/ierp/kapi/v2/awrp/bosext/attachment/download}";
/**
* A100-1 获取令牌
@@ -167,4 +205,250 @@ public interface IBfiClient {
@RequestParam("end_bizdate") String endBizdate,
@RequestParam(value = "billno", required = false) List<String> billno,
@RequestParam("org_number") List<String> orgNumber);
/**
* A902-1 客户查询
*
* @param accessToken 访问令牌,通过 getToken 获取
* @param pageNo 页码,从1开始
* @param pageSize 页数
* @param enable 使用状态
* @param status 数据状态
* @param number 编码
* @param createorgNumber 创建组织.编码
* @param societycreditcode 统一社会信用代码
* @param idno 身份证号
* @param modifytimeS 修改时间-开始
* @param modifytimeE 修改时间-结束
* @return 客户分页数据
*/
@GetMapping(CUSTOMER_QUERY_URL)
BfiResultVO<BfiPageVO<BfiCustomerVO>> customerQuery(@RequestHeader(BfiConstant.HEADER_ACCESS_TOKEN) String accessToken,
@RequestParam("pageNo") Integer pageNo,
@RequestParam("pageSize") Integer pageSize,
@RequestParam(value = "enable", required = false) String enable,
@RequestParam(value = "status", required = false) String status,
@RequestParam(value = "number", required = false) List<String> number,
@RequestParam(value = "createorg_number", required = false) String createorgNumber,
@RequestParam(value = "societycreditcode", required = false) List<String> societycreditcode,
@RequestParam(value = "idno", required = false) List<String> idno,
@RequestParam(value = "modifytimeS", required = false) String modifytimeS,
@RequestParam(value = "modifytimeE", required = false) String modifytimeE);
/**
* A902-2 客户保存
*
* @param accessToken 访问令牌,通过 getToken 获取
* @param param 请求参数
* @return 保存结果
*/
@PostMapping(CUSTOMER_SAVE_URL)
BfiResultVO<BfiBillSaveResultVO> customerSave(@RequestHeader(BfiConstant.HEADER_ACCESS_TOKEN) String accessToken, @RequestBody BfiCustomerSaveBodyDTO param);
/**
* A102-2 财务应付单保存
*
* @param accessToken 访问令牌,通过 getToken 获取
* @param param 请求参数
* @return 保存结果
*/
@PostMapping(AP_BILL_SAVE_URL)
BfiResultVO<BfiBillSaveResultVO> apBillSave(@RequestHeader(BfiConstant.HEADER_ACCESS_TOKEN) String accessToken, @RequestBody BfiApBillSaveBodyDTO param);
/**
* A102-4 财务应付单查询
*
* @param accessToken 访问令牌,通过 getToken 获取
* @param pageNo 页码,从1开始
* @param pageSize 页数
* @param awrpSrcCode 来源单据号
* @param awrpSrcSys 系统编号
* @param modifytimeS 修改时间-开始
* @param modifytimeE 修改时间-结束
* @param billstatus 单据状态
* @param settlestatus 结算状态
* @return 财务应付单分页数据
*/
@GetMapping(AP_BILL_QUERY_URL)
BfiResultVO<BfiPageVO<BfiApBillVO>> apBillQuery(@RequestHeader(BfiConstant.HEADER_ACCESS_TOKEN) String accessToken,
@RequestParam("pageNo") Integer pageNo,
@RequestParam("pageSize") Integer pageSize,
@RequestParam(value = "awrp_src_code", required = false) List<String> awrpSrcCode,
@RequestParam(value = "awrp_src_sys", required = false) String awrpSrcSys,
@RequestParam(value = "modifytimeS", required = false) String modifytimeS,
@RequestParam(value = "modifytimeE", required = false) String modifytimeE,
@RequestParam(value = "billstatus", required = false) List<String> billstatus,
@RequestParam(value = "settlestatus", required = false) List<String> settlestatus);
/**
* A302-2 财务应收单保存
*
* @param accessToken 访问令牌,通过 getToken 获取
* @param param 请求参数
* @return 保存结果
*/
@PostMapping(AR_BILL_SAVE_URL)
BfiResultVO<BfiBillSaveResultVO> arBillSave(@RequestHeader(BfiConstant.HEADER_ACCESS_TOKEN) String accessToken, @RequestBody BfiArBillSaveBodyDTO param);
/**
* A302-4 财务应收单查询
*
* @param accessToken 访问令牌,通过 getToken 获取
* @param pageNo 页码,从1开始
* @param pageSize 页数
* @param awrpSrcCode 来源单据号
* @param awrpSrcSys 系统编号
* @param modifytimeS 修改时间-开始
* @param modifytimeE 修改时间-结束
* @param billstatus 单据状态
* @param settlestatus 结算状态
* @return 财务应收单分页数据
*/
@GetMapping(AR_BILL_QUERY_URL)
BfiResultVO<BfiPageVO<BfiArBillVO>> arBillQuery(@RequestHeader(BfiConstant.HEADER_ACCESS_TOKEN) String accessToken,
@RequestParam("pageNo") Integer pageNo,
@RequestParam("pageSize") Integer pageSize,
@RequestParam(value = "awrp_src_code", required = false) List<String> awrpSrcCode,
@RequestParam(value = "awrp_src_sys", required = false) String awrpSrcSys,
@RequestParam(value = "modifytimeS", required = false) String modifytimeS,
@RequestParam(value = "modifytimeE", required = false) String modifytimeE,
@RequestParam(value = "billstatus", required = false) List<String> billstatus,
@RequestParam(value = "settlestatus", required = false) List<String> settlestatus);
/**
* A302-6 收票指定应付
*
* @param accessToken 访问令牌,通过 getToken 获取
* @param param 请求参数
* @return 指定结果
*/
@PostMapping(INVOICE_ASSIGN_URL)
BfiResultVO<BfiBillSaveResultVO> invoiceAssign(@RequestHeader(BfiConstant.HEADER_ACCESS_TOKEN) String accessToken, @RequestBody BfiInvoiceAssignBodyDTO param);
/**
* A303-1 开票申请单新增
*
* @param accessToken 访问令牌,通过 getToken 获取
* @param param 请求参数
* @return 保存结果
*/
@PostMapping(INVOICE_APPLY_SAVE_URL)
BfiResultVO<BfiBillSaveResultVO> invoiceApplySave(@RequestHeader(BfiConstant.HEADER_ACCESS_TOKEN) String accessToken, @RequestBody BfiInvoiceApplySaveBodyDTO param);
/**
* A303-4 开票申请单查询
*
* @param accessToken 访问令牌,通过 getToken 获取
* @param pageNo 页码,从1开始
* @param pageSize 页数
* @param billno 业务单据编号
* @param systemsource 数据来源系统
* @param billdateS 单据日期-开始
* @param billdateE 单据日期-结束
* @return 开票申请单分页数据
*/
@GetMapping(INVOICE_APPLY_QUERY_URL)
BfiResultVO<BfiPageVO<BfiInvoiceApplyVO>> invoiceApplyQuery(@RequestHeader(BfiConstant.HEADER_ACCESS_TOKEN) String accessToken,
@RequestParam("pageNo") Integer pageNo,
@RequestParam("pageSize") Integer pageSize,
@RequestParam(value = "billno", required = false) List<String> billno,
@RequestParam(value = "systemsource", required = false) String systemsource,
@RequestParam(value = "billdateS", required = false) String billdateS,
@RequestParam(value = "billdateE", required = false) String billdateE);
/**
* A303-5 开票申请发票查询
*
* @param accessToken 访问令牌,通过 getToken 获取
* @param param 请求参数,data 为原文 JSON 的 Base64 编码
* @return 发票查询结果
*/
@PostMapping(INVOICE_APPLY_OPEN_API_URL)
BfiOpenApiResultVO<List<Object>> invoiceApplyOpenApi(@RequestHeader(BfiConstant.HEADER_ACCESS_TOKEN) String accessToken, @RequestBody BfiInvoiceApplyOpenApiBodyDTO param);
/**
* A303-2 收票单新增(批量保存)
*
* @param accessToken 访问令牌,通过 getToken 获取
* @param param 请求参数
* @return 保存结果
*/
@PostMapping(RECEIVED_INVOICE_SAVE_URL)
BfiResultVO<BfiBillSaveResultVO> receivedInvoiceSave(@RequestHeader(BfiConstant.HEADER_ACCESS_TOKEN) String accessToken, @RequestBody BfiReceivedInvoiceSaveBodyDTO param);
/**
* A801-3 收票单查询
*
* @param accessToken 访问令牌,通过 getToken 获取
* @param param 查询参数
* @return 收票单分页数据
*/
@GetMapping(RECEIVED_INVOICE_QUERY_URL)
BfiResultVO<BfiPageVO<BfiReceivedInvoiceVO>> receivedInvoiceQuery(@RequestHeader(BfiConstant.HEADER_ACCESS_TOKEN) String accessToken, @SpringQueryMap BfiReceivedInvoiceQueryDTO param);
/**
* A301-1 收款单查询(收款处理查询)
*
* @param accessToken 访问令牌,通过 getToken 获取
* @param pageNo 页码,从1开始
* @param pageSize 页数
* @param beginBizdate 开始业务日期
* @param endBizdate 结束业务日期
* @param billno 单据编号
* @param orgNumber 收款人(公司).编码
* @return 收款处理分页数据
*/
@GetMapping(REC_BILL_QUERY_URL)
BfiResultVO<BfiPageVO<BfiRecBillVO>> recBillQuery(@RequestHeader(BfiConstant.HEADER_ACCESS_TOKEN) String accessToken,
@RequestParam("pageNo") Integer pageNo,
@RequestParam("pageSize") Integer pageSize,
@RequestParam("begin_bizdate") String beginBizdate,
@RequestParam("end_bizdate") String endBizdate,
@RequestParam(value = "billno", required = false) List<String> billno,
@RequestParam(value = "org_number", required = false) List<String> orgNumber);
/**
* A301-2 收款认领公告查询
*
* @param accessToken 访问令牌,通过 getToken 获取
* @param claimusers 参与认领用户名
* @param pageNo 页码,从1开始
* @param pageSize 页数
* @return 收款认领公告分页数据
*/
@GetMapping(CLAIM_ANNOUNCE_QUERY_URL)
BfiResultVO<BfiPageVO<BfiClaimAnnounceVO>> claimAnnounceQuery(@RequestHeader(BfiConstant.HEADER_ACCESS_TOKEN) String accessToken,
@RequestParam("claimusers") String claimusers,
@RequestParam("pageNo") Integer pageNo,
@RequestParam("pageSize") Integer pageSize);
/**
* A301-3 收款认领结果推送
*
* @param accessToken 访问令牌,通过 getToken 获取
* @param param 请求参数
* @return 推送结果
*/
@PostMapping(CLAIM_BILL_PUSH_URL)
BfiResultVO<BfiBillSaveResultVO> claimBillPush(@RequestHeader(BfiConstant.HEADER_ACCESS_TOKEN) String accessToken, @RequestBody BfiClaimPushBodyDTO param);
/**
* A801-1 查询全票池发票数据
*
* @param accessToken 访问令牌,通过 getToken 获取
* @param param 查询参数
* @return 票池发票数据列表
*/
@PostMapping(INVOICE_POOL_QUERY_URL)
BfiResultVO<List<BfiInvoicePoolVO>> invoicePoolQuery(@RequestHeader(BfiConstant.HEADER_ACCESS_TOKEN) String accessToken, @RequestBody BfiInvoicePoolQueryDTO param);
/**
* A801-2 进项发票下载(文件下载),返回文件流
*
* @param accessToken 访问令牌,通过 getToken 获取
* @param param 请求参数
* @return 文件流响应
*/
@PostMapping(INVOICE_DOWNLOAD_URL)
Response invoiceDownload(@RequestHeader(BfiConstant.HEADER_ACCESS_TOKEN) String accessToken, @RequestBody BfiInvoiceDownloadDTO param);
}
@@ -25,15 +25,42 @@
*/
package org.springblade.thirdparty.bfi.service;
import feign.Response;
import org.springblade.thirdparty.bfi.pojo.dto.BfiApBillQueryDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiApBillSaveDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiArBillQueryDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiArBillSaveDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiClaimAnnounceQueryDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiClaimPushDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiCustomerQueryDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiCustomerSaveDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiInvoiceApplyOpenApiQueryDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiInvoiceApplyQueryDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiInvoiceApplySaveDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiInvoiceAssignItemDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiInvoiceDownloadDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiInvoicePoolQueryDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiPayApplyPushDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiPayApplyQueryDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiPayApplySaveDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiPayBillQueryDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiReceivedInvoiceQueryDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiReceivedInvoiceSaveDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiRecBillQueryDTO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiApBillVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiArBillVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiBillSaveResultVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiClaimAnnounceVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiCustomerVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiExchangeRateVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiInvoiceApplyVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiInvoicePoolVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiOpenApiResultVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiPageVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiPayApplyVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiPayBillVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiReceivedInvoiceVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiRecBillVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiTokenVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiVerifyTokenVO;
@@ -126,4 +153,143 @@ public interface IBfiService {
* @return 付款处理分页数据
*/
BfiPageVO<BfiPayBillVO> queryPayBill(BfiPayBillQueryDTO param);
/**
* A902-1 客户查询
*
* @param param 查询参数,页码从1开始,修改时间范围不可超过6个月
* @return 客户分页数据
*/
BfiPageVO<BfiCustomerVO> queryCustomer(BfiCustomerQueryDTO param);
/**
* A902-2 客户信息保存
*
* @param param 客户参数,分类标准固定传 JBFLBZ/1102(外部客户)
* @return 保存结果,含成功/失败数量与客户编码
*/
BfiBillSaveResultVO saveCustomer(BfiCustomerSaveDTO param);
/**
* A102-2 财务应付单保存
*
* @param param 应付单参数,分录须携带外部系统来源分录标识用于防重
* @return 保存结果,含成功/失败数量与单据编号
*/
BfiBillSaveResultVO saveApBill(BfiApBillSaveDTO param);
/**
* A102-4 财务应付单查询
*
* @param param 查询参数,页码从1开始,修改时间范围不可超过1个月
* @return 财务应付单分页数据
*/
BfiPageVO<BfiApBillVO> queryApBill(BfiApBillQueryDTO param);
/**
* A302-2 财务应收单新增
*
* @param param 应收单参数,分录须携带外部系统来源分录标识用于防重
* @return 保存结果,含成功/失败数量与单据编号
*/
BfiBillSaveResultVO saveArBill(BfiArBillSaveDTO param);
/**
* A302-4 财务应收单查询
*
* @param param 查询参数,页码从1开始,修改时间范围不可超过1个月
* @return 财务应收单分页数据
*/
BfiPageVO<BfiArBillVO> queryArBill(BfiArBillQueryDTO param);
/**
* A302-6 收票指定应付
*
* @param op 操作类型,assign 指定、unassign 取消指定
* @param data 指定关系数据(收票单与财务应付单的来源系统编码+单号)
* @return 指定结果,含成功/失败数量
*/
BfiBillSaveResultVO invoiceAssign(String op, List<BfiInvoiceAssignItemDTO> data);
/**
* A303-1 开票申请单新增
*
* @param param 开票申请单参数,业务单据编号与组织编码为候选键
* @return 保存结果,含成功/失败数量与单据编号
*/
BfiBillSaveResultVO saveInvoiceApply(BfiInvoiceApplySaveDTO param);
/**
* A303-4 开票申请单查询
*
* @param param 查询参数,页码从1开始,单据日期范围不可超过1个月
* @return 开票申请单分页数据
*/
BfiPageVO<BfiInvoiceApplyVO> queryInvoiceApply(BfiInvoiceApplyQueryDTO param);
/**
* A303-5 开票申请发票查询
*
* @param param 查询原文参数,单据编号多个用英文逗号隔开,上限50个
* @return 发票查询结果,data 内容参考票易通文档
*/
BfiOpenApiResultVO<List<Object>> queryInvoiceApplyInvoice(BfiInvoiceApplyOpenApiQueryDTO param);
/**
* A303-2 收票单新增(批量保存)
*
* @param param 收票单参数,来源系统编码与来源单据号为候选键
* @return 保存结果,含成功/失败数量与收票单编号
*/
BfiBillSaveResultVO saveReceivedInvoice(BfiReceivedInvoiceSaveDTO param);
/**
* A801-3 收票单查询
*
* @param param 查询参数,页码从1开始
* @return 收票单分页数据
*/
BfiPageVO<BfiReceivedInvoiceVO> queryReceivedInvoice(BfiReceivedInvoiceQueryDTO param);
/**
* A301-1 收款单查询(收款处理查询)
*
* @param param 查询参数,业务日期范围不可超过1个月
* @return 收款处理分页数据
*/
BfiPageVO<BfiRecBillVO> queryRecBill(BfiRecBillQueryDTO param);
/**
* A301-2 收款认领公告查询
*
* @param claimusers 参与认领用户名
* @param pageNo 页码,从1开始
* @param pageSize 页数
* @return 收款认领公告分页数据
*/
BfiPageVO<BfiClaimAnnounceVO> queryClaimAnnounce(String claimusers, Integer pageNo, Integer pageSize);
/**
* A301-3 收款认领结果推送
*
* @param param 认领结果参数,须携带认领公告id
* @return 推送结果,含成功/失败数量
*/
BfiBillSaveResultVO pushClaimResult(BfiClaimPushDTO param);
/**
* A801-1 查询全票池发票数据
*
* @param param 查询参数,queryParam 键值对参考票易通文档
* @return 票池发票数据列表
*/
List<BfiInvoicePoolVO> queryInvoicePool(BfiInvoicePoolQueryDTO param);
/**
* A801-2 进项发票下载(文件下载)
*
* @param path 文件url,如票池发票的 downloadUrl/imageUrl
* @return 文件流响应,调用方负责关闭
*/
Response downloadInvoice(String path);
}
@@ -26,6 +26,7 @@
package org.springblade.thirdparty.bfi.service.impl;
import cn.hutool.json.JSONUtil;
import feign.Response;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.redis.cache.BladeRedis;
@@ -34,21 +35,55 @@ import org.springblade.thirdparty.bfi.config.BfiProperties;
import org.springblade.thirdparty.bfi.constant.BfiConstant;
import org.springblade.thirdparty.bfi.exception.BfiException;
import org.springblade.thirdparty.bfi.feign.IBfiClient;
import org.springblade.thirdparty.bfi.pojo.dto.BfiApBillQueryDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiApBillSaveBodyDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiApBillSaveDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiArBillQueryDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiArBillSaveBodyDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiArBillSaveDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiClaimAnnounceQueryDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiClaimPushBodyDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiClaimPushDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiCustomerQueryDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiCustomerSaveBodyDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiCustomerSaveDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiExchangeRateQueryDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiInvoiceApplyOpenApiBodyDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiInvoiceApplyOpenApiQueryDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiInvoiceApplyQueryDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiInvoiceApplySaveBodyDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiInvoiceApplySaveDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiInvoiceAssignBodyDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiInvoiceAssignItemDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiInvoiceDownloadDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiInvoicePoolQueryDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiPayApplyPushBodyDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiPayApplyPushDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiPayApplyQueryDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiPayApplySaveBodyDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiPayApplySaveDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiPayBillQueryDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiReceivedInvoiceQueryDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiReceivedInvoiceSaveBodyDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiReceivedInvoiceSaveDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiRecBillQueryDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiTokenDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiVerifyTokenDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiWithdrawTokenDTO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiApBillVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiArBillVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiBillSaveResultVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiClaimAnnounceVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiCustomerVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiExchangeRateVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiInvoiceApplyVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiInvoicePoolVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiOpenApiResultVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiPageVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiPayApplyVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiPayBillVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiReceivedInvoiceVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiRecBillVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiResultVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiTokenVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiVerifyTokenVO;
@@ -56,9 +91,11 @@ import org.springblade.thirdparty.bfi.service.IBfiService;
import org.springblade.thirdparty.bfi.util.BfiUtil;
import org.springframework.stereotype.Service;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Base64;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
@@ -233,6 +270,251 @@ public class BfiServiceImpl implements IBfiService {
return result.getData();
}
@Override
public BfiPageVO<BfiCustomerVO> queryCustomer(BfiCustomerQueryDTO param) {
if (param == null || param.getPageNo() == null || param.getPageSize() == null) {
throw new BfiException("查询BFI客户失败,分页参数不能为空");
}
String accessToken = getAccessToken();
BfiResultVO<BfiPageVO<BfiCustomerVO>> result = commonCall("客户查询", () -> client.customerQuery(accessToken,
param.getPageNo(), param.getPageSize(), param.getEnable(), param.getStatus(), param.getNumber(), param.getCreateorgNumber(),
param.getSocietycreditcode(), param.getIdno(), param.getModifytimeS(), param.getModifytimeE()));
return result.getData();
}
@Override
public BfiBillSaveResultVO saveCustomer(BfiCustomerSaveDTO param) {
if (param == null || StringUtil.isBlank(param.getName())) {
throw new BfiException("保存BFI客户失败,客户名称不能为空");
}
if (StringUtil.isBlank(param.getSocietycreditcode()) && StringUtil.isBlank(param.getIdno())) {
throw new BfiException("保存BFI客户失败,统一社会信用代码与身份证号不能同时为空");
}
if (param.getEntryGroupstandard() == null || param.getEntryGroupstandard().isEmpty()) {
throw new BfiException("保存BFI客户失败,分类标准分录不能为空");
}
String accessToken = getAccessToken();
BfiCustomerSaveBodyDTO body = new BfiCustomerSaveBodyDTO();
body.setData(Collections.singletonList(param));
BfiResultVO<BfiBillSaveResultVO> result = commonCall("客户保存", () -> client.customerSave(accessToken, body));
return result.getData();
}
@Override
public BfiBillSaveResultVO saveApBill(BfiApBillSaveDTO param) {
if (param == null || StringUtil.isBlank(param.getAwrpSrcSys()) || StringUtil.isBlank(param.getAwrpSrcCode())) {
throw new BfiException("保存BFI财务应付单失败,外部系统编号与来源单据号不能为空");
}
if (param.getDetailentry() == null || param.getDetailentry().isEmpty()) {
throw new BfiException("保存BFI财务应付单失败,明细分录不能为空");
}
String accessToken = getAccessToken();
BfiApBillSaveBodyDTO body = new BfiApBillSaveBodyDTO();
body.setData(Collections.singletonList(param));
BfiResultVO<BfiBillSaveResultVO> result = commonCall("财务应付单保存", () -> client.apBillSave(accessToken, body));
return result.getData();
}
@Override
public BfiPageVO<BfiApBillVO> queryApBill(BfiApBillQueryDTO param) {
if (param == null || param.getPageNo() == null || param.getPageSize() == null) {
throw new BfiException("查询BFI财务应付单失败,分页参数不能为空");
}
String accessToken = getAccessToken();
BfiResultVO<BfiPageVO<BfiApBillVO>> result = commonCall("财务应付单查询", () -> client.apBillQuery(accessToken,
param.getPageNo(), param.getPageSize(), param.getAwrpSrcCode(), param.getAwrpSrcSys(),
param.getModifytimeS(), param.getModifytimeE(), param.getBillstatus(), param.getSettlestatus()));
return result.getData();
}
@Override
public BfiBillSaveResultVO saveArBill(BfiArBillSaveDTO param) {
if (param == null || StringUtil.isBlank(param.getAwrpSrcSys()) || StringUtil.isBlank(param.getAwrpSrcCode())) {
throw new BfiException("保存BFI财务应收单失败,外部系统编号与来源单据号不能为空");
}
if (param.getEntry() == null || param.getEntry().isEmpty()) {
throw new BfiException("保存BFI财务应收单失败,明细分录不能为空");
}
String accessToken = getAccessToken();
BfiArBillSaveBodyDTO body = new BfiArBillSaveBodyDTO();
body.setData(Collections.singletonList(param));
BfiResultVO<BfiBillSaveResultVO> result = commonCall("财务应收单保存", () -> client.arBillSave(accessToken, body));
return result.getData();
}
@Override
public BfiPageVO<BfiArBillVO> queryArBill(BfiArBillQueryDTO param) {
if (param == null || param.getPageNo() == null || param.getPageSize() == null) {
throw new BfiException("查询BFI财务应收单失败,分页参数不能为空");
}
String accessToken = getAccessToken();
BfiResultVO<BfiPageVO<BfiArBillVO>> result = commonCall("财务应收单查询", () -> client.arBillQuery(accessToken,
param.getPageNo(), param.getPageSize(), param.getAwrpSrcCode(), param.getAwrpSrcSys(),
param.getModifytimeS(), param.getModifytimeE(), param.getBillstatus(), param.getSettlestatus()));
return result.getData();
}
@Override
public BfiBillSaveResultVO invoiceAssign(String op, List<BfiInvoiceAssignItemDTO> data) {
if (StringUtil.isBlank(op)) {
throw new BfiException("BFI收票指定应付失败,操作类型不能为空");
}
if (data == null || data.isEmpty()) {
throw new BfiException("BFI收票指定应付失败,指定关系数据不能为空");
}
String accessToken = getAccessToken();
BfiInvoiceAssignBodyDTO body = new BfiInvoiceAssignBodyDTO();
body.setOp(op);
body.setData(data);
BfiResultVO<BfiBillSaveResultVO> result = commonCall("收票指定应付", () -> client.invoiceAssign(accessToken, body));
return result.getData();
}
@Override
public BfiBillSaveResultVO saveInvoiceApply(BfiInvoiceApplySaveDTO param) {
if (param == null || StringUtil.isBlank(param.getBillno()) || StringUtil.isBlank(param.getOrgidNumber())) {
throw new BfiException("保存BFI开票申请单失败,组织编码与业务单据编号不能为空");
}
if (param.getSimOriginalBillItem() == null || param.getSimOriginalBillItem().isEmpty()) {
throw new BfiException("保存BFI开票申请单失败,单据体分录不能为空");
}
String accessToken = getAccessToken();
BfiInvoiceApplySaveBodyDTO body = new BfiInvoiceApplySaveBodyDTO();
body.setData(Collections.singletonList(param));
BfiResultVO<BfiBillSaveResultVO> result = commonCall("开票申请单保存", () -> client.invoiceApplySave(accessToken, body));
return result.getData();
}
@Override
public BfiPageVO<BfiInvoiceApplyVO> queryInvoiceApply(BfiInvoiceApplyQueryDTO param) {
if (param == null || param.getPageNo() == null || param.getPageSize() == null) {
throw new BfiException("查询BFI开票申请单失败,分页参数不能为空");
}
String accessToken = getAccessToken();
BfiResultVO<BfiPageVO<BfiInvoiceApplyVO>> result = commonCall("开票申请单查询", () -> client.invoiceApplyQuery(accessToken,
param.getPageNo(), param.getPageSize(), param.getBillno(), param.getSystemsource(), param.getBilldateS(), param.getBilldateE()));
return result.getData();
}
@Override
public BfiOpenApiResultVO<List<Object>> queryInvoiceApplyInvoice(BfiInvoiceApplyOpenApiQueryDTO param) {
if (param == null || StringUtil.isBlank(param.getSerialNo()) || StringUtil.isBlank(param.getSellerTaxpayerId())) {
throw new BfiException("查询BFI开票申请发票失败,单据编号与销方税号不能为空");
}
// data 原文需序列化为 JSON 后 Base64 编码
String data = Base64.getEncoder().encodeToString(JSONUtil.toJsonStr(param).getBytes(StandardCharsets.UTF_8));
BfiInvoiceApplyOpenApiBodyDTO body = new BfiInvoiceApplyOpenApiBodyDTO();
body.setBusinessSystemCode(properties.getClientId());
body.setInterfaceCode(BfiConstant.INVOICE_APPLY_OPEN_API_CODE);
body.setData(data);
String accessToken = getAccessToken();
BfiOpenApiResultVO<List<Object>> result = commonOpenApiCall("开票申请发票查询", () -> client.invoiceApplyOpenApi(accessToken, body));
return result;
}
@Override
public BfiBillSaveResultVO saveReceivedInvoice(BfiReceivedInvoiceSaveDTO param) {
if (param == null || StringUtil.isBlank(param.getAwrpSrcSys()) || StringUtil.isBlank(param.getAwrpSrcCode())) {
throw new BfiException("保存BFI收票单失败,外部系统编号与来源单据号不能为空");
}
if (param.getEntry() == null || param.getEntry().isEmpty()) {
throw new BfiException("保存BFI收票单失败,明细分录不能为空");
}
String accessToken = getAccessToken();
BfiReceivedInvoiceSaveBodyDTO body = new BfiReceivedInvoiceSaveBodyDTO();
body.setData(Collections.singletonList(param));
BfiResultVO<BfiBillSaveResultVO> result = commonCall("收票单保存", () -> client.receivedInvoiceSave(accessToken, body));
return result.getData();
}
@Override
public BfiPageVO<BfiReceivedInvoiceVO> queryReceivedInvoice(BfiReceivedInvoiceQueryDTO param) {
if (param == null || StringUtil.isBlank(param.getModifytime()) || StringUtil.isBlank(param.getModifytimeE())) {
throw new BfiException("查询BFI收票单失败,修改时间范围不能为空");
}
String accessToken = getAccessToken();
BfiResultVO<BfiPageVO<BfiReceivedInvoiceVO>> result = commonCall("收票单查询", () -> client.receivedInvoiceQuery(accessToken, param));
return result.getData();
}
@Override
public BfiPageVO<BfiRecBillVO> queryRecBill(BfiRecBillQueryDTO param) {
if (param == null || param.getPageNo() == null || param.getPageSize() == null) {
throw new BfiException("查询BFI收款单失败,分页参数不能为空");
}
if (StringUtil.isBlank(param.getBeginBizdate()) || StringUtil.isBlank(param.getEndBizdate())) {
throw new BfiException("查询BFI收款单失败,业务日期范围不能为空");
}
String accessToken = getAccessToken();
BfiResultVO<BfiPageVO<BfiRecBillVO>> result = commonCall("收款单查询", () -> client.recBillQuery(accessToken,
param.getPageNo(), param.getPageSize(), param.getBeginBizdate(), param.getEndBizdate(), param.getBillno(), param.getOrgNumber()));
return result.getData();
}
@Override
public BfiPageVO<BfiClaimAnnounceVO> queryClaimAnnounce(String claimusers, Integer pageNo, Integer pageSize) {
if (StringUtil.isBlank(claimusers)) {
throw new BfiException("查询BFI收款认领公告失败,参与认领用户名不能为空");
}
if (pageNo == null || pageSize == null) {
throw new BfiException("查询BFI收款认领公告失败,分页参数不能为空");
}
String accessToken = getAccessToken();
BfiResultVO<BfiPageVO<BfiClaimAnnounceVO>> result = commonCall("收款认领公告查询", () -> client.claimAnnounceQuery(accessToken, claimusers, pageNo, pageSize));
return result.getData();
}
@Override
public BfiBillSaveResultVO pushClaimResult(BfiClaimPushDTO param) {
if (param == null || param.getBillid() == null) {
throw new BfiException("推送BFI收款认领结果失败,认领公告id不能为空");
}
if (StringUtil.isBlank(param.getAwrpSrcSys()) || StringUtil.isBlank(param.getAwrpSrcCode())) {
throw new BfiException("推送BFI收款认领结果失败,来源系统编码与来源单据编码不能为空");
}
if (param.getEntryentity() == null || param.getEntryentity().isEmpty()) {
throw new BfiException("推送BFI收款认领结果失败,单据体分录不能为空");
}
String accessToken = getAccessToken();
BfiClaimPushBodyDTO body = new BfiClaimPushBodyDTO();
body.setData(Collections.singletonList(param));
BfiResultVO<BfiBillSaveResultVO> result = commonCall("收款认领结果推送", () -> client.claimBillPush(accessToken, body));
return result.getData();
}
@Override
public List<BfiInvoicePoolVO> queryInvoicePool(BfiInvoicePoolQueryDTO param) {
if (param == null || param.getQueryParam() == null || param.getQueryParam().isEmpty()) {
throw new BfiException("查询BFI全票池发票失败,查询参数不能为空");
}
String accessToken = getAccessToken();
BfiResultVO<List<BfiInvoicePoolVO>> result = commonCall("全票池发票查询", () -> client.invoicePoolQuery(accessToken, param));
return result.getData() != null ? result.getData() : List.of();
}
@Override
public Response downloadInvoice(String path) {
if (StringUtil.isBlank(path)) {
throw new BfiException("下载BFI进项发票失败,文件url不能为空");
}
BfiInvoiceDownloadDTO param = new BfiInvoiceDownloadDTO();
param.setPath(path);
String accessToken = getAccessToken();
try {
Response response = client.invoiceDownload(accessToken, param);
if (response == null || response.status() != 200) {
log.error("调用BFI接口 进项发票下载异常响应状态:{}", response == null ? "无响应" : response.status());
throw new BfiException("调用BFI接口进项发票下载异常,响应状态:" + (response == null ? "无响应" : response.status()));
}
return response;
} catch (BfiException e) {
throw e;
} catch (Exception e) {
log.error("调用BFI接口 进项发票下载异常", e);
throw new BfiException("调用BFI接口进项发票下载异常", e);
}
}
/**
* 公共调用方法,统一校验响应结果
*
@@ -258,6 +540,31 @@ public class BfiServiceImpl implements IBfiService {
}
}
/**
* 开放平台公共调用方法,校验 success 标识
*
* @param type 调用类型描述
* @param supplier 实际调用
* @param <T> 响应数据类型
* @return 响应结果
*/
private <T> BfiOpenApiResultVO<T> commonOpenApiCall(String type, Supplier<BfiOpenApiResultVO<T>> supplier) {
try {
BfiOpenApiResultVO<T> result = supplier.get();
if (result != null && result.isSuccess()) {
return result;
}
log.error("调用BFI接口 {}异常响应参数:{}", type, JSONUtil.toJsonStr(result));
String errorCode = Optional.ofNullable(result).map(BfiOpenApiResultVO::getErrorCode).orElse("");
throw new BfiException("调用BFI接口" + type + "异常 " + errorCode);
} catch (BfiException e) {
throw e;
} catch (Exception e) {
log.error("调用BFI接口 {}异常", type, e);
throw new BfiException("调用BFI接口" + type + "异常", e);
}
}
/**
* 缓存令牌,按 expires_in 毫秒数设置提前失效时间
*