170 lines
5.5 KiB
JavaScript
170 lines
5.5 KiB
JavaScript
/* Image Picker for Admin - media library modal + upload */
|
|
(function () {
|
|
var _currentField = null;
|
|
var _modal = null;
|
|
var _gallery = null;
|
|
var _loading = null;
|
|
|
|
function ensureModal() {
|
|
if (_modal) return;
|
|
var html =
|
|
'<div id="image-picker-modal" class="ip-modal-overlay" style="display:none">' +
|
|
'<div class="ip-modal">' +
|
|
'<div class="ip-modal-header">' +
|
|
'<h3>素材库</h3>' +
|
|
'<div class="ip-modal-header-actions">' +
|
|
'<button class="btn btn-sm btn-outline-success" onclick="imagePickerModalUpload()">' +
|
|
'<i class="fa-solid fa-upload"></i> 上传新图片</button>' +
|
|
'<input type="file" id="ip-modal-file" accept="image/*" style="display:none" onchange="imagePickerModalFileSelected(this)">' +
|
|
'<button class="btn btn-sm" onclick="imagePickerClose()">' +
|
|
'<i class="fa-solid fa-times"></i> 关闭</button>' +
|
|
'</div>' +
|
|
'</div>' +
|
|
'<div class="ip-modal-body">' +
|
|
'<div id="ip-loading" class="ip-loading">加载中...</div>' +
|
|
'<div id="ip-gallery" class="ip-gallery"></div>' +
|
|
'<div id="ip-empty" class="ip-empty" style="display:none">暂无图片,请先上传</div>' +
|
|
'</div>' +
|
|
'</div>' +
|
|
'</div>';
|
|
document.body.insertAdjacentHTML("beforeend", html);
|
|
_modal = document.getElementById("image-picker-modal");
|
|
_gallery = document.getElementById("ip-gallery");
|
|
_loading = document.getElementById("ip-loading");
|
|
|
|
_modal.addEventListener("click", function (e) {
|
|
if (e.target === _modal) imagePickerClose();
|
|
});
|
|
}
|
|
|
|
function loadGallery() {
|
|
_loading.style.display = "block";
|
|
_gallery.innerHTML = "";
|
|
document.getElementById("ip-empty").style.display = "none";
|
|
|
|
fetch("/admin/api/media/list", { credentials: "same-origin" })
|
|
.then(function (r) { return r.json(); })
|
|
.then(function (data) {
|
|
_loading.style.display = "none";
|
|
var images = data.images || [];
|
|
if (images.length === 0) {
|
|
document.getElementById("ip-empty").style.display = "block";
|
|
return;
|
|
}
|
|
images.forEach(function (img) {
|
|
var item = document.createElement("div");
|
|
item.className = "ip-gallery-item";
|
|
item.innerHTML =
|
|
'<img src="' + img.url + '" alt="' + img.name + '">' +
|
|
'<div class="ip-gallery-name">' + img.name + '</div>';
|
|
item.addEventListener("click", function () {
|
|
imagePickerSelect(img.url);
|
|
});
|
|
_gallery.appendChild(item);
|
|
});
|
|
})
|
|
.catch(function () {
|
|
_loading.style.display = "none";
|
|
_gallery.innerHTML = '<div class="ip-empty">加载失败,请重试</div>';
|
|
});
|
|
}
|
|
|
|
window.imagePickerOpen = function (fieldId) {
|
|
_currentField = fieldId;
|
|
ensureModal();
|
|
_modal.style.display = "flex";
|
|
loadGallery();
|
|
};
|
|
|
|
window.imagePickerClose = function () {
|
|
if (_modal) _modal.style.display = "none";
|
|
_currentField = null;
|
|
};
|
|
|
|
window.imagePickerSelect = function (url) {
|
|
if (!_currentField) return;
|
|
setFieldValue(_currentField, url);
|
|
imagePickerClose();
|
|
};
|
|
|
|
window.imagePickerClear = function (fieldId) {
|
|
setFieldValue(fieldId, "");
|
|
};
|
|
|
|
window.imagePickerUpload = function (fieldId) {
|
|
_currentField = fieldId;
|
|
document.getElementById("file-" + fieldId).click();
|
|
};
|
|
|
|
window.imagePickerFileSelected = function (fieldId, input) {
|
|
if (!input.files || !input.files[0]) return;
|
|
doUpload(input.files[0], fieldId);
|
|
input.value = "";
|
|
};
|
|
|
|
window.imagePickerModalUpload = function () {
|
|
document.getElementById("ip-modal-file").click();
|
|
};
|
|
|
|
window.imagePickerModalFileSelected = function (input) {
|
|
if (!input.files || !input.files[0]) return;
|
|
doUpload(input.files[0], _currentField, function () {
|
|
loadGallery();
|
|
});
|
|
input.value = "";
|
|
};
|
|
|
|
function doUpload(file, fieldId, callback) {
|
|
var fd = new FormData();
|
|
fd.append("file", file);
|
|
|
|
var btn = document.querySelector('.ip-modal-header-actions .btn-outline-success');
|
|
if (btn) {
|
|
btn.disabled = true;
|
|
btn.innerHTML = '<i class="fa-solid fa-spinner fa-spin"></i> 上传中...';
|
|
}
|
|
|
|
fetch("/admin/api/media/upload", {
|
|
method: "POST",
|
|
body: fd,
|
|
credentials: "same-origin",
|
|
})
|
|
.then(function (r) {
|
|
if (!r.ok) throw new Error("Upload failed");
|
|
return r.json();
|
|
})
|
|
.then(function (data) {
|
|
if (fieldId) setFieldValue(fieldId, data.url);
|
|
if (callback) callback();
|
|
})
|
|
.catch(function (err) {
|
|
alert("上传失败: " + err.message);
|
|
})
|
|
.finally(function () {
|
|
if (btn) {
|
|
btn.disabled = false;
|
|
btn.innerHTML = '<i class="fa-solid fa-upload"></i> 上传新图片';
|
|
}
|
|
});
|
|
}
|
|
|
|
function setFieldValue(fieldId, url) {
|
|
var input = document.getElementById(fieldId);
|
|
if (input) input.value = url;
|
|
|
|
var preview = document.getElementById("preview-" + fieldId);
|
|
var previewImg = document.getElementById("preview-img-" + fieldId);
|
|
var urlDisplay = document.getElementById("url-display-" + fieldId);
|
|
|
|
if (url) {
|
|
if (preview) preview.style.display = "block";
|
|
if (previewImg) previewImg.src = url;
|
|
if (urlDisplay) urlDisplay.textContent = url;
|
|
} else {
|
|
if (preview) preview.style.display = "none";
|
|
if (previewImg) previewImg.src = "";
|
|
if (urlDisplay) urlDisplay.textContent = "";
|
|
}
|
|
}
|
|
})();
|