Sửa lỗi xóa ảnh trong quản lí ảnh và media

This commit is contained in:
2026-06-08 18:19:59 +07:00
parent 965be4d0e7
commit f15e53c4e5
4 changed files with 88 additions and 12 deletions
+2 -2
View File
@@ -638,7 +638,7 @@ router.delete('/assets/:id', protect, async (req, res) => {
if (!asset) return res.status(404).json({ message: 'Ảnh không tồn tại' });
// Kiểm tra quyền: Người upload hoặc Admin (Chủ sở hữu)
const isOwner = asset.uploadedBy.toString() === req.user._id.toString();
const isOwner = asset.uploadedBy && asset.uploadedBy.toString() === req.user._id.toString();
const isAdmin = req.user.role === 'Chủ sở hữu' || req.user.role === 'admin';
if (!isOwner && !isAdmin) {
@@ -659,7 +659,7 @@ router.delete('/assets/:id', protect, async (req, res) => {
}
// 2. Xóa file vật lý trên disk
if (fs.existsSync(asset.filePath)) {
if (asset.filePath && fs.existsSync(asset.filePath)) {
fs.unlinkSync(asset.filePath);
}
+3 -1
View File
@@ -594,7 +594,9 @@ html, body {
box-shadow: 0 10px 40px rgba(0,0,0,0.6) !important;
}
#logout-confirm-modal {
#logout-confirm-modal,
#delete-asset-confirm-modal,
#success-modal {
z-index: 5500; /* Cao hơn Dashboard (4500) và Close Button (5000) */
}
+22 -1
View File
@@ -132,7 +132,7 @@
<div id="create-scene-modal" class="modal">
<div class="modal-content">
<span class="close-btn" onclick="closeModal()">&times;</span>
<h2>Create New 3D Scene</h2>
<h2 id="create-scene-modal-title">Create New 3D Scene</h2>
<form id="create-scene-form" onsubmit="submitScene(event)">
<!-- Hidden field for editing existing scene -->
<input type="hidden" id="modal-scene-id" name="sceneId">
@@ -179,6 +179,27 @@
</div>
</div>
<!-- Delete Asset Confirmation Modal -->
<div id="delete-asset-confirm-modal" class="modal-overlay">
<div class="modal-content action-modal-content logout-modal-dark">
<h2 style="color: #fff; margin-bottom: 10px;" id="delete-asset-modal-title">Xác nhận xóa ảnh</h2>
<p style="color: #ccc; margin-bottom: 25px;" id="delete-asset-modal-desc">Bạn có chắc chắn muốn xóa ảnh này? Nếu ảnh đang được gắn vào một cảnh, cảnh đó cũng sẽ bị xóa vĩnh viễn.</p>
<div class="action-buttons">
<button onclick="confirmDeleteAsset()" class="delete-btn-large">Xóa vĩnh viễn</button>
<button onclick="closeDeleteAssetModal()" class="edit-btn-large" style="background: #6c757d;">Hủy bỏ</button>
</div>
</div>
</div>
<!-- Success Message Modal -->
<div id="success-modal" class="modal-overlay" onclick="closeSuccessModal(event)">
<div class="modal-content action-modal-content logout-modal-dark" style="border-top: 4px solid #28a745; max-width: 350px;">
<div style="font-size: 40px; color: #28a745; margin-bottom: 10px;"></div>
<h2 style="color: #fff; margin-bottom: 5px;">Thành công</h2>
<p style="color: #ccc;" id="success-modal-message">Dữ liệu đã được cập nhật.</p>
</div>
</div>
<!-- Modal for Action Choice (Edit/Delete) -->
<div id="action-choice-modal" class="modal">
<div class="modal-content action-modal-content">
+61 -8
View File
@@ -8,6 +8,8 @@ let previousSceneId = null;
let miniMap = null;
let miniMapMarker = null;
let systemSettings = { timezone: 'Asia/Ho_Chi_Minh', language: 'vi' };
let returnToDashboardAfterEdit = false;
let assetIdToDelete = null;
// Initialize when DOM is ready
document.addEventListener('DOMContentLoaded', () => {
@@ -420,6 +422,10 @@ function openCreateSceneModal(lat, lng) {
document.getElementById('modal-scene-id').value = '';
document.getElementById('modal-lat').value = lat.toFixed(6);
document.getElementById('modal-lng').value = lng.toFixed(6);
const lang = systemSettings.language || 'vi';
const modalTitle = document.getElementById('create-scene-modal-title');
if (modalTitle) modalTitle.innerText = lang === 'vi' ? "Tạo 3D scene mới" : "Create New 3D Scene";
}
/**
@@ -689,6 +695,10 @@ function openEditSceneModal(scene) {
document.getElementById('modal-privacy').value = scene.privacy;
document.getElementById('modal-panorama').required = false; // Photo update is optional
const lang = systemSettings.language || 'vi';
const modalTitle = document.getElementById('create-scene-modal-title');
if (modalTitle) modalTitle.innerText = lang === 'vi' ? "Sửa 3D scene" : "Edit 3D scene";
toggleSharedUsers();
document.getElementById('create-scene-modal').style.display = 'flex';
}
@@ -1277,22 +1287,38 @@ async function loadMyAssets() {
/**
* Xóa ảnh khỏi kho media
*/
window.deleteAsset = async function(assetId) {
if (!confirm('Bạn có chắc chắn muốn xóa ảnh này? Nếu ảnh đang được gắn vào một cảnh, cảnh đó cũng sẽ bị xóa vĩnh viễn.')) {
return;
}
window.deleteAsset = function(assetId) {
assetIdToDelete = assetId;
document.getElementById('delete-asset-confirm-modal').style.display = 'flex';
};
window.closeDeleteAssetModal = function() {
document.getElementById('delete-asset-confirm-modal').style.display = 'none';
assetIdToDelete = null;
};
window.confirmDeleteAsset = async function() {
if (!assetIdToDelete) return;
const token = localStorage.getItem('jwt');
try {
const res = await fetch(`${API_BASE_URL}/assets/${assetId}`, {
const res = await fetch(`${API_BASE_URL}/assets/${assetIdToDelete}`, {
method: 'DELETE',
headers: { 'Authorization': `Bearer ${token}` }
});
const data = await res.json();
let data;
const contentType = res.headers.get("content-type");
if (contentType && contentType.includes("application/json")) {
data = await res.json();
}
if (!res.ok) throw new Error(data.message);
if (!res.ok) {
throw new Error(data?.message || `Lỗi máy chủ (${res.status})`);
}
alert(data.message);
closeDeleteAssetModal();
showSuccessModal(data.message || "Đã xóa thành công");
loadMyAssets(); // Nạp lại kho ảnh
loadScenes(); // Nạp lại bản đồ nếu có scene bị xóa kèm theo
} catch (e) {
@@ -1300,11 +1326,38 @@ window.deleteAsset = async function(assetId) {
}
};
/**
* Hiển thị Modal thông báo thành công
*/
window.showSuccessModal = function(message) {
const modal = document.getElementById('success-modal');
const msgElem = document.getElementById('success-modal-message');
if (modal && msgElem) {
msgElem.innerText = message;
modal.style.display = 'flex';
// Tự động ẩn sau 3 giây
setTimeout(() => closeSuccessModal(), 3000);
}
};
/**
* Đóng Modal thành công (hỗ trợ click ra ngoài)
*/
window.closeSuccessModal = function(e) {
const modal = document.getElementById('success-modal');
if (!modal) return;
// Nếu nhấn từ code (không có e) hoặc click trúng overlay thì đóng
if (e && e.target !== modal) return;
modal.style.display = 'none';
};
window.openEditFromMedia = function(scene) {
if (!scene || !scene._id) {
alert("Không thể chỉnh sửa: Ảnh này không được gắn với một Scene hợp lệ.");
return;
}
returnToDashboardAfterEdit = true;
closeDashboard();
openEditSceneModal(scene);
};