Files
showpic/public/js/admin.js
T
2026-07-16 22:51:02 +08:00

322 lines
9.3 KiB
JavaScript

document.addEventListener('DOMContentLoaded', function() {
checkAuth();
loadConfig();
loadGroups();
document.getElementById('logout').addEventListener('click', logout);
document.getElementById('featureToggle').addEventListener('change', toggleFeature);
document.getElementById('addGroupBtn').addEventListener('click', addGroup);
document.getElementById('uploadBtn').addEventListener('click', () => document.getElementById('fileInput').click());
document.getElementById('fileInput').addEventListener('change', handleFileSelect);
document.getElementById('cropCancel').addEventListener('click', closeCropModal);
document.getElementById('cropConfirm').addEventListener('click', cropAndUpload);
});
let cropper = null;
let selectedFile = null;
function checkAuth() {
const token = localStorage.getItem('token');
if (!token) {
window.location.href = '/login';
return;
}
// 验证token有效性(可选)
}
async function logout() {
localStorage.removeItem('token');
window.location.href = '/login';
}
async function loadConfig() {
try {
const response = await fetch('/api/config');
const config = await response.json();
document.getElementById('featureToggle').checked = config.feature_enabled === 'true';
} catch (error) {
console.error('加载配置失败:', error);
}
}
async function toggleFeature() {
const enabled = document.getElementById('featureToggle').checked;
try {
await fetch('/api/config', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${localStorage.getItem('token')}`
},
body: JSON.stringify({ key: 'feature_enabled', value: enabled.toString() })
});
} catch (error) {
console.error('更新配置失败:', error);
}
}
async function loadGroups() {
try {
const response = await fetch('/api/groups');
const groups = await response.json();
renderGroups(groups);
updateGroupSelect(groups);
} catch (error) {
console.error('加载分组失败:', error);
}
}
function renderGroups(groups) {
const container = document.getElementById('groupsList');
container.innerHTML = '';
groups.forEach(group => {
const groupItem = document.createElement('div');
groupItem.className = 'group-item';
groupItem.innerHTML = `
<div>
<strong>${group.name}</strong>
<span style="margin-left: 10px; color: #666;">展示时间: ${group.display_seconds}秒</span>
</div>
<div>
<button class="btn btn-danger" onclick="deleteGroup(${group.id})">删除</button>
</div>
`;
container.appendChild(groupItem);
});
}
function updateGroupSelect(groups) {
const select = document.getElementById('groupSelect');
select.innerHTML = '<option value="">请选择分组</option>';
groups.forEach(group => {
const option = document.createElement('option');
option.value = group.id;
option.textContent = group.name;
select.appendChild(option);
});
}
async function addGroup() {
const name = prompt('请输入分组名称:');
if (!name) return;
const displaySeconds = prompt('请输入展示时间(秒):', '30');
if (!displaySeconds) return;
try {
const token = localStorage.getItem('token');
const response = await fetch('/api/groups', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({ name, display_seconds: parseInt(displaySeconds) })
});
if (response.ok) {
loadGroups();
}
} catch (error) {
console.error('添加分组失败:', error);
}
}
async function deleteGroup(id) {
if (!confirm('确定要删除这个分组吗?')) return;
try {
const token = localStorage.getItem('token');
const response = await fetch(`/api/groups/${id}`, {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${token}`
}
});
if (response.ok) {
loadGroups();
}
} catch (error) {
console.error('删除分组失败:', error);
}
}
async function handleFileSelect(e) {
const file = e.target.files[0];
if (!file) return;
selectedFile = file;
const reader = new FileReader();
reader.onload = function(e) {
const cropImage = document.getElementById('cropImage');
cropImage.src = e.target.result;
document.getElementById('cropModal').style.display = 'block';
if (cropper) {
cropper.destroy();
}
cropper = new Cropper(cropImage, {
aspectRatio: 1,
viewMode: 1,
autoCropArea: 1,
ready: function() {
// 裁剪器就绪
}
});
};
reader.readAsDataURL(file);
e.target.value = '';
}
function closeCropModal() {
document.getElementById('cropModal').style.display = 'none';
if (cropper) {
cropper.destroy();
cropper = null;
}
selectedFile = null;
}
async function cropAndUpload() {
if (!cropper || !selectedFile) return;
const groupId = document.getElementById('groupSelect').value;
if (!groupId) {
alert('请先选择分组');
return;
}
try {
// 获取裁剪后的canvas
const canvas = cropper.getCroppedCanvas({
width: 280,
height: 280
});
// 压缩图片
const compressedBlob = await compressImage(canvas, 0.7);
// 创建FormData
const formData = new FormData();
formData.append('image', compressedBlob, selectedFile.name);
formData.append('group_id', groupId);
// 上传
const token = localStorage.getItem('token');
const response = await fetch('/api/upload', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`
},
body: formData
});
if (response.ok) {
closeCropModal();
loadImages(groupId);
alert('上传成功');
} else {
alert('上传失败');
}
} catch (error) {
console.error('上传失败:', error);
alert('上传失败');
}
}
function compressImage(canvas, quality) {
return new Promise((resolve) => {
canvas.toBlob((blob) => {
resolve(blob);
}, 'image/jpeg', quality);
});
}
async function loadImages(groupId) {
if (!groupId) {
document.getElementById('imageList').innerHTML = '';
return;
}
try {
const response = await fetch(`/api/images?group_id=${groupId}`);
const images = await response.json();
renderImages(images);
} catch (error) {
console.error('加载图片失败:', error);
}
}
function renderImages(images) {
const container = document.getElementById('imageList');
container.innerHTML = '';
images.forEach(image => {
const imageCard = document.createElement('div');
imageCard.className = `image-card ${image.enabled ? '' : 'disabled'}`;
imageCard.innerHTML = `
<img src="/uploads/${image.filename}" alt="${image.original_name}">
<div class="actions">
<button class="btn btn-success" onclick="toggleImage(${image.id}, ${image.enabled ? 0 : 1})">
${image.enabled ? '下架' : '上架'}
</button>
<button class="btn btn-danger" onclick="deleteImage(${image.id})">删除</button>
</div>
`;
container.appendChild(imageCard);
});
}
async function toggleImage(id, enable) {
try {
const token = localStorage.getItem('token');
const endpoint = enable ? 'enable' : 'disable';
const response = await fetch(`/api/images/${id}/${endpoint}`, {
method: 'PUT',
headers: {
'Authorization': `Bearer ${token}`
}
});
if (response.ok) {
const groupId = document.getElementById('groupSelect').value;
loadImages(groupId);
}
} catch (error) {
console.error('更新图片状态失败:', error);
}
}
async function deleteImage(id) {
if (!confirm('确定要删除这张图片吗?')) return;
try {
const token = localStorage.getItem('token');
const response = await fetch(`/api/images/${id}`, {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${token}`
}
});
if (response.ok) {
const groupId = document.getElementById('groupSelect').value;
loadImages(groupId);
}
} catch (error) {
console.error('删除图片失败:', error);
}
}
// 分组选择变化时加载图片
document.getElementById('groupSelect').addEventListener('change', function() {
loadImages(this.value);
});