Show total pages and card-local AJAX paging on options review.
Trades and reviewed lists now report page X / Y and flip without full-page sync refresh. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -29,7 +29,9 @@
|
|||||||
var tradesCache = {};
|
var tradesCache = {};
|
||||||
var reviewedCache = {};
|
var reviewedCache = {};
|
||||||
var tradesPage = 0;
|
var tradesPage = 0;
|
||||||
var tradesHasMore = false;
|
var tradesPages = 1;
|
||||||
|
var reviewedPage = 0;
|
||||||
|
var reviewedPages = 1;
|
||||||
|
|
||||||
function $(id) {
|
function $(id) {
|
||||||
return document.getElementById(id);
|
return document.getElementById(id);
|
||||||
@@ -115,8 +117,8 @@
|
|||||||
|
|
||||||
function reloadAll() {
|
function reloadAll() {
|
||||||
setSyncStatus("读取本地记录…");
|
setSyncStatus("读取本地记录…");
|
||||||
loadTrades();
|
loadTrades({ sync: true });
|
||||||
loadReviewed();
|
loadReviewed({ sync: false });
|
||||||
loadStats();
|
loadStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,6 +200,7 @@
|
|||||||
function setActiveTab(source) {
|
function setActiveTab(source) {
|
||||||
activeSource = source || "option_spot";
|
activeSource = source || "option_spot";
|
||||||
tradesPage = 0;
|
tradesPage = 0;
|
||||||
|
reviewedPage = 0;
|
||||||
document.querySelectorAll(".or-tab").forEach(function (btn) {
|
document.querySelectorAll(".or-tab").forEach(function (btn) {
|
||||||
btn.classList.toggle("active", btn.getAttribute("data-source") === activeSource);
|
btn.classList.toggle("active", btn.getAttribute("data-source") === activeSource);
|
||||||
});
|
});
|
||||||
@@ -213,12 +216,49 @@
|
|||||||
var label = $("or-trades-page-label");
|
var label = $("or-trades-page-label");
|
||||||
var prev = $("or-trades-prev");
|
var prev = $("or-trades-prev");
|
||||||
var next = $("or-trades-next");
|
var next = $("or-trades-next");
|
||||||
if (label) label.textContent = "第 " + (tradesPage + 1) + " 页";
|
if (label) {
|
||||||
|
label.textContent = "第 " + (tradesPage + 1) + " / " + tradesPages + " 页";
|
||||||
|
}
|
||||||
if (prev) prev.disabled = tradesPage <= 0;
|
if (prev) prev.disabled = tradesPage <= 0;
|
||||||
if (next) next.disabled = !tradesHasMore;
|
if (next) next.disabled = tradesPage + 1 >= tradesPages;
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadTrades() {
|
function updateReviewedPager() {
|
||||||
|
var label = $("or-reviewed-page-label");
|
||||||
|
var prev = $("or-reviewed-prev");
|
||||||
|
var next = $("or-reviewed-next");
|
||||||
|
if (label) {
|
||||||
|
label.textContent = "第 " + (reviewedPage + 1) + " / " + reviewedPages + " 页";
|
||||||
|
}
|
||||||
|
if (prev) prev.disabled = reviewedPage <= 0;
|
||||||
|
if (next) next.disabled = reviewedPage + 1 >= reviewedPages;
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyPagerMeta(data, kind) {
|
||||||
|
var pages = Number(data.pages || 1);
|
||||||
|
if (!pages || pages < 1) pages = 1;
|
||||||
|
var clamped = false;
|
||||||
|
if (kind === "trades") {
|
||||||
|
tradesPages = pages;
|
||||||
|
if (tradesPage >= tradesPages) {
|
||||||
|
tradesPage = Math.max(0, tradesPages - 1);
|
||||||
|
clamped = true;
|
||||||
|
}
|
||||||
|
updateTradesPager();
|
||||||
|
} else {
|
||||||
|
reviewedPages = pages;
|
||||||
|
if (reviewedPage >= reviewedPages) {
|
||||||
|
reviewedPage = Math.max(0, reviewedPages - 1);
|
||||||
|
clamped = true;
|
||||||
|
}
|
||||||
|
updateReviewedPager();
|
||||||
|
}
|
||||||
|
return clamped;
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadTrades(opts) {
|
||||||
|
opts = opts || {};
|
||||||
|
var doSync = opts.sync !== false;
|
||||||
var tbody = $("or-trades-tbody");
|
var tbody = $("or-trades-tbody");
|
||||||
if (!tbody) return;
|
if (!tbody) return;
|
||||||
tbody.innerHTML = '<tr><td colspan="6" class="muted">加载中…</td></tr>';
|
tbody.innerHTML = '<tr><td colspan="6" class="muted">加载中…</td></tr>';
|
||||||
@@ -226,20 +266,23 @@
|
|||||||
p.set("reviewed", "0");
|
p.set("reviewed", "0");
|
||||||
p.set("limit", String(PAGE_SIZE));
|
p.set("limit", String(PAGE_SIZE));
|
||||||
p.set("offset", String(tradesPage * PAGE_SIZE));
|
p.set("offset", String(tradesPage * PAGE_SIZE));
|
||||||
|
if (!doSync) p.set("sync", "0");
|
||||||
fetch("/api/options/review/trades?" + p.toString(), { credentials: "same-origin" })
|
fetch("/api/options/review/trades?" + p.toString(), { credentials: "same-origin" })
|
||||||
.then(function (r) {
|
.then(function (r) {
|
||||||
return r.json();
|
return r.json();
|
||||||
})
|
})
|
||||||
.then(function (data) {
|
.then(function (data) {
|
||||||
setSyncStatus("本地记录已加载");
|
if (doSync) setSyncStatus("本地记录已加载");
|
||||||
if (!data.ok) {
|
if (!data.ok) {
|
||||||
tbody.innerHTML = '<tr><td colspan="6" class="muted">加载失败</td></tr>';
|
tbody.innerHTML = '<tr><td colspan="6" class="muted">加载失败</td></tr>';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (applyPagerMeta(data, "trades") && Number(data.total || 0) > 0) {
|
||||||
|
loadTrades(opts);
|
||||||
|
return;
|
||||||
|
}
|
||||||
var rows = data.trades || [];
|
var rows = data.trades || [];
|
||||||
tradesHasMore = rows.length >= PAGE_SIZE;
|
|
||||||
tradesCache = {};
|
tradesCache = {};
|
||||||
updateTradesPager();
|
|
||||||
if (!rows.length) {
|
if (!rows.length) {
|
||||||
tbody.innerHTML =
|
tbody.innerHTML =
|
||||||
'<tr><td colspan="6" class="muted">暂无待复盘记录</td></tr>';
|
'<tr><td colspan="6" class="muted">暂无待复盘记录</td></tr>';
|
||||||
@@ -304,14 +347,17 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadReviewed() {
|
function loadReviewed(opts) {
|
||||||
|
opts = opts || {};
|
||||||
|
var doSync = opts.sync === true;
|
||||||
var tbody = $("or-reviewed-tbody");
|
var tbody = $("or-reviewed-tbody");
|
||||||
if (!tbody) return;
|
if (!tbody) return;
|
||||||
tbody.innerHTML = '<tr><td colspan="6" class="muted">加载中…</td></tr>';
|
tbody.innerHTML = '<tr><td colspan="6" class="muted">加载中…</td></tr>';
|
||||||
var p = baseQs();
|
var p = baseQs();
|
||||||
p.set("reviewed", "1");
|
p.set("reviewed", "1");
|
||||||
p.set("limit", "100");
|
p.set("limit", String(PAGE_SIZE));
|
||||||
p.set("offset", "0");
|
p.set("offset", String(reviewedPage * PAGE_SIZE));
|
||||||
|
if (!doSync) p.set("sync", "0");
|
||||||
fetch("/api/options/review/trades?" + p.toString(), { credentials: "same-origin" })
|
fetch("/api/options/review/trades?" + p.toString(), { credentials: "same-origin" })
|
||||||
.then(function (r) {
|
.then(function (r) {
|
||||||
return r.json();
|
return r.json();
|
||||||
@@ -321,6 +367,10 @@
|
|||||||
tbody.innerHTML = '<tr><td colspan="6" class="muted">加载失败</td></tr>';
|
tbody.innerHTML = '<tr><td colspan="6" class="muted">加载失败</td></tr>';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (applyPagerMeta(data, "reviewed") && Number(data.total || 0) > 0) {
|
||||||
|
loadReviewed(opts);
|
||||||
|
return;
|
||||||
|
}
|
||||||
var rows = data.trades || [];
|
var rows = data.trades || [];
|
||||||
reviewedCache = {};
|
reviewedCache = {};
|
||||||
if (!rows.length) {
|
if (!rows.length) {
|
||||||
@@ -929,6 +979,8 @@
|
|||||||
var delBtn = $("or-del-btn");
|
var delBtn = $("or-del-btn");
|
||||||
var prevBtn = $("or-trades-prev");
|
var prevBtn = $("or-trades-prev");
|
||||||
var nextBtn = $("or-trades-next");
|
var nextBtn = $("or-trades-next");
|
||||||
|
var reviewedPrev = $("or-reviewed-prev");
|
||||||
|
var reviewedNext = $("or-reviewed-next");
|
||||||
var detailClose = $("or-detail-close-btn");
|
var detailClose = $("or-detail-close-btn");
|
||||||
var detailEdit = $("or-detail-edit-btn");
|
var detailEdit = $("or-detail-edit-btn");
|
||||||
if (reloadBtn) reloadBtn.addEventListener("click", reloadAll);
|
if (reloadBtn) reloadBtn.addEventListener("click", reloadAll);
|
||||||
@@ -939,14 +991,28 @@
|
|||||||
prevBtn.addEventListener("click", function () {
|
prevBtn.addEventListener("click", function () {
|
||||||
if (tradesPage <= 0) return;
|
if (tradesPage <= 0) return;
|
||||||
tradesPage -= 1;
|
tradesPage -= 1;
|
||||||
loadTrades();
|
loadTrades({ sync: false });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (nextBtn) {
|
if (nextBtn) {
|
||||||
nextBtn.addEventListener("click", function () {
|
nextBtn.addEventListener("click", function () {
|
||||||
if (!tradesHasMore) return;
|
if (tradesPage + 1 >= tradesPages) return;
|
||||||
tradesPage += 1;
|
tradesPage += 1;
|
||||||
loadTrades();
|
loadTrades({ sync: false });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (reviewedPrev) {
|
||||||
|
reviewedPrev.addEventListener("click", function () {
|
||||||
|
if (reviewedPage <= 0) return;
|
||||||
|
reviewedPage -= 1;
|
||||||
|
loadReviewed({ sync: false });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (reviewedNext) {
|
||||||
|
reviewedNext.addEventListener("click", function () {
|
||||||
|
if (reviewedPage + 1 >= reviewedPages) return;
|
||||||
|
reviewedPage += 1;
|
||||||
|
loadReviewed({ sync: false });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (detailClose) detailClose.addEventListener("click", hideDetail);
|
if (detailClose) detailClose.addEventListener("click", hideDetail);
|
||||||
@@ -961,6 +1027,7 @@
|
|||||||
if (el) {
|
if (el) {
|
||||||
el.addEventListener("change", function () {
|
el.addEventListener("change", function () {
|
||||||
tradesPage = 0;
|
tradesPage = 0;
|
||||||
|
reviewedPage = 0;
|
||||||
reloadAll();
|
reloadAll();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -970,6 +1037,7 @@
|
|||||||
if (el) {
|
if (el) {
|
||||||
el.addEventListener("change", function () {
|
el.addEventListener("change", function () {
|
||||||
tradesPage = 0;
|
tradesPage = 0;
|
||||||
|
reviewedPage = 0;
|
||||||
reloadAll();
|
reloadAll();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -591,8 +591,7 @@ def enrich_trade_row(row: dict[str, Any], entry: dict[str, Any] | None = None) -
|
|||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
def list_review_trades(
|
def _review_trades_filters(
|
||||||
conn: sqlite3.Connection,
|
|
||||||
*,
|
*,
|
||||||
source_type: str | None = None,
|
source_type: str | None = None,
|
||||||
underlying: str | None = None,
|
underlying: str | None = None,
|
||||||
@@ -602,10 +601,7 @@ def list_review_trades(
|
|||||||
include_hedge_legs: bool = False,
|
include_hedge_legs: bool = False,
|
||||||
closed_from: str | None = None,
|
closed_from: str | None = None,
|
||||||
closed_to: str | None = None,
|
closed_to: str | None = None,
|
||||||
limit: int = 200,
|
) -> tuple[str, list[Any]]:
|
||||||
offset: int = 0,
|
|
||||||
) -> list[dict[str, Any]]:
|
|
||||||
init_options_review_tables(conn)
|
|
||||||
wheres: list[str] = []
|
wheres: list[str] = []
|
||||||
args: list[Any] = []
|
args: list[Any] = []
|
||||||
if source_type and source_type in SOURCE_TYPES:
|
if source_type and source_type in SOURCE_TYPES:
|
||||||
@@ -647,6 +643,69 @@ def list_review_trades(
|
|||||||
elif reviewed == "0" or reviewed == "no":
|
elif reviewed == "0" or reviewed == "no":
|
||||||
wheres.append("e.id IS NULL")
|
wheres.append("e.id IS NULL")
|
||||||
where = (" WHERE " + " AND ".join(wheres)) if wheres else ""
|
where = (" WHERE " + " AND ".join(wheres)) if wheres else ""
|
||||||
|
return where, args
|
||||||
|
|
||||||
|
|
||||||
|
def count_review_trades(
|
||||||
|
conn: sqlite3.Connection,
|
||||||
|
*,
|
||||||
|
source_type: str | None = None,
|
||||||
|
underlying: str | None = None,
|
||||||
|
opt_type: str | None = None,
|
||||||
|
strategy_tag: str | None = None,
|
||||||
|
reviewed: str | None = None,
|
||||||
|
include_hedge_legs: bool = False,
|
||||||
|
closed_from: str | None = None,
|
||||||
|
closed_to: str | None = None,
|
||||||
|
) -> int:
|
||||||
|
init_options_review_tables(conn)
|
||||||
|
where, args = _review_trades_filters(
|
||||||
|
source_type=source_type,
|
||||||
|
underlying=underlying,
|
||||||
|
opt_type=opt_type,
|
||||||
|
strategy_tag=strategy_tag,
|
||||||
|
reviewed=reviewed,
|
||||||
|
include_hedge_legs=include_hedge_legs,
|
||||||
|
closed_from=closed_from,
|
||||||
|
closed_to=closed_to,
|
||||||
|
)
|
||||||
|
row = conn.execute(
|
||||||
|
f"""
|
||||||
|
SELECT COUNT(*) AS c
|
||||||
|
FROM options_review_trades t
|
||||||
|
LEFT JOIN options_review_entries e ON e.trade_id = t.id
|
||||||
|
{where}
|
||||||
|
""",
|
||||||
|
args,
|
||||||
|
).fetchone()
|
||||||
|
return int(row["c"] if row else 0)
|
||||||
|
|
||||||
|
|
||||||
|
def list_review_trades(
|
||||||
|
conn: sqlite3.Connection,
|
||||||
|
*,
|
||||||
|
source_type: str | None = None,
|
||||||
|
underlying: str | None = None,
|
||||||
|
opt_type: str | None = None,
|
||||||
|
strategy_tag: str | None = None,
|
||||||
|
reviewed: str | None = None,
|
||||||
|
include_hedge_legs: bool = False,
|
||||||
|
closed_from: str | None = None,
|
||||||
|
closed_to: str | None = None,
|
||||||
|
limit: int = 200,
|
||||||
|
offset: int = 0,
|
||||||
|
) -> list[dict[str, Any]]:
|
||||||
|
init_options_review_tables(conn)
|
||||||
|
where, args = _review_trades_filters(
|
||||||
|
source_type=source_type,
|
||||||
|
underlying=underlying,
|
||||||
|
opt_type=opt_type,
|
||||||
|
strategy_tag=strategy_tag,
|
||||||
|
reviewed=reviewed,
|
||||||
|
include_hedge_legs=include_hedge_legs,
|
||||||
|
closed_from=closed_from,
|
||||||
|
closed_to=closed_to,
|
||||||
|
)
|
||||||
rows = conn.execute(
|
rows = conn.execute(
|
||||||
f"""
|
f"""
|
||||||
SELECT t.*, e.id AS entry_id, e.strategy_tag AS e_strategy_tag,
|
SELECT t.*, e.id AS entry_id, e.strategy_tag AS e_strategy_tag,
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ from lib.options.options_review_images_lib import (
|
|||||||
from lib.options.options_review_lib import (
|
from lib.options.options_review_lib import (
|
||||||
SOURCE_LABELS,
|
SOURCE_LABELS,
|
||||||
compute_review_stats,
|
compute_review_stats,
|
||||||
|
count_review_trades,
|
||||||
delete_review_entry,
|
delete_review_entry,
|
||||||
ensure_local_review_synced,
|
ensure_local_review_synced,
|
||||||
get_review_trade,
|
get_review_trade,
|
||||||
@@ -120,23 +121,46 @@ def register_options_review_routes(app: Flask, cfg: dict[str, Any], repo_root: s
|
|||||||
def api_options_review_trades():
|
def api_options_review_trades():
|
||||||
conn = cfg["get_db"]()
|
conn = cfg["get_db"]()
|
||||||
try:
|
try:
|
||||||
ensure_local_review_synced(conn)
|
# 翻页可跳过同步,仅刷新当前卡片列表
|
||||||
conn.commit()
|
do_sync = (request.args.get("sync") or "1").strip().lower() not in (
|
||||||
items = list_review_trades(
|
"0",
|
||||||
conn,
|
"false",
|
||||||
|
"no",
|
||||||
|
)
|
||||||
|
if do_sync:
|
||||||
|
ensure_local_review_synced(conn)
|
||||||
|
conn.commit()
|
||||||
|
filt = dict(
|
||||||
source_type=(request.args.get("source_type") or "").strip() or None,
|
source_type=(request.args.get("source_type") or "").strip() or None,
|
||||||
underlying=(request.args.get("underlying") or "").strip() or None,
|
underlying=(request.args.get("underlying") or "").strip() or None,
|
||||||
opt_type=(request.args.get("opt_type") or "").strip() or None,
|
opt_type=(request.args.get("opt_type") or "").strip() or None,
|
||||||
strategy_tag=(request.args.get("strategy_tag") or "").strip() or None,
|
strategy_tag=(request.args.get("strategy_tag") or "").strip() or None,
|
||||||
reviewed=(request.args.get("reviewed") or "").strip() or None,
|
reviewed=(request.args.get("reviewed") or "").strip() or None,
|
||||||
include_hedge_legs=(request.args.get("include_hedge_legs") or "").strip().lower()
|
include_hedge_legs=(request.args.get("include_hedge_legs") or "")
|
||||||
|
.strip()
|
||||||
|
.lower()
|
||||||
in ("1", "true", "yes"),
|
in ("1", "true", "yes"),
|
||||||
closed_from=(request.args.get("closed_from") or "").strip() or None,
|
closed_from=(request.args.get("closed_from") or "").strip() or None,
|
||||||
closed_to=(request.args.get("closed_to") or "").strip() or None,
|
closed_to=(request.args.get("closed_to") or "").strip() or None,
|
||||||
limit=min(500, max(1, int(request.args.get("limit") or 200))),
|
|
||||||
offset=max(0, int(request.args.get("offset") or 0)),
|
|
||||||
)
|
)
|
||||||
return jsonify({"ok": True, "trades": items, "source_labels": SOURCE_LABELS})
|
limit = min(500, max(1, int(request.args.get("limit") or 200)))
|
||||||
|
offset = max(0, int(request.args.get("offset") or 0))
|
||||||
|
total = count_review_trades(conn, **filt)
|
||||||
|
items = list_review_trades(conn, **filt, limit=limit, offset=offset)
|
||||||
|
pages = max(1, (total + limit - 1) // limit) if total else 1
|
||||||
|
page = (offset // limit) + 1 if limit else 1
|
||||||
|
return jsonify(
|
||||||
|
{
|
||||||
|
"ok": True,
|
||||||
|
"trades": items,
|
||||||
|
"source_labels": SOURCE_LABELS,
|
||||||
|
"total": total,
|
||||||
|
"limit": limit,
|
||||||
|
"offset": offset,
|
||||||
|
"page": page,
|
||||||
|
"pages": pages,
|
||||||
|
}
|
||||||
|
)
|
||||||
finally:
|
finally:
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
|
|||||||
@@ -89,7 +89,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="or-pager" id="or-trades-pager">
|
<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>
|
<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>
|
<span class="muted" id="or-trades-page-label">第 1 / 1 页</span>
|
||||||
<button type="button" class="btn-secondary" id="or-trades-next" style="font-size:.72rem;padding:2px 8px">下一页</button>
|
<button type="button" class="btn-secondary" id="or-trades-next" style="font-size:.72rem;padding:2px 8px">下一页</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -179,6 +179,7 @@
|
|||||||
{# 3. 已复盘记录 + 详情 #}
|
{# 3. 已复盘记录 + 详情 #}
|
||||||
<div class="card" style="margin-bottom:10px">
|
<div class="card" style="margin-bottom:10px">
|
||||||
<h3>复盘记录</h3>
|
<h3>复盘记录</h3>
|
||||||
|
<p class="muted" style="margin:0 0 8px;font-size:.72rem">已保存的复盘(每页5条).点一行查看详情.</p>
|
||||||
<p class="muted" style="margin-top:0;font-size:.72rem">保存后出现在此.点一行查看详情(含截图与完整复盘内容).</p>
|
<p class="muted" style="margin-top:0;font-size:.72rem">保存后出现在此.点一行查看详情(含截图与完整复盘内容).</p>
|
||||||
<div class="options-strike-table-wrap">
|
<div class="options-strike-table-wrap">
|
||||||
<table class="options-strike-table or-reviewed-table" id="or-reviewed-table">
|
<table class="options-strike-table or-reviewed-table" id="or-reviewed-table">
|
||||||
@@ -197,6 +198,11 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="or-pager" id="or-reviewed-pager">
|
||||||
|
<button type="button" class="btn-secondary" id="or-reviewed-prev" style="font-size:.72rem;padding:2px 8px">上一页</button>
|
||||||
|
<span class="muted" id="or-reviewed-page-label">第 1 / 1 页</span>
|
||||||
|
<button type="button" class="btn-secondary" id="or-reviewed-next" style="font-size:.72rem;padding:2px 8px">下一页</button>
|
||||||
|
</div>
|
||||||
<div class="or-detail-panel hidden" id="or-detail-panel">
|
<div class="or-detail-panel hidden" id="or-detail-panel">
|
||||||
<div class="form-row" style="align-items:center;gap:8px;margin-bottom:6px">
|
<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>
|
<h3 style="margin:0;margin-right:auto" id="or-detail-title">复盘详情</h3>
|
||||||
@@ -217,4 +223,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="/static/options_review.js?v=8"></script>
|
<script src="/static/options_review.js?v=9"></script>
|
||||||
|
|||||||
Reference in New Issue
Block a user