mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2026-03-15 03:53:16 +08:00
@@ -52,7 +52,8 @@
|
||||
{ "url": "https://*.miyoushe.com/*" },
|
||||
{ "url": "https://*.mihoyo.com/*" },
|
||||
{ "url": "https://homa.snapgenshin.com/*" },
|
||||
{ "url": "https://*.hoyoverse.com/*" }
|
||||
{ "url": "https://*.hoyoverse.com/*" },
|
||||
{ "url": "https://api.hakush.in/*" }
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -3,42 +3,43 @@
|
||||
<v-app-bar>
|
||||
<template #prepend>
|
||||
<div class="gacha-top-title">
|
||||
<img src="/source/UI/userGacha.webp" alt="gacha" />
|
||||
<img alt="gacha" src="/source/UI/userGacha.webp" />
|
||||
<span>祈愿记录</span>
|
||||
<v-select
|
||||
:hide-details="true"
|
||||
density="compact"
|
||||
v-model="uidCur"
|
||||
:hide-details="true"
|
||||
:items="selectItem"
|
||||
variant="outlined"
|
||||
density="compact"
|
||||
label="游戏UID"
|
||||
variant="outlined"
|
||||
/>
|
||||
<img
|
||||
alt="byd"
|
||||
class="gacha-top-byd"
|
||||
src="/icon/nation/千星奇域.webp"
|
||||
alt="byd"
|
||||
@click="toBeyond()"
|
||||
title="千星奇域"
|
||||
@click="toBeyond()"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #extension>
|
||||
<div class="gacha-top-btns">
|
||||
<v-btn prepend-icon="mdi-refresh" class="gacha-top-btn" @click="confirmRefresh(false)">
|
||||
<v-btn class="gacha-top-btn" prepend-icon="mdi-refresh" @click="confirmRefresh(false)">
|
||||
增量刷新
|
||||
</v-btn>
|
||||
<v-btn prepend-icon="mdi-refresh" class="gacha-top-btn" @click="confirmRefresh(true)">
|
||||
<v-btn class="gacha-top-btn" prepend-icon="mdi-refresh" @click="confirmRefresh(true)">
|
||||
全量刷新
|
||||
</v-btn>
|
||||
<v-btn prepend-icon="mdi-import" class="gacha-top-btn" @click="importUigf()">导入</v-btn>
|
||||
<v-btn prepend-icon="mdi-import" class="gacha-top-btn" @click="importUigf4()">
|
||||
<v-btn class="gacha-top-btn" prepend-icon="mdi-import" @click="importUigf()">导入</v-btn>
|
||||
<v-btn class="gacha-top-btn" prepend-icon="mdi-import" @click="importUigf4()">
|
||||
导入(v4)
|
||||
</v-btn>
|
||||
<v-btn prepend-icon="mdi-export" class="gacha-top-btn" @click="exportUigf()">导出</v-btn>
|
||||
<v-btn prepend-icon="mdi-export" class="gacha-top-btn" @click="exportUigf4()">
|
||||
<v-btn class="gacha-top-btn" prepend-icon="mdi-export" @click="exportUigf()">导出</v-btn>
|
||||
<v-btn class="gacha-top-btn" prepend-icon="mdi-export" @click="exportUigf4()">
|
||||
导出(v4)
|
||||
</v-btn>
|
||||
<v-btn prepend-icon="mdi-delete" class="gacha-top-btn" @click="deleteGacha()">删除</v-btn>
|
||||
<v-btn class="gacha-top-btn" prepend-icon="mdi-delete" @click="deleteGacha()">删除</v-btn>
|
||||
<v-btn class="gacha-top-btn" prepend-icon="mdi-delete" @click="checkData()">检测数据</v-btn>
|
||||
</div>
|
||||
</template>
|
||||
</v-app-bar>
|
||||
@@ -49,22 +50,22 @@
|
||||
<v-tab value="table">数据表格</v-tab>
|
||||
<v-tab value="history">过往祈愿</v-tab>
|
||||
<!-- TODO: 暂时隐藏内置祈愿链接 -->
|
||||
<v-tab value="iframe" v-if="false">祈愿详情</v-tab>
|
||||
<v-tab v-if="false" value="iframe">祈愿详情</v-tab>
|
||||
</v-tabs>
|
||||
<v-window v-model="tab" class="gacha-window">
|
||||
<v-window-item value="overview" class="gacha-window-item">
|
||||
<v-window-item class="gacha-window-item" value="overview">
|
||||
<gro-overview v-model="gachaListCur" />
|
||||
</v-window-item>
|
||||
<v-window-item value="echarts" class="gacha-window-item">
|
||||
<gro-echarts :uid="uidCur" v-if="uidCur" />
|
||||
<v-window-item class="gacha-window-item" value="echarts">
|
||||
<gro-echarts v-if="uidCur" :uid="uidCur" />
|
||||
</v-window-item>
|
||||
<v-window-item value="table" class="gacha-window-item">
|
||||
<v-window-item class="gacha-window-item" value="table">
|
||||
<gro-table v-model="gachaListCur" />
|
||||
</v-window-item>
|
||||
<v-window-item value="history" class="gacha-window-item">
|
||||
<v-window-item class="gacha-window-item" value="history">
|
||||
<gro-history />
|
||||
</v-window-item>
|
||||
<v-window-item value="iframe" class="gacha-window-item">
|
||||
<v-window-item class="gacha-window-item" value="iframe">
|
||||
<gro-iframe mode="normal" />
|
||||
</v-window-item>
|
||||
</v-window>
|
||||
@@ -88,6 +89,7 @@ import TSUserGacha from "@Sqlm/userGacha.js";
|
||||
import useUserStore from "@store/user.js";
|
||||
import { path } from "@tauri-apps/api";
|
||||
import { open, save } from "@tauri-apps/plugin-dialog";
|
||||
import Hakushi from "@utils/Hakushi.js";
|
||||
import TGLogger from "@utils/TGLogger.js";
|
||||
import { exportUigfData, readUigfData, verifyUigfData } from "@utils/UIGF.js";
|
||||
import { storeToRefs } from "pinia";
|
||||
@@ -108,9 +110,12 @@ const ovShow = ref<boolean>(false);
|
||||
const ovMode = ref<"export" | "import">("import");
|
||||
const selectItem = shallowRef<Array<string>>([]);
|
||||
const gachaListCur = shallowRef<Array<TGApp.Sqlite.GachaRecords.TableGacha>>([]);
|
||||
const hakushiData = shallowRef<Array<TGApp.Plugins.Hakushi.ConvertData>>([]);
|
||||
|
||||
onMounted(async () => {
|
||||
await showLoading.start("正在加载祈愿数据", "正在获取祈愿 UID 列表");
|
||||
await showLoading.start("正在加载祈愿数据", "正在获取Hakushi元数据");
|
||||
hakushiData.value = await Hakushi.fetch();
|
||||
await showLoading.update("正在获取祈愿 UID 列表");
|
||||
await TGLogger.Info("[UserGacha][onMounted] 进入角色祈愿页面");
|
||||
selectItem.value = await TSUserGacha.getUidList();
|
||||
if (selectItem.value.length === 0) {
|
||||
@@ -259,6 +264,16 @@ async function refreshGachaPool(
|
||||
const find = AppWeaponData.find((weapon) => weapon.name === item.name);
|
||||
if (find) tempItem.item_id = find.id.toString();
|
||||
}
|
||||
if (tempItem.item_id === "") {
|
||||
const find = hakushiData.value.find(
|
||||
(i) => i.type === item.item_type && i.name === item.name,
|
||||
);
|
||||
if (find) tempItem.item_id = find.id.toString();
|
||||
else {
|
||||
showSnackbar.warn(`无法搜索到 ${item.item_type} ${item.name} 的ID,请等待元数据更新`);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
uigfList.push(tempItem);
|
||||
if (force) {
|
||||
if (!gachaDataMap) gachaDataMap = {};
|
||||
@@ -388,6 +403,11 @@ async function deleteGacha(): Promise<void> {
|
||||
await new Promise<void>((resolve) => setTimeout(resolve, 1500));
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
async function checkData(): Promise<void> {
|
||||
// TODO: 读取当前UID数据并补充itemId
|
||||
showSnackbar.warn("尚未实现");
|
||||
}
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.gacha-top-title {
|
||||
|
||||
90
src/types/Plugins/Hakushi.d.ts
vendored
Normal file
90
src/types/Plugins/Hakushi.d.ts
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* Hakushi插件相关类型
|
||||
* @since Beta v0.9.0
|
||||
*/
|
||||
|
||||
declare namespace TGApp.Plugins.Hakushi {
|
||||
/**
|
||||
* 武器JSON返回
|
||||
* @since Beta v0.9.0
|
||||
* @remarks https://api.hakush.in/gi/data/weapon.json
|
||||
*/
|
||||
type WeaponResp = Record<string, WeaponBrief>;
|
||||
|
||||
/**
|
||||
* 角色JSON返回
|
||||
* @since Beta v0.9.0
|
||||
* @remarks https://api.hakush.in/gi/data/character.json
|
||||
*/
|
||||
type AvatarResp = Record<string, AvatarBrief>;
|
||||
|
||||
/**
|
||||
* 武器信息
|
||||
* @since Beta v0.9.0
|
||||
*/
|
||||
type WeaponBrief = {
|
||||
/** 图标 */
|
||||
icon: string;
|
||||
/** 稀有度 */
|
||||
rank: number;
|
||||
/**
|
||||
* 类型
|
||||
* @remarks 枚举
|
||||
* - WEAPON_BOW 弓
|
||||
*/
|
||||
type: string;
|
||||
/** 英文译名 */
|
||||
EN: string;
|
||||
/** 描述(英文) */
|
||||
desc: string;
|
||||
/** 韩文译名 */
|
||||
KR: string;
|
||||
/** 中文译名 */
|
||||
CHS: string;
|
||||
/** 日文译名 */
|
||||
JP: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* 角色信息
|
||||
* @since Beta v0.9.0
|
||||
*/
|
||||
type AvatarBrief = {
|
||||
/** 生日 */
|
||||
birth: Array<number> & { length: 2 };
|
||||
/** 图标 */
|
||||
icon: string;
|
||||
/** 稀有度 */
|
||||
rank: number;
|
||||
/**
|
||||
* 武器类型
|
||||
* @remarks 枚举
|
||||
* - WEAPON_BOW 弓
|
||||
*/
|
||||
weapon: string;
|
||||
/** 上线时间 */
|
||||
release: string;
|
||||
/** 元素 */
|
||||
element: string;
|
||||
/** 英文译名 */
|
||||
EN: string;
|
||||
/** 描述(英文) */
|
||||
desc: string;
|
||||
/** 韩文译名 */
|
||||
KR: string;
|
||||
/** 中文译名 */
|
||||
CHS: string;
|
||||
/** 日文译名 */
|
||||
JP: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* 转换后的数据
|
||||
* @since Beta v0.9.0
|
||||
*/
|
||||
type ConvertData = {
|
||||
id: string;
|
||||
name: string;
|
||||
type: "武器" | "角色";
|
||||
};
|
||||
}
|
||||
52
src/utils/Hakushi.ts
Normal file
52
src/utils/Hakushi.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Hakushi 插件入口
|
||||
* @since Beta v0.9.0
|
||||
*/
|
||||
import TGHttp from "@utils/TGHttp.js";
|
||||
|
||||
const HAKUSHI_API = "https://api.hakush.in/gi/data/";
|
||||
|
||||
/**
|
||||
* 请求角色数据
|
||||
* @since Beta v0.9.0
|
||||
* @returns {Promise<TGApp.Plugins.Hakushi.AvatarResp>}
|
||||
*/
|
||||
async function fetchAvatar(): Promise<TGApp.Plugins.Hakushi.AvatarResp> {
|
||||
return await TGHttp<TGApp.Plugins.Hakushi.AvatarResp>(`${HAKUSHI_API}character.json`, {
|
||||
method: "GET",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求武器数据
|
||||
* @since Beta v0.9.0
|
||||
* @returns {Promise<TGApp.Plugins.Hakushi.WeaponResp>}
|
||||
*/
|
||||
async function fetchWeapon(): Promise<TGApp.Plugins.Hakushi.WeaponResp> {
|
||||
return await TGHttp<TGApp.Plugins.Hakushi.WeaponResp>(`${HAKUSHI_API}weapon.json`, {
|
||||
method: "GET",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换数据
|
||||
* @since Beta v0.9.0
|
||||
*/
|
||||
async function fetchJson(): Promise<Array<TGApp.Plugins.Hakushi.ConvertData>> {
|
||||
const jsonW = await fetchWeapon();
|
||||
const jsonA = await fetchAvatar();
|
||||
const res: Array<TGApp.Plugins.Hakushi.ConvertData> = [];
|
||||
for (const [id, data] of Object.entries(jsonW)) {
|
||||
res.push({ id: id.toString(), name: data.CHS, type: "武器" });
|
||||
}
|
||||
for (const [id, data] of Object.entries(jsonA)) {
|
||||
res.push({ id: id.toString(), name: data.CHS, type: "角色" });
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
const Hakushi = {
|
||||
fetch: fetchJson,
|
||||
};
|
||||
|
||||
export default Hakushi;
|
||||
Reference in New Issue
Block a user