diff --git a/src/entries/ItemList.ts b/src/entries/ItemList.ts index 837bc69..5064b50 100644 --- a/src/entries/ItemList.ts +++ b/src/entries/ItemList.ts @@ -1,7 +1,75 @@ import "virtual:uno.css"; import { createApp } from "vue"; +import { TORAPPU_ENDPOINT } from "../utils/consts"; +import { getImagePath } from "../utils/utils"; import ItemList from "../widgets/ItemList/index.vue"; +import type { ItemData } from "../widgets/ItemList/types"; + +function readItemsFromDOM(): ItemData[] { + const elements = document.querySelectorAll("#cargo-data>div"); + const items: ItemData[] = []; + + for (const el of elements) { + const name = el.dataset.name ?? ""; + const itemId = el.dataset.itemId ?? ""; + if (!itemId) { + console.warn("[ItemList] itemId为空,跳过:", name); + continue; + } + + const obtainMethodEl = el.querySelector(".obtain-method"); + const descriptionEl = el.querySelector(".description"); + const purposeEl = el.querySelector(".purpose"); + + const filename = el.dataset.filename ?? ""; + const iconId = el.dataset.iconId ?? ""; + const imgSrc = (() => { + if (filename === "") { + return iconId === "" + ? getImagePath("无图片占位符.png") + : `${TORAPPU_ENDPOINT}/assets/item_icon/${iconId}.png`; + } else { + return filename; + } + })(); + + items.push({ + name, + description: descriptionEl?.textContent ?? "", + descriptionHtml: descriptionEl?.innerHTML ?? "", + usage: purposeEl?.textContent ?? "", + usageHtml: purposeEl?.innerHTML ?? "", + obtainApproach: (obtainMethodEl?.textContent ?? "") + .split(/[,、,]/) + .map((s) => s.trim()) + .filter(Boolean), + rarity: Number(el.dataset.rarity ?? "0"), + category1: el.dataset.category1 ?? "", + category2: el.dataset.category2 ?? "", + category3: el.dataset.category3 ?? "", + categories: [ + el.dataset.category1, + el.dataset.category2, + el.dataset.category3, + ].filter(Boolean) as string[], + itemId, + sortId: Number(el.dataset.sortId ?? "0"), + iconId, + filename, + darkBackground: el.dataset.darkBackground === "1", + imgSrc, + }); + } + + items.sort((a, b) => a.sortId - b.sortId); + return items; +} + const ele = document.querySelector("#root"); -if (ele) createApp(ItemList, {}).mount(ele); +if (ele) { + const items = readItemsFromDOM(); + console.log(items); + createApp(ItemList, { items }).mount(ele); +} diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 6978fe8..7af14c0 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -30,6 +30,26 @@ export function getImagePath(filename: string) { return `${MEDIA_ENDPOINT}/${md5.slice(0, 1)}/${md5.slice(0, 2)}/${filename}`; } +export async function getImagePathWithRedirect(filename: string) { + const resp = await fetch( + `/api.php?${new URLSearchParams({ + action: "query", + titles: `File:${filename}`, + redirects: "1", + format: "json", + })}`, + ); + const data = await resp.json(); + + if (data.query?.redirects) { + filename = (data.query.redirects[0].to || filename) + .replaceAll(" ", "_") + .replace("文件:", ""); + } + + return getImagePath(filename); +} + export const professionMap = { PIONEER: "先锋", WARRIOR: "近卫", diff --git a/src/widgets/ItemList/ItemCard.vue b/src/widgets/ItemList/ItemCard.vue index 94cd1ed..1839dcc 100644 --- a/src/widgets/ItemList/ItemCard.vue +++ b/src/widgets/ItemList/ItemCard.vue @@ -1,26 +1,11 @@
{{ item.name }}
-
- {{ item.usage }} -
-
- {{ item.description }} -
+
+
@@ -68,4 +57,7 @@ const imgSrc = computed(() => { transform: scale(1.1); z-index: 1; } +:deep(a) { + color: orange !important; +} diff --git a/src/widgets/ItemList/consts.ts b/src/widgets/ItemList/consts.ts index 98412eb..5e92e2b 100644 --- a/src/widgets/ItemList/consts.ts +++ b/src/widgets/ItemList/consts.ts @@ -12,12 +12,9 @@ export const defaultFilterConfig: FilterConfig = { "材料", "消耗道具", "作战记录", - "建材", - "建材原材料", + "精英化芯片", "技巧概要", - "芯片", - "双芯片", - "芯片组", + "基建材料", "理智药剂", "食物", "物资补给", @@ -29,15 +26,11 @@ export const defaultFilterConfig: FilterConfig = { "私人信件", "文件夹", "活动道具", - "其它道具组合", + "道具组合", "干员赠礼", "纪念物", "可露希尔票券", - "其他道具", - "其他干员道具", - "养成材料组合", - "家具收藏包", - "形艺特辑组件包", + "其他", ], }, obtainApproach: { @@ -88,6 +81,14 @@ export const rarityColorMap: Record = { 5: "#e06c00", }; +//only needed aliases +export const categoryAliases: Record = { + 精英化芯片: ["芯片", "芯片组", "双芯片"], + 基建材料: ["建材", "建材原材料"], + 道具组合: ["养成材料组合", "家具收藏包", "其它道具组合", "形艺特辑组件包"], + 其他: ["其他道具", "其他干员道具"], +}; + export const obtainApproachAliases: Record = { 采购中心: ["采购中心"], 任务奖励: ["任务奖励", "日常任务", "周常任务"], diff --git a/src/widgets/ItemList/index.vue b/src/widgets/ItemList/index.vue index 4b3e2a9..b6952fe 100644 --- a/src/widgets/ItemList/index.vue +++ b/src/widgets/ItemList/index.vue @@ -1,5 +1,5 @@ diff --git a/src/widgets/ItemList/itemData.ts b/src/widgets/ItemList/itemData.ts deleted file mode 100644 index a790c27..0000000 --- a/src/widgets/ItemList/itemData.ts +++ /dev/null @@ -1,49 +0,0 @@ -import type { ItemData } from "./types"; - -export async function fetchAllItems(): Promise { - const itemsMap = new Map(); - let offset = 0; - while (offset % 5000 === 0) { - const resp = await fetch( - `/api.php?${new URLSearchParams({ - action: "cargoquery", - format: "json", - limit: "5000", - tables: "item", - fields: - "name,description,purpose,obtain_method,rarity,category1,category2,itemId,sortId,iconId,filename,darkBackground", - order_by: "sortId", - offset: offset.toString(), - })}`, - ); - const json = await resp.json(); - if (!json.cargoquery?.length) break; - - for (const e of json.cargoquery) { - const t = e.title; - const itemId = t.itemId ?? ""; - if (!itemId) { - console.warn("[ItemList] itemId为空,跳过:", t.name); - continue; - } - const name = t.name ?? ""; - itemsMap.set(name, { - name, - description: t.description ?? "", - usage: t.purpose ?? "", - obtainApproach: (t["obtain method"] ?? "").split("、").filter(Boolean), - rarity: Number(t.rarity), - category1: t.category1 ?? "", - category2: t.category2 ?? "", - categories: [t.category1, t.category2].filter(Boolean), - itemId, - sortId: Number(t.sortId), - iconId: t.iconId ?? "", - filename: t.filename ?? "", - darkBackground: t.darkBackground === "1", - }); - } - offset += json.cargoquery.length; - } - return Array.from(itemsMap.values()); -} diff --git a/src/widgets/ItemList/types.ts b/src/widgets/ItemList/types.ts index 4f6b466..2be87db 100644 --- a/src/widgets/ItemList/types.ts +++ b/src/widgets/ItemList/types.ts @@ -1,17 +1,21 @@ export interface ItemData { name: string; description: string; + descriptionHtml: string; usage: string; + usageHtml: string; obtainApproach: string[]; rarity: number; category1: string; category2: string; + category3: string; categories: string[]; itemId: string; sortId: number; iconId: string; filename: string; darkBackground: boolean; + imgSrc: string; } export interface FilterConfig {