|
|
@@ -1,151 +0,0 @@
|
|
|
-package com.bex.staking.controller;
|
|
|
-
|
|
|
-import com.bex.common.model.R;
|
|
|
-import com.bex.staking.engine.ClearingEngine;
|
|
|
-import com.bex.staking.engine.SettleResult;
|
|
|
-import com.bex.staking.engine.SettleSummary;
|
|
|
-import com.bex.staking.engine.SettlementEngine;
|
|
|
-import com.bex.staking.entity.StakingOrder;
|
|
|
-import com.bex.staking.mq.AssetEventProducer;
|
|
|
-import com.bex.staking.mq.AssetEventRetryService;
|
|
|
-import java.time.LocalDate;
|
|
|
-import java.time.format.DateTimeFormatter;
|
|
|
-import java.util.List;
|
|
|
-import lombok.RequiredArgsConstructor;
|
|
|
-import lombok.extern.slf4j.Slf4j;
|
|
|
-import org.springframework.web.bind.annotation.GetMapping;
|
|
|
-import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
-import org.springframework.web.bind.annotation.RequestParam;
|
|
|
-import org.springframework.web.bind.annotation.RestController;
|
|
|
-
|
|
|
-/**
|
|
|
- * 质押任务测试控制器。
|
|
|
- *
|
|
|
- * <p>提供手动触发定时任务的接口,用于测试和调试。
|
|
|
- * 注意:此控制器仅用于测试环境,生产环境应禁用或限制访问权限。
|
|
|
- */
|
|
|
-@Slf4j
|
|
|
-@RestController
|
|
|
-@RequestMapping("/api/v1/staking/task")
|
|
|
-@RequiredArgsConstructor
|
|
|
-public class StakingTaskController {
|
|
|
-
|
|
|
- private static final DateTimeFormatter BIZ_DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");
|
|
|
-
|
|
|
- private final SettlementEngine settlementEngine;
|
|
|
-
|
|
|
- /** 上次结算的业务日期(用于 nextDay 模式自动递增) */
|
|
|
- private static volatile Integer lastSettledBizDate = null;
|
|
|
-
|
|
|
- /**
|
|
|
- * 手动触发每日收益结算任务。
|
|
|
- *
|
|
|
- * <p>支持指定业务日期进行测试,可模拟多日连续结算。
|
|
|
- *
|
|
|
- * @param bizDate 业务日期(可选,格式 yyyyMMdd),不传则使用当前日期
|
|
|
- * @param nextDay 是否自动使用下一天(可选,与 bizDate 互斥)
|
|
|
- * @return 结算结果汇总
|
|
|
- */
|
|
|
- @GetMapping("/settle/daily")
|
|
|
- public R<SettleResultVO> triggerDailySettlement(
|
|
|
- @RequestParam(required = false) Integer bizDate,
|
|
|
- @RequestParam(required = false, defaultValue = "false") Boolean nextDay) {
|
|
|
- log.info("手动触发每日收益结算任务");
|
|
|
-
|
|
|
- // 优先使用指定的业务日期
|
|
|
- if (bizDate != null) {
|
|
|
- log.info("使用指定业务日期: {}", bizDate);
|
|
|
- } else if (Boolean.TRUE.equals(nextDay)) {
|
|
|
- // 自动使用下一天(基于上次结算日期)
|
|
|
- bizDate = getNextBizDate();
|
|
|
- log.info("自动使用下一天业务日期: {}", bizDate);
|
|
|
- } else {
|
|
|
- // 默认使用当前日期
|
|
|
- bizDate = Integer.parseInt(LocalDate.now().format(BIZ_DATE_FORMATTER));
|
|
|
- log.info("使用当前业务日期: {}", bizDate);
|
|
|
- }
|
|
|
-
|
|
|
- try {
|
|
|
- List<StakingOrder> allOrders = settlementEngine.loadHoldingStakingOrders();
|
|
|
- log.info("待结算订单数: {}", allOrders.size());
|
|
|
-
|
|
|
- SettleSummary summary = settlementEngine.settleDaily(allOrders, bizDate);
|
|
|
-
|
|
|
- SettleResultVO result = new SettleResultVO();
|
|
|
- result.setBizDate(bizDate);
|
|
|
- result.setTotal(summary.getTotal());
|
|
|
- result.setSuccessCount(summary.getSuccessCount());
|
|
|
- result.setSkippedCount(summary.getSkippedCount());
|
|
|
- result.setFailedCount(summary.getFailedCount());
|
|
|
-
|
|
|
- if (summary.getFailedCount() > 0) {
|
|
|
- StringBuilder failedDetails = new StringBuilder();
|
|
|
- for (SettleResult failed : summary.getFailedResults()) {
|
|
|
- failedDetails.append(String.format("orderNo=%s, reason=%s; ", failed.orderNo(), failed.message()));
|
|
|
- }
|
|
|
- result.setFailedDetails(failedDetails.toString());
|
|
|
- }
|
|
|
-
|
|
|
- // 更新上次结算日期
|
|
|
- lastSettledBizDate = bizDate;
|
|
|
-
|
|
|
- log.info("每日收益结算完成: {}", result);
|
|
|
- return R.ok(result);
|
|
|
-
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("手动触发每日收益结算任务异常", e);
|
|
|
- return R.fail("结算任务执行失败: " + e.getMessage());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取下一个业务日期。
|
|
|
- * 如果上次结算日期为空,则使用当前日期;否则使用上次日期 + 1天。
|
|
|
- *
|
|
|
- * @return 下一个业务日期(yyyyMMdd)
|
|
|
- */
|
|
|
- private synchronized int getNextBizDate() {
|
|
|
- if (lastSettledBizDate == null) {
|
|
|
- // 第一次调用,使用当前日期
|
|
|
- return Integer.parseInt(LocalDate.now().format(BIZ_DATE_FORMATTER));
|
|
|
- }
|
|
|
-
|
|
|
- // 上次日期 + 1天
|
|
|
- String dateStr = String.valueOf(lastSettledBizDate);
|
|
|
- LocalDate lastDate = LocalDate.of(
|
|
|
- Integer.parseInt(dateStr.substring(0, 4)),
|
|
|
- Integer.parseInt(dateStr.substring(4, 6)),
|
|
|
- Integer.parseInt(dateStr.substring(6, 8)));
|
|
|
- LocalDate nextDate = lastDate.plusDays(1);
|
|
|
- return Integer.parseInt(nextDate.format(BIZ_DATE_FORMATTER));
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 重置上次结算日期(用于重新开始测试)。
|
|
|
- */
|
|
|
- @GetMapping("/settle/reset")
|
|
|
- public R<Void> resetSettlementDate() {
|
|
|
- lastSettledBizDate = null;
|
|
|
- log.info("已重置上次结算日期");
|
|
|
- return R.ok();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 结算结果返回对象。
|
|
|
- */
|
|
|
- @lombok.Data
|
|
|
- public static class SettleResultVO {
|
|
|
- /** 业务日期(yyyyMMdd) */
|
|
|
- private int bizDate;
|
|
|
- /** 订单总数 */
|
|
|
- private int total;
|
|
|
- /** 成功数量 */
|
|
|
- private int successCount;
|
|
|
- /** 跳过数量(幂等/已过期等) */
|
|
|
- private int skippedCount;
|
|
|
- /** 失败数量 */
|
|
|
- private int failedCount;
|
|
|
- /** 失败详情 */
|
|
|
- private String failedDetails;
|
|
|
- }
|
|
|
-}
|