diff --git a/jsowell-quartz/src/main/java/com/jsowell/quartz/service/AdapayUnsplitRecordHandleService.java b/jsowell-quartz/src/main/java/com/jsowell/quartz/service/AdapayUnsplitRecordHandleService.java index 4d01168b6..6a8b47dea 100644 --- a/jsowell-quartz/src/main/java/com/jsowell/quartz/service/AdapayUnsplitRecordHandleService.java +++ b/jsowell-quartz/src/main/java/com/jsowell/quartz/service/AdapayUnsplitRecordHandleService.java @@ -11,4 +11,6 @@ public interface AdapayUnsplitRecordHandleService { void importAdapayUnsplitRecordAndCompleteFields(String filePath); int completeAdapayUnsplitRecordFields(String startTime, String endTime); + + void processUnSettledOrder(); } diff --git a/jsowell-quartz/src/main/java/com/jsowell/quartz/service/impl/AdapayUnsplitRecordHandleServiceImpl.java b/jsowell-quartz/src/main/java/com/jsowell/quartz/service/impl/AdapayUnsplitRecordHandleServiceImpl.java index b47d74d60..323f3a5de 100644 --- a/jsowell-quartz/src/main/java/com/jsowell/quartz/service/impl/AdapayUnsplitRecordHandleServiceImpl.java +++ b/jsowell-quartz/src/main/java/com/jsowell/quartz/service/impl/AdapayUnsplitRecordHandleServiceImpl.java @@ -68,6 +68,14 @@ public class AdapayUnsplitRecordHandleServiceImpl implements AdapayUnsplitRecord @Autowired private AdapayUnsplitRecordService adapayUnsplitRecordService; + @Override + public void processUnSettledOrder() { + for (int i = 0; i < 35; i++) { + int batchNum = i + 1; + processUnSettledOrderV2(batchNum); + } + } + @Override public void processUnsplitRecordToDefaultMember() { processUnsplitRecordToDefaultMember(Constants.DEFAULT_APP_ID, 500); @@ -207,6 +215,66 @@ public class AdapayUnsplitRecordHandleServiceImpl implements AdapayUnsplitRecord return updatedCount; } + /** + * V1方法,获取退款金额与结算金额 + */ + private void processUnSettledOrderV1(int batchNum) { + String startTime = "2025-01-01 00:00:00"; + String endTime = "2025-12-31 23:59:59"; + + PageUtils.startPage(1, 1000); + List list = adapayUnsplitRecordService.queryUnsplitOrders(startTime, endTime); + log.info("第{}批次,共查询到{}条数据", batchNum, list.size()); + if (CollectionUtils.isEmpty(list)) { + return; + } + + Map map = list.stream() + .collect(Collectors.toMap(AdapayUnsplitRecord::getOrderCode, v -> v, (k1, k2) -> k1)); + Set orderCodes = map.keySet(); + + List orderList = orderBasicInfoService.selectOrderTemp(orderCodes); + Map orderMap = orderList.stream() + .collect(Collectors.toMap(OrderBasicInfo::getOrderCode, v -> v, (k1, k2) -> k1)); + + List updateList = new ArrayList<>(); + for (String orderCode : orderCodes) { + OrderBasicInfo orderBasicInfo = orderMap.get(orderCode); + if (orderBasicInfo == null) { + continue; + } + AdapayUnsplitRecord adapayUnsplitRecord = map.get(orderCode); + adapayUnsplitRecord.setDueRefundAmount(orderBasicInfo.getRefundAmount()); + adapayUnsplitRecord.setSettleAmount(orderBasicInfo.getSettleAmount()); + String pileSn = orderBasicInfo.getPileSn(); + adapayUnsplitRecord.setPileType(YouDianUtils.isEBikePileSn(pileSn) ? "eBike" : "EV"); + updateList.add(adapayUnsplitRecord); + } + adapayUnsplitRecordService.updateBatchSelective(updateList); + log.info("第{}批次,共更新{}条数据", batchNum, updateList.size()); + } + + /** + * 更新adapay_unsplit_record表,去汇付查询最新的数据 + */ + private void processUnSettledOrderV2(int batchNum) { + String startTime = "2025-01-01 00:00:00"; + String endTime = "2025-12-31 23:59:59"; + + PageUtils.startPage(1, 3); + List list = adapayUnsplitRecordService.queryUnsplitOrders(startTime, endTime); + + for (AdapayUnsplitRecord adapayUnsplitRecord : list) { + String paymentId = adapayUnsplitRecord.getPaymentId(); + + QueryPaymentConfirmDTO dto = new QueryPaymentConfirmDTO(); + dto.setWechatAppId(Constants.DEFAULT_APP_ID); + dto.setPaymentId(paymentId); + QueryPaymentConfirmDetailResponse response = adapayService.queryPaymentConfirmList(dto); + log.info("第{}批次,paymentId:{}, 汇付确认信息:{}", batchNum, paymentId, JSON.toJSONString(response)); + } + } + private ImportSummary importAdapayUnsplitRecord(Path filePath) { ImportSummary summary = new ImportSummary(); DataFormatter formatter = new DataFormatter(); diff --git a/jsowell-quartz/src/main/java/com/jsowell/quartz/task/JsowellTask.java b/jsowell-quartz/src/main/java/com/jsowell/quartz/task/JsowellTask.java index f0d919e3c..55adbb8c0 100644 --- a/jsowell-quartz/src/main/java/com/jsowell/quartz/task/JsowellTask.java +++ b/jsowell-quartz/src/main/java/com/jsowell/quartz/task/JsowellTask.java @@ -1,41 +1,24 @@ package com.jsowell.quartz.task; -import com.alibaba.fastjson2.JSON; import com.google.common.collect.Lists; -import com.jsowell.adapay.common.DivMember; -import com.jsowell.adapay.common.PaymentConfirmInfo; -import com.jsowell.adapay.dto.PaymentConfirmParam; -import com.jsowell.adapay.dto.QueryPaymentConfirmDTO; import com.jsowell.adapay.dto.WithdrawDTO; -import com.jsowell.adapay.response.PaymentConfirmResponse; -import com.jsowell.adapay.response.QueryPaymentConfirmDetailResponse; import com.jsowell.adapay.service.AdapayService; -import com.jsowell.common.YouDianUtils; import com.jsowell.common.constant.CacheConstants; import com.jsowell.common.constant.Constants; import com.jsowell.common.core.redis.RedisCache; import com.jsowell.common.enums.SoftwareProtocolEnum; -import com.jsowell.common.enums.adapay.AdapayStatusEnum; import com.jsowell.common.enums.thirdparty.ThirdPlatformTypeEnum; import com.jsowell.common.enums.ykc.PileChannelEntity; import com.jsowell.common.util.DateUtils; -import com.jsowell.common.util.PageUtils; import com.jsowell.common.util.StringUtils; import com.jsowell.common.util.spring.SpringUtils; -import com.jsowell.pile.domain.AdapayUnsplitRecord; -import com.jsowell.pile.domain.OrderBasicInfo; -import com.jsowell.pile.domain.PileBasicInfo; -import com.jsowell.pile.domain.PileMerchantInfo; -import com.jsowell.pile.domain.PileStationInfo; -import com.jsowell.pile.dto.ApplyRefundDTO; -import com.jsowell.pile.domain.ykcCommond.PublishPileBillingTemplateCommand; +import com.jsowell.pile.domain.*; import com.jsowell.pile.domain.ykcCommond.ProofreadTimeCommand; +import com.jsowell.pile.domain.ykcCommond.PublishPileBillingTemplateCommand; import com.jsowell.pile.domain.ykcCommond.StartChargingCommand; import com.jsowell.pile.service.*; -import com.jsowell.pile.vo.AdapayUnsplitRecordVO; import com.jsowell.pile.vo.base.StationInfoVO; import com.jsowell.pile.vo.web.BillingTemplateVO; -import com.jsowell.pile.vo.web.OrderDetailInfoVO; import com.jsowell.quartz.service.AdapayUnsplitRecordHandleService; import com.jsowell.thirdparty.amap.service.AMapService; import com.jsowell.thirdparty.common.NotificationDTO; @@ -47,11 +30,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import java.io.InputStream; import java.math.BigDecimal; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.*; @@ -101,9 +80,6 @@ public class JsowellTask { // @Autowired // private OrderUnsplitRecordService orderUnsplitRecordService; - @Autowired - private AdapayUnsplitRecordService adapayUnsplitRecordService; - @Autowired private AdapayUnsplitRecordHandleService adapayUnsplitRecordHandleService; @@ -508,11 +484,7 @@ public class JsowellTask { * jsowellTask.processUnSettledOrder() */ public void processUnSettledOrder() { - // processUnSettledOrderOld(); // 旧方法 - for (int i = 0; i < 35; i++) { - int batchNum = i + 1; - processUnSettledOrderV2(batchNum); // 新方法 - } + adapayUnsplitRecordHandleService.processUnSettledOrder(); } /** @@ -569,614 +541,6 @@ public class JsowellTask { adapayUnsplitRecordHandleService.importAdapayUnsplitRecordAndCompleteFields(filePath); } - private static final int IMPORT_BATCH_SIZE = 500; - - private ImportSummary importAdapayUnsplitRecord(Path filePath) { - ImportSummary summary = new ImportSummary(); - DataFormatter formatter = new DataFormatter(); - - try (InputStream inputStream = Files.newInputStream(filePath); - Workbook workbook = WorkbookFactory.create(inputStream)) { - Sheet sheet = workbook.getSheetAt(0); - if (sheet == null) { - log.error("导入未分账数据失败,Excel没有sheet, file:{}", filePath.toAbsolutePath()); - return summary; - } - - Row headerRow = sheet.getRow(sheet.getFirstRowNum()); - if (headerRow == null) { - log.error("导入未分账数据失败,Excel没有表头, file:{}", filePath.toAbsolutePath()); - return summary; - } - - Map headerIndexMap = buildHeaderIndexMap(headerRow, formatter); - List requiredHeaders = Lists.newArrayList( - "商户号", "支付时间", "交易流水号", "交易订单号", "交易订单金额", "已确认分账金额", "已撤销金额", "支付确认撤销金额", "剩余未分账金额" - ); - for (String requiredHeader : requiredHeaders) { - if (!headerIndexMap.containsKey(normalizeHeader(requiredHeader))) { - log.error("导入未分账数据失败,缺少字段:{}, file:{}", requiredHeader, filePath.toAbsolutePath()); - return summary; - } - } - - int firstDataRow = sheet.getFirstRowNum() + 1; - int lastDataRow = sheet.getLastRowNum(); - // 批量收集记录,每 IMPORT_BATCH_SIZE 条执行一次批量 upsert,减少数据库交互次数 - List batch = new ArrayList<>(IMPORT_BATCH_SIZE); - for (int rowNum = firstDataRow; rowNum <= lastDataRow; rowNum++) { - Row row = sheet.getRow(rowNum); - if (row == null || isRowEmpty(row)) { - continue; - } - summary.totalRows++; - - try { - AdapayUnsplitRecord record = convertRowToRecord(row, headerIndexMap, formatter); - if (record == null) { - summary.skippedRows++; - continue; - } - batch.add(record); - summary.updatePayTimeRange(record.getPayTime()); - - // 达到批量大小时执行一次批量写入 - if (batch.size() >= IMPORT_BATCH_SIZE) { - flushImportBatch(batch); - summary.successRows += batch.size(); - batch.clear(); - } - } catch (Exception e) { - summary.failedRows++; - log.error("导入未分账数据失败, rowNum:{}, file:{}", rowNum + 1, filePath.toAbsolutePath(), e); - } - - if (summary.totalRows % 1000 == 0) { - log.info("导入未分账数据进行中, total:{}, success:{}, skipped:{}, failed:{}", - summary.totalRows, summary.successRows, summary.skippedRows, summary.failedRows); - } - } - // 处理剩余不足一批的记录 - if (!batch.isEmpty()) { - flushImportBatch(batch); - summary.successRows += batch.size(); - } - } catch (Exception e) { - log.error("导入未分账数据失败, file:{}", filePath.toAbsolutePath(), e); - } - - return summary; - } - - /** - * 写入一批导入数据:以 paymentId 为业务唯一键, - * - 数据库已存在相同 paymentId 的记录 -> 沿用其主键 id 走 updateBatchSelective 更新 - * - 数据库不存在的 -> 走 batchInsert 新增 - * 同一批内若出现重复 paymentId,仅保留最后一条(与文件读取顺序一致) - */ - private void flushImportBatch(List batch) { - if (CollectionUtils.isEmpty(batch)) { - return; - } - - // 同批内按 paymentId 去重,保留最后一条 - Map uniqueByPaymentId = new LinkedHashMap<>(); - for (AdapayUnsplitRecord record : batch) { - if (StringUtils.isNotBlank(record.getPaymentId())) { - uniqueByPaymentId.put(record.getPaymentId(), record); - } - } - if (uniqueByPaymentId.isEmpty()) { - return; - } - - List paymentIds = new ArrayList<>(uniqueByPaymentId.keySet()); - List existingList = adapayUnsplitRecordService.selectByPaymentIds(paymentIds); - Map existingIdMap = new HashMap<>(); - if (CollectionUtils.isNotEmpty(existingList)) { - for (AdapayUnsplitRecord existing : existingList) { - existingIdMap.put(existing.getPaymentId(), existing.getId()); - } - } - - List insertList = new ArrayList<>(); - List updateList = new ArrayList<>(); - for (AdapayUnsplitRecord record : uniqueByPaymentId.values()) { - Integer existingId = existingIdMap.get(record.getPaymentId()); - if (existingId != null) { - record.setId(existingId); - updateList.add(record); - } else { - insertList.add(record); - } - } - - if (!insertList.isEmpty()) { - adapayUnsplitRecordService.batchInsert(insertList); - } - if (!updateList.isEmpty()) { - adapayUnsplitRecordService.updateBatchSelective(updateList); - } - } - - private int completeUnsplitRecordMissingFields(String startTime, String endTime, int pageSize) { - int pageNum = 1; - int updatedCount = 0; - - while (true) { - PageUtils.startPage(pageNum, pageSize); - List list = adapayUnsplitRecordService.queryUnsplitOrders(startTime, endTime); - if (CollectionUtils.isEmpty(list)) { - break; - } - - Set orderCodeSet = new HashSet<>(); - for (AdapayUnsplitRecord record : list) { - if (StringUtils.isBlank(record.getOrderCode())) { - String extractedOrderCode = extractOrderCode(record.getOrderNo()); - if (StringUtils.isNotBlank(extractedOrderCode)) { - record.setOrderCode(extractedOrderCode); - } - } - if (StringUtils.isNotBlank(record.getOrderCode())) { - orderCodeSet.add(record.getOrderCode()); - } - } - - Map orderMap = new HashMap<>(); - if (CollectionUtils.isNotEmpty(orderCodeSet)) { - List orderList = orderBasicInfoService.selectOrderTemp(orderCodeSet); - orderMap = orderList.stream() - .collect(Collectors.toMap(OrderBasicInfo::getOrderCode, v -> v, (k1, k2) -> k1)); - } - - List updateList = new ArrayList<>(); - Date now = DateUtils.getNowDate(); - for (AdapayUnsplitRecord record : list) { - boolean needUpdate = false; - - String orderCode = record.getOrderCode(); - if (StringUtils.isBlank(orderCode)) { - orderCode = extractOrderCode(record.getOrderNo()); - if (StringUtils.isNotBlank(orderCode)) { - record.setOrderCode(orderCode); - needUpdate = true; - } - } - - if (StringUtils.isNotBlank(orderCode)) { - OrderBasicInfo orderBasicInfo = orderMap.get(orderCode); - if (orderBasicInfo != null) { - BigDecimal refundAmount = orderBasicInfo.getRefundAmount(); - if (!isSameAmount(record.getDueRefundAmount(), refundAmount)) { - record.setDueRefundAmount(refundAmount); - needUpdate = true; - } - BigDecimal settleAmount = orderBasicInfo.getSettleAmount(); - if (!isSameAmount(record.getSettleAmount(), settleAmount)) { - record.setSettleAmount(settleAmount); - needUpdate = true; - } - String pileType = YouDianUtils.isEBikePileSn(orderBasicInfo.getPileSn()) ? "eBike" : "EV"; - if (!StringUtils.equals(record.getPileType(), pileType)) { - record.setPileType(pileType); - needUpdate = true; - } - } - } - - if (needUpdate) { - record.setUpdateTime(now); - updateList.add(record); - } - } - - if (CollectionUtils.isNotEmpty(updateList)) { - adapayUnsplitRecordService.updateBatchSelective(updateList); - updatedCount += updateList.size(); - } - - if (list.size() < pageSize) { - break; - } - pageNum++; - } - - return updatedCount; - } - - private boolean ensureRefundBeforeSplit(AdapayUnsplitRecordVO item, String wechatAppId) { - String orderCode = item.getOrderCode(); - String paymentId = item.getPaymentId(); - BigDecimal dueRefundAmount = parseAmount(item.getRefundAmount()); - if (dueRefundAmount.compareTo(BigDecimal.ZERO) <= 0) { - return true; - } - - OrderBasicInfo orderBasicInfo = orderBasicInfoService.getOrderInfoByOrderCode(orderCode); - if (orderBasicInfo == null) { - log.warn("未分账数据退款前置校验失败,订单不存在, paymentId:{}, orderCode:{}", paymentId, orderCode); - markRefundResult(paymentId, "FAILED"); - return false; - } - - BigDecimal refundedAmount = getSucceededRefundAmount(orderBasicInfo); - updateRefundAmount(paymentId, refundedAmount); - if (refundedAmount.compareTo(dueRefundAmount) >= 0) { - markRefundResult(paymentId, "SUCCESS"); - return true; - } - - BigDecimal refundAmount = dueRefundAmount.subtract(refundedAmount).setScale(2, BigDecimal.ROUND_HALF_UP); - try { - ApplyRefundDTO dto = new ApplyRefundDTO(); - dto.setOrderCode(orderCode); - dto.setRefundType(Constants.ONE); - dto.setRefundAmount(refundAmount); - dto.setWechatAppId(wechatAppId); - dto.setMemberId(orderBasicInfo.getMemberId()); - orderBasicInfoService.refundOrderWithAdapay(dto); - markRefundResult(paymentId, "PROCESSING"); - log.info("未分账数据先执行退款, paymentId:{}, orderCode:{}, dueRefundAmount:{}, refundedAmount:{}, refundAmount:{}", - paymentId, orderCode, dueRefundAmount, refundedAmount, refundAmount); - } catch (Exception e) { - markRefundResult(paymentId, "FAILED"); - log.error("未分账数据执行退款失败, paymentId:{}, orderCode:{}, dueRefundAmount:{}, refundedAmount:{}, refundAmount:{}", - paymentId, orderCode, dueRefundAmount, refundedAmount, refundAmount, e); - } - return false; - } - - private BigDecimal getSucceededRefundAmount(OrderBasicInfo orderBasicInfo) { - List refundInfoList = orderBasicInfoService.getOrderRefundInfoList(orderBasicInfo); - if (CollectionUtils.isEmpty(refundInfoList)) { - return BigDecimal.ZERO; - } - - BigDecimal refundedAmount = BigDecimal.ZERO; - for (OrderDetailInfoVO.OrderRefundInfo refundInfo : refundInfoList) { - if (refundInfo == null) { - continue; - } - String status = refundInfo.getStatus(); - if (StringUtils.isNotBlank(status) && !StringUtils.equals(status, AdapayStatusEnum.SUCCEEDED.getValue())) { - continue; - } - refundedAmount = refundedAmount.add(parseAmount(refundInfo.getReverseAmt())); - } - return refundedAmount.setScale(2, BigDecimal.ROUND_HALF_UP); - } - - private BigDecimal getLatestConfirmAmount(BigDecimal waitSplitAmount, String payAmount, String refundAmount, String paymentId, String wechatAppId) { - BigDecimal confirmAmt = waitSplitAmount; - try { - QueryPaymentConfirmDTO dto = new QueryPaymentConfirmDTO(); - dto.setWechatAppId(wechatAppId); - dto.setPaymentId(paymentId); - QueryPaymentConfirmDetailResponse response = adapayService.queryPaymentConfirmList(dto); - BigDecimal latestRemaining = calculateLatestRemainingAmount(payAmount, refundAmount, response); - if (latestRemaining.compareTo(BigDecimal.ZERO) > 0) { - confirmAmt = waitSplitAmount.min(latestRemaining); - } - } catch (Exception e) { - log.warn("查询汇付确认金额异常,使用数据库待分账金额继续处理, paymentId:{}, waitSplitAmount:{}", - paymentId, waitSplitAmount, e); - } - return confirmAmt; - } - - private BigDecimal calculateLatestRemainingAmount(String payAmount, String refundAmount, QueryPaymentConfirmDetailResponse response) { - BigDecimal splitLimitAmount = parseAmount(payAmount).subtract(parseAmount(refundAmount)); - if (splitLimitAmount.compareTo(BigDecimal.ZERO) <= 0 || response == null || CollectionUtils.isEmpty(response.getPaymentConfirms())) { - return splitLimitAmount.compareTo(BigDecimal.ZERO) > 0 ? splitLimitAmount : BigDecimal.ZERO; - } - - BigDecimal maxConfirmedAmt = BigDecimal.ZERO; - BigDecimal maxReservedAmt = BigDecimal.ZERO; - List confirms = response.getPaymentConfirms(); - for (PaymentConfirmInfo confirm : confirms) { - BigDecimal confirmedAmt = parseAmount(confirm.getConfirmedAmt()); - BigDecimal reservedAmt = parseAmount(confirm.getReservedAmt()); - if (confirmedAmt.compareTo(maxConfirmedAmt) > 0) { - maxConfirmedAmt = confirmedAmt; - } - if (reservedAmt.compareTo(maxReservedAmt) > 0) { - maxReservedAmt = reservedAmt; - } - } - BigDecimal latestRemaining = splitLimitAmount.subtract(maxConfirmedAmt).subtract(maxReservedAmt); - return latestRemaining.compareTo(BigDecimal.ZERO) > 0 ? latestRemaining : BigDecimal.ZERO; - } - - private void updateConfirmedSplitAmount(AdapayUnsplitRecordVO item, BigDecimal confirmAmt, String paymentId) { - BigDecimal oldConfirmedAmt = parseAmount(item.getConfirmedSplitAmount()); - BigDecimal newConfirmedAmt = oldConfirmedAmt.add(confirmAmt).setScale(2, BigDecimal.ROUND_HALF_UP); - AdapayUnsplitRecord updateRecord = new AdapayUnsplitRecord(); - updateRecord.setPaymentId(paymentId); - updateRecord.setConfirmedSplitAmount(newConfirmedAmt); - updateRecord.setUpdateTime(DateUtils.getNowDate()); - adapayUnsplitRecordService.insertOrUpdateSelective(updateRecord); - } - - private void markSplitResult(String paymentId, String splitFlag) { - AdapayUnsplitRecord updateRecord = new AdapayUnsplitRecord(); - updateRecord.setPaymentId(paymentId); - updateRecord.setSplitFlag(splitFlag); - updateRecord.setUpdateTime(DateUtils.getNowDate()); - adapayUnsplitRecordService.insertOrUpdateSelective(updateRecord); - } - - private void updateRefundAmount(String paymentId, BigDecimal refundAmount) { - AdapayUnsplitRecord updateRecord = new AdapayUnsplitRecord(); - updateRecord.setPaymentId(paymentId); - updateRecord.setRefundAmount(refundAmount.setScale(2, BigDecimal.ROUND_HALF_UP)); - updateRecord.setUpdateTime(DateUtils.getNowDate()); - adapayUnsplitRecordService.insertOrUpdateSelective(updateRecord); - } - - private void markRefundResult(String paymentId, String refundFlag) { - AdapayUnsplitRecord updateRecord = new AdapayUnsplitRecord(); - updateRecord.setPaymentId(paymentId); - updateRecord.setRefundFlag(refundFlag); - updateRecord.setUpdateTime(DateUtils.getNowDate()); - adapayUnsplitRecordService.insertOrUpdateSelective(updateRecord); - } - - private AdapayUnsplitRecord convertRowToRecord(Row row, Map headerIndexMap, DataFormatter formatter) { - String paymentId = getCellString(row, headerIndexMap.get(normalizeHeader("交易流水号")), formatter); - if (StringUtils.isBlank(paymentId)) { - return null; - } - - String orderNo = getCellString(row, headerIndexMap.get(normalizeHeader("交易订单号")), formatter); - Date payTime = parsePayTime(getCell(row, headerIndexMap.get(normalizeHeader("支付时间"))), formatter); - - AdapayUnsplitRecord record = new AdapayUnsplitRecord(); - record.setMerchantCode(getCellString(row, headerIndexMap.get(normalizeHeader("商户号")), formatter)); - record.setPayTime(payTime); - record.setPaymentId(paymentId); - record.setOrderNo(orderNo); - record.setOrderCode(extractOrderCode(orderNo)); - record.setPayAmount(getCellDecimal(row, headerIndexMap.get(normalizeHeader("交易订单金额")), formatter)); - record.setConfirmedSplitAmount(getCellDecimal(row, headerIndexMap.get(normalizeHeader("已确认分账金额")), formatter)); - record.setRefundAmount(getCellDecimal(row, headerIndexMap.get(normalizeHeader("已撤销金额")), formatter)); - record.setPaymentRevokeAmount(getCellDecimal(row, headerIndexMap.get(normalizeHeader("支付确认撤销金额")), formatter)); - record.setRemainingSplitAmount(getCellDecimal(row, headerIndexMap.get(normalizeHeader("剩余未分账金额")), formatter)); - record.setUpdateTime(DateUtils.getNowDate()); - return record; - } - - private Map buildHeaderIndexMap(Row headerRow, DataFormatter formatter) { - Map headerIndexMap = new HashMap<>(); - short firstCellNum = headerRow.getFirstCellNum(); - short lastCellNum = headerRow.getLastCellNum(); - if (firstCellNum < 0 || lastCellNum < 0) { - return headerIndexMap; - } - for (int cellIndex = firstCellNum; cellIndex < lastCellNum; cellIndex++) { - Cell cell = headerRow.getCell(cellIndex, Row.MissingCellPolicy.RETURN_BLANK_AS_NULL); - if (cell == null) { - continue; - } - String header = normalizeHeader(formatter.formatCellValue(cell)); - if (StringUtils.isNotBlank(header)) { - headerIndexMap.put(header, cellIndex); - } - } - return headerIndexMap; - } - - private String getCellString(Row row, Integer columnIndex, DataFormatter formatter) { - Cell cell = getCell(row, columnIndex); - if (cell == null) { - return null; - } - String value = formatter.formatCellValue(cell); - return StringUtils.isBlank(value) ? null : value.trim(); - } - - private Cell getCell(Row row, Integer columnIndex) { - if (row == null || columnIndex == null) { - return null; - } - return row.getCell(columnIndex, Row.MissingCellPolicy.RETURN_BLANK_AS_NULL); - } - - private BigDecimal getCellDecimal(Row row, Integer columnIndex, DataFormatter formatter) { - String value = getCellString(row, columnIndex, formatter); - return parseAmount(value); - } - - private Date parsePayTime(Cell cell, DataFormatter formatter) { - if (cell == null) { - return null; - } - if (cell.getCellType() == CellType.NUMERIC) { - return DateUtil.getJavaDate(cell.getNumericCellValue()); - } - if (cell.getCellType() == CellType.FORMULA && cell.getCachedFormulaResultType() == CellType.NUMERIC) { - return DateUtil.getJavaDate(cell.getNumericCellValue()); - } - - String value = formatter.formatCellValue(cell); - if (StringUtils.isBlank(value)) { - return null; - } - Date date = DateUtils.parseDate(value.trim()); - if (date != null) { - return date; - } - try { - return DateUtil.getJavaDate(Double.parseDouble(value.trim())); - } catch (Exception e) { - log.warn("解析支付时间失败,value:{}", value); - return null; - } - } - - private String extractOrderCode(String orderNo) { - if (StringUtils.isBlank(orderNo)) { - return null; - } - int index = orderNo.indexOf("_"); - String orderCode = index > 0 ? orderNo.substring(0, index) : orderNo; - // order_code 字段长度限制为 16,超长则无法匹配订单,返回 null - if (orderCode.length() >= 16) { - log.warn("order_code 字段长度超出限制,order_no:{}", orderNo); - } - return orderCode.length() <= 16 ? orderCode : null; - } - - private String normalizeHeader(String header) { - return header == null ? "" : header.replace(" ", "").trim(); - } - - private boolean isSameAmount(BigDecimal left, BigDecimal right) { - if (left == null && right == null) { - return true; - } - if (left == null || right == null) { - return false; - } - return left.compareTo(right) == 0; - } - - private BigDecimal parseAmount(String value) { - if (StringUtils.isBlank(value)) { - return BigDecimal.ZERO; - } - String normalizedValue = value.replace(",", "").trim(); - try { - return new BigDecimal(normalizedValue); - } catch (NumberFormatException e) { - log.warn("解析数字失败,value:{}", value); - return BigDecimal.ZERO; - } - } - - private boolean isRowEmpty(Row row) { - if (row == null) { - return true; - } - short firstCellNum = row.getFirstCellNum(); - short lastCellNum = row.getLastCellNum(); - if (firstCellNum < 0 || lastCellNum < 0) { - return true; - } - for (int i = firstCellNum; i < lastCellNum; i++) { - Cell cell = row.getCell(i, Row.MissingCellPolicy.RETURN_BLANK_AS_NULL); - if (cell == null) { - continue; - } - if (cell.getCellType() != CellType.BLANK) { - return false; - } - } - return true; - } - - private static class ImportSummary { - private int totalRows; - private int successRows; - private int skippedRows; - private int failedRows; - private Date minPayTime; - private Date maxPayTime; - - private void updatePayTimeRange(Date payTime) { - if (payTime == null) { - return; - } - if (minPayTime == null || payTime.before(minPayTime)) { - minPayTime = payTime; - } - if (maxPayTime == null || payTime.after(maxPayTime)) { - maxPayTime = payTime; - } - } - - @Override - public String toString() { - return "{" - + "\"totalRows\":" + totalRows - + ", \"successRows\":" + successRows - + ", \"skippedRows\":" + skippedRows - + ", \"failedRows\":" + failedRows - + ", \"minPayTime\":\"" + (minPayTime == null ? "" : DateUtils.formatDateTime(minPayTime)) + "\"" - + ", \"maxPayTime\":\"" + (maxPayTime == null ? "" : DateUtils.formatDateTime(maxPayTime)) + "\"" - + "}"; - } - } - - /** - * V1方法,获取退款金额与结算金额 - * @param batchNum - */ - private void processUnSettledOrderV1(int batchNum) { - String startTime = "2025-01-01 00:00:00"; - String endTime = "2025-12-31 23:59:59"; - - // 查询未分帐订单 - PageUtils.startPage(1, 1000); - List list = adapayUnsplitRecordService.queryUnsplitOrders(startTime, endTime); - log.info("第{}批次,共查询到{}条数据", batchNum, list.size()); - if (CollectionUtils.isEmpty(list)) { - return; - } - // 转为map, key:orderCode, value:AdapayUnsplitRecord - Map map = list.stream().collect(Collectors.toMap(AdapayUnsplitRecord::getOrderCode, v -> v, (k1, k2) -> k1)); - - // 取keySet - Set orderCodes = map.keySet(); - - // 查询订单的退款金额与结算金额 - List orderList = orderBasicInfoService.selectOrderTemp(orderCodes); - // 转为map, key:orderCode, value:OrderBasicInfo - Map orderMap = orderList.stream().collect(Collectors.toMap(OrderBasicInfo::getOrderCode, v -> v, (k1, k2) -> k1)); - - List updateList = new ArrayList<>(); - //更新map - for (String orderCode : orderCodes) { - OrderBasicInfo orderBasicInfo = orderMap.get(orderCode); - if (Objects.isNull(orderBasicInfo)) { - // log.error("未查询到订单:{}", orderCode); - continue; - } - AdapayUnsplitRecord adapayUnsplitRecord = map.get(orderCode); - adapayUnsplitRecord.setDueRefundAmount(orderBasicInfo.getRefundAmount()); - adapayUnsplitRecord.setSettleAmount(orderBasicInfo.getSettleAmount()); - String pileSn = orderBasicInfo.getPileSn(); - adapayUnsplitRecord.setPileType(YouDianUtils.isEBikePileSn(pileSn) ? "eBike" : "EV"); - updateList.add(adapayUnsplitRecord); - } - adapayUnsplitRecordService.updateBatchSelective(updateList); - log.info("第{}批次,共更新{}条数据", batchNum, updateList.size()); - } - - /** - * 更新adapay_unsplit_record表, 去汇付查询最新的数据 - * @param batchNum - */ - private void processUnSettledOrderV2(int batchNum) { - String startTime = "2025-01-01 00:00:00"; - String endTime = "2025-12-31 23:59:59"; - - // 查询未分帐订单 - PageUtils.startPage(1, 3); - List list = adapayUnsplitRecordService.queryUnsplitOrders(startTime, endTime); - - // 根据paymentId去汇付查询最新数据 - for (AdapayUnsplitRecord adapayUnsplitRecord : list) { - String paymentId = adapayUnsplitRecord.getPaymentId(); - - QueryPaymentConfirmDTO dto = new QueryPaymentConfirmDTO(); - dto.setWechatAppId(Constants.DEFAULT_APP_ID); - dto.setPaymentId(paymentId); - QueryPaymentConfirmDetailResponse response = adapayService.queryPaymentConfirmList(dto); - System.out.println(JSON.toJSONString(response)); - } - } - public void updateOrderReview() { LocalDate yesterday = DateUtils.getYesterday(); LocalDateTime start = yesterday.atStartOfDay(); @@ -1185,82 +549,4 @@ public class JsowellTask { orderBasicInfoService.updateOrderReviewFlagTemp(start, end, null, null); } - - // private void processUnSettledOrderOld() { - // String startTime = "2023-01-01 00:00:00"; - // String endTime = "2024-12-31 23:59:59"; - // - // // 使用redis控制请求api - // Boolean setnx = redisCache.setnx(CacheConstants.PROCESS_UNSPLIT_ORDERS, Constants.ONE, 65); - // if (!setnx) { - // return; - // } - // - // // 查询未分帐订单 - // PageUtils.startPage(1, 10); - // List list = orderUnsplitRecordService.queryUnsplitOrders(startTime, endTime); - // - // log.info("处理未分帐订单start, 当前时间:{}, 查询出[{}]条未分账订单, 下面进行处理", DateUtils.getDateTime(), list.size()); - // int count = 0; - // for (OrderUnsplitRecord orderUnsplitRecord : list) { - // String paymentId = orderUnsplitRecord.getPaymentId(); - // String orderCode = orderUnsplitRecord.getOrderCode(); - // BigDecimal confirmAmt = orderUnsplitRecord.getSettleAmount(); - // - // DivMember divMember = new DivMember(); - // divMember.setMemberId(Constants.ZERO); // 若是商户本身时,传入0 - // divMember.setAmount(AdapayUtil.formatAmount(confirmAmt)); - // divMember.setFeeFlag(Constants.Y); - // - // PaymentConfirmParam param = PaymentConfirmParam.builder() - // .paymentId(paymentId) - // .divMemberList(Lists.newArrayList(divMember)) - // .confirmAmt(confirmAmt) - // .orderCode(orderCode) - // .wechatAppId(Constants.DEFAULT_APP_ID) // 默认使用万车充的appId - // .build(); - // // 延时分账,使用确认交易API - // PaymentConfirmResponse paymentConfirmResponse = adapayService.createPaymentConfirmRequest(param); - // - // // 如果确认交易成功,则更新订单状态为已分账 - // if (paymentConfirmResponse.isSuccess()) { - // count++; - // orderUnsplitRecord.setStatus(AdapayStatusEnum.SUCCEEDED.getValue()); - // orderUnsplitRecordService.updateOrderUnsplitRecord(orderUnsplitRecord); - // log.info("processUnsplitOrders, 分账成功, paymentId:{}", paymentId); - // } else { - // // error_type:api_error, error_code:confirm_amt_over_limit, error_msg当前确认金额 > 支付金额 - 已支付确认金额 - 已支付撤销金额 - // if (paymentConfirmResponse.getError_code().equals("confirm_amt_over_limit")) { - // // 查询paymentId的总分账金额 - // BigDecimal totalSplitAmount; - // try { - // totalSplitAmount = adapayService.getTotalSplitAmountByPaymentId(paymentId); - // } catch (BaseAdaPayException e) { - // throw new RuntimeException(e); - // } - // if (totalSplitAmount.compareTo(confirmAmt) == 0) { - // // 如果总分账金额等于当前分账金额,则更新订单状态为已分账 - // orderUnsplitRecord.setStatus(AdapayStatusEnum.SUCCEEDED.getValue()); - // orderUnsplitRecordService.updateOrderUnsplitRecord(orderUnsplitRecord); - // log.info("processUnsplitOrders, 分账成功, paymentId:{}", paymentId); - // } else { - // log.info("processUnsplitOrders, 分账失败, paymentId:{}, 错误信息:{}", paymentId, paymentConfirmResponse.getError_msg()); - // } - // } - // - // // error_type:invalid_request_error, error_code:payment_over_time_doing, error_msg:数据正在处理中,请稍后再试 - // if (paymentConfirmResponse.getError_code().equals("payment_over_time_doing")) { - // log.info("processUnsplitOrders, 分账失败, paymentId:{}, 错误信息:{}", paymentId, paymentConfirmResponse.getError_msg()); - // break; - // } - // // error_type:invalid_request_error, error_code:refund_repeate_request, error_msg:请求过于频繁 - // if (paymentConfirmResponse.getError_code().equals("refund_repeate_request")) { - // log.info("processUnsplitOrders, 分账失败, paymentId:{}, 错误信息:{}", paymentId, paymentConfirmResponse.getError_msg()); - // break; - // } - // } - // } - // log.info("处理未分帐订单end, 当前时间:[{}], 成功分账[{}]条订单", DateUtils.getDateTime(), count); - // } - }