/**
* 随机参数管理组件
* 用于管理高级随机选项的类别和词条
* 支持勾选功能,仅在勾选的范围内随机
*/
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 ? 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();
});