♻️ 组件抽离,优化逻辑

This commit is contained in:
目棃
2025-01-09 11:15:35 +08:00
parent b867c008ae
commit 72a9408d38
5 changed files with 264 additions and 272 deletions

View File

@@ -17,10 +17,10 @@
</div>
</template>
<script lang="ts" setup>
import TSUserGacha from "@Sqlite/modules/userGacha.js";
import { computed } from "vue";
import { AppGachaData } from "@/data/index.js";
import { getWikiBrief } from "@/utils/toolFunc.js";
export type GroDataLineProps = { data: TGApp.Sqlite.GachaRecords.SingleTable; count: number };
@@ -28,10 +28,10 @@ const props = defineProps<GroDataLineProps>();
const hint = getEndHint();
function getIcon(): string {
const itemType = TSUserGacha.getGachaItemType(props.data.itemId);
if (itemType[0] === "角色") return `/WIKI/character/${props.data.itemId}.webp`;
if (itemType[0] === "武器") return `/WIKI/weapon/${props.data.itemId}.webp`;
return `/source/UI/paimon.webp`;
const find = getWikiBrief(props.data.itemId);
if (!find) return `/source/UI/paimon.webp`;
if (props.data.id.length === 5) return `/WIKI/weapon/${props.data.itemId}.webp`;
return `/WIKI/character/${props.data.itemId}.webp`;
}
function getEndHint(): string {

View File

@@ -12,59 +12,22 @@
:value="item.tab"
class="gro-pools"
>
<div v-for="pool in item.value" :key="pool.order" class="gro-pool">
<img
:src="pool.banner"
class="gro-banner"
alt="banner"
@click="createPost(pool.postId)"
/>
<div class="gro-pool-info">
<div class="gro-pi-title">
<span>{{ pool.name }}</span>
<span class="gro-pi-tag">{{ pool.order === 1 ? "上半" : "下半" }}</span>
<span class="gro-pi-tag">{{ getType(pool.type) }}</span>
</div>
<div class="gro-pi-time">{{ getTimeStr(pool) }}</div>
<div class="gro-pi-sub">Up 五星</div>
<div class="gro-pool-up lv5">
<TItemBox
v-for="i in pool.up5List"
:key="i"
:model-value="getBox(i)"
@click="toWiki(i)"
/>
</div>
<div class="gro-pi-sub">Up 四星</div>
<div class="gro-pool-up lv4">
<TItemBox
v-for="i in pool.up4List"
:key="i"
:model-value="getBox(i)"
@click="toWiki(i)"
/>
</div>
</div>
</div>
<UgHisCard v-for="pool in item.value" :key="pool.order" :pool="pool" />
</v-window-item>
</v-window>
</div>
</template>
<script lang="ts" setup>
import TItemBox, { type TItemBoxData } from "@comp/app/t-itemBox.vue";
import showSnackbar from "@comp/func/snackbar.js";
import { onMounted, ref, shallowRef } from "vue";
import { useRouter } from "vue-router";
import { AppCharacterData, AppGachaData, AppWeaponData } from "@/data/index.js";
import { createPost } from "@/utils/TGWindow.js";
import { timestampToDate } from "@/utils/toolFunc.js";
import UgHisCard from "./ug-his-card.vue";
import { AppGachaData } from "@/data/index.js";
type GroHistoryMap = { tab: string; value: Array<TGApp.App.Gacha.PoolItem> };
const historyTab = ref<string>("");
const tabList = shallowRef<Array<GroHistoryMap>>([]);
const router = useRouter();
onMounted(() => {
const res: Array<GroHistoryMap> = [];
@@ -79,87 +42,6 @@ onMounted(() => {
tabList.value = res.reverse();
historyTab.value = res[0].tab;
});
async function toWiki(id: number): Promise<void> {
const cFind = AppCharacterData.find((item) => item.id === id);
const wFind = AppWeaponData.find((item) => item.id === id);
if (cFind) {
await router.push({ name: "角色图鉴", params: { id: id.toString() } });
return;
}
if (wFind) {
await router.push({ name: "武器图鉴", params: { id: id.toString() } });
return;
}
showSnackbar.warn("未找到对应角色或武器");
}
function getType(type: TGApp.App.Gacha.WishType): string {
switch (type) {
case 301:
return "角色活动祈愿";
case 400:
return "角色活动祈愿2";
case 302:
return "武器活动祈愿";
case 500:
return "集录祈愿";
default:
return `未知类型 ${type}`;
}
}
function getTimeStr(pool: TGApp.App.Gacha.PoolItem): string {
const startTime = timestampToDate(Date.parse(pool.from));
const endTime = timestampToDate(Date.parse(pool.to));
return `${startTime} ~ ${endTime}`;
}
function getBox(id: number): TItemBoxData {
const cFind = AppCharacterData.find((item) => item.id === id);
const wFind = AppWeaponData.find((item) => item.id === id);
if (cFind) {
return {
bg: `/icon/bg/${cFind.star}-Star.webp`,
icon: `/WIKI/character/${cFind.id}.webp`,
size: "80px",
height: "80px",
display: "inner",
clickable: true,
lt: `/icon/element/${cFind.element}元素.webp`,
ltSize: "20px",
innerHeight: 20,
innerIcon: `/icon/weapon/${cFind.weapon}.webp`,
innerText: cFind.name,
};
}
if (wFind) {
return {
bg: `/icon/bg/${wFind.star}-Star.webp`,
icon: `/WIKI/weapon/${wFind.id}.webp`,
size: "80px",
height: "80px",
display: "inner",
clickable: true,
lt: `/icon/weapon/${wFind.weapon}.webp`,
ltSize: "20px",
innerHeight: 20,
innerText: wFind.name,
};
}
return {
bg: "/icon/bg/0-Star.webp",
icon: "/source/UI/empty/webp",
size: "80px",
height: "80px",
display: "inner",
clickable: false,
lt: "",
ltSize: "0",
innerHeight: 20,
innerText: "未找到对应角色或武器",
};
}
</script>
<style lang="css" scoped>
.gro-container {
@@ -207,81 +89,4 @@ function getBox(id: number): TItemBoxData {
justify-content: center;
row-gap: 10px;
}
.gro-pool {
position: relative;
display: flex;
width: 100%;
align-items: flex-start;
justify-content: flex-start;
padding: 10px;
border-radius: 10px;
background: var(--box-bg-2);
column-gap: 10px;
}
.gro-banner {
width: 50vw;
border-radius: 10px;
cursor: pointer;
transition: 0.5s ease-in-out;
}
.gro-banner:hover {
box-shadow: 0 0 10px 5px var(--box-bg-2);
scale: 0.95;
transition: 0.5s ease-in-out;
}
.gro-pool-info {
display: flex;
height: 100%;
flex-direction: column;
align-items: flex-start;
justify-content: flex-start;
}
.gro-pi-title {
display: flex;
column-gap: 10px;
}
.gro-pi-title :first-child {
color: var(--common-text-title);
font-family: var(--font-title);
font-size: 20px;
}
.gro-pi-tag {
display: flex;
align-items: center;
justify-content: center;
padding: 0 5px;
border-radius: 5px;
background: var(--box-bg-1);
color: var(--box-text-5);
font-size: 16px;
}
.gro-pi-sub {
font-family: var(--font-title);
font-size: 18px;
}
.gro-pool-up {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: flex-start;
gap: 10px;
overflow-y: auto;
}
.gro-pool-up.lv5 {
max-height: 80px;
}
.gro-pool-up.lv4 {
max-height: 170px;
}
</style>

View File

@@ -0,0 +1,206 @@
<template>
<div class="user-gacha-history-card-comp">
<img
class="ug-his-banner"
:src="props.pool.banner"
alt="banner"
@click="createPost(pool.postId)"
/>
<div class="ug-his-info">
<div class="ug-his-title">
<span>{{ props.pool.name }}</span>
<span class="ug-his-tag">{{ props.pool.order === 1 ? "上半" : "下半" }}</span>
<span class="ug-his-tag">{{ getType(props.pool.type) }}</span>
</div>
<div class="ug-his-time">{{ getTimeStr(props.pool) }}</div>
<div class="ug-his-sub">Up 五星</div>
<div class="ug-his-up lv5">
<TItemBox
v-for="i in props.pool.up5List"
:key="i"
:model-value="getBox(i)"
@click="toWiki(i)"
/>
</div>
<div class="ug-his-sub">Up 四星</div>
<div class="ug-his-up lv4">
<TItemBox
v-for="i in props.pool.up4List"
:key="i"
:model-value="getBox(i)"
@click="toWiki(i)"
/>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import TItemBox, { type TItemBoxData } from "@comp/app/t-itemBox.vue";
import showSnackbar from "@comp/func/snackbar.js";
import { useRouter } from "vue-router";
import { createPost } from "@/utils/TGWindow.js";
import { getWikiBrief, timestampToDate } from "@/utils/toolFunc.js";
type UgHisCardProps = { pool: TGApp.App.Gacha.PoolItem };
const router = useRouter();
const props = defineProps<UgHisCardProps>();
async function toWiki(id: number): Promise<void> {
const find = getWikiBrief(id);
if (!find) {
showSnackbar.warn("未找到对应角色或武器");
return;
}
if ("element" in find) {
await router.push({ name: "角色图鉴", params: { id: id.toString() } });
return;
}
await router.push({ name: "武器图鉴", params: { id: id.toString() } });
}
function getType(type: TGApp.App.Gacha.WishType): string {
switch (type) {
case 301:
return "角色活动祈愿";
case 400:
return "角色活动祈愿2";
case 302:
return "武器活动祈愿";
case 500:
return "集录祈愿";
default:
return `未知类型 ${type}`;
}
}
function getTimeStr(pool: TGApp.App.Gacha.PoolItem): string {
const startTime = timestampToDate(Date.parse(pool.from));
const endTime = timestampToDate(Date.parse(pool.to));
return `${startTime} ~ ${endTime}`;
}
function getBox(id: number): TItemBoxData {
const bFind = getWikiBrief(id);
if (!bFind) {
return {
bg: "/icon/bg/0-Star.webp",
icon: "/source/UI/empty/webp",
size: "80px",
height: "80px",
display: "inner",
clickable: false,
lt: "",
ltSize: "0",
innerHeight: 20,
innerText: "未找到对应角色或武器",
};
}
if ("element" in bFind) {
return {
bg: `/icon/bg/${bFind.star}-Star.webp`,
icon: `/WIKI/character/${bFind.id}.webp`,
size: "80px",
height: "80px",
display: "inner",
clickable: true,
lt: `/icon/element/${bFind.element}元素.webp`,
ltSize: "20px",
innerHeight: 20,
innerIcon: `/icon/weapon/${bFind.weapon}.webp`,
innerText: bFind.name,
};
}
return {
bg: `/icon/bg/${bFind.star}-Star.webp`,
icon: `/WIKI/weapon/${bFind.id}.webp`,
size: "80px",
height: "80px",
display: "inner",
clickable: true,
lt: `/icon/weapon/${bFind.weapon}.webp`,
ltSize: "20px",
innerHeight: 20,
innerText: bFind.name,
};
}
</script>
<style lang="scss" scoped>
.user-gacha-history-card-comp {
position: relative;
display: flex;
width: 100%;
align-items: flex-start;
justify-content: flex-start;
padding: 10px;
border-radius: 10px;
background: var(--box-bg-2);
column-gap: 10px;
}
.ug-his-banner {
width: 50vw;
border-radius: 10px;
cursor: pointer;
transition: 0.5s ease-in-out;
&:hover {
box-shadow: 0 0 10px 5px var(--box-bg-2);
scale: 0.95;
transition: 0.5s ease-in-out;
}
}
.ug-his-info {
display: flex;
height: 100%;
flex-direction: column;
align-items: flex-start;
justify-content: flex-start;
}
.ug-his-title {
display: flex;
column-gap: 10px;
:first-child {
color: var(--common-text-title);
font-family: var(--font-title);
font-size: 20px;
}
}
.ug-his-tag {
display: flex;
align-items: center;
justify-content: center;
padding: 0 5px;
border-radius: 5px;
background: var(--box-bg-1);
color: var(--box-text-5);
font-size: 16px;
}
.ug-his-sub {
font-family: var(--font-title);
font-size: 18px;
}
.ug-his-up {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: flex-start;
gap: 10px;
overflow-y: auto;
&.lv5 {
max-height: 80px;
}
&.lv4 {
max-height: 170px;
}
}
</style>

View File

@@ -1,7 +1,7 @@
/**
* @file plugins/Sqlite/modules/userGacha.ts
* @description 用户祈愿模块
* @since Beta v0.6.0
* @since Beta v0.6.8
*/
import showSnackbar from "@comp/func/snackbar.js";
@@ -9,29 +9,10 @@ import TGSqlite from "@Sqlite/index.js";
import { path } from "@tauri-apps/api";
import { exists, mkdir, readDir } from "@tauri-apps/plugin-fs";
import { AppCharacterData, AppWeaponData } from "@/data/index.js";
import TGLogger from "@/utils/TGLogger.js";
import { getWikiBrief } from "@/utils/toolFunc.js";
import { exportUigfData, readUigfData, verifyUigfData } from "@/utils/UIGF.js";
type gachaItemTypeRes =
| ["角色", TGApp.App.Character.WikiBriefInfo]
| ["武器", TGApp.App.Weapon.WikiBriefInfo]
| ["未知", "未知"];
/**
* @description 根据 item_id 获取角色/武器类型
* @since Beta v0.4.7
* @param {string} item_id - item_id
* @return {gachaItemTypeRes}
*/
function getGachaItemType(item_id: string): gachaItemTypeRes {
const findAvatar = AppCharacterData.find((i) => i.id.toString() === item_id);
if (findAvatar !== undefined) return ["角色", findAvatar];
const findWeapon = AppWeaponData.find((i) => i.id.toString() === item_id);
if (findWeapon !== undefined) return ["武器", findWeapon];
return ["未知", "未知"];
}
/**
* @description 获取导入 Sql
* @since Beta v.6.0
@@ -44,9 +25,9 @@ function getInsertSql(uid: string, gacha: TGApp.Plugins.UIGF.GachaItem): string
INSERT INTO GachaRecords (uid, gachaType, itemId, count, time, name, type, rank, id, uigfType, updated)
VALUES ('${uid}', '${gacha.gacha_type}', '${gacha.item_id ?? null}', '${gacha.count ?? null}', '${gacha.time}',
'${gacha.name}', '${gacha.item_type ?? null}', '${gacha.rank_type ?? null}', '${gacha.id}',
'${gacha.uigf_gacha_type}', datetime('now', 'localtime')) ON CONFLICT (id)
DO
UPDATE
'${gacha.uigf_gacha_type}', datetime('now', 'localtime'))
ON CONFLICT (id)
DO UPDATE
SET uid = '${uid}',
gachaType = '${gacha.gacha_type}',
uigfType = '${gacha.uigf_gacha_type}',
@@ -62,42 +43,24 @@ function getInsertSql(uid: string, gacha: TGApp.Plugins.UIGF.GachaItem): string
/**
* @description 转换祈愿数据,防止多语言
* @since Beta v0.5.1
* @since Beta v0.6.8
* @param {TGApp.Plugins.UIGF.GachaItem} gacha - UIGF数据
* @return {TGApp.Plugins.UIGF.GachaItem} 转换后的数据
*/
function transGacha(gacha: TGApp.Plugins.UIGF.GachaItem): TGApp.Plugins.UIGF.GachaItem {
const type = getGachaItemType(gacha.item_id);
let res = gacha;
res.item_type = type[0];
if (type[0] === "角色") {
const data: TGApp.App.Character.WikiBriefInfo = type[1];
res = {
const find = getWikiBrief(gacha.item_id);
if (!find) return gacha;
return {
gacha_type: gacha.gacha_type,
item_id: gacha.item_id,
count: gacha.count ?? "1",
time: gacha.time,
name: data.name,
item_type: "角色",
rank_type: data.star.toString(),
name: find.name,
item_type: "element" in find ? "角色" : "武器",
rank_type: find.star.toString(),
id: gacha.id,
uigf_gacha_type: gacha.uigf_gacha_type,
};
} else if (type[0] === "武器") {
const data: TGApp.App.Weapon.WikiBriefInfo = type[1];
res = {
gacha_type: gacha.gacha_type,
item_id: gacha.item_id,
count: gacha.count ?? "1",
time: gacha.time,
name: data.name,
item_type: "武器",
rank_type: data.star.toString(),
id: gacha.id,
uigf_gacha_type: gacha.uigf_gacha_type,
};
}
return res;
}
/**
@@ -273,7 +236,6 @@ const TSUserGacha = {
getUidList,
getGachaCheck,
getGachaRecords,
getGachaItemType,
deleteGachaRecords,
cleanGachaRecords,
mergeUIGF,

View File

@@ -1,7 +1,7 @@
/**
* @file utils/toolFunc.ts
* @description 一些工具函数
* @since Beta v0.6.7
* @since Beta v0.6.8
*/
import { path } from "@tauri-apps/api";
@@ -11,6 +11,7 @@ import type { KEYWORD } from "color-convert/conversions.js";
import { v4 } from "uuid";
import { score } from "wcag-color";
import { AppCharacterData, AppWeaponData } from "@/data/index.js";
import TGConstant from "@/web/constant/TGConstant.js";
/**
@@ -274,6 +275,7 @@ export function decodeRegExp(data: string): string {
/**
* @description 根据 gid 获取游戏名称
* @since Beta v0.6.7
* @param {number} gid
* @returns {string}
*/
@@ -284,6 +286,7 @@ export function getGameName(gid: number): string {
/**
* @description 获取游戏id
* @since Beta v0.6.7
* @param {string} mini
* @returns {string}
*/
@@ -291,3 +294,19 @@ export function getGameId(mini: string): string {
const game = TGConstant.BBS.CHANNELS.find((item) => item.mini === mini);
return game ? game.gid : "0";
}
/**
* @description 根据id获取对应角色/武器数据
* @since Beta v0.6.8
* @param {number|string} id
* @returns {TGApp.App.Character.WikiBriefInfo|TGApp.App.Weapon.WikiBriefInfo}
*/
export function getWikiBrief(
id: number | string,
): TGApp.App.Character.WikiBriefInfo | TGApp.App.Weapon.WikiBriefInfo | false {
const len = id.toString().length;
if (len === 5) {
return AppWeaponData.find((item) => item.id.toString() === id.toString()) ?? false;
}
return AppCharacterData.find((item) => item.id.toString() === id.toString()) ?? false;
}