卡厄思
梦
境
菜单
首页
回到首页
WIKI工具
全站样式
全站JS
修改导航栏
测试
沙盒
可视化管理器
战斗员管理器
卡牌管理器
伙伴管理器
装备管理器
词典管理器
图鉴
战斗员
伙伴
装备
怪物卡牌
中立卡牌
词典
小工具
配队模拟器
节奏榜生成器
搜索
链入页面
相关更改
特殊页面
页面信息
最近更改
登录
MediaWiki
查看“︁Agent.js”︁的源代码
←
MediaWiki:Agent.js
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
用户
此页面为本wiki上的软件提供界面文本,并受到保护以防止滥用。 如欲修改所有wiki的翻译,请访问
translatewiki.net
上的MediaWiki本地化项目。
您无权编辑此JavaScript页面,因为编辑此页面可能会影响所有访问者。
您可以查看和复制此页面的源代码。
/** * MediaWiki战斗员管理器 * 用于创建、编辑和管理战斗员页面 */ (function() { 'use strict'; // 只在MediaWiki:Agent页面运行 if (mw.config.get('wgPageName') !== 'MediaWiki:Agent') { return; } var AgentManager = { api: new mw.Api(), currentAgent: null, agentList: [], // 模板字段定义 templateFields: { basic: [ { name: 'id', label: 'ID', type: 'text' }, { name: '名称', label: '名称', type: 'text' }, { name: '稀有度', label: '稀有度', type: 'select', options: ['', '5', '4'] }, { name: '职业', label: '职业', type: 'select', options: ['', '决斗家', '先锋', '游侠', '猎人', '心灵术士', '控制师'] }, { name: '属性', label: '属性', type: 'select', options: ['', '热情', '秩序', '正义', '本能', '虚无'] }, { name: '实装日期', label: '实装日期', type: 'text' } ], image: [ { name: '立绘bottom', label: '立绘Bottom', type: 'text' }, { name: '立绘right', label: '立绘Right', type: 'text' }, { name: '自我bottom', label: '自我Bottom', type: 'text' }, { name: '自我right', label: '自我Right', type: 'text' } ], voice: [ { name: '声优_韩', label: '韩语声优', type: 'text' }, { name: '声优_日', label: '日语声优', type: 'text' }, { name: '声优_英', label: '英语声优', type: 'text' }, { name: '声优_中', label: '中文声优', type: 'text' } ], profile: [ { name: '种族', label: '种族', type: 'text' }, { name: '性别', label: '性别', type: 'select', options: ['', '女', '男'] }, { name: '生日', label: '生日', type: 'text' }, { name: '异能', label: '异能', type: 'text' }, { name: '所属势力', label: '所属势力', type: 'text' }, { name: '档案', label: '档案', type: 'textarea' } ], stats: [ { name: '攻击力_1级', label: '攻击力(1级)', type: 'text' }, { name: '防御力_1级', label: '防御力(1级)', type: 'text' }, { name: 'HP_1级', label: 'HP(1级)', type: 'text' }, { name: '暴击率_1级', label: '暴击率(1级)', type: 'text' }, { name: '暴击伤害_1级', label: '暴击伤害(1级)', type: 'text' }, { name: '弱点伤害率_1级', label: '弱点伤害率(1级)', type: 'text' }, { name: '自我意识恢复力_1级', label: '自我意识恢复力(1级)', type: 'text' }, { name: '骰术', label: '骰术', type: 'text' }, { name: '骰术_1级', label: '骰术(1级)', type: 'text' } ], damage: [ { name: '热情属性伤害量_1级', label: '热情属性伤害量(1级)', type: 'text' }, { name: '正义属性伤害量_1级', label: '正义属性伤害量(1级)', type: 'text' }, { name: '秩序属性伤害量_1级', label: '秩序属性伤害量(1级)', type: 'text' }, { name: '本能属性伤害量_1级', label: '本能属性伤害量(1级)', type: 'text' }, { name: '虚无属性伤害量_1级', label: '虚无属性伤害量(1级)', type: 'text' }, { name: '额外伤害量_1级', label: '额外伤害量(1级)', type: 'text' }, { name: '持续伤害量_1级', label: '持续伤害量(1级)', type: 'text' } ], skills: [ { name: '自我意识技能', label: '自我意识技能', type: 'text' } ], cards: [ { name: '起始卡牌_1', label: '起始卡牌1', type: 'text' }, { name: '起始卡牌_2', label: '起始卡牌2', type: 'text' }, { name: '起始卡牌_3', label: '起始卡牌3', type: 'text' }, { name: '起始卡牌_4', label: '起始卡牌4', type: 'text' }, { name: '独特卡牌_1', label: '独特卡牌1', type: 'text' }, { name: '独特卡牌_2', label: '独特卡牌2', type: 'text' }, { name: '独特卡牌_3', label: '独特卡牌3', type: 'text' }, { name: '独特卡牌_4', label: '独特卡牌4', type: 'text' } ], ego: [ { name: '展现自我意识_01', label: '展现自我意识01', type: 'textarea' }, { name: '展现自我意识_02', label: '展现自我意识02', type: 'textarea' }, { name: '展现自我意识_03', label: '展现自我意识03', type: 'textarea' }, { name: '展现自我意识_04', label: '展现自我意识04', type: 'textarea' }, { name: '展现自我意识_06', label: '展现自我意识06', type: 'textarea' } ], potential: [ { name: '潜力_03-1', label: '潜力03-1', type: 'textarea' }, { name: '潜力_05', label: '潜力05', type: 'textarea' }, { name: '潜力_05-1', label: '潜力05-1', type: 'textarea' }, { name: '潜力_06', label: '潜力06', type: 'textarea' }, { name: '潜力_07', label: '潜力07', type: 'textarea' } ] }, // 初始化 init: function() { this.createUI(); this.loadAgentList(); }, // 创建UI createUI: function() { var container = document.createElement('div'); container.className = 'agent-manager'; container.innerHTML = ` <div class="agent-section"> <h3>战斗员管理器</h3> <div id="agent-message"></div> <div class="agent-tabs"> <div class="agent-tab active" data-tab="list">战斗员列表</div> <div class="agent-tab" data-tab="edit">编辑/新建</div> <div class="agent-tab" data-tab="batch">批量操作</div> </div> <div id="tab-list" class="agent-tab-content active"> <div class="agent-button" id="refresh-list">刷新列表</div> <div class="agent-button" id="create-new">新建战斗员</div> <div id="agent-list" class="agent-loading">加载中...</div> </div> <div id="tab-edit" class="agent-tab-content"> <div id="editor-container"></div> </div> <div id="tab-batch" class="agent-tab-content"> <div class="agent-form-group"> <label>批量操作</label> <div class="agent-button" id="export-all">导出所有战斗员</div> <div class="agent-button secondary" id="check-templates">检查模板完整性</div> </div> <div id="batch-result"></div> </div> </div> `; var content = document.getElementById('mw-content-text'); content.innerHTML = ''; content.appendChild(container); this.bindEvents(); }, // 绑定事件 bindEvents: function() { var self = this; // 标签切换 document.querySelectorAll('.agent-tab').forEach(function(tab) { tab.addEventListener('click', function() { var tabName = this.getAttribute('data-tab'); self.switchTab(tabName); }); }); // 刷新列表 document.getElementById('refresh-list').addEventListener('click', function() { self.loadAgentList(); }); // 新建战斗员 document.getElementById('create-new').addEventListener('click', function() { self.createNewAgent(); }); // 导出所有 document.getElementById('export-all').addEventListener('click', function() { self.exportAll(); }); // 检查模板 document.getElementById('check-templates').addEventListener('click', function() { self.checkTemplates(); }); }, // 切换标签 switchTab: function(tabName) { document.querySelectorAll('.agent-tab').forEach(function(tab) { tab.classList.remove('active'); }); document.querySelectorAll('.agent-tab-content').forEach(function(content) { content.classList.remove('active'); }); document.querySelector('[data-tab="' + tabName + '"]').classList.add('active'); document.getElementById('tab-' + tabName).classList.add('active'); }, // 加载战斗员列表 loadAgentList: function() { var self = this; var listContainer = document.getElementById('agent-list'); listContainer.innerHTML = '<div class="agent-loading">加载中...</div>'; this.api.get({ action: 'query', list: 'categorymembers', cmtitle: 'Category:战斗员', cmlimit: 500, format: 'json' }).done(function(data) { self.agentList = data.query.categorymembers; self.renderAgentList(); }).fail(function() { self.showMessage('加载失败,请检查分类是否存在', 'error'); }); }, // 渲染战斗员列表 renderAgentList: function() { var listContainer = document.getElementById('agent-list'); if (this.agentList.length === 0) { listContainer.innerHTML = '<div class="agent-message info">暂无战斗员,点击"新建战斗员"开始创建</div>'; return; } var html = '<div class="agent-grid">'; this.agentList.forEach(function(agent) { html += '<div class="agent-list-item" data-title="' + mw.html.escape(agent.title) + '">' + mw.html.escape(agent.title) + '</div>'; }); html += '</div>'; listContainer.innerHTML = html; var self = this; document.querySelectorAll('.agent-list-item').forEach(function(item) { item.addEventListener('click', function() { var title = this.getAttribute('data-title'); self.loadAgent(title); }); }); }, // 加载战斗员数据 loadAgent: function(title) { var self = this; this.showMessage('加载中...', 'info'); this.api.get({ action: 'query', titles: title, prop: 'revisions', rvprop: 'content', rvslots: 'main', format: 'json' }).done(function(data) { var pages = data.query.pages; var pageId = Object.keys(pages)[0]; if (pageId === '-1') { self.showMessage('页面不存在', 'error'); return; } var content = pages[pageId].revisions[0].slots.main['*']; self.currentAgent = { title: title, content: content }; console.log('原始内容:', content); self.switchTab('edit'); self.renderEditor(); self.showMessage('已加载: ' + title, 'success'); }).fail(function(error) { console.error('加载失败:', error); self.showMessage('加载失败', 'error'); }); }, // 创建新战斗员 createNewAgent: function() { this.currentAgent = { title: '', content: this.generateTemplate({}) }; this.switchTab('edit'); this.renderEditor(); this.showMessage('请填写战斗员信息', 'info'); }, // 渲染编辑器 renderEditor: function() { var self = this; var container = document.getElementById('editor-container'); var data = this.parseTemplate(this.currentAgent.content); console.log('解析后的数据:', data); console.log('数据条目数:', Object.keys(data).length); var html = '<div class="agent-form-group">'; html += '<label>页面标题</label>'; html += '<input type="text" class="agent-input" id="page-title" value="' + mw.html.escape(this.currentAgent.title || '') + '" placeholder="例如: 战斗员/张三">'; html += '</div>'; // 基础信息 html += '<h4>基础信息</h4>'; html += '<div class="agent-field-row">'; this.templateFields.basic.forEach(function(field) { html += self.renderField(field, data[field.name] || ''); }); html += '</div>'; // 图片位置 html += '<h4>图片位置</h4>'; html += '<div class="agent-field-row">'; this.templateFields.image.forEach(function(field) { html += self.renderField(field, data[field.name] || ''); }); html += '</div>'; // 声优信息 html += '<h4>声优信息</h4>'; html += '<div class="agent-field-row">'; this.templateFields.voice.forEach(function(field) { html += self.renderField(field, data[field.name] || ''); }); html += '</div>'; // 角色档案 html += '<h4>角色档案</h4>'; this.templateFields.profile.forEach(function(field) { html += self.renderField(field, data[field.name] || ''); }); // 基础属性数值 html += '<h4>基础属性数值</h4>'; html += '<div class="agent-field-row">'; this.templateFields.stats.forEach(function(field) { html += self.renderField(field, data[field.name] || ''); }); html += '</div>'; // 伤害数值 html += '<h4>伤害数值</h4>'; html += '<div class="agent-field-row">'; this.templateFields.damage.forEach(function(field) { html += self.renderField(field, data[field.name] || ''); }); html += '</div>'; // 技能信息 html += '<h4>技能信息</h4>'; this.templateFields.skills.forEach(function(field) { html += self.renderField(field, data[field.name] || ''); }); // 卡牌信息 html += '<h4>卡牌信息</h4>'; html += '<div class="agent-field-row">'; this.templateFields.cards.forEach(function(field) { html += self.renderField(field, data[field.name] || ''); }); html += '</div>'; // 自我意识 html += '<h4>展现自我意识</h4>'; this.templateFields.ego.forEach(function(field) { html += self.renderField(field, data[field.name] || ''); }); // 潜力 html += '<h4>潜力</h4>'; this.templateFields.potential.forEach(function(field) { html += self.renderField(field, data[field.name] || ''); }); // 操作按钮 html += '<div style="margin-top: 20px;">'; html += '<div class="agent-button" id="save-agent">保存战斗员</div>'; html += '<div class="agent-button secondary" id="preview-agent">预览</div>'; html += '<div class="agent-button secondary" id="view-source">查看源码</div>'; if (this.currentAgent.title) { html += '<div class="agent-button secondary" id="view-page">查看页面</div>'; } html += '</div>'; html += '<div id="preview-container" style="margin-top: 20px;"></div>'; container.innerHTML = html; // 绑定保存事件 document.getElementById('save-agent').addEventListener('click', function() { self.saveAgent(); }); // 绑定预览事件 document.getElementById('preview-agent').addEventListener('click', function() { self.previewAgent(); }); // 绑定查看源码事件 document.getElementById('view-source').addEventListener('click', function() { self.viewSource(); }); // 绑定查看页面事件 if (this.currentAgent.title) { document.getElementById('view-page').addEventListener('click', function() { window.open(mw.util.getUrl(self.currentAgent.title), '_blank'); }); } }, // 渲染表单字段 renderField: function(field, value) { var escapedValue = mw.html.escape(String(value)); var html = '<div class="agent-form-group">'; html += '<label>' + mw.html.escape(field.label) + '</label>'; if (field.type === 'select') { html += '<select class="agent-select" data-field="' + mw.html.escape(field.name) + '">'; field.options.forEach(function(option) { var selected = (value === option) ? ' selected' : ''; html += '<option value="' + mw.html.escape(option) + '"' + selected + '>' + mw.html.escape(option || '请选择') + '</option>'; }); html += '</select>'; } else if (field.type === 'textarea') { html += '<textarea class="agent-textarea" data-field="' + mw.html.escape(field.name) + '">' + escapedValue + '</textarea>'; } else { html += '<input type="text" class="agent-input" data-field="' + mw.html.escape(field.name) + '" value="' + escapedValue + '">'; } html += '</div>'; return html; }, // 解析模板 parseTemplate: function(content) { var data = {}; // 查找战斗员模板 var templateStart = content.indexOf('{{战斗员'); var templateEnd = content.lastIndexOf('}}'); if (templateStart === -1 || templateEnd === -1) { console.log('未找到战斗员模板'); return data; } // 提取模板内容(包含 {{战斗员 和 }}) var templateContent = content.substring(templateStart, templateEnd + 2); console.log('模板内容长度:', templateContent.length); // 移除开头的 {{战斗员 和结尾的 }} templateContent = templateContent.replace(/^\{\{战斗员\s*/, '').replace(/\s*\}\}$/, ''); // 按行分割 var lines = templateContent.split('\n'); for (var i = 0; i < lines.length; i++) { var line = lines[i].trim(); // 跳过空行和只有|的行 if (!line || line === '|') { continue; } // 移除开头的 | if (line.charAt(0) === '|') { line = line.substring(1); } // 查找第一个 = 的位置 var equalPos = line.indexOf('='); if (equalPos > 0) { var key = line.substring(0, equalPos).trim(); var value = line.substring(equalPos + 1).trim(); if (key) { data[key] = value; console.log('解析字段: [' + key + '] = [' + value + ']'); } } } console.log('成功解析字段数:', Object.keys(data).length); return data; }, // 生成模板 generateTemplate: function(data) { var template = '{{面包屑|战斗员图鉴}}\n{{战斗员\n'; // 基础信息 this.templateFields.basic.forEach(function(field) { var value = data[field.name] || ''; template += '|' + field.name + '=' + value + '\n'; }); template += '\n'; // 图片位置 this.templateFields.image.forEach(function(field) { var value = data[field.name] || ''; template += '|' + field.name + '=' + value + '\n'; }); template += '\n'; // 声优信息 this.templateFields.voice.forEach(function(field) { var value = data[field.name] || ''; template += '|' + field.name + '=' + value + '\n'; }); template += '\n'; // 角色档案 this.templateFields.profile.forEach(function(field) { var value = data[field.name] || ''; template += '|' + field.name + '=' + value + '\n'; }); template += '\n'; // 基础属性数值 this.templateFields.stats.forEach(function(field) { var value = data[field.name] || ''; template += '|' + field.name + '=' + value + '\n'; }); template += '\n'; // 伤害数值 this.templateFields.damage.forEach(function(field) { var value = data[field.name] || ''; template += '|' + field.name + '=' + value + '\n'; }); template += '\n'; // 技能信息 this.templateFields.skills.forEach(function(field) { var value = data[field.name] || ''; template += '|' + field.name + '=' + value + '\n'; }); template += '\n'; // 卡牌信息 this.templateFields.cards.forEach(function(field) { var value = data[field.name] || ''; template += '|' + field.name + '=' + value + '\n'; }); template += '\n'; // 展现自我意识 this.templateFields.ego.forEach(function(field) { var value = data[field.name] || ''; template += '|' + field.name + '=' + value + '\n'; }); template += '\n'; // 潜力 this.templateFields.potential.forEach(function(field) { var value = data[field.name] || ''; template += '|' + field.name + '=' + value + '\n'; }); template += '}}\n[[分类:战斗员]]'; return template; }, // 收集表单数据 collectFormData: function() { var data = {}; document.querySelectorAll('[data-field]').forEach(function(input) { var field = input.getAttribute('data-field'); data[field] = input.value; }); console.log('收集到的表单数据:', data); return data; }, // 保存战斗员 saveAgent: function() { var self = this; var title = document.getElementById('page-title').value.trim(); if (!title) { this.showMessage('请输入页面标题', 'error'); return; } var data = this.collectFormData(); var content = this.generateTemplate(data); this.showMessage('保存中...', 'info'); this.api.postWithToken('csrf', { action: 'edit', title: title, text: content, summary: '通过战斗员管理器更新', format: 'json' }).done(function() { self.showMessage('保存成功!', 'success'); self.currentAgent.title = title; self.currentAgent.content = content; self.loadAgentList(); }).fail(function(code, error) { console.error('保存失败:', code, error); self.showMessage('保存失败: ' + (error.error ? error.error.info : '未知错误'), 'error'); }); }, // 预览 previewAgent: function() { var data = this.collectFormData(); var content = this.generateTemplate(data); var preview = document.getElementById('preview-container'); preview.innerHTML = '<h4>预览</h4><pre style="background: #f5f5f5; padding: 10px; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;">' + mw.html.escape(content) + '</pre>'; }, // 查看源码 viewSource: function() { var data = this.collectFormData(); var content = this.generateTemplate(data); var preview = document.getElementById('preview-container'); preview.innerHTML = '<h4>Wiki源码</h4>' + '<textarea class="agent-textarea" style="min-height: 400px;">' + mw.html.escape(content) + '</textarea>'; }, // 导出所有 exportAll: function() { var self = this; var result = document.getElementById('batch-result'); result.innerHTML = '<div class="agent-loading">导出中...</div>'; var exportData = []; var promises = []; this.agentList.forEach(function(agent) { var promise = self.api.get({ action: 'query', titles: agent.title, prop: 'revisions', rvprop: 'content', rvslots: 'main', format: 'json' }).then(function(data) { var pages = data.query.pages; var pageId = Object.keys(pages)[0]; if (pageId !== '-1') { var content = pages[pageId].revisions[0].slots.main['*']; exportData.push({ title: agent.title, content: content }); } }); promises.push(promise); }); Promise.all(promises).then(function() { var json = JSON.stringify(exportData, null, 2); result.innerHTML = '<h4>导出结果 (' + exportData.length + '个战斗员)</h4>' + '<textarea class="agent-textarea" style="min-height: 400px;">' + mw.html.escape(json) + '</textarea>'; }); }, // 检查模板完整性 checkTemplates: function() { var self = this; var result = document.getElementById('batch-result'); result.innerHTML = '<div class="agent-loading">检查中...</div>'; var issues = []; var promises = []; this.agentList.forEach(function(agent) { var promise = self.api.get({ action: 'query', titles: agent.title, prop: 'revisions', rvprop: 'content', rvslots: 'main', format: 'json' }).then(function(data) { var pages = data.query.pages; var pageId = Object.keys(pages)[0]; if (pageId !== '-1') { var content = pages[pageId].revisions[0].slots.main['*']; var parsedData = self.parseTemplate(content); var missingFields = []; var allFields = [].concat( self.templateFields.basic, self.templateFields.voice, self.templateFields.profile ); allFields.forEach(function(field) { if (!parsedData[field.name] || parsedData[field.name].trim() === '') { missingFields.push(field.label); } }); if (missingFields.length > 0) { issues.push({ title: agent.title, missing: missingFields }); } } }); promises.push(promise); }); Promise.all(promises).then(function() { var html = '<h4>模板检查结果</h4>'; if (issues.length === 0) { html += '<div class="agent-message success">所有战斗员模板完整!</div>'; } else { html += '<div class="agent-message error">发现 ' + issues.length + ' 个页面存在问题:</div>'; html += '<div style="max-height: 400px; overflow-y: auto;">'; issues.forEach(function(issue) { html += '<div style="margin: 10px 0; padding: 10px; background: white; border: 1px solid #ddd;">'; html += '<strong>' + mw.html.escape(issue.title) + '</strong><br>'; html += '缺失字段: ' + mw.html.escape(issue.missing.join(', ')); html += '</div>'; }); html += '</div>'; } result.innerHTML = html; }); }, // 显示消息 showMessage: function(message, type) { var container = document.getElementById('agent-message'); container.innerHTML = '<div class="agent-message ' + type + '">' + mw.html.escape(message) + '</div>'; setTimeout(function() { container.innerHTML = ''; }, 5000); } }; // 页面加载完成后初始化 $(function() { AgentManager.init(); }); })();
该页面使用的模板:
模板:战斗员 和
(
查看源代码
)
模板:战斗员 和结尾的
(
查看源代码
)
模板:提示
(
查看源代码
)
模板:面包屑
(
查看源代码
)
返回
MediaWiki:Agent.js
。