package com.by4cloud.platformx.business.service.impl; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.http.HttpUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.by4cloud.platformx.admin.api.entity.SysDept; import com.by4cloud.platformx.admin.api.feign.RemoteDeptService; import com.by4cloud.platformx.business.dto.BankStatementUpdateDTO; import com.by4cloud.platformx.business.dto.PaymentConfirmAddDTO; import com.by4cloud.platformx.business.entity.*; import com.by4cloud.platformx.business.mapper.BankStatementItemMapper; import com.by4cloud.platformx.business.mapper.BankStatementMapper; import com.by4cloud.platformx.business.mapper.BusinessCustomerMapper; import com.by4cloud.platformx.business.mapper.ContractMapper; import com.by4cloud.platformx.business.service.BankStatementService; import com.by4cloud.platformx.business.service.PaymentConfirmService; import com.by4cloud.platformx.business.vo.StatementContractVo; import com.by4cloud.platformx.common.core.util.R; import com.by4cloud.platformx.common.security.util.SecurityUtils; import com.github.yulichang.wrapper.MPJLambdaWrapper; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.util.List; import java.util.stream.Collectors; /** * 银行流水 * * @author syt * @date 2026-08-07 16:10:36 */ @Slf4j @Service @RequiredArgsConstructor public class BankStatementServiceImpl extends ServiceImpl implements BankStatementService { private final PaymentConfirmService paymentConfirmService; private final ContractMapper contractMapper; private final BusinessCustomerMapper businessCustomerMapper; private final StringRedisTemplate redisTemplate; private final RemoteDeptService remoteDeptService; private final BankStatementItemMapper bankStatementItemMapper; @Value("${bip.url}") private String url; @Value("${bip.flag}") private Boolean bipFlag; @Override public R edit(BankStatementUpdateDTO updateDTO) { BankStatement statement = baseMapper.selectById(updateDTO.getId()); if (CollUtil.isEmpty(updateDTO.getContractCollectionList())){ return R.failed("请选择收款合同后在提交"); } BigDecimal toPaidTotal = updateDTO.getContractCollectionList().stream() .map(StatementContractDTO::getToPaidAmount) .reduce(BigDecimal.ZERO, BigDecimal::add); if (toPaidTotal.compareTo(statement.getTranAmount().subtract(statement.getConfirmAmount()))>0){ return R.failed("确认收款总额不能超过交易流水金额"); } //bip推送 if (bipFlag) { R r = pushSaveCollection(statement, updateDTO.getContractCollectionList()); if (!r.isOk()){ return r; } } statement.setConfirmAmount(statement.getConfirmAmount().add(toPaidTotal)); baseMapper.updateById(statement); updateDTO.getContractCollectionList().stream().forEach(statementContractDTO -> { BankStatementItem item = new BankStatementItem(); item.setStatetId(statement.getId()); item.setBankSeqNo(statement.getBankSeqNo()); item.setConfirmAmount(statementContractDTO.getToPaidAmount()); item.setContractId(statementContractDTO.getId()); bankStatementItemMapper.insert(item); Contract contract = contractMapper.selectById(statementContractDTO.getId()); PaymentConfirmAddDTO addDTO = new PaymentConfirmAddDTO(); addDTO.setBusGuestId(statement.getBusGuestId()+""); addDTO.setConfirmTime(statement.getTranDate()); addDTO.setContractNo(contract.getContractNo()); addDTO.setInOrOut("1"); addDTO.setTransationAmount(statementContractDTO.getToPaidAmount()); addDTO.setBankSeqNo(statement.getBankSeqNo()); paymentConfirmService.add(addDTO); }); return R.ok(); } private R pushSaveCollection(BankStatement statement, List contractDTOList) { String accessToken = ""; if (redisTemplate.hasKey("BIP_TOKEN")) { accessToken = (String) redisTemplate.opsForValue().get("BIP_TOKEN"); } else { accessToken = paymentConfirmService.getAccessToken(accessToken); } if (StrUtil.isEmpty(accessToken)) { log.error("bip accessToken 获取异常"); return R.failed("bip accessToken 获取异常"); } String finalAccessToken = accessToken; BusinessCustomer customer = businessCustomerMapper.selectById(statement.getBusGuestId()); if (ObjUtil.isNull(customer)||StrUtil.isEmpty(customer.getBipCode())){ log.error("查询客户信息异常"); return R.failed("查询客户信息异常"); } R r = remoteDeptService.getById(SecurityUtils.getUser().getCompId()); log.info("查询单位信息:{}",JSONObject.toJSONString(r.getData())); if (!r.isOk()){ log.error("查询单位信息异常"); return R.failed("查询单位信息异常"); } SysDept dept = r.getData(); JSONObject params = genRequestParam(statement,dept,customer,contractDTOList); log.info("收款单集成 Request:{}", params.toJSONString()); String result = HttpUtil.post(url + "/yonbip/EFI/collection/saveandsubmit?access_token=" + finalAccessToken, params.toJSONString()); log.info("收款单集成 Response:{}", result); JSONObject resultJson = JSONObject.parseObject(result); if (!resultJson.getString("code").equals("200")) { return R.failed(resultJson.getString("message")); } return R.ok(); } private JSONObject genRequestParam(BankStatement statement,SysDept dept,BusinessCustomer customer,List contractDTOList) { JSONObject jsonObject = new JSONObject(); JSONObject data = new JSONObject(); data.put("billDate",DateUtil.format(statement.getTranDate(), DatePattern.NORM_DATETIME_FORMAT)); data.put("exchangeRate","1");//汇率 data.put("exchangeRateDate",DateUtil.now());//汇率时间 data.put("objectType","1"); data.put("customerCode",customer.getBipCode());//客户编码 data.put("financeOrgCode",dept.getBipCode());//开票组织编码 data.put("orgCode",dept.getBipCode());//业务组织编码 data.put("bustypeCode","ar_colsale");// TODO 交易类型编码 暂估默认ZGYSFP,装备默认ZBYXGLXT暂时不能用 data.put("oriCurrencyCode","CNY");//币种 data.put("srcBillType","38"); data.put("srcBillNo",statement.getBankSeqNo()); data.put("_status","Insert"); JSONArray bodyItem = new JSONArray(); for (StatementContractDTO statementContractDTO:contractDTOList) { Contract contract = contractMapper.selectById(statementContractDTO.getId()); JSONObject item = new JSONObject(); item.put("oriTaxIncludedAmount", statementContractDTO.getToPaidAmount()); item.put("contractNo", contract.getContractNo()); item.put("quickTypeCode", "1"); item.put("_status", "Insert"); bodyItem.add(item); } data.put("bodyItem",bodyItem); jsonObject.put("data",data); return jsonObject; } @Override public R getHistoryById(Long id) { MPJLambdaWrapper wrapper = new MPJLambdaWrapper() .selectAll(BankStatementItem.class) .select(Contract::getContractNo) .select(Contract::getPartyA) .select(Contract::getAmount) .leftJoin(Contract.class,Contract::getId,BankStatementItem::getContractId) .eq(BankStatementItem::getCompId,SecurityUtils.getUser().getCompId()) .orderByDesc(BankStatementItem::getCreateTime); return R.ok(bankStatementItemMapper.selectJoinList(StatementContractVo.class, wrapper)); } @Override public R delHistoryById(Long id) { BankStatementItem statement = bankStatementItemMapper.selectById(id); BankStatement bankStatement = baseMapper.selectById(statement.getStatetId()); Contract contract = contractMapper.selectById(statement.getContractId()); if (ObjUtil.isNull(contract)){ return R.failed("合同信息异常"); } BusinessCustomer customer = businessCustomerMapper.selectById(contract.getPartyAId()); if (ObjUtil.isNull(customer)){ return R.failed("客户信息信息异常"); } R r = remoteDeptService.getById(contract.getPartyBId()); if (!r.isOk()){ return r; } //bip推送 if (bipFlag) { String accessToken = ""; if (redisTemplate.hasKey("BIP_TOKEN")) { accessToken = (String) redisTemplate.opsForValue().get("BIP_TOKEN"); } else { accessToken = paymentConfirmService.getAccessToken(accessToken); } if (StrUtil.isEmpty(accessToken)) { log.error("bip accessToken 获取异常"); return R.failed("bip accessToken 获取异常"); } String finalAccessToken = accessToken; JSONObject request = genRefundParam(bankStatement,statement, contract, customer, r.getData()); log.info("收款退款单-退款单一历史确认请求入参:{}", request.toJSONString()); String result = HttpUtil.post(url + "/yonbip/EFI/arRefund/saveandsubmit?access_token=" + finalAccessToken, request.toJSONString()); log.info("收款退款单-退款单一历史确认请求回参:{}", result); JSONObject resultJson = JSONObject.parseObject(result); if (!resultJson.getString("code").equals("200")) { return R.failed(resultJson.getString("message")); } } bankStatementItemMapper.deleteById(id); bankStatement.setConfirmAmount(bankStatement.getConfirmAmount().subtract(statement.getConfirmAmount())); baseMapper.updateById(bankStatement); return R.ok(); } private JSONObject genRefundParam(BankStatement bankStatement,BankStatementItem statement, Contract contract,BusinessCustomer customer, SysDept dept) { JSONObject jsonObject = new JSONObject(); JSONObject data = new JSONObject(); data.put("billDate",DateUtil.now()); data.put("exchangeRate","1");//汇率 data.put("exchangeRateDate",DateUtil.now());//汇率时间 data.put("objectType","1"); data.put("customerCode",customer.getBipCode());//客户编码 data.put("financeOrgCode",dept.getBipCode());//开票组织编码 data.put("orgCode",dept.getBipCode());//业务组织编码 data.put("bustypeCode","ar_refsale");//交易类型编码 暂估默认ZGYSFP,销售默认MJHYXGLXT data.put("oriCurrencyCode","CNY");//币种 data.put("srcBillType","38"); data.put("srcBillNo",bankStatement.getBankSeqNo()); data.put("_status","Insert"); JSONArray bodyItem = new JSONArray(); JSONObject item = new JSONObject(); item.put("oriTaxIncludedAmount", statement.getConfirmAmount()); item.put("contractNo", contract.getContractNo()); item.put("quickTypeCode", "1"); item.put("_status", "Insert"); bodyItem.add(item); data.put("bodyItem",bodyItem); jsonObject.put("data",data); return jsonObject; } @Override public R backBal(Long id) { BankStatement bankStatement = baseMapper.selectById(id); BusinessCustomer customer = businessCustomerMapper.selectById(bankStatement.getBusGuestId()); if (ObjUtil.isNull(customer)||StrUtil.isEmpty(customer.getBipCode())){ log.error("查询客户信息异常"); return R.failed("查询客户信息异常"); } R r = remoteDeptService.getById(SecurityUtils.getUser().getCompId()); if (!r.isOk()){ log.error("查询单位信息异常"); return R.failed("查询单位信息异常"); } SysDept dept = r.getData(); List items = bankStatementItemMapper.selectList(Wrappers.lambdaQuery() .eq(BankStatementItem::getStatetId,id)); if (bipFlag){ String accessToken = ""; if (redisTemplate.hasKey("BIP_TOKEN")) { accessToken = (String) redisTemplate.opsForValue().get("BIP_TOKEN"); } else { accessToken = paymentConfirmService.getAccessToken(accessToken); } if (StrUtil.isEmpty(accessToken)) { log.error("bip accessToken 获取异常"); return R.failed("bip accessToken 获取异常"); } String finalAccessToken = accessToken; JSONObject request = genBackBalParam(bankStatement,customer,dept,items); log.info("收款退款单-退款余额请求入参:{}", request.toJSONString()); String result = HttpUtil.post(url + "/yonbip/EFI/arRefund/saveandsubmit?access_token=" + finalAccessToken, request.toJSONString()); log.info("收款退款单-退款余额请求回参:{}", result); JSONObject resultJson = JSONObject.parseObject(result); if (!resultJson.getString("code").equals("200")) { return R.failed(resultJson.getString("message")); } } bankStatement.setTranAmount(bankStatement.getConfirmAmount()); baseMapper.updateById(bankStatement); return R.ok(); } private JSONObject genBackBalParam(BankStatement bankStatement, BusinessCustomer customer, SysDept dept, List items) { JSONObject jsonObject = new JSONObject(); JSONObject data = new JSONObject(); data.put("billDate",DateUtil.now()); data.put("exchangeRate","1");//汇率 data.put("exchangeRateDate",DateUtil.now());//汇率时间 data.put("objectType","1"); data.put("customerCode",customer.getBipCode());//客户编码 data.put("financeOrgCode",dept.getBipCode());//开票组织编码 data.put("orgCode",dept.getBipCode());//业务组织编码 data.put("bustypeCode","ar_refsale");//交易类型编码 暂估默认ZGYSFP,销售默认MJHYXGLXT data.put("oriCurrencyCode","CNY");//币种 data.put("srcBillType","38"); data.put("srcBillNo",bankStatement.getBankSeqNo()); data.put("_status","Insert"); JSONArray bodyItem = new JSONArray(); JSONObject item = new JSONObject(); item.put("oriTaxIncludedAmount", bankStatement.getTranAmount().subtract(bankStatement.getConfirmAmount())); item.put("quickTypeCode", "1"); item.put("_status", "Insert"); bodyItem.add(item); data.put("bodyItem",bodyItem); jsonObject.put("data",data); return jsonObject; } @Override public R backAll(Long id) { BankStatement bankStatement = baseMapper.selectById(id); BusinessCustomer customer = businessCustomerMapper.selectById(bankStatement.getBusGuestId()); if (ObjUtil.isNull(customer)||StrUtil.isEmpty(customer.getBipCode())){ log.error("查询客户信息异常"); return R.failed("查询客户信息异常"); } R r = remoteDeptService.getById(SecurityUtils.getUser().getCompId()); if (!r.isOk()){ log.error("查询单位信息异常"); return R.failed("查询单位信息异常"); } SysDept dept = r.getData(); List items = bankStatementItemMapper.selectList(Wrappers.lambdaQuery() .eq(BankStatementItem::getStatetId,id)); if (bipFlag){ String accessToken = ""; if (redisTemplate.hasKey("BIP_TOKEN")) { accessToken = (String) redisTemplate.opsForValue().get("BIP_TOKEN"); } else { accessToken = paymentConfirmService.getAccessToken(accessToken); } if (StrUtil.isEmpty(accessToken)) { log.error("bip accessToken 获取异常"); return R.failed("bip accessToken 获取异常"); } String finalAccessToken = accessToken; JSONObject request = genBackAllParam(bankStatement,customer,dept,items); log.info("收款退款单-退款所有请求入参:{}", request.toJSONString()); String result = HttpUtil.post(url + "/yonbip/EFI/arRefund/saveandsubmit?access_token=" + finalAccessToken, request.toJSONString()); log.info("收款退款单-退款所有请求回参:{}", result); JSONObject resultJson = JSONObject.parseObject(result); if (!resultJson.getString("code").equals("200")) { return R.failed(resultJson.getString("message")); } } bankStatement.setConfirmAmount(new BigDecimal("0")); baseMapper.updateById(bankStatement); return R.ok(); } private JSONObject genBackAllParam(BankStatement bankStatement, BusinessCustomer customer, SysDept dept, List items) { JSONObject jsonObject = new JSONObject(); JSONObject data = new JSONObject(); data.put("billDate",DateUtil.now()); data.put("exchangeRate","1");//汇率 data.put("exchangeRateDate",DateUtil.now());//汇率时间 data.put("objectType","1"); data.put("customerCode",customer.getBipCode());//客户编码 data.put("financeOrgCode",dept.getBipCode());//开票组织编码 data.put("orgCode",dept.getBipCode());//业务组织编码 data.put("bustypeCode","ar_refsale");//交易类型编码 暂估默认ZGYSFP,销售默认MJHYXGLXT data.put("oriCurrencyCode","CNY");//币种 data.put("srcBillType","38"); data.put("srcBillNo",bankStatement.getBankSeqNo()); data.put("_status","Insert"); JSONArray bodyItem = new JSONArray(); JSONObject item = new JSONObject(); item.put("oriTaxIncludedAmount", bankStatement.getTranAmount()); item.put("quickTypeCode", "1"); item.put("_status", "Insert"); bodyItem.add(item); data.put("bodyItem",bodyItem); jsonObject.put("data",data); return jsonObject; } @Override public R backHis(Long id) { BankStatement bankStatement = baseMapper.selectById(id); BusinessCustomer customer = businessCustomerMapper.selectById(bankStatement.getBusGuestId()); if (ObjUtil.isNull(customer)||StrUtil.isEmpty(customer.getBipCode())){ log.error("查询客户信息异常"); return R.failed("查询客户信息异常"); } R r = remoteDeptService.getById(SecurityUtils.getUser().getCompId()); if (!r.isOk()){ log.error("查询单位信息异常"); return R.failed("查询单位信息异常"); } SysDept dept = r.getData(); List items = bankStatementItemMapper.selectList(Wrappers.lambdaQuery() .eq(BankStatementItem::getStatetId,id)); if (bipFlag){ String accessToken = ""; if (redisTemplate.hasKey("BIP_TOKEN")) { accessToken = (String) redisTemplate.opsForValue().get("BIP_TOKEN"); } else { accessToken = paymentConfirmService.getAccessToken(accessToken); } if (StrUtil.isEmpty(accessToken)) { log.error("bip accessToken 获取异常"); return R.failed("bip accessToken 获取异常"); } String finalAccessToken = accessToken; JSONObject request = genBackHisParam(bankStatement,customer,dept,items); log.info("收款退款单-退款历史确认请求入参:{}", request.toJSONString()); String result = HttpUtil.post(url + "/yonbip/EFI/arRefund/saveandsubmit?access_token=" + finalAccessToken, request.toJSONString()); log.info("收款退款单-退款历史确认请求回参:{}", result); JSONObject resultJson = JSONObject.parseObject(result); if (!resultJson.getString("code").equals("200")) { return R.failed(resultJson.getString("message")); } } bankStatement.setConfirmAmount(new BigDecimal("0")); baseMapper.updateById(bankStatement); bankStatementItemMapper.deleteByIds(items.stream().map(item->item.getId()).collect(Collectors.toList())); return R.ok(); } private JSONObject genBackHisParam(BankStatement bankStatement, BusinessCustomer customer, SysDept dept,List items) { JSONObject jsonObject = new JSONObject(); JSONObject data = new JSONObject(); data.put("billDate",DateUtil.now()); data.put("exchangeRate","1");//汇率 data.put("exchangeRateDate",DateUtil.now());//汇率时间 data.put("objectType","1"); data.put("customerCode",customer.getBipCode());//客户编码 data.put("financeOrgCode",dept.getBipCode());//开票组织编码 data.put("orgCode",dept.getBipCode());//业务组织编码 data.put("bustypeCode","ar_refsale");//交易类型编码 暂估默认ZGYSFP,销售默认MJHYXGLXT data.put("oriCurrencyCode","CNY");//币种 data.put("srcBillType","38"); data.put("srcBillNo",bankStatement.getBankSeqNo()); data.put("_status","Insert"); JSONArray bodyItem = new JSONArray(); for (BankStatementItem statementItem:items) { Contract contract = contractMapper.selectById(statementItem.getContractId()); JSONObject item = new JSONObject(); item.put("oriTaxIncludedAmount", statementItem.getConfirmAmount()); item.put("contractNo", contract.getContractNo()); item.put("quickTypeCode", "1"); item.put("_status", "Insert"); bodyItem.add(item); } data.put("bodyItem",bodyItem); jsonObject.put("data",data); return jsonObject; } }