mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2025-12-13 09:28:14 +08:00
🌱 UIGF 相关处理草创
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
* @file plugins Sqlite index.ts
|
* @file plugins Sqlite index.ts
|
||||||
* @description Sqlite 数据库操作类
|
* @description Sqlite 数据库操作类
|
||||||
* @author BTMuli<bt-muli@outlook.com>
|
* @author BTMuli<bt-muli@outlook.com>
|
||||||
* @since Alpha v0.2.2
|
* @since Alpha v0.2.3
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// tauri
|
// tauri
|
||||||
@@ -10,7 +10,7 @@ import Database from "tauri-plugin-sql-api";
|
|||||||
// utils
|
// utils
|
||||||
import initDataSql from "./sql/initData";
|
import initDataSql from "./sql/initData";
|
||||||
import initTableSql from "./sql/initTable";
|
import initTableSql from "./sql/initTable";
|
||||||
import { importUIAFData } from "./sql/updateData";
|
import { importUIAFData, importUIGFData } from "./sql/updateData";
|
||||||
import { getUiafStatus } from "../../utils/UIAF";
|
import { getUiafStatus } from "../../utils/UIAF";
|
||||||
import {
|
import {
|
||||||
insertAbyssData,
|
insertAbyssData,
|
||||||
@@ -30,7 +30,7 @@ class Sqlite {
|
|||||||
private readonly dbPath: string = "sqlite:tauri-genshin.db";
|
private readonly dbPath: string = "sqlite:tauri-genshin.db";
|
||||||
/**
|
/**
|
||||||
* @description 数据库包含的表
|
* @description 数据库包含的表
|
||||||
* @since Alpha v0.2.0
|
* @since Alpha v0.2.3
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
private readonly tables: string[] = [
|
private readonly tables: string[] = [
|
||||||
@@ -43,6 +43,7 @@ class Sqlite {
|
|||||||
"SpiralAbyss",
|
"SpiralAbyss",
|
||||||
"UserCharacters",
|
"UserCharacters",
|
||||||
"UserRecord",
|
"UserRecord",
|
||||||
|
"GachaRecords",
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -468,6 +469,37 @@ class Sqlite {
|
|||||||
if (res.length === 0) return false;
|
if (res.length === 0) return false;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 获取指定 uid 的用户角色数据
|
||||||
|
* @since Alpha v0.2。3
|
||||||
|
* @param {string} uid 用户 uid
|
||||||
|
* @returns {Promise<TGApp.Sqlite.GachaRecords.SingleTable[]>}
|
||||||
|
*/
|
||||||
|
public async getGachaRecords(uid: string): Promise<TGApp.Sqlite.GachaRecords.SingleTable[]> {
|
||||||
|
const db = await Database.load(this.dbPath);
|
||||||
|
const sql = `SELECT * FROM GachaRecords WHERE uid = '${uid}'`;
|
||||||
|
const res: TGApp.Sqlite.GachaRecords.SingleTable[] = await db.select(sql);
|
||||||
|
await db.close();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 合并祈愿数据
|
||||||
|
* @since Alpha v0.2.3
|
||||||
|
* @param {string} uid UID
|
||||||
|
* @param {string} data UIGF 数据
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
public async mergeUIGF(uid: string, data: string): Promise<void> {
|
||||||
|
const db = await Database.load(this.dbPath);
|
||||||
|
const gachaList: TGApp.Plugins.UIGF.GachaItem[] = JSON.parse(data);
|
||||||
|
const sql = importUIGFData(uid, gachaList);
|
||||||
|
for (const item of sql) {
|
||||||
|
await db.execute(item);
|
||||||
|
}
|
||||||
|
await db.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const TGSqlite = new Sqlite();
|
const TGSqlite = new Sqlite();
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
-- @file plugins Sqlite sql createTable.sql
|
-- @file plugins Sqlite sql createTable.sql
|
||||||
-- @brief sqlite数据库创建表语句
|
-- @brief sqlite数据库创建表语句
|
||||||
-- @author BTMuli <bt-muli@outlook.com>
|
-- @author BTMuli <bt-muli@outlook.com>
|
||||||
-- @since Alpha v0.2.0
|
-- @since Alpha v0.2.3
|
||||||
|
|
||||||
-- @brief 创建成就数据表
|
-- @brief 创建成就数据表
|
||||||
create table if not exists Achievements
|
create table if not exists Achievements
|
||||||
@@ -131,7 +131,23 @@ create table if not exists UserCharacters
|
|||||||
constellation text,
|
constellation text,
|
||||||
activeConstellation integer,
|
activeConstellation integer,
|
||||||
costume text,
|
costume text,
|
||||||
talent text, -- todo: 数据获取
|
talent text,
|
||||||
updated text,
|
updated text,
|
||||||
primary key (uid, cid)
|
primary key (uid, cid)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
-- @brief 创建祈愿数据表
|
||||||
|
create table if not exists GachaRecords
|
||||||
|
(
|
||||||
|
id text primary key not null,
|
||||||
|
uid text,
|
||||||
|
gachaType text,
|
||||||
|
uigfType text,
|
||||||
|
time text,
|
||||||
|
itemId text,
|
||||||
|
name text,
|
||||||
|
type text,
|
||||||
|
rank text,
|
||||||
|
count text,
|
||||||
|
updated text
|
||||||
|
);
|
||||||
|
|||||||
@@ -5,9 +5,12 @@
|
|||||||
* @since Alpha v0.2.0
|
* @since Alpha v0.2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// utils
|
||||||
|
import minifySql from "../../../utils/minifySql";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 导入UIAF数据
|
* @description 导入UIAF数据
|
||||||
* @since Alpha v0.1.5
|
* @since Alpha v0.2.3
|
||||||
* @param {TGApp.Plugins.UIAF.Achievement[]} data
|
* @param {TGApp.Plugins.UIAF.Achievement[]} data
|
||||||
* @returns {string[]} sql
|
* @returns {string[]} sql
|
||||||
*/
|
*/
|
||||||
@@ -34,7 +37,43 @@ export function importUIAFData(data: TGApp.Plugins.UIAF.Achievement[]): string[]
|
|||||||
WHERE id = ${achievement.id} AND progress != ${achievement.current};
|
WHERE id = ${achievement.id} AND progress != ${achievement.current};
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
return sqlRes.push(sql);
|
return sqlRes.push(minifySql(sql));
|
||||||
|
});
|
||||||
|
return sqlRes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 导入UIGF数据
|
||||||
|
* @since Alpha v0.2.3
|
||||||
|
* @param {string} uid - UID
|
||||||
|
* @param {TGApp.Plugins.UIGF.GachaItem[]} data - UIGF数据
|
||||||
|
* @returns {string[]} sql
|
||||||
|
*/
|
||||||
|
export function importUIGFData(uid: string, data: TGApp.Plugins.UIGF.GachaItem[]): string[] {
|
||||||
|
const sqlRes: string[] = [];
|
||||||
|
data.forEach((gacha) => {
|
||||||
|
const sql = `
|
||||||
|
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 SET
|
||||||
|
uid = '${uid}',
|
||||||
|
gachaType = '${gacha.gacha_type}',
|
||||||
|
uigfType = '${gacha.uigf_gacha_type}',
|
||||||
|
time = '${gacha.time}',
|
||||||
|
itemId = '${gacha.item_id ?? null}',
|
||||||
|
count = '${gacha.count ?? null}',
|
||||||
|
name = '${gacha.name}',
|
||||||
|
type = '${gacha.item_type ?? null}',
|
||||||
|
rank = '${gacha.rank_type ?? null}',
|
||||||
|
updated = datetime('now', 'localtime');
|
||||||
|
`;
|
||||||
|
sqlRes.push(minifySql(sql));
|
||||||
});
|
});
|
||||||
return sqlRes;
|
return sqlRes;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
/**
|
/**
|
||||||
* @file utils UIAF.ts
|
* @file utils UIAF.ts
|
||||||
* @description UIAF工具类
|
* @description UIAF工具类
|
||||||
* @author BTMuli<bt-muli@outlook.com>
|
* @author BTMuli <bt-muli@outlook.com>
|
||||||
* @since Alpha v0.1.4
|
* @since Alpha v0.2.3
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// tauri
|
// tauri
|
||||||
@@ -10,23 +10,6 @@ import { app, fs, path } from "@tauri-apps/api";
|
|||||||
// utils
|
// utils
|
||||||
import TGSqlite from "../plugins/Sqlite";
|
import TGSqlite from "../plugins/Sqlite";
|
||||||
|
|
||||||
/**
|
|
||||||
* @description 时间戳转换为日期
|
|
||||||
* @since Alpha v0.1.4
|
|
||||||
* @param {number} timestamp - 时间戳
|
|
||||||
* @returns {string} 日期 2021-01-01 00:00:00
|
|
||||||
*/
|
|
||||||
export function timestampToDate(timestamp: number): string {
|
|
||||||
return new Date(timestamp * 1000).toLocaleString("zh", {
|
|
||||||
year: "numeric",
|
|
||||||
month: "2-digit",
|
|
||||||
day: "2-digit",
|
|
||||||
hour: "2-digit",
|
|
||||||
minute: "2-digit",
|
|
||||||
second: "2-digit",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 根据 completed 跟 progress 获取 status
|
* @description 根据 completed 跟 progress 获取 status
|
||||||
* @since Alpha v0.1.4
|
* @since Alpha v0.1.4
|
||||||
@@ -53,13 +36,9 @@ export function getUiafStatus(completed: boolean, progress: number): number {
|
|||||||
*/
|
*/
|
||||||
export async function getUiafHeader(): Promise<TGApp.Plugins.UIAF.Export> {
|
export async function getUiafHeader(): Promise<TGApp.Plugins.UIAF.Export> {
|
||||||
return {
|
return {
|
||||||
// eslint-disable-next-line camelcase
|
|
||||||
export_app: "Tauri.Genshin",
|
export_app: "Tauri.Genshin",
|
||||||
// eslint-disable-next-line camelcase
|
|
||||||
export_timestamp: Math.floor(Date.now() / 1000),
|
export_timestamp: Math.floor(Date.now() / 1000),
|
||||||
// eslint-disable-next-line camelcase
|
|
||||||
export_app_version: await app.getVersion(),
|
export_app_version: await app.getVersion(),
|
||||||
// eslint-disable-next-line camelcase
|
|
||||||
uiaf_version: "v1.1",
|
uiaf_version: "v1.1",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
92
src/utils/UIGF.ts
Normal file
92
src/utils/UIGF.ts
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
/**
|
||||||
|
* @file utils UIGF.ts
|
||||||
|
* @description UIGF工具类
|
||||||
|
* @author BTMuli <bt-muli@outlook.com>
|
||||||
|
* @since Alpha v0.2.3
|
||||||
|
*/
|
||||||
|
|
||||||
|
// tauri
|
||||||
|
import { app, fs, path } from "@tauri-apps/api";
|
||||||
|
// utils
|
||||||
|
import TGSqlite from "../plugins/Sqlite";
|
||||||
|
import { timestampToDate } from "./t2D";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 获取 UIGF 头部信息
|
||||||
|
* @since Alpha v0.2.3
|
||||||
|
* @param {string} uid - UID
|
||||||
|
* @returns {Promise<TGApp.Plugins.UIGF.Export>}
|
||||||
|
*/
|
||||||
|
export async function getUigfHeader(uid: string): Promise<TGApp.Plugins.UIGF.Export> {
|
||||||
|
const stamp = Date.now();
|
||||||
|
return {
|
||||||
|
uid,
|
||||||
|
lang: "zh-cn",
|
||||||
|
uigf_version: "2.3.0",
|
||||||
|
export_timestamp: Math.floor(stamp / 1000),
|
||||||
|
export_time: timestampToDate(stamp),
|
||||||
|
export_app: "Tauri.Genshin",
|
||||||
|
export_app_version: await app.getVersion(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 检测是否存在 UIGF 数据
|
||||||
|
* @description 粗略检测,不保证数据完整性
|
||||||
|
* @since Alpha v0.2.3
|
||||||
|
* @param {string} path - UIGF 数据路径
|
||||||
|
* @returns {Promise<boolean>} 是否存在 UIGF 数据
|
||||||
|
*/
|
||||||
|
export async function verifyUigfData(path: string): Promise<boolean> {
|
||||||
|
const fileData: string = await fs.readTextFile(path);
|
||||||
|
const UigfData: TGApp.Plugins.UIGF.Export = JSON.parse(fileData).info;
|
||||||
|
return UigfData.uigf_version !== undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 读取 UIGF 数据
|
||||||
|
* @since Alpha v0.2.3
|
||||||
|
* @param {string} userPath - UIGF 数据路径
|
||||||
|
* @returns {Promise<string|false>} UIGF 数据
|
||||||
|
*/
|
||||||
|
export async function readUigfData(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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 备份 UIGF 数据
|
||||||
|
* @since Alpha v0.2.3
|
||||||
|
* @param {TGApp.Plugins.UIAF.GachaItem[]} gachaList - 祈愿列表
|
||||||
|
* @param {string} uid - UID
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
export async function backupUigfData(
|
||||||
|
gachaList: TGApp.Plugins.UIGF.GachaItem[],
|
||||||
|
uid: string,
|
||||||
|
): Promise<void> {
|
||||||
|
const savePath = `${await path.appLocalDataDir()}\\userData\\UIGF_${uid}.json`;
|
||||||
|
await fs.writeTextFile(savePath, JSON.stringify(gachaList, null, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 恢复 UIGF 数据
|
||||||
|
* @since Alpha v0.2.3
|
||||||
|
* @param {string} uid - UID
|
||||||
|
* @returns {Promise<boolean>} UIGF 数据
|
||||||
|
*/
|
||||||
|
export async function restoreUigfData(uid: string): Promise<boolean> {
|
||||||
|
const uigfPath = `${await path.appLocalDataDir()}\\userData\\UIGF_${uid}.json`;
|
||||||
|
const uigfData = await readUigfData(uigfPath);
|
||||||
|
if (uigfData === false) return false;
|
||||||
|
await TGSqlite.mergeUIGF(uid, uigfData);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
23
src/utils/t2D.ts
Normal file
23
src/utils/t2D.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* @file utils t2D.ts
|
||||||
|
* @description time to date 时间戳转换为日期工具类
|
||||||
|
* @author BTMuli<bt-muli@outlook.com>
|
||||||
|
* @since Alpha v0.2.3
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 时间戳转换为日期
|
||||||
|
* @since Alpha v0.2.3
|
||||||
|
* @param {number} timestamp - 时间戳(毫秒)
|
||||||
|
* @returns {string} 日期 2021-01-01 00:00:00
|
||||||
|
*/
|
||||||
|
export function timestampToDate(timestamp: number): string {
|
||||||
|
return new Date(timestamp).toLocaleString("zh", {
|
||||||
|
year: "numeric",
|
||||||
|
month: "2-digit",
|
||||||
|
day: "2-digit",
|
||||||
|
hour: "2-digit",
|
||||||
|
minute: "2-digit",
|
||||||
|
second: "2-digit",
|
||||||
|
});
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user