a
This commit is contained in:
parent
35b3777f3e
commit
a3aed32224
|
|
@ -22,41 +22,47 @@ router = APIRouter()
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def get_date_range(period: Optional[str] = None):
|
def get_timestamp_range(period: Optional[str] = None):
|
||||||
"""
|
"""
|
||||||
根据时间段参数返回开始和结束日期
|
根据时间段参数返回开始和结束时间戳(Unix时间戳秒数)
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
period: 时间段 ('1d', '7d', '30d', 'custom')
|
period: 时间段 ('1d', '7d', '30d', 'today', 'week', 'month', 'custom')
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
(start_date, end_date) 元组,格式为 'YYYY-MM-DD HH:MM:SS'
|
(start_timestamp, end_timestamp) 元组,Unix时间戳(秒数)
|
||||||
"""
|
"""
|
||||||
# 使用当前时间作为结束时间,确保包含最新的单子
|
# 使用当前时间作为结束时间(Unix时间戳秒数)
|
||||||
end_date = datetime.now()
|
beijing_tz = timezone(timedelta(hours=8))
|
||||||
|
now = datetime.now(beijing_tz)
|
||||||
|
end_timestamp = int(now.timestamp())
|
||||||
|
|
||||||
if period == '1d':
|
if period == '1d':
|
||||||
# 最近1天:从今天00:00:00到现在(确保包含今天的所有单子)
|
# 最近1天:当前时间减去24小时
|
||||||
# 这样即使查询时已经是晚上,也能查到今天早上开的单子
|
start_timestamp = end_timestamp - 24 * 3600
|
||||||
start_date = end_date.replace(hour=0, minute=0, second=0, microsecond=0)
|
|
||||||
elif period == '7d':
|
elif period == '7d':
|
||||||
# 最近7天:从7天前00:00:00到现在
|
# 最近7天:当前时间减去7*24小时
|
||||||
start_date = (end_date - timedelta(days=7)).replace(hour=0, minute=0, second=0, microsecond=0)
|
start_timestamp = end_timestamp - 7 * 24 * 3600
|
||||||
elif period == '30d':
|
elif period == '30d':
|
||||||
# 最近30天:从30天前00:00:00到现在
|
# 最近30天:当前时间减去30*24小时
|
||||||
start_date = (end_date - timedelta(days=30)).replace(hour=0, minute=0, second=0, microsecond=0)
|
start_timestamp = end_timestamp - 30 * 24 * 3600
|
||||||
|
elif period == 'today':
|
||||||
|
# 今天:从今天00:00:00到现在
|
||||||
|
today_start = now.replace(hour=0, minute=0, second=0, microsecond=0)
|
||||||
|
start_timestamp = int(today_start.timestamp())
|
||||||
|
elif period == 'week':
|
||||||
|
# 本周:从本周一00:00:00到现在
|
||||||
|
days_since_monday = now.weekday() # 0=Monday, 6=Sunday
|
||||||
|
week_start = (now - timedelta(days=days_since_monday)).replace(hour=0, minute=0, second=0, microsecond=0)
|
||||||
|
start_timestamp = int(week_start.timestamp())
|
||||||
|
elif period == 'month':
|
||||||
|
# 本月:从本月1日00:00:00到现在
|
||||||
|
month_start = now.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
|
||||||
|
start_timestamp = int(month_start.timestamp())
|
||||||
else:
|
else:
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
# 开始时间:使用计算出的开始日期的00:00:00
|
return start_timestamp, end_timestamp
|
||||||
start_date_str = start_date.strftime('%Y-%m-%d %H:%M:%S')
|
|
||||||
# 结束时间:使用当前时间,确保包含最新单子,北京时间
|
|
||||||
# 使用北京时间(东八区)
|
|
||||||
beijing_tz = timezone(timedelta(hours=8))
|
|
||||||
end_date = datetime.now(beijing_tz)
|
|
||||||
end_date_str = end_date.strftime('%Y-%m-%d %H:%M:%S')
|
|
||||||
|
|
||||||
return start_date_str, end_date_str
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("")
|
@router.get("")
|
||||||
|
|
@ -64,7 +70,7 @@ def get_date_range(period: Optional[str] = None):
|
||||||
async def get_trades(
|
async def get_trades(
|
||||||
start_date: Optional[str] = Query(None, description="开始日期 (YYYY-MM-DD 或 YYYY-MM-DD HH:MM:SS)"),
|
start_date: Optional[str] = Query(None, description="开始日期 (YYYY-MM-DD 或 YYYY-MM-DD HH:MM:SS)"),
|
||||||
end_date: Optional[str] = Query(None, description="结束日期 (YYYY-MM-DD 或 YYYY-MM-DD HH:MM:SS)"),
|
end_date: Optional[str] = Query(None, description="结束日期 (YYYY-MM-DD 或 YYYY-MM-DD HH:MM:SS)"),
|
||||||
period: Optional[str] = Query(None, description="快速时间段筛选: '1d'(最近1天), '7d'(最近7天), '30d'(最近30天)"),
|
period: Optional[str] = Query(None, description="快速时间段筛选: '1d'(最近1天), '7d'(最近7天), '30d'(最近30天), 'today'(今天), 'week'(本周), 'month'(本月)"),
|
||||||
symbol: Optional[str] = Query(None, description="交易对筛选"),
|
symbol: Optional[str] = Query(None, description="交易对筛选"),
|
||||||
trade_type: Optional[str] = Query(None, description="交易类型筛选: 'buy', 'sell'"),
|
trade_type: Optional[str] = Query(None, description="交易类型筛选: 'buy', 'sell'"),
|
||||||
exit_reason: Optional[str] = Query(None, description="平仓原因筛选: 'stop_loss', 'take_profit', 'trailing_stop', 'manual', 'sync'"),
|
exit_reason: Optional[str] = Query(None, description="平仓原因筛选: 'stop_loss', 'take_profit', 'trailing_stop', 'manual', 'sync'"),
|
||||||
|
|
@ -75,28 +81,47 @@ async def get_trades(
|
||||||
获取交易记录
|
获取交易记录
|
||||||
|
|
||||||
支持两种筛选方式:
|
支持两种筛选方式:
|
||||||
1. 快速时间段筛选:使用 period 参数 ('1d', '7d', '30d')
|
1. 快速时间段筛选:使用 period 参数 ('1d', '7d', '30d', 'today', 'week', 'month')
|
||||||
2. 自定义时间段筛选:使用 start_date 和 end_date 参数
|
2. 自定义时间段筛选:使用 start_date 和 end_date 参数(会转换为Unix时间戳)
|
||||||
|
|
||||||
如果同时提供了 period 和 start_date/end_date,period 优先级更高
|
如果同时提供了 period 和 start_date/end_date,period 优先级更高
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
logger.info(f"获取交易记录请求: start_date={start_date}, end_date={end_date}, period={period}, symbol={symbol}, status={status}, limit={limit}, trade_type={trade_type}, exit_reason={exit_reason}")
|
logger.info(f"获取交易记录请求: start_date={start_date}, end_date={end_date}, period={period}, symbol={symbol}, status={status}, limit={limit}, trade_type={trade_type}, exit_reason={exit_reason}")
|
||||||
|
|
||||||
|
start_timestamp = None
|
||||||
|
end_timestamp = None
|
||||||
|
|
||||||
# 如果提供了 period,使用快速时间段筛选
|
# 如果提供了 period,使用快速时间段筛选
|
||||||
if period:
|
if period:
|
||||||
period_start, period_end = get_date_range(period)
|
period_start, period_end = get_timestamp_range(period)
|
||||||
if period_start and period_end:
|
if period_start is not None and period_end is not None:
|
||||||
start_date = period_start
|
start_timestamp = period_start
|
||||||
end_date = period_end
|
end_timestamp = period_end
|
||||||
logger.info(f"使用快速时间段筛选: {period} -> {start_date} 至 {end_date}")
|
logger.info(f"使用快速时间段筛选: {period} -> {start_timestamp} ({datetime.fromtimestamp(start_timestamp)}) 至 {end_timestamp} ({datetime.fromtimestamp(end_timestamp)})")
|
||||||
|
elif start_date or end_date:
|
||||||
# 格式化日期(如果只提供了日期,添加时间部分)
|
# 自定义时间段:将日期字符串转换为Unix时间戳
|
||||||
if start_date and len(start_date) == 10: # YYYY-MM-DD
|
beijing_tz = timezone(timedelta(hours=8))
|
||||||
|
if start_date:
|
||||||
|
if len(start_date) == 10: # YYYY-MM-DD
|
||||||
start_date = f"{start_date} 00:00:00"
|
start_date = f"{start_date} 00:00:00"
|
||||||
if end_date and len(end_date) == 10: # YYYY-MM-DD
|
try:
|
||||||
|
dt = datetime.strptime(start_date, '%Y-%m-%d %H:%M:%S')
|
||||||
|
dt = dt.replace(tzinfo=beijing_tz)
|
||||||
|
start_timestamp = int(dt.timestamp())
|
||||||
|
except ValueError:
|
||||||
|
logger.warning(f"无效的开始日期格式: {start_date}")
|
||||||
|
if end_date:
|
||||||
|
if len(end_date) == 10: # YYYY-MM-DD
|
||||||
end_date = f"{end_date} 23:59:59"
|
end_date = f"{end_date} 23:59:59"
|
||||||
|
try:
|
||||||
|
dt = datetime.strptime(end_date, '%Y-%m-%d %H:%M:%S')
|
||||||
|
dt = dt.replace(tzinfo=beijing_tz)
|
||||||
|
end_timestamp = int(dt.timestamp())
|
||||||
|
except ValueError:
|
||||||
|
logger.warning(f"无效的结束日期格式: {end_date}")
|
||||||
|
|
||||||
trades = Trade.get_all(start_date, end_date, symbol, status, trade_type, exit_reason)
|
trades = Trade.get_all(start_timestamp, end_timestamp, symbol, status, trade_type, exit_reason)
|
||||||
logger.info(f"查询到 {len(trades)} 条交易记录")
|
logger.info(f"查询到 {len(trades)} 条交易记录")
|
||||||
|
|
||||||
# 格式化交易记录,添加平仓类型的中文显示
|
# 格式化交易记录,添加平仓类型的中文显示
|
||||||
|
|
@ -124,8 +149,10 @@ async def get_trades(
|
||||||
"total": len(trades),
|
"total": len(trades),
|
||||||
"trades": formatted_trades,
|
"trades": formatted_trades,
|
||||||
"filters": {
|
"filters": {
|
||||||
"start_date": start_date,
|
"start_timestamp": start_timestamp,
|
||||||
"end_date": end_date,
|
"end_timestamp": end_timestamp,
|
||||||
|
"start_date": datetime.fromtimestamp(start_timestamp).strftime('%Y-%m-%d %H:%M:%S') if start_timestamp else None,
|
||||||
|
"end_date": datetime.fromtimestamp(end_timestamp).strftime('%Y-%m-%d %H:%M:%S') if end_timestamp else None,
|
||||||
"period": period,
|
"period": period,
|
||||||
"symbol": symbol,
|
"symbol": symbol,
|
||||||
"status": status
|
"status": status
|
||||||
|
|
@ -143,26 +170,45 @@ async def get_trades(
|
||||||
async def get_trade_stats(
|
async def get_trade_stats(
|
||||||
start_date: Optional[str] = Query(None, description="开始日期 (YYYY-MM-DD 或 YYYY-MM-DD HH:MM:SS)"),
|
start_date: Optional[str] = Query(None, description="开始日期 (YYYY-MM-DD 或 YYYY-MM-DD HH:MM:SS)"),
|
||||||
end_date: Optional[str] = Query(None, description="结束日期 (YYYY-MM-DD 或 YYYY-MM-DD HH:MM:SS)"),
|
end_date: Optional[str] = Query(None, description="结束日期 (YYYY-MM-DD 或 YYYY-MM-DD HH:MM:SS)"),
|
||||||
period: Optional[str] = Query(None, description="快速时间段筛选: '1d', '7d', '30d'"),
|
period: Optional[str] = Query(None, description="快速时间段筛选: '1d', '7d', '30d', 'today', 'week', 'month'"),
|
||||||
symbol: Optional[str] = Query(None, description="交易对筛选")
|
symbol: Optional[str] = Query(None, description="交易对筛选")
|
||||||
):
|
):
|
||||||
"""获取交易统计"""
|
"""获取交易统计"""
|
||||||
try:
|
try:
|
||||||
logger.info(f"获取交易统计请求: start_date={start_date}, end_date={end_date}, period={period}, symbol={symbol}")
|
logger.info(f"获取交易统计请求: start_date={start_date}, end_date={end_date}, period={period}, symbol={symbol}")
|
||||||
|
|
||||||
|
start_timestamp = None
|
||||||
|
end_timestamp = None
|
||||||
|
|
||||||
# 如果提供了 period,使用快速时间段筛选
|
# 如果提供了 period,使用快速时间段筛选
|
||||||
if period:
|
if period:
|
||||||
period_start, period_end = get_date_range(period)
|
period_start, period_end = get_timestamp_range(period)
|
||||||
if period_start and period_end:
|
if period_start is not None and period_end is not None:
|
||||||
start_date = period_start
|
start_timestamp = period_start
|
||||||
end_date = period_end
|
end_timestamp = period_end
|
||||||
|
elif start_date or end_date:
|
||||||
# 格式化日期
|
# 自定义时间段:将日期字符串转换为Unix时间戳
|
||||||
if start_date and len(start_date) == 10:
|
beijing_tz = timezone(timedelta(hours=8))
|
||||||
|
if start_date:
|
||||||
|
if len(start_date) == 10: # YYYY-MM-DD
|
||||||
start_date = f"{start_date} 00:00:00"
|
start_date = f"{start_date} 00:00:00"
|
||||||
if end_date and len(end_date) == 10:
|
try:
|
||||||
|
dt = datetime.strptime(start_date, '%Y-%m-%d %H:%M:%S')
|
||||||
|
dt = dt.replace(tzinfo=beijing_tz)
|
||||||
|
start_timestamp = int(dt.timestamp())
|
||||||
|
except ValueError:
|
||||||
|
logger.warning(f"无效的开始日期格式: {start_date}")
|
||||||
|
if end_date:
|
||||||
|
if len(end_date) == 10: # YYYY-MM-DD
|
||||||
end_date = f"{end_date} 23:59:59"
|
end_date = f"{end_date} 23:59:59"
|
||||||
|
try:
|
||||||
|
dt = datetime.strptime(end_date, '%Y-%m-%d %H:%M:%S')
|
||||||
|
dt = dt.replace(tzinfo=beijing_tz)
|
||||||
|
end_timestamp = int(dt.timestamp())
|
||||||
|
except ValueError:
|
||||||
|
logger.warning(f"无效的结束日期格式: {end_date}")
|
||||||
|
|
||||||
trades = Trade.get_all(start_date, end_date, symbol, None)
|
trades = Trade.get_all(start_timestamp, end_timestamp, symbol, None)
|
||||||
closed_trades = [t for t in trades if t['status'] == 'closed']
|
closed_trades = [t for t in trades if t['status'] == 'closed']
|
||||||
win_trades = [t for t in closed_trades if float(t['pnl']) > 0]
|
win_trades = [t for t in closed_trades if float(t['pnl']) > 0]
|
||||||
|
|
||||||
|
|
@ -176,8 +222,10 @@ async def get_trade_stats(
|
||||||
"total_pnl": sum(float(t['pnl']) for t in closed_trades),
|
"total_pnl": sum(float(t['pnl']) for t in closed_trades),
|
||||||
"avg_pnl": sum(float(t['pnl']) for t in closed_trades) / len(closed_trades) if closed_trades else 0,
|
"avg_pnl": sum(float(t['pnl']) for t in closed_trades) / len(closed_trades) if closed_trades else 0,
|
||||||
"filters": {
|
"filters": {
|
||||||
"start_date": start_date,
|
"start_timestamp": start_timestamp,
|
||||||
"end_date": end_date,
|
"end_timestamp": end_timestamp,
|
||||||
|
"start_date": datetime.fromtimestamp(start_timestamp).strftime('%Y-%m-%d %H:%M:%S') if start_timestamp else None,
|
||||||
|
"end_date": datetime.fromtimestamp(end_timestamp).strftime('%Y-%m-%d %H:%M:%S') if end_timestamp else None,
|
||||||
"period": period,
|
"period": period,
|
||||||
"symbol": symbol
|
"symbol": symbol
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,15 +25,15 @@ CREATE TABLE IF NOT EXISTS `trades` (
|
||||||
`quantity` DECIMAL(20, 8) NOT NULL,
|
`quantity` DECIMAL(20, 8) NOT NULL,
|
||||||
`entry_price` DECIMAL(20, 8) NOT NULL,
|
`entry_price` DECIMAL(20, 8) NOT NULL,
|
||||||
`exit_price` DECIMAL(20, 8),
|
`exit_price` DECIMAL(20, 8),
|
||||||
`entry_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`entry_time` INT UNSIGNED NOT NULL COMMENT '入场时间(Unix时间戳秒数)',
|
||||||
`exit_time` TIMESTAMP NULL,
|
`exit_time` INT UNSIGNED NULL COMMENT '平仓时间(Unix时间戳秒数)',
|
||||||
`pnl` DECIMAL(20, 8) DEFAULT 0,
|
`pnl` DECIMAL(20, 8) DEFAULT 0,
|
||||||
`pnl_percent` DECIMAL(10, 4) DEFAULT 0,
|
`pnl_percent` DECIMAL(10, 4) DEFAULT 0,
|
||||||
`leverage` INT DEFAULT 10,
|
`leverage` INT DEFAULT 10,
|
||||||
`entry_reason` TEXT,
|
`entry_reason` TEXT,
|
||||||
`exit_reason` VARCHAR(50) COMMENT 'stop_loss, take_profit, trailing_stop, manual',
|
`exit_reason` VARCHAR(50) COMMENT 'stop_loss, take_profit, trailing_stop, manual',
|
||||||
`status` VARCHAR(20) DEFAULT 'open' COMMENT 'open, closed, cancelled',
|
`status` VARCHAR(20) DEFAULT 'open' COMMENT 'open, closed, cancelled',
|
||||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
`created_at` INT UNSIGNED NOT NULL DEFAULT (UNIX_TIMESTAMP()) COMMENT '创建时间(Unix时间戳秒数)',
|
||||||
INDEX `idx_symbol` (`symbol`),
|
INDEX `idx_symbol` (`symbol`),
|
||||||
INDEX `idx_entry_time` (`entry_time`),
|
INDEX `idx_entry_time` (`entry_time`),
|
||||||
INDEX `idx_status` (`status`),
|
INDEX `idx_status` (`status`),
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@ import logging
|
||||||
BEIJING_TZ = timezone(timedelta(hours=8))
|
BEIJING_TZ = timezone(timedelta(hours=8))
|
||||||
|
|
||||||
def get_beijing_time():
|
def get_beijing_time():
|
||||||
"""获取当前北京时间(UTC+8)"""
|
"""获取当前北京时间(UTC+8)的Unix时间戳(秒)"""
|
||||||
return datetime.now(BEIJING_TZ).replace(tzinfo=None)
|
return int(datetime.now(BEIJING_TZ).timestamp())
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
@ -233,17 +233,26 @@ class Trade:
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_all(start_date=None, end_date=None, symbol=None, status=None, trade_type=None, exit_reason=None):
|
def get_all(start_timestamp=None, end_timestamp=None, symbol=None, status=None, trade_type=None, exit_reason=None):
|
||||||
"""获取交易记录"""
|
"""获取交易记录
|
||||||
|
|
||||||
|
Args:
|
||||||
|
start_timestamp: 开始时间(Unix时间戳秒数,可选)
|
||||||
|
end_timestamp: 结束时间(Unix时间戳秒数,可选)
|
||||||
|
symbol: 交易对(可选)
|
||||||
|
status: 状态(可选)
|
||||||
|
trade_type: 交易类型(可选)
|
||||||
|
exit_reason: 平仓原因(可选)
|
||||||
|
"""
|
||||||
query = "SELECT * FROM trades WHERE 1=1"
|
query = "SELECT * FROM trades WHERE 1=1"
|
||||||
params = []
|
params = []
|
||||||
|
|
||||||
if start_date:
|
if start_timestamp is not None:
|
||||||
query += " AND created_at >= %s"
|
query += " AND created_at >= %s"
|
||||||
params.append(start_date)
|
params.append(start_timestamp)
|
||||||
if end_date:
|
if end_timestamp is not None:
|
||||||
query += " AND created_at <= %s"
|
query += " AND created_at <= %s"
|
||||||
params.append(end_date)
|
params.append(end_timestamp)
|
||||||
if symbol:
|
if symbol:
|
||||||
query += " AND symbol = %s"
|
query += " AND symbol = %s"
|
||||||
params.append(symbol)
|
params.append(symbol)
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ const TradeList = () => {
|
||||||
const [loading, setLoading] = useState(true)
|
const [loading, setLoading] = useState(true)
|
||||||
|
|
||||||
// 筛选状态
|
// 筛选状态
|
||||||
const [period, setPeriod] = useState(null) // '1d', '7d', '30d', null
|
const [period, setPeriod] = useState(null) // '1d', '7d', '30d', 'today', 'week', 'month', null
|
||||||
const [startDate, setStartDate] = useState('')
|
const [startDate, setStartDate] = useState('')
|
||||||
const [endDate, setEndDate] = useState('')
|
const [endDate, setEndDate] = useState('')
|
||||||
const [symbol, setSymbol] = useState('')
|
const [symbol, setSymbol] = useState('')
|
||||||
|
|
@ -98,6 +98,24 @@ const TradeList = () => {
|
||||||
<div className="filter-section">
|
<div className="filter-section">
|
||||||
<label>快速筛选:</label>
|
<label>快速筛选:</label>
|
||||||
<div className="period-buttons">
|
<div className="period-buttons">
|
||||||
|
<button
|
||||||
|
className={period === 'today' ? 'active' : ''}
|
||||||
|
onClick={() => handlePeriodChange('today')}
|
||||||
|
>
|
||||||
|
今天
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className={period === 'week' ? 'active' : ''}
|
||||||
|
onClick={() => handlePeriodChange('week')}
|
||||||
|
>
|
||||||
|
本周
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className={period === 'month' ? 'active' : ''}
|
||||||
|
onClick={() => handlePeriodChange('month')}
|
||||||
|
>
|
||||||
|
本月
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
className={period === '1d' ? 'active' : ''}
|
className={period === '1d' ? 'active' : ''}
|
||||||
onClick={() => handlePeriodChange('1d')}
|
onClick={() => handlePeriodChange('1d')}
|
||||||
|
|
@ -280,11 +298,18 @@ const TradeList = () => {
|
||||||
const pnlPercent = margin > 0 ? (pnl / margin) * 100 : 0
|
const pnlPercent = margin > 0 ? (pnl / margin) * 100 : 0
|
||||||
|
|
||||||
// 格式化时间为北京时间
|
// 格式化时间为北京时间
|
||||||
const formatTime = (timeStr) => {
|
// 支持Unix时间戳(秒数)或日期字符串
|
||||||
if (!timeStr) return '-'
|
const formatTime = (timeValue) => {
|
||||||
|
if (!timeValue) return '-'
|
||||||
try {
|
try {
|
||||||
const date = new Date(timeStr)
|
let date
|
||||||
if (isNaN(date.getTime())) return timeStr
|
// 如果是数字(Unix时间戳),转换为毫秒
|
||||||
|
if (typeof timeValue === 'number') {
|
||||||
|
date = new Date(timeValue * 1000)
|
||||||
|
} else {
|
||||||
|
date = new Date(timeValue)
|
||||||
|
}
|
||||||
|
if (isNaN(date.getTime())) return String(timeValue)
|
||||||
return date.toLocaleString('zh-CN', {
|
return date.toLocaleString('zh-CN', {
|
||||||
year: 'numeric',
|
year: 'numeric',
|
||||||
month: '2-digit',
|
month: '2-digit',
|
||||||
|
|
@ -294,7 +319,7 @@ const TradeList = () => {
|
||||||
timeZone: 'Asia/Shanghai'
|
timeZone: 'Asia/Shanghai'
|
||||||
})
|
})
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return timeStr
|
return String(timeValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -350,11 +375,18 @@ const TradeList = () => {
|
||||||
const pnlPercent = margin > 0 ? (pnl / margin) * 100 : 0
|
const pnlPercent = margin > 0 ? (pnl / margin) * 100 : 0
|
||||||
|
|
||||||
// 格式化时间为北京时间
|
// 格式化时间为北京时间
|
||||||
const formatTime = (timeStr) => {
|
// 支持Unix时间戳(秒数)或日期字符串
|
||||||
if (!timeStr) return '-'
|
const formatTime = (timeValue) => {
|
||||||
|
if (!timeValue) return '-'
|
||||||
try {
|
try {
|
||||||
const date = new Date(timeStr)
|
let date
|
||||||
if (isNaN(date.getTime())) return timeStr
|
// 如果是数字(Unix时间戳),转换为毫秒
|
||||||
|
if (typeof timeValue === 'number') {
|
||||||
|
date = new Date(timeValue * 1000)
|
||||||
|
} else {
|
||||||
|
date = new Date(timeValue)
|
||||||
|
}
|
||||||
|
if (isNaN(date.getTime())) return String(timeValue)
|
||||||
return date.toLocaleString('zh-CN', {
|
return date.toLocaleString('zh-CN', {
|
||||||
month: '2-digit',
|
month: '2-digit',
|
||||||
day: '2-digit',
|
day: '2-digit',
|
||||||
|
|
@ -363,7 +395,7 @@ const TradeList = () => {
|
||||||
timeZone: 'Asia/Shanghai'
|
timeZone: 'Asia/Shanghai'
|
||||||
})
|
})
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return timeStr
|
return String(timeValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user