Fix options review screenshots missing after journal upload hijack.
Stop journal_upload_slots from binding options slots; resolve journal_* files from static/images root so existing reviews display again. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -112,17 +112,23 @@ def images_json_dumps(items: Sequence[Mapping[str, str]]) -> Optional[str]:
|
||||
|
||||
|
||||
def options_review_image_paths(row: Any, upload_folder: str) -> List[str]:
|
||||
upload_folder = os.path.abspath(upload_folder or "")
|
||||
upload_root = os.path.abspath(upload_folder or "")
|
||||
options_dir = options_review_upload_dir(upload_root)
|
||||
paths: List[str] = []
|
||||
seen: set[str] = set()
|
||||
|
||||
def _add(name: Optional[str]) -> None:
|
||||
if not name:
|
||||
return
|
||||
p = os.path.abspath(os.path.join(upload_folder, str(name).strip()))
|
||||
if os.path.isfile(p) and p not in seen:
|
||||
seen.add(p)
|
||||
paths.append(p)
|
||||
base = os.path.basename(str(name).strip())
|
||||
if not base:
|
||||
return
|
||||
for folder in (options_dir, upload_root):
|
||||
p = os.path.abspath(os.path.join(folder, base))
|
||||
if os.path.isfile(p) and p not in seen:
|
||||
seen.add(p)
|
||||
paths.append(p)
|
||||
return
|
||||
|
||||
try:
|
||||
keys = row.keys() if hasattr(row, "keys") else ()
|
||||
|
||||
@@ -100,7 +100,13 @@ def register_options_review_routes(app: Flask, cfg: dict[str, Any], repo_root: s
|
||||
safe = os.path.basename(filename or "")
|
||||
path = os.path.join(folder, safe)
|
||||
if not os.path.isfile(path):
|
||||
return ("not found", 404)
|
||||
# 兼容误走合约 journal 上传、落在 UPLOAD_FOLDER 根目录的文件
|
||||
root = os.path.abspath(cfg["upload_folder"] or "")
|
||||
alt = os.path.join(root, safe)
|
||||
if os.path.isfile(alt):
|
||||
path = alt
|
||||
else:
|
||||
return ("not found", 404)
|
||||
return send_file(path)
|
||||
|
||||
@app.route("/api/options/review/sync", methods=["POST"])
|
||||
|
||||
@@ -68,6 +68,11 @@
|
||||
.or-pager{display:flex;align-items:center;gap:8px;margin-top:8px;font-size:.74rem}
|
||||
.or-list-loading{opacity:.55;pointer-events:none;transition:opacity .12s ease}
|
||||
.or-trades-table-wrap,.or-reviewed-table-wrap{min-height:9.5rem}
|
||||
.or-slot-thumb{
|
||||
display:block;margin-top:6px;max-width:160px;max-height:90px;
|
||||
object-fit:contain;border-radius:4px;border:1px solid rgba(127,127,127,.3);
|
||||
background:rgba(0,0,0,.2);cursor:zoom-in;
|
||||
}
|
||||
</style>
|
||||
|
||||
{# 1. 交易记录(含 Tab/筛选,固定约5行) #}
|
||||
@@ -176,13 +181,12 @@
|
||||
<option value="">入场逻辑</option>
|
||||
</select>
|
||||
|
||||
<input type="hidden" id="journal-draft-id" value="">
|
||||
<div class="journal-upload-slots" id="or-upload-slots">
|
||||
{% for tf in ['5m', '15m', '1h', '4h'] %}
|
||||
<div class="journal-upload-row" data-tf="{{ tf }}">
|
||||
<span class="journal-upload-slot-label">{{ tf }}</span>
|
||||
<input type="file" accept="image/*" class="journal-upload-slot-input or-upload-input" data-tf="{{ tf }}">
|
||||
<input type="hidden" class="journal-upload-hidden-file or-upload-hidden" data-tf="{{ tf }}" value="">
|
||||
<input type="file" accept="image/*" class="or-upload-input" data-tf="{{ tf }}">
|
||||
<input type="hidden" class="or-upload-hidden" data-tf="{{ tf }}" value="">
|
||||
<span class="journal-upload-status or-upload-status" data-tf="{{ tf }}" aria-live="polite"></span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
@@ -261,4 +265,4 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/static/options_review.js?v=13"></script>
|
||||
<script src="/static/options_review.js?v=14"></script>
|
||||
|
||||
Reference in New Issue
Block a user