MediaWiki

Equipment.js:修订间差异

来自卡厄思梦境WIKI

律Rhyme留言 | 贡献
创建页面,内容为“(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();…”
 
律Rhyme留言 | 贡献
无编辑摘要
第1行: 第1行:
(function() {
(function() {
     'use strict';
     'use strict';
   
 
    // 等待页面加载完成
    if (mw.config.get('wgPageName') !== 'MediaWiki:Equipment') {
        return;
    }
   
     // 加载 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 = {
         data: {},
         currentData: {},
         currentEditKey: null,
         editingEquipment: null,
          
          
        // 初始化
         init: function() {
         init: function() {
             this.loadData();
             this.loadData();
             this.renderUI();
             this.renderUI();
            this.bindEvents();
         },
         },
          
          
        // 从模块加载数据
         loadData: function() {
         loadData: function() {
            // 通过 API 加载模块数据
             var self = this;
             var self = this;
             $.ajax({
             new mw.Api().get({
                url: mw.util.wikiScript('api'),
                 action: 'parse',
                 data: {
                page: '模块:装备/data',
                    action: 'scribunto-console',
                prop: 'wikitext'
                    title: '模块:装备/data',
            }).done(function(data) {
                    question: 'return require("模块:装备/data")',
                if (data.parse && data.parse.wikitext) {
                    format: 'json'
                    self.parseDataModule(data.parse.wikitext['*']);
                },
                success: function(response) {
                    if (response && response.print) {
                        self.parseData(response.print);
                    }
                 }
                 }
             });
             });
           
            // 备用:从页面解析
            this.loadFromPage();
         },
         },
          
          
         loadFromPage: function() {
         // 解析 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;
             $.get(mw.util.wikiScript('index'), {
             new mw.Api().get({
                 title: '模块:装备/data',
                action: 'expandtemplates',
                 action: 'raw'
                 text: '{{#invoke:装备|getAllData}}',
             }, function(content) {
                 prop: 'wikitext'
                 self.parseDataFromLua(content);
             }).done(function(data) {
                self.renderTable();
                 if (data.expandtemplates && data.expandtemplates.wikitext) {
                    try {
                        self.currentData = JSON.parse(data.expandtemplates.wikitext);
                        self.renderEquipmentList();
                    } catch(e) {
                        console.error('数据解析失败', e);
                    }
                }
             });
             });
         },
         },
          
          
         parseDataFromLua: function(luaContent) {
         // 渲染界面
            // 简单的 Lua 解析
        renderUI: function() {
             var equipmentPattern = /equipment\["([^"]+)"\]\s*=\s*\{([^}]+(?:\{[^}]*\}[^}]*)*)\}/g;
             var $container = $('#mw-content-text');
             var match;
             $container.empty();
              
              
             while ((match = equipmentPattern.exec(luaContent)) !== null) {
             var html = '<div class="equipment-manager">' +
                var name = match[1];
                '<div class="eq-header">' +
                var content = match[2];
                    '<div class="eq-title">装备数据管理</div>' +
                  
                    '<div class="eq-btn eq-btn-primary" id="eq-add-new">新增装备</div>' +
                 var item = {
                 '</div>' +
                    name: name,
                 '<div class="eq-list" id="equipment-list"></div>' +
                     id: this.extractValue(content, 'id'),
                '<div class="eq-modal" id="eq-modal" style="display:none;">' +
                    rarity: this.extractValue(content, 'rarity'),
                     '<div class="eq-modal-content">' +
                    type: this.extractValue(content, 'type'),
                        '<div class="eq-modal-header">' +
                    tag: this.extractValue(content, 'tag'),
                            '<div class="eq-modal-title" id="modal-title">新增装备</div>' +
                     desc: this.extractArray(content, 'desc')
                            '<div class="eq-modal-close" id="modal-close">×</div>' +
                 };
                        '</div>' +
                  
                        '<div class="eq-modal-body">' +
                this.data[name] = item;
                            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);
         },
         },
          
          
         extractValue: function(content, key) {
         // 渲染表单
             var pattern = new RegExp(key + '\\s*=\\s*["\']?([^,"\'\\n]+)["\']?');
        renderForm: function() {
            var match = content.match(pattern);
             return '<div class="eq-form">' +
             return match ? match[1].trim() : '';
                '<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>';
         },
         },
          
          
         extractArray: function(content, key) {
         // 渲染等级输入
             var pattern = new RegExp(key + '\\s*=\\s*\\{([^}]+)\\}');
        renderLevelInputs: function() {
             var match = content.match(pattern);
             var html = '';
            if (!match) return [];
             for (var i = 1; i <= 5; i++) {
           
                html += '<div class="eq-level-group">' +
            var items = match[1].match(/"([^"]+)"/g) || [];
                    '<div class="eq-level-title">★' + i + '</div>' +
            return items.map(function(item) {
                    '<div class="eq-form-row">' +
                return item.replace(/"/g, '');
                        '<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;
         },
         },
          
          
         renderUI: function() {
         // 渲染装备列表
             var container = $('#mw-content-text');
        renderEquipmentList: function() {
             container.empty();
             var $list = $('#equipment-list');
             $list.empty();
              
              
             var html = [
             var html = '<div class="eq-table">' +
                '<div class="equipment-manager">',
                 '<div class="eq-table-header">' +
                '  <div class="eq-header">',
                    '<div class="eq-th eq-th-image">图片</div>' +
                '    <h2>装备数据管理器</h2>',
                    '<div class="eq-th eq-th-name">名称</div>' +
                 '   <div class="eq-btn eq-btn-primary" id="eq-add-new">新增装备</div>',
                    '<div class="eq-th">地区</div>' +
                '  </div>',
                    '<div class="eq-th">稀有度</div>' +
                '  <div id="eq-table-container"></div>',
                    '<div class="eq-th">类型</div>' +
                ' <div id="eq-form-modal" class="eq-modal" style="display:none;">',
                    '<div class="eq-th">TAG</div>' +
                '    <div class="eq-modal-content">',
                    '<div class="eq-th eq-th-actions">操作</div>' +
                '      <div class="eq-modal-header">',
                 '</div>' +
                '        <h3 id="eq-form-title">新增装备</h3>',
                 '<div class="eq-table-body">';
                '        <span class="eq-close">&times;</span>',
                '      </div>',
                '     <div class="eq-modal-body">',
                '        <form id="eq-form">',
                '          <div class="eq-form-group">',
                '            <label>装备名称:</label>',
                '            <input type="text" name="name" class="eq-input" required />',
                '          </div>',
                '         <div class="eq-form-group">',
                '            <label>ID:</label>',
                '            <input type="number" name="id" class="eq-input" required />',
                '          </div>',
                '         <div class="eq-form-group">',
                '            <label>稀有度:</label>',
                '           <div class="eq-radio-group">',
                '              <label><input type="radio" name="rarity" value="蓝" /> 蓝</label>',
                '              <label><input type="radio" name="rarity" value="紫" /> 紫</label>',
                '              <label><input type="radio" name="rarity" value="橙" /> 橙</label>',
                '            </div>',
                '         </div>',
                '          <div class="eq-form-group">',
                '            <label>类型:</label>',
                '            <div class="eq-radio-group">',
                '              <label><input type="radio" name="type" value="武器" /> 武器</label>',
                '             <label><input type="radio" name="type" value="装甲" /> 装甲</label>',
                '              <label><input type="radio" name="type" value="戒指" /> 戒指</label>',
                '            </div>',
                '          </div>',
                '          <div class="eq-form-group">',
                '            <label>标签:</label>',
                '            <input type="text" name="tag" class="eq-input" placeholder="用逗号分隔" />',
                '          </div>',
                '          <div class="eq-form-group">',
                '            <label>描述(每行一个等级):</label>',
                '            <textarea name="desc" class="eq-textarea" rows="5"></textarea>',
                '          </div>',
                 '         <div class="eq-form-actions">',
                '            <div class="eq-btn eq-btn-primary" id="eq-save">保存</div>',
                 '           <div class="eq-btn eq-btn-secondary" id="eq-cancel">取消</div>',
                '          </div>',
                '        </form>',
                '      </div>',
                '    </div>',
                '  </div>',
                '</div>'
            ].join('');
              
              
             container.html(html);
             for (var name in this.currentData) {
            this.bindEvents();
                if (name === 'base') continue;
            this.renderTable();
                var equip = this.currentData[name];
        },
                var base = equip.base;
       
                 var relicId = base.art ? base.art.replace('.png', '') : 'unknown';
        renderTable: function() {
                  
            var tbody = [];
                html += '<div class="eq-table-row" data-equipment="' + name + '">' +
            var index = 1;
                     '<div class="eq-td eq-td-image">' +
           
                        '<img src="/images/' + relicId + '.png" alt="' + name + '" class="eq-thumbnail">' +
            for (var name in this.data) {
                    '</div>' +
                 var item = this.data[name];
                     '<div class="eq-td eq-td-name">' + name + '</div>' +
                 tbody.push([
                     '<div class="eq-td">' + (base.area || '') + '</div>' +
                    '<div class="eq-table-row">',
                     '<div class="eq-td"><span class="eq-rarity eq-rarity-' + base.rarity + '">' + base.rarity + '</span></div>' +
                     ' <div class="eq-cell">' + index++ + '</div>',
                     '<div class="eq-td">' + (base.type || '') + '</div>' +
                     ' <div class="eq-cell">' + mw.html.escape(name) + '</div>',
                     '<div class="eq-td">' + (base.tag || '') + '</div>' +
                     ' <div class="eq-cell">' + mw.html.escape(item.id) + '</div>',
                     '<div class="eq-td eq-td-actions">' +
                     ' <div class="eq-cell eq-rarity-' + item.rarity + '">' + mw.html.escape(item.rarity) + '</div>',
                        '<div class="eq-btn-small eq-btn-edit" data-name="' + name + '">编辑</div>' +
                     ' <div class="eq-cell">' + mw.html.escape(item.type) + '</div>',
                        '<div class="eq-btn-small eq-btn-delete" data-name="' + name + '">删除</div>' +
                     ' <div class="eq-cell">' + mw.html.escape(item.tag) + '</div>',
                     '</div>' +
                     ' <div class="eq-cell eq-actions">',
                '</div>';
                    '   <span class="eq-link eq-edit" data-name="' + mw.html.escape(name) + '">编辑</span>',
                    '   <span class="eq-link eq-delete" data-name="' + mw.html.escape(name) + '">删除</span>',
                     ' </div>',
                    '</div>'
                ].join(''));
             }
             }
              
              
             var html = [
             html += '</div></div>';
                '<div class="eq-table">',
             $list.html(html);
                '  <div class="eq-table-header">',
                '    <div class="eq-cell">序号</div>',
                '    <div class="eq-cell">名称</div>',
                '    <div class="eq-cell">ID</div>',
                '    <div class="eq-cell">稀有度</div>',
                '    <div class="eq-cell">类型</div>',
                '    <div class="eq-cell">标签</div>',
                '    <div class="eq-cell">操作</div>',
                '  </div>',
                '  <div class="eq-table-body">',
                tbody.join(''),
                '  </div>',
                '</div>'
            ].join('');
           
             $('#eq-table-container').html(html);
            this.bindTableEvents();
         },
         },
          
          
        // 绑定事件
         bindEvents: function() {
         bindEvents: function() {
             var self = this;
             var self = this;
              
              
             // 新增按钮
             // 新增按钮
             $('#eq-add-new').on('click', function() {
             $(document).on('click', '#eq-add-new', function() {
                 self.showForm('add');
                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);
             });
             });
              
              
             // 关闭模态框
             // 关闭模态框
             $('.eq-close, #eq-cancel').on('click', function() {
             $(document).on('click', '#modal-close, #eq-cancel, #modal-backdrop', function() {
                 self.hideForm();
                 self.closeModal();
             });
             });
              
              
             // 保存按钮
             // 保存按钮
             $('#eq-save').on('click', function() {
             $(document).on('click', '#eq-save', function() {
                 self.saveData();
                 self.saveEquipment();
             });
             });
              
              
             // 点击模态框外部关闭
             // 自定义下拉框
             $('#eq-form-modal').on('click', function(e) {
             $(document).on('click', '.eq-select-display', function(e) {
                 if (e.target.id === 'eq-form-modal') {
                 e.stopPropagation();
                    self.hideForm();
                $(this).siblings('.eq-select-dropdown').toggle();
                }
             });
             });
        },
       
        bindTableEvents: function() {
            var self = this;
              
              
            // 编辑按钮
             $(document).on('click', '.eq-select-option', function() {
             $('.eq-edit').on('click', function() {
                 var value = $(this).data('value');
                 var name = $(this).data('name');
                 var text = $(this).text();
                 self.showForm('edit', name);
                $(this).closest('.eq-select').find('.eq-select-display')
                    .text(text)
                    .attr('data-value', value);
                $(this).parent().hide();
             });
             });
              
              
            // 删除按钮
             $(document).on('click', function() {
             $('.eq-delete').on('click', function() {
                 $('.eq-select-dropdown').hide();
                 var name = $(this).data('name');
                self.deleteItem(name);
             });
             });
         },
         },
          
          
         showForm: function(mode, name) {
         // 打开模态框
             this.currentEditKey = name || null;
        openModal: function(mode, equipmentName) {
            var form = $('#eq-form')[0];
             this.editingEquipment = equipmentName;
            form.reset();
              
              
             if (mode === 'add') {
             if (mode === 'edit' && equipmentName) {
                 $('#eq-form-title').text('新增装备');
                 $('#modal-title').text('编辑装备');
                 $('input[name="name"]').prop('disabled', false);
                 this.fillFormData(equipmentName);
             } else {
             } else {
                 $('#eq-form-title').text('编辑装备');
                 $('#modal-title').text('新增装备');
                 var item = this.data[name];
                 this.clearForm();
                $('input[name="name"]').val(item.name).prop('disabled', true);
                $('input[name="id"]').val(item.id);
                $('input[name="rarity"][value="' + item.rarity + '"]').prop('checked', true);
                $('input[name="type"][value="' + item.type + '"]').prop('checked', true);
                $('input[name="tag"]').val(item.tag);
                $('textarea[name="desc"]').val(item.desc.join('\n'));
             }
             }
              
              
             $('#eq-form-modal').fadeIn();
             $('#eq-modal, #modal-backdrop').fadeIn(200);
         },
         },
          
          
         hideForm: function() {
         // 关闭模态框
             $('#eq-form-modal').fadeOut();
        closeModal: function() {
             this.currentEditKey = null;
             $('#eq-modal, #modal-backdrop').fadeOut(200);
             this.editingEquipment = null;
         },
         },
          
          
         saveData: function() {
         // 填充表单数据
             var form = $('#eq-form')[0];
        fillFormData: function(name) {
             var name = $('input[name="name"]').val().trim();
             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 item = {
             var data = {
                 name: name,
                 name: name,
                 id: $('input[name="id"]').val(),
                 base: {
                rarity: $('input[name="rarity"]:checked').val() || '蓝',
                    area: area,
                type: $('input[name="type"]:checked').val() || '武器',
                    rarity: rarity,
                tag: $('input[name="tag"]').val().trim(),
                    type: type,
                desc: $('textarea[name="desc"]').val().split('\n').filter(function(line) {
                    value_type: valueType,
                    return line.trim();
                    tag: tag,
                 })
                    art: relicId + '.png'
                },
                 levels: {}
             };
             };
              
              
             this.data[name] = item;
             // 获取等级数据
            this.hideForm();
            for (var i = 1; i <= 5; i++) {
            this.renderTable();
                var value = $('#eq-value-' + i).text().trim();
            this.generateLuaCode();
                var desc = $('#eq-desc-' + i).text().trim();
               
                if (value || desc) {
                    data.levels[i] = {
                        value: value,
                        desc_global: desc
                    };
                }
            }
           
            return data;
         },
         },
          
          
         deleteItem: function(name) {
         // 保存装备
             if (!confirm('确定要删除装备 "' + name + '" 吗?')) {
        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.data[name];
             // 更新本地数据
             this.renderTable();
            var equipmentData = {
             this.generateLuaCode();
                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 lines = ['local equipment = {}', ''];
             var lua = 'local data = {\n';
           
            // 按名称排序
            var names = Object.keys(this.currentData).sort();
              
              
             for (var name in this.data) {
             for (var i = 0; i < names.length; i++) {
                 var item = this.data[name];
                 var name = names[i];
                 lines.push('equipment["' + name + '"] = {');
                 var equip = this.currentData[name];
                lines.push('    id = ' + item.id + ',');
                lines.push('    rarity = "' + item.rarity + '",');
                lines.push('    type = "' + item.type + '",');
                lines.push('    tag = "' + item.tag + '",');
                lines.push('    desc = {');
                  
                  
                 item.desc.forEach(function(desc, index) {
                 lua += '    ["' + this.escapeLua(name) + '"] = {\n';
                    var comma = index < item.desc.length - 1 ? ',' : '';
                lua += '        base = {\n';
                    lines.push('       "' + desc.replace(/"/g, '\\"') + '"' + comma);
                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';
                  
                  
                 lines.push('   }');
                 // 添加等级数据
                lines.push('}');
                for (var level = 1; level <= 5; level++) {
                 lines.push('');
                    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';
             }
             }
              
              
             lines.push('return equipment');
             lua += '}\n\nreturn data';
              
              
             var code = lines.join('\n');
             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;
              
              
             // 显示生成的代码
             // 显示保存中状态
             var codeBox = $('#eq-generated-code');
             mw.notify('正在保存...', {type: 'info'});
            if (codeBox.length === 0) {
                $('.equipment-manager').append([
                    '<div class="eq-code-section">',
                    '  <h3>生成的 Lua 代码</h3>',
                    '  <div class="eq-code-box" id="eq-generated-code"></div>',
                    '  <div class="eq-btn eq-btn-primary" id="eq-copy-code">复制代码</div>',
                    '</div>'
                ].join(''));
               
                $('#eq-copy-code').on('click', function() {
                    var text = $('#eq-generated-code').text();
                    navigator.clipboard.writeText(text).then(function() {
                        mw.notify('代码已复制到剪贴板', { type: 'success' });
                    });
                });
            }
              
              
             $('#eq-generated-code').text(code);
             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();
    });
    
})();