♻️ UIAF重构,支持祈愿备份/恢复

close #109
This commit is contained in:
目棃
2024-05-07 19:52:34 +08:00
parent 2803d06418
commit 2f14405cab
14 changed files with 468 additions and 235 deletions

View File

@@ -1,14 +1,12 @@
/**
* @file plugins/Sqlite/index.ts
* @description Sqlite 数据库操作类
* @since Beta v0.4.5
* @since Beta v0.4.7
*/
import { app } from "@tauri-apps/api";
import Database from "tauri-plugin-sql-api";
import { getUiafStatus } from "../../utils/UIAF";
import initDataSql from "./sql/initData";
import {
importAbyssData,
@@ -18,7 +16,6 @@ import {
insertRecordData,
insertRoleData,
} from "./sql/insertData";
import { importUIAFData } from "./sql/updateData";
class Sqlite {
/**
@@ -201,57 +198,6 @@ class Sqlite {
await this.initDB();
}
/**
* @description 获取最新成就版本
* @since Beta v0.3.3
* @returns {Promise<string>}
*/
public async getLatestAchievementVersion(): Promise<string> {
const db = await this.getDB();
const sql = "SELECT version FROM Achievements ORDER BY version DESC LIMIT 1;";
const res: Array<{ version: string }> = await db.select(sql);
return res[0].version;
}
/**
* @description 合并 UIAF 数据
* @since Beta v0.3.3
* @param {TGApp.Plugins.UIAF.Achievement[]} achievements UIAF 数据
* @returns {Promise<void>}
*/
public async mergeUIAF(achievements: TGApp.Plugins.UIAF.Achievement[]): Promise<void> {
const db = await this.getDB();
const sql = importUIAFData(achievements);
for (const item of sql) {
await db.execute(item);
}
}
/**
* @description 获取 UIAF 数据
* @since Beta v0.3.3
* @returns {Promise<TGApp.Plugins.UIAF.Achievement[]>}
*/
public async getUIAF(): Promise<TGApp.Plugins.UIAF.Achievement[]> {
const db = await this.getDB();
const sql = "SELECT * FROM Achievements WHERE isCompleted = 1 OR progress > 0";
const res: TGApp.Sqlite.Achievement.SingleTable[] = await db.select(sql);
const achievements: TGApp.Plugins.UIAF.Achievement[] = [];
for (const item of res) {
const completed = item.isCompleted === 1;
const status = getUiafStatus(completed, item.progress);
achievements.push({
id: item.id,
status,
timestamp:
completed && item.completedTime ? new Date(item.completedTime).getTime() / 1000 : 0,
current: item.progress,
});
}
return achievements;
}
/**
* @description 保存深渊数据
* @since Beta v0.3.3

View File

@@ -0,0 +1,194 @@
/**
* @file plugins/Sqlite/modules/userAchi.ts
* @description 用户成就模块
* @since Beta v0.4.7
*/
import { getUiafStatus } from "../../../utils/UIAF.js";
import TGSqlite from "../index";
import { importUIAFData } from "../sql/updateData";
/**
* @description 获取成就概况
* @since Beta v0.4.7
* @returns {Promise<TGApp.Sqlite.Achievement.Overview}> 成就概况
*/
async function getOverview(): Promise<TGApp.Sqlite.Achievement.Overview> {
const db = await TGSqlite.getDB();
const res = await db.select<TGApp.Sqlite.Achievement.Overview>(
"SELECT SUM(totalCount) as total,SUM(finCount) AS fin From AchievementSeries",
);
return res[0];
}
/**
* @description 获取最新成就版本
* @since Beta v0.4.7
* @returns {Promise<string>} 最新成就版本
*/
async function getLatestAchiVersion(): Promise<string> {
const db = await TGSqlite.getDB();
type resType = { version: string };
const res = await db.select<resType>(
"SELECT version FROM Achievements ORDER BY version DESC LIMIT 1;",
);
return res[0].version;
}
/**
* @description 获取成就系列数据
* @since Beta v0.4.7
* @param {number|undefined} id 成就系列ID
* @returns {Promise<TGApp.Sqlite.Achievement.SeriesTable[]>} 成就系列数据
*/
async function getSeries(id?: number): Promise<TGApp.Sqlite.Achievement.SeriesTable[]> {
const db = await TGSqlite.getDB();
let res: TGApp.Sqlite.Achievement.SeriesTable[] = [];
if (id === undefined) {
res = await db.select<TGApp.Sqlite.Achievement.SeriesTable>(
"SELECT * FROM AchievementSeries ORDER BY `order`;",
);
} else {
res = await db.select<TGApp.Sqlite.Achievement.SeriesTable>(
"SELECT * FROM AchievementSeries WHERE id = ?;",
[id],
);
}
return res;
}
/**
* @description 获取成就数据
* @since Beta v0.4.7
* @param {number|undefined} id 成就系列ID
* @returns {Promise<TGApp.Sqlite.Achievement.SingleTable[]>} 成就数据
*/
async function getAchievements(id?: string): Promise<TGApp.Sqlite.Achievement.SingleTable[]> {
const db = await TGSqlite.getDB();
let res: TGApp.Sqlite.Achievement.SingleTable[] = [];
if (id === undefined) {
res = await db.select<TGApp.Sqlite.Achievement.SingleTable>(
"SELECT * FROM Achievements ORDER BY isCompleted,`order`;",
);
} else {
res = await db.select<TGApp.Sqlite.Achievement.SingleTable>(
"SELECT * FROM Achievements WHERE series = ? ORDER BY `order`;",
[id],
);
}
return res;
}
/**
* @description 获取成就名片
* @since Beta v0.4.7
* @param {string} id 成就系列ID
* @returns {Promise<string>} 成就名片
*/
async function getSeriesNameCard(id: string): Promise<string> {
const db = await TGSqlite.getDB();
type resType = { nameCard: string };
const res = await db.select<resType>("SELECT nameCard FROM AchievementSeries WHERE id = ?;", [
id,
]);
return res[0].nameCard;
}
/**
* @description 查找成就数据
* @since Beta v0.4.7
* @param {string} keyword 关键词
* @returns {Promise<TGApp.Sqlite.Achievement.SingleTable[]>} 成就数据
*/
async function searchAchievements(
keyword: string,
): Promise<TGApp.Sqlite.Achievement.SingleTable[]> {
if (keyword === "") return await getAchievements();
const db = await TGSqlite.getDB();
const versionReg = /^v\d+(\.\d+)?$/;
if (versionReg.test(keyword)) {
return await db.select<TGApp.Sqlite.Achievement.SingleTable>(
"SELECT * FROM Achievements WHERE version LIKE ? ORDER BY isCompleted,`order`;",
[keyword],
);
}
return await db.select<TGApp.Sqlite.Achievement.SingleTable>(
"SELECT * FROM Achievements WHERE name LIKE ? OR description LIKE ? ORDER BY isCompleted,`order`;",
[`%${keyword}%`, `%${keyword}%`],
);
}
/**
* @description 更新成就数据
* @since Beta v0.4.7
* @param {TGApp.Sqlite.Achievement.SingleTable} data UIAF数据
* @returns {Promise<void>}
*/
async function updateAchievement(data: TGApp.Sqlite.Achievement.SingleTable): Promise<void> {
const db = await TGSqlite.getDB();
await db.execute("UPDATE Achievements SET isCompleted = ?, completedTime = ? WHERE id = ?;", [
data.isCompleted,
data.completedTime.toString(),
data.id,
]);
}
/**
* @description 将数据库数据转换为UIAF数据
* @since Beta v0.4.7
* @param {TGApp.Sqlite.Achievement.SingleTable} data 数据库数据
* @returns {TGApp.Plugins.UIAF.Achievement} UIAF数据
*/
function transDb2Uiaf(data: TGApp.Sqlite.Achievement.SingleTable): TGApp.Plugins.UIAF.Achievement {
const isCompleted = data.isCompleted === 1;
const status = getUiafStatus(isCompleted, data.progress);
return {
id: data.id,
timestamp: data.timestamp,
current: data.progress,
status,
};
}
/**
* @description 获取UIAF数据
* @since Beta v0.4.7
* @returns {Promise<TGApp.Plugins.UIAF.Achievement[]>}
*/
async function getUIAF(): Promise<TGApp.Plugins.UIAF.Achievement[]> {
const db = await TGSqlite.getDB();
const data = await db.select<TGApp.Sqlite.Achievement.SingleTable>("SELECT * FROM Achievements;");
const res: TGApp.Plugins.UIAF.Achievement[] = [];
for (const item: TGApp.Sqlite.Achievement.SingleTable of data) {
res.push(transDb2Uiaf(item));
}
return res;
}
/**
* @description 合并UIAF数据
* @since Beta v0.4.7
* @param {TGApp.Plugins.UIAF.Achievement[]} data UIAF数据
* @returns {Promise<void>}
*/
async function mergeUIAF(data: TGApp.Plugins.UIAF.Achievement[]): Promise<void> {
const db = await TGSqlite.getDB();
for (const item of data) {
const sql = importUIAFData(item);
await db.execute(sql);
}
}
const TSUserAchi = {
getOverview,
getLatestAchiVersion,
getSeries,
getSeriesNameCard,
getAchievements,
searchAchievements,
updateAchievement,
getUIAF,
mergeUIAF,
};
export default TSUserAchi;

View File

@@ -130,7 +130,6 @@ async function mergeUIGF(uid: string, data: TGApp.Plugins.UIGF.GachaItem[]): Pro
const db = await TGSqlite.getDB();
for (const gacha of data) {
const trans = transGacha(gacha);
console.log(trans);
const sql = importUIGFData(uid, trans);
await db.execute(sql);
}

View File

@@ -7,43 +7,39 @@
import minifySql from "../../../utils/minifySql";
/**
* @description 导入UIAF数据
* @since Alpha v0.2.3
* @param {TGApp.Plugins.UIAF.Achievement[]} data
* @returns {string[]} sql
* @description 导入UIAF数据-单项
* @since Beta v0.4.7
* @param {TGApp.Plugins.UIAF.Achievement} data
* @returns {string} sql
*/
export function importUIAFData(data: TGApp.Plugins.UIAF.Achievement[]): string[] {
const sqlRes: string[] = [];
data.map((achievement) => {
let sql;
// 获取完成状态
const isCompleted = achievement.status === 2 || achievement.status === 3;
if (isCompleted) {
const completedTime = new Date(achievement.timestamp * 1000)
.toISOString()
.replace("T", " ")
.slice(0, 19);
sql = `
UPDATE Achievements
SET isCompleted = 1,
completedTime = '${completedTime}',
progress = ${achievement.current},
updated = datetime('now', 'localtime')
WHERE id = ${achievement.id}
AND (isCompleted = 0 OR completedTime != '${completedTime}' OR progress != ${achievement.current});
`;
} else {
sql = `
export function importUIAFData(data: TGApp.Plugins.UIAF.Achievement): string[] {
let sql;
const isCompleted = data.status === 2 || data.status === 3;
if (isCompleted) {
const completedTime = new Date(data.timestamp * 1000)
.toISOString()
.replace("T", " ")
.slice(0, 19);
sql = `
UPDATE Achievements
SET isCompleted = 1,
completedTime = '${completedTime}',
progress = ${data.current},
updated = datetime('now', 'localtime')
WHERE id = ${data.id}
AND (isCompleted = 0 OR completedTime != '${completedTime}'
OR progress != ${data.current});
`;
} else {
sql = `
UPDATE Achievements
SET progress = ${achievement.current},
updated = datetime('now', 'localtime')
WHERE id = ${achievement.id}
AND progress != ${achievement.current};
`;
}
return sqlRes.push(minifySql(sql));
});
return sqlRes;
}
return minifySql(sql);
}
/**