a1abe159fa
Add deploy/manage.sh bootstrap for git.bz121.com/dekun/crypto_okx and point docs at this repo. Co-authored-by: Cursor <cursoragent@cursor.com>
154 lines
4.4 KiB
JavaScript
154 lines
4.4 KiB
JavaScript
/**
|
|
* 复盘表单:四周期截图即时上传与状态展示.
|
|
*/
|
|
(function (global) {
|
|
"use strict";
|
|
|
|
function newDraftId() {
|
|
if (global.crypto && typeof global.crypto.randomUUID === "function") {
|
|
return global.crypto.randomUUID().replace(/-/g, "");
|
|
}
|
|
var s = "";
|
|
for (var i = 0; i < 32; i++) {
|
|
s += Math.floor(Math.random() * 16).toString(16);
|
|
}
|
|
return s;
|
|
}
|
|
|
|
function ensureDraftId(root) {
|
|
var scope = root || document;
|
|
var el = scope.querySelector("#journal-draft-id");
|
|
if (!el) return "";
|
|
if (!el.value) {
|
|
el.value = newDraftId();
|
|
}
|
|
return el.value;
|
|
}
|
|
|
|
function rowParts(input) {
|
|
var row = input.closest(".journal-upload-row");
|
|
if (!row) return {};
|
|
return {
|
|
row: row,
|
|
status: row.querySelector(".journal-upload-status"),
|
|
hidden: row.querySelector(".journal-upload-hidden-file"),
|
|
};
|
|
}
|
|
|
|
function setStatus(statusEl, text, kind) {
|
|
if (!statusEl) return;
|
|
statusEl.textContent = text || "";
|
|
statusEl.classList.remove(
|
|
"journal-upload-status--pending",
|
|
"journal-upload-status--ok",
|
|
"journal-upload-status--err"
|
|
);
|
|
if (kind) {
|
|
statusEl.classList.add("journal-upload-status--" + kind);
|
|
}
|
|
}
|
|
|
|
function uploadSlotFile(input, file) {
|
|
var parts = rowParts(input);
|
|
var draftId = ensureDraftId(input.form || document);
|
|
if (!draftId || !file) {
|
|
setStatus(parts.status, "上传失败", "err");
|
|
return;
|
|
}
|
|
|
|
setStatus(parts.status, "上传中…", "pending");
|
|
if (parts.hidden) {
|
|
parts.hidden.value = "";
|
|
}
|
|
|
|
var fd = new FormData();
|
|
fd.append("journal_draft_id", draftId);
|
|
fd.append("tf", input.getAttribute("data-tf") || "");
|
|
fd.append("file", file);
|
|
|
|
fetch("/api/journal_upload_slot", { method: "POST", body: fd, credentials: "same-origin" })
|
|
.then(function (res) {
|
|
return res.json().then(function (data) {
|
|
return { ok: res.ok, data: data };
|
|
});
|
|
})
|
|
.then(function (result) {
|
|
if (!result.ok || !result.data || !result.data.ok) {
|
|
throw new Error(
|
|
(result.data && result.data.error) || "upload failed"
|
|
);
|
|
}
|
|
var fname = String(result.data.file || "").trim();
|
|
if (parts.hidden) {
|
|
parts.hidden.value = fname;
|
|
}
|
|
input.value = "";
|
|
setStatus(parts.status, "上传成功 " + fname, "ok");
|
|
})
|
|
.catch(function () {
|
|
if (parts.hidden) {
|
|
parts.hidden.value = "";
|
|
}
|
|
setStatus(parts.status, "上传失败", "err");
|
|
});
|
|
}
|
|
|
|
function isOptionsReviewSlot(input) {
|
|
if (!input) return false;
|
|
if (input.classList && input.classList.contains("or-upload-input")) return true;
|
|
return !!(input.closest && input.closest("#or-upload-slots, #options-review-root"));
|
|
}
|
|
|
|
function bindInput(input) {
|
|
if (!input || input.dataset.journalSlotBound === "1") return;
|
|
// 期权复盘槽位由 options_review.js 处理,勿被合约复盘上传抢走
|
|
if (isOptionsReviewSlot(input)) return;
|
|
input.dataset.journalSlotBound = "1";
|
|
input.addEventListener("change", function () {
|
|
var file = input.files && input.files[0];
|
|
if (!file) {
|
|
var parts = rowParts(input);
|
|
if (parts.hidden) {
|
|
parts.hidden.value = "";
|
|
}
|
|
setStatus(parts.status, "", "");
|
|
return;
|
|
}
|
|
uploadSlotFile(input, file);
|
|
});
|
|
}
|
|
|
|
function resetSlots(root) {
|
|
var scope = root || document;
|
|
var draftEl = scope.querySelector("#journal-draft-id");
|
|
if (draftEl) {
|
|
draftEl.value = newDraftId();
|
|
}
|
|
scope.querySelectorAll(".journal-upload-hidden-file").forEach(function (el) {
|
|
el.value = "";
|
|
});
|
|
scope.querySelectorAll(".journal-upload-slot-input").forEach(function (el) {
|
|
el.value = "";
|
|
});
|
|
scope.querySelectorAll(".journal-upload-status").forEach(function (el) {
|
|
setStatus(el, "", "");
|
|
});
|
|
}
|
|
|
|
function init(root) {
|
|
var scope = root || document;
|
|
ensureDraftId(scope);
|
|
scope.querySelectorAll(".journal-upload-slot-input").forEach(bindInput);
|
|
}
|
|
|
|
global.JournalUploadSlots = { init: init, reset: resetSlots };
|
|
|
|
if (document.readyState === "loading") {
|
|
document.addEventListener("DOMContentLoaded", function () {
|
|
init(document);
|
|
});
|
|
} else {
|
|
init(document);
|
|
}
|
|
})(typeof window !== "undefined" ? window : globalThis);
|