/** * 随机参数管理组件 * 用于管理高级随机选项的类别和词条 * 支持勾选功能,仅在勾选的范围内随机 */ class RandomOptionsManager { constructor() { this.modal = null; this.optionsData = {}; // 配置数据 this.selectionData = {}; // 勾选状态数据 this.isLoading = false; this.init(); } /** * 初始化组件 */ init() { this.bindEvents(); } /** * 绑定事件 */ bindEvents() { // 打开模态框按钮 const openBtn = document.getElementById('editRandomOptionsBtn'); if (openBtn) { openBtn.addEventListener('click', () => this.openModal()); } // 关闭模态框 const closeBtn = document.getElementById('randomOptionsModalClose'); if (closeBtn) { closeBtn.addEventListener('click', () => this.closeModal()); } // 保存按钮 const saveBtn = document.getElementById('saveRandomOptionsBtn'); if (saveBtn) { saveBtn.addEventListener('click', () => this.saveOptions()); } // 取消按钮 const cancelBtn = document.getElementById('cancelRandomOptionsBtn'); if (cancelBtn) { cancelBtn.addEventListener('click', () => this.closeModal()); } // 添加类别按钮 const addCategoryBtn = document.getElementById('addCategoryBtn'); if (addCategoryBtn) { addCategoryBtn.addEventListener('click', () => this.showAddCategoryDialog()); } // 点击模态框外部关闭 const modal = document.getElementById('randomOptionsModal'); if (modal) { modal.addEventListener('click', (e) => { if (e.target === modal) { this.closeModal(); } }); } // 监听高级随机选项复选框变化 const advancedRandomCheckbox = document.getElementById('advancedRandom'); if (advancedRandomCheckbox) { advancedRandomCheckbox.addEventListener('change', () => this.toggleEditButton()); // 初始化时检查状态 this.toggleEditButton(); } } /** * 切换编辑按钮显示状态 */ toggleEditButton() { const advancedRandomCheckbox = document.getElementById('advancedRandom'); const editBtn = document.getElementById('editRandomOptionsBtn'); if (editBtn && advancedRandomCheckbox) { editBtn.style.display = advancedRandomCheckbox.checked ? 'flex' : 'none'; } } /** * 打开模态框 */ async openModal() { const modal = document.getElementById('randomOptionsModal'); if (modal) { modal.style.display = 'block'; await this.loadOptions(); } } /** * 关闭模态框 */ closeModal() { const modal = document.getElementById('randomOptionsModal'); if (modal) { modal.style.display = 'none'; } } /** * 加载配置数据和勾选状态 */ async loadOptions() { if (this.isLoading) return; this.isLoading = true; this.showLoading(true); try { // 并行加载配置和勾选状态 const [optionsResponse, selectionResponse] = await Promise.all([ window.randomOptionsApi.getOptions(), window.randomOptionsApi.getSelection() ]); if (optionsResponse.success) { this.optionsData = optionsResponse.data; } else { this.showToast(optionsResponse.error || '加载配置失败', 'error'); return; } if (selectionResponse.success) { this.selectionData = selectionResponse.data; } else { // 如果加载勾选状态失败,默认全选 this.initDefaultSelection(); } this.renderOptions(); } catch (error) { console.error('加载随机参数配置失败:', error); this.showToast('加载配置失败: ' + error.message, 'error'); } finally { this.isLoading = false; this.showLoading(false); } } /** * 初始化默认勾选状态(全选) */ initDefaultSelection() { this.selectionData = {}; Object.entries(this.optionsData).forEach(([category, items]) => { if (Array.isArray(items)) { this.selectionData[category] = items.slice(); } else { this.selectionData[category] = true; } }); } /** * 渲染配置选项 */ renderOptions() { const container = document.getElementById('randomOptionsContainer'); if (!container) return; container.innerHTML = ''; // 渲染整体全选控件 const globalSelectAll = this.createGlobalSelectAll(); container.appendChild(globalSelectAll); // 渲染各个类别 Object.entries(this.optionsData).forEach(([category, items]) => { const categoryElement = this.createCategoryElement(category, items); container.appendChild(categoryElement); }); // 更新整体全选状态 this.updateGlobalSelectAllState(); } /** * 创建整体全选控件 */ createGlobalSelectAll() { const div = document.createElement('div'); div.className = 'global-select-all'; div.innerHTML = ` `; // 绑定事件 setTimeout(() => { const checkbox = document.getElementById('globalSelectAllCheckbox'); if (checkbox) { checkbox.addEventListener('change', (e) => this.handleGlobalSelectAll(e.target.checked)); } }, 0); return div; } /** * 处理整体全选 */ handleGlobalSelectAll(checked) { Object.entries(this.optionsData).forEach(([category, items]) => { if (Array.isArray(items)) { this.selectionData[category] = checked ? items.slice() : []; } else { this.selectionData[category] = checked; } }); this.renderOptions(); } /** * 更新整体全选状态 */ updateGlobalSelectAllState() { const checkbox = document.getElementById('globalSelectAllCheckbox'); if (!checkbox) return; let allSelected = true; let anySelected = false; Object.entries(this.optionsData).forEach(([category, items]) => { if (Array.isArray(items)) { const selected = this.selectionData[category] || []; if (selected.length === items.length) { anySelected = true; } else if (selected.length > 0) { allSelected = false; anySelected = true; } else { allSelected = false; } } else { if (this.selectionData[category]) { anySelected = true; } else { allSelected = false; } } }); checkbox.checked = allSelected && anySelected; checkbox.indeterminate = !allSelected && anySelected; } /** * 创建类别元素 */ createCategoryElement(category, items) { const categoryDiv = document.createElement('div'); categoryDiv.className = 'random-option-category'; categoryDiv.dataset.category = category; // 判断是数组还是字符串 const isArray = Array.isArray(items); // 检查类别是否全选 const isCategoryFullySelected = this.isCategoryFullySelected(category, items); const isCategoryPartiallySelected = this.isCategoryPartiallySelected(category, items); categoryDiv.innerHTML = `
${isArray ? `` : ''}
${isArray ? this.renderItemsList(category, items) : this.renderTextArea(category, items)}
`; // 绑定类别勾选事件 setTimeout(() => { const categoryCheckbox = categoryDiv.querySelector('.category-checkbox'); if (categoryCheckbox) { // 设置indeterminate状态 if (categoryCheckbox.dataset.indeterminate === 'true') { categoryCheckbox.indeterminate = true; } categoryCheckbox.addEventListener('change', (e) => { this.handleCategorySelect(category, e.target.checked); }); } }, 0); // 绑定删除类别事件 const deleteBtn = categoryDiv.querySelector('.btn-delete-category'); if (deleteBtn) { deleteBtn.addEventListener('click', () => this.confirmDeleteCategory(category)); } // 绑定添加词条事件(仅数组类型) if (isArray) { const addItemBtn = categoryDiv.querySelector('.btn-add-item'); if (addItemBtn) { addItemBtn.addEventListener('click', () => this.showAddItemDialog(category)); } } return categoryDiv; } /** * 检查类别是否全选 */ isCategoryFullySelected(category, items) { if (Array.isArray(items)) { const selected = this.selectionData[category] || []; return selected.length === items.length && items.length > 0; } else { return this.selectionData[category] === true; } } /** * 检查类别是否部分选中 */ isCategoryPartiallySelected(category, items) { if (Array.isArray(items)) { const selected = this.selectionData[category] || []; return selected.length > 0; } else { return this.selectionData[category] === true; } } /** * 处理类别全选 */ handleCategorySelect(category, checked) { const items = this.optionsData[category]; if (Array.isArray(items)) { this.selectionData[category] = checked ? items.slice() : []; } else { this.selectionData[category] = checked; } this.renderOptions(); } /** * 渲染词条列表(数组类型) */ renderItemsList(category, items) { if (!items || items.length === 0) { return '
暂无词条,点击上方 + 添加
'; } const selectedItems = this.selectionData[category] || []; const itemsHtml = items.map((item, index) => { const isSelected = selectedItems.includes(item); return `
`; }).join(''); // 使用setTimeout绑定事件,因为元素还未添加到DOM setTimeout(() => { const container = document.querySelector(`.random-option-category[data-category="${category}"] .category-content`); if (container) { // 绑定词条勾选事件 container.querySelectorAll('.item-checkbox').forEach(checkbox => { checkbox.addEventListener('change', (e) => { const cat = e.target.dataset.category; const item = e.target.dataset.item; this.handleItemSelect(cat, item, e.target.checked); }); }); // 绑定删除事件 container.querySelectorAll('.btn-remove-item').forEach(btn => { btn.addEventListener('click', (e) => { const cat = e.currentTarget.dataset.category; const idx = parseInt(e.currentTarget.dataset.index); this.removeItem(cat, idx); }); }); } }, 0); return `
${itemsHtml}
`; } /** * 处理词条勾选 */ handleItemSelect(category, item, checked) { if (!this.selectionData[category]) { this.selectionData[category] = []; } const selectedItems = this.selectionData[category]; const index = selectedItems.indexOf(item); if (checked && index === -1) { selectedItems.push(item); } else if (!checked && index !== -1) { selectedItems.splice(index, 1); } // 更新UI this.updateCategoryCheckboxState(category); this.updateGlobalSelectAllState(); // 更新词条的选中样式 const itemElement = document.querySelector(`.option-item .item-checkbox[data-category="${category}"][data-item="${item}"]`); if (itemElement) { const optionItem = itemElement.closest('.option-item'); if (optionItem) { optionItem.classList.toggle('selected', checked); } } } /** * 更新类别复选框状态 */ updateCategoryCheckboxState(category) { const items = this.optionsData[category]; const checkbox = document.querySelector(`.category-checkbox[data-category="${category}"]`); if (!checkbox || !Array.isArray(items)) return; const selected = this.selectionData[category] || []; const allSelected = selected.length === items.length && items.length > 0; const someSelected = selected.length > 0 && selected.length < items.length; checkbox.checked = allSelected; checkbox.indeterminate = someSelected; } /** * 渲染文本域(字符串类型) */ renderTextArea(category, text) { const textareaId = `textarea-${category.replace(/\s+/g, '-')}`; const isSelected = this.selectionData[category] === true; setTimeout(() => { const textarea = document.getElementById(textareaId); if (textarea) { textarea.addEventListener('change', (e) => { this.optionsData[category] = e.target.value; }); } }, 0); return `
`; } /** * 显示添加类别对话框 */ showAddCategoryDialog() { const categoryName = prompt('请输入新类别名称:'); if (categoryName && categoryName.trim()) { this.addCategory(categoryName.trim()); } } /** * 添加新类别 */ addCategory(name) { if (this.optionsData.hasOwnProperty(name)) { this.showToast(`类别 "${name}" 已存在`, 'error'); return; } this.optionsData[name] = []; this.selectionData[name] = []; // 新类别默认空选 this.renderOptions(); this.showToast(`类别 "${name}" 添加成功`); } /** * 确认删除类别 */ confirmDeleteCategory(category) { if (confirm(`确定要删除类别 "${category}" 吗?此操作不可恢复。`)) { this.deleteCategory(category); } } /** * 删除类别 */ deleteCategory(category) { if (this.optionsData.hasOwnProperty(category)) { delete this.optionsData[category]; delete this.selectionData[category]; this.renderOptions(); this.showToast(`类别 "${category}" 已删除`); } } /** * 显示添加词条对话框 */ showAddItemDialog(category) { const itemText = prompt(`请输入要添加到 "${category}" 的词条:`); if (itemText && itemText.trim()) { this.addItem(category, itemText.trim()); } } /** * 添加词条 */ addItem(category, item) { if (!Array.isArray(this.optionsData[category])) { this.showToast('该类别不支持添加词条', 'error'); return; } if (this.optionsData[category].includes(item)) { this.showToast(`词条 "${item}" 已存在于该类别中`, 'error'); return; } this.optionsData[category].push(item); // 新添加的词条默认勾选 if (!this.selectionData[category]) { this.selectionData[category] = []; } this.selectionData[category].push(item); this.renderOptions(); this.showToast(`词条 "${item}" 添加成功`); } /** * 删除词条 */ removeItem(category, index) { if (!Array.isArray(this.optionsData[category])) { return; } const item = this.optionsData[category][index]; this.optionsData[category].splice(index, 1); // 同时从勾选状态中删除 if (Array.isArray(this.selectionData[category])) { const selIndex = this.selectionData[category].indexOf(item); if (selIndex !== -1) { this.selectionData[category].splice(selIndex, 1); } } this.renderOptions(); this.showToast(`词条 "${item}" 已删除`); } /** * 保存配置和勾选状态 */ async saveOptions() { this.showLoading(true); try { // 并行保存配置和勾选状态 const [optionsResponse, selectionResponse] = await Promise.all([ window.randomOptionsApi.saveOptions(this.optionsData), window.randomOptionsApi.saveSelection(this.selectionData) ]); if (optionsResponse.success && selectionResponse.success) { this.showToast('配置保存成功'); this.closeModal(); } else { const errorMsg = optionsResponse.error || selectionResponse.error || '保存配置失败'; this.showToast(errorMsg, 'error'); } } catch (error) { console.error('保存随机参数配置失败:', error); this.showToast('保存配置失败: ' + error.message, 'error'); } finally { this.showLoading(false); } } /** * 显示/隐藏加载状态 */ showLoading(show) { const loadingEl = document.getElementById('randomOptionsLoading'); const containerEl = document.getElementById('randomOptionsContainer'); if (loadingEl) { loadingEl.style.display = show ? 'flex' : 'none'; } if (containerEl) { containerEl.style.display = show ? 'none' : 'block'; } } /** * 显示提示消息 */ showToast(message, type = 'success') { const container = document.getElementById('toastContainer'); if (!container) return; const toast = document.createElement('div'); toast.className = `toast ${type}`; toast.textContent = message; container.appendChild(toast); setTimeout(() => { toast.remove(); }, 3000); } /** * HTML转义 */ escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } } // 当DOM加载完成后初始化 document.addEventListener('DOMContentLoaded', function() { window.randomOptionsManager = new RandomOptionsManager(); });