Warhummer/templates/admin/characters.html
2025-06-25 09:35:26 +08:00

541 lines
26 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>管理人物 - 战锤40K行星总督</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/admin.css') }}">
</head>
<body class="admin-page">
<div class="admin-sidebar">
<div class="admin-logo">
<h2>战锤40K</h2>
<p>管理员控制台</p>
</div>
<nav class="admin-nav">
<a href="{{ url_for('admin_index') }}">
<span class="icon">🏠</span>
<span class="text">主页</span>
</a>
<a href="{{ url_for('admin_characters') }}" class="active">
<span class="icon">👤</span>
<span class="text">管理人物</span>
</a>
<a href="{{ url_for('admin_dashboard') }}">
<span class="icon">📊</span>
<span class="text">数据面板</span>
</a>
<a href="{{ url_for('admin_logout') }}" class="logout">
<span class="icon">🚪</span>
<span class="text">登出</span>
</a>
</nav>
</div>
<div class="admin-content">
<header class="admin-header">
<h1>管理人物</h1>
<div class="header-actions">
<button id="new-character-btn" class="btn btn-primary">
<span class="icon">+</span> 新建人物
</button>
</div>
</header>
<div class="admin-toolbar">
<div class="search-box">
<input type="text" id="character-search" placeholder="搜索人物...">
</div>
<div class="filter-options">
<select id="character-type-filter">
<option value="all">所有类型</option>
<option value="resident">常驻角色</option>
<option value="special">特殊角色</option>
<option value="status">状态效果</option>
</select>
</div>
</div>
<div class="characters-grid" id="characters-container">
<!-- 角色列表将通过JavaScript加载 -->
<div class="loading-indicator">加载中...</div>
</div>
</div>
<!-- 模态框容器 - 将所有模态框放在body的直接子元素位置 -->
<div id="modals-container">
<!-- 角色编辑对话框 -->
<div class="modal" id="character-modal">
<div class="modal-content">
<div class="modal-header">
<h2 id="modal-title">编辑人物</h2>
<span class="close-modal">&times;</span>
</div>
<div class="modal-body">
<form id="character-form">
<input type="hidden" id="character-id">
<div class="form-row">
<div class="form-group">
<label for="character-name">名称</label>
<input type="text" id="character-name" required>
</div>
<div class="form-group">
<label for="character-title">称号</label>
<input type="text" id="character-title" required>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="character-avatar">头像表情</label>
<input type="text" id="character-avatar" required placeholder="使用Emoji或符号">
</div>
<div class="form-group">
<label for="character-avatar-path">头像图片路径</label>
<input type="text" id="character-avatar-path" placeholder="例如: images/characters/name.png">
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="character-type">人物类型</label>
<select id="character-type" required>
<option value="resident">常驻角色</option>
<option value="special">特殊角色</option>
<option value="status">状态效果</option>
</select>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="character-weight">出现权重 (1-1000)</label>
<input type="number" id="character-weight" min="1" max="1000" value="100" required>
<small class="help-text">数值越大角色出现概率越高。默认值为100。</small>
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">保存</button>
<button type="button" class="btn btn-secondary close-btn">取消</button>
</div>
</form>
</div>
</div>
</div>
<!-- 事件编辑对话框 -->
<div class="modal" id="event-modal">
<div class="modal-content">
<div class="modal-header">
<h2 id="event-modal-title">编辑事件</h2>
<span class="close-modal">&times;</span>
</div>
<div class="modal-body">
<form id="event-form">
<input type="hidden" id="event-character-id">
<input type="hidden" id="event-id">
<div class="form-group">
<label for="event-text">事件描述</label>
<textarea id="event-text" required rows="3"></textarea>
</div>
<div class="event-options">
<div class="event-option">
<h3>选项A (蓝色/左滑)</h3>
<div class="form-group">
<label for="option-a-text">文本</label>
<input type="text" id="option-a-text" required>
</div>
<div class="effects-grid">
<div class="effect-item">
<label for="option-a-loyalty">忠诚度</label>
<input type="number" id="option-a-loyalty" min="-25" max="25" value="0">
</div>
<div class="effect-item">
<label for="option-a-chaos">混沌</label>
<input type="number" id="option-a-chaos" min="-25" max="25" value="0">
</div>
<div class="effect-item">
<label for="option-a-population">人口</label>
<input type="number" id="option-a-population" min="-25" max="25" value="0">
</div>
<div class="effect-item">
<label for="option-a-military">军事</label>
<input type="number" id="option-a-military" min="-25" max="25" value="0">
</div>
<div class="effect-item">
<label for="option-a-resources">资源</label>
<input type="number" id="option-a-resources" min="-25" max="25" value="0">
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="option-a-add-status">添加状态</label>
<input type="text" id="option-a-add-status" placeholder="状态ID (可选)">
</div>
<div class="form-group">
<label for="option-a-remove-status">移除状态</label>
<input type="text" id="option-a-remove-status" placeholder="状态ID (可选)">
</div>
</div>
</div>
<div class="event-option">
<h3>选项B (红色/右滑)</h3>
<div class="form-group">
<label for="option-b-text">文本</label>
<input type="text" id="option-b-text" required>
</div>
<div class="effects-grid">
<div class="effect-item">
<label for="option-b-loyalty">忠诚度</label>
<input type="number" id="option-b-loyalty" min="-25" max="25" value="0">
</div>
<div class="effect-item">
<label for="option-b-chaos">混沌</label>
<input type="number" id="option-b-chaos" min="-25" max="25" value="0">
</div>
<div class="effect-item">
<label for="option-b-population">人口</label>
<input type="number" id="option-b-population" min="-25" max="25" value="0">
</div>
<div class="effect-item">
<label for="option-b-military">军事</label>
<input type="number" id="option-b-military" min="-25" max="25" value="0">
</div>
<div class="effect-item">
<label for="option-b-resources">资源</label>
<input type="number" id="option-b-resources" min="-25" max="25" value="0">
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="option-b-add-status">添加状态</label>
<input type="text" id="option-b-add-status" placeholder="状态ID (可选)">
</div>
<div class="form-group">
<label for="option-b-remove-status">移除状态</label>
<input type="text" id="option-b-remove-status" placeholder="状态ID (可选)">
</div>
</div>
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">保存事件</button>
<button type="button" class="btn btn-secondary close-btn">取消</button>
</div>
</form>
</div>
</div>
</div>
<!-- 角色详情对话框 -->
<div class="modal" id="character-detail-modal">
<div class="modal-content">
<div class="modal-header">
<h2 id="detail-title">角色详情</h2>
<span class="close-modal">&times;</span>
</div>
<div class="modal-body">
<div class="character-info-section">
<div class="character-header">
<div class="character-avatar" id="detail-avatar">👤</div>
<div class="character-header-info">
<h3 id="detail-name">角色名称</h3>
<p id="detail-title-text">角色称号</p>
<p id="detail-type">角色类型</p>
<p id="detail-weight" class="character-weight">出现权重: <span>5</span></p>
</div>
</div>
<div class="character-actions">
<button id="edit-character-btn" class="btn btn-secondary">
<span class="icon">✏️</span> 编辑角色
</button>
<button id="delete-character-btn" class="btn btn-danger">
<span class="icon">🗑️</span> 删除角色
</button>
</div>
</div>
<div class="character-events-section">
<div class="section-header">
<h3>事件列表</h3>
<button id="add-event-btn" class="btn btn-primary">
<span class="icon">+</span> 添加事件
</button>
</div>
<div id="events-container" class="events-list">
<!-- 事件列表将通过JavaScript加载 -->
<div class="empty-events">该角色暂无事件</div>
</div>
</div>
</div>
</div>
</div>
<!-- 确认对话框 -->
<div class="modal" id="confirm-modal">
<div class="modal-content">
<div class="modal-header">
<h2 id="confirm-title">确认操作</h2>
<span class="close-modal">&times;</span>
</div>
<div class="modal-body">
<p id="confirm-message">您确定要执行此操作吗?</p>
<div class="form-actions">
<button id="confirm-ok" class="btn btn-danger">确认</button>
<button id="confirm-cancel" class="btn btn-secondary close-btn">取消</button>
</div>
</div>
</div>
</div>
</div>
<!-- 角色管理页面脚本 -->
<script src="{{ url_for('static', filename='js/admin/characters.js') }}"></script>
<!-- 紧急修复代码 - 添加在 </body> 标签之前 -->
<style>
/* 强制修复模态框样式 */
.modal {
position: fixed !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
bottom: 0 !important;
width: 100vw !important;
height: 100vh !important;
background-color: rgba(0, 0, 0, 0.5) !important;
z-index: 999999 !important;
display: none;
padding: 20px !important;
box-sizing: border-box !important;
overflow: auto !important;
}
/* 确保每个模态框有不同的z-index确认框最高 */
#character-modal { z-index: 999997 !important; }
#event-modal { z-index: 999998 !important; }
#character-detail-modal { z-index: 999996 !important; }
#confirm-modal { z-index: 999999 !important; }
/* 确保内容显示在最上层 */
.modal-content {
position: relative !important;
background-color: white !important;
margin: 10vh auto !important;
max-width: 800px !important;
width: 90% !important;
border-radius: 8px !important;
overflow: hidden !important;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5) !important;
max-height: 80vh !important;
display: flex !important;
flex-direction: column !important;
}
.modal-body {
overflow-y: auto !important;
max-height: 60vh !important;
padding: 20px !important;
}
/* 确保确认模态框居中 */
#confirm-modal .modal-content {
max-width: 500px !important;
}
/* 特殊处理事件模态框 */
#event-modal .modal-content {
max-width: 1000px !important;
max-height: 90vh !important;
}
/* 移动设备适配 */
@media (max-width: 768px) {
.modal-content {
width: 95% !important;
margin: 5vh auto !important;
}
.modal-body {
max-height: 70vh !important;
}
.event-options {
flex-direction: column !important;
}
}
</style>
<script>
// 紧急修复脚本
document.addEventListener('DOMContentLoaded', function() {
// 强制修复模态框问题
// 当点击"编辑角色"按钮时
document.getElementById('edit-character-btn').addEventListener('click', function(e) {
e.preventDefault();
e.stopPropagation();
// 先关闭详情模态框
document.getElementById('character-detail-modal').style.display = 'none';
// 再异步打开编辑模态框
setTimeout(function() {
if (currentCharacter) {
// 填充表单
document.getElementById('character-id').value = currentCharacter.id;
document.getElementById('character-name').value = currentCharacter.name || '';
document.getElementById('character-title').value = currentCharacter.title || '';
document.getElementById('character-avatar').value = currentCharacter.avatar || '';
document.getElementById('character-avatar-path').value = currentCharacter.avatarPath || '';
document.getElementById('character-type').value = currentCharacter.type || 'resident';
// 打开模态框
document.getElementById('character-modal').style.display = 'block';
}
}, 100);
return false;
});
// 当点击"添加事件"按钮时
document.getElementById('add-event-btn').addEventListener('click', function(e) {
e.preventDefault();
e.stopPropagation();
// 先关闭详情模态框
document.getElementById('character-detail-modal').style.display = 'none';
// 异步打开事件模态框
setTimeout(function() {
if (currentCharacter) {
// 重置表单
document.getElementById('event-form').reset();
document.getElementById('event-character-id').value = currentCharacter.id;
document.getElementById('event-id').value = generateUUID(); // 假设这个函数存在
// 打开模态框
document.getElementById('event-modal').style.display = 'block';
}
}, 100);
return false;
});
// 处理所有关闭按钮
document.querySelectorAll('.close-modal, .close-btn').forEach(function(btn) {
btn.addEventListener('click', function(e) {
e.preventDefault();
e.stopPropagation();
// 找到最近的模态框
var modal = this.closest('.modal');
if (modal) {
modal.style.display = 'none';
}
return false;
});
});
// 点击模态框背景关闭
document.querySelectorAll('.modal').forEach(function(modal) {
modal.addEventListener('click', function(e) {
if (e.target === this) {
this.style.display = 'none';
}
});
});
// 阻止内容区域点击传播
document.querySelectorAll('.modal-content').forEach(function(content) {
content.addEventListener('click', function(e) {
e.stopPropagation();
});
});
// 处理编辑事件按钮
document.addEventListener('click', function(e) {
if (e.target.classList.contains('edit-event-btn') || e.target.closest('.edit-event-btn')) {
e.preventDefault();
e.stopPropagation();
// 找到事件项
var eventItem = e.target.closest('.event-item');
if (!eventItem) return;
// 关闭详情模态框
document.getElementById('character-detail-modal').style.display = 'none';
// 获取事件ID
var eventId = eventItem.querySelector('h4').textContent.split(':')[1].trim();
// 找到当前角色中的对应事件
if (currentCharacter && currentCharacter.events) {
var event = currentCharacter.events.find(function(e) {
return e.id == eventId;
});
if (event) {
// 异步打开编辑事件模态框
setTimeout(function() {
// 填充表单
document.getElementById('event-character-id').value = currentCharacter.id;
document.getElementById('event-id').value = event.id;
document.getElementById('event-text').value = event.text || '';
// 填充选项A
if (event.optionA) {
document.getElementById('option-a-text').value = event.optionA.text || '';
if (event.optionA.effects) {
document.getElementById('option-a-loyalty').value = event.optionA.effects.loyalty || 0;
document.getElementById('option-a-chaos').value = event.optionA.effects.chaos || 0;
document.getElementById('option-a-population').value = event.optionA.effects.population || 0;
document.getElementById('option-a-military').value = event.optionA.effects.military || 0;
document.getElementById('option-a-resources').value = event.optionA.effects.resources || 0;
}
document.getElementById('option-a-add-status').value = event.optionA.add_status || '';
document.getElementById('option-a-remove-status').value = event.optionA.remove_status || '';
}
// 填充选项B
if (event.optionB) {
document.getElementById('option-b-text').value = event.optionB.text || '';
if (event.optionB.effects) {
document.getElementById('option-b-loyalty').value = event.optionB.effects.loyalty || 0;
document.getElementById('option-b-chaos').value = event.optionB.effects.chaos || 0;
document.getElementById('option-b-population').value = event.optionB.effects.population || 0;
document.getElementById('option-b-military').value = event.optionB.effects.military || 0;
document.getElementById('option-b-resources').value = event.optionB.effects.resources || 0;
}
document.getElementById('option-b-add-status').value = event.optionB.add_status || '';
document.getElementById('option-b-remove-status').value = event.optionB.remove_status || '';
}
// 打开模态框
document.getElementById('event-modal').style.display = 'block';
}, 100);
}
}
}
});
});
</script>
</body>
</html>