From 4cbd925544b8e9c7706d09a11f0b6f9bf0e1c4dc Mon Sep 17 00:00:00 2001 From: "weicw1996@qq.com" Date: Tue, 8 Sep 2026 20:54:01 +0800 Subject: [PATCH] =?UTF-8?q?feat(hjc):=20=E9=98=B6=E6=AE=B52=20=E8=AE=A2?= =?UTF-8?q?=E5=8D=95=E6=94=AF=E4=BB=98=E9=97=AD=E7=8E=AF=20-=20=E4=B8=8B?= =?UTF-8?q?=E5=8D=95=E5=90=8E=E5=8F=91=E8=B5=B7=E5=BE=AE=E4=BF=A1Native?= =?UTF-8?q?=E6=94=AF=E4=BB=98=E5=B9=B6=E5=9B=9E=E6=8E=A8=E4=B8=80=E7=AB=99?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - HjcOrderController: POST /api/hjc/order/pay(复用 payment.createPayment 取codeUrl)、PUT /api/hjc/order/mark-paid(幂等置已付+触发一站式推送) - HjcBizService.markPaid: 置 payStatus=1/orderStatus=1/payTime,支付成功即 pushOrderToOneStop - 出向推送在 base-url 未配置时不发起HTTP,仅记日志待重试 --- .../hjc/controller/HjcOrderController.java | 76 +++++++++++++++++++ .../gxwebsoft/hjc/service/HjcBizService.java | 5 ++ .../hjc/service/impl/HjcBizServiceImpl.java | 29 +++++++ 3 files changed, 110 insertions(+) diff --git a/src/main/java/com/gxwebsoft/hjc/controller/HjcOrderController.java b/src/main/java/com/gxwebsoft/hjc/controller/HjcOrderController.java index 49e3ca2..9eebd79 100644 --- a/src/main/java/com/gxwebsoft/hjc/controller/HjcOrderController.java +++ b/src/main/java/com/gxwebsoft/hjc/controller/HjcOrderController.java @@ -11,8 +11,13 @@ import com.gxwebsoft.hjc.entity.HjcEnterprise; import com.gxwebsoft.hjc.entity.HjcOrder; import com.gxwebsoft.hjc.param.HjcOrderParam; import com.gxwebsoft.hjc.service.HjcBidProjectService; +import com.gxwebsoft.hjc.service.HjcBizService; import com.gxwebsoft.hjc.service.HjcEnterpriseService; import com.gxwebsoft.hjc.service.HjcOrderService; +import com.gxwebsoft.payment.dto.PaymentRequest; +import com.gxwebsoft.payment.dto.PaymentResponse; +import com.gxwebsoft.payment.enums.PaymentType; +import com.gxwebsoft.payment.service.PaymentService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.web.bind.annotation.*; @@ -22,6 +27,7 @@ import java.math.BigDecimal; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.List; +import java.util.Map; /** * 汇吉采标书订单(下单 + 我的订单 + 后台订单) @@ -39,6 +45,10 @@ public class HjcOrderController extends BaseController { private HjcBidProjectService hjcBidProjectService; @Resource private HjcEnterpriseService hjcEnterpriseService; + @Resource + private PaymentService paymentService; + @Resource + private HjcBizService hjcBizService; @Operation(summary = "下单(创建待支付订单)") @PostMapping("/create") @@ -99,6 +109,65 @@ public class HjcOrderController extends BaseController { return success("下单成功", order); } + @Operation(summary = "发起支付(微信Native扫码,返回codeUrl)") + @PostMapping("/pay") + public ApiResult pay(@RequestBody Map body) { + Integer userId = getLoginUserId(); + if (userId == null) { + return fail("用户未登录"); + } + String orderNo = body.get("orderNo") == null ? null : String.valueOf(body.get("orderNo")); + if (orderNo == null) { + return fail("订单号不能为空"); + } + HjcOrder order = hjcOrderService.getByOrderNo(orderNo); + if (order == null) { + return fail("订单不存在"); + } + if (order.getPayStatus() != null && order.getPayStatus() == 1) { + return fail("订单已支付"); + } + HjcEnterprise enterprise = hjcEnterpriseService.getByUserId(userId); + if (enterprise == null || !enterprise.getId().equals(order.getEnterpriseId())) { + return fail("无权操作该订单"); + } + PaymentRequest request = new PaymentRequest(); + request.setTenantId(order.getTenantId()); + request.setUserId(userId); + request.setPaymentType(PaymentType.WECHAT_NATIVE); + request.setAmount(order.getTotalAmount()); + request.setSubject(truncate(order.getProjectName(), 127)); + request.setOrderNo(order.getOrderNo()); + try { + PaymentResponse resp = paymentService.createPayment(request); + return success("发起支付成功", resp); + } catch (com.gxwebsoft.payment.exception.PaymentException e) { + return fail("发起支付失败:" + e.getMessage()); + } + } + + @Operation(summary = "标记订单已支付(支付成功后调用,幂等),并触发一站式推送") + @PutMapping("/mark-paid") + public ApiResult markPaid(@RequestBody Map body) { + Integer userId = getLoginUserId(); + if (userId == null) { + return fail("用户未登录"); + } + String orderNo = body.get("orderNo") == null ? null : String.valueOf(body.get("orderNo")); + if (orderNo == null) { + return fail("订单号不能为空"); + } + HjcOrder order = hjcOrderService.getByOrderNo(orderNo); + if (order == null) { + return fail("订单不存在"); + } + HjcEnterprise enterprise = hjcEnterpriseService.getByUserId(userId); + if (enterprise == null || !enterprise.getId().equals(order.getEnterpriseId())) { + return fail("无权操作该订单"); + } + return success("已支付", hjcBizService.markPaid(orderNo)); + } + @Operation(summary = "我的订单") @GetMapping("/my") public ApiResult my() { @@ -136,4 +205,11 @@ public class HjcOrderController extends BaseController { private String firstNotBlank(String a, String b) { return a != null && !a.trim().isEmpty() ? a : b; } + + private String truncate(String s, int max) { + if (s == null) { + return ""; + } + return s.length() > max ? s.substring(0, max) : s; + } } diff --git a/src/main/java/com/gxwebsoft/hjc/service/HjcBizService.java b/src/main/java/com/gxwebsoft/hjc/service/HjcBizService.java index 8636d25..cf5d1d9 100644 --- a/src/main/java/com/gxwebsoft/hjc/service/HjcBizService.java +++ b/src/main/java/com/gxwebsoft/hjc/service/HjcBizService.java @@ -16,6 +16,11 @@ public interface HjcBizService { */ void pushOrderToOneStop(HjcOrder order); + /** + * 支付成功后标记订单已支付(幂等),并触发一站式推送 + */ + HjcOrder markPaid(String orderNo); + /** * 重试失败的推送(幂等) */ diff --git a/src/main/java/com/gxwebsoft/hjc/service/impl/HjcBizServiceImpl.java b/src/main/java/com/gxwebsoft/hjc/service/impl/HjcBizServiceImpl.java index 7fd3790..42437b3 100644 --- a/src/main/java/com/gxwebsoft/hjc/service/impl/HjcBizServiceImpl.java +++ b/src/main/java/com/gxwebsoft/hjc/service/impl/HjcBizServiceImpl.java @@ -109,6 +109,7 @@ public class HjcBizServiceImpl implements HjcBizService { } @Override + @Transactional(rollbackFor = Exception.class) public void retryPendingPush() { List pending = hjcOrderPushLogService.list(new LambdaQueryWrapper() .in(HjcOrderPushLog::getPushStatus, 0, 2) @@ -123,10 +124,38 @@ public class HjcBizServiceImpl implements HjcBizService { } } + @Override + @Transactional(rollbackFor = Exception.class) + public HjcOrder markPaid(String orderNo) { + HjcOrder order = hjcOrderService.getByOrderNo(orderNo); + if (order == null) { + throw new RuntimeException("订单不存在"); + } + if (order.getPayStatus() != null && order.getPayStatus() == 1) { + return order; + } + order.setPayStatus(1); + order.setOrderStatus(1); + order.setPayTime(LocalDateTime.now()); + hjcOrderService.updateById(order); + // 支付成功后触发一站式推送 + pushOrderToOneStop(order); + return order; + } + private void doPush(HjcOrder order, HjcOrderPushLog logEntity) { try { CreatePurchaseDetails body = buildCreatePurchaseDetails(order); String payload = objectMapper.writeValueAsString(body); + logEntity.setPayload(payload); + if (StrUtil.isBlank(oneStopBaseUrl)) { + logEntity.setAttemptCount(logEntity.getAttemptCount() + 1); + logEntity.setPushStatus(2); + logEntity.setErrorMsg("一站式base-url未配置"); + logEntity.setNextRetryTime(LocalDateTime.now().plusMinutes(30)); + hjcOrderPushLogService.updateById(logEntity); + return; + } String ts = HjcOneStopAuthUtil.timestamp(); String sign = HjcOneStopAuthUtil.sign(ts);