嵌入祈愿详情

This commit is contained in:
BTMuli
2025-10-25 19:27:50 +08:00
parent 6db4ff5ac9
commit babc6a9a75
11 changed files with 239 additions and 49 deletions

View File

@@ -20,7 +20,7 @@ import { computed } from "vue";
import { AppGachaData } from "@/data/index.js";
export type GroDataLineProps = { data: TGApp.Sqlite.GachaRecords.SingleTable; count: number };
export type GroDataLineProps = { data: TGApp.Sqlite.GachaRecords.TableGacha; count: number };
const props = defineProps<GroDataLineProps>();
const hint = getEndHint();

View File

@@ -64,7 +64,7 @@ import GroDataLine, { type GroDataLineProps } from "./gro-data-line.vue";
type GachaDataViewProps = {
dataType: "new" | "avatar" | "weapon" | "normal" | "mix";
dataVal: Array<TGApp.Sqlite.GachaRecords.SingleTable>;
dataVal: Array<TGApp.Sqlite.GachaRecords.TableGacha>;
};
const props = defineProps<GachaDataViewProps>();

View File

@@ -0,0 +1,128 @@
<!-- 嵌入游戏内容的iframe组件 -->
<template>
<div class="gro-iframe-container">
<v-tabs class="gro-ic-tabs" v-model="poolTab" align-tabs="start" direction="vertical">
<v-tab v-for="(item, index) in tabList" :key="index" :value="item.value">
<template v-if="item.beyond">
<img src="/icon/nation/千星奇域.webp" title="千星奇域" alt="beyond" />
</template>
{{ item.label }}
</v-tab>
</v-tabs>
<iframe class="gro-iframe" :src="link" style="width: 100%; height: 100%; border: none" />
</div>
</template>
<script lang="ts" setup>
import showSnackbar from "@comp/func/snackbar.js";
import takumiReq from "@req/takumiReq.js";
import useUserStore from "@store/user.js";
import { storeToRefs } from "pinia";
import { onMounted, ref, shallowRef, watch } from "vue";
/**
* 卡池类型-ID映射
* @remarks
* 目前缺失集录&新手池
* TODO: 动态获取当前卡池类型&ID映射
*/
const GachaIdMap: Record<string, string> = {
"200": "34ff1a235049182fd199d285110e3e7d292c50cd", // 常驻
"301": "182e725d99b742b14839117650d3e79628cc6221", //角色活动
"302": "8ff7a7d42bea79b0d54e92fdb58a20f971490372", // 武器活动
"400": "bb0486115a7e7c4bd2994135f7d212014b17173b", // 角色活动-2
"1000": "f3f5090a8ec0b28f15805c9969aa6c4ec357", // 千星奇域常驻
"20011": "a8d0a985efb4ed61eb2e73a86a57237bd116", // 千星奇域角色活动-男
"20021": "57016dec6b768231ba1342c01935417a799b", // 千星奇域角色活动-女
};
type GroTabKey = keyof typeof GachaIdMap;
type GroTab = { label: string; value: string; beyond?: boolean };
const { cookie, account } = storeToRefs(useUserStore());
const authkey = ref<string>("");
const link = ref<string>("");
const poolTab = ref<GroTabKey>("200");
const tabList = shallowRef<ReadonlyArray<GroTab>>([
{ label: "常驻祈愿", value: "200" },
{ label: "角色活动祈愿", value: "301" },
{ label: "武器活动祈愿", value: "302" },
{ label: "角色活动祈愿-2", value: "400" },
{ label: "常驻颂愿", value: "1000", beyond: true },
{ label: "活动颂愿-男", value: "20011", beyond: true },
{ label: "活动颂愿-女", value: "20021", beyond: true },
]);
onMounted(async () => {
link.value = await getUrl();
});
watch(
() => poolTab.value,
async () => {
link.value = await getUrl();
},
);
async function getUrl(): Promise<string> {
const path = "https://webstatic.mihoyo.com/hk4e/event/e20190909gacha-v3/index.html";
const pathB = "https://webstatic.mihoyo.com/hk4e/event/e20250716gacha/index.html";
const pathF = poolTab.value.length < 4 ? path : pathB;
if (authkey.value === "") await refreshAuthkey();
const param: Record<string, string> = {
win_mode: "fullscreen",
no_joypad_close: "1",
authkey_ver: "1",
sign_type: "2",
auth_appid: "webview_gacha",
gacha_id: GachaIdMap[poolTab.value],
timestamp: Math.floor(Date.now() / 1000).toString(),
lang: "zh-cn",
device_type: "pc",
region: account.value.region,
authkey: authkey.value,
game_biz: account.value.gameBiz,
};
const targetLink = new URL(pathF);
for (const key in param) {
targetLink.searchParams.append(key, param[key]);
}
return targetLink.toString();
}
async function refreshAuthkey(): Promise<void> {
if (!cookie.value || !account.value) {
return;
}
const authkeyRes = await takumiReq.bind.authKey(cookie.value, account.value);
if (typeof authkeyRes === "string") {
authkey.value = authkeyRes;
} else {
showSnackbar.error("获取authkey失败");
return;
}
}
</script>
<style lang="scss" scoped>
.gro-iframe-container {
display: flex;
width: 100%;
height: 100%;
align-items: center;
justify-content: space-between;
}
.gro-ic-tabs {
height: 100%;
img {
width: 24px;
height: 24px;
margin-right: 4px;
}
}
.gro-ic-window {
height: 100%;
flex: 1;
}
</style>

View File

@@ -12,22 +12,22 @@ import { computed, ref, watch } from "vue";
import GroDataView from "./gro-data-view.vue";
type GachaOverviewProps = { modelValue: Array<TGApp.Sqlite.GachaRecords.SingleTable> };
type GachaOverviewProps = { modelValue: Array<TGApp.Sqlite.GachaRecords.TableGacha> };
const props = defineProps<GachaOverviewProps>();
const newData = computed<Array<TGApp.Sqlite.GachaRecords.SingleTable>>(() =>
const newData = computed<Array<TGApp.Sqlite.GachaRecords.TableGacha>>(() =>
props.modelValue.filter((item) => item.uigfType === "100"),
);
const normalData = computed<Array<TGApp.Sqlite.GachaRecords.SingleTable>>(() =>
const normalData = computed<Array<TGApp.Sqlite.GachaRecords.TableGacha>>(() =>
props.modelValue.filter((item) => item.uigfType === "200"),
);
const avatarData = computed<Array<TGApp.Sqlite.GachaRecords.SingleTable>>(() =>
const avatarData = computed<Array<TGApp.Sqlite.GachaRecords.TableGacha>>(() =>
props.modelValue.filter((item) => item.uigfType === "301"),
);
const weaponData = computed<Array<TGApp.Sqlite.GachaRecords.SingleTable>>(() =>
const weaponData = computed<Array<TGApp.Sqlite.GachaRecords.TableGacha>>(() =>
props.modelValue.filter((item) => item.uigfType === "302"),
);
const mixData = computed<Array<TGApp.Sqlite.GachaRecords.SingleTable>>(() =>
const mixData = computed<Array<TGApp.Sqlite.GachaRecords.TableGacha>>(() =>
props.modelValue.filter((item) => item.uigfType === "500"),
);
@@ -56,7 +56,7 @@ watch(
.gro-o-container {
display: grid;
height: 100%;
grid-column-gap: 8px;
column-gap: 8px;
grid-template-columns: v-bind(cnCols); /* stylelint-disable-line value-keyword-case */
}
</style>

View File

@@ -19,7 +19,7 @@
</v-data-table>
</template>
<script lang="ts" setup>
type GroTableProps = { modelValue: Array<TGApp.Sqlite.GachaRecords.SingleTable> };
type GroTableProps = { modelValue: Array<TGApp.Sqlite.GachaRecords.TableGacha> };
const props = defineProps<GroTableProps>();

View File

@@ -161,7 +161,7 @@ async function handleExportData(): Promise<void> {
data.value = tmpData;
}
function parseDataRaw(data: TGApp.Sqlite.GachaRecords.SingleTable[]): UgoUidItem {
function parseDataRaw(data: TGApp.Sqlite.GachaRecords.TableGacha[]): UgoUidItem {
const timeList = data.map((item) => new Date(item.time).getTime());
return {
uid: data[0].uid,