This commit is contained in:
薇薇安 2026-01-15 16:58:05 +08:00
parent db2bd6a3b2
commit 2e672d1f25
3 changed files with 83 additions and 7 deletions

View File

@ -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

View File

@ -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

View File

@ -14,10 +14,56 @@ function Recommendations() {
useEffect(() => {
loadRecommendations()
// 10
// 10loading
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 || []
// 使setStateloading
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