模块:CardData
来自夜幕之下
更多操作
此模块的文档可以在模块:CardData/doc创建
-- Module:CardData
-- 用法:{{#invoke:CardData|render|复仇童谣}}
local p = {}
local function val(v, fallback)
if v == nil or v == "" then return fallback or "—" end
return v
end
local function rarityStars(n)
n = tonumber(n) or 0
return string.rep("★", n)
end
local function parseJson(str)
if not str or str == "" then return nil end
local ok, result = pcall(mw.text.jsonDecode, str)
if ok then return result else return nil end
end
local function makeTitle(titleText, subtitleText, extraClass)
local div = mw.html.create("div")
:addClass("card_content-item-title")
:addClass("card_content-item-title--mt")
if extraClass then div:addClass(extraClass) end
div:wikitext(titleText)
div:tag("span")
:addClass("card_content-item-subtitle")
:wikitext(subtitleText)
return div
end
local function makeHr(extraClass)
local div = mw.html.create("div")
:addClass("card_content-item-hr")
if extraClass then div:addClass(extraClass) end
return div
end
local function makeStoryTimeline(stories, cardTitle)
local timeline = mw.html.create("div")
:addClass("card_timeline card_content_story-timeline")
timeline:tag("div")
:addClass("card_timeline-line")
-- 更安全获取 entry
local entry
if type(stories) == "table" then
for _,v in pairs(stories) do
entry = v
break
end
end
local chapters = entry and entry.story or {}
if not chapters or type(chapters) ~= "table" then
chapters = {}
end
if next(chapters) == nil then
timeline:tag("div")
:addClass("card_timeline-item")
:wikitext("(小传数据待补充)")
return timeline
end
local romans = { "Ⅰ","Ⅱ","Ⅲ","Ⅳ","Ⅴ","Ⅵ","Ⅶ","Ⅷ" }
local unlockLevels = {
"Lv.20 解锁",
"Lv.40 解锁",
"Lv.60 解锁",
"Lv.80 解锁",
"Lv.100 解锁"
}
local idx = 1
for _, chapter in pairs(chapters) do
local item = timeline:tag("div")
:addClass("card_timeline-item")
item:tag("div")
:addClass("card_timeline-dot")
item:tag("div")
:addClass("card_timeline-unlock")
:wikitext(unlockLevels[idx] or ("Lv."..(idx*20).." 解锁"))
local titleDiv = item:tag("div")
:addClass("card_timeline-title")
titleDiv:tag("span")
:addClass("card_timeline-numeral")
:wikitext(romans[idx] or idx)
titleDiv:tag("span")
:addClass("card_timeline-chapter")
:wikitext(cardTitle or "")
titleDiv:tag("span")
:addClass("card_timeline-label")
:wikitext("/ Story")
local bodyDiv = item:tag("div")
:addClass("card_timeline-body")
local text = chapter.text or ""
if text ~= "" then
local lines = mw.text.split(text,"\n")
for i,line in ipairs(lines) do
if line ~= "" then
bodyDiv:wikitext(line)
end
if i < #lines then
bodyDiv:tag("br")
end
end
end
idx = idx + 1
end
return timeline
end
function p.render(frame)
local name = mw.text.trim(frame.args[1] or frame.args.name or "")
if name == "" then
return '<span class="error">错误:请提供卡片名称</span>'
end
-- 关键:stories.story.*
local fields = table.concat({
"stylename",
"rarity",
"character.name",
"profession.name",
"desire.name",
"skill_normal_attack.name",
"skill_normal_attack.type",
"skill_normal_attack.weapon",
"skill_normal_attack.description",
"skill_normal_attack.levels.*",
"skill_passive.name",
"skill_passive.type",
"skill_passive.trigger_type",
"skill_passive.trigger_value",
"skill_passive.tags",
"skill_passive.description",
"skill_passive.levels.*",
"skill_ultimate.name",
"skill_ultimate.type",
"skill_ultimate.desire_cost",
"skill_ultimate.tags",
"skill_ultimate.description",
"skill_ultimate.levels.*",
"feats.stages",
-- 修复 stories
"stories.*",
"stories.story.*"
},",")
local encodedName = mw.uri.encode(name,"QUERY")
local apiUrl =
"https://data.saltedkiss.org/items/cards"
.. "?fields=" .. mw.uri.encode(fields,"QUERY")
.. "&filter[stylename][_eq]=" .. encodedName
local rawResponse = frame:preprocess(
'{{#get_web_data:url='..apiUrl
..'|format=text|data=responseText=__text}}'
..'{{#external_value:responseText}}'
)
rawResponse = mw.text.trim(rawResponse or "")
local parsed = parseJson(rawResponse)
local card =
parsed
and type(parsed.data) == "table"
and parsed.data[1]
or nil
if not card then
return '<span class="error">⚠ 无法加载卡片数据</span>'
end
local stories = card.stories or {}
local root = mw.html.create("div")
:addClass("ron-card")
local rightCol = root:tag("div")
:addClass("card_content_right")
local storySection = rightCol:tag("div")
:addClass("card_content_story")
local storyHeader = storySection:tag("div")
:addClass("card_content_story-header")
local storyLeft = storyHeader:tag("div")
:addClass("card_content_story-header-left")
storyLeft:node(makeTitle("小传","Story"))
storyLeft:node(makeHr("card_content-item-hr--mb12"))
storyHeader:node(
makeStoryTimeline(stories,card.stylename)
)
return tostring(root)
end
return p