You've already forked FrameTour-BE
feat(profit-share): 实现分账管理V2版本功能
- 新增分账规则的创建、查询、更新、启用、禁用和删除接口 - 新增分账记录的查询接口,支持按景区、订单ID等多种方式查询 - 新增手动触发分账和计算分账结果的功能接口 - 新增获取支持类型的接口,方便前端展示和选择- 集成分账服务Feign客户端,实现与zt-profitshare微服务通信 - 添加Kafka消息配置,支持分账和退款消息的发送 - 完善DTO结构定义,包括规则、记录、明细及消息相关实体类 - 实现集成服务层,封装对分账服务的操作并提供fallback机制 - 控制器层增加参数校验和异常处理逻辑,提高系统健壮性- 所有接口均遵循RESTful设计规范,并提供详细的日志记录
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
package com.ycwl.basic.integration.profitshare.client;
|
||||
|
||||
import com.ycwl.basic.integration.common.response.CommonResponse;
|
||||
import com.ycwl.basic.integration.common.response.PageResponse;
|
||||
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;
|
||||
import com.ycwl.basic.integration.profitshare.dto.rule.CreateRuleRequest;
|
||||
import com.ycwl.basic.integration.profitshare.dto.rule.RuleVO;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* 分账服务Feign客户端
|
||||
*
|
||||
* @author Claude Code
|
||||
* @date 2025-01-11
|
||||
*/
|
||||
@FeignClient(name = "zt-profitshare", contextId = "profit-share-v2", path = "/api/profit-share/v2")
|
||||
public interface ProfitShareClient {
|
||||
|
||||
/**
|
||||
* 创建分账规则
|
||||
*/
|
||||
@PostMapping("/rules")
|
||||
CommonResponse<RuleVO> createRule(@RequestBody CreateRuleRequest request);
|
||||
|
||||
/**
|
||||
* 查询分账规则列表
|
||||
*/
|
||||
@GetMapping("/rules")
|
||||
CommonResponse<PageResponse<RuleVO>> listRules(@RequestParam(value = "scenic_id", required = false) Long scenicId,
|
||||
@RequestParam(value = "status", required = false) String status,
|
||||
@RequestParam(value = "rule_type", required = false) String ruleType,
|
||||
@RequestParam(value = "page", defaultValue = "1") Integer page,
|
||||
@RequestParam(value = "page_size", defaultValue = "10") Integer pageSize);
|
||||
|
||||
/**
|
||||
* 获取分账规则详情
|
||||
*/
|
||||
@GetMapping("/rules/{id}")
|
||||
CommonResponse<RuleVO> getRule(@PathVariable("id") Long ruleId);
|
||||
|
||||
/**
|
||||
* 更新分账规则
|
||||
*/
|
||||
@PutMapping("/rules/{id}")
|
||||
CommonResponse<RuleVO> updateRule(@PathVariable("id") Long ruleId,
|
||||
@RequestBody CreateRuleRequest request);
|
||||
|
||||
/**
|
||||
* 删除分账规则
|
||||
*/
|
||||
@DeleteMapping("/rules/{id}")
|
||||
CommonResponse<Void> deleteRule(@PathVariable("id") Long ruleId);
|
||||
|
||||
/**
|
||||
* 启用规则
|
||||
*/
|
||||
@PutMapping("/rules/{id}/enable")
|
||||
CommonResponse<Void> enableRule(@PathVariable("id") Long ruleId);
|
||||
|
||||
/**
|
||||
* 禁用规则
|
||||
*/
|
||||
@PutMapping("/rules/{id}/disable")
|
||||
CommonResponse<Void> disableRule(@PathVariable("id") Long ruleId);
|
||||
|
||||
/**
|
||||
* 查询景区分账记录
|
||||
*/
|
||||
@GetMapping("/records/scenic/{scenic_id}")
|
||||
CommonResponse<PageResponse<RecordVO>> getRecordsByScenic(@PathVariable("scenic_id") Long scenicId,
|
||||
@RequestParam(value = "page", defaultValue = "1") Integer page,
|
||||
@RequestParam(value = "page_size", defaultValue = "10") Integer pageSize);
|
||||
|
||||
/**
|
||||
* 查询分账记录详情
|
||||
*/
|
||||
@GetMapping("/records/{id}")
|
||||
CommonResponse<RecordDetailVO> getRecordById(@PathVariable("id") Long recordId);
|
||||
|
||||
/**
|
||||
* 按订单ID查询分账记录
|
||||
*/
|
||||
@GetMapping("/records/order/{order_id}")
|
||||
CommonResponse<RecordDetailVO> getRecordByOrderId(@PathVariable("order_id") String orderId);
|
||||
|
||||
/**
|
||||
* 手动触发分账
|
||||
*/
|
||||
@PostMapping("/manual")
|
||||
CommonResponse<Void> manualShare(@RequestBody ManualShareRequest request);
|
||||
|
||||
/**
|
||||
* 计算分账金额(不执行)
|
||||
*/
|
||||
@PostMapping("/calculate")
|
||||
CommonResponse<CalculateResultVO> calculateShare(@RequestBody CalculateShareRequest request);
|
||||
|
||||
/**
|
||||
* 获取支持的类型
|
||||
*/
|
||||
@GetMapping("/types")
|
||||
CommonResponse<TypesVO> getSupportedTypes();
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.ycwl.basic.integration.profitshare.config;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 分账服务集成配置
|
||||
*
|
||||
* @author Claude Code
|
||||
* @date 2025-01-11
|
||||
*/
|
||||
@Slf4j
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "integration.profitshare")
|
||||
public class ProfitShareIntegrationConfig {
|
||||
|
||||
public ProfitShareIntegrationConfig() {
|
||||
log.info("ZT-ProfitShare集成配置初始化完成");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.ycwl.basic.integration.profitshare.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 计算分账结果VO
|
||||
*
|
||||
* @author Claude Code
|
||||
* @date 2025-01-11
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class CalculateResultVO {
|
||||
|
||||
/**
|
||||
* 总金额
|
||||
*/
|
||||
@JsonProperty("total_amount")
|
||||
private Double totalAmount;
|
||||
|
||||
/**
|
||||
* 分账明细列表
|
||||
*/
|
||||
@JsonProperty("details")
|
||||
private List<CalculateDetailVO> details;
|
||||
|
||||
/**
|
||||
* 分账明细VO
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public static class CalculateDetailVO {
|
||||
/**
|
||||
* 接收人名称
|
||||
*/
|
||||
@JsonProperty("recipient_name")
|
||||
private String recipientName;
|
||||
|
||||
/**
|
||||
* 接收人类型
|
||||
*/
|
||||
@JsonProperty("recipient_type")
|
||||
private String recipientType;
|
||||
|
||||
/**
|
||||
* 分账金额
|
||||
*/
|
||||
@JsonProperty("share_amount")
|
||||
private Double shareAmount;
|
||||
|
||||
/**
|
||||
* 分账类型
|
||||
*/
|
||||
@JsonProperty("share_type")
|
||||
private String shareType;
|
||||
|
||||
/**
|
||||
* 分账值
|
||||
*/
|
||||
@JsonProperty("share_value")
|
||||
private Double shareValue;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.ycwl.basic.integration.profitshare.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.ycwl.basic.integration.profitshare.dto.rule.CreateRecipientRequest;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 计算分账请求
|
||||
*
|
||||
* @author Claude Code
|
||||
* @date 2025-01-11
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class CalculateShareRequest {
|
||||
|
||||
/**
|
||||
* 景区ID
|
||||
*/
|
||||
@JsonProperty("scenic_id")
|
||||
private Long scenicId;
|
||||
|
||||
/**
|
||||
* 总金额
|
||||
*/
|
||||
@JsonProperty("total_amount")
|
||||
private Double totalAmount;
|
||||
|
||||
/**
|
||||
* 规则类型
|
||||
*/
|
||||
@JsonProperty("rule_type")
|
||||
private String ruleType;
|
||||
|
||||
/**
|
||||
* 分账接收人列表
|
||||
*/
|
||||
@JsonProperty("recipients")
|
||||
private List<CreateRecipientRequest> recipients;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.ycwl.basic.integration.profitshare.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 手动分账请求
|
||||
*
|
||||
* @author Claude Code
|
||||
* @date 2025-01-11
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class ManualShareRequest {
|
||||
|
||||
/**
|
||||
* 订单ID
|
||||
*/
|
||||
@JsonProperty("order_id")
|
||||
private String orderId;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.ycwl.basic.integration.profitshare.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 支持的类型VO
|
||||
*
|
||||
* @author Claude Code
|
||||
* @date 2025-01-11
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class TypesVO {
|
||||
|
||||
/**
|
||||
* 规则类型列表
|
||||
*/
|
||||
@JsonProperty("rule_types")
|
||||
private List<String> ruleTypes;
|
||||
|
||||
/**
|
||||
* 接收人类型列表
|
||||
*/
|
||||
@JsonProperty("recipient_types")
|
||||
private List<String> recipientTypes;
|
||||
|
||||
/**
|
||||
* 分账类型列表
|
||||
*/
|
||||
@JsonProperty("share_types")
|
||||
private List<String> shareTypes;
|
||||
|
||||
/**
|
||||
* 状态列表
|
||||
*/
|
||||
@JsonProperty("statuses")
|
||||
private List<String> statuses;
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.ycwl.basic.integration.profitshare.dto.message;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 订单分账消息(发送到 zt-profitshare topic)
|
||||
*
|
||||
* @author Claude Code
|
||||
* @date 2025-01-11
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class OrderMessage {
|
||||
|
||||
/**
|
||||
* 订单ID
|
||||
*/
|
||||
@JsonProperty("order_id")
|
||||
private String orderId;
|
||||
|
||||
/**
|
||||
* 景区ID
|
||||
*/
|
||||
@JsonProperty("scenic_id")
|
||||
private Long scenicId;
|
||||
|
||||
/**
|
||||
* 总金额(单位:元)
|
||||
*/
|
||||
@JsonProperty("total_amount")
|
||||
private Double totalAmount;
|
||||
|
||||
/**
|
||||
* 支付系统(alipay, wechat, union)
|
||||
*/
|
||||
@JsonProperty("payment_system")
|
||||
private String paymentSystem;
|
||||
|
||||
/**
|
||||
* 支付订单ID
|
||||
*/
|
||||
@JsonProperty("payment_order_id")
|
||||
private String paymentOrderId;
|
||||
|
||||
/**
|
||||
* Unix 时间戳(秒)
|
||||
*/
|
||||
@JsonProperty("timestamp")
|
||||
private Long timestamp;
|
||||
|
||||
/**
|
||||
* 快速创建订单消息
|
||||
*/
|
||||
public static OrderMessage of(String orderId, Long scenicId, Double totalAmount, String paymentSystem, String paymentOrderId) {
|
||||
return OrderMessage.builder()
|
||||
.orderId(orderId)
|
||||
.scenicId(scenicId)
|
||||
.totalAmount(totalAmount)
|
||||
.paymentSystem(paymentSystem)
|
||||
.paymentOrderId(paymentOrderId)
|
||||
.timestamp(System.currentTimeMillis() / 1000)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.ycwl.basic.integration.profitshare.dto.message;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 退款消息(发送到 zt-refund topic)
|
||||
*
|
||||
* @author Claude Code
|
||||
* @date 2025-01-11
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class RefundMessage {
|
||||
|
||||
/**
|
||||
* 订单ID
|
||||
*/
|
||||
@JsonProperty("order_id")
|
||||
private String orderId;
|
||||
|
||||
/**
|
||||
* 景区ID
|
||||
*/
|
||||
@JsonProperty("scenic_id")
|
||||
private Long scenicId;
|
||||
|
||||
/**
|
||||
* 退款金额(单位:元)
|
||||
*/
|
||||
@JsonProperty("refund_amount")
|
||||
private Double refundAmount;
|
||||
|
||||
/**
|
||||
* 支付系统(alipay, wechat, union)
|
||||
*/
|
||||
@JsonProperty("payment_system")
|
||||
private String paymentSystem;
|
||||
|
||||
/**
|
||||
* 退款订单ID
|
||||
*/
|
||||
@JsonProperty("refund_order_id")
|
||||
private String refundOrderId;
|
||||
|
||||
/**
|
||||
* Unix 时间戳(秒)
|
||||
*/
|
||||
@JsonProperty("timestamp")
|
||||
private Long timestamp;
|
||||
|
||||
/**
|
||||
* 快速创建退款消息
|
||||
*/
|
||||
public static RefundMessage of(String orderId, Long scenicId, Double refundAmount, String paymentSystem, String refundOrderId) {
|
||||
return RefundMessage.builder()
|
||||
.orderId(orderId)
|
||||
.scenicId(scenicId)
|
||||
.refundAmount(refundAmount)
|
||||
.paymentSystem(paymentSystem)
|
||||
.refundOrderId(refundOrderId)
|
||||
.timestamp(System.currentTimeMillis() / 1000)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package com.ycwl.basic.integration.profitshare.dto.record;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 分账记录详情VO
|
||||
*
|
||||
* @author Claude Code
|
||||
* @date 2025-01-11
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class RecordDetailVO {
|
||||
|
||||
/**
|
||||
* 记录ID
|
||||
*/
|
||||
@JsonProperty("id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 订单ID
|
||||
*/
|
||||
@JsonProperty("order_id")
|
||||
private String orderId;
|
||||
|
||||
/**
|
||||
* 景区ID
|
||||
*/
|
||||
@JsonProperty("scenic_id")
|
||||
private Long scenicId;
|
||||
|
||||
/**
|
||||
* 规则ID
|
||||
*/
|
||||
@JsonProperty("rule_id")
|
||||
private Long ruleId;
|
||||
|
||||
/**
|
||||
* 总金额
|
||||
*/
|
||||
@JsonProperty("total_amount")
|
||||
private Double totalAmount;
|
||||
|
||||
/**
|
||||
* 支付系统
|
||||
*/
|
||||
@JsonProperty("payment_system")
|
||||
private String paymentSystem;
|
||||
|
||||
/**
|
||||
* 支付订单ID
|
||||
*/
|
||||
@JsonProperty("payment_order_id")
|
||||
private String paymentOrderId;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
@JsonProperty("status")
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 错误信息
|
||||
*/
|
||||
@JsonProperty("error_message")
|
||||
private String errorMessage;
|
||||
|
||||
/**
|
||||
* 分账明细列表
|
||||
*/
|
||||
@JsonProperty("details")
|
||||
private List<ShareDetailVO> details;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@JsonProperty("created_at")
|
||||
private String createdAt;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@JsonProperty("updated_at")
|
||||
private String updatedAt;
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package com.ycwl.basic.integration.profitshare.dto.record;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 分账记录VO
|
||||
*
|
||||
* @author Claude Code
|
||||
* @date 2025-01-11
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class RecordVO {
|
||||
|
||||
/**
|
||||
* 记录ID
|
||||
*/
|
||||
@JsonProperty("id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 订单ID
|
||||
*/
|
||||
@JsonProperty("order_id")
|
||||
private String orderId;
|
||||
|
||||
/**
|
||||
* 景区ID
|
||||
*/
|
||||
@JsonProperty("scenic_id")
|
||||
private Long scenicId;
|
||||
|
||||
/**
|
||||
* 规则ID
|
||||
*/
|
||||
@JsonProperty("rule_id")
|
||||
private Long ruleId;
|
||||
|
||||
/**
|
||||
* 总金额
|
||||
*/
|
||||
@JsonProperty("total_amount")
|
||||
private Double totalAmount;
|
||||
|
||||
/**
|
||||
* 支付系统
|
||||
*/
|
||||
@JsonProperty("payment_system")
|
||||
private String paymentSystem;
|
||||
|
||||
/**
|
||||
* 支付订单ID
|
||||
*/
|
||||
@JsonProperty("payment_order_id")
|
||||
private String paymentOrderId;
|
||||
|
||||
/**
|
||||
* 状态(pending, processing, success, failed)
|
||||
*/
|
||||
@JsonProperty("status")
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 错误信息
|
||||
*/
|
||||
@JsonProperty("error_message")
|
||||
private String errorMessage;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@JsonProperty("created_at")
|
||||
private String createdAt;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@JsonProperty("updated_at")
|
||||
private String updatedAt;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.ycwl.basic.integration.profitshare.dto.record;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 分账明细VO
|
||||
*
|
||||
* @author Claude Code
|
||||
* @date 2025-01-11
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class ShareDetailVO {
|
||||
|
||||
/**
|
||||
* 明细ID
|
||||
*/
|
||||
@JsonProperty("id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 接收人名称
|
||||
*/
|
||||
@JsonProperty("recipient_name")
|
||||
private String recipientName;
|
||||
|
||||
/**
|
||||
* 接收人类型
|
||||
*/
|
||||
@JsonProperty("recipient_type")
|
||||
private String recipientType;
|
||||
|
||||
/**
|
||||
* 账户信息
|
||||
*/
|
||||
@JsonProperty("account_info")
|
||||
private String accountInfo;
|
||||
|
||||
/**
|
||||
* 分账金额
|
||||
*/
|
||||
@JsonProperty("share_amount")
|
||||
private Double shareAmount;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
@JsonProperty("status")
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 错误信息
|
||||
*/
|
||||
@JsonProperty("error_message")
|
||||
private String errorMessage;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.ycwl.basic.integration.profitshare.dto.rule;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 分账接收人请求
|
||||
*
|
||||
* @author Claude Code
|
||||
* @date 2025-01-11
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class CreateRecipientRequest {
|
||||
|
||||
/**
|
||||
* 接收人名称
|
||||
*/
|
||||
@JsonProperty("recipient_name")
|
||||
private String recipientName;
|
||||
|
||||
/**
|
||||
* 接收人类型(platform, merchant, agent)
|
||||
*/
|
||||
@JsonProperty("recipient_type")
|
||||
private String recipientType;
|
||||
|
||||
/**
|
||||
* 账户信息
|
||||
*/
|
||||
@JsonProperty("account_info")
|
||||
private String accountInfo;
|
||||
|
||||
/**
|
||||
* 分账类型(percentage, fixed_amount)
|
||||
*/
|
||||
@JsonProperty("share_type")
|
||||
private String shareType;
|
||||
|
||||
/**
|
||||
* 分账值(百分比或固定金额)
|
||||
*/
|
||||
@JsonProperty("share_value")
|
||||
private Double shareValue;
|
||||
|
||||
/**
|
||||
* 最小分账金额
|
||||
*/
|
||||
@JsonProperty("min_amount")
|
||||
private Double minAmount;
|
||||
|
||||
/**
|
||||
* 最大分账金额
|
||||
*/
|
||||
@JsonProperty("max_amount")
|
||||
private Double maxAmount;
|
||||
|
||||
/**
|
||||
* 优先级
|
||||
*/
|
||||
@JsonProperty("priority")
|
||||
private Integer priority;
|
||||
|
||||
/**
|
||||
* 扩展配置
|
||||
*/
|
||||
@JsonProperty("ext_config")
|
||||
private Map<String, Object> extConfig;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.ycwl.basic.integration.profitshare.dto.rule;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 创建分账规则请求
|
||||
*
|
||||
* @author Claude Code
|
||||
* @date 2025-01-11
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class CreateRuleRequest {
|
||||
|
||||
/**
|
||||
* 景区ID
|
||||
*/
|
||||
@JsonProperty("scenic_id")
|
||||
private Long scenicId;
|
||||
|
||||
/**
|
||||
* 规则名称
|
||||
*/
|
||||
@JsonProperty("rule_name")
|
||||
private String ruleName;
|
||||
|
||||
/**
|
||||
* 规则类型(percentage, fixed_amount, scaled_amount)
|
||||
*/
|
||||
@JsonProperty("rule_type")
|
||||
private String ruleType;
|
||||
|
||||
/**
|
||||
* 规则描述
|
||||
*/
|
||||
@JsonProperty("description")
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 分账接收人列表
|
||||
*/
|
||||
@JsonProperty("recipients")
|
||||
private List<CreateRecipientRequest> recipients;
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package com.ycwl.basic.integration.profitshare.dto.rule;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 分账接收人VO
|
||||
*
|
||||
* @author Claude Code
|
||||
* @date 2025-01-11
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class RecipientVO {
|
||||
|
||||
/**
|
||||
* 接收人ID
|
||||
*/
|
||||
@JsonProperty("id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 接收人名称
|
||||
*/
|
||||
@JsonProperty("recipient_name")
|
||||
private String recipientName;
|
||||
|
||||
/**
|
||||
* 接收人类型
|
||||
*/
|
||||
@JsonProperty("recipient_type")
|
||||
private String recipientType;
|
||||
|
||||
/**
|
||||
* 账户信息
|
||||
*/
|
||||
@JsonProperty("account_info")
|
||||
private String accountInfo;
|
||||
|
||||
/**
|
||||
* 分账类型
|
||||
*/
|
||||
@JsonProperty("share_type")
|
||||
private String shareType;
|
||||
|
||||
/**
|
||||
* 分账值
|
||||
*/
|
||||
@JsonProperty("share_value")
|
||||
private Double shareValue;
|
||||
|
||||
/**
|
||||
* 最小分账金额
|
||||
*/
|
||||
@JsonProperty("min_amount")
|
||||
private Double minAmount;
|
||||
|
||||
/**
|
||||
* 最大分账金额
|
||||
*/
|
||||
@JsonProperty("max_amount")
|
||||
private Double maxAmount;
|
||||
|
||||
/**
|
||||
* 优先级
|
||||
*/
|
||||
@JsonProperty("priority")
|
||||
private Integer priority;
|
||||
|
||||
/**
|
||||
* 扩展配置
|
||||
*/
|
||||
@JsonProperty("ext_config")
|
||||
private Map<String, Object> extConfig;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
@JsonProperty("status")
|
||||
private String status;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.ycwl.basic.integration.profitshare.dto.rule;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 分账规则VO
|
||||
*
|
||||
* @author Claude Code
|
||||
* @date 2025-01-11
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class RuleVO {
|
||||
|
||||
/**
|
||||
* 规则ID
|
||||
*/
|
||||
@JsonProperty("id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 景区ID
|
||||
*/
|
||||
@JsonProperty("scenic_id")
|
||||
private Long scenicId;
|
||||
|
||||
/**
|
||||
* 规则名称
|
||||
*/
|
||||
@JsonProperty("rule_name")
|
||||
private String ruleName;
|
||||
|
||||
/**
|
||||
* 规则类型
|
||||
*/
|
||||
@JsonProperty("rule_type")
|
||||
private String ruleType;
|
||||
|
||||
/**
|
||||
* 规则描述
|
||||
*/
|
||||
@JsonProperty("description")
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 状态(active, inactive)
|
||||
*/
|
||||
@JsonProperty("status")
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 分账接收人列表
|
||||
*/
|
||||
@JsonProperty("recipients")
|
||||
private List<RecipientVO> recipients;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@JsonProperty("created_at")
|
||||
private String createdAt;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@JsonProperty("updated_at")
|
||||
private String updatedAt;
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
package com.ycwl.basic.integration.profitshare.service;
|
||||
|
||||
import com.ycwl.basic.integration.common.exception.IntegrationException;
|
||||
import com.ycwl.basic.integration.common.response.CommonResponse;
|
||||
import com.ycwl.basic.integration.common.response.PageResponse;
|
||||
import com.ycwl.basic.integration.common.service.IntegrationFallbackService;
|
||||
import com.ycwl.basic.integration.profitshare.client.ProfitShareClient;
|
||||
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;
|
||||
import com.ycwl.basic.integration.profitshare.dto.rule.CreateRuleRequest;
|
||||
import com.ycwl.basic.integration.profitshare.dto.rule.RuleVO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 分账集成服务
|
||||
*
|
||||
* @author Claude Code
|
||||
* @date 2025-01-11
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class ProfitShareIntegrationService {
|
||||
|
||||
private final ProfitShareClient profitShareClient;
|
||||
private final IntegrationFallbackService fallbackService;
|
||||
|
||||
private static final String SERVICE_NAME = "zt-profitshare";
|
||||
|
||||
// ==================== 规则管理 ====================
|
||||
|
||||
/**
|
||||
* 创建分账规则(直接操作,无fallback)
|
||||
*/
|
||||
public RuleVO createRule(CreateRuleRequest request) {
|
||||
log.debug("创建分账规则, scenicId: {}, ruleName: {}", request.getScenicId(), request.getRuleName());
|
||||
CommonResponse<RuleVO> response = profitShareClient.createRule(request);
|
||||
return handleResponse(response, "创建分账规则失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询分账规则列表(带fallback)
|
||||
*/
|
||||
public PageResponse<RuleVO> listRules(Long scenicId, String status, String ruleType, Integer page, Integer pageSize) {
|
||||
log.debug("查询分账规则列表, scenicId: {}, status: {}, ruleType: {}, page: {}, pageSize: {}",
|
||||
scenicId, status, ruleType, page, pageSize);
|
||||
return fallbackService.executeWithFallback(
|
||||
SERVICE_NAME,
|
||||
String.format("rules:list:%s:%s:%s:%d:%d", scenicId, status, ruleType, page, pageSize),
|
||||
() -> {
|
||||
CommonResponse<PageResponse<RuleVO>> response = profitShareClient.listRules(scenicId, status, ruleType, page, pageSize);
|
||||
return handleResponse(response, "查询分账规则列表失败");
|
||||
},
|
||||
PageResponse.class
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分账规则详情(带fallback)
|
||||
*/
|
||||
public RuleVO getRule(Long ruleId) {
|
||||
log.debug("获取分账规则详情, ruleId: {}", ruleId);
|
||||
return fallbackService.executeWithFallback(
|
||||
SERVICE_NAME,
|
||||
"rule:" + ruleId,
|
||||
() -> {
|
||||
CommonResponse<RuleVO> response = profitShareClient.getRule(ruleId);
|
||||
return handleResponse(response, "获取分账规则详情失败");
|
||||
},
|
||||
RuleVO.class
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新分账规则(直接操作,无fallback)
|
||||
*/
|
||||
public RuleVO updateRule(Long ruleId, CreateRuleRequest request) {
|
||||
log.debug("更新分账规则, ruleId: {}", ruleId);
|
||||
CommonResponse<RuleVO> response = profitShareClient.updateRule(ruleId, request);
|
||||
return handleResponse(response, "更新分账规则失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除分账规则(直接操作,无fallback)
|
||||
*/
|
||||
public void deleteRule(Long ruleId) {
|
||||
log.debug("删除分账规则, ruleId: {}", ruleId);
|
||||
CommonResponse<Void> response = profitShareClient.deleteRule(ruleId);
|
||||
handleResponse(response, "删除分账规则失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用规则(直接操作,无fallback)
|
||||
*/
|
||||
public void enableRule(Long ruleId) {
|
||||
log.debug("启用分账规则, ruleId: {}", ruleId);
|
||||
CommonResponse<Void> response = profitShareClient.enableRule(ruleId);
|
||||
handleResponse(response, "启用分账规则失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用规则(直接操作,无fallback)
|
||||
*/
|
||||
public void disableRule(Long ruleId) {
|
||||
log.debug("禁用分账规则, ruleId: {}", ruleId);
|
||||
CommonResponse<Void> response = profitShareClient.disableRule(ruleId);
|
||||
handleResponse(response, "禁用分账规则失败");
|
||||
}
|
||||
|
||||
// ==================== 分账记录查询 ====================
|
||||
|
||||
/**
|
||||
* 查询景区分账记录(带fallback)
|
||||
*/
|
||||
public PageResponse<RecordVO> getRecordsByScenic(Long scenicId, Integer page, Integer pageSize) {
|
||||
log.debug("查询景区分账记录, scenicId: {}, page: {}, pageSize: {}", scenicId, page, pageSize);
|
||||
return fallbackService.executeWithFallback(
|
||||
SERVICE_NAME,
|
||||
String.format("records:scenic:%d:%d:%d", scenicId, page, pageSize),
|
||||
() -> {
|
||||
CommonResponse<PageResponse<RecordVO>> response = profitShareClient.getRecordsByScenic(scenicId, page, pageSize);
|
||||
return handleResponse(response, "查询景区分账记录失败");
|
||||
},
|
||||
PageResponse.class
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询分账记录详情(带fallback)
|
||||
*/
|
||||
public RecordDetailVO getRecordById(Long recordId) {
|
||||
log.debug("查询分账记录详情, recordId: {}", recordId);
|
||||
return fallbackService.executeWithFallback(
|
||||
SERVICE_NAME,
|
||||
"record:" + recordId,
|
||||
() -> {
|
||||
CommonResponse<RecordDetailVO> response = profitShareClient.getRecordById(recordId);
|
||||
return handleResponse(response, "查询分账记录详情失败");
|
||||
},
|
||||
RecordDetailVO.class
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 按订单ID查询分账记录(带fallback)
|
||||
*/
|
||||
public RecordDetailVO getRecordByOrderId(String orderId) {
|
||||
log.debug("按订单ID查询分账记录, orderId: {}", orderId);
|
||||
return fallbackService.executeWithFallback(
|
||||
SERVICE_NAME,
|
||||
"record:order:" + orderId,
|
||||
() -> {
|
||||
CommonResponse<RecordDetailVO> response = profitShareClient.getRecordByOrderId(orderId);
|
||||
return handleResponse(response, "按订单ID查询分账记录失败");
|
||||
},
|
||||
RecordDetailVO.class
|
||||
);
|
||||
}
|
||||
|
||||
// ==================== 分账操作 ====================
|
||||
|
||||
/**
|
||||
* 手动触发分账(直接操作,无fallback)
|
||||
*/
|
||||
public void manualShare(String orderId) {
|
||||
log.debug("手动触发分账, orderId: {}", orderId);
|
||||
ManualShareRequest request = ManualShareRequest.builder()
|
||||
.orderId(orderId)
|
||||
.build();
|
||||
CommonResponse<Void> response = profitShareClient.manualShare(request);
|
||||
handleResponse(response, "手动触发分账失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算分账金额(不执行)(带fallback)
|
||||
*/
|
||||
public CalculateResultVO calculateShare(CalculateShareRequest request) {
|
||||
log.debug("计算分账金额, scenicId: {}, totalAmount: {}", request.getScenicId(), request.getTotalAmount());
|
||||
return fallbackService.executeWithFallback(
|
||||
SERVICE_NAME,
|
||||
String.format("calculate:%d:%.2f", request.getScenicId(), request.getTotalAmount()),
|
||||
() -> {
|
||||
CommonResponse<CalculateResultVO> response = profitShareClient.calculateShare(request);
|
||||
return handleResponse(response, "计算分账金额失败");
|
||||
},
|
||||
CalculateResultVO.class
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取支持的类型(带fallback)
|
||||
*/
|
||||
public TypesVO getSupportedTypes() {
|
||||
log.debug("获取支持的类型");
|
||||
return fallbackService.executeWithFallback(
|
||||
SERVICE_NAME,
|
||||
"types",
|
||||
() -> {
|
||||
CommonResponse<TypesVO> response = profitShareClient.getSupportedTypes();
|
||||
return handleResponse(response, "获取支持的类型失败");
|
||||
},
|
||||
TypesVO.class
|
||||
);
|
||||
}
|
||||
|
||||
// ==================== 私有方法 ====================
|
||||
|
||||
private <T> T handleResponse(CommonResponse<T> response, String errorMessage) {
|
||||
if (response == null || !response.isSuccess()) {
|
||||
String msg = response != null && response.getMessage() != null
|
||||
? response.getMessage()
|
||||
: errorMessage;
|
||||
Integer code = response != null ? response.getCode() : 5000;
|
||||
throw new IntegrationException(code, msg, SERVICE_NAME);
|
||||
}
|
||||
return response.getData();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
package com.ycwl.basic.integration.profitshare.service;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.ycwl.basic.integration.kafka.config.KafkaIntegrationProperties;
|
||||
import com.ycwl.basic.integration.profitshare.dto.message.OrderMessage;
|
||||
import com.ycwl.basic.integration.profitshare.dto.message.RefundMessage;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.kafka.core.KafkaTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 分账Kafka消息生产者
|
||||
*
|
||||
* @author Claude Code
|
||||
* @date 2025-01-11
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@ConditionalOnProperty(name = "kafka.enabled", havingValue = "true")
|
||||
public class ProfitShareKafkaProducer {
|
||||
|
||||
public static final String DEFAULT_PROFITSHARE_TOPIC = "zt-profitshare";
|
||||
public static final String DEFAULT_REFUND_TOPIC = "zt-refund";
|
||||
|
||||
private final KafkaTemplate<String, String> kafkaTemplate;
|
||||
private final ObjectMapper objectMapper;
|
||||
private final KafkaIntegrationProperties kafkaProps;
|
||||
|
||||
/**
|
||||
* 发送分账消息(订单支付成功后调用)
|
||||
*/
|
||||
public void sendProfitShareMessage(OrderMessage message) {
|
||||
validate(message);
|
||||
String topic = kafkaProps != null && StringUtils.isNotBlank(kafkaProps.getProfitShareTopic())
|
||||
? kafkaProps.getProfitShareTopic()
|
||||
: DEFAULT_PROFITSHARE_TOPIC;
|
||||
String key = message.getOrderId();
|
||||
String payload = toJson(message);
|
||||
|
||||
log.info("[PROFIT-SHARE] producing to topic={}, key={}, orderId={}, scenicId={}, amount={}",
|
||||
topic, key, message.getOrderId(), message.getScenicId(), message.getTotalAmount());
|
||||
|
||||
kafkaTemplate.send(topic, key, payload).whenComplete((metadata, ex) -> {
|
||||
if (ex != null) {
|
||||
log.error("[PROFIT-SHARE] produce failed: orderId={}, error={}", message.getOrderId(), ex.getMessage(), ex);
|
||||
} else if (metadata != null) {
|
||||
log.info("[PROFIT-SHARE] produced: orderId={}, partition={}, offset={}",
|
||||
message.getOrderId(), metadata.getRecordMetadata().partition(), metadata.getRecordMetadata().offset());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送退款消息(订单退款成功后调用)
|
||||
*/
|
||||
public void sendRefundMessage(RefundMessage message) {
|
||||
validateRefund(message);
|
||||
String topic = kafkaProps != null && StringUtils.isNotBlank(kafkaProps.getRefundTopic())
|
||||
? kafkaProps.getRefundTopic()
|
||||
: DEFAULT_REFUND_TOPIC;
|
||||
String key = message.getOrderId();
|
||||
String payload = toJson(message);
|
||||
|
||||
log.info("[REFUND] producing to topic={}, key={}, orderId={}, scenicId={}, amount={}",
|
||||
topic, key, message.getOrderId(), message.getScenicId(), message.getRefundAmount());
|
||||
|
||||
kafkaTemplate.send(topic, key, payload).whenComplete((metadata, ex) -> {
|
||||
if (ex != null) {
|
||||
log.error("[REFUND] produce failed: orderId={}, error={}", message.getOrderId(), ex.getMessage(), ex);
|
||||
} else if (metadata != null) {
|
||||
log.info("[REFUND] produced: orderId={}, partition={}, offset={}",
|
||||
message.getOrderId(), metadata.getRecordMetadata().partition(), metadata.getRecordMetadata().offset());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void validate(OrderMessage msg) {
|
||||
if (msg == null) {
|
||||
throw new IllegalArgumentException("OrderMessage is null");
|
||||
}
|
||||
if (StringUtils.isBlank(msg.getOrderId())) {
|
||||
throw new IllegalArgumentException("orderId is required");
|
||||
}
|
||||
if (msg.getScenicId() == null || msg.getScenicId() <= 0) {
|
||||
throw new IllegalArgumentException("scenicId is required and must be positive");
|
||||
}
|
||||
if (msg.getTotalAmount() == null || msg.getTotalAmount() <= 0) {
|
||||
throw new IllegalArgumentException("totalAmount is required and must be positive");
|
||||
}
|
||||
if (StringUtils.isBlank(msg.getPaymentSystem())) {
|
||||
throw new IllegalArgumentException("paymentSystem is required");
|
||||
}
|
||||
if (StringUtils.isBlank(msg.getPaymentOrderId())) {
|
||||
throw new IllegalArgumentException("paymentOrderId is required");
|
||||
}
|
||||
}
|
||||
|
||||
private void validateRefund(RefundMessage msg) {
|
||||
if (msg == null) {
|
||||
throw new IllegalArgumentException("RefundMessage is null");
|
||||
}
|
||||
if (StringUtils.isBlank(msg.getOrderId())) {
|
||||
throw new IllegalArgumentException("orderId is required");
|
||||
}
|
||||
if (msg.getScenicId() == null || msg.getScenicId() <= 0) {
|
||||
throw new IllegalArgumentException("scenicId is required and must be positive");
|
||||
}
|
||||
if (msg.getRefundAmount() == null || msg.getRefundAmount() <= 0) {
|
||||
throw new IllegalArgumentException("refundAmount is required and must be positive");
|
||||
}
|
||||
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) {
|
||||
try {
|
||||
return objectMapper.writeValueAsString(obj);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new IllegalArgumentException("failed to serialize message", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user