Equipment.js:修订间差异
来自卡厄思梦境WIKI
创建页面,内容为“(function() { 'use strict'; // 等待页面加载完成 if (mw.config.get('wgPageName') !== 'MediaWiki:Equipment') { return; } // 加载 CSS mw.loader.load('/index.php?title=MediaWiki:Equipment.css&action=raw&ctype=text/css', 'text/css'); var EquipmentManager = { data: {}, currentEditKey: null, init: function() { this.loadData(); this.renderUI();…” |
无编辑摘要 |
||
| 第1行: | 第1行: | ||
(function() { | (function() { | ||
'use strict'; | 'use strict'; | ||
// 加载 CSS | // 加载 CSS | ||
mw.loader.load('/index.php?title=MediaWiki:Equipment.css&action=raw&ctype=text/css', 'text/css'); | mw.loader.load('/index.php?title=MediaWiki:Equipment.css&action=raw&ctype=text/css', 'text/css'); | ||
// 装备数据管理类 | |||
var EquipmentManager = { | var EquipmentManager = { | ||
currentData: {}, | |||
editingEquipment: null, | |||
// 初始化 | |||
init: function() { | init: function() { | ||
this.loadData(); | this.loadData(); | ||
this.renderUI(); | this.renderUI(); | ||
this.bindEvents(); | |||
}, | }, | ||
// 从模块加载数据 | |||
loadData: function() { | loadData: function() { | ||
var self = this; | var self = this; | ||
new mw.Api().get({ | |||
action: 'parse', | |||
page: '模块:装备/data', | |||
prop: 'wikitext' | |||
}).done(function(data) { | |||
if (data.parse && data.parse.wikitext) { | |||
self.parseDataModule(data.parse.wikitext['*']); | |||
} | } | ||
}); | }); | ||
}, | }, | ||
// 解析 Lua 数据模块 | |||
parseDataModule: function(luaCode) { | |||
var dataMatch = luaCode.match(/local data = \{([\s\S]*)\}\s*return/); | |||
if (dataMatch) { | |||
this.loadDataViaInvoke(); | |||
} | |||
}, | |||
// 通过 scribunto 调用获取数据 | |||
loadDataViaInvoke: function() { | |||
var self = this; | var self = this; | ||
new mw.Api().get({ | |||
action: 'expandtemplates', | |||
text: '{{#invoke:装备|getAllData}}', | |||
} | prop: 'wikitext' | ||
self. | }).done(function(data) { | ||
if (data.expandtemplates && data.expandtemplates.wikitext) { | |||
try { | |||
self.currentData = JSON.parse(data.expandtemplates.wikitext); | |||
self.renderEquipmentList(); | |||
} catch(e) { | |||
console.error('数据解析失败', e); | |||
} | |||
} | |||
}); | }); | ||
}, | }, | ||
// 渲染界面 | |||
renderUI: function() { | |||
var | var $container = $('#mw-content-text'); | ||
$container.empty(); | |||
var html = '<div class="equipment-manager">' + | |||
'<div class="eq-header">' + | |||
'<div class="eq-title">装备数据管理</div>' + | |||
'<div class="eq-btn eq-btn-primary" id="eq-add-new">新增装备</div>' + | |||
'</div>' + | |||
'<div class="eq-list" id="equipment-list"></div>' + | |||
id | '<div class="eq-modal" id="eq-modal" style="display:none;">' + | ||
'<div class="eq-modal-content">' + | |||
'<div class="eq-modal-header">' + | |||
'<div class="eq-modal-title" id="modal-title">新增装备</div>' + | |||
'<div class="eq-modal-close" id="modal-close">×</div>' + | |||
'</div>' + | |||
'<div class="eq-modal-body">' + | |||
this.renderForm() + | |||
'</div>' + | |||
'<div class="eq-modal-footer">' + | |||
'<div class="eq-btn eq-btn-secondary" id="eq-cancel">取消</div>' + | |||
'<div class="eq-btn eq-btn-primary" id="eq-save">保存</div>' + | |||
'</div>' + | |||
'</div>' + | |||
'</div>' + | |||
'<div class="eq-modal-backdrop" id="modal-backdrop" style="display:none;"></div>' + | |||
'</div>'; | |||
$container.html(html); | |||
}, | }, | ||
// 渲染表单 | |||
renderForm: function() { | |||
return '<div class="eq-form">' + | |||
'<div class="eq-form-group">' + | |||
'<div class="eq-label">装备名称:</div>' + | |||
'<div class="eq-input" contenteditable="true" id="eq-name" data-placeholder="请输入装备名称"></div>' + | |||
'</div>' + | |||
'<div class="eq-form-group">' + | |||
'<div class="eq-label">遗物ID:</div>' + | |||
'<div class="eq-input" contenteditable="true" id="eq-relic-id" data-placeholder="例如: 1001"></div>' + | |||
'</div>' + | |||
'<div class="eq-form-group">' + | |||
'<div class="eq-label">地区:</div>' + | |||
'<div class="eq-select" id="eq-area">' + | |||
'<div class="eq-select-display" data-value="">请选择地区</div>' + | |||
'<div class="eq-select-dropdown">' + | |||
'<div class="eq-select-option" data-value="蓝壶">蓝壶</div>' + | |||
'<div class="eq-select-option" data-value="双星之影">双星之影</div>' + | |||
'<div class="eq-select-option" data-value="雾之都市">雾之都市</div>' + | |||
'</div>' + | |||
'</div>' + | |||
'</div>' + | |||
'<div class="eq-form-group">' + | |||
'<div class="eq-label">稀有度:</div>' + | |||
'<div class="eq-select" id="eq-rarity">' + | |||
'<div class="eq-select-display" data-value="">请选择稀有度</div>' + | |||
'<div class="eq-select-dropdown">' + | |||
'<div class="eq-select-option" data-value="蓝">蓝</div>' + | |||
'<div class="eq-select-option" data-value="紫">紫</div>' + | |||
'<div class="eq-select-option" data-value="金">金</div>' + | |||
'</div>' + | |||
'</div>' + | |||
'</div>' + | |||
'<div class="eq-form-group">' + | |||
'<div class="eq-label">类型:</div>' + | |||
'<div class="eq-select" id="eq-type">' + | |||
'<div class="eq-select-display" data-value="">请选择类型</div>' + | |||
'<div class="eq-select-dropdown">' + | |||
'<div class="eq-select-option" data-value="武器">武器</div>' + | |||
'<div class="eq-select-option" data-value="装甲">装甲</div>' + | |||
'<div class="eq-select-option" data-value="戒指">戒指</div>' + | |||
'</div>' + | |||
'</div>' + | |||
'</div>' + | |||
'<div class="eq-form-group">' + | |||
'<div class="eq-label">属性类型:</div>' + | |||
'<div class="eq-input" contenteditable="true" id="eq-value-type" data-placeholder="例如: 攻击力"></div>' + | |||
'</div>' + | |||
'<div class="eq-form-group">' + | |||
'<div class="eq-label">TAG (用逗号分隔):</div>' + | |||
'<div class="eq-input" contenteditable="true" id="eq-tag" data-placeholder="例如: 输出,爆发"></div>' + | |||
'</div>' + | |||
'<div class="eq-form-section">' + | |||
'<div class="eq-section-title">等级数据</div>' + | |||
this.renderLevelInputs() + | |||
'</div>' + | |||
'</div>'; | |||
}, | }, | ||
// 渲染等级输入 | |||
var | renderLevelInputs: function() { | ||
var | var html = ''; | ||
for (var i = 1; i <= 5; i++) { | |||
html += '<div class="eq-level-group">' + | |||
'<div class="eq-level-title">★' + i + '</div>' + | |||
'<div class="eq-form-row">' + | |||
'<div class="eq-form-col">' + | |||
} | '<div class="eq-label-small">属性值:</div>' + | ||
'<div class="eq-input-small" contenteditable="true" id="eq-value-' + i + '" data-placeholder="数值"></div>' + | |||
'</div>' + | |||
'<div class="eq-form-col">' + | |||
'<div class="eq-label-small">描述:</div>' + | |||
'<div class="eq-input-small" contenteditable="true" id="eq-desc-' + i + '" data-placeholder="效果描述"></div>' + | |||
'</div>' + | |||
'</div>' + | |||
'</div>'; | |||
} | |||
return html; | |||
}, | }, | ||
// 渲染装备列表 | |||
var | renderEquipmentList: function() { | ||
var $list = $('#equipment-list'); | |||
$list.empty(); | |||
var html = | var html = '<div class="eq-table">' + | ||
'<div class="eq-table-header">' + | |||
'<div class="eq-th eq-th-image">图片</div>' + | |||
'<div class="eq-th eq-th-name">名称</div>' + | |||
' | '<div class="eq-th">地区</div>' + | ||
'<div class="eq-th">稀有度</div>' + | |||
'<div class="eq-th">类型</div>' + | |||
'<div class="eq-th">TAG</div>' + | |||
'<div class="eq-th eq-th-actions">操作</div>' + | |||
'</div>' + | |||
'<div class="eq-table-body">'; | |||
' | |||
' | |||
for (var name in this.currentData) { | |||
if (name === 'base') continue; | |||
var equip = this.currentData[name]; | |||
var base = equip.base; | |||
var relicId = base.art ? base.art.replace('.png', '') : 'unknown'; | |||
html += '<div class="eq-table-row" data-equipment="' + name + '">' + | |||
'<div class="eq-td eq-td-image">' + | |||
'<img src="/images/' + relicId + '.png" alt="' + name + '" class="eq-thumbnail">' + | |||
'</div>' + | |||
var | '<div class="eq-td eq-td-name">' + name + '</div>' + | ||
'<div class="eq-td">' + (base.area || '') + '</div>' + | |||
'<div class="eq-td"><span class="eq-rarity eq-rarity-' + base.rarity + '">' + base.rarity + '</span></div>' + | |||
' | '<div class="eq-td">' + (base.type || '') + '</div>' + | ||
' | '<div class="eq-td">' + (base.tag || '') + '</div>' + | ||
' | '<div class="eq-td eq-td-actions">' + | ||
' | '<div class="eq-btn-small eq-btn-edit" data-name="' + name + '">编辑</div>' + | ||
' | '<div class="eq-btn-small eq-btn-delete" data-name="' + name + '">删除</div>' + | ||
' | '</div>' + | ||
' | '</div>'; | ||
' | |||
} | } | ||
html += '</div></div>'; | |||
$list.html(html); | |||
$ | |||
}, | }, | ||
// 绑定事件 | |||
bindEvents: function() { | bindEvents: function() { | ||
var self = this; | var self = this; | ||
// 新增按钮 | // 新增按钮 | ||
$('#eq-add-new').on('click', function() { | $(document).on('click', '#eq-add-new', function() { | ||
self. | self.openModal('add'); | ||
}); | |||
// 编辑按钮 | |||
$(document).on('click', '.eq-btn-edit', function() { | |||
var name = $(this).data('name'); | |||
self.openModal('edit', name); | |||
}); | |||
// 删除按钮 | |||
$(document).on('click', '.eq-btn-delete', function() { | |||
var name = $(this).data('name'); | |||
self.deleteEquipment(name); | |||
}); | }); | ||
// 关闭模态框 | // 关闭模态框 | ||
$(' | $(document).on('click', '#modal-close, #eq-cancel, #modal-backdrop', function() { | ||
self. | self.closeModal(); | ||
}); | }); | ||
// 保存按钮 | // 保存按钮 | ||
$( | $(document).on('click', '#eq-save', function() { | ||
self. | self.saveEquipment(); | ||
}); | }); | ||
// | // 自定义下拉框 | ||
$( | $(document).on('click', '.eq-select-display', function(e) { | ||
e.stopPropagation(); | |||
$(this).siblings('.eq-select-dropdown').toggle(); | |||
}); | }); | ||
$(document).on('click', '.eq-select-option', function() { | |||
$( | var value = $(this).data('value'); | ||
var | var text = $(this).text(); | ||
$(this).closest('.eq-select').find('.eq-select-display') | |||
.text(text) | |||
.attr('data-value', value); | |||
$(this).parent().hide(); | |||
}); | }); | ||
$(document).on('click', function() { | |||
$( | $('.eq-select-dropdown').hide(); | ||
}); | }); | ||
}, | }, | ||
// 打开模态框 | |||
this. | openModal: function(mode, equipmentName) { | ||
this.editingEquipment = equipmentName; | |||
if (mode === ' | if (mode === 'edit' && equipmentName) { | ||
$('# | $('#modal-title').text('编辑装备'); | ||
this.fillFormData(equipmentName); | |||
} else { | } else { | ||
$('# | $('#modal-title').text('新增装备'); | ||
this.clearForm(); | |||
} | } | ||
$('#eq- | $('#eq-modal, #modal-backdrop').fadeIn(200); | ||
}, | }, | ||
// 关闭模态框 | |||
$('#eq- | closeModal: function() { | ||
this. | $('#eq-modal, #modal-backdrop').fadeOut(200); | ||
this.editingEquipment = null; | |||
}, | }, | ||
// 填充表单数据 | |||
var | fillFormData: function(name) { | ||
var equip = this.currentData[name]; | |||
if (!equip) return; | |||
var base = equip.base; | |||
$('#eq-name').text(name); | |||
$('#eq-relic-id').text(base.art ? base.art.replace('.png', '') : ''); | |||
$('#eq-area .eq-select-display').text(base.area).attr('data-value', base.area); | |||
$('#eq-rarity .eq-select-display').text(base.rarity).attr('data-value', base.rarity); | |||
$('#eq-type .eq-select-display').text(base.type).attr('data-value', base.type); | |||
$('#eq-value-type').text(base.value_type || ''); | |||
$('#eq-tag').text(base.tag || ''); | |||
for (var i = 1; i <= 5; i++) { | |||
if (equip[i]) { | |||
$('#eq-value-' + i).text(equip[i].value || ''); | |||
$('#eq-desc-' + i).text(equip[i].desc_global || ''); | |||
} | |||
} | |||
}, | |||
// 清空表单 | |||
clearForm: function() { | |||
$('.eq-input, .eq-input-small').text(''); | |||
$('.eq-select-display').text('请选择').attr('data-value', ''); | |||
$('#eq-area .eq-select-display').text('请选择地区'); | |||
$('#eq-rarity .eq-select-display').text('请选择稀有度'); | |||
$('#eq-type .eq-select-display').text('请选择类型'); | |||
}, | |||
// 获取表单数据 | |||
getFormData: function() { | |||
var name = $('#eq-name').text().trim(); | |||
var relicId = $('#eq-relic-id').text().trim(); | |||
var area = $('#eq-area .eq-select-display').attr('data-value'); | |||
var rarity = $('#eq-rarity .eq-select-display').attr('data-value'); | |||
var type = $('#eq-type .eq-select-display').attr('data-value'); | |||
var valueType = $('#eq-value-type').text().trim(); | |||
var tag = $('#eq-tag').text().trim(); | |||
// 验证必填项 | |||
if (!name) { | if (!name) { | ||
mw.notify('请输入装备名称', { type: 'error' }); | mw.notify('请输入装备名称', {type: 'error'}); | ||
return; | return null; | ||
} | |||
if (!relicId) { | |||
mw.notify('请输入遗物ID', {type: 'error'}); | |||
return null; | |||
} | |||
if (!area) { | |||
mw.notify('请选择地区', {type: 'error'}); | |||
return null; | |||
} | |||
if (!rarity) { | |||
mw.notify('请选择稀有度', {type: 'error'}); | |||
return null; | |||
} | |||
if (!type) { | |||
mw.notify('请选择类型', {type: 'error'}); | |||
return null; | |||
} | } | ||
var | var data = { | ||
name: name, | name: name, | ||
base: { | |||
area: area, | |||
rarity: rarity, | |||
type: type, | |||
value_type: valueType, | |||
tag: tag, | |||
} | art: relicId + '.png' | ||
}, | |||
levels: {} | |||
}; | }; | ||
// 获取等级数据 | |||
for (var i = 1; i <= 5; i++) { | |||
var value = $('#eq-value-' + i).text().trim(); | |||
var desc = $('#eq-desc-' + i).text().trim(); | |||
if (value || desc) { | |||
data.levels[i] = { | |||
value: value, | |||
desc_global: desc | |||
}; | |||
} | |||
} | |||
return data; | |||
}, | }, | ||
// 保存装备 | |||
if (! | saveEquipment: function() { | ||
var self = this; | |||
var formData = this.getFormData(); | |||
if (!formData) return; | |||
// 检查是否重名(新增模式下) | |||
if (!this.editingEquipment && this.currentData[formData.name]) { | |||
mw.notify('装备名称已存在', {type: 'error'}); | |||
return; | return; | ||
} | } | ||
delete this. | // 更新本地数据 | ||
this. | var equipmentData = { | ||
this. | base: formData.base | ||
}; | |||
for (var level in formData.levels) { | |||
equipmentData[level] = formData.levels[level]; | |||
} | |||
// 如果是编辑模式且名称改变,删除旧条目 | |||
if (this.editingEquipment && this.editingEquipment !== formData.name) { | |||
delete this.currentData[this.editingEquipment]; | |||
} | |||
this.currentData[formData.name] = equipmentData; | |||
// 生成 Lua 代码 | |||
var luaCode = this.generateLuaCode(); | |||
// 保存到模块 | |||
this.saveToModule(luaCode); | |||
}, | }, | ||
// 删除装备 | |||
deleteEquipment: function(name) { | |||
var self = this; | |||
if (!confirm('确定要删除装备"' + name + '"吗?')) { | |||
return; | |||
} | |||
delete this.currentData[name]; | |||
// 生成 Lua 代码 | |||
var luaCode = this.generateLuaCode(); | |||
// 保存到模块 | |||
this.saveToModule(luaCode); | |||
}, | |||
// 生成 Lua 代码 | |||
generateLuaCode: function() { | generateLuaCode: function() { | ||
var | var lua = 'local data = {\n'; | ||
// 按名称排序 | |||
var names = Object.keys(this.currentData).sort(); | |||
for (var | for (var i = 0; i < names.length; i++) { | ||
var | var name = names[i]; | ||
var equip = this.currentData[name]; | |||
lua += ' ["' + this.escapeLua(name) + '"] = {\n'; | |||
lua += ' base = {\n'; | |||
lua += ' area = "' + this.escapeLua(equip.base.area) + '",\n'; | |||
} | lua += ' rarity = "' + this.escapeLua(equip.base.rarity) + '",\n'; | ||
lua += ' type = "' + this.escapeLua(equip.base.type) + '",\n'; | |||
lua += ' value_type = "' + this.escapeLua(equip.base.value_type || '') + '",\n'; | |||
lua += ' tag = "' + this.escapeLua(equip.base.tag || '') + '",\n'; | |||
lua += ' art = "' + this.escapeLua(equip.base.art) + '"\n'; | |||
lua += ' },\n'; | |||
// 添加等级数据 | |||
for (var level = 1; level <= 5; level++) { | |||
if (equip[level]) { | |||
lua += ' ["' + level + '"] = {\n'; | |||
lua += ' value = "' + this.escapeLua(equip[level].value || '') + '",\n'; | |||
lua += ' desc_global = "' + this.escapeLua(equip[level].desc_global || '') + '"\n'; | |||
lua += ' },\n'; | |||
} | |||
} | |||
lua += ' },\n'; | |||
} | } | ||
lua += '}\n\nreturn data'; | |||
return lua; | |||
}, | |||
// 转义 Lua 字符串 | |||
escapeLua: function(str) { | |||
if (!str) return ''; | |||
return str.replace(/\\/g, '\\\\') | |||
.replace(/"/g, '\\"') | |||
.replace(/\n/g, '\\n') | |||
.replace(/\r/g, '\\r'); | |||
}, | |||
// 保存到模块 | |||
saveToModule: function(luaCode) { | |||
var self = this; | |||
// | // 显示保存中状态 | ||
mw.notify('正在保存...', {type: 'info'}); | |||
new mw.Api().postWithToken('csrf', { | |||
action: 'edit', | |||
title: '模块:装备/data', | |||
text: luaCode, | |||
summary: '通过装备管理器更新数据', | |||
minor: true | |||
}).done(function(data) { | |||
if (data.edit && data.edit.result === 'Success') { | |||
mw.notify('保存成功!', {type: 'success'}); | |||
self.closeModal(); | |||
self.renderEquipmentList(); | |||
} else { | |||
mw.notify('保存失败', {type: 'error'}); | |||
} | |||
}).fail(function(code, result) { | |||
mw.notify('保存失败: ' + (result.error ? result.error.info : '未知错误'), {type: 'error'}); | |||
}); | |||
} | } | ||
}; | }; | ||
// | // 页面加载完成后初始化 | ||
$(function() { | $(function() { | ||
EquipmentManager.init(); | EquipmentManager.init(); | ||
2025年10月17日 (五) 19:05的版本
(function() {
'use strict';
// 加载 CSS
mw.loader.load('/index.php?title=MediaWiki:Equipment.css&action=raw&ctype=text/css', 'text/css');
// 装备数据管理类
var EquipmentManager = {
currentData: {},
editingEquipment: null,
// 初始化
init: function() {
this.loadData();
this.renderUI();
this.bindEvents();
},
// 从模块加载数据
loadData: function() {
var self = this;
new mw.Api().get({
action: 'parse',
page: '模块:装备/data',
prop: 'wikitext'
}).done(function(data) {
if (data.parse && data.parse.wikitext) {
self.parseDataModule(data.parse.wikitext['*']);
}
});
},
// 解析 Lua 数据模块
parseDataModule: function(luaCode) {
var dataMatch = luaCode.match(/local data = \{([\s\S]*)\}\s*return/);
if (dataMatch) {
this.loadDataViaInvoke();
}
},
// 通过 scribunto 调用获取数据
loadDataViaInvoke: function() {
var self = this;
new mw.Api().get({
action: 'expandtemplates',
text: '{{#invoke:装备|getAllData}}',
prop: 'wikitext'
}).done(function(data) {
if (data.expandtemplates && data.expandtemplates.wikitext) {
try {
self.currentData = JSON.parse(data.expandtemplates.wikitext);
self.renderEquipmentList();
} catch(e) {
console.error('数据解析失败', e);
}
}
});
},
// 渲染界面
renderUI: function() {
var $container = $('#mw-content-text');
$container.empty();
var html = '<div class="equipment-manager">' +
'<div class="eq-header">' +
'<div class="eq-title">装备数据管理</div>' +
'<div class="eq-btn eq-btn-primary" id="eq-add-new">新增装备</div>' +
'</div>' +
'<div class="eq-list" id="equipment-list"></div>' +
'<div class="eq-modal" id="eq-modal" style="display:none;">' +
'<div class="eq-modal-content">' +
'<div class="eq-modal-header">' +
'<div class="eq-modal-title" id="modal-title">新增装备</div>' +
'<div class="eq-modal-close" id="modal-close">×</div>' +
'</div>' +
'<div class="eq-modal-body">' +
this.renderForm() +
'</div>' +
'<div class="eq-modal-footer">' +
'<div class="eq-btn eq-btn-secondary" id="eq-cancel">取消</div>' +
'<div class="eq-btn eq-btn-primary" id="eq-save">保存</div>' +
'</div>' +
'</div>' +
'</div>' +
'<div class="eq-modal-backdrop" id="modal-backdrop" style="display:none;"></div>' +
'</div>';
$container.html(html);
},
// 渲染表单
renderForm: function() {
return '<div class="eq-form">' +
'<div class="eq-form-group">' +
'<div class="eq-label">装备名称:</div>' +
'<div class="eq-input" contenteditable="true" id="eq-name" data-placeholder="请输入装备名称"></div>' +
'</div>' +
'<div class="eq-form-group">' +
'<div class="eq-label">遗物ID:</div>' +
'<div class="eq-input" contenteditable="true" id="eq-relic-id" data-placeholder="例如: 1001"></div>' +
'</div>' +
'<div class="eq-form-group">' +
'<div class="eq-label">地区:</div>' +
'<div class="eq-select" id="eq-area">' +
'<div class="eq-select-display" data-value="">请选择地区</div>' +
'<div class="eq-select-dropdown">' +
'<div class="eq-select-option" data-value="蓝壶">蓝壶</div>' +
'<div class="eq-select-option" data-value="双星之影">双星之影</div>' +
'<div class="eq-select-option" data-value="雾之都市">雾之都市</div>' +
'</div>' +
'</div>' +
'</div>' +
'<div class="eq-form-group">' +
'<div class="eq-label">稀有度:</div>' +
'<div class="eq-select" id="eq-rarity">' +
'<div class="eq-select-display" data-value="">请选择稀有度</div>' +
'<div class="eq-select-dropdown">' +
'<div class="eq-select-option" data-value="蓝">蓝</div>' +
'<div class="eq-select-option" data-value="紫">紫</div>' +
'<div class="eq-select-option" data-value="金">金</div>' +
'</div>' +
'</div>' +
'</div>' +
'<div class="eq-form-group">' +
'<div class="eq-label">类型:</div>' +
'<div class="eq-select" id="eq-type">' +
'<div class="eq-select-display" data-value="">请选择类型</div>' +
'<div class="eq-select-dropdown">' +
'<div class="eq-select-option" data-value="武器">武器</div>' +
'<div class="eq-select-option" data-value="装甲">装甲</div>' +
'<div class="eq-select-option" data-value="戒指">戒指</div>' +
'</div>' +
'</div>' +
'</div>' +
'<div class="eq-form-group">' +
'<div class="eq-label">属性类型:</div>' +
'<div class="eq-input" contenteditable="true" id="eq-value-type" data-placeholder="例如: 攻击力"></div>' +
'</div>' +
'<div class="eq-form-group">' +
'<div class="eq-label">TAG (用逗号分隔):</div>' +
'<div class="eq-input" contenteditable="true" id="eq-tag" data-placeholder="例如: 输出,爆发"></div>' +
'</div>' +
'<div class="eq-form-section">' +
'<div class="eq-section-title">等级数据</div>' +
this.renderLevelInputs() +
'</div>' +
'</div>';
},
// 渲染等级输入
renderLevelInputs: function() {
var html = '';
for (var i = 1; i <= 5; i++) {
html += '<div class="eq-level-group">' +
'<div class="eq-level-title">★' + i + '</div>' +
'<div class="eq-form-row">' +
'<div class="eq-form-col">' +
'<div class="eq-label-small">属性值:</div>' +
'<div class="eq-input-small" contenteditable="true" id="eq-value-' + i + '" data-placeholder="数值"></div>' +
'</div>' +
'<div class="eq-form-col">' +
'<div class="eq-label-small">描述:</div>' +
'<div class="eq-input-small" contenteditable="true" id="eq-desc-' + i + '" data-placeholder="效果描述"></div>' +
'</div>' +
'</div>' +
'</div>';
}
return html;
},
// 渲染装备列表
renderEquipmentList: function() {
var $list = $('#equipment-list');
$list.empty();
var html = '<div class="eq-table">' +
'<div class="eq-table-header">' +
'<div class="eq-th eq-th-image">图片</div>' +
'<div class="eq-th eq-th-name">名称</div>' +
'<div class="eq-th">地区</div>' +
'<div class="eq-th">稀有度</div>' +
'<div class="eq-th">类型</div>' +
'<div class="eq-th">TAG</div>' +
'<div class="eq-th eq-th-actions">操作</div>' +
'</div>' +
'<div class="eq-table-body">';
for (var name in this.currentData) {
if (name === 'base') continue;
var equip = this.currentData[name];
var base = equip.base;
var relicId = base.art ? base.art.replace('.png', '') : 'unknown';
html += '<div class="eq-table-row" data-equipment="' + name + '">' +
'<div class="eq-td eq-td-image">' +
'<img src="/images/' + relicId + '.png" alt="' + name + '" class="eq-thumbnail">' +
'</div>' +
'<div class="eq-td eq-td-name">' + name + '</div>' +
'<div class="eq-td">' + (base.area || '') + '</div>' +
'<div class="eq-td"><span class="eq-rarity eq-rarity-' + base.rarity + '">' + base.rarity + '</span></div>' +
'<div class="eq-td">' + (base.type || '') + '</div>' +
'<div class="eq-td">' + (base.tag || '') + '</div>' +
'<div class="eq-td eq-td-actions">' +
'<div class="eq-btn-small eq-btn-edit" data-name="' + name + '">编辑</div>' +
'<div class="eq-btn-small eq-btn-delete" data-name="' + name + '">删除</div>' +
'</div>' +
'</div>';
}
html += '</div></div>';
$list.html(html);
},
// 绑定事件
bindEvents: function() {
var self = this;
// 新增按钮
$(document).on('click', '#eq-add-new', function() {
self.openModal('add');
});
// 编辑按钮
$(document).on('click', '.eq-btn-edit', function() {
var name = $(this).data('name');
self.openModal('edit', name);
});
// 删除按钮
$(document).on('click', '.eq-btn-delete', function() {
var name = $(this).data('name');
self.deleteEquipment(name);
});
// 关闭模态框
$(document).on('click', '#modal-close, #eq-cancel, #modal-backdrop', function() {
self.closeModal();
});
// 保存按钮
$(document).on('click', '#eq-save', function() {
self.saveEquipment();
});
// 自定义下拉框
$(document).on('click', '.eq-select-display', function(e) {
e.stopPropagation();
$(this).siblings('.eq-select-dropdown').toggle();
});
$(document).on('click', '.eq-select-option', function() {
var value = $(this).data('value');
var text = $(this).text();
$(this).closest('.eq-select').find('.eq-select-display')
.text(text)
.attr('data-value', value);
$(this).parent().hide();
});
$(document).on('click', function() {
$('.eq-select-dropdown').hide();
});
},
// 打开模态框
openModal: function(mode, equipmentName) {
this.editingEquipment = equipmentName;
if (mode === 'edit' && equipmentName) {
$('#modal-title').text('编辑装备');
this.fillFormData(equipmentName);
} else {
$('#modal-title').text('新增装备');
this.clearForm();
}
$('#eq-modal, #modal-backdrop').fadeIn(200);
},
// 关闭模态框
closeModal: function() {
$('#eq-modal, #modal-backdrop').fadeOut(200);
this.editingEquipment = null;
},
// 填充表单数据
fillFormData: function(name) {
var equip = this.currentData[name];
if (!equip) return;
var base = equip.base;
$('#eq-name').text(name);
$('#eq-relic-id').text(base.art ? base.art.replace('.png', '') : '');
$('#eq-area .eq-select-display').text(base.area).attr('data-value', base.area);
$('#eq-rarity .eq-select-display').text(base.rarity).attr('data-value', base.rarity);
$('#eq-type .eq-select-display').text(base.type).attr('data-value', base.type);
$('#eq-value-type').text(base.value_type || '');
$('#eq-tag').text(base.tag || '');
for (var i = 1; i <= 5; i++) {
if (equip[i]) {
$('#eq-value-' + i).text(equip[i].value || '');
$('#eq-desc-' + i).text(equip[i].desc_global || '');
}
}
},
// 清空表单
clearForm: function() {
$('.eq-input, .eq-input-small').text('');
$('.eq-select-display').text('请选择').attr('data-value', '');
$('#eq-area .eq-select-display').text('请选择地区');
$('#eq-rarity .eq-select-display').text('请选择稀有度');
$('#eq-type .eq-select-display').text('请选择类型');
},
// 获取表单数据
getFormData: function() {
var name = $('#eq-name').text().trim();
var relicId = $('#eq-relic-id').text().trim();
var area = $('#eq-area .eq-select-display').attr('data-value');
var rarity = $('#eq-rarity .eq-select-display').attr('data-value');
var type = $('#eq-type .eq-select-display').attr('data-value');
var valueType = $('#eq-value-type').text().trim();
var tag = $('#eq-tag').text().trim();
// 验证必填项
if (!name) {
mw.notify('请输入装备名称', {type: 'error'});
return null;
}
if (!relicId) {
mw.notify('请输入遗物ID', {type: 'error'});
return null;
}
if (!area) {
mw.notify('请选择地区', {type: 'error'});
return null;
}
if (!rarity) {
mw.notify('请选择稀有度', {type: 'error'});
return null;
}
if (!type) {
mw.notify('请选择类型', {type: 'error'});
return null;
}
var data = {
name: name,
base: {
area: area,
rarity: rarity,
type: type,
value_type: valueType,
tag: tag,
art: relicId + '.png'
},
levels: {}
};
// 获取等级数据
for (var i = 1; i <= 5; i++) {
var value = $('#eq-value-' + i).text().trim();
var desc = $('#eq-desc-' + i).text().trim();
if (value || desc) {
data.levels[i] = {
value: value,
desc_global: desc
};
}
}
return data;
},
// 保存装备
saveEquipment: function() {
var self = this;
var formData = this.getFormData();
if (!formData) return;
// 检查是否重名(新增模式下)
if (!this.editingEquipment && this.currentData[formData.name]) {
mw.notify('装备名称已存在', {type: 'error'});
return;
}
// 更新本地数据
var equipmentData = {
base: formData.base
};
for (var level in formData.levels) {
equipmentData[level] = formData.levels[level];
}
// 如果是编辑模式且名称改变,删除旧条目
if (this.editingEquipment && this.editingEquipment !== formData.name) {
delete this.currentData[this.editingEquipment];
}
this.currentData[formData.name] = equipmentData;
// 生成 Lua 代码
var luaCode = this.generateLuaCode();
// 保存到模块
this.saveToModule(luaCode);
},
// 删除装备
deleteEquipment: function(name) {
var self = this;
if (!confirm('确定要删除装备"' + name + '"吗?')) {
return;
}
delete this.currentData[name];
// 生成 Lua 代码
var luaCode = this.generateLuaCode();
// 保存到模块
this.saveToModule(luaCode);
},
// 生成 Lua 代码
generateLuaCode: function() {
var lua = 'local data = {\n';
// 按名称排序
var names = Object.keys(this.currentData).sort();
for (var i = 0; i < names.length; i++) {
var name = names[i];
var equip = this.currentData[name];
lua += ' ["' + this.escapeLua(name) + '"] = {\n';
lua += ' base = {\n';
lua += ' area = "' + this.escapeLua(equip.base.area) + '",\n';
lua += ' rarity = "' + this.escapeLua(equip.base.rarity) + '",\n';
lua += ' type = "' + this.escapeLua(equip.base.type) + '",\n';
lua += ' value_type = "' + this.escapeLua(equip.base.value_type || '') + '",\n';
lua += ' tag = "' + this.escapeLua(equip.base.tag || '') + '",\n';
lua += ' art = "' + this.escapeLua(equip.base.art) + '"\n';
lua += ' },\n';
// 添加等级数据
for (var level = 1; level <= 5; level++) {
if (equip[level]) {
lua += ' ["' + level + '"] = {\n';
lua += ' value = "' + this.escapeLua(equip[level].value || '') + '",\n';
lua += ' desc_global = "' + this.escapeLua(equip[level].desc_global || '') + '"\n';
lua += ' },\n';
}
}
lua += ' },\n';
}
lua += '}\n\nreturn data';
return lua;
},
// 转义 Lua 字符串
escapeLua: function(str) {
if (!str) return '';
return str.replace(/\\/g, '\\\\')
.replace(/"/g, '\\"')
.replace(/\n/g, '\\n')
.replace(/\r/g, '\\r');
},
// 保存到模块
saveToModule: function(luaCode) {
var self = this;
// 显示保存中状态
mw.notify('正在保存...', {type: 'info'});
new mw.Api().postWithToken('csrf', {
action: 'edit',
title: '模块:装备/data',
text: luaCode,
summary: '通过装备管理器更新数据',
minor: true
}).done(function(data) {
if (data.edit && data.edit.result === 'Success') {
mw.notify('保存成功!', {type: 'success'});
self.closeModal();
self.renderEquipmentList();
} else {
mw.notify('保存失败', {type: 'error'});
}
}).fail(function(code, result) {
mw.notify('保存失败: ' + (result.error ? result.error.info : '未知错误'), {type: 'error'});
});
}
};
// 页面加载完成后初始化
$(function() {
EquipmentManager.init();
});
})();