diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/CustomerArchiveController.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/CustomerArchiveController.java index d0998aa3..b0580c5a 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/CustomerArchiveController.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/CustomerArchiveController.java @@ -136,21 +136,25 @@ public class CustomerArchiveController extends BladeController { } /** - * 审核通过(通过后自动推送金蝶,推送失败不影响审批结果) + * 审核通过(通过后自动推送金蝶,推送失败不影响审批结果,失败原因以警告文案返回) */ @PostMapping("/approve") @ApiOperationSupport(order = 6) @Operation(summary = "审核通过", description = "传入id") public R approve(@Parameter(description = "主键", required = true) @RequestParam Long id) { boolean result = customerArchiveService.approve(id); - if (result) { - try { - customerArchiveService.syncKingdee(id); - } catch (Exception exception) { - log.error("客商审批通过后推送金蝶异常,id={}", id, exception); - } + if (!result) { + return R.status(false); + } + try { + customerArchiveService.syncKingdee(id); + return R.success("审核通过"); + } catch (Exception exception) { + log.error("客商审批通过后推送金蝶异常,id={}", id, exception); + String reason = exception.getMessage() == null ? "金蝶接口调用异常" : exception.getMessage(); + // 与结算/付款/开票审批口径一致:审批已生效,推送失败原因以 data=false 警告文案返回 + return R.data(Boolean.FALSE, "审核通过,但推送金蝶失败:" + reason); } - return R.status(result); } /** diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/ICustomerArchiveService.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/ICustomerArchiveService.java index 459e35cd..e50f1a47 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/ICustomerArchiveService.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/ICustomerArchiveService.java @@ -196,6 +196,14 @@ public interface ICustomerArchiveService extends BaseService { */ CustomerArchive syncKingdee(Long id); + /** + * 推送失败状态落库(独立事务):推送主事务已回滚,失败状态与原因单独落库供页面展示与手动重推 + * + * @param id 主键 + * @param reason 失败原因 + */ + void markKingdeeSyncFailed(Long id, String reason); + /** * 定时同步金蝶客商数据:待推送客商自动推送 + 已同步客商使用状态回写 * diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/CustomerArchiveServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/CustomerArchiveServiceImpl.java index f3545757..af8f84c2 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/CustomerArchiveServiceImpl.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/CustomerArchiveServiceImpl.java @@ -34,6 +34,7 @@ import lombok.extern.slf4j.Slf4j; import org.springblade.core.log.exception.ServiceException; import org.springblade.core.mp.base.BaseServiceImpl; import org.springblade.core.secure.utils.AuthUtil; +import org.springblade.core.tool.utils.SpringUtil; import org.springblade.transport.mk.MkProcessNodeHelper; import org.springblade.transport.support.TransportBusinessSupport; import org.springblade.core.tenant.annotation.TenantIgnore; @@ -96,6 +97,7 @@ import org.springblade.transport.pojo.vo.CustomerReceiptAccountVO; import org.springblade.transport.service.ICustomerArchiveService; import org.springblade.transport.support.KingdeeSyncLockSupport; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; @@ -528,14 +530,52 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpllambdaUpdate() + .eq(CustomerArchive::getId, id) + .eq(CustomerArchive::getApprovalStatus, APPROVAL_APPROVED) + .and(wrapper -> wrapper.isNull(CustomerArchive::getKingdeeStatus) + .or() + .notIn(CustomerArchive::getKingdeeStatus, List.of(KINGDEE_STATUS_SYNCED, KINGDEE_STATUS_EXIST))) + .set(CustomerArchive::getKingdeeStatus, KINGDEE_STATUS_FAILED) + .set(CustomerArchive::getKingdeeFailReason, failReason)); + if (updated > 0 && before != null) { + // 变更记录留档(推送主事务已回滚,此处独立事务落状态与记录) + CustomerArchive after = copyCustomer(before); + after.setKingdeeStatus(KINGDEE_STATUS_FAILED); + after.setKingdeeFailReason(failReason); + addChangeRecord(id, "推送金蝶失败:" + failReason, before, after); + } + } + /** * 组装 A902-2 报文推送金蝶并回写协同状态;detail 由调用方准备, - * 定时同步批量组装报文数据,避免逐条 detail 查询的 N+1 问题 + * 定时同步批量组装报文数据,避免逐条 detail 查询的 N+1 问题; + * 推送失败先落 failed 状态与变更记录,再抛出异常由调用方提示前端(与结算/付款/开票口径一致) */ private void pushCustomerToKingdee(Long id, CustomerArchive customer, CustomerArchive after, CustomerArchiveVO detail) { try { @@ -549,12 +589,18 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl())); - CustomerArchive after = copyCustomer(customer); - after.setKingdeeSyncTime(LocalDateTime.now()); pushCustomerToKingdee(customer.getId(), customer, after, detail); updateList.add(after); if (Objects.equals(after.getKingdeeStatus(), KINGDEE_STATUS_SYNCED)) { @@ -735,6 +781,8 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl