diff --git a/src/pages/Achievements.vue b/src/pages/Achievements.vue
index 72deb1e6..e288750d 100644
--- a/src/pages/Achievements.vue
+++ b/src/pages/Achievements.vue
@@ -10,37 +10,16 @@
导入
-
-
- 合并
-
导出
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -52,11 +31,11 @@ import UIAF_Oper from "../plugins/UIAF";
import { dialog, fs } from "@tauri-apps/api";
import { UIAF_Achievement, Achievements } from "../plugins/UIAF/interface/UIAF";
import {
- Achievement as TGAchievement,
- AchievementSeries as TGAchievementSeries,
- AchievementDisplay as TGAchievementDisplay,
- AchievementSeriesDisplay as TGAchievementSeriesDisplay,
+ AchievementMap as TGAchievementMap,
+ SeriesMap as TGSeriesMap,
} from "../interface/Achievements";
+import TGMap from "../utils/TGMap";
+import { Map } from "../interface/Base";
export default defineComponent({
name: "Achievements",
@@ -65,16 +44,45 @@ export default defineComponent({
// 标题 成就完成数/成就总数 完成率
title: "" as string,
// 成就系列列表,用于侧边栏
- seriesList: [] as TGAchievementSeries[],
- // 成就列表-所有
- achievementsAll: [] as TGAchievementDisplay[],
+ seriesList: {} as Map,
+ // 成就列表-所有成就的数据
+ achievementsList: {} as Map,
+ // 选中的成就系列 id,用于决定右侧显示的成就列表
+ selectedSeries: -1 as number,
};
},
async mounted() {
await this.loadData();
},
methods: {
- // 导入
+ // 加载数据,数据源:合并后的本地数据
+ async loadData() {
+ const appStore = useAppStore();
+ const achievementsStore = useAchievementsStore();
+ const localSeriesPath = appStore.mergePath.achievementSeries;
+ const localAchievementsPath = appStore.mergePath.achievements;
+ const seriesMap: TGMap = new TGMap(
+ JSON.parse(await fs.readTextFile(localSeriesPath))
+ );
+ const achievementsMap: TGMap = new TGMap(
+ JSON.parse(await fs.readTextFile(localAchievementsPath))
+ );
+ await achievementsStore.flushData(seriesMap);
+ this.title = this.getTitle();
+ this.achievementsList = achievementsMap.getMap();
+ this.seriesList = seriesMap.getMap();
+ },
+ // 获取标题
+ getTitle() {
+ const achievementsStore = useAchievementsStore();
+ const achievementsAll = achievementsStore.total_achievements;
+ const achievementsDone = achievementsStore.fin_achievements;
+ return `成就完成数:${achievementsDone}/${achievementsAll} 完成率:${(
+ (achievementsDone / achievementsAll) *
+ 100
+ ).toFixed(2)}%`;
+ },
+ // 导入 UIAF 数据,进行数据合并、刷新
async importJson() {
const appStore = useAppStore();
const localPath = appStore.userPath.achievements;
@@ -87,55 +95,71 @@ export default defineComponent({
},
],
});
- // 选中文件
- if (selectedFile) {
- console.log("正在读取本地文件...");
- // 读取应用内文件
+ if (selectedFile && (await UIAF_Oper.importOper.checkUIAFData(selectedFile))) {
const localRaw: string | false = await UIAF_Oper.importOper.readUIAFData(localPath);
- console.log("读取本地文件成功");
- // 检测文件是否符合 UIAF 格式
- console.log("正在检测文件格式...");
- if (await UIAF_Oper.importOper.checkUIAFData(selectedFile)) {
- await console.log("检测文件格式成功, 开始导入...");
- // 读取选中文件
- const remoteRaw: string | false = await UIAF_Oper.importOper.readUIAFData(
- selectedFile
- );
- console.log("读取选中文件成功,开始解析数据...");
- // 解析数据
- let localData: UIAF_Achievement[] | false = false;
- let remoteData: Achievements;
- if (localRaw !== false) {
- localData = JSON.parse(localRaw);
- }
- await console.log("解析数据成功,开始合并数据...");
- if (localData === false) {
- localData = [];
- }
- if (remoteRaw === false) {
- await dialog.message("文件格式不正确,导入失败");
- return;
- }
- remoteData = JSON.parse(remoteRaw);
- // 数据合并
- const mergedData = await UIAF_Oper.importOper.mergeUIAFData(
- localData,
- remoteData
- );
- if (mergedData === false) {
- await dialog.message("合并数据失败,请检查文件是否符合 UIAF 格式");
- return;
- }
- await console.log("合并数据成功,开始写入数据...");
- // 写入数据
- await fs.writeTextFile(localPath, JSON.stringify(mergedData, null, 2));
- await console.log("写入数据成功,导入完成");
- await console.log("正在刷新数据...");
- // 刷新数据
- await this.flushStore(mergedData.length);
- } else {
- await dialog.message("文件格式不正确,请检查文件是否符合 UIAF 格式");
+ const remoteRaw: string | false = await UIAF_Oper.importOper.readUIAFData(
+ selectedFile
+ );
+ if (remoteRaw === false) {
+ await dialog.message("文件格式不正确,导入失败");
+ return;
}
+ let remoteData: Achievements = JSON.parse(remoteRaw);
+ let localData: UIAF_Achievement[] = JSON.parse(localRaw || "[]");
+ // 因为
+ const mergeUIAF: UIAF_Achievement[] = await UIAF_Oper.importOper.mergeUIAFData(
+ localData,
+ remoteData
+ );
+ await fs.writeTextFile(localPath, JSON.stringify(mergeUIAF, null, 4));
+ // 读取本地 mergeData
+ const mergeAchievementMap: TGMap = new TGMap(
+ JSON.parse(await fs.readTextFile(appStore.mergePath.achievements))
+ );
+ const mergeSeriesMap: TGMap = new TGMap(
+ JSON.parse(await fs.readTextFile(appStore.mergePath.achievementSeries))
+ );
+ // 遍历 mergeUIAF,对 mergeData 进行更新
+ mergeUIAF.map(UIAF_Item => {
+ // 更新成就
+ if (mergeAchievementMap.has(UIAF_Item.id)) {
+ const achievement = mergeAchievementMap.get(UIAF_Item.id);
+ achievement.completed = true;
+ achievement.completed_time = new Date(
+ UIAF_Item.timestamp * 1000
+ ).toLocaleString();
+ mergeAchievementMap.set(UIAF_Item.id, achievement);
+ // 如果成就系列中没有该成就,则添加
+ if (!mergeSeriesMap.has(achievement.series)) {
+ const series = mergeSeriesMap.get(achievement.series);
+ series.achievements.push(achievement.id);
+ mergeSeriesMap.set(achievement.series, series);
+ }
+ }
+ });
+ // 更新成就系列
+ mergeSeriesMap.forEach(seriesMap => {
+ let completed = 0;
+ seriesMap.achievements.map(achievement => {
+ if (mergeAchievementMap.get(achievement).completed) {
+ completed++;
+ }
+ });
+ seriesMap.completed_count = completed;
+ seriesMap.total_count = seriesMap.achievements.length;
+ mergeSeriesMap.set(seriesMap.id, seriesMap);
+ });
+ // 写入数据
+ await fs.writeTextFile(
+ appStore.mergePath.achievements,
+ JSON.stringify(mergeAchievementMap.getMap(), null, 4)
+ );
+ await fs.writeTextFile(
+ appStore.mergePath.achievementSeries,
+ JSON.stringify(mergeSeriesMap.getMap(), null, 4)
+ );
+ // 刷新数据
+ await this.loadData();
}
},
// 导出
@@ -156,97 +180,9 @@ export default defineComponent({
],
});
if (is_save) {
- await fs.writeTextFile(is_save, JSON.stringify(achievements, null, 2));
+ await fs.writeTextFile(is_save, JSON.stringify(achievements, null, 4));
}
},
- // 获取 MergeData
- async mergeJson() {
- const appStore = useAppStore();
- const localPath = appStore.userPath.achievements;
- // 读取用户的 UIAF 数据
- const localRaw: string | false = await UIAF_Oper.importOper.readUIAFData(localPath);
- if (localRaw === false) {
- await dialog.message("读取用户数据失败,请检查文件是否符合 UIAF 格式");
- return;
- }
- const localData: UIAF_Achievement[] = JSON.parse(localRaw);
- // 读取 MergeData
- const mergeAchievementRaw = await fs.readTextFile(appStore.mergePath.achievements);
- const mergeSeriesRaw = await fs.readTextFile(appStore.mergePath.achievementSeries);
- const mergeAchievementData: TGAchievementDisplay[] = JSON.parse(mergeAchievementRaw);
- const mergeSeriesData: TGAchievementSeriesDisplay[] = JSON.parse(mergeSeriesRaw);
- // 遍历 localData,对 MergeData 进行更新
- localData.map(localAchievement => {
- const achievementSingle = mergeAchievementData.find(
- achievement => achievement.id === localAchievement.id
- );
- if (achievementSingle) {
- achievementSingle.completed = true;
- achievementSingle.completed_time = new Date(
- localAchievement.timestamp * 1000
- ).toLocaleString();
- }
- });
- // 遍历 mergeSeries 对 mergeSeries 进行更新
- // todo 缺乏拓展性
- mergeSeriesData.map(mergeSeries => {
- let completed = 0;
- // 更新成就
- mergeSeries.achievements.map(achievement => {
- const findAchievement = mergeAchievementData.find(achievementSingle => {
- return achievementSingle.id === achievement.id;
- });
- if (findAchievement) {
- if (findAchievement !== achievement) {
- achievement.completed = findAchievement.completed;
- achievement.completed_time = findAchievement.completed_time;
- }
- }
- if (achievement.completed) {
- completed++;
- }
- });
- // 更新系列
- mergeSeries.completed_count = completed;
- });
- // 写入数据
- await fs.writeTextFile(
- appStore.mergePath.achievements,
- JSON.stringify(mergeAchievementData, null, 4)
- );
- await fs.writeTextFile(
- appStore.mergePath.achievementSeries,
- JSON.stringify(mergeSeriesData, null, 4)
- );
- await dialog.message("合并数据成功");
- },
- // 获取标题
- getTitle() {
- const achievementsStore = useAchievementsStore();
- const achievementsAll = achievementsStore.total_achievements;
- const achievementsDone = achievementsStore.fin_achievements;
- return `成就完成数:${achievementsDone}/${achievementsAll} 完成率:${(
- (achievementsDone / achievementsAll) *
- 100
- ).toFixed(2)}%`;
- },
- // 刷新数据
- async flushStore(fin_num: number) {
- const achievementsStore = useAchievementsStore();
- achievementsStore.fin_achievements = fin_num;
- const appStore = useAppStore();
- const localPath = appStore.appPath.achievements;
- const localRaw: string = await fs.readTextFile(localPath);
- const localData: TGAchievement[] = JSON.parse(localRaw);
- achievementsStore.total_achievements = localData.length;
- this.title = this.getTitle();
- },
- // 加载数据
- async loadData() {
- this.title = this.getTitle();
- // this.seriesList = TGAppData.MergeData.achievementSeries;
- // this.achievementsAll = TGAppData.MergeData.achievements;
- },
},
});
diff --git a/src/plugins/UIAF/utils/importData.ts b/src/plugins/UIAF/utils/importData.ts
index fe42fe8d..e2d82cba 100644
--- a/src/plugins/UIAF/utils/importData.ts
+++ b/src/plugins/UIAF/utils/importData.ts
@@ -11,6 +11,7 @@ import { fs } from "@tauri-apps/api";
/**
* @description 检测是否存在 UIAF 数据
* @description 粗略检测,不保证数据完整性
+ * @since Alpha
* @param {string} path - UIAF 数据路径
* @return {Promise} 是否存在 UIAF 数据
*/
@@ -22,6 +23,7 @@ export async function checkUIAFData(path: string): Promise {
/**
* @description 读取 UIAF 数据
+ * @since Alpha
* @param {string} userPath - UIAF 数据路径
* @return {Promise} UIAF 数据
*/
@@ -40,14 +42,15 @@ export async function readUIAFData(userPath: string): Promise {
/**
* @description 数据合并
+ * @since Alpha
* @param {UIAF_Achievement[]} localData - 本地数据
* @param {Achievements} remoteData - 远程数据
- * @return {Promise} 合并后的数据,如果合并失败则返回 false
+ * @return {Promise} 合并后的数据
*/
export async function mergeUIAFData(
localData: UIAF_Achievement[],
remoteData: Achievements
-): Promise {
+): Promise {
// 遍历 remoteData.list
remoteData.list.map((remoteAchievement: UIAF_Achievement) => {
// 查找 id 相同的 localAchievement
diff --git a/src/store/modules/achievements.ts b/src/store/modules/achievements.ts
index da3abec0..aa959e23 100644
--- a/src/store/modules/achievements.ts
+++ b/src/store/modules/achievements.ts
@@ -6,6 +6,8 @@
*/
import { defineStore } from "pinia";
+import TGMap from "../../utils/TGMap";
+import { SeriesMap } from "../../interface/Achievements";
const useAchievementsStore = defineStore({
id: "achievements",
@@ -13,10 +15,23 @@ const useAchievementsStore = defineStore({
return {
total_achievements: 899,
fin_achievements: 0,
+ // 这个数据用于说明当前的数据版本,不会被渲染
last_version: "v3.5",
UIAF_Version: "v1.1",
};
},
+ actions: {
+ flushData(seriesMap: TGMap) {
+ let total = 0;
+ let fin = 0;
+ seriesMap.forEach(series => {
+ total += series.total_count;
+ fin += series.completed_count;
+ });
+ this.total_achievements = total;
+ this.fin_achievements = fin;
+ },
+ },
persist: true,
});