mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2025-12-13 09:28:14 +08:00
🎨 refactor(UIAF): 目录结构优化
This commit is contained in:
@@ -107,13 +107,10 @@ import TLoading from "../components/t-loading.vue";
|
||||
import { dialog, fs } from "@tauri-apps/api";
|
||||
// Store
|
||||
import { useAchievementsStore } from "../store/modules/achievements";
|
||||
// Interface
|
||||
import { Achievements, UiafHeader, UiafAchievement } from "../plugins/UIAF/interface/UIAF";
|
||||
// Plugins
|
||||
import UiafOper from "../plugins/UIAF";
|
||||
// Utils
|
||||
import { createTGWindow } from "../utils/TGWindow";
|
||||
import { ReadAllTGData, ReadTGDataByIndex, ReadTGDataByKey, UpdateTGDataByKey } from "../utils/TGIndex";
|
||||
import { getHeader, readUIAF, verifyUIAF } from "../utils/UIAF";
|
||||
|
||||
// Store
|
||||
const achievementsStore = useAchievementsStore();
|
||||
@@ -124,8 +121,8 @@ const loadingTitle = ref("正在加载数据" as string);
|
||||
|
||||
// data
|
||||
const title = ref(achievementsStore.title as string);
|
||||
const CardsInfo = ref([] as BTMuli.Genshin.NameCard.NameCard[]);
|
||||
const getCardInfo = ref({} as BTMuli.Genshin.NameCard.NameCard);
|
||||
const CardsInfo = ref([] as BTMuli.Genshin.NameCard[]);
|
||||
const getCardInfo = ref({} as BTMuli.Genshin.NameCard);
|
||||
// series
|
||||
const seriesList = ref([] as BTMuli.Genshin.AchievementSeries[]);
|
||||
const selectedIndex = ref(-1 as number);
|
||||
@@ -178,11 +175,11 @@ async function selectSeries (index: number) {
|
||||
selectedIndex.value = index;
|
||||
selectedSeries.value = seriesList.value[index].id;
|
||||
loadingTitle.value = "正在查找对应的成就名片";
|
||||
let getCard: BTMuli.Genshin.NameCard.NameCard;
|
||||
let getCard: BTMuli.Genshin.NameCard;
|
||||
if (selectedSeries.value !== 0 && selectedSeries.value !== 17) {
|
||||
getCard = CardsInfo.value.find((card) => card.name === seriesList.value[index].card)!;
|
||||
} else {
|
||||
getCard = {} as BTMuli.Genshin.NameCard.NameCard;
|
||||
getCard = {} as BTMuli.Genshin.NameCard;
|
||||
}
|
||||
loadingTitle.value = "正在对成就数据进行排序";
|
||||
getAchievements.sort((a, b) => {
|
||||
@@ -250,8 +247,8 @@ async function importJson () {
|
||||
},
|
||||
],
|
||||
});
|
||||
if (selectedFile && (await UiafOper.checkUiafData(<string>selectedFile))) {
|
||||
const remoteRaw: string | false = await UiafOper.readUiafData(<string>selectedFile);
|
||||
if (selectedFile && (await verifyUIAF(<string>selectedFile))) {
|
||||
const remoteRaw: string | false = await readUIAF(<string>selectedFile);
|
||||
if (remoteRaw === false) {
|
||||
snackbarText.value = "读取 UIAF 数据失败,请检查文件是否符合规范";
|
||||
snackbar.value = true;
|
||||
@@ -259,7 +256,7 @@ async function importJson () {
|
||||
}
|
||||
loadingTitle.value = "正在解析数据";
|
||||
loading.value = true;
|
||||
const remoteData: Achievements = JSON.parse(remoteRaw);
|
||||
const remoteData: TGPlugin.UIAF.BaseData = JSON.parse(remoteRaw);
|
||||
loadingTitle.value = "正在合并成就数据";
|
||||
await Promise.allSettled(
|
||||
remoteData.list.map(async (data) => {
|
||||
@@ -335,12 +332,12 @@ async function exportJson () {
|
||||
const achievements = (await ReadAllTGData("Achievements")).filter((data) => {
|
||||
return data.progress !== 0 || data.completed === true;
|
||||
});
|
||||
const UIAF_DATA = {
|
||||
info: {} as UiafHeader,
|
||||
list: [] as UiafAchievement[],
|
||||
const UiafData = {
|
||||
info: await getHeader(),
|
||||
list: [] as TGPlugin.UIAF.Achievement[],
|
||||
};
|
||||
// 转换数据
|
||||
UIAF_DATA.list = achievements.map((data) => {
|
||||
UiafData.list = achievements.map((data) => {
|
||||
let status;
|
||||
// 计算点数但是没有完成
|
||||
if (data.progress !== 0 && data.completed === false) {
|
||||
@@ -361,7 +358,6 @@ async function exportJson () {
|
||||
status,
|
||||
};
|
||||
});
|
||||
UIAF_DATA.info = await UiafOper.getUiafInfo();
|
||||
const isSave = await dialog.save({
|
||||
filters: [
|
||||
{
|
||||
@@ -371,7 +367,7 @@ async function exportJson () {
|
||||
],
|
||||
});
|
||||
if (isSave) {
|
||||
await fs.writeTextFile(isSave, JSON.stringify(UIAF_DATA));
|
||||
await fs.writeTextFile(isSave, JSON.stringify(UiafData));
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
/**
|
||||
* @file plugins UIAF index.ts
|
||||
* @description UIAF plugin index
|
||||
* @author BTMuli<bt-muli@outlook.com>
|
||||
* @since Alpha v0.1.2
|
||||
*/
|
||||
|
||||
import { checkUiafData, readUiafData } from "./utils/importData";
|
||||
import { getUiafInfo } from "./utils/exportData";
|
||||
|
||||
const UiafOper = {
|
||||
checkUiafData,
|
||||
readUiafData,
|
||||
getUiafInfo,
|
||||
};
|
||||
|
||||
export default UiafOper;
|
||||
@@ -1,53 +0,0 @@
|
||||
/**
|
||||
* @file plugins UIAF interface UIAF.ts
|
||||
* @description UIAF interface
|
||||
* @author BTMuli<bt-muli@outlook.com>
|
||||
* @see https://github.com/DGP-Studio/Snap.Genshin.Docs/blob/main/docs/development/UIAF.md
|
||||
* @version v1.1
|
||||
* @since Alpha v0.1.2
|
||||
*/
|
||||
|
||||
/**
|
||||
* @interface Achievements
|
||||
* @description UIAF 成就数据
|
||||
* @property {UIAF_Info} info UIAF 头部信息
|
||||
* @property {UIAF_Achievement[]} list UIAF 成就列表
|
||||
* @returns {Achievements}
|
||||
*/
|
||||
export interface Achievements {
|
||||
info: UiafHeader
|
||||
list: UiafAchievement[]
|
||||
}
|
||||
|
||||
/**
|
||||
* @interface UiafHeader
|
||||
* @description UIAF 头部信息
|
||||
* @property {string} export_app 导出的应用名称
|
||||
* @property {number} export_timestamp 导出时间戳,正确时间戳得乘以 1000
|
||||
* @property {string} export_app_version 导出的应用版本
|
||||
* @property {string} uiaf_version UIAF 版本
|
||||
* @returns {UiafHeader}
|
||||
*/
|
||||
export interface UiafHeader {
|
||||
export_app: string
|
||||
export_timestamp: number
|
||||
export_app_version: string
|
||||
uiaf_version: string
|
||||
}
|
||||
|
||||
/**
|
||||
* @interface UiafAchievement
|
||||
* @since Alpha v0.1.2
|
||||
* @description UIAF 单个成就数据
|
||||
* @property {number} id 成就 ID
|
||||
* @property {number} timestamp 成就记录时间戳,正确时间戳得乘以 1000
|
||||
* @property {number} current 成就进度
|
||||
* @property {number} status 成就状态,0 为未完成,1 为已完成
|
||||
* @returns {UiafAchievement}
|
||||
*/
|
||||
export interface UiafAchievement {
|
||||
id: number
|
||||
timestamp: number
|
||||
current: number
|
||||
status: number
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
/**
|
||||
* @file plugins UIAF utils exportData.ts
|
||||
* @description UIAF export data utils
|
||||
* @author BTMuli<bt-muli@outlook.com>
|
||||
* @since Alpha v0.1.2
|
||||
*/
|
||||
|
||||
import { type UiafHeader } from "../interface/UIAF";
|
||||
import { app } from "@tauri-apps/api";
|
||||
|
||||
/**
|
||||
* @description 获取 UIAF 头部信息
|
||||
* @since Alpha v0.1.2
|
||||
* @returns {Promise<UiafHeader>}
|
||||
*/
|
||||
export async function getUiafInfo (): Promise<UiafHeader> {
|
||||
return {
|
||||
export_app: "Tauri.Genshin",
|
||||
export_timestamp: Math.floor(Date.now() / 1000),
|
||||
export_app_version: await app.getVersion(),
|
||||
uiaf_version: "v1.1",
|
||||
};
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/**
|
||||
* @file plugins UIAF utils importData.ts
|
||||
* @description UIAF import data utils
|
||||
* @author BTMuli<bt-muli@outlook.com>
|
||||
* @since Alpha v0.1.2
|
||||
*/
|
||||
|
||||
import { type UiafHeader } from "../interface/UIAF";
|
||||
import { fs } from "@tauri-apps/api";
|
||||
|
||||
/**
|
||||
* @description 检测是否存在 UIAF 数据
|
||||
* @description 粗略检测,不保证数据完整性
|
||||
* @since Alpha v0.1.2
|
||||
* @param {string} path - UIAF 数据路径
|
||||
* @returns {Promise<boolean>} 是否存在 UIAF 数据
|
||||
*/
|
||||
export async function checkUiafData (path: string): Promise<boolean> {
|
||||
const fileData: string = await fs.readTextFile(path);
|
||||
const UIAFData: UiafHeader = JSON.parse(fileData).info;
|
||||
return UIAFData.uiaf_version !== undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 读取 UIAF 数据
|
||||
* @since Alpha v0.1.2
|
||||
* @param {string} userPath - UIAF 数据路径
|
||||
* @returns {Promise<string|false>} UIAF 数据
|
||||
*/
|
||||
export async function readUiafData (userPath: string): Promise<string | false> {
|
||||
if (await fs.exists(userPath)) {
|
||||
const fileData = await fs.readTextFile(userPath);
|
||||
if (fileData !== undefined && fileData !== null && fileData !== "" && fileData !== "{}") {
|
||||
return fileData;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
81
src/types/Achievement.d.ts
vendored
81
src/types/Achievement.d.ts
vendored
@@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @ file
|
||||
* @ author BTMuli<bt-muli@outlook.com>
|
||||
* @ description IndexedDB 里面存储的成就相关类型
|
||||
* @ since Alpha v0.1.2
|
||||
* @file types Achievement.d.ts
|
||||
* @author BTMuli<bt-muli@outlook.com>
|
||||
* @description 成就相关类型定义
|
||||
* @since Alpha v0.1.2
|
||||
*/
|
||||
|
||||
declare namespace BTMuli.Genshin {
|
||||
@@ -34,9 +34,7 @@ declare namespace BTMuli.Genshin {
|
||||
progress: number
|
||||
version: string
|
||||
}
|
||||
|
||||
export namespace Achievement {
|
||||
/**
|
||||
/**
|
||||
* @description 本应用的成就系列类型
|
||||
* @since Alpha v0.1.2
|
||||
* @interface AchievementSeries
|
||||
@@ -51,16 +49,63 @@ declare namespace BTMuli.Genshin {
|
||||
* @property {string} icon - 成就系列图标
|
||||
* @return AchievementSeries
|
||||
*/
|
||||
export interface Series {
|
||||
id: number
|
||||
order: number
|
||||
name: string
|
||||
version: string
|
||||
achievements: number[]
|
||||
total_count: number
|
||||
completed_count: number
|
||||
card?: string
|
||||
icon: string
|
||||
}
|
||||
export interface AchievementSeries {
|
||||
id: number
|
||||
order: number
|
||||
name: string
|
||||
version: string
|
||||
achievements: number[]
|
||||
total_count: number
|
||||
completed_count: number
|
||||
card?: string
|
||||
icon: string
|
||||
}
|
||||
}
|
||||
|
||||
declare namespace TGPlugin.UIAF {
|
||||
/**
|
||||
* @interface BaseData
|
||||
* @since Alpha v0.1.2
|
||||
* @description UIAF 成就数据
|
||||
* @property {UIAF_Info} info UIAF 头部信息
|
||||
* @property {UIAF_Achievement[]} list UIAF 成就列表
|
||||
* @return BaseData
|
||||
*/
|
||||
export interface BaseData {
|
||||
info: Header
|
||||
list: Achievement[]
|
||||
}
|
||||
|
||||
/**
|
||||
* @interface Header
|
||||
* @description UIAF 头部信息
|
||||
* @property {string} export_app 导出的应用名称
|
||||
* @property {number} export_timestamp 导出时间戳,正确时间戳得乘以 1000
|
||||
* @property {string} export_app_version 导出的应用版本
|
||||
* @property {string} uiaf_version UIAF 版本
|
||||
* @return Header
|
||||
*/
|
||||
export interface Header {
|
||||
export_app: string
|
||||
export_timestamp: number
|
||||
export_app_version: string
|
||||
uiaf_version: string
|
||||
}
|
||||
|
||||
/**
|
||||
* @interface Achievement
|
||||
* @since Alpha v0.1.2
|
||||
* @description UIAF 单个成就数据
|
||||
* @property {number} id 成就 ID
|
||||
* @property {number} timestamp 成就记录时间戳,正确时间戳得乘以 1000
|
||||
* @property {number} current 成就进度
|
||||
* @property {number} status 成就状态,0 为未完成,1 为已完成
|
||||
* @return Achievement
|
||||
*/
|
||||
export interface Achievement {
|
||||
id: number
|
||||
timestamp: number
|
||||
current: number
|
||||
status: number
|
||||
}
|
||||
}
|
||||
|
||||
2
src/types/NameCard.d.ts
vendored
2
src/types/NameCard.d.ts
vendored
@@ -28,6 +28,4 @@ declare namespace BTMuli.Genshin {
|
||||
type: number
|
||||
source: string
|
||||
}
|
||||
export namespace NameCard {
|
||||
}
|
||||
}
|
||||
|
||||
58
src/utils/UIAF.ts
Normal file
58
src/utils/UIAF.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* @description 获取 UIAF 头部信息
|
||||
* @since Alpha v0.1.2
|
||||
* @returns {Promise<TGPlugin.UIAF.Header>}
|
||||
*/
|
||||
|
||||
import { app, fs } from "@tauri-apps/api";
|
||||
|
||||
/**
|
||||
* @description 获取 UIAF 头部信息
|
||||
* @since Alpha v0.1.2
|
||||
* @returns {Promise<TGPlugin.UIAF.Header>}
|
||||
*/
|
||||
|
||||
export async function getHeader (): Promise<TGPlugin.UIAF.Header> {
|
||||
return {
|
||||
// eslint-disable-next-line camelcase
|
||||
export_app: "Tauri.Genshin",
|
||||
// eslint-disable-next-line camelcase
|
||||
export_timestamp: Math.floor(Date.now() / 1000),
|
||||
// eslint-disable-next-line camelcase
|
||||
export_app_version: await app.getVersion(),
|
||||
// eslint-disable-next-line camelcase
|
||||
uiaf_version: "v1.1",
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 检测是否存在 UIAF 数据
|
||||
* @description 粗略检测,不保证数据完整性
|
||||
* @since Alpha v0.1.2
|
||||
* @param {string} path - UIAF 数据路径
|
||||
* @returns {Promise<boolean>} 是否存在 UIAF 数据
|
||||
*/
|
||||
export async function verifyUIAF (path: string): Promise<boolean> {
|
||||
const fileData: string = await fs.readTextFile(path);
|
||||
const UIAFData: TGPlugin.UIAF.Header = JSON.parse(fileData).info;
|
||||
return UIAFData.uiaf_version !== undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 读取 UIAF 数据
|
||||
* @since Alpha v0.1.2
|
||||
* @param {string} userPath - UIAF 数据路径
|
||||
* @returns {Promise<string|false>} UIAF 数据
|
||||
*/
|
||||
export async function readUIAF (userPath: string): Promise<string | false> {
|
||||
if (await fs.exists(userPath)) {
|
||||
const fileData = await fs.readTextFile(userPath);
|
||||
if (fileData !== undefined && fileData !== null && fileData !== "" && fileData !== "{}") {
|
||||
return fileData;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user