MediaWiki

Equipment.js:修订间差异

来自卡厄思梦境WIKI

律Rhyme留言 | 贡献
无编辑摘要
律Rhyme留言 | 贡献
无编辑摘要
第1行: 第1行:
(function() {
( function () {
     'use strict';
     'use strict';
    // 加载 CSS
    mw.loader.load('/index.php?title=MediaWiki:Equipment.css&action=raw&ctype=text/css', 'text/css');
      
      
     // 装备管理器
     mw.loader.using( ['mediawiki.api', 'mediawiki.util'], function () {
    var EquipmentManager = {
        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 = {};
 
         // 固定选项
         // 固定选项
         areas: ['蓝壶', '双星之影', '雾之都市'],
         var AREA_OPTIONS = ['蓝壶', '双星之影', '雾之都市'];
         rarities: ['蓝', '金', '彩'],
         var RARITY_OPTIONS = ['蓝', '金', '彩'];
         types: ['武器', '装甲', '戒指'],
         var TYPE_OPTIONS = ['武器', '装甲', '戒指'];
       
 
        // 当前装备数据
        equipmentData: {},
        currentEditItem: null,
       
         // 初始化
         // 初始化
         init: function() {
         function init() {
             var container = document.getElementById('equipment-manager');
             loadEquipmentData();
            if (!container) return;
         }
           
 
            // 加载CSS
            mw.loader.load(['ext.gadget.Equipment-css']);
           
            this.loadEquipmentData();
            this.render();
            this.bindEvents();
         },
       
         // 加载装备数据
         // 加载装备数据
         loadEquipmentData: function() {
         function loadEquipmentData() {
             var self = this;
             api.get({
            new mw.Api().get({
                 action: 'raw',
                 action: 'query',
                 title: 'Module:装备/data'
                 prop: 'revisions',
             }).done(function (data) {
                titles: 'Module:装备/data',
                 parseEquipmentData(data);
                rvprop: 'content',
                 renderUI();
                format: 'json'
            }).fail(function () {
             }).done(function(data) {
                 mw.notify('加载装备数据失败', { type: 'error' });
                 var pages = data.query.pages;
                 for (var pageId in pages) {
                    var content = pages[pageId].revisions[0]['*'];
                    self.parseEquipmentData(content);
                 }
                self.renderEquipmentList();
             });
             });
         },
         }
       
 
         // 解析Lua数据
         // 解析 Lua 数据
         parseEquipmentData: function(luaContent) {
         function parseEquipmentData(luaCode) {
             var self = this;
             equipmentData = {};
             // 简单的Lua解析器,提取装备数据
           
             var regex = /equipment$$"([^"]+)"$$\s*=\s*\{([^}]+)\}/g;
             // 匹配每个装备条目
             var pattern = /equipment\["([^"]+)"\]\s*=\s*\{([^}]+(?:\{[^}]*\}[^}]*)*)\}/g;
             var match;
             var match;
              
              
             while ((match = regex.exec(luaContent)) !== null) {
             while ((match = pattern.exec(luaCode)) !== null) {
                 var name = match[1];
                 var name = match[1];
                 var dataStr = match[2];
                 var content = match[2];
                  
                  
                // 解析装备属性
                 var item = {
                 var equipment = {
                     name: name,
                     name: name,
                     id: this.extractValue(dataStr, 'id'),
                     id: extractValue(content, 'id'),
                     area: this.extractStringValue(dataStr, 'area'),
                     area: extractValue(content, 'area'),
                     rarity: this.extractStringValue(dataStr, 'rarity'),
                     rarity: extractValue(content, 'rarity'),
                     type: this.extractStringValue(dataStr, 'type'),
                     type: extractValue(content, 'type'),
                     tag: this.extractStringValue(dataStr, 'tag'),
                     tag: extractValue(content, 'tag'),
                     desc: this.extractDescArray(dataStr)
                     desc: extractDescArray(content)
                 };
                 };
                  
                  
                 self.equipmentData[name] = equipment;
                 equipmentData[name] = item;
             }
             }
         },
         }
       
 
         // 提取数值
         // 提取单个值
         extractValue: function(str, key) {
         function extractValue(content, key) {
             var regex = new RegExp(key + '\\s*=\\s*(\\d+)');
             var regex = new RegExp(key + '\\s*=\\s*"?([^",\\n]+)"?');
            var match = str.match(regex);
             var match = content.match(regex);
            return match ? parseInt(match[1]) : 0;
             return match ? match[1].trim() : '';
        },
         }
       
 
        // 提取字符串值
        extractStringValue: function(str, key) {
            var regex = new RegExp(key + '\\s*=\\s*"([^"]+)"');
             var match = str.match(regex);
             return match ? match[1] : '';
         },
       
         // 提取描述数组
         // 提取描述数组
         extractDescArray: function(str) {
         function extractDescArray(content) {
             var descMatch = str.match(/desc\s*=\s*\{([^}]+)\}/);
             var descMatch = content.match(/desc\s*=\s*\{([^}]+)\}/);
             if (!descMatch) return [];
             if (!descMatch) return ['', '', '', '', ''];
              
              
             var descStr = descMatch[1];
             var descContent = descMatch[1];
             var descs = [];
             var items = [];
             var regex = /"([^"]+)"/g;
             var regex = /"([^"]+)"/g;
             var match;
             var match;
              
              
             while ((match = regex.exec(descStr)) !== null) {
             while ((match = regex.exec(descContent)) !== null) {
                 descs.push(match[1]);
                 items.push(match[1]);
            }
           
            while (items.length < 5) {
                items.push('');
             }
             }
              
              
             return descs;
             return items.slice(0, 5);
         },
         }
       
 
         // 渲染界面
         // 渲染界面
         render: function() {
         function renderUI() {
             var container = document.getElementById('equipment-manager');
             var $container = $('<div>').addClass('equipment-manager');
              
              
             var html = [
             // 标题
                '<div class="equipment-container">',
            $container.append($('<div>').addClass('equipment-title').text('装备数据管理'));
                '  <div class="equipment-header">',
                '    <h2>装备管理器</h2>',
                '    <div class="equipment-actions">',
                '      新增装备</a>',
                '    </div>',
                '  </div>',
                '  <div class="equipment-form-container" style="display:none;">',
                '    <h3 class="form-title">新增装备</h3>',
                '    <div class="equipment-form">',
                '      <div class="form-group">',
                '        <label>装备名称:</label>',
                '        <input type="text" class="form-input" id="equipment-name" />',
                '      </div>',
                '      <div class="form-group">',
                '        <label>装备ID:</label>',
                '        <input type="number" class="form-input" id="equipment-id" />',
                '      </div>',
                '      <div class="form-group">',
                '        <label>地区:</label>',
                '        <div class="radio-group">',
                this.areas.map(function(area) {
                    return '<label class="radio-label"><input type="radio" name="equipment-area" value="' + area + '" /> ' + area + '</label>';
                }).join(''),
                '        </div>',
                '      </div>',
                '      <div class="form-group">',
                '        <label>稀有度:</label>',
                '        <div class="radio-group">',
                this.rarities.map(function(rarity) {
                    return '<label class="radio-label"><input type="radio" name="equipment-rarity" value="' + rarity + '" /> ' + rarity + '</label>';
                }).join(''),
                '        </div>',
                '      </div>',
                '      <div class="form-group">',
                '        <label>类型:</label>',
                '        <div class="radio-group">',
                this.types.map(function(type) {
                    return '<label class="radio-label"><input type="radio" name="equipment-type" value="' + type + '" /> ' + type + '</label>';
                }).join(''),
                '        </div>',
                '      </div>',
                '      <div class="form-group">',
                '        <label>标签(用逗号分隔):</label>',
                '        <input type="text" class="form-input" id="equipment-tag" placeholder="例如: 暴击率提升,获得信用点数" />',
                '      </div>',
                '      <div class="form-group">',
                '        <label>描述(每行一个等级):</label>',
                '        <textarea class="form-textarea" id="equipment-desc" rows="5" placeholder="每行输入一个等级的描述"></textarea>',
                '      </div>',
                '      <div class="form-actions">',
                '        保存',
                '        取消',
                '      </div>',
                '    </div>',
                '  </div>',
                '  <div class="equipment-list-container">',
                '    <h3>装备列表</h3>',
                '    <div class="equipment-filter">',
                '      <input type="text" class="filter-input" id="equipment-search" placeholder="搜索装备..." />',
                '    </div>',
                '    <div class="equipment-list" id="equipment-list">',
                '      <!-- 装备列表将在这里动态生成 -->',
                '    </div>',
                '  </div>',
                '</div>'
            ].join('');
              
              
             container.innerHTML = html;
             // 添加新装备按钮
        },
             var $addBtn = $('<div>').addClass('equipment-button equipment-button-primary')
       
                .text('添加新装备')
        // 渲染装备列表
                .on('click', function () {
        renderEquipmentList: function() {
                    showEditForm(null);
             var listContainer = document.getElementById('equipment-list');
                });
             if (!listContainer) return;
             $container.append($addBtn);
              
              
             var html = [];
            // 装备列表
             var $list = $('<div>').addClass('equipment-list');
              
              
             for (var name in this.equipmentData) {
             for (var name in equipmentData) {
                 var equipment = this.equipmentData[name];
                 $list.append(createEquipmentItem(equipmentData[name]));
                html.push(this.renderEquipmentItem(equipment));
             }
             }
              
              
             listContainer.innerHTML = html.join('');
             $container.append($list);
         },
           
       
            // 插入到页面
         // 渲染单个装备项
            $('#mw-content-text').empty().append($container);
         renderEquipmentItem: function(equipment) {
         }
             var imageUrl = '/images/' + equipment.id + '.png';
 
         // 创建装备项
         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));
              
              
             return [
             var $actions = $('<div>').addClass('equipment-actions');
                '<div class="equipment-item" data-name="' + equipment.name + '">',
            $actions.append(
                '  <div class="equipment-image">',
                 $('<div>').addClass('equipment-button equipment-button-small').text('编辑')
                '    <img src="' + imageUrl + '" alt="' + equipment.name + '" onerror="this.src=\'/images/default-equipment.png\'" />',
                    .on('click', function () {
                 ' </div>',
                        showEditForm(item);
                '  <div class="equipment-info">',
                    })
                '    <div class="equipment-name">' + equipment.name + '</div>',
            );
                '    <div class="equipment-meta">',
            $actions.append(
                '      <span class="equipment-rarity rarity-' + equipment.rarity + '">' + equipment.rarity + '</span>',
                 $('<div>').addClass('equipment-button equipment-button-small equipment-button-danger').text('删除')
                '      <span class="equipment-type">' + equipment.type + '</span>',
                    .on('click', function () {
                '      <span class="equipment-area">' + equipment.area + '</span>',
                        deleteEquipment(item.name);
                '    </div>',
                    })
                '    <div class="equipment-tags">' + equipment.tag + '</div>',
             );
                 ' </div>',
                ' <div class="equipment-actions">',
                '    edit" data-name="' + equipment.name + '">编辑',
                '    delete" data-name="' + equipment.name + '">删除',
                ' </div>',
                '</div>'
            ].join('');
        },
       
        // 绑定事件
        bindEvents: function() {
             var self = this;
              
              
             // 新增按钮
             $item.append($info).append($actions);
             $(document).on('click', '.equipment-btn-add', function(e) {
            return $item;
                e.preventDefault();
        }
                self.showForm();
 
                self.currentEditItem = null;
        // 显示编辑表单
             });
        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', 'number', isEdit ? item.id : ''));
              
            // 地区
            $form.append(createFormSelect('地区', 'area', AREA_OPTIONS, isEdit ? item.area : ''));
              
              
             // 保存按钮
             // 稀有度
             $(document).on('click', '.equipment-btn-save', function(e) {
             $form.append(createFormSelect('稀有度', 'rarity', RARITY_OPTIONS, isEdit ? item.rarity : ''));
                e.preventDefault();
                self.saveEquipment();
            });
              
              
             // 取消按钮
             // 类型
             $(document).on('click', '.equipment-btn-cancel', function(e) {
             $form.append(createFormSelect('类型', 'type', TYPE_OPTIONS, isEdit ? item.type : ''));
                e.preventDefault();
                self.hideForm();
            });
              
              
             // 编辑按钮
             // 标签
             $(document).on('click', '.action-edit', function(e) {
             $form.append(createFormField('标签 (用逗号分隔)', 'tag', 'text', isEdit ? item.tag : ''));
                e.preventDefault();
                var name = $(this).data('name');
                self.editEquipment(name);
            });
              
              
             // 删除按钮
             // 描述 (5个等级)
             $(document).on('click', '.action-delete', function(e) {
             for (var i = 1; i <= 5; i++) {
                e.preventDefault();
                $form.append(createFormField('描述等级 ' + i, 'desc' + i, 'text',  
                var name = $(this).data('name');
                    isEdit ? item.desc[i - 1] : ''));
                self.deleteEquipment(name);
             }
             });
              
              
             // 搜索框
             var $actions = $('<div>').addClass('equipment-modal-actions');
            $(document).on('input', '#equipment-search', function() {
            $actions.append(
                self.filterEquipment($(this).val());
                $('<div>').addClass('equipment-button equipment-button-primary').text('保存')
            });
                    .on('click', function () {
        },
                        saveEquipment($form, isEdit);
       
                        $overlay.remove();
        // 显示表单
                    })
        showForm: function() {
             );
            $('.equipment-form-container').slideDown();
             $actions.append(
            this.clearForm();
                $('<div>').addClass('equipment-button').text('取消')
        },
                    .on('click', function () {
       
                        $overlay.remove();
        // 隐藏表单
                    })
        hideForm: function() {
             );
            $('.equipment-form-container').slideUp();
            this.clearForm();
        },
       
        // 清空表单
        clearForm: function() {
             $('#equipment-name').val('');
             $('#equipment-id').val('');
            $('#equipment-tag').val('');
            $('#equipment-desc').val('');
            $('input[name="equipment-area"]').prop('checked', false);
            $('input[name="equipment-rarity"]').prop('checked', false);
            $('input[name="equipment-type"]').prop('checked', false);
        },
       
        // 编辑装备
        editEquipment: function(name) {
             var equipment = this.equipmentData[name];
            if (!equipment) return;
              
              
             this.currentEditItem = name;
             $modal.append($form).append($actions);
             this.showForm();
            $overlay.append($modal);
             $('.form-title').text('编辑装备');
            $('body').append($overlay);
        }
 
        // 创建表单字段
        function createFormField(label, name, type, value, readonly) {
            var $field = $('<div>').addClass('equipment-form-field');
            $field.append($('<div>').addClass('equipment-form-label').text(label));
            var $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);
              
              
             $('#equipment-name').val(equipment.name);
             $select.append($('<option>').val('').text('请选择...'));
            $('#equipment-id').val(equipment.id);
             options.forEach(function (opt) {
            $('#equipment-tag').val(equipment.tag);
                $select.append($('<option>').val(opt).text(opt));
            $('#equipment-desc').val(equipment.desc.join('\n'));
            });
             $('input[name="equipment-area"][value="' + equipment.area + '"]').prop('checked', true);
             $select.val(value || '');
            $('input[name="equipment-rarity"][value="' + equipment.rarity + '"]').prop('checked', true);
            $('input[name="equipment-type"][value="' + equipment.type + '"]').prop('checked', true);
        },
       
        // 删除装备
        deleteEquipment: function(name) {
             if (!confirm('确定要删除装备 "' + name + '" 吗?')) return;
              
              
             delete this.equipmentData[name];
             $field.append($select);
            this.saveLuaData();
             return $field;
             this.renderEquipmentList();
         }
         },
 
       
         // 保存装备
         // 保存装备
         saveEquipment: function() {
         function saveEquipment($form, isEdit) {
             var name = $('#equipment-name').val().trim();
             var formData = {};
             var id = $('#equipment-id').val();
             $form.find('input, select').each(function () {
            var area = $('input[name="equipment-area"]:checked').val();
                var $el = $(this);
            var rarity = $('input[name="equipment-rarity"]:checked').val();
                formData[$el.attr('name')] = $el.val();
            var type = $('input[name="equipment-type"]:checked').val();
             });
            var tag = $('#equipment-tag').val().trim();
             var desc = $('#equipment-desc').val().trim().split('\n').filter(function(d) { return d.trim(); });
              
              
             if (!name || !id || !area || !rarity || !type) {
             var desc = [];
                 alert('请填写所有必填字段');
            for (var i = 1; i <= 5; i++) {
                return;
                 desc.push(formData['desc' + i] || '');
             }
             }
              
              
             var equipment = {
             var newItem = {
                 name: name,
                 name: formData.name,
                 id: parseInt(id),
                 id: formData.id,
                 area: area,
                 area: formData.area,
                 rarity: rarity,
                 rarity: formData.rarity,
                 type: type,
                 type: formData.type,
                 tag: tag,
                 tag: formData.tag,
                 desc: desc
                 desc: desc
             };
             };
              
              
             // 如果是编辑模式且名称改变了,需要删除旧的
             equipmentData[formData.name] = newItem;
             if (this.currentEditItem && this.currentEditItem !== name) {
            saveToModule();
                 delete this.equipmentData[this.currentEditItem];
        }
 
        // 删除装备
        function deleteEquipment(name) {
             if (!confirm('确定要删除装备 "' + name + '" 吗?')) {
                 return;
             }
             }
              
              
             this.equipmentData[name] = equipment;
             delete equipmentData[name];
            this.saveLuaData();
             saveToModule();
            this.hideForm();
         }
            this.renderEquipmentList();
 
        },
         // 保存到模块
       
         function saveToModule() {
        // 保存到Lua模块
             var luaCode = 'local equipment = {}\n\n';
        saveLuaData: function() {
            var luaContent = this.generateLuaContent();
           
            new mw.Api().postWithToken('csrf', {
                action: 'edit',
                title: 'Module:装备/data',
                text: luaContent,
                summary: '通过装备管理器更新装备数据',
                format: 'json'
            }).done(function() {
                mw.notify('装备数据已保存', { type: 'success' });
             }).fail(function() {
                mw.notify('保存失败,请检查权限', { type: 'error' });
            });
         },
       
         // 生成Lua内容
         generateLuaContent: function() {
             var lines = ['local equipment = {}', ''];
              
              
             for (var name in this.equipmentData) {
             for (var name in equipmentData) {
                 var eq = this.equipmentData[name];
                 var item = equipmentData[name];
                 lines.push('equipment["' + name + '"] = {');
                 luaCode += 'equipment["' + name + '"] = {\n';
                 lines.push('    id = ' + eq.id + ',');
                 luaCode += '    id = ' + item.id + ',\n';
                 lines.push('   area = "' + eq.area + '",');
                 luaCode += '\tarea = "' + item.area + '",\n';
                 lines.push('    rarity = "' + eq.rarity + '",');
                 luaCode += '    rarity = "' + item.rarity + '",\n';
                 lines.push('    type = "' + eq.type + '",');
                 luaCode += '    type = "' + item.type + '",\n';
                 lines.push('    tag = "' + eq.tag + '",');
                 luaCode += '    tag = "' + item.tag + '",\n';
                 lines.push('    desc = {');
                 luaCode += '    desc = {\n';
                  
                  
                 eq.desc.forEach(function(desc, index) {
                 for (var i = 0; i < 5; i++) {
                     var comma = index < eq.desc.length - 1 ? ',' : '';
                     luaCode += '        "' + (item.desc[i] || '') + '"';
                     lines.push('       "' + desc + '"' + comma);
                     if (i < 4) luaCode += ',';
                 });
                    luaCode += '\n';
                 }
                  
                  
                 lines.push('    }');
                 luaCode += '    }\n';
                 lines.push('}');
                 luaCode += '}\n\n';
                lines.push('');
             }
             }
              
              
             lines.push('return equipment');
             luaCode += 'return equipment\n';
            return lines.join('\n');
        },
       
        // 过滤装备
        filterEquipment: function(searchText) {
            var items = document.querySelectorAll('.equipment-item');
            var search = searchText.toLowerCase();
              
              
             items.forEach(function(item) {
             api.postWithToken('csrf', {
                 var name = item.getAttribute('data-name').toLowerCase();
                 action: 'edit',
                 var info = item.textContent.toLowerCase();
                title: 'Module:装备/data',
                  
                text: luaCode,
                if (name.indexOf(search) !== -1 || info.indexOf(search) !== -1) {
                summary: '通过装备管理界面更新数据',
                    item.style.display = '';
                contentmodel: 'Scribunto'
                } else {
            }).done(function () {
                    item.style.display = 'none';
                 mw.notify('保存成功!', { type: 'success' });
                }
                 loadEquipmentData();
            }).fail(function () {
                mw.notify('保存失败!', { type: 'error' });
             });
             });
         }
         }
     };
 
        init();
     });
})();
})();

2025年10月17日 (五) 19:35的版本

( 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: 'raw',
                title: 'Module:装备/data'
            }).done(function (data) {
                parseEquipmentData(data);
                renderUI();
            }).fail(function () {
                mw.notify('加载装备数据失败', { type: 'error' });
            });
        }

        // 解析 Lua 数据
        function parseEquipmentData(luaCode) {
            equipmentData = {};
            
            // 匹配每个装备条目
            var pattern = /equipment\["([^"]+)"\]\s*=\s*\{([^}]+(?:\{[^}]*\}[^}]*)*)\}/g;
            var match;
            
            while ((match = pattern.exec(luaCode)) !== null) {
                var name = match[1];
                var content = match[2];
                
                var item = {
                    name: name,
                    id: extractValue(content, 'id'),
                    area: extractValue(content, 'area'),
                    rarity: extractValue(content, 'rarity'),
                    type: extractValue(content, 'type'),
                    tag: extractValue(content, 'tag'),
                    desc: extractDescArray(content)
                };
                
                equipmentData[name] = item;
            }
        }

        // 提取单个值
        function extractValue(content, key) {
            var regex = new RegExp(key + '\\s*=\\s*"?([^",\\n]+)"?');
            var match = content.match(regex);
            return match ? match[1].trim() : '';
        }

        // 提取描述数组
        function extractDescArray(content) {
            var descMatch = content.match(/desc\s*=\s*\{([^}]+)\}/);
            if (!descMatch) return ['', '', '', '', ''];
            
            var descContent = descMatch[1];
            var items = [];
            var regex = /"([^"]+)"/g;
            var match;
            
            while ((match = regex.exec(descContent)) !== null) {
                items.push(match[1]);
            }
            
            while (items.length < 5) {
                items.push('');
            }
            
            return items.slice(0, 5);
        }

        // 渲染界面
        function renderUI() {
            var $container = $('<div>').addClass('equipment-manager');
            
            // 标题
            $container.append($('<div>').addClass('equipment-title').text('装备数据管理'));
            
            // 添加新装备按钮
            var $addBtn = $('<div>').addClass('equipment-button equipment-button-primary')
                .text('添加新装备')
                .on('click', function () {
                    showEditForm(null);
                });
            $container.append($addBtn);
            
            // 装备列表
            var $list = $('<div>').addClass('equipment-list');
            
            for (var name in equipmentData) {
                $list.append(createEquipmentItem(equipmentData[name]));
            }
            
            $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 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', 'number', 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++) {
                $form.append(createFormField('描述等级 ' + i, 'desc' + i, 'text', 
                    isEdit ? item.desc[i - 1] : ''));
            }
            
            var $actions = $('<div>').addClass('equipment-modal-actions');
            $actions.append(
                $('<div>').addClass('equipment-button equipment-button-primary').text('保存')
                    .on('click', function () {
                        saveEquipment($form, isEdit);
                        $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) {
            var $field = $('<div>').addClass('equipment-form-field');
            $field.append($('<div>').addClass('equipment-form-label').text(label));
            var $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) {
            var formData = {};
            $form.find('input, select').each(function () {
                var $el = $(this);
                formData[$el.attr('name')] = $el.val();
            });
            
            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
            };
            
            equipmentData[formData.name] = newItem;
            saveToModule();
        }

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

        // 保存到模块
        function saveToModule() {
            var luaCode = 'local equipment = {}\n\n';
            
            for (var name in equipmentData) {
                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 i = 0; i < 5; i++) {
                    luaCode += '        "' + (item.desc[i] || '') + '"';
                    if (i < 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 () {
                mw.notify('保存失败!', { type: 'error' });
            });
        }

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