// DOM元素 const cardTitleInput = document.getElementById('card-title'); const characterNameInput = document.getElementById('character-name'); const characterTitleInput = document.getElementById('character-title'); const characterAvatarInput = document.getElementById('character-avatar'); const cardDescriptionInput = document.getElementById('card-description'); const optionATextInput = document.getElementById('option-a-text'); const optionBTextInput = document.getElementById('option-b-text'); // 选项A的效果输入 const optionALoyalty = document.getElementById('option-a-loyalty'); const optionAChaos = document.getElementById('option-a-chaos'); const optionAPopulation = document.getElementById('option-a-population'); const optionAMilitary = document.getElementById('option-a-military'); const optionAResources = document.getElementById('option-a-resources'); // 选项B的效果输入 const optionBLoyalty = document.getElementById('option-b-loyalty'); const optionBChaos = document.getElementById('option-b-chaos'); const optionBPopulation = document.getElementById('option-b-population'); const optionBMilitary = document.getElementById('option-b-military'); const optionBResources = document.getElementById('option-b-resources'); // 表单和按钮 const createCardForm = document.getElementById('create-card-form'); const previewButton = document.getElementById('preview-button'); // 计数器元素 const titleCount = document.getElementById('title-count'); const nameCount = document.getElementById('name-count'); const titleCount2 = document.getElementById('title-count-2'); const descCount = document.getElementById('desc-count'); const optionACount = document.getElementById('option-a-count'); const optionBCount = document.getElementById('option-b-count'); // 效果总计 const optionATotal = document.getElementById('option-a-total'); const optionBTotal = document.getElementById('option-b-total'); const optionAWarning = document.getElementById('option-a-warning'); const optionBWarning = document.getElementById('option-b-warning'); // 预览模态框元素 const previewModal = document.getElementById('preview-modal'); const closePreview = document.getElementById('close-preview'); const previewCardTitle = document.getElementById('preview-card-title'); const previewCharacterName = document.getElementById('preview-character-name'); const previewCharacterTitle = document.getElementById('preview-character-title'); const previewCharacterAvatar = document.getElementById('preview-character-avatar'); const previewCardDescription = document.getElementById('preview-card-description'); const previewOptionAText = document.getElementById('preview-option-a-text'); const previewOptionBText = document.getElementById('preview-option-b-text'); const previewOptionAEffects = document.getElementById('preview-option-a-effects'); const previewOptionBEffects = document.getElementById('preview-option-b-effects'); // 表情符号选择器 const emojiItems = document.querySelectorAll('.emoji-item'); // 页面加载完成后初始化 document.addEventListener('DOMContentLoaded', () => { // 添加字符计数事件监听器 setupCharacterCounter(cardTitleInput, titleCount, 50); setupCharacterCounter(characterNameInput, nameCount, 30); setupCharacterCounter(characterTitleInput, titleCount2, 30); setupCharacterCounter(cardDescriptionInput, descCount, 200); setupCharacterCounter(optionATextInput, optionACount, 50); setupCharacterCounter(optionBTextInput, optionBCount, 50); // 添加效果值变化监听器 setupEffectListeners('option-a'); setupEffectListeners('option-b'); // 预览按钮点击事件 previewButton.addEventListener('click', showPreview); // 关闭预览模态框 closePreview.addEventListener('click', () => { previewModal.style.display = 'none'; }); // 点击模态框外部关闭 window.addEventListener('click', (event) => { if (event.target === previewModal) { previewModal.style.display = 'none'; } }); // 表单提交事件 createCardForm.addEventListener('submit', submitCard); // 表情符号选择器 emojiItems.forEach(item => { item.addEventListener('click', () => { const emoji = item.getAttribute('data-emoji'); characterAvatarInput.value = emoji; }); }); }); // 设置字符计数器 function setupCharacterCounter(input, counter, maxLength) { // 初始更新 updateCharacterCount(input, counter); // 添加输入事件监听器 input.addEventListener('input', () => { updateCharacterCount(input, counter); }); } // 更新字符计数 function updateCharacterCount(input, counter) { const length = input.value.length; counter.textContent = length; // 如果超过最大长度,添加警告样式 if (length >= parseInt(input.getAttribute('maxlength'))) { counter.parentElement.classList.add('warning'); } else { counter.parentElement.classList.remove('warning'); } } // 设置效果值监听器 function setupEffectListeners(prefix) { const effects = [ document.getElementById(`${prefix}-loyalty`), document.getElementById(`${prefix}-chaos`), document.getElementById(`${prefix}-population`), document.getElementById(`${prefix}-military`), document.getElementById(`${prefix}-resources`) ]; // 为每个效果输入添加监听器 effects.forEach(effect => { effect.addEventListener('input', () => { updateEffectsTotal(prefix); }); }); // 初始计算总和 updateEffectsTotal(prefix); } // 更新效果总和 function updateEffectsTotal(prefix) { const effects = [ parseInt(document.getElementById(`${prefix}-loyalty`).value) || 0, parseInt(document.getElementById(`${prefix}-chaos`).value) || 0, parseInt(document.getElementById(`${prefix}-population`).value) || 0, parseInt(document.getElementById(`${prefix}-military`).value) || 0, parseInt(document.getElementById(`${prefix}-resources`).value) || 0 ]; // 计算绝对值总和 const total = effects.reduce((sum, effect) => sum + Math.abs(effect), 0); // 更新显示 const totalElement = document.getElementById(`${prefix}-total`); const warningElement = document.getElementById(`${prefix}-warning`); // 添加空检查 if (totalElement) { totalElement.textContent = total; } else { console.error(`找不到元素: ${prefix}-total`); } // 添加空检查 if (warningElement) { if (total > 80) { warningElement.style.display = 'block'; if (totalElement) totalElement.classList.add('warning'); } else { warningElement.style.display = 'none'; if (totalElement) totalElement.classList.remove('warning'); } } } // 获取选项效果对象 function getOptionEffects(prefix) { return { loyalty: parseInt(document.getElementById(`${prefix}-loyalty`).value) || 0, chaos: parseInt(document.getElementById(`${prefix}-chaos`).value) || 0, population: parseInt(document.getElementById(`${prefix}-population`).value) || 0, military: parseInt(document.getElementById(`${prefix}-military`).value) || 0, resources: parseInt(document.getElementById(`${prefix}-resources`).value) || 0 }; } // 生成效果标签HTML function generateEffectTags(effects) { const tags = []; for (const [stat, value] of Object.entries(effects)) { if (value === 0) continue; let statName = ''; let statIcon = ''; switch (stat) { case 'loyalty': statName = '帝国忠诚度'; statIcon = '🦅'; break; case 'chaos': statName = '混沌侵染'; statIcon = '🌀'; break; case 'population': statName = '民众控制'; statIcon = '👥'; break; case 'military': statName = '军事力量'; statIcon = '🔫'; break; case 'resources': statName = '资源储备'; statIcon = '⚙️'; break; } const isPositive = value > 0; tags.push(`
${statIcon} ${statName} ${isPositive ? '+' : ''}${value}
`); } return tags.join(''); } // 验证表单 function validateForm() { // 基本字段验证 if (!cardTitleInput.value.trim()) { showMessage('请输入卡牌标题'); cardTitleInput.focus(); return false; } if (!characterNameInput.value.trim()) { showMessage('请输入角色名称'); characterNameInput.focus(); return false; } if (!characterTitleInput.value.trim()) { showMessage('请输入角色头衔'); characterTitleInput.focus(); return false; } if (!characterAvatarInput.value.trim()) { showMessage('请选择角色图标'); characterAvatarInput.focus(); return false; } if (!cardDescriptionInput.value.trim()) { showMessage('请输入卡牌描述'); cardDescriptionInput.focus(); return false; } if (!optionATextInput.value.trim()) { showMessage('请输入选项A文本'); optionATextInput.focus(); return false; } if (!optionBTextInput.value.trim()) { showMessage('请输入选项B文本'); optionBTextInput.focus(); return false; } // 效果值总和验证 const optionAEffectsTotal = Object.values(getOptionEffects('option-a')).reduce((sum, val) => sum + Math.abs(val), 0); const optionBEffectsTotal = Object.values(getOptionEffects('option-b')).reduce((sum, val) => sum + Math.abs(val), 0); if (optionAEffectsTotal > 80) { showMessage('选项A的效果总和不能超过40'); return false; } if (optionBEffectsTotal > 80) { showMessage('选项B的效果总和不能超过40'); return false; } return true; } // 显示预览 function showPreview() { if (!validateForm()) return; // 填充预览内容 previewCardTitle.textContent = cardTitleInput.value; previewCharacterName.textContent = characterNameInput.value; previewCharacterTitle.textContent = characterTitleInput.value; previewCharacterAvatar.textContent = characterAvatarInput.value; previewCardDescription.textContent = cardDescriptionInput.value; previewOptionAText.textContent = optionATextInput.value; previewOptionBText.textContent = optionBTextInput.value; // 生成效果标签 const optionAEffects = getOptionEffects('option-a'); const optionBEffects = getOptionEffects('option-b'); previewOptionAEffects.innerHTML = generateEffectTags(optionAEffects); previewOptionBEffects.innerHTML = generateEffectTags(optionBEffects); // 显示预览模态框 previewModal.style.display = 'block'; } async function submitCard(event) { event.preventDefault(); console.log("表单提交触发"); // 添加调试日志 if (!validateForm()) return; // 构造卡牌数据 const cardData = { title: cardTitleInput.value.trim(), character: { name: characterNameInput.value.trim(), title: characterTitleInput.value.trim(), avatar: characterAvatarInput.value.trim() }, description: cardDescriptionInput.value.trim(), option_a: { text: optionATextInput.value.trim(), effects: getOptionEffects('option-a') }, option_b: { text: optionBTextInput.value.trim(), effects: getOptionEffects('option-b') } }; console.log("准备发送的数据:", cardData); // 添加调试日志 try { // 显示加载状态 const submitButton = createCardForm.querySelector('button[type="submit"]'); const originalText = submitButton.textContent; submitButton.disabled = true; submitButton.textContent = '提交中...'; // 发送请求 const response = await fetch('/api/create_custom_card', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(cardData) }); console.log("服务器响应状态:", response.status); // 添加调试日志 if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.message || '创建卡牌失败'); } const result = await response.json(); console.log("创建成功, 结果:", result); // 添加调试日志 // 创建成功,跳转到卡牌列表页 window.location.href = '/custom_cards'; } catch (error) { console.error('创建卡牌失败:', error); showMessage(error.message || '创建卡牌失败,请稍后再试'); // 恢复按钮状态 const submitButton = createCardForm.querySelector('button[type="submit"]'); submitButton.disabled = false; submitButton.textContent = '提交卡牌'; } } // 显示消息(临时弹出提示) function showMessage(message) { const messageElement = document.createElement('div'); messageElement.className = 'message-popup'; messageElement.textContent = message; document.body.appendChild(messageElement); // 消息显示动画 setTimeout(() => { messageElement.classList.add('show'); }, 10); // 3秒后移除消息 setTimeout(() => { messageElement.classList.remove('show'); setTimeout(() => { messageElement.remove(); }, 300); }, 3000); }