package com.ruoyi.tms.service.impl; import java.util.List; import com.ruoyi.common.utils.DateUtils; import javax.annotation.Resource; import com.ruoyi.tms.domain.TmsApBillItem; import com.ruoyi.tms.domain.TmsArBillItem; import com.ruoyi.tms.mapper.TmsApBillItemMapper; import org.springframework.transaction.annotation.Transactional; import org.springframework.stereotype.Service; import org.springframework.scheduling.annotation.Async; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.ruoyi.common.utils.PageUtils; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.annotation.DataSource; import com.ruoyi.common.enums.DataSourceType; import com.ruoyi.common.core.service.BaseService; import com.ruoyi.tms.mapper.TmsApBillMapper; import com.ruoyi.tms.domain.TmsApBill; import com.ruoyi.tms.service.ITmsApBillService; import com.ruoyi.common.core.text.Convert; import com.ruoyi.tms.mapper.TmsPayableFeeMapper; import com.ruoyi.tms.domain.TmsPayableFee; import com.ruoyi.tms.domain.TmsPayableFeeItem; import com.ruoyi.tms.mapper.TmsPayableFeeItemMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.task.AsyncTaskExecutor; import org.springframework.core.task.SimpleAsyncTaskExecutor; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestTemplate; import com.alibaba.fastjson2.JSON; import com.ruoyi.tms.domain.PayableAuditLog; import com.ruoyi.tms.service.IPayableAuditLogService; /** * 应付账单Service业务层处理 * * @author ruoyi * @date 2026-01-12 */ @Service @Transactional(rollbackFor = Exception.class) public class TmsApBillServiceImpl extends BaseService implements ITmsApBillService { protected final Logger logger = LoggerFactory.getLogger(getClass()); @Resource private TmsApBillMapper tmsApBillMapper; @Resource private TmsApBillItemMapper tmsApBillItemMapper; @Resource private TmsPayableFeeMapper tmsPayableFeeMapper; @Resource private TmsPayableFeeItemMapper tmsPayableFeeItemMapper; @Autowired private RestTemplate restTemplate; @Autowired private IPayableAuditLogService payableAuditLogService; @Value("${custom.cwxtApi.url}") private String url; /** * 查询应付账单 * * @param id 应付账单ID * @return 应付账单 */ @DataSource(DataSourceType.SLAVE) @Override public TmsApBill selectTmsApBillById(Integer id) { TmsApBill tmsApBill = tmsApBillMapper.selectTmsApBillById(id); tmsApBill.setItems(tmsApBillItemMapper.selectTmsApBillItemList(new TmsApBillItem(){{setBillId( id);setStatus(0);}})); return tmsApBill; } /** * 查询应付账单 记录数 * * @param tmsApBill 应付账单 * @return 应付账单集合 */ @DataSource(DataSourceType.SLAVE) @Override public int selectTmsApBillCount(TmsApBill tmsApBill) { return tmsApBillMapper.selectTmsApBillCount(tmsApBill); } /** * 查询应付账单列表 * * @param tmsApBill 应付账单 * @return 应付账单 */ @DataSource(DataSourceType.SLAVE) @Override public List selectTmsApBillList(TmsApBill tmsApBill) { return tmsApBillMapper.selectTmsApBillList(tmsApBill); } /** * 查询应付账单列表 异步 导出 * * @param tmsApBill 应付账单 * @param exportKey 导出功能的唯一标识 * @return 应付账单集合 */ @DataSource(DataSourceType.SLAVE) @Async @Override public void export(TmsApBill tmsApBill,String exportKey) { super.export(TmsApBill.class,exportKey,"tmsApBillData",(pageNum)->{ PageUtils.startPage(pageNum, Constants.EXPORT_PATE_SIZE); return selectTmsApBillList(tmsApBill); }); } /** * 新增应付账单 * * @param tmsApBill 应付账单 * @return 结果 */ @Override public int insertTmsApBill(TmsApBill tmsApBill) { tmsApBill.setCreateTime(DateUtils.getNowDate()); return tmsApBillMapper.insertTmsApBill(tmsApBill); } /** * 新增应付账单[批量] * * @param tmsApBills 应付账单 * @return 结果 */ @Override public int insertTmsApBillBatch(List tmsApBills) { int rows = tmsApBillMapper.insertTmsApBillBatch(tmsApBills); return rows; } /** * 修改应付账单 * * @param tmsApBill 应付账单 * @return 结果 */ @Override public int updateTmsApBill(TmsApBill tmsApBill) { tmsApBill.setUpdateTime(DateUtils.getNowDate()); return tmsApBillMapper.updateTmsApBill(tmsApBill); } /** * 修改应付账单[批量] * * @param tmsApBills 应付账单 * @return 结果 */ @Override public int updateTmsApBillBatch(List tmsApBills){ return tmsApBillMapper.updateTmsApBillBatch(tmsApBills); } /** * 删除应付账单对象 * * @param ids 需要删除的数据ID * @return 结果 */ @Override public int deleteTmsApBillByIds(String ids) { return deleteTmsApBillByIds(Convert.toIntArray(ids)); } /** * 删除应付账单对象 * * * @param ids 需要删除的数据ID * @return 结果 */ @Override public int deleteTmsApBillByIds(Integer[] ids) { return tmsApBillMapper.deleteTmsApBillByIds(ids); } /** * 删除应付账单信息 * * @param id 应付账单ID * @return 结果 */ @Override public int deleteTmsApBillById(Integer id) { return tmsApBillMapper.deleteTmsApBillById(id); } /** * 手动推送应付账单到外部系统 * * @param id 应付账单ID * @return 结果 */ @Override public void manualPushToExternalSystem(Integer id) { TmsApBill tmsApBill = tmsApBillMapper.selectTmsApBillById(id); if (tmsApBill == null) { throw new RuntimeException("应付账单不存在"); } // 查询关联的应付费用列表 List tmsPayableFeeList = tmsPayableFeeMapper.selectList(new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper() .eq(TmsPayableFee::getBillPayableId, id) ); // 为每个应付费用加载明细 for (TmsPayableFee fee : tmsPayableFeeList) { List payableFeeItems = tmsPayableFeeItemMapper.selectTmsPayableFeeItemList(new TmsPayableFeeItem() { { setHeadId(fee.getId()); } }); fee.setPayableFeeItems(payableFeeItems); } // 异步推送 AsyncTaskExecutor executor = new SimpleAsyncTaskExecutor(); executor.execute(() -> pushPayableToExternalSystem(tmsApBill, tmsPayableFeeList)); } /** * 更新推送状态 * * @param id 应付账单ID * @param pushStatus 推送状态 * @return 结果 */ @Override public int updatePushStatus(Integer id, Integer pushStatus) { TmsApBill tmsApBill = new TmsApBill(); tmsApBill.setId(id); tmsApBill.setPushStatus(pushStatus); tmsApBill.setPushTime(DateUtils.getNowDate()); return tmsApBillMapper.updateTmsApBill(tmsApBill); } /** * 添加应付账单审核日志 * * @param auditLog 审核日志 * @return 结果 */ public int addApBillAuditLog(PayableAuditLog auditLog) { return payableAuditLogService.insertPayableAuditLog(auditLog); } /** * 向外部系统推送应付数据 * @param tmsApBill 应付账单 * @param tmsPayableFeeList 应付费用列表 */ @Async protected void pushPayableToExternalSystem(TmsApBill tmsApBill, List tmsPayableFeeList) { java.util.Map requestBody = new java.util.HashMap<>(); try { // 更新推送状态为推送中 tmsApBill.setPushStatus(1); tmsApBill.setPushTime(DateUtils.getNowDate()); tmsApBillMapper.updateTmsApBill(tmsApBill); // 构建请求体 String apiUrl = url+"/addPayableBill"; // 构建bill部分 java.util.Map billMap = new java.util.HashMap<>(); billMap.put("billName", tmsApBill.getBillName()); billMap.put("supplierName", tmsApBill.getServiceProviderName()); billMap.put("totalAmount", tmsApBill.getSettleAmount()); billMap.put("currency", "RMB"); billMap.put("status", "0"); billMap.put("isInternalSettlement", "0"); billMap.put("internalSettlementUnit", tmsApBill.getServiceProviderName()); billMap.put("documentCount", tmsPayableFeeList.size()); billMap.put("discountAmount", 0.00); billMap.put("paidAmount", 0.00); billMap.put("pendingAmount", tmsApBill.getSettleAmount()); billMap.put("exchangeRate", tmsApBill.getSettleRate()); billMap.put("cnyAmount", tmsApBill.getSettleAmount()); billMap.put("periodType", ""); billMap.put("businessStartDate", ""); billMap.put("businessEndDate", ""); billMap.put("billingStartDate", ""); billMap.put("billingEndDate", ""); billMap.put("billGenerateDate", ""); billMap.put("billSendDate", ""); billMap.put("billDueDate", ""); billMap.put("remark", ""); // 构建fees部分 List> feesList = new java.util.ArrayList<>(); for (int i = 0; i < tmsPayableFeeList.size(); i++) { TmsPayableFee fee = tmsPayableFeeList.get(i); java.util.Map feeMap = new java.util.HashMap<>(); feeMap.put("sourceSystem", "TMS"); feeMap.put("documentNo", fee.getDispatchNo() != null ? fee.getDispatchNo() : ""); feeMap.put("supplierName", tmsApBill.getServiceProviderName()); feeMap.put("payableAmount", fee.getPayableRmbAmount().add(fee.getPayableHkbAmount())); java.math.BigDecimal rmbAmount = fee.getPayableRmbAmount(); java.math.BigDecimal hkbAmount = fee.getPayableHkbAmount(); StringBuilder amountStr = new StringBuilder(); if (rmbAmount.compareTo(java.math.BigDecimal.ZERO) > 0) { amountStr.append(rmbAmount).append("人民币"); } if (hkbAmount.compareTo(java.math.BigDecimal.ZERO) > 0) { if (amountStr.length() > 0) { amountStr.append(" "); } amountStr.append(hkbAmount).append("港币"); } feeMap.put("payableAmountStr", amountStr.toString()); feeMap.put("serialNumber", String.format("%03d", i + 1)); feeMap.put("relatedBillNo", ""); feeMap.put("businessSector", "0"); feeMap.put("documentType", "0"); feeMap.put("isInternalSettlement", "0"); feeMap.put("internalSettlementUnit", ""); feeMap.put("projectName", fee.getProjectName() != null ? fee.getProjectName() : ""); feeMap.put("businessTime", fee.getDispatchConfirmTime()); feeMap.put("payableConfirmTime", fee.getDispatchConfirmTime()); feeMap.put("status", "1"); feeMap.put("remark", ""); // 构建feeDetails部分 List> feeDetailsList = new java.util.ArrayList<>(); List payableFeeItems = fee.getPayableFeeItems(); for (TmsPayableFeeItem payableFeeItem : payableFeeItems) { java.util.Map feeDetailMap = new java.util.HashMap<>(); feeDetailMap.put("feeType", payableFeeItem.getFeeType()); feeDetailMap.put("feeName", payableFeeItem.getFeeName()); feeDetailMap.put("unitPrice", payableFeeItem.getRegisterAmount()); feeDetailMap.put("billingQuantity", payableFeeItem.getRegisterAmount()); feeDetailMap.put("billingAmount", payableFeeItem.getRegisterAmount()); feeDetailMap.put("billingUnit", "次"); feeDetailMap.put("actualAmount", payableFeeItem.getRegisterAmount()); feeDetailMap.put("currency", payableFeeItem.getCurrency()); feeDetailMap.put("feeRegTime", payableFeeItem.getRegisterTime()); feeDetailMap.put("remark", ""); feeDetailsList.add(feeDetailMap); } feeMap.put("feeDetails", feeDetailsList); feesList.add(feeMap); } // 构建完整请求体 requestBody.put("bill", billMap); requestBody.put("fees", feesList); // 设置HTTP头 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity entity = new HttpEntity<>(JSON.toJSONString(requestBody), headers); // 发送API请求 ResponseEntity response = restTemplate.exchange(apiUrl, HttpMethod.POST, entity, String.class); logger.info("推送应付数据到外部系统成功,响应: {}", response.getBody()); // 更新推送状态为成功 tmsApBill.setPushStatus(2); tmsApBill.setPushTime(DateUtils.getNowDate()); tmsApBillMapper.updateTmsApBill(tmsApBill); } catch (Exception e) { logger.error("推送应付数据到外部系统失败,账单ID: {}, 供应商: {}", tmsApBill.getId(), tmsApBill.getServiceProviderName(), e); logger.debug("推送失败的请求数据: {}", JSON.toJSONString(requestBody)); // 更新推送状态为失败 tmsApBill.setPushStatus(3); tmsApBill.setPushTime(DateUtils.getNowDate()); tmsApBillMapper.updateTmsApBill(tmsApBill); } } }