feat: 添加关键字过滤功能并优化市场 slug 处理

主要变更:
1. 关键字过滤功能
   - 添加关键字过滤模式(白名单/黑名单/禁用)
   - 支持关键字列表配置(JSON 存储)
   - 实现关键字匹配逻辑(不区分大小写)
   - 数据库迁移:V20__add_keyword_filter.sql

2. 市场 slug 优化
   - 区分显示用 slug 和跳转用 eventSlug
   - 添加 event_slug 字段到 markets 表(V21__add_event_slug_to_markets.sql)
   - 从 events[0].slug 获取跳转用的 slug 并存入数据库
   - 减少 API 请求,提高性能

3. UI 优化
   - 将创建/编辑跟单配置改为 Modal 方式
   - 删除独立的 CopyTradingAdd 和 CopyTradingEdit 页面
   - 更新前端跳转逻辑,优先使用 eventSlug

4. API 响应优化
   - 更新 MarketResponse 添加 events 字段
   - 统一从 events[0].slug 获取跳转用的 slug
   - 更新所有相关服务使用新的 slug 获取逻辑
This commit is contained in:
WrBug
2026-01-08 17:47:00 +08:00
parent 3d5a923caf
commit 9ed5190bfe
33 changed files with 738 additions and 773 deletions
+19 -5
View File
@@ -210,6 +210,9 @@ export interface CopyTrading {
// 最大仓位配置
maxPositionValue?: string // 最大仓位金额(USDC),NULL表示不启用
maxPositionCount?: number // 最大仓位数量,NULL表示不启用
// 关键字过滤配置
keywordFilterMode?: 'DISABLED' | 'WHITELIST' | 'BLACKLIST' // 关键字过滤模式
keywords?: string[] // 关键字列表,当keywordFilterMode为DISABLED时为null
// 新增配置字段
configName?: string // 配置名(可选,但提供时必须非空)
pushFailedOrders: boolean // 推送失败订单(默认关闭)
@@ -256,6 +259,9 @@ export interface CopyTradingCreateRequest {
// 最大仓位配置
maxPositionValue?: string // 最大仓位金额(USDC),NULL表示不启用
maxPositionCount?: number // 最大仓位数量,NULL表示不启用
// 关键字过滤配置
keywordFilterMode?: 'DISABLED' | 'WHITELIST' | 'BLACKLIST' // 关键字过滤模式
keywords?: string[] // 关键字列表,当keywordFilterMode为DISABLED时为null
// 新增配置字段
configName?: string // 配置名(可选,但提供时必须非空)
pushFailedOrders?: boolean // 推送失败订单(可选)
@@ -290,6 +296,9 @@ export interface CopyTradingUpdateRequest {
// 最大仓位配置
maxPositionValue?: string // 最大仓位金额(USDC),NULL表示不启用
maxPositionCount?: number // 最大仓位数量,NULL表示不启用
// 关键字过滤配置
keywordFilterMode?: 'DISABLED' | 'WHITELIST' | 'BLACKLIST' // 关键字过滤模式
keywords?: string[] // 关键字列表,当keywordFilterMode为DISABLED时为null
// 新增配置字段
configName?: string // 配置名(可选,但提供时必须非空)
pushFailedOrders?: boolean // 推送失败订单(可选)
@@ -372,7 +381,8 @@ export interface AccountPosition {
proxyAddress: string
marketId: string
marketTitle?: string
marketSlug?: string
marketSlug?: string // 显示用的 slug
eventSlug?: string // 跳转用的 slug(从 events[0].slug 获取)
marketIcon?: string // 市场图标 URL
side: string // 结果名称(如 "YES", "NO", "Pakistan" 等)
outcomeIndex?: number // 结果索引(0, 1, 2...),用于计算 tokenId
@@ -628,7 +638,8 @@ export interface BuyOrderInfo {
leaderTradeId: string
marketId: string
marketTitle?: string // 市场名称
marketSlug?: string // 市场 slug(用于构建 URL
marketSlug?: string // 市场 slug(用于显示
eventSlug?: string // 跳转用的 slug(从 events[0].slug 获取)
marketCategory?: string // 市场分类(sports, crypto 等)
side: string
quantity: string
@@ -648,7 +659,8 @@ export interface SellOrderInfo {
leaderTradeId: string
marketId: string
marketTitle?: string // 市场名称
marketSlug?: string // 市场 slug(用于构建 URL
marketSlug?: string // 市场 slug(用于显示
eventSlug?: string // 跳转用的 slug(从 events[0].slug 获取)
marketCategory?: string // 市场分类(sports, crypto 等)
side: string
quantity: string
@@ -666,7 +678,8 @@ export interface MatchedOrderInfo {
buyOrderId: string
marketId?: string // 市场ID
marketTitle?: string // 市场名称
marketSlug?: string // 市场 slug(用于构建 URL
marketSlug?: string // 市场 slug(用于显示
eventSlug?: string // 跳转用的 slug(从 events[0].slug 获取)
marketCategory?: string // 市场分类(sports, crypto 等)
matchedQuantity: string
buyPrice: string
@@ -729,7 +742,8 @@ export interface MarketOrderStats {
export interface MarketOrderGroup {
marketId: string
marketTitle?: string
marketSlug?: string
marketSlug?: string // 显示用的 slug
eventSlug?: string // 跳转用的 slug(从 events[0].slug 获取)
marketCategory?: string
stats: MarketOrderStats
orders: BuyOrderInfo[] | SellOrderInfo[] // 订单列表