Restructure options review into pending trades, form, and reviewed detail.

Show five pending trades per page, reveal the upload form only after clicking 复盘, and list saved reviews with image detail above stats.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-17 10:50:12 +08:00
parent 01ca035c2a
commit 8842f0b869
3 changed files with 406 additions and 90 deletions
+2
View File
@@ -582,10 +582,12 @@ def enrich_trade_row(row: dict[str, Any], entry: dict[str, Any] | None = None) -
out["entry"]["images"] = parse_options_review_images_json(entry.get("images_json"))
out["strategy_tag"] = entry.get("strategy_tag")
out["result_tag"] = entry.get("result_tag")
out["reviewed_at"] = entry.get("reviewed_at") or entry.get("updated_at")
else:
out["entry"] = None
out["strategy_tag"] = None
out["result_tag"] = None
out["reviewed_at"] = None
return out
+70 -32
View File
@@ -1,4 +1,4 @@
{# OKX 期权复盘:读本地记录;复盘上传区字体缩小,截图槽位对齐合约 #}
{# OKX 期权复盘:交易记录(5行) → 点复盘出表单 → 复盘记录 → 统计 #}
<div class="options-review-wrap" id="options-review-root" style="grid-column:1/-1">
{% if not options_enabled %}
<div class="flash" style="margin-bottom:12px;font-size:.82rem">期权未启用:请设置 <code>OKX_OPTIONS_ENABLED=true</code> 后重启.</div>
@@ -7,7 +7,7 @@
<style>
.options-review-wrap{font-size:.82rem}
.options-review-wrap h2{font-size:1rem;margin:0 0 8px}
.options-review-wrap h3{font-size:.9rem}
.options-review-wrap h3{font-size:.9rem;margin:0 0 8px}
.or-tabs{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:8px}
.or-tab{border:1px solid rgba(127,127,127,.35);background:transparent;color:inherit;padding:5px 10px;border-radius:6px;cursor:pointer;font-size:.78rem}
.or-tab.active{background:rgba(59,130,246,.25);border-color:rgba(59,130,246,.55)}
@@ -15,7 +15,6 @@
.or-stat-card{border:1px solid rgba(127,127,127,.25);border-radius:8px;padding:8px;font-size:.78rem}
.or-trades-table{font-size:.78rem}
.or-trades-table tr.or-row-active{outline:1px solid rgba(59,130,246,.55);background:rgba(59,130,246,.08)}
.or-trades-table tbody tr{cursor:pointer}
.or-journal-card{font-size:.78rem}
.or-journal-card h2{font-size:.92rem}
.or-journal-card input,
@@ -27,9 +26,19 @@
.or-journal-card .or-mood-grid{display:flex;flex-wrap:wrap;gap:6px 12px;margin:8px 0;font-size:.74rem}
.or-journal-card .muted,
.or-journal-card .sub{font-size:.7rem}
.or-journal-idle .or-journal-body{opacity:.78}
.or-journal-card.hidden{display:none!important}
.or-reviewed-table tbody tr{cursor:pointer}
.or-detail-panel{margin-top:10px;padding-top:10px;border-top:1px solid rgba(127,127,127,.25)}
.or-detail-panel.hidden{display:none!important}
.or-detail-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:6px 12px;font-size:.76rem;margin-bottom:8px}
.or-detail-images{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:8px;margin:8px 0}
.or-detail-img-cell{border:1px solid rgba(127,127,127,.25);border-radius:6px;padding:6px;text-align:center}
.or-detail-img-label{display:block;font-size:.7rem;margin-bottom:4px;opacity:.8}
.or-detail-img-thumb{max-width:100%;max-height:160px;border-radius:4px;cursor:pointer}
.or-pager{display:flex;align-items:center;gap:8px;margin-top:8px;font-size:.74rem}
</style>
{# 1. 交易记录(含 Tab/筛选,固定约5行) #}
<div class="card" style="margin-bottom:10px">
<div class="form-row" style="flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:6px">
<h2 style="margin:0;margin-right:auto">期权复盘</h2>
@@ -41,8 +50,8 @@
<button type="button" class="or-tab" data-source="options_options" role="tab">期期对冲记录</button>
<button type="button" class="or-tab" data-source="perp_options" role="tab">永期对冲记录</button>
</div>
<p class="muted" style="margin:0 0 8px;font-size:.72rem">直接读取本地已平期权与已结束对冲计划,无需同步交易所.点下方记录可填入复盘表单.</p>
<div class="form-row" style="flex-wrap:wrap;gap:6px">
<p class="muted" style="margin:0 0 8px;font-size:.72rem">待复盘交易(每页5条).点「复盘」填写表单;保存后进入下方复盘记录.</p>
<div class="form-row" style="flex-wrap:wrap;gap:6px;margin-bottom:8px">
<select id="or-filter-uly" style="font-size:.76rem">
<option value="">标的:全部</option>
<option value="ETH">ETH</option>
@@ -53,11 +62,6 @@
<option value="C">Call</option>
<option value="P">Put</option>
</select>
<select id="or-filter-reviewed" style="font-size:.76rem">
<option value="">复盘:全部</option>
<option value="0">待复盘</option>
<option value="1">已复盘</option>
</select>
<input type="text" id="or-filter-strategy" placeholder="策略标签" style="max-width:110px;font-size:.76rem">
<input type="datetime-local" id="or-filter-from" title="平仓起" style="font-size:.76rem">
<input type="datetime-local" id="or-filter-to" title="平仓止" style="font-size:.76rem">
@@ -65,11 +69,35 @@
<input type="checkbox" id="or-include-hedge-legs"> 含已归属对冲的期权腿
</label>
</div>
<h3 id="or-list-title" style="margin-top:0">期权交易记录</h3>
<div class="options-strike-table-wrap">
<table class="options-strike-table or-trades-table" id="or-trades-table">
<thead>
<tr>
<th>类型</th>
<th>标的/合约</th>
<th>盈亏</th>
<th>开/平</th>
<th>持有</th>
<th>操作</th>
</tr>
</thead>
<tbody id="or-trades-tbody">
<tr><td colspan="6" class="muted">加载中…</td></tr>
</tbody>
</table>
</div>
<div class="or-pager" id="or-trades-pager">
<button type="button" class="btn-secondary" id="or-trades-prev" style="font-size:.72rem;padding:2px 8px">上一页</button>
<span class="muted" id="or-trades-page-label">1</span>
<button type="button" class="btn-secondary" id="or-trades-next" style="font-size:.72rem;padding:2px 8px">下一页</button>
</div>
</div>
<div class="card journal-card or-journal-card or-journal-idle" id="or-journal-card" style="margin-bottom:10px">
{# 2. 复盘上传(默认隐藏,点交易「复盘」后显示) #}
<div class="card journal-card or-journal-card hidden" id="or-journal-card" style="margin-bottom:10px">
<h2>复盘记录上传(含截图)</h2>
<p class="muted" id="or-journal-summary" style="margin-top:0">点下方列表一笔记录自动填入;截图槽位与合约复盘相同(5m / 15m / 1h / 4h).</p>
<p class="muted" id="or-journal-summary" style="margin-top:0">截图槽位与合约复盘相同(5m / 15m / 1h / 4h).</p>
<div class="or-journal-body">
<form id="or-journal-form" onsubmit="return false;">
<input type="hidden" id="or-trade-id" value="">
@@ -126,7 +154,7 @@
</div>
{% endfor %}
</div>
<p class="sub journal-upload-hint">可只传部分周期;选文件后即时上传,保存后详情页四宫格查看</p>
<p class="sub journal-upload-hint">可只传部分周期;选文件后即时上传</p>
<div class="or-mood-grid mood-grid">
<label><input type="checkbox" class="or-mood" value="怕踏空">怕踏空</label>
@@ -139,8 +167,8 @@
<textarea id="or-f-note" rows="2" placeholder="备注" style="width:100%;box-sizing:border-box"></textarea>
<div class="form-row" style="margin-top:8px;gap:6px">
<button type="button" class="btn" id="or-save-btn">保存复盘记录</button>
<button type="button" class="btn-secondary" id="or-clear-btn">清空表单</button>
<button type="button" class="btn-secondary" id="or-del-btn">删除复盘</button>
<button type="button" class="btn-secondary" id="or-clear-btn">取消</button>
<button type="button" class="btn-secondary" id="or-del-btn">删除复盘内容</button>
<span class="muted" id="or-save-status"></span>
</div>
<div id="or-legs-host" style="margin-top:10px;font-size:.74rem"></div>
@@ -148,35 +176,45 @@
</div>
</div>
{# 3. 已复盘记录 + 详情 #}
<div class="card" style="margin-bottom:10px">
<h3 style="margin-top:0">统计</h3>
<div id="or-kpi" class="form-row" style="flex-wrap:wrap;gap:10px"></div>
<div id="or-stats-groups" style="margin-top:10px;display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:8px"></div>
</div>
<div class="card">
<h3 style="margin-top:0" id="or-list-title">期权交易记录</h3>
<p class="muted" style="margin-top:0;font-size:.72rem">点选一行,上方复盘表单自动填入.</p>
<h3>复盘记录</h3>
<p class="muted" style="margin-top:0;font-size:.72rem">保存后出现在此.点一行查看详情(含截图与完整复盘内容).</p>
<div class="options-strike-table-wrap">
<table class="options-strike-table or-trades-table" id="or-trades-table">
<table class="options-strike-table or-reviewed-table" id="or-reviewed-table">
<thead>
<tr>
<th>类型</th>
<th>标的/合约</th>
<th>盈亏</th>
<th>开/平</th>
<th>持有</th>
<th>策略</th>
<th>状态</th>
<th>操作</th>
<th>结果</th>
<th>复盘时间</th>
</tr>
</thead>
<tbody id="or-trades-tbody">
<tr><td colspan="8" class="muted">加载中…</td></tr>
<tbody id="or-reviewed-tbody">
<tr><td colspan="6" class="muted">加载中…</td></tr>
</tbody>
</table>
</div>
<div class="or-detail-panel hidden" id="or-detail-panel">
<div class="form-row" style="align-items:center;gap:8px;margin-bottom:6px">
<h3 style="margin:0;margin-right:auto" id="or-detail-title">复盘详情</h3>
<button type="button" class="btn-secondary" id="or-detail-edit-btn" style="font-size:.72rem;padding:2px 8px">编辑</button>
<button type="button" class="btn-secondary" id="or-detail-close-btn" style="font-size:.72rem;padding:2px 8px">收起</button>
</div>
<div class="or-detail-grid" id="or-detail-meta"></div>
<div id="or-detail-text" style="font-size:.76rem;line-height:1.5;margin-bottom:8px"></div>
<div class="or-detail-images" id="or-detail-images"></div>
</div>
</div>
{# 4. 统计 #}
<div class="card" style="margin-bottom:10px">
<h3>统计</h3>
<div id="or-kpi" class="form-row" style="flex-wrap:wrap;gap:10px"></div>
<div id="or-stats-groups" style="margin-top:10px;display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:8px"></div>
</div>
</div>
<script src="/static/options_review.js?v=7"></script>
<script src="/static/options_review.js?v=8"></script>