|
|
| (未显示同一用户的2个中间版本) |
| 第1行: |
第1行: |
| local p = {} | | local p = {} |
| local data = mw.loadData("模块:中立&怪物卡牌灵光一闪/data") | | local data = mw.loadData("模块:中立&怪物卡牌灵光一闪/data") |
|
| |
| -- 分割字符串函数
| |
| local function split(str, delimiter)
| |
| if not str or str == "" then
| |
| return {}
| |
| end
| |
| local result = {}
| |
| for match in (str .. delimiter):gmatch("(.-)" .. delimiter) do
| |
| table.insert(result, match)
| |
| end
| |
| return result
| |
| end
| |
|
| |
| -- 检查是否包含某个值
| |
| local function contains(str, value)
| |
| if not str or str == "" then
| |
| return false
| |
| end
| |
| local items = split(str, "、")
| |
| for _, item in ipairs(items) do
| |
| if item == value then
| |
| return true
| |
| end
| |
| end
| |
| return false
| |
| end
| |
|
| |
| -- 检查费用范围
| |
| local function checkCost(item, minCost, maxCost)
| |
| if minCost and tonumber(minCost) then
| |
| if item.cost_min < tonumber(minCost) then
| |
| return false
| |
| end
| |
| end
| |
| if maxCost and tonumber(maxCost) then
| |
| if item.cost_max > tonumber(maxCost) then
| |
| return false
| |
| end
| |
| end
| |
| return true
| |
| end
| |
|
| |
| -- 筛选函数
| |
| local function filterData(filters)
| |
| local result = {}
| |
|
| |
| for _, item in ipairs(data) do
| |
| local match = true
| |
|
| |
| -- 筛选类型
| |
| if filters.type and filters.type ~= "" and filters.type ~= "全部" then
| |
| if not item.type or not contains(item.type, filters.type) then
| |
| match = false
| |
| end
| |
| end
| |
|
| |
| -- 筛选包含机制
| |
| if match and filters.dict_include and filters.dict_include ~= "" and filters.dict_include ~= "全部" then
| |
| if not item.dict_include or not contains(item.dict_include, filters.dict_include) then
| |
| match = false
| |
| end
| |
| end
| |
|
| |
| -- 筛选排除机制
| |
| if match and filters.dict_exclude and filters.dict_exclude ~= "" and filters.dict_exclude ~= "全部" then
| |
| if not item.dict_exclude or not contains(item.dict_exclude, filters.dict_exclude) then
| |
| match = false
| |
| end
| |
| end
| |
|
| |
| -- 筛选职业
| |
| if match and filters.class and filters.class ~= "" and filters.class ~= "全部" then
| |
| if not item.class or not contains(item.class, filters.class) then
| |
| match = false
| |
| end
| |
| end
| |
|
| |
| -- 筛选费用
| |
| if match then
| |
| if not checkCost(item, filters.cost_min, filters.cost_max) then
| |
| match = false
| |
| end
| |
| end
| |
|
| |
| if match then
| |
| table.insert(result, item)
| |
| end
| |
| end
| |
|
| |
| return result
| |
| end
| |
|
| |
| -- 创建筛选表单
| |
| local function createFilterForm(currentPage)
| |
| local form = mw.html.create('div')
| |
| form:addClass('filter-form')
| |
| form:css('background-color', '#f9f9f9')
| |
| form:css('padding', '15px')
| |
| form:css('margin-bottom', '20px')
| |
| form:css('border', '1px solid #ddd')
| |
| form:css('border-radius', '5px')
| |
|
| |
| local formTag = form:tag('form')
| |
| formTag:attr('method', 'get')
| |
| formTag:attr('action', mw.title.getCurrentTitle():fullUrl())
| |
|
| |
| local table = formTag:tag('table')
| |
| table:css('width', '100%')
| |
|
| |
| -- 类型筛选
| |
| local row1 = table:tag('tr')
| |
| row1:tag('td'):css('width', '120px'):wikitext("'''类型:'''")
| |
| local td1 = row1:tag('td')
| |
| local select1 = td1:tag('select')
| |
| select1:attr('name', 'type')
| |
| select1:attr('id', 'filter-type')
| |
| for _, v in ipairs({"全部", "攻击", "技能", "强化"}) do
| |
| local option = select1:tag('option')
| |
| option:attr('value', v == "全部" and "" or v)
| |
| option:wikitext(v)
| |
| end
| |
|
| |
| -- 包含机制筛选
| |
| local row2 = table:tag('tr')
| |
| row2:tag('td'):wikitext("'''包含机制:'''")
| |
| local td2 = row2:tag('td')
| |
| local select2 = td2:tag('select')
| |
| select2:attr('name', 'dict_include')
| |
| select2:attr('id', 'filter-dict-include')
| |
| for _, v in ipairs({"全部", "消耗", "终极"}) do
| |
| local option = select2:tag('option')
| |
| option:attr('value', v == "全部" and "" or v)
| |
| option:wikitext(v)
| |
| end
| |
|
| |
| -- 排除机制筛选
| |
| local row3 = table:tag('tr')
| |
| row3:tag('td'):wikitext("'''排除机制:'''")
| |
| local td3 = row3:tag('td')
| |
| local select3 = td3:tag('select')
| |
| select3:attr('name', 'dict_exclude')
| |
| select3:attr('id', 'filter-dict-exclude')
| |
| for _, v in ipairs({"全部", "无法使用", "消耗", "终极"}) do
| |
| local option = select3:tag('option')
| |
| option:attr('value', v == "全部" and "" or v)
| |
| option:wikitext(v)
| |
| end
| |
|
| |
| -- 职业筛选
| |
| local row4 = table:tag('tr')
| |
| row4:tag('td'):wikitext("'''职业:'''")
| |
| local td4 = row4:tag('td')
| |
| local select4 = td4:tag('select')
| |
| select4:attr('name', 'class')
| |
| select4:attr('id', 'filter-class')
| |
| for _, v in ipairs({"全部", "决斗家", "游侠", "猎人", "心灵术士", "控制师", "先锋"}) do
| |
| local option = select4:tag('option')
| |
| option:attr('value', v == "全部" and "" or v)
| |
| option:wikitext(v)
| |
| end
| |
|
| |
| -- 最低费用筛选
| |
| local row5 = table:tag('tr')
| |
| row5:tag('td'):wikitext("'''最低费用:'''")
| |
| local td5 = row5:tag('td')
| |
| local select5 = td5:tag('select')
| |
| select5:attr('name', 'cost_min')
| |
| select5:attr('id', 'filter-cost-min')
| |
| for _, v in ipairs({"全部", "-1", "0", "1", "2", "3", "4"}) do
| |
| local option = select5:tag('option')
| |
| option:attr('value', v == "全部" and "" or v)
| |
| option:wikitext(v)
| |
| end
| |
|
| |
| -- 最高费用筛选
| |
| local row6 = table:tag('tr')
| |
| row6:tag('td'):wikitext("'''最高费用:'''")
| |
| local td6 = row6:tag('td')
| |
| local select6 = td6:tag('select')
| |
| select6:attr('name', 'cost_max')
| |
| select6:attr('id', 'filter-cost-max')
| |
| for _, v in ipairs({"全部", "0", "1", "2", "3", "99"}) do
| |
| local option = select6:tag('option')
| |
| option:attr('value', v == "全部" and "" or v)
| |
| option:wikitext(v)
| |
| end
| |
|
| |
| -- 按钮行
| |
| local row7 = table:tag('tr')
| |
| local td7 = row7:tag('td')
| |
| td7:attr('colspan', '2')
| |
| td7:css('text-align', 'center')
| |
| td7:css('padding-top', '10px')
| |
|
| |
| local submitBtn = td7:tag('button')
| |
| submitBtn:attr('type', 'submit')
| |
| submitBtn:css('padding', '8px 20px')
| |
| submitBtn:css('margin-right', '10px')
| |
| submitBtn:css('background-color', '#4CAF50')
| |
| submitBtn:css('color', 'white')
| |
| submitBtn:css('border', 'none')
| |
| submitBtn:css('border-radius', '4px')
| |
| submitBtn:css('cursor', 'pointer')
| |
| submitBtn:wikitext('筛选')
| |
|
| |
| local resetBtn = td7:tag('button')
| |
| resetBtn:attr('type', 'button')
| |
| resetBtn:attr('onclick', 'window.location.href="' .. mw.title.getCurrentTitle():fullUrl() .. '"')
| |
| resetBtn:css('padding', '8px 20px')
| |
| resetBtn:css('background-color', '#f44336')
| |
| resetBtn:css('color', 'white')
| |
| resetBtn:css('border', 'none')
| |
| resetBtn:css('border-radius', '4px')
| |
| resetBtn:css('cursor', 'pointer')
| |
| resetBtn:wikitext('重置')
| |
|
| |
| return tostring(form)
| |
| end
| |
|
| |
| -- 设置下拉框选中状态的JavaScript
| |
| local function createSelectionScript(filters)
| |
| local script = mw.html.create('script')
| |
| script:wikitext([[
| |
| document.addEventListener('DOMContentLoaded', function() {
| |
| var params = new URLSearchParams(window.location.search);
| |
|
| |
| if (params.get('type')) {
| |
| document.getElementById('filter-type').value = params.get('type');
| |
| }
| |
| if (params.get('dict_include')) {
| |
| document.getElementById('filter-dict-include').value = params.get('dict_include');
| |
| }
| |
| if (params.get('dict_exclude')) {
| |
| document.getElementById('filter-dict-exclude').value = params.get('dict_exclude');
| |
| }
| |
| if (params.get('class')) {
| |
| document.getElementById('filter-class').value = params.get('class');
| |
| }
| |
| if (params.get('cost_min')) {
| |
| document.getElementById('filter-cost-min').value = params.get('cost_min');
| |
| }
| |
| if (params.get('cost_max')) {
| |
| document.getElementById('filter-cost-max').value = params.get('cost_max');
| |
| }
| |
| });
| |
| ]])
| |
|
| |
| return tostring(script)
| |
| end
| |
|
| |
|
| -- 主函数 | | -- 主函数 |
| function p.show(frame) | | function p.show(frame) |
| -- 获取URL参数
| |
| local request = mw.getCurrentFrame():getParent() or frame
| |
| local args = request.args
| |
|
| |
| -- 尝试从URL获取参数
| |
| local urlArgs = {}
| |
| if mw.title.getCurrentTitle().namespace == 0 then
| |
| -- 从当前页面的查询字符串中提取参数
| |
| for k, v in pairs(args) do
| |
| urlArgs[k] = v
| |
| end
| |
| end
| |
|
| |
| -- 获取筛选参数
| |
| local filters = {
| |
| type = args.type or urlArgs.type or "",
| |
| dict_include = args.dict_include or urlArgs.dict_include or "",
| |
| dict_exclude = args.dict_exclude or urlArgs.dict_exclude or "",
| |
| class = args.class or urlArgs["class"] or "",
| |
| cost_min = args.cost_min or urlArgs.cost_min or "",
| |
| cost_max = args.cost_max or urlArgs.cost_max or ""
| |
| }
| |
|
| |
| -- 筛选数据
| |
| local filteredData = filterData(filters)
| |
|
| |
| -- 构建输出
| |
| local output = "" | | local output = "" |
| | | |
| -- 添加筛选表单 | | -- 构建包含所有数据的表格 |
| output = output .. "== 筛选条件 ==\n" | | output = output .. "=== 结果 ===\n" |
| output = output .. createFilterForm(mw.title.getCurrentTitle().prefixedText)
| |
| output = output .. createSelectionScript(filters)
| |
|
| |
| -- 显示当前筛选信息
| |
| local hasFilter = false
| |
| local filterInfo = ""
| |
| if filters.type and filters.type ~= "" then
| |
| filterInfo = filterInfo .. "* 类型: " .. filters.type .. "\n"
| |
| hasFilter = true
| |
| end
| |
| if filters.dict_include and filters.dict_include ~= "" then
| |
| filterInfo = filterInfo .. "* 包含机制: " .. filters.dict_include .. "\n"
| |
| hasFilter = true
| |
| end
| |
| if filters.dict_exclude and filters.dict_exclude ~= "" then
| |
| filterInfo = filterInfo .. "* 排除机制: " .. filters.dict_exclude .. "\n"
| |
| hasFilter = true
| |
| end
| |
| if filters.class and filters.class ~= "" then
| |
| filterInfo = filterInfo .. "* 职业: " .. filters.class .. "\n"
| |
| hasFilter = true
| |
| end
| |
| if filters.cost_min and filters.cost_min ~= "" then
| |
| filterInfo = filterInfo .. "* 最低费用: " .. filters.cost_min .. "\n"
| |
| hasFilter = true
| |
| end
| |
| if filters.cost_max and filters.cost_max ~= "" then
| |
| filterInfo = filterInfo .. "* 最高费用: " .. filters.cost_max .. "\n"
| |
| hasFilter = true
| |
| end
| |
|
| |
| if hasFilter then
| |
| output = output .. "\n=== 当前筛选 ===\n" .. filterInfo
| |
| end
| |
|
| |
| -- 构建表格
| |
| output = output .. "\n== 结果 ==\n"
| |
| local html = mw.html.create('table') | | local html = mw.html.create('table') |
| html:addClass('wikitable sortable') | | html:addClass('wikitable sortable') |
| | html:attr('id', 'card-results-table') |
| | | |
| -- 表头 | | -- 表头 |
| 第335行: |
第23行: |
| | | |
| -- 数据行 | | -- 数据行 |
| for _, item in ipairs(filteredData) do | | for _, item in ipairs(data) do |
| local row = html:tag('tr') | | local row = html:tag('tr') |
| | row:attr('data-type', item.type or "") |
| | row:attr('data-dict-include', item.dict_include or "") |
| | row:attr('data-dict-exclude', item.dict_exclude or "") |
| | row:attr('data-class', item.class or "") |
| | row:attr('data-cost-min', tostring(item.cost_min)) |
| | row:attr('data-cost-max', tostring(item.cost_max)) |
| | |
| row:tag('td'):wikitext(item.desc_global or "") | | row:tag('td'):wikitext(item.desc_global or "") |
| row:tag('td'):wikitext(tostring(item.cost_min)) | | row:tag('td'):wikitext(tostring(item.cost_min)) |
| 第347行: |
第42行: |
| | | |
| output = output .. tostring(html) | | output = output .. tostring(html) |
| output = output .. "\n\n''共 " .. #filteredData .. " 条结果''" | | output = output .. "\n\n<div id='result-count'>''共 " .. #data .. " 条结果''</div>" |
| | | |
| return output | | return output |