From 7173d24fe10a8ca03006209b1376d56cdca31dca Mon Sep 17 00:00:00 2001 From: WrBug Date: Mon, 8 Dec 2025 23:02:57 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E7=BB=93=E6=9E=84=EF=BC=8C=E6=8C=89=E4=B8=9A=E5=8A=A1?= =?UTF-8?q?=E5=88=86=E7=B1=BB=E7=BB=84=E7=BB=87=20Controller=20=E5=92=8C?= =?UTF-8?q?=20Service?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 重构 API 路径为 /api/业务/xxx 格式 - 将 Controller 和 Service 按业务分类组织: * copytrading: 跟单相关(configs, leaders, statistics, templates) * accounts: 账户管理(公共模块) * markets: 市场数据(公共模块) * system: 系统管理(users, notifications, proxy, health) * auth: 认证 * announcement: 公告 - 将所有完整类名引用改为使用 import 导入 - 修复 calculatePositionValue 方法实现 - 更新前端 API 调用路径 --- .gitignore | 7 + .../polymarketbot/api/PolymarketClobApi.kt | 2 +- .../config/ProxyConfigInitializer.kt | 2 +- .../{ => accounts}/AccountController.kt | 6 +- .../AnnouncementController.kt | 4 +- .../controller/{ => auth}/AuthController.kt | 4 +- .../configs}/CopyTradingController.kt | 8 +- .../leaders}/LeaderController.kt | 4 +- .../CopyTradingStatisticsController.kt | 4 +- .../CopyTradingTemplateController.kt | 4 +- .../{ => markets}/MarketController.kt | 8 +- .../{ => system}/HealthController.kt | 4 +- .../{ => system}/NotificationController.kt | 8 +- .../{ => system}/ProxyConfigController.kt | 8 +- .../{ => system}/SystemConfigController.kt | 6 +- .../controller/{ => system}/UserController.kt | 6 +- .../service/{ => accounts}/AccountService.kt | 18 ++- .../{ => accounts}/PositionCheckService.kt | 11 +- .../{ => accounts}/PositionPollingService.kt | 2 +- .../{ => accounts}/PositionPushService.kt | 5 +- .../{ => announcement}/AnnouncementService.kt | 149 +++++++++--------- .../service/{ => auth}/AuthService.kt | 3 +- .../service/{ => common}/BlockchainService.kt | 3 +- .../{ => common}/PolymarketApiKeyService.kt | 2 +- .../{ => common}/PolymarketClobService.kt | 2 +- .../service/{ => common}/RateLimitService.kt | 2 +- .../WebSocketSubscriptionService.kt | 4 +- .../configs}/CopyTradingFilterService.kt | 3 +- .../configs}/CopyTradingService.kt | 11 +- .../configs}/FilteredOrderService.kt | 2 +- .../leaders}/LeaderService.kt | 2 +- .../monitor}/CopyTradingMonitorService.kt | 2 +- .../monitor}/CopyTradingPollingService.kt | 7 +- .../monitor}/CopyTradingWebSocketService.kt | 5 +- .../orders}/OrderPushService.kt | 28 ++-- .../orders}/OrderSigningService.kt | 6 +- .../statistics}/CopyOrderTrackingService.kt | 32 ++-- .../CopyTradingStatisticsService.kt | 55 +++++-- .../templates}/CopyTradingTemplateService.kt | 2 +- .../{ => system}/ApiHealthCheckService.kt | 4 +- .../{ => system}/NotificationConfigService.kt | 2 +- .../{ => system}/ProxyConfigService.kt | 4 +- .../{ => system}/RelayClientService.kt | 6 +- .../{ => system}/SystemConfigService.kt | 2 +- .../TelegramNotificationService.kt | 5 +- .../service/{ => system}/UserService.kt | 2 +- .../websocket/UnifiedWebSocketHandler.kt | 2 +- frontend/src/services/api.ts | 76 ++++----- 48 files changed, 310 insertions(+), 234 deletions(-) rename backend/src/main/kotlin/com/wrbug/polymarketbot/controller/{ => accounts}/AccountController.kt (99%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/controller/{ => announcement}/AnnouncementController.kt (95%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/controller/{ => auth}/AuthController.kt (98%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/controller/{ => copytrading/configs}/CopyTradingController.kt (97%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/controller/{ => copytrading/leaders}/LeaderController.kt (98%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/controller/{ => copytrading/statistics}/CopyTradingStatisticsController.kt (98%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/controller/{ => copytrading/templates}/CopyTradingTemplateController.kt (98%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/controller/{ => markets}/MarketController.kt (94%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/controller/{ => system}/HealthController.kt (87%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/controller/{ => system}/NotificationController.kt (98%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/controller/{ => system}/ProxyConfigController.kt (95%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/controller/{ => system}/SystemConfigController.kt (96%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/controller/{ => system}/UserController.kt (98%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/service/{ => accounts}/AccountService.kt (98%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/service/{ => accounts}/PositionCheckService.kt (98%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/service/{ => accounts}/PositionPollingService.kt (99%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/service/{ => accounts}/PositionPushService.kt (97%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/service/{ => announcement}/AnnouncementService.kt (88%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/service/{ => auth}/AuthService.kt (98%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/service/{ => common}/BlockchainService.kt (99%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/service/{ => common}/PolymarketApiKeyService.kt (99%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/service/{ => common}/PolymarketClobService.kt (99%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/service/{ => common}/RateLimitService.kt (97%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/service/{ => common}/WebSocketSubscriptionService.kt (96%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/service/{ => copytrading/configs}/CopyTradingFilterService.kt (98%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/service/{ => copytrading/configs}/CopyTradingService.kt (98%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/service/{ => copytrading/configs}/FilteredOrderService.kt (98%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/service/{ => copytrading/leaders}/LeaderService.kt (99%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/service/{ => copytrading/monitor}/CopyTradingMonitorService.kt (98%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/service/{ => copytrading/monitor}/CopyTradingPollingService.kt (97%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/service/{ => copytrading/monitor}/CopyTradingWebSocketService.kt (98%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/service/{ => copytrading/orders}/OrderPushService.kt (94%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/service/{ => copytrading/orders}/OrderSigningService.kt (98%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/service/{ => copytrading/statistics}/CopyOrderTrackingService.kt (98%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/service/{ => copytrading/statistics}/CopyTradingStatisticsService.kt (91%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/service/{ => copytrading/templates}/CopyTradingTemplateService.kt (99%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/service/{ => system}/ApiHealthCheckService.kt (98%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/service/{ => system}/NotificationConfigService.kt (99%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/service/{ => system}/ProxyConfigService.kt (98%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/service/{ => system}/RelayClientService.kt (99%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/service/{ => system}/SystemConfigService.kt (99%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/service/{ => system}/TelegramNotificationService.kt (99%) rename backend/src/main/kotlin/com/wrbug/polymarketbot/service/{ => system}/UserService.kt (99%) diff --git a/.gitignore b/.gitignore index e5c1907..e526be3 100644 --- a/.gitignore +++ b/.gitignore @@ -94,6 +94,13 @@ coverage/ test-results/ *.test.log +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python + # Misc *.bak *.backup diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/api/PolymarketClobApi.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/api/PolymarketClobApi.kt index 58b6f31..01612b9 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/api/PolymarketClobApi.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/api/PolymarketClobApi.kt @@ -227,7 +227,7 @@ data class CreateOrderRequest( @Deprecated("使用 NewOrderRequest 代替") data class CreateOrdersBatchRequest( - val orders: List + val orders: List ) data class CancelOrdersBatchRequest( diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/config/ProxyConfigInitializer.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/config/ProxyConfigInitializer.kt index 9bcd437..78830d7 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/config/ProxyConfigInitializer.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/config/ProxyConfigInitializer.kt @@ -1,6 +1,6 @@ package com.wrbug.polymarketbot.config -import com.wrbug.polymarketbot.service.ProxyConfigService +import com.wrbug.polymarketbot.service.system.ProxyConfigService import jakarta.annotation.PostConstruct import org.slf4j.LoggerFactory import org.springframework.stereotype.Component diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/AccountController.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/accounts/AccountController.kt similarity index 99% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/controller/AccountController.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/controller/accounts/AccountController.kt index 0f9da36..44ac456 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/AccountController.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/accounts/AccountController.kt @@ -1,8 +1,8 @@ -package com.wrbug.polymarketbot.controller +package com.wrbug.polymarketbot.controller.accounts import com.wrbug.polymarketbot.dto.* import com.wrbug.polymarketbot.enums.ErrorCode -import com.wrbug.polymarketbot.service.AccountService +import com.wrbug.polymarketbot.service.accounts.AccountService import com.wrbug.polymarketbot.util.toSafeBigDecimal import kotlinx.coroutines.runBlocking import org.slf4j.LoggerFactory @@ -15,7 +15,7 @@ import java.math.BigDecimal * 账户管理控制器 */ @RestController -@RequestMapping("/api/copy-trading/accounts") +@RequestMapping("/api/accounts") class AccountController( private val accountService: AccountService, private val messageSource: MessageSource diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/AnnouncementController.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/announcement/AnnouncementController.kt similarity index 95% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/controller/AnnouncementController.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/controller/announcement/AnnouncementController.kt index f8b5ef3..759d55f 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/AnnouncementController.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/announcement/AnnouncementController.kt @@ -1,8 +1,8 @@ -package com.wrbug.polymarketbot.controller +package com.wrbug.polymarketbot.controller.announcement import com.wrbug.polymarketbot.dto.* import com.wrbug.polymarketbot.enums.ErrorCode -import com.wrbug.polymarketbot.service.AnnouncementService +import com.wrbug.polymarketbot.service.announcement.AnnouncementService import kotlinx.coroutines.runBlocking import org.slf4j.LoggerFactory import org.springframework.context.MessageSource diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/AuthController.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/auth/AuthController.kt similarity index 98% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/controller/AuthController.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/controller/auth/AuthController.kt index c985405..ca53c3c 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/AuthController.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/auth/AuthController.kt @@ -1,8 +1,8 @@ -package com.wrbug.polymarketbot.controller +package com.wrbug.polymarketbot.controller.auth import com.wrbug.polymarketbot.dto.* import com.wrbug.polymarketbot.enums.ErrorCode -import com.wrbug.polymarketbot.service.AuthService +import com.wrbug.polymarketbot.service.auth.AuthService import jakarta.servlet.http.HttpServletRequest import org.slf4j.LoggerFactory import org.springframework.context.MessageSource diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/CopyTradingController.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/copytrading/configs/CopyTradingController.kt similarity index 97% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/controller/CopyTradingController.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/controller/copytrading/configs/CopyTradingController.kt index 8be18a8..22b7242 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/CopyTradingController.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/copytrading/configs/CopyTradingController.kt @@ -1,9 +1,9 @@ -package com.wrbug.polymarketbot.controller +package com.wrbug.polymarketbot.controller.copytrading.configs import com.wrbug.polymarketbot.dto.* import com.wrbug.polymarketbot.enums.ErrorCode -import com.wrbug.polymarketbot.service.CopyTradingService -import com.wrbug.polymarketbot.service.FilteredOrderService +import com.wrbug.polymarketbot.service.copytrading.configs.CopyTradingService +import com.wrbug.polymarketbot.service.copytrading.configs.FilteredOrderService import org.slf4j.LoggerFactory import org.springframework.context.MessageSource import org.springframework.http.ResponseEntity @@ -13,7 +13,7 @@ import org.springframework.web.bind.annotation.* * 跟单配置管理控制器(钱包-模板关联) */ @RestController -@RequestMapping("/api/copy-trading") +@RequestMapping("/api/copy-trading/configs") class CopyTradingController( private val copyTradingService: CopyTradingService, private val filteredOrderService: FilteredOrderService, diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/LeaderController.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/copytrading/leaders/LeaderController.kt similarity index 98% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/controller/LeaderController.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/controller/copytrading/leaders/LeaderController.kt index edcbfda..1bce8d3 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/LeaderController.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/copytrading/leaders/LeaderController.kt @@ -1,8 +1,8 @@ -package com.wrbug.polymarketbot.controller +package com.wrbug.polymarketbot.controller.copytrading.leaders import com.wrbug.polymarketbot.dto.* import com.wrbug.polymarketbot.enums.ErrorCode -import com.wrbug.polymarketbot.service.LeaderService +import com.wrbug.polymarketbot.service.copytrading.leaders.LeaderService import org.slf4j.LoggerFactory import org.springframework.context.MessageSource import org.springframework.http.ResponseEntity diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/CopyTradingStatisticsController.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/copytrading/statistics/CopyTradingStatisticsController.kt similarity index 98% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/controller/CopyTradingStatisticsController.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/controller/copytrading/statistics/CopyTradingStatisticsController.kt index cc53ae1..b717eab 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/CopyTradingStatisticsController.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/copytrading/statistics/CopyTradingStatisticsController.kt @@ -1,8 +1,8 @@ -package com.wrbug.polymarketbot.controller +package com.wrbug.polymarketbot.controller.copytrading.statistics import com.wrbug.polymarketbot.dto.* import com.wrbug.polymarketbot.enums.ErrorCode -import com.wrbug.polymarketbot.service.CopyTradingStatisticsService +import com.wrbug.polymarketbot.service.copytrading.statistics.CopyTradingStatisticsService import kotlinx.coroutines.runBlocking import org.slf4j.LoggerFactory import org.springframework.context.MessageSource diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/CopyTradingTemplateController.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/copytrading/templates/CopyTradingTemplateController.kt similarity index 98% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/controller/CopyTradingTemplateController.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/controller/copytrading/templates/CopyTradingTemplateController.kt index 4ae0e6f..8269564 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/CopyTradingTemplateController.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/copytrading/templates/CopyTradingTemplateController.kt @@ -1,8 +1,8 @@ -package com.wrbug.polymarketbot.controller +package com.wrbug.polymarketbot.controller.copytrading.templates import com.wrbug.polymarketbot.dto.* import com.wrbug.polymarketbot.enums.ErrorCode -import com.wrbug.polymarketbot.service.CopyTradingTemplateService +import com.wrbug.polymarketbot.service.copytrading.templates.CopyTradingTemplateService import org.slf4j.LoggerFactory import org.springframework.context.MessageSource import org.springframework.http.ResponseEntity diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/MarketController.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/markets/MarketController.kt similarity index 94% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/controller/MarketController.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/controller/markets/MarketController.kt index 1646a33..6deed2d 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/MarketController.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/markets/MarketController.kt @@ -1,10 +1,10 @@ -package com.wrbug.polymarketbot.controller +package com.wrbug.polymarketbot.controller.markets import com.wrbug.polymarketbot.api.LatestPriceResponse import com.wrbug.polymarketbot.dto.* import com.wrbug.polymarketbot.enums.ErrorCode -import com.wrbug.polymarketbot.service.AccountService -import com.wrbug.polymarketbot.service.PolymarketClobService +import com.wrbug.polymarketbot.service.accounts.AccountService +import com.wrbug.polymarketbot.service.common.PolymarketClobService import kotlinx.coroutines.runBlocking import org.slf4j.LoggerFactory import org.springframework.context.MessageSource @@ -16,7 +16,7 @@ import org.springframework.web.bind.annotation.* * 提供市场相关的数据查询接口(价格、订单簿等) */ @RestController -@RequestMapping("/api/copy-trading/markets") +@RequestMapping("/api/markets") class MarketController( private val accountService: AccountService, private val clobService: PolymarketClobService, diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/HealthController.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/system/HealthController.kt similarity index 87% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/controller/HealthController.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/controller/system/HealthController.kt index 3fb6219..9a242cd 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/HealthController.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/system/HealthController.kt @@ -1,4 +1,4 @@ -package com.wrbug.polymarketbot.controller +package com.wrbug.polymarketbot.controller.system import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.GetMapping @@ -11,7 +11,7 @@ import java.util.* * 用于 Docker 健康检查和监控 */ @RestController -@RequestMapping("/api/health") +@RequestMapping("/api/system/health") class HealthController { @GetMapping diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/NotificationController.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/system/NotificationController.kt similarity index 98% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/controller/NotificationController.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/controller/system/NotificationController.kt index e0d991d..0f42d28 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/NotificationController.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/system/NotificationController.kt @@ -1,9 +1,9 @@ -package com.wrbug.polymarketbot.controller +package com.wrbug.polymarketbot.controller.system import com.wrbug.polymarketbot.dto.* import com.wrbug.polymarketbot.enums.ErrorCode -import com.wrbug.polymarketbot.service.NotificationConfigService -import com.wrbug.polymarketbot.service.TelegramNotificationService +import com.wrbug.polymarketbot.service.system.NotificationConfigService +import com.wrbug.polymarketbot.service.system.TelegramNotificationService import kotlinx.coroutines.runBlocking import org.slf4j.LoggerFactory import org.springframework.context.MessageSource @@ -14,7 +14,7 @@ import org.springframework.web.bind.annotation.* * 消息推送配置控制器 */ @RestController -@RequestMapping("/api/notifications") +@RequestMapping("/api/system/notifications") class NotificationController( private val notificationConfigService: NotificationConfigService, private val telegramNotificationService: TelegramNotificationService, diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/ProxyConfigController.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/system/ProxyConfigController.kt similarity index 95% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/controller/ProxyConfigController.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/controller/system/ProxyConfigController.kt index 42bd207..8a2335b 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/ProxyConfigController.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/system/ProxyConfigController.kt @@ -1,9 +1,9 @@ -package com.wrbug.polymarketbot.controller +package com.wrbug.polymarketbot.controller.system import com.wrbug.polymarketbot.dto.* import com.wrbug.polymarketbot.enums.ErrorCode -import com.wrbug.polymarketbot.service.ApiHealthCheckService -import com.wrbug.polymarketbot.service.ProxyConfigService +import com.wrbug.polymarketbot.service.system.ApiHealthCheckService +import com.wrbug.polymarketbot.service.system.ProxyConfigService import jakarta.servlet.http.HttpServletRequest import kotlinx.coroutines.runBlocking import org.slf4j.LoggerFactory @@ -15,7 +15,7 @@ import org.springframework.web.bind.annotation.* * 代理配置控制器 */ @RestController -@RequestMapping("/api/proxy-config") +@RequestMapping("/api/system/proxy") class ProxyConfigController( private val proxyConfigService: ProxyConfigService, private val apiHealthCheckService: ApiHealthCheckService, diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/SystemConfigController.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/system/SystemConfigController.kt similarity index 96% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/controller/SystemConfigController.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/controller/system/SystemConfigController.kt index 1b8d83c..b3a404a 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/SystemConfigController.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/system/SystemConfigController.kt @@ -1,9 +1,9 @@ -package com.wrbug.polymarketbot.controller +package com.wrbug.polymarketbot.controller.system import com.wrbug.polymarketbot.dto.* import com.wrbug.polymarketbot.enums.ErrorCode -import com.wrbug.polymarketbot.service.SystemConfigService -import com.wrbug.polymarketbot.service.RelayClientService +import com.wrbug.polymarketbot.service.system.SystemConfigService +import com.wrbug.polymarketbot.service.system.RelayClientService import kotlinx.coroutines.runBlocking import org.slf4j.LoggerFactory import org.springframework.context.MessageSource diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/UserController.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/system/UserController.kt similarity index 98% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/controller/UserController.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/controller/system/UserController.kt index 55c2d57..4c170eb 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/UserController.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/controller/system/UserController.kt @@ -1,8 +1,8 @@ -package com.wrbug.polymarketbot.controller +package com.wrbug.polymarketbot.controller.system import com.wrbug.polymarketbot.dto.* import com.wrbug.polymarketbot.enums.ErrorCode -import com.wrbug.polymarketbot.service.UserService +import com.wrbug.polymarketbot.service.system.UserService import jakarta.servlet.http.HttpServletRequest import org.slf4j.LoggerFactory import org.springframework.context.MessageSource @@ -13,7 +13,7 @@ import org.springframework.web.bind.annotation.* * 用户管理控制器 */ @RestController -@RequestMapping("/api/users") +@RequestMapping("/api/system/users") class UserController( private val userService: UserService, private val messageSource: MessageSource diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/AccountService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/accounts/AccountService.kt similarity index 98% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/service/AccountService.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/service/accounts/AccountService.kt index 1e29329..f7c4bc1 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/AccountService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/accounts/AccountService.kt @@ -1,4 +1,4 @@ -package com.wrbug.polymarketbot.service +package com.wrbug.polymarketbot.service.accounts import com.wrbug.polymarketbot.api.TradeResponse import com.wrbug.polymarketbot.dto.* @@ -8,6 +8,14 @@ import com.wrbug.polymarketbot.util.RetrofitFactory import com.wrbug.polymarketbot.util.toSafeBigDecimal import com.wrbug.polymarketbot.util.eq import com.wrbug.polymarketbot.util.JsonUtils +import com.wrbug.polymarketbot.service.common.PolymarketClobService +import com.wrbug.polymarketbot.service.common.BlockchainService +import com.wrbug.polymarketbot.service.common.PolymarketApiKeyService +import com.wrbug.polymarketbot.service.copytrading.orders.OrderPushService +import com.wrbug.polymarketbot.service.copytrading.orders.OrderSigningService +import com.wrbug.polymarketbot.service.system.TelegramNotificationService +import com.wrbug.polymarketbot.service.system.RelayClientService +import com.wrbug.polymarketbot.util.CryptoUtils import kotlinx.coroutines.* import org.slf4j.LoggerFactory import org.springframework.stereotype.Service @@ -27,7 +35,7 @@ class AccountService( private val apiKeyService: PolymarketApiKeyService, private val orderPushService: OrderPushService, private val orderSigningService: OrderSigningService, - private val cryptoUtils: com.wrbug.polymarketbot.util.CryptoUtils, + private val cryptoUtils: CryptoUtils, private val telegramNotificationService: TelegramNotificationService? = null, // 可选,避免循环依赖 private val relayClientService: RelayClientService ) { @@ -1070,7 +1078,7 @@ class AccountService( /** * 从订单表获取最优价(用于市价单) * 支持多元市场(二元、三元及以上) - * 委托给 PolymarketClobService.getOptimalPrice 方法 + * 委托给 com.wrbug.polymarketbot.service.common.PolymarketClobService.getOptimalPrice 方法 * * @param tokenId token ID(通过 marketId 和 outcomeIndex 计算得出) * @param isSellOrder 是否为卖出订单(true: 卖单,需要 bestBid;false: 买单,需要 bestAsk) @@ -1167,7 +1175,7 @@ class AccountService( /** * 获取可赎回仓位统计 */ - suspend fun getRedeemablePositionsSummary(accountId: Long? = null): Result { + suspend fun getRedeemablePositionsSummary(accountId: Long? = null): Result { return try { val positionsResult = getAllPositions() positionsResult.fold( @@ -1223,7 +1231,7 @@ class AccountService( * 赎回仓位 * 支持多账户、多仓位赎回(自动按账户和市场分组) */ - suspend fun redeemPositions(request: com.wrbug.polymarketbot.dto.PositionRedeemRequest): Result { + suspend fun redeemPositions(request: PositionRedeemRequest): Result { return try { // 检查 Builder API Key 是否已配置 if (!relayClientService.isBuilderApiKeyConfigured()) { diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/PositionCheckService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/accounts/PositionCheckService.kt similarity index 98% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/service/PositionCheckService.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/service/accounts/PositionCheckService.kt index 63cb6eb..00f0615 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/PositionCheckService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/accounts/PositionCheckService.kt @@ -1,4 +1,4 @@ -package com.wrbug.polymarketbot.service +package com.wrbug.polymarketbot.service.accounts import com.wrbug.polymarketbot.dto.AccountPositionDto import com.wrbug.polymarketbot.entity.CopyOrderTracking @@ -18,6 +18,9 @@ import jakarta.annotation.PostConstruct import jakarta.annotation.PreDestroy import org.springframework.context.MessageSource import org.springframework.context.i18n.LocaleContextHolder +import com.wrbug.polymarketbot.service.system.SystemConfigService +import com.wrbug.polymarketbot.service.system.RelayClientService +import com.wrbug.polymarketbot.service.system.TelegramNotificationService import org.springframework.stereotype.Service import java.math.BigDecimal import java.util.concurrent.ConcurrentHashMap @@ -368,15 +371,15 @@ class PositionCheckService( if (position == null) { // 仓位不存在,更新所有订单状态为已卖出 val currentPrice = getCurrentMarketPrice(marketId, outcomeIndex) - updateOrdersAsSold(orders, currentPrice, copyTrading.id!!, marketId, outcomeIndex) + updateOrdersAsSold(orders, currentPrice, copyTrading.id, marketId, outcomeIndex) } else { // 有仓位,按订单下单顺序(FIFO)更新状态 // 如果仓位数量 >= 订单数量总和,所有订单完全成交 // 如果仓位数量 < 订单数量总和,按FIFO顺序部分成交 - val totalUnmatchedQuantity = orders.sumOf { it.remainingQuantity.toSafeBigDecimal() } val positionQuantity = position.quantity.toSafeBigDecimal() val currentPrice = getCurrentMarketPrice(marketId, outcomeIndex) - updateOrdersAsSoldByFIFO(orders, positionQuantity, currentPrice, copyTrading.id!!, marketId, outcomeIndex) + updateOrdersAsSoldByFIFO(orders, positionQuantity, currentPrice, + copyTrading.id, marketId, outcomeIndex) } } } diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/PositionPollingService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/accounts/PositionPollingService.kt similarity index 99% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/service/PositionPollingService.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/service/accounts/PositionPollingService.kt index 82ac97e..8c154a9 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/PositionPollingService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/accounts/PositionPollingService.kt @@ -1,4 +1,4 @@ -package com.wrbug.polymarketbot.service +package com.wrbug.polymarketbot.service.accounts import com.wrbug.polymarketbot.dto.PositionListResponse import jakarta.annotation.PostConstruct diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/PositionPushService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/accounts/PositionPushService.kt similarity index 97% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/service/PositionPushService.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/service/accounts/PositionPushService.kt index b19cf82..4c633ce 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/PositionPushService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/accounts/PositionPushService.kt @@ -1,6 +1,7 @@ -package com.wrbug.polymarketbot.service +package com.wrbug.polymarketbot.service.accounts import com.wrbug.polymarketbot.dto.AccountPositionDto +import com.wrbug.polymarketbot.dto.PositionListResponse import com.wrbug.polymarketbot.dto.PositionPushMessage import com.wrbug.polymarketbot.dto.PositionPushMessageType import com.wrbug.polymarketbot.dto.getPositionKey @@ -155,7 +156,7 @@ class PositionPushService( * 处理仓位更新事件 * 根据文档要求:每次轮训完成后向订阅者发送全量数据 */ - private fun handlePositionUpdate(positions: com.wrbug.polymarketbot.dto.PositionListResponse) { + private fun handlePositionUpdate(positions: PositionListResponse) { // 更新快照 lastCurrentPositions = positions.currentPositions.associateBy { it.getPositionKey() } lastHistoryPositions = positions.historyPositions.associateBy { it.getPositionKey() } diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/AnnouncementService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/announcement/AnnouncementService.kt similarity index 88% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/service/AnnouncementService.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/service/announcement/AnnouncementService.kt index 1e2305a..bc8ccea 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/AnnouncementService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/announcement/AnnouncementService.kt @@ -1,6 +1,7 @@ -package com.wrbug.polymarketbot.service +package com.wrbug.polymarketbot.service.announcement import com.wrbug.polymarketbot.api.GitHubApi +import com.wrbug.polymarketbot.api.GitHubCommentResponse import com.wrbug.polymarketbot.dto.AnnouncementDto import com.wrbug.polymarketbot.dto.AnnouncementListResponse import com.wrbug.polymarketbot.util.RetrofitFactory @@ -25,30 +26,30 @@ class AnnouncementService( @Value("\${github.announcement.issue.number:1}") private val issueNumber: Int ) { - + private val logger = LoggerFactory.getLogger(AnnouncementService::class.java) - + // GitHub API 客户端(懒加载) private val githubApi: GitHubApi by lazy { retrofitFactory.createGitHubApi() } - + // 需要排除的 Issue ID(从 issue_url 中提取) private val excludedIssueId = "3703128976" - + // 缓存数据(1分钟有效期) private data class CachedData( val data: T, val timestamp: Long ) - + private var cachedList: CachedData? = null private var cachedAssignees: CachedData>? = null private var cachedComments: CachedData>? = null - + // 缓存有效期:10分钟(毫秒) private val cacheExpiryTime = 10 * 60 * 1000L - + /** * 检查缓存是否有效 */ @@ -57,7 +58,7 @@ class AnnouncementService( val now = System.currentTimeMillis() return (now - cached.timestamp) < cacheExpiryTime } - + /** * 检查是否被限流 */ @@ -70,7 +71,7 @@ class AnnouncementService( val remaining = response.headers()["X-RateLimit-Remaining"] return remaining == "0" } - + /** * 获取 Issue 的 assignees 列表(通过 API 获取,带缓存) * @return Pair @@ -81,14 +82,14 @@ class AnnouncementService( logger.debug("使用缓存的 assignees") return Pair(cachedAssignees!!.data, true) } - + return try { val response = githubApi.getIssue( owner = repoOwner, repo = repoName, issueNumber = issueNumber ) - + // 如果被限流,使用缓存数据,不更新缓存 if (isRateLimited(response)) { logger.warn("GitHub API 被限流,使用缓存的 assignees(不更新缓存)") @@ -98,14 +99,14 @@ class AnnouncementService( // 如果没有缓存,使用默认值 return Pair(listOf("WrBug"), false) } - + val assignees = if (response.isSuccessful && response.body() != null) { response.body()!!.assignees.map { it.login } } else { logger.warn("获取 Issue assignees 失败,使用默认值: code=${response.code()}") listOf("WrBug") // 默认值 } - + // 更新缓存 cachedAssignees = CachedData(assignees, System.currentTimeMillis()) Pair(assignees, false) // 返回新数据,标记为未使用缓存 @@ -119,24 +120,24 @@ class AnnouncementService( Pair(listOf("WrBug"), false) // 默认值 } } - + /** * 获取 Issue 评论列表(带缓存) * @return Pair<评论列表, 是否使用了缓存> */ - private suspend fun getIssueComments(forceRefresh: Boolean = false): Pair, Boolean> { + private suspend fun getIssueComments(forceRefresh: Boolean = false): Pair, Boolean> { // 检查缓存 if (!forceRefresh && isCacheValid(cachedComments)) { logger.debug("使用缓存的评论列表") return Pair(cachedComments!!.data, true) } - + val response = githubApi.getIssueComments( owner = repoOwner, repo = repoName, issueNumber = issueNumber ) - + // 如果被限流,使用缓存数据,不更新缓存 if (isRateLimited(response)) { logger.warn("GitHub API 被限流,使用缓存的评论列表(不更新缓存)") @@ -146,7 +147,7 @@ class AnnouncementService( // 如果没有缓存,抛出异常 throw Exception("获取公告列表失败: GitHub API 被限流,且无缓存数据") } - + if (!response.isSuccessful || response.body() == null) { logger.error("获取 GitHub Issue 评论失败: code=${response.code()}, message=${response.message()}") // 如果缓存存在,使用缓存 @@ -156,14 +157,14 @@ class AnnouncementService( } throw Exception("获取公告列表失败: HTTP ${response.code()}") } - + val comments = response.body()!! - + // 更新缓存 cachedComments = CachedData(comments, System.currentTimeMillis()) return Pair(comments, false) // 返回新数据,标记为未使用缓存 } - + /** * 获取公告列表(最近10条) * @param forceRefresh 是否强制刷新缓存 @@ -174,12 +175,12 @@ class AnnouncementService( logger.debug("使用缓存的公告列表") return Result.success(cachedList!!.data) } - + return try { // 强制刷新时,先尝试获取新数据 val (assigneeList, assigneesFromCache) = getAssignees(forceRefresh) val (comments, commentsFromCache) = getIssueComments(forceRefresh) - + // 如果强制刷新时使用了缓存(被限流),直接返回缓存数据,不更新缓存 if (forceRefresh && (assigneesFromCache || commentsFromCache)) { logger.warn("强制刷新时被限流,返回缓存的公告列表(不更新缓存)") @@ -187,48 +188,47 @@ class AnnouncementService( return Result.success(cachedList!!.data) } } - + // 筛选条件: // 1. assignees 发布的评论 // 2. 排除 issueNumber 为 3703128976 的评论(从 issue_url 中提取) - val filteredComments = comments - .filter { comment -> - // 检查是否为 assignee - val isAssignee = assigneeList.contains(comment.user.login) - - // 检查是否应该排除(从 issue_url 中提取 issue ID) - val shouldExclude = comment.issue_url?.let { issueUrl -> - // issue_url 格式:https://api.github.com/repos/owner/repo/issues/3703128976 - // 提取最后的数字 - val issueId = issueUrl.split("/").lastOrNull() - issueId == excludedIssueId - } ?: false - - isAssignee && !shouldExclude - } + val filteredComments = comments.filter { comment -> + // 检查是否为 assignee + val isAssignee = assigneeList.contains(comment.user.login) + + // 检查是否应该排除(从 issue_url 中提取 issue ID) + val shouldExclude = comment.issue_url?.let { issueUrl -> + // issue_url 格式:https://api.github.com/repos/owner/repo/issues/3703128976 + // 提取最后的数字 + val issueId = issueUrl.split("/").lastOrNull() + issueId == excludedIssueId + } ?: false + + isAssignee && !shouldExclude + } .sortedByDescending { comment -> parseGitHubTime(comment.created_at) } - + val total = filteredComments.size val hasMore = total > 10 - + // 取前10条 val latest10 = filteredComments.take(10).map { comment -> toAnnouncementDto(comment) } - + val result = AnnouncementListResponse( list = latest10, hasMore = hasMore, total = total ) - + // 只有在数据正常返回时才更新缓存(不是从缓存获取的) if (!assigneesFromCache && !commentsFromCache) { cachedList = CachedData(result, System.currentTimeMillis()) } - + Result.success(result) } catch (e: Exception) { logger.error("获取公告列表异常: ${e.message}", e) @@ -240,7 +240,7 @@ class AnnouncementService( Result.failure(e) } } - + /** * 获取公告详情 * @param id 评论ID,如果为 null 则返回最新一条 @@ -249,19 +249,18 @@ class AnnouncementService( suspend fun getAnnouncementDetail(id: Long?, forceRefresh: Boolean = false): Result { return try { // 获取 assignees - val (assigneeList, assigneesFromCache) = getAssignees(forceRefresh) - + val (assigneeList, _) = getAssignees(forceRefresh) + // 获取评论列表 - val (comments, commentsFromCache) = getIssueComments(forceRefresh) - + val (comments, _) = getIssueComments(forceRefresh) + // 筛选条件: // 1. assignees 发布的评论 // 2. 排除 issueNumber 为 3703128976 的评论(从 issue_url 中提取) - val filteredComments = comments - .filter { comment -> + val filteredComments = comments.filter { comment -> // 检查是否为 assignee val isAssignee = assigneeList.contains(comment.user.login) - + // 检查是否应该排除(从 issue_url 中提取 issue ID) val shouldExclude = comment.issue_url?.let { issueUrl -> // issue_url 格式:https://api.github.com/repos/owner/repo/issues/3703128976 @@ -269,37 +268,37 @@ class AnnouncementService( val issueId = issueUrl.split("/").lastOrNull() issueId == excludedIssueId } ?: false - + isAssignee && !shouldExclude } .sortedByDescending { comment -> parseGitHubTime(comment.created_at) } - + val targetComment = if (id != null) { filteredComments.find { it.id == id } } else { filteredComments.firstOrNull() } - + if (targetComment == null) { return Result.failure(IllegalArgumentException("公告不存在")) } - + Result.success(toAnnouncementDto(targetComment)) } catch (e: Exception) { logger.error("获取公告详情异常: ${e.message}", e) Result.failure(e) } } - + /** * 将 GitHub 评论转换为 AnnouncementDto */ - private fun toAnnouncementDto(comment: com.wrbug.polymarketbot.api.GitHubCommentResponse): AnnouncementDto { + private fun toAnnouncementDto(comment: GitHubCommentResponse): AnnouncementDto { // 提取标题(第一行,移除 Markdown 格式) val title = extractTitle(comment.body) - + // 转换 reactions 数据 val reactions = comment.reactions?.let { r -> com.wrbug.polymarketbot.dto.ReactionsDto( @@ -314,7 +313,7 @@ class AnnouncementService( total = r.total_count ) } - + return AnnouncementDto( id = comment.id, title = title, @@ -326,7 +325,7 @@ class AnnouncementService( reactions = reactions ) } - + /** * 从评论内容中提取标题(第一行,移除 Markdown 格式) * 支持的 Markdown 格式: @@ -342,49 +341,49 @@ class AnnouncementService( if (body.isBlank()) { return "" } - + // 获取第一行 val firstLine = body.lines().firstOrNull()?.trim() ?: "" if (firstLine.isBlank()) { return "" } - + // 移除 Markdown 格式 var title = firstLine - + // 移除标题标记(# ## ### 等) title = title.replace(Regex("^#{1,6}\\s+"), "") - + // 移除粗体标记(**text** 或 __text__) title = title.replace(Regex("\\*\\*([^*]+)\\*\\*"), "$1") title = title.replace(Regex("__([^_]+)__"), "$1") - + // 移除斜体标记(*text* 或 _text_) title = title.replace(Regex("(? text) title = title.replace(Regex("^>\\s+"), "") - + // 移除列表标记(- * + 1. 等) title = title.replace(Regex("^[-*+]\\s+"), "") title = title.replace(Regex("^\\d+\\.\\s+"), "") - + return title.trim() } - + /** * 解析 GitHub 时间格式(ISO 8601)为时间戳(毫秒) * GitHub API 返回的时间格式:2025-12-07T14:30:00Z diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/AuthService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/auth/AuthService.kt similarity index 98% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/service/AuthService.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/service/auth/AuthService.kt index bcdd280..cd0a880 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/AuthService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/auth/AuthService.kt @@ -1,4 +1,4 @@ -package com.wrbug.polymarketbot.service +package com.wrbug.polymarketbot.service.auth import com.wrbug.polymarketbot.dto.CheckFirstUseResponse import com.wrbug.polymarketbot.dto.LoginResponse @@ -10,6 +10,7 @@ import jakarta.servlet.http.HttpServletRequest import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Value import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder +import com.wrbug.polymarketbot.service.common.RateLimitService import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/BlockchainService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/common/BlockchainService.kt similarity index 99% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/service/BlockchainService.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/service/common/BlockchainService.kt index 3edd188..d3513a7 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/BlockchainService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/common/BlockchainService.kt @@ -1,4 +1,4 @@ -package com.wrbug.polymarketbot.service +package com.wrbug.polymarketbot.service.common import com.wrbug.polymarketbot.api.EthereumRpcApi import com.wrbug.polymarketbot.api.JsonRpcRequest @@ -11,6 +11,7 @@ import com.wrbug.polymarketbot.util.RetrofitFactory import com.wrbug.polymarketbot.util.createClient import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Value +import com.wrbug.polymarketbot.service.system.RelayClientService import org.springframework.stereotype.Service import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/PolymarketApiKeyService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/common/PolymarketApiKeyService.kt similarity index 99% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/service/PolymarketApiKeyService.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/service/common/PolymarketApiKeyService.kt index ad43297..339634c 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/PolymarketApiKeyService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/common/PolymarketApiKeyService.kt @@ -1,4 +1,4 @@ -package com.wrbug.polymarketbot.service +package com.wrbug.polymarketbot.service.common import com.wrbug.polymarketbot.api.ApiKeyResponse import com.wrbug.polymarketbot.api.PolymarketClobApi diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/PolymarketClobService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/common/PolymarketClobService.kt similarity index 99% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/service/PolymarketClobService.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/service/common/PolymarketClobService.kt index f75a1cd..6cb5b9c 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/PolymarketClobService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/common/PolymarketClobService.kt @@ -1,4 +1,4 @@ -package com.wrbug.polymarketbot.service +package com.wrbug.polymarketbot.service.common import com.wrbug.polymarketbot.api.* import com.wrbug.polymarketbot.util.RetrofitFactory diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/RateLimitService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/common/RateLimitService.kt similarity index 97% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/service/RateLimitService.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/service/common/RateLimitService.kt index 053dbb2..ca0bf41 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/RateLimitService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/common/RateLimitService.kt @@ -1,4 +1,4 @@ -package com.wrbug.polymarketbot.service +package com.wrbug.polymarketbot.service.common import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Value diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/WebSocketSubscriptionService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/common/WebSocketSubscriptionService.kt similarity index 96% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/service/WebSocketSubscriptionService.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/service/common/WebSocketSubscriptionService.kt index 3013852..187a91b 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/WebSocketSubscriptionService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/common/WebSocketSubscriptionService.kt @@ -1,9 +1,11 @@ -package com.wrbug.polymarketbot.service +package com.wrbug.polymarketbot.service.common import com.wrbug.polymarketbot.dto.OrderPushMessage import com.wrbug.polymarketbot.dto.PositionPushMessage import com.wrbug.polymarketbot.dto.WebSocketMessage as WsMessage import com.wrbug.polymarketbot.dto.WebSocketMessageType +import com.wrbug.polymarketbot.service.accounts.PositionPushService +import com.wrbug.polymarketbot.service.copytrading.orders.OrderPushService import kotlinx.coroutines.* import org.slf4j.LoggerFactory import org.springframework.stereotype.Service diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/CopyTradingFilterService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/configs/CopyTradingFilterService.kt similarity index 98% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/service/CopyTradingFilterService.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/configs/CopyTradingFilterService.kt index e9dbbd1..452a831 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/CopyTradingFilterService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/configs/CopyTradingFilterService.kt @@ -1,4 +1,4 @@ -package com.wrbug.polymarketbot.service +package com.wrbug.polymarketbot.service.copytrading.configs import com.wrbug.polymarketbot.api.OrderbookResponse import com.wrbug.polymarketbot.entity.CopyTrading @@ -7,6 +7,7 @@ import com.wrbug.polymarketbot.util.lt import com.wrbug.polymarketbot.util.multi import com.wrbug.polymarketbot.util.toSafeBigDecimal import org.slf4j.LoggerFactory +import com.wrbug.polymarketbot.service.common.PolymarketClobService import org.springframework.stereotype.Service import java.math.BigDecimal diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/CopyTradingService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/configs/CopyTradingService.kt similarity index 98% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/service/CopyTradingService.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/configs/CopyTradingService.kt index 2ad2262..7ed6128 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/CopyTradingService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/configs/CopyTradingService.kt @@ -1,11 +1,14 @@ -package com.wrbug.polymarketbot.service +package com.wrbug.polymarketbot.service.copytrading.configs import com.wrbug.polymarketbot.dto.* +import com.wrbug.polymarketbot.entity.Account import com.wrbug.polymarketbot.entity.CopyTrading +import com.wrbug.polymarketbot.entity.Leader import com.wrbug.polymarketbot.repository.AccountRepository import com.wrbug.polymarketbot.repository.CopyTradingRepository import com.wrbug.polymarketbot.repository.CopyTradingTemplateRepository import com.wrbug.polymarketbot.repository.LeaderRepository +import com.wrbug.polymarketbot.service.copytrading.monitor.CopyTradingMonitorService import com.wrbug.polymarketbot.util.toSafeBigDecimal import org.slf4j.LoggerFactory import org.springframework.stereotype.Service @@ -339,7 +342,7 @@ class CopyTradingService( fun getAccountTemplates(accountId: Long): Result { return try { // 验证账户是否存在 - val account = accountRepository.findById(accountId).orElse(null) + accountRepository.findById(accountId).orElse(null) ?: return Result.failure(IllegalArgumentException("账户不存在")) val copyTradings = copyTradingRepository.findByAccountId(accountId) @@ -380,8 +383,8 @@ class CopyTradingService( */ private fun toDto( copyTrading: CopyTrading, - account: com.wrbug.polymarketbot.entity.Account, - leader: com.wrbug.polymarketbot.entity.Leader + account: Account, + leader: Leader ): CopyTradingDto { return CopyTradingDto( id = copyTrading.id!!, diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/FilteredOrderService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/configs/FilteredOrderService.kt similarity index 98% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/service/FilteredOrderService.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/configs/FilteredOrderService.kt index bbabbde..faf85d4 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/FilteredOrderService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/configs/FilteredOrderService.kt @@ -1,4 +1,4 @@ -package com.wrbug.polymarketbot.service +package com.wrbug.polymarketbot.service.copytrading.configs import com.wrbug.polymarketbot.dto.FilteredOrderDto import com.wrbug.polymarketbot.dto.FilteredOrderListRequest diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/LeaderService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/leaders/LeaderService.kt similarity index 99% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/service/LeaderService.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/leaders/LeaderService.kt index 32d3670..025791b 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/LeaderService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/leaders/LeaderService.kt @@ -1,4 +1,4 @@ -package com.wrbug.polymarketbot.service +package com.wrbug.polymarketbot.service.copytrading.leaders import com.wrbug.polymarketbot.dto.* import com.wrbug.polymarketbot.entity.Leader diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/CopyTradingMonitorService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/monitor/CopyTradingMonitorService.kt similarity index 98% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/service/CopyTradingMonitorService.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/monitor/CopyTradingMonitorService.kt index a65815d..b622e16 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/CopyTradingMonitorService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/monitor/CopyTradingMonitorService.kt @@ -1,4 +1,4 @@ -package com.wrbug.polymarketbot.service +package com.wrbug.polymarketbot.service.copytrading.monitor import com.wrbug.polymarketbot.entity.CopyTrading import com.wrbug.polymarketbot.entity.Leader diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/CopyTradingPollingService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/monitor/CopyTradingPollingService.kt similarity index 97% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/service/CopyTradingPollingService.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/monitor/CopyTradingPollingService.kt index e5f4a37..e5cbef1 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/CopyTradingPollingService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/monitor/CopyTradingPollingService.kt @@ -1,4 +1,4 @@ -package com.wrbug.polymarketbot.service +package com.wrbug.polymarketbot.service.copytrading.monitor import com.wrbug.polymarketbot.api.TradeResponse import com.wrbug.polymarketbot.api.UserActivityResponse @@ -9,6 +9,7 @@ import jakarta.annotation.PreDestroy import kotlinx.coroutines.* import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Value +import com.wrbug.polymarketbot.service.copytrading.statistics.CopyOrderTrackingService import org.springframework.stereotype.Service import retrofit2.Response import java.util.concurrent.ConcurrentHashMap @@ -72,7 +73,7 @@ class CopyTradingPollingService( return } - val leaderId = leader.id!! + val leaderId = leader.id monitoredLeaders[leaderId] = leader // 初始化缓存的交易ID集合 cachedTradeIds[leaderId] = mutableSetOf() @@ -178,7 +179,7 @@ class CopyTradingPollingService( return } - val leaderId = leader.id!! + val leaderId = leader.id val leaderAddress = leader.leaderAddress try { diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/CopyTradingWebSocketService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/monitor/CopyTradingWebSocketService.kt similarity index 98% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/service/CopyTradingWebSocketService.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/monitor/CopyTradingWebSocketService.kt index de24cbd..f3ff981 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/CopyTradingWebSocketService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/monitor/CopyTradingWebSocketService.kt @@ -1,4 +1,4 @@ -package com.wrbug.polymarketbot.service +package com.wrbug.polymarketbot.service.copytrading.monitor import com.google.gson.Gson import com.google.gson.JsonObject @@ -11,6 +11,7 @@ import jakarta.annotation.PreDestroy import kotlinx.coroutines.* import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Value +import com.wrbug.polymarketbot.service.copytrading.statistics.CopyOrderTrackingService import org.springframework.stereotype.Service import java.util.concurrent.ConcurrentHashMap @@ -65,7 +66,7 @@ class CopyTradingWebSocketService( return } - val leaderId = leader.id!! + val leaderId = leader.id val leaderAddress = leader.leaderAddress.lowercase() leaderAddresses[leaderId] = leaderAddress diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/OrderPushService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/orders/OrderPushService.kt similarity index 94% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/service/OrderPushService.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/orders/OrderPushService.kt index e77f202..e1f8427 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/OrderPushService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/orders/OrderPushService.kt @@ -1,6 +1,7 @@ -package com.wrbug.polymarketbot.service +package com.wrbug.polymarketbot.service.copytrading.orders import com.fasterxml.jackson.databind.ObjectMapper +import com.wrbug.polymarketbot.api.MarketResponse import com.wrbug.polymarketbot.dto.OrderDetailDto import com.wrbug.polymarketbot.dto.OrderMessageDto import com.wrbug.polymarketbot.dto.OrderPushMessage @@ -13,6 +14,11 @@ import jakarta.annotation.PreDestroy import kotlinx.coroutines.* import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Value +import com.wrbug.polymarketbot.service.common.PolymarketClobService +import com.wrbug.polymarketbot.util.CryptoUtils +import com.wrbug.polymarketbot.repository.CopyOrderTrackingRepository +import com.wrbug.polymarketbot.repository.CopyTradingRepository +import com.wrbug.polymarketbot.repository.LeaderRepository import org.springframework.stereotype.Service import java.util.concurrent.ConcurrentHashMap @@ -26,10 +32,10 @@ class OrderPushService( private val objectMapper: ObjectMapper, private val clobService: PolymarketClobService, private val retrofitFactory: RetrofitFactory, // 用于创建 Gamma API 客户端(不需要认证) - private val cryptoUtils: com.wrbug.polymarketbot.util.CryptoUtils, - private val copyOrderTrackingRepository: com.wrbug.polymarketbot.repository.CopyOrderTrackingRepository? = null, // 可选,避免循环依赖 - private val copyTradingRepository: com.wrbug.polymarketbot.repository.CopyTradingRepository? = null, // 可选,避免循环依赖 - private val leaderRepository: com.wrbug.polymarketbot.repository.LeaderRepository? = null // 可选,避免循环依赖 + private val cryptoUtils: CryptoUtils, + private val copyOrderTrackingRepository: CopyOrderTrackingRepository? = null, // 可选,避免循环依赖 + private val copyTradingRepository: CopyTradingRepository? = null, // 可选,避免循环依赖 + private val leaderRepository: LeaderRepository? = null // 可选,避免循环依赖 ) { private val logger = LoggerFactory.getLogger(OrderPushService::class.java) @@ -152,9 +158,9 @@ class OrderPushService( return account.apiKey != null && account.apiSecret != null && account.apiPassphrase != null && - account.apiKey!!.isNotBlank() && - account.apiSecret!!.isNotBlank() && - account.apiPassphrase!!.isNotBlank() + account.apiKey.isNotBlank() && + account.apiSecret.isNotBlank() && + account.apiPassphrase.isNotBlank() } /** @@ -378,7 +384,7 @@ class OrderPushService( /** * 获取订单详情 - * 通过 PolymarketClobService 获取订单详情 + * 通过 com.wrbug.polymarketbot.service.common.PolymarketClobService 获取订单详情 */ private suspend fun fetchOrderDetail( account: Account, @@ -391,7 +397,7 @@ class OrderPushService( return null } - // 通过 PolymarketClobService 获取订单详情(需要 L2 认证) + // 通过 com.wrbug.polymarketbot.service.common.PolymarketClobService 获取订单详情(需要 L2 认证) // 解密 API 凭证 val apiSecret = try { decryptApiSecret(account) @@ -453,7 +459,7 @@ class OrderPushService( * 使用 /markets 接口,通过 condition_ids 查询参数获取市场信息 * 订单返回的 market 字段是 16 进制的 condition ID(如 "0x...") */ - private suspend fun fetchMarketInfo(conditionId: String): com.wrbug.polymarketbot.api.MarketResponse? { + private suspend fun fetchMarketInfo(conditionId: String): MarketResponse? { return try { // 创建 Gamma API 客户端(公开 API,不需要认证) val gammaApi = retrofitFactory.createGammaApi() diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/OrderSigningService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/orders/OrderSigningService.kt similarity index 98% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/service/OrderSigningService.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/orders/OrderSigningService.kt index 9da1509..90a0dde 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/OrderSigningService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/orders/OrderSigningService.kt @@ -1,4 +1,4 @@ -package com.wrbug.polymarketbot.service +package com.wrbug.polymarketbot.service.copytrading.orders import com.wrbug.polymarketbot.api.SignedOrderObject import com.wrbug.polymarketbot.util.toSafeBigDecimal @@ -77,10 +77,6 @@ class OrderSigningService { ): OrderAmounts { val sizeDecimal = size.toSafeBigDecimal() val priceDecimal = price.toSafeBigDecimal() - - // 舍入价格 - val roundedPrice = roundNormal(priceDecimal, roundConfig.price) - if (side.uppercase() == "BUY") { // BUY: makerAmount = price * size (USDC), takerAmount = size (shares) // makerAmount 是 USDC 金额,最多 2 位小数 diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/CopyOrderTrackingService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/statistics/CopyOrderTrackingService.kt similarity index 98% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/service/CopyOrderTrackingService.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/statistics/CopyOrderTrackingService.kt index b577101..6bfeb97 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/CopyOrderTrackingService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/statistics/CopyOrderTrackingService.kt @@ -1,6 +1,7 @@ -package com.wrbug.polymarketbot.service +package com.wrbug.polymarketbot.service.copytrading.statistics import com.wrbug.polymarketbot.api.NewOrderRequest +import com.wrbug.polymarketbot.api.PolymarketClobApi import com.wrbug.polymarketbot.api.TradeResponse import com.wrbug.polymarketbot.entity.* import com.wrbug.polymarketbot.repository.* @@ -9,6 +10,11 @@ import com.wrbug.polymarketbot.util.* import kotlinx.coroutines.* import org.slf4j.LoggerFactory import org.springframework.dao.DataIntegrityViolationException +import com.wrbug.polymarketbot.service.copytrading.configs.CopyTradingFilterService +import com.wrbug.polymarketbot.service.copytrading.orders.OrderSigningService +import com.wrbug.polymarketbot.service.common.BlockchainService +import com.wrbug.polymarketbot.service.system.TelegramNotificationService +import com.wrbug.polymarketbot.util.CryptoUtils import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional import java.math.BigDecimal @@ -33,7 +39,7 @@ class CopyOrderTrackingService( private val orderSigningService: OrderSigningService, private val blockchainService: BlockchainService, private val retrofitFactory: RetrofitFactory, - private val cryptoUtils: com.wrbug.polymarketbot.util.CryptoUtils, + private val cryptoUtils: CryptoUtils, private val telegramNotificationService: TelegramNotificationService? = null // 可选,避免循环依赖 ) { @@ -381,7 +387,7 @@ class CopyOrderTrackingService( side = "BUY", price = buyPrice.toString(), size = finalBuyQuantity.toString(), - owner = account.apiKey!!, + owner = account.apiKey, copyTradingId = copyTrading.id!!, tradeId = trade.id ) @@ -759,7 +765,7 @@ class CopyOrderTrackingService( // 这样可以快速响应 Leader 的交易,避免订单长期挂单导致价格不匹配 val orderRequest = NewOrderRequest( order = signedOrder, - owner = account.apiKey!!, + owner = account.apiKey, orderType = "FAK", // Fill-And-Kill deferExec = false ) @@ -782,8 +788,8 @@ class CopyOrderTrackingService( side = "SELL", price = sellPrice.toString(), size = totalMatched.toString(), - owner = account.apiKey!!, - copyTradingId = copyTrading.id!!, + owner = account.apiKey, + copyTradingId = copyTrading.id, tradeId = leaderSellTrade.id ) @@ -830,11 +836,11 @@ class CopyOrderTrackingService( val totalRealizedPnl = matchDetails.sumOf { it.realizedPnl.toSafeBigDecimal() } val matchRecord = SellMatchRecord( - copyTradingId = copyTrading.id!!, + copyTradingId = copyTrading.id, sellOrderId = realSellOrderId, // 使用真实订单ID leaderSellTradeId = leaderSellTrade.id, marketId = leaderSellTrade.market, - side = leaderSellTrade.outcomeIndex?.toString() ?: "0", // 使用outcomeIndex作为side(兼容旧数据) + side = leaderSellTrade.outcomeIndex.toString(), // 使用outcomeIndex作为side(兼容旧数据) outcomeIndex = leaderSellTrade.outcomeIndex, // 新增字段 totalMatchedQuantity = totalMatched, sellPrice = sellPrice, @@ -857,7 +863,7 @@ class CopyOrderTrackingService( * 注意:重试时会重新生成salt并重新签名,确保每次重试都是新的订单 */ private suspend fun createOrderWithRetry( - clobApi: com.wrbug.polymarketbot.api.PolymarketClobApi, + clobApi: PolymarketClobApi, privateKey: String, makerAddress: String, tokenId: String, @@ -914,7 +920,7 @@ class CopyOrderTrackingService( delay(1000) // 重试前等待1秒 continue } - return Result.failure(lastError!!) + return Result.failure(lastError) } val response = orderResponse.body()!! @@ -928,7 +934,7 @@ class CopyOrderTrackingService( delay(1000) // 重试前等待1秒 continue } - return Result.failure(lastError!!) + return Result.failure(lastError) } // 成功 @@ -943,7 +949,7 @@ class CopyOrderTrackingService( delay(1000) // 重试前等待1秒 continue } - return Result.failure(lastError!!) + return Result.failure(lastError) } } @@ -1105,7 +1111,7 @@ class CopyOrderTrackingService( } // 2. 检查每日亏损限制(需要计算今日已实现盈亏) - val todaySellRecords = sellMatchRecordRepository.findByCopyTradingId(copyTrading.id!!) + val todaySellRecords = sellMatchRecordRepository.findByCopyTradingId(copyTrading.id) .filter { it.createdAt >= todayStart } val todayRealizedPnl = todaySellRecords.sumOf { it.totalRealizedPnl.toSafeBigDecimal() } diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/CopyTradingStatisticsService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/statistics/CopyTradingStatisticsService.kt similarity index 91% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/service/CopyTradingStatisticsService.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/statistics/CopyTradingStatisticsService.kt index df837d9..785154a 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/CopyTradingStatisticsService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/statistics/CopyTradingStatisticsService.kt @@ -1,4 +1,4 @@ -package com.wrbug.polymarketbot.service +package com.wrbug.polymarketbot.service.copytrading.statistics import com.wrbug.polymarketbot.dto.* import com.wrbug.polymarketbot.entity.* @@ -13,6 +13,8 @@ import org.slf4j.LoggerFactory import org.springframework.data.domain.PageRequest import org.springframework.data.domain.Pageable import org.springframework.data.domain.Sort +import com.wrbug.polymarketbot.service.accounts.AccountService +import com.wrbug.polymarketbot.service.common.BlockchainService import org.springframework.stereotype.Service import java.math.BigDecimal import java.math.RoundingMode @@ -30,7 +32,7 @@ class CopyTradingStatisticsService( private val accountRepository: AccountRepository, private val leaderRepository: LeaderRepository, private val accountService: AccountService, - private val blockchainService: com.wrbug.polymarketbot.service.BlockchainService + private val blockchainService: BlockchainService ) { private val logger = LoggerFactory.getLogger(CopyTradingStatisticsService::class.java) @@ -69,7 +71,10 @@ class CopyTradingStatisticsService( // 9. 计算未实现盈亏(使用链上实际持仓,而不是 remainingQuantity) val unrealizedPnl = calculateUnrealizedPnl(buyOrders, currentPrice, actualPositions) - // 9. 构建响应 + // 10. 计算持仓价值(使用链上实际持仓和当前价格) + val positionValue = calculatePositionValue(buyOrders, currentPrice, actualPositions) + + // 11. 构建响应 val response = CopyTradingStatisticsResponse( copyTradingId = copyTradingId, accountId = copyTrading.accountId, @@ -85,7 +90,7 @@ class CopyTradingStatisticsService( totalSellOrders = statistics.totalSellOrders, totalSellAmount = statistics.totalSellAmount, currentPositionQuantity = statistics.currentPositionQuantity, - currentPositionValue = calculatePositionValue(statistics.currentPositionQuantity, currentPrice), + currentPositionValue = positionValue, totalRealizedPnl = statistics.totalRealizedPnl, totalUnrealizedPnl = unrealizedPnl, totalPnl = (statistics.totalRealizedPnl.toSafeBigDecimal().add(unrealizedPnl.toSafeBigDecimal())).toString(), @@ -105,7 +110,7 @@ class CopyTradingStatisticsService( fun getOrderList(request: OrderTrackingRequest): Result { return try { // 1. 验证跟单关系 - val copyTrading = copyTradingRepository.findById(request.copyTradingId).orElse(null) + copyTradingRepository.findById(request.copyTradingId).orElse(null) ?: return Result.failure(IllegalArgumentException("跟单关系不存在: ${request.copyTradingId}")) // 2. 根据类型查询 @@ -354,7 +359,7 @@ class CopyTradingStatisticsService( * 获取链上实际持仓 * 按 (marketId, outcomeIndex) 组合返回实际持仓数量 */ - private suspend fun getActualPositions(account: com.wrbug.polymarketbot.entity.Account?): Map { + private suspend fun getActualPositions(account: Account?): Map { val positions = mutableMapOf() if (account == null || account.proxyAddress.isBlank()) { @@ -424,11 +429,41 @@ class CopyTradingStatisticsService( /** * 计算持仓价值 + * 使用链上实际持仓数量和当前市场价格计算 */ - private fun calculatePositionValue(positionQuantity: String, currentPrices: Map): String { - // 这里简化处理,实际应该根据每个市场的持仓分别计算 - // 暂时返回0,因为需要知道每个市场的持仓数量 - return "0" + private fun calculatePositionValue( + buyOrders: List, + currentPrices: Map, + actualPositions: Map + ): String { + var totalPositionValue = BigDecimal.ZERO + + for (order in buyOrders) { + // 如果没有 outcomeIndex,跳过(无法确定价格和持仓) + if (order.outcomeIndex == null) { + logger.warn("订单缺少 outcomeIndex,跳过持仓价值计算: orderId=${order.buyOrderId}, marketId=${order.marketId}") + continue + } + + // 使用 "marketId:outcomeIndex" 作为 key + val key = "${order.marketId}:${order.outcomeIndex}" + + // 获取链上实际持仓数量(如果存在),否则使用 remainingQuantity + val actualQty = actualPositions[key] ?: order.remainingQuantity.toSafeBigDecimal() + + // 如果实际持仓 <= 0,说明已全部卖出(包括手动卖出),跳过持仓价值计算 + if (actualQty.lte(BigDecimal.ZERO)) continue + + // 获取当前市场价格 + val currentPrice = currentPrices[key]?.toSafeBigDecimal() + ?: continue // 如果没有当前价格,跳过 + + // 计算持仓价值:持仓数量 × 当前价格 + val positionValue = actualQty.multi(currentPrice) + totalPositionValue = totalPositionValue.add(positionValue) + } + + return totalPositionValue.toString() } /** diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/CopyTradingTemplateService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/templates/CopyTradingTemplateService.kt similarity index 99% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/service/CopyTradingTemplateService.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/templates/CopyTradingTemplateService.kt index f745dff..18918b3 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/CopyTradingTemplateService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/templates/CopyTradingTemplateService.kt @@ -1,4 +1,4 @@ -package com.wrbug.polymarketbot.service +package com.wrbug.polymarketbot.service.copytrading.templates import com.wrbug.polymarketbot.dto.* import com.wrbug.polymarketbot.entity.CopyTradingTemplate diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/ApiHealthCheckService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/system/ApiHealthCheckService.kt similarity index 98% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/service/ApiHealthCheckService.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/service/system/ApiHealthCheckService.kt index 26bf7a0..e619c80 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/ApiHealthCheckService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/system/ApiHealthCheckService.kt @@ -1,4 +1,4 @@ -package com.wrbug.polymarketbot.service +package com.wrbug.polymarketbot.service.system import com.wrbug.polymarketbot.dto.ApiHealthCheckDto import com.wrbug.polymarketbot.dto.ApiHealthCheckResponse @@ -12,6 +12,8 @@ import org.springframework.beans.BeansException import org.springframework.context.ApplicationContext import org.springframework.context.ApplicationContextAware import org.springframework.beans.factory.annotation.Value +import com.wrbug.polymarketbot.service.copytrading.orders.OrderPushService +import com.wrbug.polymarketbot.service.copytrading.monitor.CopyTradingWebSocketService import org.springframework.stereotype.Service import java.util.concurrent.TimeUnit diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/NotificationConfigService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/system/NotificationConfigService.kt similarity index 99% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/service/NotificationConfigService.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/service/system/NotificationConfigService.kt index 90699e6..57db4d1 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/NotificationConfigService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/system/NotificationConfigService.kt @@ -1,4 +1,4 @@ -package com.wrbug.polymarketbot.service +package com.wrbug.polymarketbot.service.system import com.fasterxml.jackson.databind.ObjectMapper import com.wrbug.polymarketbot.dto.* diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/ProxyConfigService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/system/ProxyConfigService.kt similarity index 98% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/service/ProxyConfigService.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/service/system/ProxyConfigService.kt index 046037a..4e2430c 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/ProxyConfigService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/system/ProxyConfigService.kt @@ -1,8 +1,10 @@ -package com.wrbug.polymarketbot.service +package com.wrbug.polymarketbot.service.system import com.wrbug.polymarketbot.dto.* import com.wrbug.polymarketbot.entity.ProxyConfig import com.wrbug.polymarketbot.repository.ProxyConfigRepository +import com.wrbug.polymarketbot.service.copytrading.monitor.CopyTradingWebSocketService +import com.wrbug.polymarketbot.service.copytrading.orders.OrderPushService import com.wrbug.polymarketbot.util.ProxyConfigProvider import com.wrbug.polymarketbot.util.TrustAllHostnameVerifier import com.wrbug.polymarketbot.util.createSSLSocketFactory diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/RelayClientService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/system/RelayClientService.kt similarity index 99% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/service/RelayClientService.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/service/system/RelayClientService.kt index 5b72f65..8c30a59 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/RelayClientService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/system/RelayClientService.kt @@ -1,4 +1,4 @@ -package com.wrbug.polymarketbot.service +package com.wrbug.polymarketbot.service.system import com.wrbug.polymarketbot.api.BuilderRelayerApi import com.wrbug.polymarketbot.api.EthereumRpcApi @@ -802,10 +802,10 @@ class RelayClientService( safeTxs: List ): Result { // 批量执行:将多个交易合并为一个 execTransaction 调用 - // 当前实现:委托给 BlockchainService + // 当前实现:委托给 com.wrbug.polymarketbot.service.common.BlockchainService return Result.failure( UnsupportedOperationException( - "批量 Gasless 执行暂未实现。请使用 BlockchainService.redeemPositions() 方法。" + "批量 Gasless 执行暂未实现。请使用 com.wrbug.polymarketbot.service.common.BlockchainService.redeemPositions() 方法。" ) ) } diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/SystemConfigService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/system/SystemConfigService.kt similarity index 99% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/service/SystemConfigService.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/service/system/SystemConfigService.kt index 0beef4b..5a8fe57 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/SystemConfigService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/system/SystemConfigService.kt @@ -1,4 +1,4 @@ -package com.wrbug.polymarketbot.service +package com.wrbug.polymarketbot.service.system import com.wrbug.polymarketbot.dto.SystemConfigDto import com.wrbug.polymarketbot.dto.SystemConfigUpdateRequest diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/TelegramNotificationService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/system/TelegramNotificationService.kt similarity index 99% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/service/TelegramNotificationService.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/service/system/TelegramNotificationService.kt index 7722b40..2f45e05 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/TelegramNotificationService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/system/TelegramNotificationService.kt @@ -1,7 +1,8 @@ -package com.wrbug.polymarketbot.service +package com.wrbug.polymarketbot.service.system import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.ObjectMapper +import com.wrbug.polymarketbot.api.PolymarketClobApi import com.wrbug.polymarketbot.dto.NotificationConfigData import com.wrbug.polymarketbot.dto.TelegramConfigData import com.wrbug.polymarketbot.util.createClient @@ -65,7 +66,7 @@ class TelegramNotificationService( side: String, accountName: String? = null, walletAddress: String? = null, - clobApi: com.wrbug.polymarketbot.api.PolymarketClobApi? = null, + clobApi: PolymarketClobApi? = null, apiKey: String? = null, apiSecret: String? = null, apiPassphrase: String? = null, diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/UserService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/system/UserService.kt similarity index 99% rename from backend/src/main/kotlin/com/wrbug/polymarketbot/service/UserService.kt rename to backend/src/main/kotlin/com/wrbug/polymarketbot/service/system/UserService.kt index d95406e..70daebe 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/UserService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/system/UserService.kt @@ -1,4 +1,4 @@ -package com.wrbug.polymarketbot.service +package com.wrbug.polymarketbot.service.system import com.wrbug.polymarketbot.dto.UserCreateRequest import com.wrbug.polymarketbot.dto.UserDto diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/websocket/UnifiedWebSocketHandler.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/websocket/UnifiedWebSocketHandler.kt index 4d9c9d8..d002764 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/websocket/UnifiedWebSocketHandler.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/websocket/UnifiedWebSocketHandler.kt @@ -3,7 +3,7 @@ package com.wrbug.polymarketbot.websocket import com.fasterxml.jackson.databind.ObjectMapper import com.wrbug.polymarketbot.dto.WebSocketMessage as WsMessage import com.wrbug.polymarketbot.dto.WebSocketMessageType -import com.wrbug.polymarketbot.service.WebSocketSubscriptionService +import com.wrbug.polymarketbot.service.common.WebSocketSubscriptionService import jakarta.annotation.PostConstruct import jakarta.annotation.PreDestroy import kotlinx.coroutines.* diff --git a/frontend/src/services/api.ts b/frontend/src/services/api.ts index 8a6d04c..dcfb666 100644 --- a/frontend/src/services/api.ts +++ b/frontend/src/services/api.ts @@ -145,31 +145,31 @@ export const apiService = { * 获取用户列表 */ list: () => - apiClient.post>('/users/list', {}), + apiClient.post>('/system/users/list', {}), /** * 创建用户 */ create: (data: { username: string; password: string }) => - apiClient.post>('/users/create', data), + apiClient.post>('/system/users/create', data), /** * 更新用户密码 */ updatePassword: (data: { userId: number; newPassword: string }) => - apiClient.post>('/users/update-password', data), + apiClient.post>('/system/users/update-password', data), /** * 删除用户 */ delete: (data: { userId: number }) => - apiClient.post>('/users/delete', data), + apiClient.post>('/system/users/delete', data), /** * 用户修改自己的密码 */ updateOwnPassword: (data: { newPassword: string }) => - apiClient.post>('/users/update-own-password', data) + apiClient.post>('/system/users/update-own-password', data) }, /** @@ -203,61 +203,61 @@ export const apiService = { * 导入账户 */ import: (data: any) => - apiClient.post>('/copy-trading/accounts/import', data), + apiClient.post>('/accounts/import', data), /** * 更新账户 */ update: (data: any) => - apiClient.post>('/copy-trading/accounts/update', data), + apiClient.post>('/accounts/update', data), /** * 删除账户 */ delete: (data: { accountId: number }) => - apiClient.post>('/copy-trading/accounts/delete', data), + apiClient.post>('/accounts/delete', data), /** * 查询账户列表 */ list: () => - apiClient.post>('/copy-trading/accounts/list', {}), + apiClient.post>('/accounts/list', {}), /** * 查询账户详情 */ detail: (data: { accountId?: number }) => - apiClient.post>('/copy-trading/accounts/detail', data), + apiClient.post>('/accounts/detail', data), /** * 查询账户余额 */ balance: (data: { accountId?: number }) => - apiClient.post>('/copy-trading/accounts/balance', data), + apiClient.post>('/accounts/balance', data), /** * 查询所有账户的仓位列表 */ positionsList: () => - apiClient.post>('/copy-trading/accounts/positions/list', {}), + apiClient.post>('/accounts/positions/list', {}), /** * 卖出仓位 */ sellPosition: (data: any) => - apiClient.post>('/copy-trading/accounts/positions/sell', data), + apiClient.post>('/accounts/positions/sell', data), /** * 获取可赎回仓位统计 */ getRedeemableSummary: (data: { accountId?: number }) => - apiClient.post>('/copy-trading/accounts/positions/redeemable-summary', data), + apiClient.post>('/accounts/positions/redeemable-summary', data), /** * 赎回仓位 */ redeemPositions: (data: any) => - apiClient.post>('/copy-trading/accounts/positions/redeem', data), + apiClient.post>('/accounts/positions/redeem', data), }, @@ -269,13 +269,13 @@ export const apiService = { * 获取市场价格(通过 Gamma API) */ getMarketPrice: (data: { marketId: string; outcomeIndex?: number }) => - apiClient.post>('/copy-trading/markets/price', data), + apiClient.post>('/markets/price', data), /** * 获取最新价(从订单表获取,供前端下单时显示) */ getLatestPrice: (data: { tokenId: string }) => - apiClient.post>('/copy-trading/markets/latest-price', data) + apiClient.post>('/markets/latest-price', data) }, /** @@ -365,37 +365,37 @@ export const apiService = { * 2. 不提供 templateId:手动输入所有配置参数 */ create: (data: any) => - apiClient.post>('/copy-trading/create', data), + apiClient.post>('/copy-trading/configs/create', data), /** * 更新跟单配置 */ update: (data: any) => - apiClient.post>('/copy-trading/update', data), + apiClient.post>('/copy-trading/configs/update', data), /** * 查询跟单列表 */ list: (data: { accountId?: number; leaderId?: number; enabled?: boolean } = {}) => - apiClient.post>('/copy-trading/list', data), + apiClient.post>('/copy-trading/configs/list', data), /** * 更新跟单状态(兼容旧接口) */ updateStatus: (data: { copyTradingId: number; enabled: boolean }) => - apiClient.post>('/copy-trading/update-status', data), + apiClient.post>('/copy-trading/configs/update-status', data), /** * 删除跟单 */ delete: (data: { copyTradingId: number }) => - apiClient.post>('/copy-trading/delete', data), + apiClient.post>('/copy-trading/configs/delete', data), /** * 查询钱包绑定的跟单配置(兼容旧接口) */ getAccountTemplates: (data: { accountId: number }) => - apiClient.post>('/copy-trading/account-templates', data), + apiClient.post>('/copy-trading/configs/account-templates', data), /** * 查询被过滤订单列表 @@ -408,7 +408,7 @@ export const apiService = { startTime?: number endTime?: number }) => - apiClient.post>('/copy-trading/filtered-orders', data) + apiClient.post>('/copy-trading/configs/filtered-orders', data) }, /** @@ -476,13 +476,13 @@ export const apiService = { * 获取当前代理配置 */ get: () => - apiClient.post>('/proxy-config/get', {}), + apiClient.post>('/system/proxy/get', {}), /** * 获取所有代理配置 */ list: () => - apiClient.post>('/proxy-config/list', {}), + apiClient.post>('/system/proxy/list', {}), /** * 保存 HTTP 代理配置 @@ -494,7 +494,7 @@ export const apiService = { username?: string password?: string }) => - apiClient.post>('/proxy-config/http/save', data), + apiClient.post>('/system/proxy/http/save', data), /** * 检查代理是否可用 @@ -504,13 +504,13 @@ export const apiService = { success: boolean message: string responseTime?: number - }>>('/proxy-config/check', {}), + }>>('/system/proxy/check', {}), /** * 删除代理配置 */ delete: (data: { id: number }) => - apiClient.post>('/proxy-config/delete', data), + apiClient.post>('/system/proxy/delete', data), /** * 检查所有 API 的健康状态 @@ -524,7 +524,7 @@ export const apiService = { message: string responseTime?: number }> - }>>('/proxy-config/api-health-check', {}) + }>>('/system/proxy/api-health-check', {}) }, /** @@ -535,49 +535,49 @@ export const apiService = { * 获取配置列表 */ list: (data?: { type?: string }) => - apiClient.post>('/notifications/configs/list', data || {}), + apiClient.post>('/system/notifications/configs/list', data || {}), /** * 获取配置详情 */ detail: (data: { id: number }) => - apiClient.post>('/notifications/configs/detail', data), + apiClient.post>('/system/notifications/configs/detail', data), /** * 创建配置 */ create: (data: NotificationConfigRequest) => - apiClient.post>('/notifications/configs/create', data), + apiClient.post>('/system/notifications/configs/create', data), /** * 更新配置 */ update: (data: NotificationConfigUpdateRequest) => - apiClient.post>('/notifications/configs/update', data), + apiClient.post>('/system/notifications/configs/update', data), /** * 更新启用状态 */ updateEnabled: (data: { id: number; enabled: boolean }) => - apiClient.post>('/notifications/configs/update-enabled', data), + apiClient.post>('/system/notifications/configs/update-enabled', data), /** * 删除配置 */ delete: (data: { id: number }) => - apiClient.post>('/notifications/configs/delete', data), + apiClient.post>('/system/notifications/configs/delete', data), /** * 测试通知 */ test: (data?: { message?: string }) => - apiClient.post>('/notifications/test', data || {}), + apiClient.post>('/system/notifications/test', data || {}), /** * 获取 Telegram Chat IDs */ getTelegramChatIds: (data: { botToken: string }) => - apiClient.post>('/notifications/telegram/get-chat-ids', data) + apiClient.post>('/system/notifications/telegram/get-chat-ids', data) }, /**