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留言 | 贡献
无编辑摘要
 
(未显示同一用户的7个中间版本)
第1行: 第1行:
(function() {
( function () {
     'use strict';
     'use strict';
      
      
     // 等待页面加载完成
     mw.loader.using( ['mediawiki.api', 'mediawiki.util'], function () {
    if (mw.config.get('wgPageName') !== 'MediaWiki:Equipment') {
        if ( mw.config.get( 'wgPageName' ) !== 'MediaWiki:Equipment' ) {
        return;
            return;
    }
        }
   
 
    // 加载 CSS
        mw.loader.load( mw.util.getUrl( '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 api = new mw.Api();
    var EquipmentManager = {
         var equipmentData = {};
         data: {},
 
         currentEditKey: null,
        // 固定选项
          
        var AREA_OPTIONS = ['蓝壶', '双星之影', '雾之都市'];
         init: function() {
         var RARITY_OPTIONS = ['蓝', '金', '彩'];
             this.loadData();
        var TYPE_OPTIONS = ['武器', '装甲', '戒指'];
            this.renderUI();
 
         },
         // 初始化
          
         function init() {
         loadData: function() {
             loadEquipmentData();
             // 通过 API 加载模块数据
         }
            var self = this;
 
            $.ajax({
         // 加载装备数据
                 url: mw.util.wikiScript('api'),
         function loadEquipmentData() {
                 data: {
             api.get({
                    action: 'scribunto-console',
                 action: 'query',
                    title: '模块:装备/data',
                 prop: 'revisions',
                    question: 'return require("模块:装备/data")',
                titles: 'Module:装备/data',
                    format: 'json'
                rvprop: 'content',
                 },
                rvslots: 'main',
                 success: function(response) {
                 formatversion: 2
                     if (response && response.print) {
            }).done(function (data) {
                         self.parseData(response.print);
                 if (data.query && data.query.pages && data.query.pages[0]) {
                    var page = data.query.pages[0];
                     if (page.revisions && page.revisions[0]) {
                         var content = page.revisions[0].slots.main.content;
                        parseEquipmentData(content);
                        renderUI();
                        return;
                     }
                     }
                 }
                 }
                mw.notify('加载装备数据失败: 未找到数据', { type: 'error' });
            }).fail(function (code, result) {
                console.error('API Error:', code, result);
                mw.notify('加载装备数据失败: ' + code, { type: 'error' });
             });
             });
        }
        // 解析 Lua 数据
        function parseEquipmentData(luaCode) {
            equipmentData = {};
              
              
             // 备用:从页面解析
             try {
            this.loadFromPage();
                // 匹配每个装备条目 - 改进的正则表达式
        },
                var lines = luaCode.split('\n');
       
                var currentName = null;
        loadFromPage: function() {
                var currentItem = null;
            var self = this;
                var inDesc = false;
            $.get(mw.util.wikiScript('index'), {
                var descArray = [];
                title: '模块:装备/data',
               
                action: 'raw'
                for (var i = 0; i < lines.length; i++) {
            }, function(content) {
                    var line = lines[i].trim();
                self.parseDataFromLua(content);
                   
                self.renderTable();
                    // 匹配装备名称
            });
                    var nameMatch = line.match(/equipment\["([^"]+)"\]\s*=\s*\{/);
        },
                    if (nameMatch) {
       
                        if (currentName && currentItem) {
        parseDataFromLua: function(luaContent) {
                            if (descArray.length > 0) {
            // 简单的 Lua 解析
                                currentItem.desc = descArray;
            var equipmentPattern = /equipment\["([^"]+)"\]\s*=\s*\{([^}]+(?:\{[^}]*\}[^}]*)*)\}/g;
                            }
            var match;
                            equipmentData[currentName] = currentItem;
           
                        }
            while ((match = equipmentPattern.exec(luaContent)) !== null) {
                        currentName = nameMatch[1];
                var name = match[1];
                        currentItem = { name: currentName, desc: [] };
                 var content = match[2];
                        inDesc = false;
                        descArray = [];
                        continue;
                    }
                   
                    if (!currentItem) continue;
                   
                    // 匹配 desc 开始
                    if (line.match(/desc\s*=\s*\{/)) {
                        inDesc = true;
                        descArray = [];
                        continue;
                    }
                   
                    // desc 结束
                    if (inDesc && line.match(/^\}/)) {
                        inDesc = false;
                        currentItem.desc = descArray;
                        continue;
                    }
                   
                    // 在 desc 内
                    if (inDesc) {
                        var descMatch = line.match(/"([^"]*)"/);
                        if (descMatch) {
                            descArray.push(descMatch[1]);
                        }
                        continue;
                    }
                   
                    // 匹配其他属性
                    var idMatch = line.match(/id\s*=\s*"?([^",\n]+)"?/);
                    if (idMatch) {
                        currentItem.id = idMatch[1];
                        continue;
                    }
 
                   
                    var areaMatch = line.match(/area\s*=\s*"([^"]+)"/);
                    if (areaMatch) {
                        currentItem.area = areaMatch[1];
                        continue;
                    }
                   
                    var rarityMatch = line.match(/rarity\s*=\s*"([^"]+)"/);
                    if (rarityMatch) {
                        currentItem.rarity = rarityMatch[1];
                        continue;
                    }
                   
                    var typeMatch = line.match(/type\s*=\s*"([^"]+)"/);
                    if (typeMatch) {
                        currentItem.type = typeMatch[1];
                        continue;
                    }
                   
                    var tagMatch = line.match(/tag\s*=\s*"([^"]+)"/);
                    if (tagMatch) {
                        currentItem.tag = tagMatch[1];
                        continue;
                    }
                 }
               
                // 保存最后一个装备
                if (currentName && currentItem) {
                    if (descArray.length > 0) {
                        currentItem.desc = descArray;
                    }
                    equipmentData[currentName] = currentItem;
                }
                  
                  
                 var item = {
                 console.log('解析到的装备数据:', equipmentData);
                    name: name,
                    id: this.extractValue(content, 'id'),
                    rarity: this.extractValue(content, 'rarity'),
                    type: this.extractValue(content, 'type'),
                    tag: this.extractValue(content, 'tag'),
                    desc: this.extractArray(content, 'desc')
                };
                  
                  
                 this.data[name] = item;
            } catch (e) {
                 console.error('解析装备数据出错:', e);
                mw.notify('解析装备数据失败', { type: 'error' });
             }
             }
         },
         }
          
 
         extractValue: function(content, key) {
         // 渲染界面
             var pattern = new RegExp(key + '\\s*=\\s*["\']?([^,"\'\\n]+)["\']?');
         function renderUI() {
             var match = content.match(pattern);
             var $container = $('<div>').addClass('equipment-manager');
             return match ? match[1].trim() : '';
           
        },
            // 标题
       
            $container.append($('<div>').addClass('equipment-title').text('装备数据管理'));
        extractArray: function(content, key) {
           
             var pattern = new RegExp(key + '\\s*=\\s*\\{([^}]+)\\}');
            // 统计信息
             var match = content.match(pattern);
             var count = Object.keys(equipmentData).length;
             if (!match) return [];
             $container.append($('<div>').addClass('equipment-stats').text('' + count + ' 个装备'));
           
            // 添加新装备按钮
            var $addBtn = $('<div>').addClass('equipment-button equipment-button-primary')
                .text('添加新装备')
                .on('click', function () {
                    showEditForm(null);
                });
            $container.append($addBtn);
           
            // 装备列表
             var $list = $('<div>').addClass('equipment-list');
           
            var items = Object.keys(equipmentData).sort();
            for (var i = 0; i < items.length; i++) {
                $list.append(createEquipmentItem(equipmentData[items[i]]));
            }
           
            $container.append($list);
              
            // 插入到页面
            $('#mw-content-text').empty().append($container);
        }
 
        // 创建装备项
        function createEquipmentItem(item) {
             var $item = $('<div>').addClass('equipment-item');
              
              
             var items = match[1].match(/"([^"]+)"/g) || [];
             var $info = $('<div>').addClass('equipment-info');
             return items.map(function(item) {
             $info.append($('<div>').addClass('equipment-name').text(item.name));
                return item.replace(/"/g, '');
             $info.append($('<div>').addClass('equipment-meta')
             });
                .text('ID: ' + item.id + ' | ' + item.area + ' | ' + item.rarity + ' | ' + item.type));
        },
             $info.append($('<div>').addClass('equipment-tags').text('标签: ' + item.tag));
       
        renderUI: function() {
             var container = $('#mw-content-text');
            container.empty();
              
              
             var html = [
             var $actions = $('<div>').addClass('equipment-actions');
                '<div class="equipment-manager">',
            $actions.append(
                ' <div class="eq-header">',
                 $('<div>').addClass('equipment-button equipment-button-small').text('编辑')
                '    <h2>装备数据管理器</h2>',
                    .on('click', function () {
                '    <div class="eq-btn eq-btn-primary" id="eq-add-new">新增装备</div>',
                        showEditForm(item);
                '  </div>',
                    })
                '  <div id="eq-table-container"></div>',
            );
                '  <div id="eq-form-modal" class="eq-modal" style="display:none;">',
            $actions.append(
                '    <div class="eq-modal-content">',
                 $('<div>').addClass('equipment-button equipment-button-small equipment-button-danger').text('删除')
                 '     <div class="eq-modal-header">',
                    .on('click', function () {
                '       <h3 id="eq-form-title">新增装备</h3>',
                        deleteEquipment(item.name);
                '        <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);
             $item.append($info).append($actions);
            this.bindEvents();
             return $item;
             this.renderTable();
         }
         },
 
          
         // 插入文本到输入框
         renderTable: function() {
         function insertTextIntoTextarea($textarea, beforeText, afterText) {
             var tbody = [];
             var textarea = $textarea[0];
             var index = 1;
             var start = textarea.selectionStart;
            var end = textarea.selectionEnd;
            var text = textarea.value;
            var selectedText = text.substring(start, end);
              
              
             for (var name in this.data) {
             var insertText;
                var item = this.data[name];
            if (selectedText) {
                tbody.push([
                insertText = beforeText + selectedText + afterText;
                    '<div class="eq-table-row">',
            } else {
                    '  <div class="eq-cell">' + index++ + '</div>',
                insertText = beforeText + afterText;
                    '  <div class="eq-cell">' + mw.html.escape(name) + '</div>',
                    '  <div class="eq-cell">' + mw.html.escape(item.id) + '</div>',
                    '  <div class="eq-cell eq-rarity-' + item.rarity + '">' + mw.html.escape(item.rarity) + '</div>',
                    '  <div class="eq-cell">' + mw.html.escape(item.type) + '</div>',
                    '  <div class="eq-cell">' + mw.html.escape(item.tag) + '</div>',
                    '  <div class="eq-cell eq-actions">',
                    '    <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 = [
             var newText = text.substring(0, start) + insertText + text.substring(end);
                '<div class="eq-table">',
            $textarea.val(newText);
                 ' <div class="eq-table-header">',
           
                 '   <div class="eq-cell">序号</div>',
            // 设置光标位置
                '   <div class="eq-cell">名称</div>',
            var newCursorPos = start + beforeText.length + selectedText.length;
                 '   <div class="eq-cell">ID</div>',
            textarea.setSelectionRange(newCursorPos, newCursorPos);
                 '   <div class="eq-cell">稀有度</div>',
            textarea.focus();
                 '   <div class="eq-cell">类型</div>',
        }
                 '   <div class="eq-cell">标签</div>',
 
                '   <div class="eq-cell">操作</div>',
        // 创建格式化按钮工具栏
                 ' </div>',
        function createFormatToolbar($targetTextarea) {
                ' <div class="eq-table-body">',
            var $toolbar = $('<div>').addClass('equipment-format-toolbar');
                tbody.join(''),
           
                ' </div>',
            // 橙色文本按钮
                 '</div>'
            var $orangeBtn = $('<div>')
            ].join('');
                 .addClass('equipment-button equipment-button-small equipment-format-btn')
                .css('color', '#ff8c00')
                .text('橙色文本')
                 .on('click', function () {
                    insertTextIntoTextarea($targetTextarea, '{{文本|橙|', '}}');
                 });
           
            // 词典按钮
            var $dictBtn = $('<div>')
                 .addClass('equipment-button equipment-button-small equipment-format-btn')
                 .text('词典')
                 .on('click', function () {
                    insertTextIntoTextarea($targetTextarea, '{{词典|', '}}');
                 });
           
            $toolbar.append($orangeBtn).append($dictBtn);
            return $toolbar;
        }
 
        // 显示编辑表单
        function showEditForm(item) {
            var isEdit = item !== null;
            var $overlay = $('<div>').addClass('equipment-overlay');
            var $modal = $('<div>').addClass('equipment-modal');
           
            $modal.append($('<div>').addClass('equipment-modal-title')
                 .text(isEdit ? '编辑装备' : '添加新装备'));
           
            var $form = $('<div>').addClass('equipment-form');
              
              
             $('#eq-table-container').html(html);
            // 名称
            this.bindTableEvents();
             $form.append(createFormField('名称', 'name', 'text', isEdit ? item.name : '', isEdit));
        },
       
        bindEvents: function() {
            var self = this;
              
              
             // 新增按钮
             // ID
             $('#eq-add-new').on('click', function() {
             $form.append(createFormField('ID', 'id', 'text', isEdit ? item.id : ''));
                self.showForm('add');
 
            });
           
            // 地区
            $form.append(createFormSelect('地区', 'area', AREA_OPTIONS, isEdit ? item.area : ''));
           
            // 稀有度
            $form.append(createFormSelect('稀有度', 'rarity', RARITY_OPTIONS, isEdit ? item.rarity : ''));
              
              
             // 关闭模态框
             // 类型
             $('.eq-close, #eq-cancel').on('click', function() {
             $form.append(createFormSelect('类型', 'type', TYPE_OPTIONS, isEdit ? item.type : ''));
                self.hideForm();
            });
              
              
             // 保存按钮
             // 标签
             $('#eq-save').on('click', function() {
             $form.append(createFormField('标签 (用逗号分隔)', 'tag', 'text', isEdit ? item.tag : ''));
                self.saveData();
            });
              
              
             // 点击模态框外部关闭
             // 描述 (5个等级)
             $('#eq-form-modal').on('click', function(e) {
             for (var i = 1; i <= 5; i++) {
                 if (e.target.id === 'eq-form-modal') {
                var $field = createFormField('描述等级 ' + i, 'desc' + i, 'text',
                    self.hideForm();
                    isEdit && item.desc ? item.desc[i - 1] : '', false, true);
               
                // 在第一个描述输入框上方添加格式化工具栏
                 if (i === 1) {
                    var $textarea = $field.find('textarea');
                    var $toolbar = createFormatToolbar($textarea);
                    $field.find('.equipment-form-label').after($toolbar);
                 }
                 }
            });
               
        },
                $form.append($field);
       
             }
        bindTableEvents: function() {
             var self = this;
              
              
             // 编辑按钮
             var $actions = $('<div>').addClass('equipment-modal-actions');
             $('.eq-edit').on('click', function() {
             $actions.append(
                 var name = $(this).data('name');
                $('<div>').addClass('equipment-button equipment-button-primary').text('保存')
                self.showForm('edit', name);
                    .on('click', function () {
             });
                        saveEquipment($form, isEdit, item ? item.name : null);
                        $overlay.remove();
                    })
            );
            $actions.append(
                 $('<div>').addClass('equipment-button').text('取消')
                    .on('click', function () {
                        $overlay.remove();
                    })
             );
              
              
            // 删除按钮
             $modal.append($form).append($actions);
             $('.eq-delete').on('click', function() {
            $overlay.append($modal);
                var name = $(this).data('name');
            $('body').append($overlay);
                self.deleteItem(name);
        }
            });
 
        },
         // 创建表单字段
          
         function createFormField(label, name, type, value, readonly, isTextarea) {
         showForm: function(mode, name) {
             var $field = $('<div>').addClass('equipment-form-field');
            this.currentEditKey = name || null;
             $field.append($('<div>').addClass('equipment-form-label').text(label));
             var form = $('#eq-form')[0];
             form.reset();
              
              
             if (mode === 'add') {
            var $input;
                 $('#eq-form-title').text('新增装备');
             if (isTextarea) {
                $('input[name="name"]').prop('disabled', false);
                 $input = $('<textarea>').addClass('equipment-form-input equipment-form-textarea')
                    .attr('name', name)
                    .attr('rows', '3')
                    .val(value || '');
             } else {
             } else {
                 $('#eq-form-title').text('编辑装备');
                 $input = $('<input>').addClass('equipment-form-input')
                var item = this.data[name];
                    .attr('type', type)
                $('input[name="name"]').val(item.name).prop('disabled', true);
                    .attr('name', name)
                $('input[name="id"]').val(item.id);
                    .val(value || '');
                $('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();
             if (readonly) {
         },
                $input.attr('readonly', 'readonly');
          
            }
         hideForm: function() {
            $field.append($input);
             $('#eq-form-modal').fadeOut();
            return $field;
             this.currentEditKey = null;
         }
        },
 
       
         // 创建下拉选择框
        saveData: function() {
         function createFormSelect(label, name, options, value) {
            var form = $('#eq-form')[0];
             var $field = $('<div>').addClass('equipment-form-field');
             var name = $('input[name="name"]').val().trim();
             $field.append($('<div>').addClass('equipment-form-label').text(label));
             var $select = $('<select>').addClass('equipment-form-input').attr('name', name);
              
              
             if (!name) {
            $select.append($('<option>').val('').text('请选择...'));
                 mw.notify('请输入装备名称', { type: 'error' });
            options.forEach(function (opt) {
                $select.append($('<option>').val(opt).text(opt));
            });
            $select.val(value || '');
           
            $field.append($select);
            return $field;
        }
 
        // 保存装备
        function saveEquipment($form, isEdit, oldName) {
            var formData = {};
            $form.find('input, select, textarea').each(function () {
                var $el = $(this);
                formData[$el.attr('name')] = $el.val().trim();
            });
           
            // 验证必填项
             if (!formData.name || !formData.id || !formData.area || !formData.rarity || !formData.type) {
                 mw.notify('请填写所有必填项', { type: 'error' });
                 return;
                 return;
             }
             }
              
              
             var item = {
             var desc = [];
                 name: name,
            for (var i = 1; i <= 5; i++) {
                 id: $('input[name="id"]').val(),
                desc.push(formData['desc' + i] || '');
                 rarity: $('input[name="rarity"]:checked').val() || '蓝',
            }
                 type: $('input[name="type"]:checked').val() || '武器',
           
                 tag: $('input[name="tag"]').val().trim(),
            var newItem = {
                 desc: $('textarea[name="desc"]').val().split('\n').filter(function(line) {
                 name: formData.name,
                    return line.trim();
                 id: formData.id,
                })
                area: formData.area,
                 rarity: formData.rarity,
                 type: formData.type,
                 tag: formData.tag,
                 desc: desc
             };
             };
              
              
             this.data[name] = item;
             // 如果是编辑且名称改变了,删除旧的
             this.hideForm();
            if (isEdit && oldName && oldName !== formData.name) {
             this.renderTable();
                delete equipmentData[oldName];
             this.generateLuaCode();
             }
         },
           
          
             equipmentData[formData.name] = newItem;
         deleteItem: function(name) {
             saveToModule();
         }
 
         // 删除装备
         function deleteEquipment(name) {
             if (!confirm('确定要删除装备 "' + name + '" 吗?')) {
             if (!confirm('确定要删除装备 "' + name + '" 吗?')) {
                 return;
                 return;
             }
             }
              
              
             delete this.data[name];
             delete equipmentData[name];
             this.renderTable();
             saveToModule();
            this.generateLuaCode();
         }
         },
 
          
         // 保存到模块
         generateLuaCode: function() {
         function saveToModule() {
             var lines = ['local equipment = {}', ''];
             var luaCode = 'local equipment = {}\n\n';
              
              
             for (var name in this.data) {
            var names = Object.keys(equipmentData).sort();
                 var item = this.data[name];
           
                 lines.push('equipment["' + name + '"] = {');
             for (var i = 0; i < names.length; i++) {
                 lines.push('    id = ' + item.id + ',');
                var name = names[i];
                 lines.push('    rarity = "' + item.rarity + '",');
                 var item = equipmentData[name];
                 lines.push('    type = "' + item.type + '",');
                  
                 lines.push('    tag = "' + item.tag + '",');
                luaCode += 'equipment["' + name + '"] = {\n';
                 lines.push('    desc = {');
                 luaCode += '    id = "' + item.id + '",\n';
                 luaCode += '\tarea = "' + item.area + '",\n';
                luaCode += '    rarity = "' + item.rarity + '",\n';
                 luaCode += '    type = "' + item.type + '",\n';
                 luaCode += '    tag = "' + item.tag + '",\n';
                 luaCode += '    desc = {\n';
                  
                  
                 item.desc.forEach(function(desc, index) {
                 for (var j = 0; j < 5; j++) {
                     var comma = index < item.desc.length - 1 ? ',' : '';
                     var desc = item.desc[j] || '';
                     lines.push('        "' + desc.replace(/"/g, '\\"') + '"' + comma);
                     luaCode += '        "' + desc + '"';
                 });
                    if (j < 4) luaCode += ',';
                    luaCode += '\n';
                 }
                  
                  
                 lines.push('    }');
                 luaCode += '    }\n';
                 lines.push('}');
                 luaCode += '}\n\n';
                lines.push('');
             }
             }
              
              
             lines.push('return equipment');
             luaCode += 'return equipment\n';
              
              
             var code = lines.join('\n');
             api.postWithToken('csrf', {
           
                 action: 'edit',
            // 显示生成的代码
                title: 'Module:装备/data',
            var codeBox = $('#eq-generated-code');
                text: luaCode,
            if (codeBox.length === 0) {
                summary: '通过装备管理界面更新数据',
                 $('.equipment-manager').append([
                contentmodel: 'Scribunto'
                    '<div class="eq-code-section">',
            }).done(function () {
                    ' <h3>生成的 Lua 代码</h3>',
                 mw.notify('保存成功!', { type: 'success' });
                    '  <div class="eq-code-box" id="eq-generated-code"></div>',
                loadEquipmentData();
                    ' <div class="eq-btn eq-btn-primary" id="eq-copy-code">复制代码</div>',
            }).fail(function (code, result) {
                    '</div>'
                console.error('保存失败:', code, result);
                ].join(''));
                mw.notify('保存失败: ' + code, { type: 'error' });
                  
             });
                $('#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);
         }
         }
    };
 
   
         init();
    // 初始化
    $(function() {
         EquipmentManager.init();
     });
     });
   
})();
})();

2025年10月17日 (五) 20:45的最新版本

( function () {
    'use strict';
    
    mw.loader.using( ['mediawiki.api', 'mediawiki.util'], function () {
        if ( mw.config.get( 'wgPageName' ) !== 'MediaWiki:Equipment' ) {
            return;
        }

        mw.loader.load( mw.util.getUrl( 'MediaWiki:Equipment.css', { action: 'raw', ctype: 'text/css' } ), 'text/css' );

        var api = new mw.Api();
        var equipmentData = {};

        // 固定选项
        var AREA_OPTIONS = ['蓝壶', '双星之影', '雾之都市'];
        var RARITY_OPTIONS = ['蓝', '金', '彩'];
        var TYPE_OPTIONS = ['武器', '装甲', '戒指'];

        // 初始化
        function init() {
            loadEquipmentData();
        }

        // 加载装备数据
        function loadEquipmentData() {
            api.get({
                action: 'query',
                prop: 'revisions',
                titles: 'Module:装备/data',
                rvprop: 'content',
                rvslots: 'main',
                formatversion: 2
            }).done(function (data) {
                if (data.query && data.query.pages && data.query.pages[0]) {
                    var page = data.query.pages[0];
                    if (page.revisions && page.revisions[0]) {
                        var content = page.revisions[0].slots.main.content;
                        parseEquipmentData(content);
                        renderUI();
                        return;
                    }
                }
                mw.notify('加载装备数据失败: 未找到数据', { type: 'error' });
            }).fail(function (code, result) {
                console.error('API Error:', code, result);
                mw.notify('加载装备数据失败: ' + code, { type: 'error' });
            });
        }

        // 解析 Lua 数据
        function parseEquipmentData(luaCode) {
            equipmentData = {};
            
            try {
                // 匹配每个装备条目 - 改进的正则表达式
                var lines = luaCode.split('\n');
                var currentName = null;
                var currentItem = null;
                var inDesc = false;
                var descArray = [];
                
                for (var i = 0; i < lines.length; i++) {
                    var line = lines[i].trim();
                    
                    // 匹配装备名称
                    var nameMatch = line.match(/equipment\["([^"]+)"\]\s*=\s*\{/);
                    if (nameMatch) {
                        if (currentName && currentItem) {
                            if (descArray.length > 0) {
                                currentItem.desc = descArray;
                            }
                            equipmentData[currentName] = currentItem;
                        }
                        currentName = nameMatch[1];
                        currentItem = { name: currentName, desc: [] };
                        inDesc = false;
                        descArray = [];
                        continue;
                    }
                    
                    if (!currentItem) continue;
                    
                    // 匹配 desc 开始
                    if (line.match(/desc\s*=\s*\{/)) {
                        inDesc = true;
                        descArray = [];
                        continue;
                    }
                    
                    // desc 结束
                    if (inDesc && line.match(/^\}/)) {
                        inDesc = false;
                        currentItem.desc = descArray;
                        continue;
                    }
                    
                    // 在 desc 内
                    if (inDesc) {
                        var descMatch = line.match(/"([^"]*)"/);
                        if (descMatch) {
                            descArray.push(descMatch[1]);
                        }
                        continue;
                    }
                    
                    // 匹配其他属性
                    var idMatch = line.match(/id\s*=\s*"?([^",\n]+)"?/);
                    if (idMatch) {
                        currentItem.id = idMatch[1];
                        continue;
                    }

                    
                    var areaMatch = line.match(/area\s*=\s*"([^"]+)"/);
                    if (areaMatch) {
                        currentItem.area = areaMatch[1];
                        continue;
                    }
                    
                    var rarityMatch = line.match(/rarity\s*=\s*"([^"]+)"/);
                    if (rarityMatch) {
                        currentItem.rarity = rarityMatch[1];
                        continue;
                    }
                    
                    var typeMatch = line.match(/type\s*=\s*"([^"]+)"/);
                    if (typeMatch) {
                        currentItem.type = typeMatch[1];
                        continue;
                    }
                    
                    var tagMatch = line.match(/tag\s*=\s*"([^"]+)"/);
                    if (tagMatch) {
                        currentItem.tag = tagMatch[1];
                        continue;
                    }
                }
                
                // 保存最后一个装备
                if (currentName && currentItem) {
                    if (descArray.length > 0) {
                        currentItem.desc = descArray;
                    }
                    equipmentData[currentName] = currentItem;
                }
                
                console.log('解析到的装备数据:', equipmentData);
                
            } catch (e) {
                console.error('解析装备数据出错:', e);
                mw.notify('解析装备数据失败', { type: 'error' });
            }
        }

        // 渲染界面
        function renderUI() {
            var $container = $('<div>').addClass('equipment-manager');
            
            // 标题
            $container.append($('<div>').addClass('equipment-title').text('装备数据管理'));
            
            // 统计信息
            var count = Object.keys(equipmentData).length;
            $container.append($('<div>').addClass('equipment-stats').text('共 ' + count + ' 个装备'));
            
            // 添加新装备按钮
            var $addBtn = $('<div>').addClass('equipment-button equipment-button-primary')
                .text('添加新装备')
                .on('click', function () {
                    showEditForm(null);
                });
            $container.append($addBtn);
            
            // 装备列表
            var $list = $('<div>').addClass('equipment-list');
            
            var items = Object.keys(equipmentData).sort();
            for (var i = 0; i < items.length; i++) {
                $list.append(createEquipmentItem(equipmentData[items[i]]));
            }
            
            $container.append($list);
            
            // 插入到页面
            $('#mw-content-text').empty().append($container);
        }

        // 创建装备项
        function createEquipmentItem(item) {
            var $item = $('<div>').addClass('equipment-item');
            
            var $info = $('<div>').addClass('equipment-info');
            $info.append($('<div>').addClass('equipment-name').text(item.name));
            $info.append($('<div>').addClass('equipment-meta')
                .text('ID: ' + item.id + ' | ' + item.area + ' | ' + item.rarity + ' | ' + item.type));
            $info.append($('<div>').addClass('equipment-tags').text('标签: ' + item.tag));
            
            var $actions = $('<div>').addClass('equipment-actions');
            $actions.append(
                $('<div>').addClass('equipment-button equipment-button-small').text('编辑')
                    .on('click', function () {
                        showEditForm(item);
                    })
            );
            $actions.append(
                $('<div>').addClass('equipment-button equipment-button-small equipment-button-danger').text('删除')
                    .on('click', function () {
                        deleteEquipment(item.name);
                    })
            );
            
            $item.append($info).append($actions);
            return $item;
        }

        // 插入文本到输入框
        function insertTextIntoTextarea($textarea, beforeText, afterText) {
            var textarea = $textarea[0];
            var start = textarea.selectionStart;
            var end = textarea.selectionEnd;
            var text = textarea.value;
            var selectedText = text.substring(start, end);
            
            var insertText;
            if (selectedText) {
                insertText = beforeText + selectedText + afterText;
            } else {
                insertText = beforeText + afterText;
            }
            
            var newText = text.substring(0, start) + insertText + text.substring(end);
            $textarea.val(newText);
            
            // 设置光标位置
            var newCursorPos = start + beforeText.length + selectedText.length;
            textarea.setSelectionRange(newCursorPos, newCursorPos);
            textarea.focus();
        }

        // 创建格式化按钮工具栏
        function createFormatToolbar($targetTextarea) {
            var $toolbar = $('<div>').addClass('equipment-format-toolbar');
            
            // 橙色文本按钮
            var $orangeBtn = $('<div>')
                .addClass('equipment-button equipment-button-small equipment-format-btn')
                .css('color', '#ff8c00')
                .text('橙色文本')
                .on('click', function () {
                    insertTextIntoTextarea($targetTextarea, '{{文本|橙|', '}}');
                });
            
            // 词典按钮
            var $dictBtn = $('<div>')
                .addClass('equipment-button equipment-button-small equipment-format-btn')
                .text('词典')
                .on('click', function () {
                    insertTextIntoTextarea($targetTextarea, '{{词典|', '}}');
                });
            
            $toolbar.append($orangeBtn).append($dictBtn);
            return $toolbar;
        }

        // 显示编辑表单
        function showEditForm(item) {
            var isEdit = item !== null;
            var $overlay = $('<div>').addClass('equipment-overlay');
            var $modal = $('<div>').addClass('equipment-modal');
            
            $modal.append($('<div>').addClass('equipment-modal-title')
                .text(isEdit ? '编辑装备' : '添加新装备'));
            
            var $form = $('<div>').addClass('equipment-form');
            
            // 名称
            $form.append(createFormField('名称', 'name', 'text', isEdit ? item.name : '', isEdit));
            
            // ID
            $form.append(createFormField('ID', 'id', 'text', isEdit ? item.id : ''));

            
            // 地区
            $form.append(createFormSelect('地区', 'area', AREA_OPTIONS, isEdit ? item.area : ''));
            
            // 稀有度
            $form.append(createFormSelect('稀有度', 'rarity', RARITY_OPTIONS, isEdit ? item.rarity : ''));
            
            // 类型
            $form.append(createFormSelect('类型', 'type', TYPE_OPTIONS, isEdit ? item.type : ''));
            
            // 标签
            $form.append(createFormField('标签 (用逗号分隔)', 'tag', 'text', isEdit ? item.tag : ''));
            
            // 描述 (5个等级)
            for (var i = 1; i <= 5; i++) {
                var $field = createFormField('描述等级 ' + i, 'desc' + i, 'text', 
                    isEdit && item.desc ? item.desc[i - 1] : '', false, true);
                
                // 在第一个描述输入框上方添加格式化工具栏
                if (i === 1) {
                    var $textarea = $field.find('textarea');
                    var $toolbar = createFormatToolbar($textarea);
                    $field.find('.equipment-form-label').after($toolbar);
                }
                
                $form.append($field);
            }
            
            var $actions = $('<div>').addClass('equipment-modal-actions');
            $actions.append(
                $('<div>').addClass('equipment-button equipment-button-primary').text('保存')
                    .on('click', function () {
                        saveEquipment($form, isEdit, item ? item.name : null);
                        $overlay.remove();
                    })
            );
            $actions.append(
                $('<div>').addClass('equipment-button').text('取消')
                    .on('click', function () {
                        $overlay.remove();
                    })
            );
            
            $modal.append($form).append($actions);
            $overlay.append($modal);
            $('body').append($overlay);
        }

        // 创建表单字段
        function createFormField(label, name, type, value, readonly, isTextarea) {
            var $field = $('<div>').addClass('equipment-form-field');
            $field.append($('<div>').addClass('equipment-form-label').text(label));
            
            var $input;
            if (isTextarea) {
                $input = $('<textarea>').addClass('equipment-form-input equipment-form-textarea')
                    .attr('name', name)
                    .attr('rows', '3')
                    .val(value || '');
            } else {
                $input = $('<input>').addClass('equipment-form-input')
                    .attr('type', type)
                    .attr('name', name)
                    .val(value || '');
            }
            
            if (readonly) {
                $input.attr('readonly', 'readonly');
            }
            $field.append($input);
            return $field;
        }

        // 创建下拉选择框
        function createFormSelect(label, name, options, value) {
            var $field = $('<div>').addClass('equipment-form-field');
            $field.append($('<div>').addClass('equipment-form-label').text(label));
            var $select = $('<select>').addClass('equipment-form-input').attr('name', name);
            
            $select.append($('<option>').val('').text('请选择...'));
            options.forEach(function (opt) {
                $select.append($('<option>').val(opt).text(opt));
            });
            $select.val(value || '');
            
            $field.append($select);
            return $field;
        }

        // 保存装备
        function saveEquipment($form, isEdit, oldName) {
            var formData = {};
            $form.find('input, select, textarea').each(function () {
                var $el = $(this);
                formData[$el.attr('name')] = $el.val().trim();
            });
            
            // 验证必填项
            if (!formData.name || !formData.id || !formData.area || !formData.rarity || !formData.type) {
                mw.notify('请填写所有必填项', { type: 'error' });
                return;
            }
            
            var desc = [];
            for (var i = 1; i <= 5; i++) {
                desc.push(formData['desc' + i] || '');
            }
            
            var newItem = {
                name: formData.name,
                id: formData.id,
                area: formData.area,
                rarity: formData.rarity,
                type: formData.type,
                tag: formData.tag,
                desc: desc
            };
            
            // 如果是编辑且名称改变了,删除旧的
            if (isEdit && oldName && oldName !== formData.name) {
                delete equipmentData[oldName];
            }
            
            equipmentData[formData.name] = newItem;
            saveToModule();
        }

        // 删除装备
        function deleteEquipment(name) {
            if (!confirm('确定要删除装备 "' + name + '" 吗?')) {
                return;
            }
            
            delete equipmentData[name];
            saveToModule();
        }

        // 保存到模块
        function saveToModule() {
            var luaCode = 'local equipment = {}\n\n';
            
            var names = Object.keys(equipmentData).sort();
            
            for (var i = 0; i < names.length; i++) {
                var name = names[i];
                var item = equipmentData[name];
                
                luaCode += 'equipment["' + name + '"] = {\n';
                luaCode += '    id = "' + item.id + '",\n';
                luaCode += '\tarea = "' + item.area + '",\n';
                luaCode += '    rarity = "' + item.rarity + '",\n';
                luaCode += '    type = "' + item.type + '",\n';
                luaCode += '    tag = "' + item.tag + '",\n';
                luaCode += '    desc = {\n';
                
                for (var j = 0; j < 5; j++) {
                    var desc = item.desc[j] || '';
                    luaCode += '        "' + desc + '"';
                    if (j < 4) luaCode += ',';
                    luaCode += '\n';
                }
                
                luaCode += '    }\n';
                luaCode += '}\n\n';
            }
            
            luaCode += 'return equipment\n';
            
            api.postWithToken('csrf', {
                action: 'edit',
                title: 'Module:装备/data',
                text: luaCode,
                summary: '通过装备管理界面更新数据',
                contentmodel: 'Scribunto'
            }).done(function () {
                mw.notify('保存成功!', { type: 'success' });
                loadEquipmentData();
            }).fail(function (code, result) {
                console.error('保存失败:', code, result);
                mw.notify('保存失败: ' + code, { type: 'error' });
            });
        }

        init();
    });
})();