a
This commit is contained in:
parent
db2bd6a3b2
commit
2e672d1f25
|
|
@ -118,10 +118,22 @@ async def get_active_recommendations():
|
|||
"""
|
||||
获取当前有效的推荐(未过期、未执行、未取消)
|
||||
使用WebSocket实时价格更新推荐中的价格信息
|
||||
同一交易对只返回最新的推荐(已去重)
|
||||
"""
|
||||
try:
|
||||
recommendations = TradeRecommendation.get_active()
|
||||
|
||||
# 确保时间格式正确(转换为ISO格式字符串,包含时区信息)
|
||||
from datetime import datetime
|
||||
for rec in recommendations:
|
||||
if rec.get('recommendation_time'):
|
||||
if isinstance(rec['recommendation_time'], datetime):
|
||||
# 如果是datetime对象,转换为ISO格式字符串(UTC+8)
|
||||
rec['recommendation_time'] = rec['recommendation_time'].isoformat()
|
||||
elif isinstance(rec['recommendation_time'], str):
|
||||
# 如果已经是字符串,确保格式正确
|
||||
pass
|
||||
|
||||
# 尝试从WebSocket缓存获取实时价格更新推荐中的价格
|
||||
try:
|
||||
import sys
|
||||
|
|
|
|||
|
|
@ -322,11 +322,19 @@ class TradeRecommendation:
|
|||
|
||||
@staticmethod
|
||||
def get_active():
|
||||
"""获取当前有效的推荐(未过期、未执行、未取消)"""
|
||||
"""获取当前有效的推荐(未过期、未执行、未取消)
|
||||
同一交易对只返回最新的推荐(去重)
|
||||
"""
|
||||
return db.execute_query(
|
||||
"""SELECT * FROM trade_recommendations
|
||||
WHERE status = 'active' AND (expires_at IS NULL OR expires_at > NOW())
|
||||
ORDER BY signal_strength DESC, recommendation_time DESC"""
|
||||
"""SELECT t1.* FROM trade_recommendations t1
|
||||
INNER JOIN (
|
||||
SELECT symbol, MAX(recommendation_time) as max_time
|
||||
FROM trade_recommendations
|
||||
WHERE status = 'active' AND (expires_at IS NULL OR expires_at > NOW())
|
||||
GROUP BY symbol
|
||||
) t2 ON t1.symbol = t2.symbol AND t1.recommendation_time = t2.max_time
|
||||
WHERE t1.status = 'active' AND (t1.expires_at IS NULL OR t1.expires_at > NOW())
|
||||
ORDER BY t1.signal_strength DESC, t1.recommendation_time DESC"""
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
|
|
|
|||
|
|
@ -14,10 +14,56 @@ function Recommendations() {
|
|||
useEffect(() => {
|
||||
loadRecommendations()
|
||||
|
||||
// 如果是查看有效推荐,每10秒自动刷新一次(获取实时价格)
|
||||
// 如果是查看有效推荐,每10秒静默更新价格(不触发loading状态)
|
||||
let interval = null
|
||||
if (statusFilter === 'active') {
|
||||
interval = setInterval(loadRecommendations, 10000) // 每10秒刷新
|
||||
interval = setInterval(async () => {
|
||||
// 静默更新:只更新价格,不显示loading
|
||||
try {
|
||||
const result = await api.getActiveRecommendations()
|
||||
const newData = result.data || []
|
||||
|
||||
// 使用setState直接更新,不触发loading状态
|
||||
setRecommendations(prevRecommendations => {
|
||||
// 如果新数据为空,保持原数据不变
|
||||
if (newData.length === 0) {
|
||||
return prevRecommendations
|
||||
}
|
||||
|
||||
// 创建一个映射,用于快速查找
|
||||
const newDataMap = new Map(newData.map(rec => [rec.id, rec]))
|
||||
const prevMap = new Map(prevRecommendations.map(rec => [rec.id, rec]))
|
||||
|
||||
// 合并数据:优先使用新数据(包含实时价格更新)
|
||||
const updated = prevRecommendations.map(prevRec => {
|
||||
const newRec = newDataMap.get(prevRec.id)
|
||||
if (newRec) {
|
||||
// 如果新数据中有该推荐,使用新数据(包含价格更新)
|
||||
return newRec
|
||||
}
|
||||
// 如果新数据中没有,保留旧数据(可能已过期或状态改变)
|
||||
return prevRec
|
||||
})
|
||||
|
||||
// 添加新出现的推荐
|
||||
const newItems = newData.filter(newRec => !prevMap.has(newRec.id))
|
||||
|
||||
// 合并并去重(按id)
|
||||
const merged = [...updated, ...newItems]
|
||||
const uniqueMap = new Map()
|
||||
merged.forEach(rec => {
|
||||
if (!uniqueMap.has(rec.id)) {
|
||||
uniqueMap.set(rec.id, rec)
|
||||
}
|
||||
})
|
||||
|
||||
return Array.from(uniqueMap.values())
|
||||
})
|
||||
} catch (err) {
|
||||
// 静默失败,不显示错误
|
||||
console.debug('静默更新价格失败:', err)
|
||||
}
|
||||
}, 10000) // 每10秒刷新
|
||||
}
|
||||
|
||||
return () => {
|
||||
|
|
@ -104,14 +150,24 @@ function Recommendations() {
|
|||
const formatTime = (timeStr) => {
|
||||
if (!timeStr) return '-'
|
||||
try {
|
||||
// 处理时区问题:如果时间字符串包含时区信息,直接解析
|
||||
// 否则假设是UTC时间,转换为本地时间
|
||||
const date = new Date(timeStr)
|
||||
|
||||
// 检查日期是否有效
|
||||
if (isNaN(date.getTime())) {
|
||||
return timeStr
|
||||
}
|
||||
|
||||
// 使用本地时区格式化(显示北京时间,如果服务器返回的是UTC时间)
|
||||
return date.toLocaleString('zh-CN', {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit'
|
||||
second: '2-digit',
|
||||
timeZone: 'Asia/Shanghai' // 明确使用北京时间
|
||||
})
|
||||
} catch (e) {
|
||||
return timeStr
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user