From 8064c68b8b4b3f5fbb00f003ffaae170f2bf4111 Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Fri, 24 Oct 2025 20:10:44 +0800 Subject: [PATCH] =?UTF-8?q?feat(profit-share):=20=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E5=88=86=E8=B4=A6=E4=B8=8E=E9=80=80=E6=AC=BE=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E7=BB=93=E6=9E=84=E5=B9=B6=E4=BC=98=E5=8C=96=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修改手动分账接口路径为 /manual 并支持请求体参数 - 更新计算分账结果接口路径为 /calculate - 将退款消息主题从 zt-refund 更改为 zt-profitshare-refund -重构退款消息对象字段,增加退款类型和原订单 ID - 更新退款消息生产者逻辑以适配新字段和主题配置 - 强化退款消息校验规则,确保必要字段完整性 --- .../pc/ProfitShareV2Controller.java | 13 +++---- .../config/KafkaIntegrationProperties.java | 2 +- .../dto/message/RefundMessage.java | 36 +++++++++---------- .../service/ProfitShareKafkaProducer.java | 28 +++++++-------- 4 files changed, 40 insertions(+), 39 deletions(-) diff --git a/src/main/java/com/ycwl/basic/controller/pc/ProfitShareV2Controller.java b/src/main/java/com/ycwl/basic/controller/pc/ProfitShareV2Controller.java index ce0274e4..d7a7b49f 100644 --- a/src/main/java/com/ycwl/basic/controller/pc/ProfitShareV2Controller.java +++ b/src/main/java/com/ycwl/basic/controller/pc/ProfitShareV2Controller.java @@ -2,6 +2,7 @@ package com.ycwl.basic.controller.pc; import com.ycwl.basic.integration.profitshare.dto.CalculateResultVO; import com.ycwl.basic.integration.profitshare.dto.CalculateShareRequest; +import com.ycwl.basic.integration.profitshare.dto.ManualShareRequest; import com.ycwl.basic.integration.profitshare.dto.TypesVO; import com.ycwl.basic.integration.profitshare.dto.record.RecordDetailVO; import com.ycwl.basic.integration.profitshare.dto.record.RecordVO; @@ -210,14 +211,14 @@ public class ProfitShareV2Controller { /** * 手动触发分账 */ - @PostMapping("/share/manual/{orderId}") - public ApiResponse manualShare(@PathVariable String orderId) { - log.info("手动触发分账, orderId: {}", orderId); + @PostMapping("/manual") + public ApiResponse manualShare(@Valid @RequestBody ManualShareRequest request) { + log.info("手动触发分账, orderId: {}", request.getOrderId()); try { - profitShareIntegrationService.manualShare(orderId); + profitShareIntegrationService.manualShare(request.getOrderId()); return ApiResponse.success("手动分账触发成功"); } catch (Exception e) { - log.error("手动触发分账失败, orderId: {}", orderId, e); + log.error("手动触发分账失败, orderId: {}", request.getOrderId(), e); return ApiResponse.fail("手动触发分账失败: " + e.getMessage()); } } @@ -225,7 +226,7 @@ public class ProfitShareV2Controller { /** * 计算分账结果(不执行) */ - @PostMapping("/share/calculate") + @PostMapping("/calculate") public ApiResponse calculateShare(@Valid @RequestBody CalculateShareRequest request) { log.info("计算分账结果, scenicId: {}, totalAmount: {}", request.getScenicId(), request.getTotalAmount()); try { diff --git a/src/main/java/com/ycwl/basic/integration/kafka/config/KafkaIntegrationProperties.java b/src/main/java/com/ycwl/basic/integration/kafka/config/KafkaIntegrationProperties.java index 8a6920b7..c180521e 100644 --- a/src/main/java/com/ycwl/basic/integration/kafka/config/KafkaIntegrationProperties.java +++ b/src/main/java/com/ycwl/basic/integration/kafka/config/KafkaIntegrationProperties.java @@ -13,7 +13,7 @@ public class KafkaIntegrationProperties { private String bootstrapServers = "100.64.0.12:39092"; private String ztMessageTopic = "zt-message"; // topic for zt-message microservice private String profitShareTopic = "zt-profitshare"; // topic for profit share messages - private String refundTopic = "zt-refund"; // topic for refund messages + private String refundTopic = "zt-profitshare-refund"; // topic for refund messages private Consumer consumer = new Consumer(); private Producer producer = new Producer(); diff --git a/src/main/java/com/ycwl/basic/integration/profitshare/dto/message/RefundMessage.java b/src/main/java/com/ycwl/basic/integration/profitshare/dto/message/RefundMessage.java index a9b15277..e1862fd6 100644 --- a/src/main/java/com/ycwl/basic/integration/profitshare/dto/message/RefundMessage.java +++ b/src/main/java/com/ycwl/basic/integration/profitshare/dto/message/RefundMessage.java @@ -8,7 +8,7 @@ import lombok.Data; import lombok.NoArgsConstructor; /** - * 退款消息(发送到 zt-refund topic) + * 退款消息(发送到 zt-profitshare-refund topic) * * @author Claude Code * @date 2025-01-11 @@ -21,16 +21,16 @@ import lombok.NoArgsConstructor; public class RefundMessage { /** - * 订单ID + * 退款订单ID */ - @JsonProperty("order_id") - private String orderId; + @JsonProperty("refund_order_id") + private String refundOrderId; /** - * 景区ID + * 原订单ID */ - @JsonProperty("scenic_id") - private Long scenicId; + @JsonProperty("original_order_id") + private String originalOrderId; /** * 退款金额(单位:元) @@ -38,18 +38,18 @@ public class RefundMessage { @JsonProperty("refund_amount") private Double refundAmount; + /** + * 退款类型(full: 全额退款, partial: 部分退款) + */ + @JsonProperty("refund_type") + private String refundType; + /** * 支付系统(alipay, wechat, union) */ @JsonProperty("payment_system") private String paymentSystem; - /** - * 退款订单ID - */ - @JsonProperty("refund_order_id") - private String refundOrderId; - /** * Unix 时间戳(秒) */ @@ -59,13 +59,13 @@ public class RefundMessage { /** * 快速创建退款消息 */ - public static RefundMessage of(String orderId, Long scenicId, Double refundAmount, String paymentSystem, String refundOrderId) { + public static RefundMessage of(String refundOrderId, String originalOrderId, Double refundAmount, String refundType, String paymentSystem) { return RefundMessage.builder() - .orderId(orderId) - .scenicId(scenicId) - .refundAmount(refundAmount) - .paymentSystem(paymentSystem) .refundOrderId(refundOrderId) + .originalOrderId(originalOrderId) + .refundAmount(refundAmount) + .refundType(refundType) + .paymentSystem(paymentSystem) .timestamp(System.currentTimeMillis() / 1000) .build(); } diff --git a/src/main/java/com/ycwl/basic/integration/profitshare/service/ProfitShareKafkaProducer.java b/src/main/java/com/ycwl/basic/integration/profitshare/service/ProfitShareKafkaProducer.java index eeb13922..c1a509e0 100644 --- a/src/main/java/com/ycwl/basic/integration/profitshare/service/ProfitShareKafkaProducer.java +++ b/src/main/java/com/ycwl/basic/integration/profitshare/service/ProfitShareKafkaProducer.java @@ -25,7 +25,7 @@ import org.springframework.stereotype.Service; public class ProfitShareKafkaProducer { public static final String DEFAULT_PROFITSHARE_TOPIC = "zt-profitshare"; - public static final String DEFAULT_REFUND_TOPIC = "zt-refund"; + public static final String DEFAULT_REFUND_TOPIC = "zt-profitshare-refund"; private final KafkaTemplate kafkaTemplate; private final ObjectMapper objectMapper; @@ -63,18 +63,18 @@ public class ProfitShareKafkaProducer { String topic = kafkaProps != null && StringUtils.isNotBlank(kafkaProps.getRefundTopic()) ? kafkaProps.getRefundTopic() : DEFAULT_REFUND_TOPIC; - String key = message.getOrderId(); + String key = message.getOriginalOrderId(); String payload = toJson(message); - log.info("[REFUND] producing to topic={}, key={}, orderId={}, scenicId={}, amount={}", - topic, key, message.getOrderId(), message.getScenicId(), message.getRefundAmount()); + log.info("[REFUND] producing to topic={}, key={}, refundOrderId={}, originalOrderId={}, amount={}, type={}", + topic, key, message.getRefundOrderId(), message.getOriginalOrderId(), message.getRefundAmount(), message.getRefundType()); kafkaTemplate.send(topic, key, payload).whenComplete((metadata, ex) -> { if (ex != null) { - log.error("[REFUND] produce failed: orderId={}, error={}", message.getOrderId(), ex.getMessage(), ex); + log.error("[REFUND] produce failed: refundOrderId={}, error={}", message.getRefundOrderId(), ex.getMessage(), ex); } else if (metadata != null) { - log.info("[REFUND] produced: orderId={}, partition={}, offset={}", - message.getOrderId(), metadata.getRecordMetadata().partition(), metadata.getRecordMetadata().offset()); + log.info("[REFUND] produced: refundOrderId={}, partition={}, offset={}", + message.getRefundOrderId(), metadata.getRecordMetadata().partition(), metadata.getRecordMetadata().offset()); } }); } @@ -104,21 +104,21 @@ public class ProfitShareKafkaProducer { if (msg == null) { throw new IllegalArgumentException("RefundMessage is null"); } - if (StringUtils.isBlank(msg.getOrderId())) { - throw new IllegalArgumentException("orderId is required"); + if (StringUtils.isBlank(msg.getRefundOrderId())) { + throw new IllegalArgumentException("refundOrderId is required"); } - if (msg.getScenicId() == null || msg.getScenicId() <= 0) { - throw new IllegalArgumentException("scenicId is required and must be positive"); + if (StringUtils.isBlank(msg.getOriginalOrderId())) { + throw new IllegalArgumentException("originalOrderId is required"); } if (msg.getRefundAmount() == null || msg.getRefundAmount() <= 0) { throw new IllegalArgumentException("refundAmount is required and must be positive"); } + if (StringUtils.isBlank(msg.getRefundType())) { + throw new IllegalArgumentException("refundType is required"); + } if (StringUtils.isBlank(msg.getPaymentSystem())) { throw new IllegalArgumentException("paymentSystem is required"); } - if (StringUtils.isBlank(msg.getRefundOrderId())) { - throw new IllegalArgumentException("refundOrderId is required"); - } } private String toJson(Object obj) {