Files
video-factory/shortdrama/view/modal-prop.html
T
2026-07-01 10:26:01 +08:00

121 lines
6.2 KiB
HTML

<script>
// ==================== 道具管理 ====================
function openPropModal(id) {
currentDramaId = id;
document.getElementById('propModal').classList.add('show');
document.getElementById('propModalDramaTitle').textContent = '加载中...';
document.getElementById('propModalDramaMeta').textContent = '';
document.getElementById('propList').innerHTML = '<div style="color:#999;font-size:13px;text-align:center;padding:20px;">加载中...</div>';
fetch('/drama/get?id=' + id).then(r => r.json()).then(data => {
if (data.code !== 0) throw new Error(data.message);
const d = data.data;
document.getElementById('propModalDramaTitle').textContent = d.title || '未命名短剧';
document.getElementById('propModalDramaMeta').textContent = (d.style || '') + ' · 道具';
renderPropList(d.props || []);
}).catch(err => {
document.getElementById('propList').innerHTML = '<div style="color:red;font-size:13px;text-align:center;padding:20px;">加载失败: ' + err.message + '</div>';
});
}
function hidePropModal() {
document.getElementById('propModal').classList.remove('show');
currentDramaId = null;
}
function renderPropList(props) {
currentChars = props;
const list = document.getElementById('propList');
if (!props || props.length === 0) {
list.innerHTML = '<div style="color:#999;font-size:13px;padding:8px 0">暂无道具,点击下方添加</div>';
return;
}
list.innerHTML = props.map(function(p, i) {
var initial = p.name ? p.name.charAt(0) : '?';
var imgUrl = p.imagePath ? '/' + p.imagePath : '';
return '<div style="display:flex;gap:8px;align-items:center;padding:8px 10px;background:#fafafa;border-radius:8px;border:1px solid #eee;margin-bottom:6px;">'
+ (imgUrl ? '<img src="' + imgUrl + '" style="width:36px;height:36px;border-radius:6px;object-fit:cover;flex-shrink:0;">' : '<span style="width:36px;height:36px;border-radius:6px;background:#e0e0e0;display:inline-flex;align-items:center;justify-content:center;font-size:15px;font-weight:bold;color:#666;flex-shrink:0;">' + initial + '</span>')
+ '<div style="flex:1;font-size:13px;"><strong>' + escHtml(p.name) + '</strong>' + (p.description ? '<br><span style="color:#888;font-size:11px;">' + escHtml(p.description) + '</span>' : '') + '</div>'
+ '<div style="display:flex;gap:4px;flex-shrink:0;">'
+ '<button class="btn btn-sm btn-outline" onclick="editProp(' + i + ')" style="padding:2px 8px;font-size:11px;">编辑</button>'
+ '<button class="btn btn-sm btn-danger" onclick="deleteProp(' + i + ')" style="padding:2px 8px;font-size:11px;">删除</button></div></div>';
}).join('');
}
function showPropForm() {
document.getElementById('modalPropTitle').textContent = '添加道具';
document.getElementById('editModalPropIdx').value = '-1';
document.getElementById('modalPropName').value = '';
document.getElementById('modalPropDesc').value = '';
document.getElementById('modalPropImage').value = '';
document.getElementById('modalPropModal').classList.add('show');
}
function hideModalPropForm() { document.getElementById('modalPropModal').classList.remove('show'); }
function editProp(idx) {
var p = currentChars[idx]; if (!p) return;
document.getElementById('modalPropTitle').textContent = '编辑道具';
document.getElementById('editModalPropIdx').value = p.id;
document.getElementById('modalPropName').value = p.name || '';
document.getElementById('modalPropDesc').value = p.description || '';
document.getElementById('modalPropImage').value = '';
document.getElementById('modalPropModal').classList.add('show');
}
async function saveProp() {
var name = document.getElementById('modalPropName').value.trim();
if (!name) { alert('请输入道具名'); return; }
var id = parseInt(document.getElementById('editModalPropIdx').value);
const btn = event.target; btn.disabled = true;
try {
var formData = new FormData();
formData.append('dramaId', currentDramaId);
formData.append('name', name);
formData.append('description', document.getElementById('modalPropDesc').value.trim());
var imgInput = document.getElementById('modalPropImage');
if (imgInput.files && imgInput.files[0]) {
formData.append('imageFile', imgInput.files[0]);
}
if (id >= 0) formData.append('id', id);
const url = id >= 0 ? '/drama/prop/update' : '/drama/prop/add';
const resp = await fetch(url, { method: 'POST', body: formData });
const data = await resp.json();
if (data.code !== 0) throw new Error(data.message);
hideModalPropForm();
openPropModal(currentDramaId);
} catch (err) { alert('保存道具失败: ' + err.message); }
finally { btn.disabled = false; }
}
function deleteProp(idx) {
var p = currentChars[idx]; if (!p) return;
confirmAction = async function() {
try {
const resp = await fetch('/drama/prop/delete', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: parseInt(p.id), dramaId: parseInt(currentDramaId) }) });
const data = await resp.json(); if (data.code !== 0) throw new Error(data.message);
openPropModal(currentDramaId);
} catch (err) { alert('删除道具失败: ' + err.message); }
};
document.getElementById('confirmTitle').textContent = '删除道具';
document.getElementById('confirmMsg').textContent = '确定要删除道具「' + p.name + '」吗?';
document.getElementById('confirmBtn').className = 'btn btn-danger';
document.getElementById('confirmModal').classList.add('show');
}
</script>
<!-- 道具管理弹窗 -->
<div class="modal-overlay" id="propModal">
<div class="modal" style="width:80vw;height:80vh;max-width:1100px;padding:24px 28px;display:flex;flex-direction:column;">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:16px;flex-shrink:0;">
<div>
<h3 id="propModalDramaTitle" style="margin-bottom:4px;">道具管理</h3>
<span id="propModalDramaMeta" style="font-size:12px;color:#888;"></span>
</div>
<button class="btn btn-outline btn-sm" onclick="hidePropModal()">关闭</button>
</div>
<div id="propList" style="flex:1;overflow-y:auto;padding-right:8px;min-height:60px;"></div>
<div class="add-link" onclick="showPropForm()" style="margin-top:8px;flex-shrink:0;">+ 添加道具</div>
</div>
</div>