fix: improve frontend UX and fix OKX close position

Frontend improvements:
- Replace window.location.reload() with SWR mutate() for data refresh
- Replace native alert/confirm with toast notifications (confirmToast, notify)
- Add loading skeletons to AITradersPage and EquityChart
- Fix flash of empty state during initial load
OKX fixes:
- Fix proxy issue in Docker by using explicit no-proxy function
- Fix CloseShort sz parameter error - ensure quantity is always positive
- Fix GetPositions to return absolute value for positionAmt
This commit is contained in:
tinkle-community
2025-12-06 19:57:13 +08:00
parent a77c54dbef
commit 7bd5ca0a55
8 changed files with 132 additions and 30 deletions

View File

@@ -28,6 +28,7 @@ import {
Send,
} from 'lucide-react'
import type { Strategy, StrategyConfig, AIModel } from '../types'
import { confirmToast, notify } from '../lib/notify'
import { CoinSourceEditor } from '../components/strategy/CoinSourceEditor'
import { IndicatorEditor } from '../components/strategy/IndicatorEditor'
import { RiskControlEditor } from '../components/strategy/RiskControlEditor'
@@ -175,16 +176,30 @@ export function StrategyStudioPage() {
// Delete strategy
const handleDeleteStrategy = async (id: string) => {
if (!token || !confirm(language === 'zh' ? '确定删除此策略?' : 'Delete this strategy?')) return
if (!token) return
const confirmed = await confirmToast(
language === 'zh' ? '确定删除此策略?' : 'Delete this strategy?',
{
title: language === 'zh' ? '确认删除' : 'Confirm Delete',
okText: language === 'zh' ? '删除' : 'Delete',
cancelText: language === 'zh' ? '取消' : 'Cancel',
}
)
if (!confirmed) return
try {
const response = await fetch(`${API_BASE}/api/strategies/${id}`, {
method: 'DELETE',
headers: { Authorization: `Bearer ${token}` },
})
if (!response.ok) throw new Error('Failed to delete strategy')
notify.success(language === 'zh' ? '策略已删除' : 'Strategy deleted')
await fetchStrategies()
} catch (err) {
setError(err instanceof Error ? err.message : 'Unknown error')
const errorMsg = err instanceof Error ? err.message : 'Unknown error'
setError(errorMsg)
notify.error(errorMsg)
}
}

View File

@@ -1,6 +1,6 @@
import { useEffect, useState } from 'react'
import { useNavigate, useSearchParams } from 'react-router-dom'
import useSWR from 'swr'
import useSWR, { mutate } from 'swr'
import { api } from '../lib/api'
import { ChartTabs } from '../components/ChartTabs'
import { useLanguage } from '../contexts/LanguageContext'
@@ -22,6 +22,7 @@ import {
Loader2,
} from 'lucide-react'
import { stripLeadingIcons } from '../lib/text'
import { confirmToast, notify } from '../lib/notify'
import type {
SystemStatus,
AccountInfo,
@@ -88,18 +89,26 @@ export default function TraderDashboard() {
? `确定要平仓 ${symbol} ${side === 'LONG' ? '多仓' : '空仓'} 吗?`
: `Are you sure you want to close ${symbol} ${side === 'LONG' ? 'LONG' : 'SHORT'} position?`
if (!confirm(confirmMsg)) return
const confirmed = await confirmToast(confirmMsg, {
title: language === 'zh' ? '确认平仓' : 'Confirm Close',
okText: language === 'zh' ? '确认' : 'Confirm',
cancelText: language === 'zh' ? '取消' : 'Cancel',
})
if (!confirmed) return
setClosingPosition(symbol)
try {
await api.closePosition(selectedTraderId, symbol, side)
const successMsg = language === 'zh' ? '平仓成功' : 'Position closed successfully'
alert(successMsg)
// 刷新持仓数据
window.location.reload()
notify.success(language === 'zh' ? '平仓成功' : 'Position closed successfully')
// 使用 SWR mutate 刷新数据而非重新加载页面
await Promise.all([
mutate(`positions-${selectedTraderId}`),
mutate(`account-${selectedTraderId}`),
])
} catch (err: unknown) {
const errorMsg = err instanceof Error ? err.message : (language === 'zh' ? '平仓失败' : 'Failed to close position')
alert(errorMsg)
notify.error(errorMsg)
} finally {
setClosingPosition(null)
}