跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
特殊页面
快速跳转
快速上手
登场角色
歌曲列表
成就指南
任务指南
DLC购买指南
其他企划
CDC赛事
DJMAX Ent
DJMAX中文资料库
搜索
搜索
外观
外观
移至侧栏
隐藏
创建账号
登录
个人工具
创建账号
登录
查看“︁模块:Db”︁的源代码
模块
讨论
English
阅读
查看源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
查看源代码
查看历史
常规
链入页面
相关更改
页面信息
←
模块:Db
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
local p = {} -- [[------------------------------------------------------------------]] -- [[ 1. 国际化和常量 ]] -- [[------------------------------------------------------------------]] local i18n = { ['true'] = '是', ['false'] = '否', ['none'] = '无', ['category_missing_value'] = '缺失%s', ['error_no_type'] = '<span class="error">Db:调用时必须提供type参数。</span>', ['error_find_keys_args'] = '<span class="error">Db:findKeysByValue必须提供field和value参数。</span>', ['error_generate_table_args'] = '<span class="error">Db:generateListTable调用缺少field或columns参数。</span>', } -- [[------------------------------------------------------------------]] -- [[ 2. 表格标题映射 ]] -- [[------------------------------------------------------------------]] local displayNames = { ['title'] = '歌曲标题', ['composer'] = '艺术家', ['bpm'] = 'BPM', ['singer'] = '歌手', ['genre'] = '流派', ['id'] = '歌曲ID', ['key'] = 'KEY音', ['bga'] = 'BGA作者', ['duration'] = '时长', ['pack'] = '曲包', ['4b_nm'] = '4B NM', ['4b_nm_notes'] = '4B NM', ['4b_hd'] = '4B HD', ['4b_hd_notes'] = '4B HD', ['4b_mx'] = '4B MX', ['4b_mx_notes'] = '4B MX', ['4b_sc'] = '4B SC', ['4b_sc_notes'] = '4B SC', ['5b_nm'] = '5B NM', ['5b_nm_notes'] = '5B NM', ['5b_hd'] = '5B HD', ['5b_hd_notes'] = '5B HD', ['5b_mx'] = '5B MX', ['5b_mx_notes'] = '5B MX', ['5b_sc'] = '5B SC', ['5b_sc_notes'] = '5B SC', ['6b_nm'] = '6B NM', ['6b_nm_notes'] = '6B NM', ['6b_hd'] = '6B HD', ['6b_hd_notes'] = '6B HD', ['6b_mx'] = '6B MX', ['6b_mx_notes'] = '6B MX', ['6b_sc'] = '6B SC', ['6b_sc_notes'] = '6B SC', ['8b_nm'] = '8B NM', ['8b_nm_notes'] = '8B NM', ['8b_hd'] = '8B HD', ['8b_hd_notes'] = '8B HD', ['8b_mx'] = '8B MX', ['8b_mx_notes'] = '8B MX', ['8b_sc'] = '8B SC', ['8b_sc_notes'] = '8B SC', } -- **Pack 缩写映射表(用户输入缩写 -> 完整包名,键使用大写以便不区分大小写查询)** local packAbbreviations = { ['VL'] = 'V LIBERTY', ['VL2'] = 'V LIBERTY 2', ['VL3'] = 'V LIBERTY 3', ['VE'] = 'V EXTENSION', ['VE2'] = 'V EXTENSION 2', ['VE3'] = 'V EXTENSION 3', ['VE4'] = 'V EXTENSION 4', ['VE5'] = 'V EXTENSION 5', ['P1'] = 'PORTABLE 1', ['P2'] = 'PORTABLE 2', ['P3'] = 'PORTABLE 3', ['CE'] = 'CLAZZIQUAI', ['BS'] = 'BLACK SQUARE', ['TR'] = 'TRILOGY', ['T1'] = 'TECHNIKA', ['T2'] = 'TECHNIKA 2', ['T3'] = 'TECHNIKA 3', ['R'] = 'RESPECT', ['RV'] = 'RESPECT V', ['ARC'] = 'ARCAEA', ['BA'] = 'BLUE ARCHIVE', ['CY'] = 'CYTUS', ['CHU'] = 'CHUNITHM', ['DE'] = 'DEEMO', ['EZ'] = 'EZ2ON', ['GC'] = 'GROOVE COASTER', ['MD'] = 'MUSE DASH', ['ESTI'] = 'ESTIMATE', ['FC'] = 'FALCOM', ['GF'] = 'GIRL\'S FRONTLINE', ['GG'] = 'GUILTY GEAR', ['MAP'] = 'MAPLESTORY', ['NXN'] = 'NEXON', ['TK'] = 'TEKKEN', ['TB1'] = 'PLI: TRIBUTE VOL.1', ['645141'] = 'PLI: 64514 VOL.1', } -- [[------------------------------------------------------------------]] -- [[ 3. 本地辅助函数定义 ]] -- [[------------------------------------------------------------------]] local function GetValuesTable() return mw.loadData('Module:db_song') end local function ValueFromValuesByKey(values, key) if values and key then return values[key] end return nil end -- **Pack 缩写解析** local function resolvePackValue(input) if type(input) ~= 'string' then return input end -- 尝试查找缩写(不区分大小写,因为 packAbbreviations 的键是大写) local upperInput = string.upper(input) if packAbbreviations[upperInput] then return packAbbreviations[upperInput] end -- 找不到缩写,返回原始输入 return input end local function formatSingleValue(value, fieldType) if value == nil then return i18n['none'] elseif type(value) == 'boolean' then return value and i18n['true'] or i18n['false'] elseif type(p.valueMappingMethod[fieldType]) == 'function' then return p.valueMappingMethod[fieldType](value) else return tostring(value) end end local function formatBPMValue(valueString) if string.find(valueString, '-') then return '<span style="color:red;">' .. valueString .. '</span>' end return valueString end -- **格式化 key 值 (仅在表格中使用)** local function formatKeyValue(value) if type(value) == 'boolean' then local color = value and 'green' or 'red' local text = value and i18n['true'] or i18n['false'] return '<span style="color:' .. color .. ';">' .. text .. '</span>' end return tostring(value) end local function getDifficultyDetails(field) local checkField = field and string.lower(mw.text.trim(field)) or '' local difficultyFields = { ['4b_nm'] = true, ['4b_hd'] = true, ['4b_mx'] = true, ['4b_sc'] = true, ['5b_nm'] = true, ['5b_hd'] = true, ['5b_mx'] = true, ['5b_sc'] = true, ['6b_nm'] = true, ['6b_hd'] = true, ['6b_mx'] = true, ['6b_sc'] = true, ['8b_nm'] = true, ['8b_hd'] = true, ['8b_mx'] = true, ['8b_sc'] = true, } if difficultyFields[checkField] == true then local mode = checkField:sub(-2) return checkField:match("^(%d+)b"), mode end return nil, nil end -- **核心:难度样式应用 (仅用于表格,并处理可能存在的 'sc' 前缀)** local function formatDifficultyStyles(valueString, mode) if valueString == '-' or valueString == i18n['none'] then return valueString end local displayString = valueString local numValue = tonumber(valueString) if mode == 'sc' and numValue == nil then local stripped = valueString:match("^[Ss][Cc](%d+)$") if stripped then numValue = tonumber(stripped) displayString = stripped end end if numValue == nil then return valueString end local style = '' if mode == 'sc' then local blueGlow = ' text-shadow: 0 0 5px #3D66FF, 0 0 8px #3D66FF;' style = 'font-weight: bold;' if numValue >= 1 and numValue <= 5 then style = style .. ' color: #E00075;' elseif numValue >= 6 and numValue <= 10 then style = style .. ' color: #C604E3;' elseif numValue >= 11 and numValue <= 12 then style = style .. ' color: #3D66FF;' elseif numValue == 13 then style = style .. ' color: orange;' .. blueGlow elseif numValue == 14 then style = style .. ' color: red;' .. blueGlow elseif numValue == 15 then style = style .. ' color: purple;' .. blueGlow end elseif (mode == 'nm' or mode == 'hd' or mode == 'mx') then if numValue == 14 then style = 'font-weight: bold; color: orange;' elseif numValue == 15 then style = 'font-weight: bold; color: red;' end end if style ~= '' then return '<span style="' .. style .. '">' .. displayString .. '</span>' end return displayString end -- **NOTES 字段加粗/变色逻辑** local function formatNotesValue(valueString, context) local numValue = tonumber(valueString) if numValue and numValue >= 2000 then local content = valueString if context == 'table' then -- --- 表格环境 (高优先级颜色 + 加粗) --- if numValue >= 3000 then -- Table, >= 3000: 紫色加粗 return '<span style="font-weight: bold; color: purple;">' .. content .. '</span>' elseif numValue >= 2000 then -- Table, 2000 <= X < 3000: 红色加粗 return '<span style="font-weight: bold; color: red;">' .. content .. '</span>' end else -- --- 非表格环境 (仅加粗) --- return '<b>' .. content .. '</b>' end end -- 如果小于 2000,返回原始字符串 return valueString end -- **SC 前缀应用 (仅用于 p.value)** local function applySCPrefix(valueString, fieldType) local isSC = string.match(fieldType, '_sc$') if isSC and valueString ~= i18n['none'] and valueString ~= '-' then if not valueString:lower():find('sc') then return 'sc' .. valueString end end return valueString end -- 4. 值格式化方法 (valueMappingMethod) p.valueMappingMethod = { ['duration'] = (function (value) if type(value) == 'number' then local minutes = math.floor(value / 60) local seconds = value % 60 return string.format('%d:%02d', minutes, seconds) end return value end), -- key 字段在非表格环境中的默认处理 (例如 p.value 调用) ['key'] = (function(value) if type(value) == 'boolean' then return value and i18n['true'] or i18n['false'] end return tostring(value) end) } -- [[------------------------------------------------------------------]] -- [[ 5. 外部调用函数 (p.*) ]] -- [[------------------------------------------------------------------]] function p.value(f) local args = f local frame = mw.getCurrentFrame() if f == frame then args = require('Module:ProcessArgs').merge(true) end local argTargetName = mw.text.trim(args[1] or '') local argTypeString = args.type local argNocat = args.nocat if not argTypeString then return i18n['error_no_type'] end local values = GetValuesTable() local songEntry = ValueFromValuesByKey(values, argTargetName) if not songEntry then if not argNocat then local title = mw.title.getCurrentTitle() if title.namespace == 0 and not title.isSubpage then return '?' .. '[[Category:' .. string.format(i18n['category_missing_value'], '歌曲ID ' .. argTargetName) .. ']]' end end return i18n['none'] end local fieldNames = mw.text.split(argTypeString, ',') local resultTable = {} for _, argType in ipairs(fieldNames) do argType = mw.text.trim(argType) local value = ValueFromValuesByKey(songEntry, argType) -- 使用 formatSingleValue 处理 BPM/Duration/Key(boolean->text) 等映射 local formattedValue = formatSingleValue(value, argType) formattedValue = applySCPrefix(formattedValue, argType) -- 非表格环境下应用 NOTES 格式化(仅加粗) if string.match(argType, '_notes$') then formattedValue = formatNotesValue(formattedValue, 'text') end table.insert(resultTable, formattedValue) end return table.concat(resultTable, ' / ') end function p.generateListTable(f) local args = require('Module:ProcessArgs').merge(true) local conditionField = mw.text.trim(args.field or '') local conditionValue = args.value local displayFieldsString = mw.text.trim(args.columns or '') local isPackFilter = (conditionField == 'pack') -- 定义 pack 筛选标记 -- ** 预处理 conditionValue ** if type(conditionValue) == 'string' then local trimmedValue = mw.text.trim(conditionValue) local lowerValue = string.lower(trimmedValue) if lowerValue == 'true' or trimmedValue == '是' then conditionValue = true elseif lowerValue == 'false' or trimmedValue == '否' then conditionValue = false else local num = tonumber(trimmedValue) -- 核心修复:如果是 Pack 筛选,即使能转为数字也不转,保持字符串以便后续缩写解析和不区分大小写比较 if num ~= nil and not isPackFilter then conditionValue = num else conditionValue = trimmedValue end end end if conditionField == '' or displayFieldsString == '' then return i18n['error_generate_table_args'] end local songData = GetValuesTable() local displayFields = mw.text.split(displayFieldsString, ',') local matchingKeys = {} local shouldFilter = conditionValue ~= nil -- 如果是 pack 筛选,提前解析 conditionValue 以支持缩写 local resolvedConditionValue = nil if isPackFilter and type(conditionValue) == 'string' then resolvedConditionValue = resolvePackValue(conditionValue) end for songId, songEntry in pairs(songData) do if not shouldFilter then table.insert(matchingKeys, songId) else local currentValue = ValueFromValuesByKey(songEntry, conditionField) local match = false if isPackFilter and type(currentValue) == 'string' and type(conditionValue) == 'string' then -- Pack Filter: 使用解析后的值进行不区分大小写的比较 if string.upper(currentValue) == string.upper(resolvedConditionValue) then match = true end elseif currentValue == conditionValue then -- Standard Match (用于非 pack 字符串、数字、布尔值) match = true end if match then table.insert(matchingKeys, songId) end end end table.sort(matchingKeys) if #matchingKeys == 0 then return '未找到符合条件的歌曲。' end local output = {} -- 表格样式 table.insert(output, '{| class="wikitable sortable" style="width: 100%; margin: 0 auto; text-align: center;"') -- 构造表格头部:添加宽度样式控制 table.insert(output, '|-') for _, field in ipairs(displayFields) do field = mw.text.trim(field) local _, mode = getDifficultyDetails(field) local headerContent = displayNames[field] or field local headerStyle = '' local separator = ' ' -- 默认分隔符是空格 -- BPM/Pack/Key/Duration 字段,固定宽度 6% if field == 'bpm' or field == 'pack' or field == 'key' or field == 'duration' then headerStyle = ' style="width: 6%;"' separator = ' | ' elseif mode then -- 谱面难度字段 (3.2% 固定宽度) headerStyle = ' style="width: 3.2%;"' separator = ' | ' elseif string.match(field, '_notes$') then -- NOTES 字段 (4% 固定宽度) headerStyle = ' style="width: 4%;"' separator = ' | ' end -- MediaWiki 表格头单元格: ! style | Content table.insert(output, '!' .. headerStyle .. separator .. headerContent) end -- 构造表格行 for _, songId in ipairs(matchingKeys) do local songEntry = songData[songId] table.insert(output, '|-') for _, field in ipairs(displayFields) do field = mw.text.trim(field) local rawValue = ValueFromValuesByKey(songEntry, field) -- 获取格式化的值 local formattedValue = formatSingleValue(rawValue, field) -- 应用内容样式 (BPM/Key) if field == 'bpm' then formattedValue = formatBPMValue(formattedValue) elseif field == 'key' then formattedValue = formatKeyValue(rawValue) -- 对 key 字段应用颜色逻辑,使用原始值 (rawValue) end local _, mode = getDifficultyDetails(field) if mode then formattedValue = formatDifficultyStyles(formattedValue, mode) end -- *** NOTES 字段样式逻辑 (包含 _sc_notes 默认颜色) *** if string.match(field, '_notes$') then local numValue = tonumber(rawValue) -- 1. 检查是否为高优先级(>= 2000/3000) if numValue and numValue >= 2000 then -- 高优先级:应用红/紫色的 formatNotesValue formattedValue = formatNotesValue(formattedValue, 'table') -- 2. 检查是否为所有 _sc_notes 字段且为低优先级(< 2000) elseif string.match(field, '_sc_notes$') then -- <-- 修复点:使用正则匹配所有 _sc_notes 结尾的字段 -- sc_notes 默认颜色:3d66ff (如果值不是高优先级) formattedValue = '<span style="color: #3d66ff;">' .. formattedValue .. '</span>' end end local cellContent = formattedValue -- CRITICAL FIX: 如果内容是单个 '-', 增加空格以避免被解析为行分隔符 '|-'. if cellContent == '-' then cellContent = ' -' end table.insert(output, '|' .. cellContent) end end table.insert(output, '|}') return table.concat(output, '\n') end return p
该页面使用的模板:
模块:Db/doc
(
查看源代码
)
返回
模块:Db
。
搜索
搜索
查看“︁模块:Db”︁的源代码
添加话题