fix(trade_query): 优化时间筛选逻辑以支持创建时间的回退处理
在交易查询逻辑中,调整了时间筛选条件,确保在存在 `created_at` 列时使用 `COALESCE(created_at, entry_time)`,并在无该列时回退至 `entry_time`。同时,增强了对时间筛选的支持,确保在不同筛选条件下均能正确返回结果。这一改动旨在提升查询的准确性与一致性。
This commit is contained in:
parent
5c854290eb
commit
5a3888d905
|
|
@ -1104,7 +1104,7 @@ class Trade:
|
||||||
query += " AND (entry_reason IS NULL OR entry_reason != 'sync_recovered')"
|
query += " AND (entry_reason IS NULL OR entry_reason != 'sync_recovered')"
|
||||||
query += " AND (exit_reason IS NULL OR exit_reason != 'sync')"
|
query += " AND (exit_reason IS NULL OR exit_reason != 'sync')"
|
||||||
|
|
||||||
# 按创建时间筛选时若表无 created_at 则回退为 entry_time
|
# 按创建时间筛选:有 created_at 列则用 COALESCE(created_at, entry_time);无则回退为 entry_time,保证「按创建时间」有结果
|
||||||
use_created = (time_filter == "created" and _table_has_column("trades", "created_at"))
|
use_created = (time_filter == "created" and _table_has_column("trades", "created_at"))
|
||||||
time_col = "COALESCE(created_at, entry_time)" if use_created else None
|
time_col = "COALESCE(created_at, entry_time)" if use_created else None
|
||||||
|
|
||||||
|
|
@ -1118,6 +1118,9 @@ class Trade:
|
||||||
elif use_created:
|
elif use_created:
|
||||||
query += " AND " + time_col + " >= %s AND " + time_col + " <= %s"
|
query += " AND " + time_col + " >= %s AND " + time_col + " <= %s"
|
||||||
params.extend([start_timestamp, end_timestamp])
|
params.extend([start_timestamp, end_timestamp])
|
||||||
|
elif time_filter == "created":
|
||||||
|
query += " AND entry_time >= %s AND entry_time <= %s"
|
||||||
|
params.extend([start_timestamp, end_timestamp])
|
||||||
else:
|
else:
|
||||||
query += " AND COALESCE(exit_time, entry_time) >= %s AND COALESCE(exit_time, entry_time) <= %s"
|
query += " AND COALESCE(exit_time, entry_time) >= %s AND COALESCE(exit_time, entry_time) <= %s"
|
||||||
params.extend([start_timestamp, end_timestamp])
|
params.extend([start_timestamp, end_timestamp])
|
||||||
|
|
@ -1125,12 +1128,12 @@ class Trade:
|
||||||
if time_filter == "exit":
|
if time_filter == "exit":
|
||||||
query += " AND ((status = 'closed' AND exit_time >= %s) OR (status != 'closed' AND entry_time >= %s))"
|
query += " AND ((status = 'closed' AND exit_time >= %s) OR (status != 'closed' AND entry_time >= %s))"
|
||||||
params.extend([start_timestamp, start_timestamp])
|
params.extend([start_timestamp, start_timestamp])
|
||||||
elif time_filter == "entry":
|
|
||||||
query += " AND entry_time >= %s"
|
|
||||||
params.append(start_timestamp)
|
|
||||||
elif use_created:
|
elif use_created:
|
||||||
query += " AND " + time_col + " >= %s"
|
query += " AND " + time_col + " >= %s"
|
||||||
params.append(start_timestamp)
|
params.append(start_timestamp)
|
||||||
|
elif time_filter == "entry" or time_filter == "created":
|
||||||
|
query += " AND entry_time >= %s"
|
||||||
|
params.append(start_timestamp)
|
||||||
else:
|
else:
|
||||||
query += " AND COALESCE(exit_time, entry_time) >= %s"
|
query += " AND COALESCE(exit_time, entry_time) >= %s"
|
||||||
params.append(start_timestamp)
|
params.append(start_timestamp)
|
||||||
|
|
@ -1138,12 +1141,12 @@ class Trade:
|
||||||
if time_filter == "exit":
|
if time_filter == "exit":
|
||||||
query += " AND ((status = 'closed' AND exit_time <= %s) OR (status != 'closed' AND entry_time <= %s))"
|
query += " AND ((status = 'closed' AND exit_time <= %s) OR (status != 'closed' AND entry_time <= %s))"
|
||||||
params.extend([end_timestamp, end_timestamp])
|
params.extend([end_timestamp, end_timestamp])
|
||||||
elif time_filter == "entry":
|
|
||||||
query += " AND entry_time <= %s"
|
|
||||||
params.append(end_timestamp)
|
|
||||||
elif use_created:
|
elif use_created:
|
||||||
query += " AND " + time_col + " <= %s"
|
query += " AND " + time_col + " <= %s"
|
||||||
params.append(end_timestamp)
|
params.append(end_timestamp)
|
||||||
|
elif time_filter == "entry" or time_filter == "created":
|
||||||
|
query += " AND entry_time <= %s"
|
||||||
|
params.append(end_timestamp)
|
||||||
else:
|
else:
|
||||||
query += " AND COALESCE(exit_time, entry_time) <= %s"
|
query += " AND COALESCE(exit_time, entry_time) <= %s"
|
||||||
params.append(end_timestamp)
|
params.append(end_timestamp)
|
||||||
|
|
@ -1163,6 +1166,8 @@ class Trade:
|
||||||
|
|
||||||
if use_created:
|
if use_created:
|
||||||
query += " ORDER BY " + time_col + " DESC, id DESC"
|
query += " ORDER BY " + time_col + " DESC, id DESC"
|
||||||
|
elif time_filter == "created":
|
||||||
|
query += " ORDER BY entry_time DESC, id DESC"
|
||||||
else:
|
else:
|
||||||
query += " ORDER BY COALESCE(exit_time, entry_time) DESC, id DESC"
|
query += " ORDER BY COALESCE(exit_time, entry_time) DESC, id DESC"
|
||||||
# 未传 limit 时使用默认上限,防止全表加载导致内存暴增(2 CPU 4G 场景)
|
# 未传 limit 时使用默认上限,防止全表加载导致内存暴增(2 CPU 4G 场景)
|
||||||
|
|
|
||||||
|
|
@ -339,6 +339,14 @@
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.position-time-row {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: #212529;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
.position-time-row:empty { display: none; }
|
||||||
|
|
||||||
.entry-time {
|
.entry-time {
|
||||||
color: #999;
|
color: #999;
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
|
|
|
||||||
|
|
@ -696,6 +696,11 @@ const StatsDashboard = () => {
|
||||||
{trade.side}
|
{trade.side}
|
||||||
</div>
|
</div>
|
||||||
<div className="trade-info">
|
<div className="trade-info">
|
||||||
|
<div className="position-time-row">
|
||||||
|
开仓时间: {(trade.entry_time || trade.created_at) ? formatEntryTime(trade.entry_time || trade.created_at) : '—'}
|
||||||
|
{' · '}
|
||||||
|
创建时间: {(trade.created_at != null && trade.created_at !== '') ? formatEntryTime(trade.created_at) : '—'}
|
||||||
|
</div>
|
||||||
<div className="entry-type-line">
|
<div className="entry-type-line">
|
||||||
入场类型:{' '}
|
入场类型:{' '}
|
||||||
<span
|
<span
|
||||||
|
|
@ -736,14 +741,6 @@ const StatsDashboard = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 止损止盈比例 */}
|
{/* 止损止盈比例 */}
|
||||||
|
|
||||||
|
|
||||||
<div className="entry-time">
|
|
||||||
开仓时间: {(trade.entry_time || trade.created_at) ? formatEntryTime(trade.entry_time || trade.created_at) : '—'}
|
|
||||||
</div>
|
|
||||||
<div className="entry-time">
|
|
||||||
创建时间: {(trade.created_at != null && trade.created_at !== '') ? formatEntryTime(trade.created_at) : '—'}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="trade-protection-col">
|
<div className="trade-protection-col">
|
||||||
<div className="stop-take-info">
|
<div className="stop-take-info">
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ const TradeList = () => {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadData()
|
loadData()
|
||||||
}, [accountId, reconciledOnly, timeFilter]) // accountId / 仅可对账 / 时间筛选方式 变化时重新加载
|
}, [accountId, reconciledOnly, timeFilter, period, useCustomDate, startDate, endDate, symbol, status, tradeType, exitReason]) // 筛选条件变化时重新加载(含按创建时间、快速时间段)
|
||||||
|
|
||||||
const loadData = async () => {
|
const loadData = async () => {
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user