Dictionary.js:修订间差异
来自卡厄思梦境WIKI
无编辑摘要 |
无编辑摘要 |
||
| 第2行: | 第2行: | ||
'use strict'; | 'use strict'; | ||
if (mw.config.get('wgPageName') !== 'MediaWiki:Dictionary') return; | |||
const API_URL = mw.util.wikiScript('api'); | |||
const MODULE_PAGE = '模块:词典/data'; | |||
let dictionaryData = {}; | |||
let currentEditKey = null; | |||
let currentEditIndex = null; | |||
// | // 初始化 | ||
function | function init() { | ||
const content = document.createElement('div'); | |||
content.className = 'dict-editor'; | |||
content.innerHTML = ` | |||
<div class="dict-controls"> | |||
<div class="dict-btn dict-btn-success" id="dict-add-btn">添加新词条</div> | |||
<div class="dict-btn" id="dict-refresh-btn">刷新数据</div> | |||
<div class="dict-btn" id="dict-save-btn">保存到模块</div> | |||
</div> | |||
<div id="dict-message"></div> | |||
<div id="dict-content" class="dict-loading">加载中...</div> | |||
<div class="dict-overlay" id="dict-overlay"></div> | |||
<div class="dict-form" id="dict-form"> | |||
<h3 id="dict-form-title">添加词条</h3> | |||
<div class="dict-form-group"> | |||
<label for="dict-name">词条名称</label> | |||
<input type="text" id="dict-name" class="dict-input" /> | |||
</div> | |||
<div class="dict-form-group"> | |||
<label for="dict-icon">图标</label> | |||
<input type="text" id="dict-icon" class="dict-input" /> | |||
</div> | |||
<div class="dict-form-group"> | |||
<label for="dict-type">类型</label> | |||
<div class="dict-select" id="dict-type" data-value=""> | |||
<div class="dict-select-display">请选择类型</div> | |||
<div class="dict-select-options"> | |||
<div class="dict-select-option" data-value="卡牌机制">卡牌机制</div> | |||
<div class="dict-select-option" data-value="战斗员专属机制">战斗员专属机制</div> | |||
<div class="dict-select-option" data-value="buff">buff</div> | |||
<div class="dict-select-option" data-value="debuff">debuff</div> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="dict-form-group"> | |||
<label for="dict-color">颜色</label> | |||
<div class="dict-select" id="dict-color" data-value=""> | |||
<div class="dict-select-display">请选择颜色</div> | |||
<div class="dict-select-options"> | |||
<div class="dict-select-option" data-value="白">白</div> | |||
<div class="dict-select-option" data-value="蓝">蓝</div> | |||
<div class="dict-select-option" data-value="红">红</div> | |||
<div class="dict-select-option" data-value="橙">橙</div> | |||
<div class="dict-select-option" data-value="彩">彩</div> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="dict-form-group"> | |||
<label for="dict-desc">描述</label> | |||
<textarea id="dict-desc" class="dict-textarea"></textarea> | |||
</div> | |||
<div class="dict-form-actions"> | |||
<div class="dict-btn" id="dict-cancel-btn">取消</div> | |||
<div class="dict-btn dict-btn-success" id="dict-submit-btn">保存</div> | |||
</div> | |||
</div> | |||
`; | |||
const container = document.getElementById('mw-content-text'); | |||
container.innerHTML = ''; | |||
container.appendChild(content); | |||
initCustomSelect(); | |||
bindEvents(); | |||
loadData(); | |||
} | } | ||
// | // 自定义下拉选择器 | ||
function | function initCustomSelect() { | ||
document.querySelectorAll('.dict-select').forEach(select => { | |||
const display = select.querySelector('.dict-select-display'); | |||
const options = select.querySelector('.dict-select-options'); | |||
display.addEventListener('click', () => { | |||
select.classList.toggle('open'); | |||
}); | |||
select.querySelectorAll('.dict-select-option').forEach(option => { | |||
option.addEventListener('click', () => { | |||
const value = option.getAttribute('data-value'); | |||
select.setAttribute('data-value', value); | |||
display.textContent = option.textContent; | |||
select.classList.remove('open'); | |||
}); | |||
}); | |||
}); | |||
// 点击外部关闭 | |||
document.addEventListener('click', (e) => { | |||
if (!e.target.closest('.dict-select')) { | |||
document.querySelectorAll('.dict-select').forEach(s => s.classList.remove('open')); | |||
} | } | ||
}); | }); | ||
} | } | ||
// | // 绑定事件 | ||
function | function bindEvents() { | ||
document.getElementById('dict-add-btn').addEventListener('click', () => openForm()); | |||
document.getElementById('dict-refresh-btn').addEventListener('click', () => loadData()); | |||
document.getElementById('dict-save-btn').addEventListener('click', () => saveData()); | |||
document.getElementById('dict-overlay').addEventListener('click', closeForm); | |||
document.getElementById('dict-cancel-btn').addEventListener('click', closeForm); | |||
document.getElementById('dict-submit-btn').addEventListener('click', submitForm); | |||
} | } | ||
// | // 加载数据 | ||
function | function loadData() { | ||
showMessage('加载中...', 'loading'); | |||
fetch(API_URL + '?' + new URLSearchParams({ | |||
action: 'query', | |||
prop: 'revisions', | |||
if ( | titles: MODULE_PAGE, | ||
rvprop: 'content', | |||
rvslots: 'main', | |||
format: 'json' | |||
})) | |||
.then(res => res.json()) | |||
.then(data => { | |||
const pages = data.query.pages; | |||
const page = pages[Object.keys(pages)[0]]; | |||
if (page.revisions) { | |||
const content = page.revisions[0].slots.main['*']; | |||
parseModuleData(content); | |||
renderTable(); | |||
showMessage('数据加载成功', 'success'); | |||
} else { | |||
showMessage('模块页面不存在', 'error'); | |||
} | |||
}) | |||
.catch(err => { | |||
showMessage('加载失败: ' + err.message, 'error'); | |||
}); | |||
} | |||
// 解析模块数据 | |||
function parseModuleData(content) { | |||
try { | |||
// 提取 dictionary 表的内容 | |||
const match = content.match(/data\.dictionary\s*=\s*(\{[\s\S]*?\n\})/); | |||
if (match) { | |||
// 简单的Lua表转JSON (这是简化版本,可能需要更复杂的解析) | |||
let jsonStr = match[1] | |||
.replace(/\["([^"]+)"\]\s*=/g, '"$1":') | |||
.replace(/\[(\d+)\]\s*=/g, '') | |||
.replace(/,(\s*[}\]])/g, '$1'); | |||
dictionaryData = eval('(' + jsonStr + ')'); | |||
} | } | ||
} catch (e) { | |||
console.error('解析错误:', e); | |||
dictionaryData = {}; | |||
} | } | ||
} | } | ||
// | // 渲染表格 | ||
function | function renderTable() { | ||
const content = document.getElementById('dict-content'); | |||
if (Object.keys(dictionaryData).length === 0) { | |||
content.innerHTML = '<p>暂无数据</p>'; | |||
return; | |||
} | } | ||
let html = '<table class="dict-table"><thead><tr><th>词条名称</th><th>变体</th><th>操作</th></tr></thead><tbody>'; | |||
for (const [key, variants] of Object.entries(dictionaryData)) { | |||
html += `<tr><td rowspan="${variants.length + 1}"><strong>${key}</strong></td></tr>`; | |||
variants.forEach((variant, index) => { | |||
const colorClass = getColorClass(variant.颜色); | |||
html += ` | |||
<tr> | |||
<td> | |||
<div class="dict-variant"> | |||
<div><span class="dict-badge ${colorClass}">${variant.类型}</span> <span class="dict-badge ${colorClass}">${variant.颜色}</span></div> | |||
<div style="margin-top: 5px;">${variant.描述}</div> | |||
${variant.icon ? '<div>图标: ' + variant.icon + '</div>' : ''} | |||
</div> | |||
</td> | |||
<td> | |||
<div class="dict-btn" onclick="dictEdit('${key}', ${index})">编辑</div> | |||
<div class="dict-btn dict-btn-danger" onclick="dictDelete('${key}', ${index})">删除</div> | |||
</td> | |||
</tr> | |||
`; | |||
}); | |||
} | } | ||
html += '</tbody></table>'; | |||
return | content.innerHTML = html; | ||
} | |||
// 获取颜色类名 | |||
function getColorClass(color) { | |||
const colorMap = { | |||
'白': 'dict-badge-white', | |||
'蓝': 'dict-badge-blue', | |||
'红': 'dict-badge-red', | |||
'橙': 'dict-badge-orange', | |||
'彩': 'dict-badge-rainbow' | |||
}; | |||
return colorMap[color] || 'dict-badge-white'; | |||
} | } | ||
// | // 打开表单 | ||
function | function openForm(key = null, index = null) { | ||
currentEditKey = key; | |||
currentEditIndex = index; | |||
const form = document.getElementById('dict-form'); | |||
const overlay = document.getElementById('dict-overlay'); | |||
const title = document.getElementById('dict-form-title'); | |||
if (key !== null && index !== null) { | |||
if ( | title.textContent = '编辑词条'; | ||
const variant = dictionaryData[key][index]; | |||
document.getElementById('dict-name').value = key; | |||
document.getElementById('dict-name').disabled = true; | |||
document.getElementById('dict-icon').value = variant.icon || ''; | |||
setSelectValue('dict-type', variant.类型); | |||
setSelectValue('dict-color', variant.颜色); | |||
document.getElementById('dict-desc').value = variant.描述 || ''; | |||
} else { | } else { | ||
title.textContent = '添加词条'; | |||
document.getElementById('dict-name').value = ''; | |||
document.getElementById('dict-name').disabled = false; | |||
document.getElementById('dict-icon').value = ''; | |||
setSelectValue('dict-type', ''); | |||
setSelectValue('dict-color', ''); | |||
document.getElementById('dict-desc').value = ''; | |||
} | } | ||
form.classList.add('active'); | |||
overlay.classList.add('active'); | |||
} | } | ||
// | // 设置选择器值 | ||
function | function setSelectValue(id, value) { | ||
const select = document.getElementById(id); | |||
select.setAttribute('data-value', value); | |||
const display = select.querySelector('.dict-select-display'); | |||
if (value) { | |||
display.textContent = value; | |||
} else { | |||
display.textContent = select.id === 'dict-type' ? '请选择类型' : '请选择颜色'; | |||
} | |||
. | |||
} | } | ||
// | // 关闭表单 | ||
function | function closeForm() { | ||
document.getElementById('dict-form').classList.remove('active'); | |||
document.getElementById('dict-overlay').classList.remove('active'); | |||
} | } | ||
// | // 提交表单 | ||
function | function submitForm() { | ||
const name = document.getElementById('dict-name').value.trim(); | |||
const icon = document.getElementById('dict-icon').value.trim(); | |||
const type = document.getElementById('dict-type').getAttribute('data-value'); | |||
const color = document.getElementById('dict-color').getAttribute('data-value'); | |||
const desc = document.getElementById('dict-desc').value.trim(); | |||
if (!name || !type || !color || !desc) { | |||
showMessage('请填写所有必填字段', 'error'); | |||
return; | |||
} | |||
const variant = { | |||
icon: icon, | |||
类型: type, | |||
颜色: color, | |||
描述: desc | |||
}; | |||
if (currentEditKey !== null && currentEditIndex !== null) { | |||
// 编辑 | |||
dictionaryData[currentEditKey][currentEditIndex] = variant; | |||
} else { | |||
// 新增 | |||
if (!dictionaryData[name]) { | |||
dictionaryData[name] = []; | |||
} | |||
if (! | |||
} | } | ||
dictionaryData[name].push(variant); | |||
} | } | ||
renderTable(); | |||
closeForm(); | |||
showMessage('操作成功,请点击"保存到模块"按钮保存更改', 'success'); | |||
} | } | ||
// | // 删除 | ||
window.dictDelete = function(key, index) { | |||
if (!confirm('确定要删除这个变体吗?')) return; | |||
if (!confirm(' | |||
dictionaryData[key].splice(index, 1); | dictionaryData[key].splice(index, 1); | ||
| 第392行: | 第312行: | ||
delete dictionaryData[key]; | delete dictionaryData[key]; | ||
} | } | ||
} | renderTable(); | ||
showMessage('删除成功,请点击"保存到模块"按钮保存更改', 'success'); | |||
}; | |||
// 编辑 | |||
window.dictEdit = function(key, index) { | |||
openForm(key, index); | |||
}; | |||
// | // 保存数据 | ||
function | function saveData() { | ||
if (!confirm('确定要保存到模块吗?这将覆盖现有数据!')) return; | |||
// | const luaContent = generateLuaContent(); | ||
new | |||
showMessage('保存中...', 'loading'); | |||
// 获取编辑令牌 | |||
fetch(API_URL + '?' + new URLSearchParams({ | |||
}). | action: 'query', | ||
if ( | meta: 'tokens', | ||
format: 'json' | |||
})) | |||
.then(res => res.json()) | |||
.then(data => { | |||
const token = data.query.tokens.csrftoken; | |||
// 保存页面 | |||
return fetch(API_URL, { | |||
method: 'POST', | |||
headers: { | |||
'Content-Type': 'application/x-www-form-urlencoded', | |||
}, | |||
body: new URLSearchParams({ | |||
action: 'edit', | |||
title: MODULE_PAGE, | |||
text: luaContent, | |||
summary: '通过词典编辑器更新数据', | |||
token: token, | |||
format: 'json' | |||
}) | |||
}); | |||
}) | |||
.then(res => res.json()) | |||
.then(data => { | |||
if (data.edit && data.edit.result === 'Success') { | |||
showMessage('保存成功!', 'success'); | |||
} else { | } else { | ||
showMessage('保存失败: ' + JSON.stringify(data), 'error'); | |||
} | } | ||
}). | }) | ||
.catch(err => { | |||
showMessage('保存失败: ' + err.message, 'error'); | |||
}); | }); | ||
} | } | ||
// | // 生成Lua内容 | ||
function | function generateLuaContent() { | ||
let lua = 'local data = {}\n\ndata.dictionary = {\n'; | |||
for (const [key, variants] of Object.entries(dictionaryData)) { | |||
lua += ` ["${key}"] = {\n`; | |||
variants.forEach(variant => { | |||
lua += ' {\n'; | |||
lua += ` ["icon"] = "${variant.icon || ''}",\n`; | |||
lua += ` ["类型"] = "${variant.类型}",\n`; | |||
lua += ` ["颜色"] = "${variant.颜色}",\n`; | |||
lua += ` ["描述"] = "${variant.描述}",\n`; | |||
lua += ' },\n'; | |||
}); | }); | ||
lua += ' },\n'; | |||
} | |||
lua += '}\n\nreturn data\n'; | |||
return lua; | |||
} | |||
// 显示消息 | |||
function showMessage(msg, type) { | |||
const msgDiv = document.getElementById('dict-message'); | |||
msgDiv.className = 'dict-' + type; | |||
msgDiv.textContent = msg; | |||
if (type === 'success' || type === 'error') { | |||
setTimeout(() => { | |||
msgDiv.textContent = ''; | |||
msgDiv.className = ''; | |||
}, 3000); | |||
} | |||
} | } | ||
// | // 页面加载完成后初始化 | ||
if (document.readyState === 'loading') { | if (document.readyState === 'loading') { | ||
document.addEventListener('DOMContentLoaded', init); | |||
} else { | } else { | ||
init(); | |||
} | } | ||
})(); | })(); | ||
2025年10月3日 (五) 19:12的版本
(function() {
'use strict';
if (mw.config.get('wgPageName') !== 'MediaWiki:Dictionary') return;
const API_URL = mw.util.wikiScript('api');
const MODULE_PAGE = '模块:词典/data';
let dictionaryData = {};
let currentEditKey = null;
let currentEditIndex = null;
// 初始化
function init() {
const content = document.createElement('div');
content.className = 'dict-editor';
content.innerHTML = `
<div class="dict-controls">
<div class="dict-btn dict-btn-success" id="dict-add-btn">添加新词条</div>
<div class="dict-btn" id="dict-refresh-btn">刷新数据</div>
<div class="dict-btn" id="dict-save-btn">保存到模块</div>
</div>
<div id="dict-message"></div>
<div id="dict-content" class="dict-loading">加载中...</div>
<div class="dict-overlay" id="dict-overlay"></div>
<div class="dict-form" id="dict-form">
<h3 id="dict-form-title">添加词条</h3>
<div class="dict-form-group">
<label for="dict-name">词条名称</label>
<input type="text" id="dict-name" class="dict-input" />
</div>
<div class="dict-form-group">
<label for="dict-icon">图标</label>
<input type="text" id="dict-icon" class="dict-input" />
</div>
<div class="dict-form-group">
<label for="dict-type">类型</label>
<div class="dict-select" id="dict-type" data-value="">
<div class="dict-select-display">请选择类型</div>
<div class="dict-select-options">
<div class="dict-select-option" data-value="卡牌机制">卡牌机制</div>
<div class="dict-select-option" data-value="战斗员专属机制">战斗员专属机制</div>
<div class="dict-select-option" data-value="buff">buff</div>
<div class="dict-select-option" data-value="debuff">debuff</div>
</div>
</div>
</div>
<div class="dict-form-group">
<label for="dict-color">颜色</label>
<div class="dict-select" id="dict-color" data-value="">
<div class="dict-select-display">请选择颜色</div>
<div class="dict-select-options">
<div class="dict-select-option" data-value="白">白</div>
<div class="dict-select-option" data-value="蓝">蓝</div>
<div class="dict-select-option" data-value="红">红</div>
<div class="dict-select-option" data-value="橙">橙</div>
<div class="dict-select-option" data-value="彩">彩</div>
</div>
</div>
</div>
<div class="dict-form-group">
<label for="dict-desc">描述</label>
<textarea id="dict-desc" class="dict-textarea"></textarea>
</div>
<div class="dict-form-actions">
<div class="dict-btn" id="dict-cancel-btn">取消</div>
<div class="dict-btn dict-btn-success" id="dict-submit-btn">保存</div>
</div>
</div>
`;
const container = document.getElementById('mw-content-text');
container.innerHTML = '';
container.appendChild(content);
initCustomSelect();
bindEvents();
loadData();
}
// 自定义下拉选择器
function initCustomSelect() {
document.querySelectorAll('.dict-select').forEach(select => {
const display = select.querySelector('.dict-select-display');
const options = select.querySelector('.dict-select-options');
display.addEventListener('click', () => {
select.classList.toggle('open');
});
select.querySelectorAll('.dict-select-option').forEach(option => {
option.addEventListener('click', () => {
const value = option.getAttribute('data-value');
select.setAttribute('data-value', value);
display.textContent = option.textContent;
select.classList.remove('open');
});
});
});
// 点击外部关闭
document.addEventListener('click', (e) => {
if (!e.target.closest('.dict-select')) {
document.querySelectorAll('.dict-select').forEach(s => s.classList.remove('open'));
}
});
}
// 绑定事件
function bindEvents() {
document.getElementById('dict-add-btn').addEventListener('click', () => openForm());
document.getElementById('dict-refresh-btn').addEventListener('click', () => loadData());
document.getElementById('dict-save-btn').addEventListener('click', () => saveData());
document.getElementById('dict-overlay').addEventListener('click', closeForm);
document.getElementById('dict-cancel-btn').addEventListener('click', closeForm);
document.getElementById('dict-submit-btn').addEventListener('click', submitForm);
}
// 加载数据
function loadData() {
showMessage('加载中...', 'loading');
fetch(API_URL + '?' + new URLSearchParams({
action: 'query',
prop: 'revisions',
titles: MODULE_PAGE,
rvprop: 'content',
rvslots: 'main',
format: 'json'
}))
.then(res => res.json())
.then(data => {
const pages = data.query.pages;
const page = pages[Object.keys(pages)[0]];
if (page.revisions) {
const content = page.revisions[0].slots.main['*'];
parseModuleData(content);
renderTable();
showMessage('数据加载成功', 'success');
} else {
showMessage('模块页面不存在', 'error');
}
})
.catch(err => {
showMessage('加载失败: ' + err.message, 'error');
});
}
// 解析模块数据
function parseModuleData(content) {
try {
// 提取 dictionary 表的内容
const match = content.match(/data\.dictionary\s*=\s*(\{[\s\S]*?\n\})/);
if (match) {
// 简单的Lua表转JSON (这是简化版本,可能需要更复杂的解析)
let jsonStr = match[1]
.replace(/\["([^"]+)"\]\s*=/g, '"$1":')
.replace(/\[(\d+)\]\s*=/g, '')
.replace(/,(\s*[}\]])/g, '$1');
dictionaryData = eval('(' + jsonStr + ')');
}
} catch (e) {
console.error('解析错误:', e);
dictionaryData = {};
}
}
// 渲染表格
function renderTable() {
const content = document.getElementById('dict-content');
if (Object.keys(dictionaryData).length === 0) {
content.innerHTML = '<p>暂无数据</p>';
return;
}
let html = '<table class="dict-table"><thead><tr><th>词条名称</th><th>变体</th><th>操作</th></tr></thead><tbody>';
for (const [key, variants] of Object.entries(dictionaryData)) {
html += `<tr><td rowspan="${variants.length + 1}"><strong>${key}</strong></td></tr>`;
variants.forEach((variant, index) => {
const colorClass = getColorClass(variant.颜色);
html += `
<tr>
<td>
<div class="dict-variant">
<div><span class="dict-badge ${colorClass}">${variant.类型}</span> <span class="dict-badge ${colorClass}">${variant.颜色}</span></div>
<div style="margin-top: 5px;">${variant.描述}</div>
${variant.icon ? '<div>图标: ' + variant.icon + '</div>' : ''}
</div>
</td>
<td>
<div class="dict-btn" onclick="dictEdit('${key}', ${index})">编辑</div>
<div class="dict-btn dict-btn-danger" onclick="dictDelete('${key}', ${index})">删除</div>
</td>
</tr>
`;
});
}
html += '</tbody></table>';
content.innerHTML = html;
}
// 获取颜色类名
function getColorClass(color) {
const colorMap = {
'白': 'dict-badge-white',
'蓝': 'dict-badge-blue',
'红': 'dict-badge-red',
'橙': 'dict-badge-orange',
'彩': 'dict-badge-rainbow'
};
return colorMap[color] || 'dict-badge-white';
}
// 打开表单
function openForm(key = null, index = null) {
currentEditKey = key;
currentEditIndex = index;
const form = document.getElementById('dict-form');
const overlay = document.getElementById('dict-overlay');
const title = document.getElementById('dict-form-title');
if (key !== null && index !== null) {
title.textContent = '编辑词条';
const variant = dictionaryData[key][index];
document.getElementById('dict-name').value = key;
document.getElementById('dict-name').disabled = true;
document.getElementById('dict-icon').value = variant.icon || '';
setSelectValue('dict-type', variant.类型);
setSelectValue('dict-color', variant.颜色);
document.getElementById('dict-desc').value = variant.描述 || '';
} else {
title.textContent = '添加词条';
document.getElementById('dict-name').value = '';
document.getElementById('dict-name').disabled = false;
document.getElementById('dict-icon').value = '';
setSelectValue('dict-type', '');
setSelectValue('dict-color', '');
document.getElementById('dict-desc').value = '';
}
form.classList.add('active');
overlay.classList.add('active');
}
// 设置选择器值
function setSelectValue(id, value) {
const select = document.getElementById(id);
select.setAttribute('data-value', value);
const display = select.querySelector('.dict-select-display');
if (value) {
display.textContent = value;
} else {
display.textContent = select.id === 'dict-type' ? '请选择类型' : '请选择颜色';
}
}
// 关闭表单
function closeForm() {
document.getElementById('dict-form').classList.remove('active');
document.getElementById('dict-overlay').classList.remove('active');
}
// 提交表单
function submitForm() {
const name = document.getElementById('dict-name').value.trim();
const icon = document.getElementById('dict-icon').value.trim();
const type = document.getElementById('dict-type').getAttribute('data-value');
const color = document.getElementById('dict-color').getAttribute('data-value');
const desc = document.getElementById('dict-desc').value.trim();
if (!name || !type || !color || !desc) {
showMessage('请填写所有必填字段', 'error');
return;
}
const variant = {
icon: icon,
类型: type,
颜色: color,
描述: desc
};
if (currentEditKey !== null && currentEditIndex !== null) {
// 编辑
dictionaryData[currentEditKey][currentEditIndex] = variant;
} else {
// 新增
if (!dictionaryData[name]) {
dictionaryData[name] = [];
}
dictionaryData[name].push(variant);
}
renderTable();
closeForm();
showMessage('操作成功,请点击"保存到模块"按钮保存更改', 'success');
}
// 删除
window.dictDelete = function(key, index) {
if (!confirm('确定要删除这个变体吗?')) return;
dictionaryData[key].splice(index, 1);
if (dictionaryData[key].length === 0) {
delete dictionaryData[key];
}
renderTable();
showMessage('删除成功,请点击"保存到模块"按钮保存更改', 'success');
};
// 编辑
window.dictEdit = function(key, index) {
openForm(key, index);
};
// 保存数据
function saveData() {
if (!confirm('确定要保存到模块吗?这将覆盖现有数据!')) return;
const luaContent = generateLuaContent();
showMessage('保存中...', 'loading');
// 获取编辑令牌
fetch(API_URL + '?' + new URLSearchParams({
action: 'query',
meta: 'tokens',
format: 'json'
}))
.then(res => res.json())
.then(data => {
const token = data.query.tokens.csrftoken;
// 保存页面
return fetch(API_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
action: 'edit',
title: MODULE_PAGE,
text: luaContent,
summary: '通过词典编辑器更新数据',
token: token,
format: 'json'
})
});
})
.then(res => res.json())
.then(data => {
if (data.edit && data.edit.result === 'Success') {
showMessage('保存成功!', 'success');
} else {
showMessage('保存失败: ' + JSON.stringify(data), 'error');
}
})
.catch(err => {
showMessage('保存失败: ' + err.message, 'error');
});
}
// 生成Lua内容
function generateLuaContent() {
let lua = 'local data = {}\n\ndata.dictionary = {\n';
for (const [key, variants] of Object.entries(dictionaryData)) {
lua += ` ["${key}"] = {\n`;
variants.forEach(variant => {
lua += ' {\n';
lua += ` ["icon"] = "${variant.icon || ''}",\n`;
lua += ` ["类型"] = "${variant.类型}",\n`;
lua += ` ["颜色"] = "${variant.颜色}",\n`;
lua += ` ["描述"] = "${variant.描述}",\n`;
lua += ' },\n';
});
lua += ' },\n';
}
lua += '}\n\nreturn data\n';
return lua;
}
// 显示消息
function showMessage(msg, type) {
const msgDiv = document.getElementById('dict-message');
msgDiv.className = 'dict-' + type;
msgDiv.textContent = msg;
if (type === 'success' || type === 'error') {
setTimeout(() => {
msgDiv.textContent = '';
msgDiv.className = '';
}, 3000);
}
}
// 页面加载完成后初始化
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();