♻️ types 重构后的问题搞完了,累死

This commit is contained in:
BTMuli
2023-05-23 00:56:43 +08:00
parent 573eb8bbe4
commit caadb5df79
38 changed files with 362 additions and 408 deletions

View File

@@ -11,7 +11,3 @@
font-family: "Consolas";
src: url("./consolas.ttf") format("truetype");
}
/* 全局字体样式 */
.global-font {
font-family: "Genshin", sans-serif;
}

View File

@@ -23,7 +23,7 @@
</template>
<script lang="ts" setup>
interface TMiniWeaponProps {
item: BTMuli.Genshin.Material.BriefInfo;
item: TGApp.App.Calendar.Material;
}
defineProps<TMiniWeaponProps>();
</script>

View File

@@ -102,12 +102,12 @@
</template>
<script lang="ts" setup>
// vue
import { onMounted, ref } from "vue";
import { computed, onMounted, ref } from "vue";
import TMiniAvatar from "./t-mini-avatar.vue";
import TMiniWeapon from "./t-mini-weapon.vue";
import TCalendarMaterial from "./t-calendar-material.vue";
// data
import { TGAppData } from "../data";
import { AppCalendarData } from "../data";
// interface
import { OBC_CONTENT_API } from "../plugins/Mys/interface/utils";
import { createTGWindow } from "../utils/TGWindow";
@@ -116,19 +116,19 @@ import { createTGWindow } from "../utils/TGWindow";
const loading = ref(true as boolean);
// data
const calendarData = ref(TGAppData.calendar);
const calendarData = computed(() => AppCalendarData);
const weekNow = ref(0 as number);
const btnNow = ref(0 as number);
const dateNow = ref(new Date().toLocaleDateString());
// calendar
const calendarNow = ref([] as BTMuli.Genshin.Calendar.Data[]);
const characterCards = ref([] as BTMuli.Genshin.Calendar.Data[]);
const weaponCards = ref([] as BTMuli.Genshin.Calendar.Data[]);
const calendarNow = ref([] as TGApp.App.Calendar.Item[]);
const characterCards = ref([] as TGApp.App.Calendar.Item[]);
const weaponCards = ref([] as TGApp.App.Calendar.Item[]);
// calendar item
const showItem = ref(false as boolean);
const selectedItem = ref({} as BTMuli.Genshin.Calendar.Data);
const selectedItem = ref({} as TGApp.App.Calendar.Item);
const selectedType = ref("character");
// snackbar
@@ -177,38 +177,38 @@ onMounted(() => {
weekNow.value = dayNow;
btnNow.value = dayNow;
calendarNow.value = getCalendar(dayNow);
characterCards.value = calendarNow.value.filter((item) => item.item_type === "character");
weaponCards.value = calendarNow.value.filter((item) => item.item_type === "weapon");
characterCards.value = calendarNow.value.filter((item) => item.itemType === "character");
weaponCards.value = calendarNow.value.filter((item) => item.itemType === "weapon");
loading.value = false;
});
// 获取当前日历
function getCalendar (day: number) {
return calendarData.value.filter((item) => item.drop_day.includes(day));
return calendarData.value.filter((item) => item.dropDays.includes(day));
}
function selectContent (item: BTMuli.Genshin.Calendar.Data, type: string) {
function selectContent (item: TGApp.App.Calendar.Item, type: string) {
selectedItem.value = item;
selectedType.value = type;
showItem.value = true;
}
function showDetail (item: BTMuli.Genshin.Calendar.Data) {
if (item.content_id === null) {
function showDetail (item: TGApp.App.Calendar.Item) {
if (item.contentId === 0) {
snackbarText.value = "暂无详情";
snackbarColor.value = "error";
snackbar.value = true;
return;
}
const url = OBC_CONTENT_API.replace("{content_id}", item.content_id.toString());
const url = OBC_CONTENT_API.replace("{content_id}", item.contentId.toString());
createTGWindow(url, "素材详情", item.name, 1200, 800, true);
}
function getContents (day: number) {
btnNow.value = day;
calendarNow.value = getCalendar(day);
characterCards.value = calendarNow.value.filter((item) => item.item_type === "character");
weaponCards.value = calendarNow.value.filter((item) => item.item_type === "weapon");
characterCards.value = calendarNow.value.filter((item) => item.itemType === "character");
weaponCards.value = calendarNow.value.filter((item) => item.itemType === "weapon");
}
</script>
<style lang="css" scoped>

View File

@@ -2,20 +2,20 @@
<div class="card-box">
<!-- 底层背景图 -->
<div class="card-bg">
<img :src="item.bg" alt="bg">
<img :src="props.modelValue.bg" alt="bg">
</div>
<!-- 中层角色图 -->
<div class="card-icon">
<img :src="item.icon" alt="icon">
<img :src="props.modelValue.icon" alt="icon">
</div>
<!-- 上层图标&内容 -->
<div class="card-cover">
<div class="card-element">
<img :src="item.element" alt="element">
<img :src="props.modelValue.elementIcon" alt="element">
</div>
<div class="card-name">
<img :src="item.weapon_type" alt="weapon">
<span>{{ item.name }}</span>
<img :src="props.modelValue.weaponIcon" alt="weapon">
<span>{{ props.modelValue.name }}</span>
</div>
</div>
</div>
@@ -24,7 +24,7 @@
import { computed } from "vue";
interface TMiniWeaponProps {
size: string;
modelValue: BTMuli.Genshin.Wiki.Character.BriefInfo | BTMuli.Genshin.Calendar.Data
modelValue: TGApp.App.Character.WikiBriefInfo | TGApp.App.Calendar.Item;
}
const props = defineProps<TMiniWeaponProps>();
@@ -32,29 +32,6 @@ const props = defineProps<TMiniWeaponProps>();
const getSize = computed(() => {
return props.size === "100px" ? "30px" : "40px";
});
const item = computed(() => {
let res;
if (props.modelValue.hasOwnProperty("weapon_type")) {
res = props.modelValue as BTMuli.Genshin.Wiki.Character.BriefInfo;
return {
bg: res.bg,
icon: res.icon,
element: res.element,
weapon_type: res.weapon_type,
name: res.name,
};
} else {
res = props.modelValue as BTMuli.Genshin.Calendar.Data;
return {
bg: res.bg,
icon: res.icon,
element: res.element,
weapon_type: res.weapon,
name: res.name,
};
}
});
</script>
<style lang="css" scoped>
.card-box {

View File

@@ -2,19 +2,19 @@
<div class="card-box">
<!-- 底层背景图 -->
<div class="card-bg">
<img :src="item.bg" alt="bg">
<img :src="props.modelValue.bg" alt="bg">
</div>
<!-- 中层武器图 -->
<div class="card-icon">
<img :src="item.icon" alt="icon">
<img :src="props.modelValue.icon" alt="icon">
</div>
<!-- 上层图标&内容 -->
<div class="card-cover">
<div class="card-weapon">
<img :src="item.weapon_type" alt="type">
<img :src="props.modelValue.weaponIcon" alt="type">
</div>
<div class="card-name">
<span>{{ item.name }}</span>
<span>{{ props.modelValue.name }}</span>
</div>
</div>
</div>
@@ -23,36 +23,13 @@
import { computed } from "vue";
interface TMiniWeaponProps {
size: string;
modelValue: BTMuli.Genshin.Wiki.Weapon.BriefInfo | BTMuli.Genshin.Calendar.Data
modelValue: TGApp.App.Weapon.WikiBriefInfo | TGApp.App.Calendar.Item
}
const props = defineProps<TMiniWeaponProps>();
const getSize = computed(() => {
return props.size === "100px" ? "30px" : "40px";
});
const item = computed(() => {
let res;
if (!props.modelValue.hasOwnProperty("weapon_type")) {
res = props.modelValue as BTMuli.Genshin.Wiki.Weapon.BriefInfo;
return {
bg: res.bg,
icon: res.icon,
element: res.element,
weapon_type: res.type,
name: res.name,
};
} else {
res = props.modelValue as BTMuli.Genshin.Calendar.Data;
return {
bg: res.bg,
icon: res.icon,
element: res.element,
weapon_type: res.weapon_type,
name: res.name,
};
}
});
</script>
<style lang="css" scoped>
.card-box {

View File

@@ -429,16 +429,6 @@
"weaponIcon": "/icon/weapon/长柄武器.webp",
"icon": "/WIKI/character/icon/10000064.webp"
},
{
"id": 10000061,
"contentId": 0,
"name": "绮良良",
"star": 4,
"bg": "/icon/bg/4-Star.webp",
"elementIcon": "/icon/element/草元素.webp",
"weaponIcon": "/icon/weapon/单手剑.webp",
"icon": "/WIKI/character/icon/10000061.webp"
},
{
"id": 10000059,
"contentId": 4197,

View File

@@ -1,25 +0,0 @@
/**
* @file data app index
* @description data app index
* @author BTMuli<bt-muli@outlook.com>
* @since Alpha v0.1.5
*/
// Data
import achievements from "./achievements.json";
import achievementSeries from "./achievementSeries.json";
import calendar from "./calendar.json";
import character from "./character.json";
import GCG from "./GCG.json";
import material from "./material.json";
import nameCards from "./namecard.json";
import weapon from "./weapon.json";
export const AppAchievementsData = achievements as TGApp.App.Achievement.Item[];
export const AppAchievementSeriesData = achievementSeries as TGApp.App.Achievement.Series[];
export const AppCalendarData = calendar as TGApp.App.Calendar.Item[];
export const AppCharacterData = character as TGApp.App.Character.WikiBriefInfo[];
export const AppGCGData = GCG as TGApp.App.GCG.WikiBriefInfo[];
export const AppMaterialData = material as TGApp.App.Calendar.Material[];
export const AppNameCardsData = nameCards as TGApp.App.NameCard.Item[];
export const AppWeaponData = weapon as TGApp.App.Weapon.WikiBriefInfo[];

View File

@@ -2,9 +2,24 @@
* @file data index
* @description data index
* @author BTMuli<bt-muli@outlook.com>
* @since Alpha v0.1.4
* @since Alpha v0.1.5
*/
import { AppData } from "./app";
// Data
import achievements from "./app/achievements.json";
import achievementSeries from "./app/achievementSeries.json";
import calendar from "./app/calendar.json";
import character from "./app/character.json";
import GCG from "./app/GCG.json";
import material from "./app/material.json";
import nameCards from "./app/namecard.json";
import weapon from "./app/weapon.json";
export const TGAppData = AppData;
export const AppAchievementsData = achievements as TGApp.App.Achievement.Item[];
export const AppAchievementSeriesData = achievementSeries as TGApp.App.Achievement.Series[];
export const AppCalendarData = calendar as TGApp.App.Calendar.Item[];
export const AppCharacterData = character as TGApp.App.Character.WikiBriefInfo[];
export const AppGCGData = GCG as TGApp.App.GCG.WikiBriefInfo[];
export const AppMaterialData = material as TGApp.App.Calendar.Material[];
export const AppNameCardsData = nameCards as TGApp.App.NameCard.Item[];
export const AppWeaponData = weapon as TGApp.App.Weapon.WikiBriefInfo[];

View File

@@ -61,7 +61,7 @@
}"
@click="openImg()"
>
<v-list-item :title="getCardInfo.name" :subtitle="getCardInfo.description">
<v-list-item :title="getCardInfo.name" :subtitle="getCardInfo.desc">
<template #prepend>
<v-img width="80px" style="margin-right: 10px" :src="getCardInfo.icon" />
</template>
@@ -129,11 +129,11 @@ const loadingTitle = ref("正在加载数据" as string);
// data
const title = ref(achievementsStore.title as string);
const getCardInfo = ref({} as BTMuli.SQLite.NameCard);
const getCardInfo = ref({} as TGApp.Sqlite.NameCard.Item);
// series
const seriesList = ref([] as BTMuli.SQLite.AchievementSeries[]);
const seriesList = ref([] as TGApp.Sqlite.Achievement.SeriesTable[]);
const selectedSeries = ref(-1 as number);
const selectedAchievement = ref([] as BTMuli.SQLite.Achievements[]);
const selectedAchievement = ref([] as TGApp.Sqlite.Achievement.SingleTable[]);
const renderAchievement = computed(() => {
return selectedAchievement.value.slice(start.value, start.value + itemCount.value + 1);
});
@@ -349,13 +349,6 @@ async function exportJson () {
width: 100%;
}
.list-container {
position: relative;
width: 100%;
height: 100%;
max-height: calc(100vh - 100px);
}
/* 版本信息 */
.version-icon-series {
font-family: Genshin, serif;

View File

@@ -115,10 +115,10 @@ const router = useRouter();
// 数据
const tab = ref("");
const annoCards = ref({
activity: [] as BTMuli.Genshin.Announcement.ListCard[],
game: [] as BTMuli.Genshin.Announcement.ListCard[],
activity: [] as TGApp.App.Announcement.ListCard[],
game: [] as TGApp.App.Announcement.ListCard[],
});
const annoData = ref({} as BTMuli.Genshin.Announcement.ListData);
const annoData = ref({} as TGApp.BBS.Announcement.ListData);
onMounted(async () => {
loadingTitle.value = "正在获取公告数据";
@@ -139,7 +139,7 @@ async function switchNews () {
await router.push("/news/2");
}
async function toPost (item: BTMuli.Genshin.Announcement.ListCard) {
async function toPost (item: TGApp.App.Announcement.ListCard) {
const path = router.resolve({
name: "游戏内公告",
params: {
@@ -150,7 +150,7 @@ async function toPost (item: BTMuli.Genshin.Announcement.ListCard) {
createTGWindow(path, "游戏内公告", item.title, 960, 720, false, false);
}
async function toJson (item: BTMuli.Genshin.Announcement.ListCard) {
async function toJson (item: TGApp.App.Announcement.ListCard) {
const path = router.resolve({
name: "游戏内公告JSON",
params: {

View File

@@ -246,7 +246,13 @@ onMounted(async () => {
versionTauri.value = await app.getTauriVersion();
osPlatform.value = `${await os.platform()}`;
osVersion.value = await os.version();
dbInfo.value = await TGSqlite.getAppData();
try {
dbInfo.value = await TGSqlite.getAppData();
} catch (e) {
snackbarText.value = "读取数据库失败!";
snackbarColor.value = "warn";
snackbar.value = true;
}
loading.value = false;
});
@@ -484,7 +490,7 @@ async function refreshUser () {
}
const infoRes = await TGRequest.User.byCookie.getUserInfo(ck.cookie_token, ck.account_id);
if (infoRes.hasOwnProperty("nickname")) {
const info = infoRes as BTMuli.User.Base.BriefInfo;
const info = infoRes as TGApp.App.Account.BriefInfo;
userStore.setBriefInfo(info);
loadingTitle.value = "获取成功!正在获取用户游戏账号信息";
} else {
@@ -493,8 +499,8 @@ async function refreshUser () {
}
const accountRes = await TGRequest.User.byCookie.getAccounts(ck.cookie_token, ck.account_id);
if (Array.isArray(accountRes)) {
loadingTitle.value = "获取成功!正在保存到数据库!";
await TGSqlite.insertAccount(accountRes);
loadingTitle.value = "获取成功!";
} else {
loadingTitle.value = "获取失败!";
failCount++;
@@ -538,9 +544,9 @@ async function inputCookie () {
loadingTitle.value = "正在获取用户信息...";
const cookie_token = userStore.getCookieItem("cookie_token");
const resUser = await TGRequest.User.byCookie.getUserInfo(cookie_token, uid);
// . 判断返回是否为 BTMuli.User.Base.BriefInfo
// . 判断返回是否为 BTMuli.User.Account.BriefInfo
if (resUser.hasOwnProperty("nickname")) {
const info = resUser as BTMuli.User.Base.BriefInfo;
const info = resUser as TGApp.App.Account.BriefInfo;
userStore.setBriefInfo(info);
appStore.isLogin = true;
}

View File

@@ -26,7 +26,7 @@ const abyssCookie = ref({
ltoken: "",
ltuid: "",
});
const user = ref({} as BTMuli.User.Game.Account);
const user = ref({} as TGApp.User.Account.Game);
onMounted(async () => {
const curUser = await TGSqlite.getCurAccount();
@@ -44,7 +44,7 @@ onMounted(async () => {
async function getAbyssData (schedule:string): Promise<void> {
const res = await TGRequest.User.byCookie.getAbyss(abyssCookie.value, schedule, user.value);
if (res.hasOwnProperty("retcode")) {
const warn = res as BTMuli.Genshin.Base.Response;
const warn = res as TGApp.BBS.Response.Base;
console.warn(warn);
} else {
console.log(res);

View File

@@ -11,28 +11,24 @@
<script lang="ts" setup>
// vue
import { ref, onMounted } from "vue";
import { ref, computed } from "vue";
import TMiniAvatar from "../../components/t-mini-avatar.vue";
// utils
import { createTGWindow } from "../../utils/TGWindow";
import { TGAppData } from "../../data";
import { AppCharacterData } from "../../data";
import { OBC_CONTENT_API } from "../../plugins/Mys/interface/utils";
// snackbar
const snackbar = ref(false);
// data
const cardsInfo = ref([] as BTMuli.Genshin.Wiki.Character.BriefInfo[]);
const cardsInfo = computed(() => AppCharacterData);
onMounted(async () => {
cardsInfo.value = TGAppData.character;
});
function toOuter (item: BTMuli.Genshin.Wiki.Character.BriefInfo) {
if (item.content_id === null || item.content_id === undefined) {
function toOuter (item: TGApp.App.Character.WikiBriefInfo) {
if (item.contentId === 0) {
snackbar.value = true;
return;
}
const url = OBC_CONTENT_API.replace("{content_id}", item.content_id.toString());
const url = OBC_CONTENT_API.replace("{content_id}", item.contentId.toString());
createTGWindow(url, "角色详情", item.name, 1200, 800, true);
}

View File

@@ -30,7 +30,7 @@
<v-window v-model="tab">
<v-window-item value="character">
<div class="cards-grid">
<v-card v-for="item in CardsInfoC" :key="item.content_id" class="card-cls" @click="toOuter(item.name, item.content_id)">
<v-card v-for="item in CardsInfoC" :key="item.contentId" class="card-cls" @click="toOuter(item.name, item.contentId)">
<div class="card-border">
<img src="/WIKI/GCG/bg/normal.webp" alt="border">
</div>
@@ -45,7 +45,7 @@
</v-window-item>
<v-window-item value="action">
<div class="cards-grid">
<v-card v-for="item in CardsInfoA" :key="item.content_id" class="card-cls" @click="toOuter(item.name, item.content_id)">
<v-card v-for="item in CardsInfoA" :key="item.contentId" class="card-cls" @click="toOuter(item.name, item.contentId)">
<div class="card-border">
<img src="/WIKI/GCG/bg/normal.webp" alt="border">
</div>
@@ -60,7 +60,7 @@
</v-window-item>
<v-window-item value="monster">
<div class="cards-grid">
<v-card v-for="item in CardsInfoM" :key="item.content_id" class="card-cls" @click="toOuter(item.name, item.content_id)">
<v-card v-for="item in CardsInfoM" :key="item.contentId" class="card-cls" @click="toOuter(item.name, item.contentId)">
<div class="card-border">
<img src="/WIKI/GCG/bg/normal.webp" alt="border">
</div>
@@ -77,7 +77,7 @@
</div>
<div v-else>
<div class="cards-grid">
<div v-for="item in CardsInfoS" :key="item.content_id" class="card-cls" @click="toOuter(item.name, item.content_id)">
<div v-for="item in CardsInfoS" :key="item.contentId" class="card-cls" @click="toOuter(item.name, item.contentId)">
<div class="card-border">
<img src="/WIKI/GCG/bg/normal.webp" alt="border">
</div>
@@ -97,16 +97,17 @@
</template>
<script lang="ts" setup>
// vue
import { ref, onMounted } from "vue";
import { ref, onMounted, computed } from "vue";
import TLoading from "../../components/t-loading.vue";
// utils
import { createTGWindow } from "../../utils/TGWindow";
import { TGAppData } from "../../data";
import { AppGCGData } from "../../data";
// interface
import { OBC_CONTENT_API } from "../../plugins/Mys/interface/utils";
// loading
const loading = ref(true);
const allCards = computed(() => AppGCGData);
// snackbar
const snackbar = ref(false);
// search
@@ -114,20 +115,19 @@ const doSearch = ref(false);
const search = ref("");
// data
const tab = ref("character");
const CardsInfoC = ref([] as BTMuli.Genshin.Wiki.GCG.BriefInfo[]);
const CardsInfoA = ref([] as BTMuli.Genshin.Wiki.GCG.BriefInfo[]);
const CardsInfoM = ref([] as BTMuli.Genshin.Wiki.GCG.BriefInfo[]);
const CardsInfoS = ref([] as BTMuli.Genshin.Wiki.GCG.BriefInfo[]);
const CardsInfoC = ref([] as TGApp.App.GCG.WikiBriefInfo[]);
const CardsInfoA = ref([] as TGApp.App.GCG.WikiBriefInfo[]);
const CardsInfoM = ref([] as TGApp.App.GCG.WikiBriefInfo[]);
const CardsInfoS = ref([] as TGApp.App.GCG.WikiBriefInfo[]);
onMounted(async () => {
await loadData();
});
async function loadData () {
const CardsInfo = TGAppData.GCG;
CardsInfoC.value = CardsInfo.filter((item) => item.type === "角色牌");
CardsInfoA.value = CardsInfo.filter((item) => item.type === "行动牌");
CardsInfoM.value = CardsInfo.filter((item) => item.type === "魔物牌");
CardsInfoC.value = allCards.value.filter((item) => item.type === "角色牌");
CardsInfoA.value = allCards.value.filter((item) => item.type === "行动牌");
CardsInfoM.value = allCards.value.filter((item) => item.type === "魔物牌");
loading.value = false;
}
function toOuter (cardName: string, cardId: number) {
@@ -137,9 +137,8 @@ function toOuter (cardName: string, cardId: number) {
async function searchCard () {
loading.value = true;
doSearch.value = true;
const res: BTMuli.Genshin.Wiki.GCG.BriefInfo[] = [];
const allCardsInfo = TGAppData.GCG;
allCardsInfo.map((item) => (item.name.includes(search.value) ? res.push(item) : null));
const res: TGApp.App.GCG.WikiBriefInfo[] = [];
allCards.value.map((item) => (item.name.includes(search.value) ? res.push(item) : null));
res.sort((a, b) => a.name.localeCompare(b.name));
loading.value = false;
if (res.length === 0) {

View File

@@ -11,28 +11,24 @@
<script lang="ts" setup>
// vue
import { ref, onMounted } from "vue";
import { ref, computed } from "vue";
import TMiniWeapon from "../../components/t-mini-weapon.vue";
// utils
import { createTGWindow } from "../../utils/TGWindow";
import { TGAppData } from "../../data";
import { AppWeaponData } from "../../data";
import { OBC_CONTENT_API } from "../../plugins/Mys/interface/utils";
// snackbar
const snackbar = ref(false);
// data
const cardsInfo = ref([] as BTMuli.Genshin.Wiki.Weapon.BriefInfo[]);
const cardsInfo = computed(() => AppWeaponData);
onMounted(async () => {
cardsInfo.value = TGAppData.weapon;
});
function toOuter (item: BTMuli.Genshin.Wiki.Weapon.BriefInfo) {
if (item.content_id === null || item.content_id === undefined) {
function toOuter (item: TGApp.App.Weapon.WikiBriefInfo) {
if (item.contentId === 0) {
snackbar.value = true;
return;
}
const url = OBC_CONTENT_API.replace("{content_id}", item.content_id.toString());
const url = OBC_CONTENT_API.replace("{content_id}", item.contentId.toString());
createTGWindow(url, "武器详情", item.name, 1200, 800, true);
}

View File

@@ -17,10 +17,10 @@ export const useUserStore = defineStore(
avatar: "",
uid: "",
desc: "",
} as BTMuli.User.Base.BriefInfo);
} as TGApp.App.Account.BriefInfo);
const cookie = ref({} as Record<string, string>);
function setBriefInfo (info: BTMuli.User.Base.BriefInfo): void {
function setBriefInfo (info: TGApp.App.Account.BriefInfo): void {
briefInfo.value = info;
}

View File

@@ -5,7 +5,7 @@
* @since Alpha v0.1.5
*/
declare namespace BTMuli.BBS.Announcement {
declare namespace TGApp.BBS.Announcement {
/**
* @description 公告列表返回响应类型
* @interface ListResponse
@@ -84,6 +84,21 @@ declare namespace BTMuli.BBS.Announcement {
* @description 公告列表项
* @interface ListItem
* @since Alpha v0.1.5
* @property {AnnoSingle[]} list - 公告列表
* @property {number} type_id - 公告类型 ID
* @property {string} type_label - 公告类型标签
* @return ListItem
*/
export interface ListItem {
list: AnnoSingle[]
type_id: number
type_label: string
}
/**
* @description 单个公告内容
* @interface AnnoSingle
* @since Alpha v0.1.5
* @property {number} ann_id 公告 ID
* @property {string} title 公告标题
* @property {string} subtitle 公告副标题
@@ -104,9 +119,9 @@ declare namespace BTMuli.BBS.Announcement {
* @property {number} remind_ver 公告提醒版本
* @property {boolean} has_content 是否有内容
* @property {boolean} extra_remind 是否有额外提醒
* @return ListItem
* @return AnnoSingle
*/
export interface ListItem {
export interface AnnoSingle {
ann_id: number
title: string
subtitle: string

View File

@@ -22,22 +22,31 @@ declare namespace TGApp.BBS.Response {
data: any
}
/**
* @description 获取 ltoken 跟 stoken 的响应数据返回
* @interface getTokensRes
* @since Alpha v0.1.5
* @property {string} name - token 名称
* @property {string} token - token 值
* @return getTokensRes
*/
export interface getTokensRes {
name: string
token: string
}
/**
* @description 获取 ltoken 跟 stoken 的响应数据
* @interface getTokens
* @since Alpha v0.1.5
* @todo 添加 request 索引
* @extends Base
* @property {string} data.list[].name - token 名称
* @property {string} data.list[].token - token 值
* @property {getTokensRes[]} data.list - token 列表
* @return getTokens
*/
export interface getTokens extends Base {
data: {
list: Array<{
name: string
token: string
}>
list: getTokensRes[]
}
}

View File

@@ -6,7 +6,7 @@
* @since Alpha v0.2.0
*/
declare namespace BTMuli.Game.Abyss {
declare namespace TGApp.Game.Abyss {
/**
* @description 深渊数据返回类型
* @interface Response

View File

@@ -10,13 +10,13 @@ declare namespace TGApp.User.Account {
* @description 游戏账号返回类型
* @interface GameResponse
* @since Alpha v0.1.5
* @extends BTMuli.Constant.Response.Base
* @property {Game} data.list 游戏账号列表
* @extends TGApp.BBS.Response.Base
* @property {Game[]} data.list 游戏账号列表
* @return GameResponse
*/
export interface GameResponse extends BTMuli.Constant.Response.Base {
export interface GameResponse extends TGApp.BBS.Response.Base {
data: {
list: Game
list: Game[]
}
}

View File

@@ -2,68 +2,71 @@
* @file utils TGSql.ts
* @description 数据库sql语句
* @author BTMuli<bt-muli@outlook.com>
* @since Alpha v0.2.0
* @since Alpha v0.1.5
*/
// tauri
import { app } from "@tauri-apps/api";
// utils
import { getBuildTime } from "./TGBuild";
import { TGAppData } from "../data";
import minifySql from "./minifySql";
import { AppAchievementsData, AppAchievementSeriesData, AppNameCardsData } from "../data";
/**
* @description 初始化应用数据表
* @since Alpha v0.1.4
* @since Alpha v0.1.5
* @returns {string[]} sql
*/
function initAppTable (): string[] {
const sqlRes = [];
// 创建应用数据表
sqlRes.push(`
sqlRes.push(minifySql(`
CREATE TABLE IF NOT EXISTS AppData
(
key TEXT PRIMARY KEY,
value TEXT DEFAULT NULL,
updated TEXT DEFAULT NULL
);
`);
`));
return sqlRes;
}
/**
* @description 初始化游戏账号数据表
* @since Alpha v0.2.0
* @see BTMuli.User.Game.Account
* @since Alpha v0.1.5
* @see TGApp.Sqlite.Account.Game
* @returns {string[]} sql
*/
function initGameAccountTable (): string[] {
const sqlRes = [];
// 创建游戏账号数据表
sqlRes.push(`
sqlRes.push(minifySql(`
CREATE TABLE IF NOT EXISTS GameAccount
(
game_biz TEXT NOT NULL,
game_uid TEXT NOT NULL,
is_chosen BOOLEAN DEFAULT 0,
is_official BOOLEAN DEFAULT 0,
gameBiz TEXT NOT NULL,
gameUid TEXT NOT NULL,
isChosen BOOLEAN DEFAULT 0,
isOfficial BOOLEAN DEFAULT 0,
level INTEGER DEFAULT 0,
nickname TEXT DEFAULT NULL,
region TEXT DEFAULT NULL,
region_name TEXT DEFAULT NULL,
regionName TEXT DEFAULT NULL,
updated TEXT DEFAULT NULL,
PRIMARY KEY (game_biz, game_uid)
PRIMARY KEY (gameBiz, gameUid)
);
`);
`));
return sqlRes;
}
/**
* @description 初始化成就系列数据表
* @since Alpha v0.1.4
* @since Alpha v0.1.5
* @returns {string[]} sql
*/
function initAchievementSeriesTable (): string[] {
const sqlRes = [];
// 创建成就系列数据表
sqlRes.push(`
sqlRes.push(minifySql(`
CREATE TABLE IF NOT EXISTS AchievementSeries
(
id INTEGER PRIMARY KEY,
@@ -76,19 +79,19 @@ function initAchievementSeriesTable (): string[] {
nameCard TEXT NOT NULL,
updated TEXT DEFAULT NULL
);
`);
`));
return sqlRes;
}
/**
* @description 初始化成就数据表
* @since Alpha v0.1.4
* @since Alpha v0.1.5
* @returns {string[]} sql
*/
function initAchievementTable (): string[] {
const sqlRes = [];
// 创建成就数据表
sqlRes.push(`
sqlRes.push(minifySql(`
CREATE TABLE IF NOT EXISTS Achievements
(
id INTEGER PRIMARY KEY,
@@ -103,9 +106,9 @@ function initAchievementTable (): string[] {
version TEXT DEFAULT NULL,
updated TEXT DEFAULT NULL
);
`);
`));
// 创建触发器
sqlRes.push(`
sqlRes.push(minifySql(`
CREATE TRIGGER IF NOT EXISTS updateAchievement
AFTER UPDATE ON Achievements
FOR EACH ROW
@@ -115,8 +118,8 @@ function initAchievementTable (): string[] {
UPDATE AchievementSeries SET finCount = finCount - 1, updated = datetime('now', 'localtime')
WHERE id = NEW.series AND NEW.isCompleted = 0 AND OLD.isCompleted = 1;
END;
`);
sqlRes.push(`
`));
sqlRes.push(minifySql(`
CREATE TRIGGER IF NOT EXISTS insertAchievement
AFTER INSERT ON Achievements
FOR EACH ROW
@@ -126,23 +129,23 @@ function initAchievementTable (): string[] {
UPDATE AchievementSeries SET version = NEW.version, updated = datetime('now', 'localtime')
WHERE id = NEW.series AND NEW.version > version;
END;
`);
`));
return sqlRes;
}
/**
* @description 初始化名片数据表
* @since Alpha v0.1.4
* @since Alpha v0.1.5
* @returns {string[]} sql
*/
function initNameCardTable (): string[] {
const sqlRes = [];
// 创建名片数据表
sqlRes.push(`
sqlRes.push(minifySql(`
CREATE TABLE IF NOT EXISTS NameCard
(
name TEXT PRIMARY KEY,
description TEXT DEFAULT NULL,
"desc" TEXT DEFAULT NULL,
icon TEXT NOT NULL,
bg TEXT NOT NULL,
profile TEXT NOT NULL,
@@ -150,7 +153,7 @@ function initNameCardTable (): string[] {
source TEXT DEFAULT NULL,
updated TEXT DEFAULT NULL
);
`);
`));
return sqlRes;
}
@@ -171,7 +174,7 @@ export function initSQLiteTable (): string[] {
/**
* @description 初始化应用数据
* @since Alpha v0.1.4
* @since Alpha v0.1.5
* @returns {Promise<string[]>} sql
*/
async function initAppData (): Promise<string[]> {
@@ -180,39 +183,38 @@ async function initAppData (): Promise<string[]> {
const buildTime = getBuildTime();
const dataUpdated = buildTime.startsWith("dev") ? buildTime.slice(4) : buildTime;
// 初始化应用版本
sqlRes.push(`
sqlRes.push(minifySql(`
INSERT INTO AppData (key, value, updated)
VALUES ('appVersion', '${appVersion}', datetime('now', 'localtime'))
ON CONFLICT(key) DO UPDATE SET value = '${appVersion}', updated = datetime('now', 'localtime');
`);
`));
// 初始化应用数据更新时间
sqlRes.push(`
sqlRes.push(minifySql(`
INSERT INTO AppData (key, value, updated)
VALUES ('dataUpdated', '${dataUpdated}', datetime('now', 'localtime'))
ON CONFLICT(key) DO UPDATE SET value = '${dataUpdated}', updated = datetime('now', 'localtime');
`);
`));
// 初始化 cookie
sqlRes.push(`
sqlRes.push(minifySql(`
INSERT INTO AppData (key, value, updated)
VALUES ('cookie', '{}', datetime('now', 'localtime'))
ON CONFLICT(key) DO NOTHING;
`);
`));
return sqlRes;
}
/**
* @description 初始化成就系列数据
* @since Alpha v0.1.4
* @since Alpha v0.1.5
* @returns {string[]} sql
*/
function initAchievementSeriesData (): string[] {
const sqlRes: string[] = [];
const oriData = TGAppData.achievementSeries;
oriData.map((data) => {
const sql = `
AppAchievementSeriesData.map((data) => {
const sql = minifySql(`
INSERT OR IGNORE INTO AchievementSeries (id, "order", name, version, icon, nameCard, updated)
VALUES (${data.id}, ${data.order}, '${data.name}', '${data.version}', '${data.icon}', '${data.card}', datetime('now', 'localtime'));
`;
`);
return sqlRes.push(sql);
});
return sqlRes;
@@ -220,17 +222,16 @@ function initAchievementSeriesData (): string[] {
/**
* @description 初始化成就数据
* @since Alpha v0.1.4
* @since Alpha v0.1.5
* @returns {string[]} sql
*/
function initAchievementData (): string[] {
const sqlRes: string[] = [];
const oriData = TGAppData.achievements;
oriData.map((data) => {
const sql = `
AppAchievementsData.map((data) => {
const sql = minifySql(`
INSERT OR IGNORE INTO Achievements (id, series, "order", name, description, reward, version, updated)
VALUES (${data.id}, ${data.series}, ${data.order}, '${data.name}', '${data.description}', ${data.reward}, '${data.version}', datetime('now', 'localtime'));
`;
`);
return sqlRes.push(sql);
});
return sqlRes;
@@ -238,17 +239,16 @@ function initAchievementData (): string[] {
/**
* @description 初始化名片数据
* @since Alpha v0.1.4
* @since Alpha v0.1.5
* @returns {string[]} sql
*/
function initNameCardData (): string[] {
const sqlRes: string[] = [];
const oriData = TGAppData.nameCards;
oriData.map((data) => {
const sql = `
INSERT OR IGNORE INTO NameCard (name, description, icon, bg, profile, type, source, updated)
VALUES ('${data.name}', '${data.description}', '${data.icon}', '${data.bg}', '${data.profile}', ${data.type}, '${data.source}', datetime('now', 'localtime'));
`;
AppNameCardsData.map((data) => {
const sql = minifySql(`
INSERT OR IGNORE INTO NameCard (name, "desc", icon, bg, profile, type, source, updated)
VALUES ('${data.name}', '${data.desc}', '${data.icon}', '${data.bg}', '${data.profile}', ${data.type}, '${data.source}', datetime('now', 'localtime'));
`);
return sqlRes.push(sql);
});
return sqlRes;
@@ -270,11 +270,11 @@ export async function initSQLiteData (): Promise<string[]> {
/**
* @description 导入UIAF数据
* @since Alpha v0.1.4
* @param {TGPlugin.UIAF.Achievement[]} data
* @since Alpha v0.1.5
* @param {TGApp.Plugins.UIAF.Achievement[]} data
* @returns {string[]} sql
*/
export function importUIAFData (data: TGPlugin.UIAF.Achievement[]): string[] {
export function importUIAFData (data: TGApp.Plugins.UIAF.Achievement[]): string[] {
const sqlRes: string[] = [];
data.map((achievement) => {
let sql;
@@ -282,17 +282,17 @@ export function importUIAFData (data: TGPlugin.UIAF.Achievement[]): string[] {
const isCompleted = achievement.status === 2 || achievement.status === 3;
if (isCompleted) {
const completedTime = new Date(achievement.timestamp * 1000).toISOString().replace("T", " ").slice(0, 19);
sql = `
sql = minifySql(`
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 = `
sql = minifySql(`
UPDATE Achievements
SET progress = ${achievement.current}, updated = datetime('now', 'localtime')
WHERE id = ${achievement.id} AND progress != ${achievement.current};
`;
`);
}
return sqlRes.push(sql);
});

View File

@@ -2,13 +2,14 @@
* @file utils TGSqlite.ts
* @description 数据库操作类
* @author BTMuli<bt-muli@outlook.com>
* @since Alpha v0.2.0
* @since Alpha v0.1.5
*/
// tauri
import Database from "tauri-plugin-sql-api";
// utils
import { importUIAFData, initSQLiteData, initSQLiteTable } from "./TGSql";
import minifySql from "./minifySql";
import { getUiafStatus } from "./UIAF";
class TGSqlite {
@@ -59,12 +60,12 @@ class TGSqlite {
* @description 获取数据库信息
* @memberOf TGSqlite
* @since Alpha v0.1.4
* @returns {Promise<{ key: string, value: string, updated: string }[]>}
* @returns {Promise<TGApp.Sqlite.AppData.Item[]>}
*/
public async getAppData (): Promise<Array<{ key: string, value: string, updated: string }>> {
public async getAppData (): Promise<TGApp.Sqlite.AppData.Item[]> {
const db = await Database.load(this.dbPath);
const sql = "SELECT * FROM AppData;";
const res: Array<{ key: string, value: string, updated: string }> = await db.select(sql);
const res: TGApp.Sqlite.AppData.Item[] = await db.select(sql);
await db.close();
return res;
}
@@ -86,29 +87,28 @@ class TGSqlite {
/**
* @description 插入 Account 数据
* @memberOf TGSqlite
* @since Alpha v0.2.0
* @param {BTMuli.User.Game.Account[]} accounts
* @since Alpha v0.1.5
* @param {TGApp.User.Account.Game[]} accounts
* @returns {Promise<void>}
*/
public async insertAccount (accounts: BTMuli.User.Game.Account[]): Promise<void> {
public async insertAccount (accounts: TGApp.User.Account.Game[]): Promise<void> {
const db = await Database.load(this.dbPath);
for (const a of accounts) {
const is_chosen = a.is_chosen ? 1 : 0;
const is_official = a.is_official ? 1 : 0;
const sql = `
INSERT INTO GameAccount (game_biz, game_uid, is_chosen, is_official, level, nickname, region, region_name, updated)
VALUES ('${a.game_biz}', '${a.game_uid}', ${is_chosen}, ${is_official}, '${a.level}', '${a.nickname}',
'${a.region}', '${a.region_name}', datetime('now', 'localtime'))
ON CONFLICT(game_biz, game_uid) DO UPDATE SET
is_chosen = ${is_chosen},
is_official = ${is_official},
level = ${a.level},
nickname = '${a.nickname}',
region = '${a.region}',
region_name = '${a.region_name}',
updated = datetime('now', 'localtime');
`;
console.log(sql);
const isChosen = a.is_chosen ? 1 : 0;
const isOfficial = a.is_official ? 1 : 0;
const sql = minifySql(`
INSERT INTO GameAccount (gameBiz, gameUid, isChosen, isOfficial, level, nickname, region, regionName, updated)
VALUES ('${a.game_biz}', '${a.game_uid}', ${isChosen}, ${isOfficial}, '${a.level}', '${a.nickname}',
'${a.region}', '${a.region_name}', datetime('now', 'localtime'))
ON CONFLICT(gameBiz, gameUid) DO UPDATE SET
isChosen = ${isChosen},
isOfficial = ${isOfficial},
level = ${a.level},
nickname = '${a.nickname}',
region = '${a.region}',
regionName = '${a.region_name}',
updated = datetime('now', 'localtime');
`);
await db.execute(sql);
}
await db.close();
@@ -118,12 +118,12 @@ class TGSqlite {
* @description 获取当前选择的游戏账号
* @memberOf TGSqlite
* @since Alpha v0.2.0
* @returns {Promise<BTMuli.User.Game.Account|false>}
* @returns {Promise<TGApp.User.Account.Game|false>}
*/
public async getCurAccount (): Promise<BTMuli.User.Game.Account | false> {
public async getCurAccount (): Promise<TGApp.User.Account.Game | false> {
const db = await Database.load(this.dbPath);
const sql = "SELECT * FROM GameAccount WHERE is_chosen=1;";
const res: BTMuli.User.Game.Account[] = await db.select(sql);
const sql = "SELECT * FROM GameAccount WHERE isChosen=1;";
const res: TGApp.User.Account.Game[] = await db.select(sql);
await db.close();
return res.length === 0 ? false : res[0];
}
@@ -131,18 +131,18 @@ class TGSqlite {
/**
* @description 保存 appData
* @memberOf TGSqlite
* @since Alpha v0.2.0
* @since Alpha v0.1.5
* @param {string} key
* @param {string} value
* @returns {Promise<void>}
*/
public async saveAppData (key: string, value: string): Promise<void> {
const db = await Database.load(this.dbPath);
const sql = `
const sql = minifySql(`
INSERT INTO AppData (key, value, updated)
VALUES ('${key}', '${value}', datetime('now', 'localtime'))
ON CONFLICT(key) DO UPDATE SET value = '${value}',updated = datetime('now', 'localtime');
`;
`);
await db.execute(sql);
await db.close();
}
@@ -175,7 +175,7 @@ class TGSqlite {
const sqlT = "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;";
const res: Array<{ name: string }> = await db.select(sqlT);
// 考虑到 sqlite_sequence 表,所以需要 +1
if (res.length === this.tables.length + 1) {
if (res.length === this.tables.length) {
if (this.tables.every((item) => res.map((i) => i.name).includes(item))) {
isVerified = true;
}
@@ -203,13 +203,13 @@ class TGSqlite {
/**
* @description 获取成就系列列表
* @memberOf TGSqlite
* @since Alpha v0.1.4
* @returns {Promise<BTMuli.SQLite.AchievementSeries[]>}
* @since Alpha v0.1.5
* @returns {Promise<TGApp.Sqlite.Achievement.SeriesTable[]>}
*/
public async getAchievementSeries (): Promise<BTMuli.SQLite.AchievementSeries[]> {
public async getAchievementSeries (): Promise<TGApp.Sqlite.Achievement.SeriesTable[]> {
const db = await Database.load(this.dbPath);
const sql = "SELECT * FROM AchievementSeries ORDER BY `order`;";
const res: BTMuli.SQLite.AchievementSeries[] = await db.select(sql);
const res: TGApp.Sqlite.Achievement.SeriesTable[] = await db.select(sql);
await db.close();
return res;
}
@@ -217,17 +217,14 @@ class TGSqlite {
/**
* @description 获取成就系列对应的名片
* @memberOf TGSqlite
* @since Alpha v0.1.4
* @since Alpha v0.1.5
* @param {number} seriesId 系列 ID
* @returns {Promise<BTMuli.SQLite.NameCard>}
* @returns {Promise<TGApp.Sqlite.NameCard.Item>}
*/
public async getNameCard (seriesId: number): Promise<BTMuli.SQLite.NameCard> {
public async getNameCard (seriesId: number): Promise<TGApp.Sqlite.NameCard.Item> {
const db = await Database.load(this.dbPath);
const sql = `SELECT *
FROM NameCard
WHERE name = (SELECT nameCard FROM AchievementSeries WHERE id = ${seriesId});
`;
const res: BTMuli.SQLite.NameCard[] = await db.select(sql);
const sql = `SELECT * FROM NameCard WHERE name = (SELECT nameCard FROM AchievementSeries WHERE id = ${seriesId});`;
const res: TGApp.Sqlite.NameCard.Item[] = await db.select(sql);
await db.close();
return res[0];
}
@@ -236,10 +233,10 @@ class TGSqlite {
* @description 获取成就列表
* @memberOf TGSqlite
* @param {number} [seriesId] 系列 ID
* @since Alpha v0.1.4
* @returns {Promise<BTMuli.SQLite.Achievements[]>}
* @since Alpha v0.1.5
* @returns {Promise<TGApp.Sqlite.Achievement.SingleTable[]>}
*/
public async getAchievements (seriesId?: number): Promise<BTMuli.SQLite.Achievements[]> {
public async getAchievements (seriesId?: number): Promise<TGApp.Sqlite.Achievement.SingleTable[]> {
const db = await Database.load(this.dbPath);
let sql;
if (seriesId) {
@@ -247,7 +244,7 @@ class TGSqlite {
} else {
sql = "SELECT * FROM Achievements ORDER BY isCompleted, `order`;";
}
const res: BTMuli.SQLite.Achievements[] = await db.select(sql);
const res: TGApp.Sqlite.Achievement.SingleTable[] = await db.select(sql);
await db.close();
return res;
}
@@ -270,24 +267,20 @@ class TGSqlite {
* @description 查询成就
* @memberOf TGSqlite
* @param {string} keyword 关键词
* @since Alpha v0.1.4
* @returns {Promise<BTMuli.SQLite.Achievements[]>}
* @since Alpha v0.1.5
* @returns {Promise<TGApp.Sqlite.Achievement.SingleTable[]>}
*/
public async searchAchievements (keyword: string): Promise<BTMuli.SQLite.Achievements[]> {
public async searchAchievements (keyword: string): Promise<TGApp.Sqlite.Achievement.SingleTable[]> {
const db = await Database.load(this.dbPath);
let sql;
if (keyword.startsWith("v")) {
const version = keyword.replace("v", "");
sql = `SELECT * FROM Achievements WHERE version LIKE '%${version}%' ORDER BY isCompleted, \`order\`;`;
} else {
sql = `SELECT *
FROM Achievements
WHERE name LIKE '%${keyword}%'
OR description LIKE '%${keyword}%'
ORDER BY isCompleted, \`order\`;
`;
sql = `SELECT * FROM Achievements WHERE name LIKE '%${keyword}%' OR description LIKE '%${keyword}%'
ORDER BY isCompleted, \`order\`;`;
}
const res: BTMuli.SQLite.Achievements[] = await db.select(sql);
const res: TGApp.Sqlite.Achievement.SingleTable[] = await db.select(sql);
await db.close();
return res;
}
@@ -295,11 +288,11 @@ class TGSqlite {
/**
* @description 合并 UIAF 数据
* @memberOf TGSqlite
* @param {BTMuli.UIAF.Achievement[]} achievements UIAF 数据
* @param {TGApp.Plugins.UIAF.Achievement[]} achievements UIAF 数据
* @since Alpha v0.1.4
* @returns {Promise<void>}
*/
public async mergeUIAF (achievements: TGPlugin.UIAF.Achievement[]): Promise<void> {
public async mergeUIAF (achievements: TGApp.Plugins.UIAF.Achievement[]): Promise<void> {
const db = await Database.load(this.dbPath);
const sql = importUIAFData(achievements);
for (const item of sql) {
@@ -312,14 +305,14 @@ class TGSqlite {
* @description 获取 UIAF 数据
* @memberOf TGSqlite
* @since Alpha v0.1.4
* @returns {Promise<TGPlugin.UIAF.Achievement[]>}
* @returns {Promise<TGApp.Plugins.UIAF.Achievement[]>}
*/
public async getUIAF (): Promise<TGPlugin.UIAF.Achievement[]> {
public async getUIAF (): Promise<TGApp.Plugins.UIAF.Achievement[]> {
const db = await Database.load(this.dbPath);
const sql = "SELECT * FROM Achievements WHERE isCompleted = 1 OR progress > 0";
const res: BTMuli.SQLite.Achievements[] = await db.select(sql);
const res: TGApp.Sqlite.Achievement.SingleTable[] = await db.select(sql);
await db.close();
const achievements: TGPlugin.UIAF.Achievement[] = [];
const achievements: TGApp.Plugins.UIAF.Achievement[] = [];
for (const item of res) {
const completed = item.isCompleted === 1;
const status = getUiafStatus(completed, item.progress);

View File

@@ -49,9 +49,9 @@ export function getUiafStatus (completed: boolean, progress: number): number {
/**
* @description 获取 UIAF 头部信息
* @since Alpha v0.1.3
* @returns {Promise<TGPlugin.UIAF.Header>}
* @returns {Promise<TGApp.Plugins.UIAF.Export>}
*/
export async function getUiafHeader (): Promise<TGPlugin.UIAF.Header> {
export async function getUiafHeader (): Promise<TGApp.Plugins.UIAF.Export> {
return {
// eslint-disable-next-line camelcase
export_app: "Tauri.Genshin",
@@ -73,7 +73,7 @@ export async function getUiafHeader (): Promise<TGPlugin.UIAF.Header> {
*/
export async function verifyUiafData (path: string): Promise<boolean> {
const fileData: string = await fs.readTextFile(path);
const UiafData: TGPlugin.UIAF.Header = JSON.parse(fileData).info;
const UiafData: TGApp.Plugins.UIAF.Export = JSON.parse(fileData).info;
return UiafData.uiaf_version !== undefined;
}
@@ -99,10 +99,10 @@ export async function readUiafData (userPath: string): Promise<string | false> {
/**
* @description 根据成就数据导出 UIAF 数据
* @since Alpha v0.1.4
* @param {TGPlugin.UIAF.Achievement[]} achievementData - 成就数据
* @param {TGApp.Plugins.UIAF.Achievement[]} achievementData - 成就数据
* @returns {Promise<void>}
*/
export async function backupUiafData (achievementData: TGPlugin.UIAF.Achievement[]): Promise<void> {
export async function backupUiafData (achievementData: TGApp.Plugins.UIAF.Achievement[]): Promise<void> {
const savePath = `${await path.appLocalDataDir()}\\userData\\UIAF.json`;
await fs.writeTextFile(savePath, JSON.stringify(achievementData, null, 2));
}
@@ -118,7 +118,7 @@ export async function restoreUiafData (): Promise<boolean> {
if (!await fs.exists(uiafPath)) {
return false;
}
const uiafData = JSON.parse(await fs.readTextFile(uiafPath)) as TGPlugin.UIAF.Achievement[];
const uiafData = JSON.parse(await fs.readTextFile(uiafPath)) as TGApp.Plugins.UIAF.Achievement[];
await TGSqlite.mergeUIAF(uiafData);
return true;
}

18
src/utils/minifySql.ts Normal file
View File

@@ -0,0 +1,18 @@
/**
* @file utils minifySql.ts
* @description 减少 sql 语句体积的工具函数
* @author BTMuli<bt-muli@outlook.com>
* @since Alpha v0.1.5
*/
/**
* @description 减少 sql 语句体积的工具函数
* @function minifySql
* @param {string} sql - sql 语句
* @return {string} minifiedSql - 减少体积后的 sql 语句
*/
function minifySql (sql: string): string {
return sql.replace(/\n/g, " ").replace(/\s+/g, " ").trim();
}
export default minifySql;

View File

@@ -47,8 +47,8 @@ onMounted(async () => {
// 获取数据
loadingTitle.value = "正在获取数据...";
const listData = await TGRequest.Anno.getList();
listData.list.map((item: BTMuli.Genshin.Announcement) => {
return item.list.map((single: BTMuli.Genshin.Announcement.ListItem) => {
listData.list.map((item: TGApp.BBS.Announcement.ListItem) => {
return item.list.map((single: TGApp.BBS.Announcement.AnnoSingle) => {
return single.ann_id === annoId ? (jsonList = single) : null;
});
});

View File

@@ -34,7 +34,7 @@ const loadingEmpty = ref(false as boolean);
// 数据
const annoId = Number(useRoute().params.anno_id);
const annoData = ref({} as BTMuli.Genshin.Announcement.ContentItem);
const annoData = ref({} as TGApp.BBS.Announcement.ContentItem);
const annoHtml = ref("");
onMounted(async () => {

View File

@@ -18,20 +18,20 @@ import { getRequestHeader } from "../utils/getRequestHeader";
* @since Alpha v0.2.0
* @param {Record<string, string>} cookie cookie
* @param {string} schedule_type 0: 本期, 1: 上期
* @param {BTMuli.User.Game.Account} account 游戏账号
* @returns {Promise<unknown|BTMuli.Genshin.Base.Response>}
* @param {TGApp.User.Game.Account} account 游戏账号
* @returns {Promise<TGApp.Game.Abyss.FullData|TGApp.App.Base.Response>}
*/
export async function getAbyss (cookie: Record<string, string>, schedule_type: string, account: BTMuli.User.Game.Account): Promise<unknown | BTMuli.Genshin.Base.Response> {
export async function getAbyss (cookie: Record<string, string>, schedule_type: string, account: TGApp.User.Account.Game): Promise<TGApp.Game.Abyss.FullData | TGApp.BBS.Response.Base> {
const url = TGApi.GameData.getAbyss;
const role_id = account.game_uid;
const params = { role_id, schedule_type, server: getServerByUid(role_id) };
const header = getRequestHeader(cookie, "GET", params, "common");
return await http.fetch<any>(url, {
return await http.fetch<TGApp.Game.Abyss.Response>(url, {
method: "GET",
headers: header,
query: params,
}).then(res => {
if (res.data.retcode !== 0) return res.data;
return res.data.data as unknown;
return res.data.data;
});
}

View File

@@ -7,27 +7,27 @@
// Tauri
import { http } from "@tauri-apps/api";
// Tauri.Genshin
// Tauri.App
import TGApi from "../api/TGApi";
/**
* @description 获取游戏内公告列表
* @since Alpha v0.1.2
* @returns {Promise<BTMuli.Genshin.Announcement.ListData>}
* @returns {Promise<TGApp.BBS.Announcement.ListData>}
*/
export async function getAnnoList (): Promise<BTMuli.Genshin.Announcement.ListData> {
return await http.fetch<BTMuli.Genshin.Announcement.ListResponse>(`${TGApi.GameAnnoList}${TGApi.GameAnnoQuery}`).then((res) => res.data.data);
export async function getAnnoList (): Promise<TGApp.BBS.Announcement.ListData> {
return await http.fetch<TGApp.BBS.Announcement.ListResponse>(`${TGApi.GameAnnoList}${TGApi.GameAnnoQuery}`).then((res) => res.data.data);
}
/**
* @description 获取游戏内公告内容
* @since Alpha v0.1.2
* @param {number} annId 公告 ID
* @returns {Promise<BTMuli.Genshin.Announcement.ContentItem>}
* @returns {Promise<TGApp.BBS.Announcement.ContentItem>}
*/
export async function getAnnoContent (annId: number): Promise<BTMuli.Genshin.Announcement.ContentItem> {
const annoContents: BTMuli.Genshin.Announcement.ContentItem[] = await http
.fetch<BTMuli.Genshin.Announcement.ContentResponse>(`${TGApi.GameAnnoContent}${TGApi.GameAnnoQuery}`)
export async function getAnnoContent (annId: number): Promise<TGApp.BBS.Announcement.ContentItem> {
const annoContents: TGApp.BBS.Announcement.ContentItem[] = await http
.fetch<TGApp.BBS.Announcement.ContentResponse>(`${TGApi.GameAnnoContent}${TGApi.GameAnnoQuery}`)
.then((res) => res.data.data.list);
const annoContent = annoContents.find((item) => item.ann_id === annId);
if (annoContent) {

View File

@@ -2,7 +2,7 @@
* @file web request getCookieToken.ts
* @description 获取 Cookie Token 的请求函数
* @author BTMuli<bt-muli@outlook.com>
* @since Alpha v0.2.0
* @since Alpha v0.1.5
*/
// tauri
@@ -14,12 +14,12 @@ import TGUtils from "../utils/TGUtils";
/**
* @description 根据 stoken 获取 cookie_token
* @since Alpha v0.2.0
* @since Alpha v0.1.5
* @param {string} stuid 登录用户 uid
* @param {string} stoken stoken
* @returns {Promise<string|BTMuli.Genshin.Base.Response>}
* @returns {Promise<string|TGApp.BBS.Response.Base>}
*/
export async function getCookieTokenBySToken (stuid: string, stoken: string): Promise<string | BTMuli.Genshin.Base.Response> {
export async function getCookieTokenBySToken (stuid: string, stoken: string): Promise<string | TGApp.BBS.Response.Base> {
const url = TGApi.GameTokens.getCookieToken;
const cookie = {
stuid,
@@ -27,10 +27,10 @@ export async function getCookieTokenBySToken (stuid: string, stoken: string): Pr
};
const params = { stoken };
const header = TGUtils.User.getHeader(cookie, "GET", params, "common");
return await http.fetch<BTMuli.User.Response.CookieToken>(url, {
return await http.fetch<TGApp.BBS.Response.getCookieTokenBySToken>(url, {
method: "GET",
headers: header,
body: http.Body.json(params),
query: params,
}).then((res) => {
if (res.data.retcode !== 0) return res.data;
return res.data.data.cookie_token;

View File

@@ -1,21 +1,21 @@
/**
* @file web request getEnkaData.ts
* @description 获取 ENKA 数据
* @author BTMuli<bt-muli@outlook.com>
* @since Alpha v0.1.3
*/
// Tauri
import { http } from "@tauri-apps/api";
// Tauri.Genshin
import TGApi from "../api/TGApi";
/**
* @description 获取 ENKA 数据
* @since Alpha v0.1.3
* @param {number} uid 用户 UID
* @returns {Promise<BTMuli.Genshin.Enka.Data>}
*/
export async function getEnkaData (uid: number): Promise<BTMuli.Genshin.Enka.Data> {
return await http.fetch<BTMuli.Genshin.Enka.Data>(`${TGApi.GameEnka}${uid}`).then((res) => res.data);
}
// /**
// * @file web request getEnkaData.ts
// * @description 获取 ENKA 数据
// * @author BTMuli<bt-muli@outlook.com>
// * @since Alpha v0.1.3
// */
//
// // Tauri
// import { http } from "@tauri-apps/api";
// // Tauri.App
// import TGApi from "../api/TGApi";
//
// /**
// * @description 获取 ENKA 数据
// * @since Alpha v0.1.3
// * @param {number} uid 用户 UID
// * @returns {Promise<TGApp.Plugins.Enka>}
// */
// export async function getEnkaData (uid: number): Promise<BTMuli.App.Enka.Data> {
// return await http.fetch<BTMuli.App.Enka.Data>(`${TGApi.GameEnka}${uid}`).then((res) => res.data);
// }

View File

@@ -2,7 +2,7 @@
* @file web request getGameAccounts.ts
* @description 获取游戏账号信息相关请求函数
* @author BTMuli<bt-muli@outlook.com>
* @since Alpha v0.2.0
* @since Alpha v0.1.5
*/
// tauri
@@ -15,12 +15,12 @@ import TGConstant from "../constant/TGConstant";
/**
* @description 通过 stoken 获取游戏账号
* @since Alpha v0.2.0
* @since Alpha v0.1.5
* @param {string} stoken stoken
* @param {string} stuid 登录用户 uid
* @returns {Promise<BTMuli.User.Game.Account[]|BTMuli.Genshin.Base.Response>}
* @returns {Promise<TGApp.User.Game.Account[]|TGApp.BBS.Response.Base>}
*/
export async function getGameAccountsBySToken (stoken: string, stuid: string): Promise<BTMuli.User.Game.Account[] | BTMuli.Genshin.Base.Response> {
export async function getGameAccountsBySToken (stoken: string, stuid: string): Promise<TGApp.User.Account.Game[] | TGApp.BBS.Response.Base> {
const url = TGApi.GameData.bySToken.getAccounts;
const cookie = {
stuid,
@@ -32,12 +32,12 @@ export async function getGameAccountsBySToken (stoken: string, stuid: string): P
/**
* @description 通过 cookie 获取游戏账号
* @since Alpha v0.2.0
* @since Alpha v0.1.5
* @param {string} cookie_token cookie_token
* @param {string} account_id 游戏账号 id
* @returns {Promise<BTMuli.User.Game.Account[]|BTMuli.Genshin.Base.Response>}
* @returns {Promise<TGApp.User.Account.Game[]|TGApp.BBS.Response.Base>}
*/
export async function getGameAccountsByCookie (cookie_token: string, account_id: string): Promise<BTMuli.User.Game.Account[] | BTMuli.Genshin.Base.Response> {
export async function getGameAccountsByCookie (cookie_token: string, account_id: string): Promise<TGApp.User.Account.Game[] | TGApp.BBS.Response.Base> {
const url = TGApi.GameData.byCookie.getAccounts;
const cookie = {
account_id,
@@ -53,14 +53,14 @@ export async function getGameAccountsByCookie (cookie_token: string, account_id:
* @param {string} url 请求地址
* @param {Record<string, string>} cookie cookie
* @param {Record<string, string>} params 请求参数
* @returns {Promise<BTMuli.User.Game.Account[]|BTMuli.Genshin.Base.Response>}
* @returns {Promise<TGApp.User.Account.Game[]|TGApp.BBS.Response.Base>}
*/
async function getGameAccounts (url: string, cookie: Record<string, string>, params: Record<string, string>): Promise<BTMuli.User.Game.Account[] | BTMuli.Genshin.Base.Response> {
async function getGameAccounts (url: string, cookie: Record<string, string>, params: Record<string, string>): Promise<TGApp.BBS.Response.Base | TGApp.User.Account.Game[]> {
const header = TGUtils.User.getHeader(cookie, "GET", params, "common");
return await http.fetch<BTMuli.User.Response.GameAccounts>(url, {
return await http.fetch<TGApp.User.Account.GameResponse>(url, {
method: "GET",
headers: header,
body: http.Body.json(params),
query: params,
}).then(res => {
if (res.data.retcode !== 0) return res.data;
return res.data.data.list;

View File

@@ -2,7 +2,7 @@
* @file web request getLToken.ts
* @description 获取 ltoken 的请求
* @author BTMuli<bt-muli@outlook.com>
* @since Alpha v0.2.0
* @since Alpha v0.1.5
*/
// tauri
@@ -14,12 +14,12 @@ import TGUtils from "../utils/TGUtils";
/**
* @description 根据 stoken 获取 ltoken
* @since Alpha v0.2.0
* @since Alpha v0.1.5
* @param {string} stuid 登录用户 uid
* @param {string} stoken stoken
* @returns {Promise<string|BTMuli.Genshin.Base.Response>}
* @returns {Promise<string|TGApp.BBS.Response.Base>}
*/
export async function getLTokenBySToken (stuid: string, stoken: string): Promise<string | BTMuli.Genshin.Base.Response> {
export async function getLTokenBySToken (stuid: string, stoken: string): Promise<string | TGApp.BBS.Response.Base> {
const url = TGApi.GameTokens.getLToken;
const cookie = {
stuid,
@@ -27,10 +27,10 @@ export async function getLTokenBySToken (stuid: string, stoken: string): Promise
};
const params = { stoken };
const header = TGUtils.User.getHeader(cookie, "GET", params, "common");
return await http.fetch<BTMuli.User.Response.LToken>(url, {
return await http.fetch<TGApp.BBS.Response.getLTokenBySToken>(url, {
method: "GET",
headers: header,
body: http.Body.json(params),
query: params,
}).then((res) => {
if (res.data.retcode !== 0) return res.data;
return res.data.data.ltoken;

View File

@@ -2,7 +2,7 @@
* @file web request getTokens.ts
* @description 获取游戏 Token
* @author BTMuli<bt-muli@outlook.com>
* @since Alpha v0.2.0
* @since Alpha v0.1.5
*/
// tauri
@@ -14,12 +14,12 @@ import TGUtils from "../utils/TGUtils";
/**
* @description 根据 login_ticket 获取游戏 Token包括 stoken 和 ltoken
* @since Alpha v0.2.0
* @since Alpha v0.1.5
* @param {string} ticket 登录票证
* @param {string} uid 登录用户 uid
* @returns {Promise<BTMuli.User.Base.TokenItem[] | BTMuli.Genshin.Base.Response>}
* @returns {Promise<TGApp.BBS.Response.getTokensRes[] | TGApp.BBS.Response.Base>}
*/
export async function getTokensByLoginTicket (ticket: string, uid: string): Promise<BTMuli.User.Response.TokenItem[] | BTMuli.Genshin.Base.Response> {
export async function getTokensByLoginTicket (ticket: string, uid: string): Promise<TGApp.BBS.Response.getTokensRes[] | TGApp.BBS.Response.Base> {
const cookie = {
login_ticket: ticket,
login_uid: uid,
@@ -28,10 +28,10 @@ export async function getTokensByLoginTicket (ticket: string, uid: string): Prom
// eslint-disable-next-line camelcase
const params = { login_ticket: ticket, token_types: 3, uid };
const header = TGUtils.User.getHeader(cookie, "GET", params, "common");
return await http.fetch<BTMuli.User.Response.Tokens>(url, {
return await http.fetch<TGApp.BBS.Response.getTokens>(url, {
method: "GET",
headers: header,
body: http.Body.json(params),
query: params,
}).then((res) => {
console.log(res);
if (res.data.retcode !== 0) return res.data;

View File

@@ -2,7 +2,7 @@
* @file web request getUserInfo.ts
* @description 获取用户信息请求
* @author BTMuli<bt-muli@outlook.com>
* @since Alpha v0.2.0
* @since Alpha v0.1.5
*/
// tauri
@@ -19,20 +19,20 @@ import { type UserResponse } from "../../plugins/Mys/interface/user";
* @since Alpha v0.2.0
* @param {string} cookie_token cookie token
* @param {string} account_id 用户 account_id
* @returns {Promise<BTMuli.User.Base.BriefInfo | BTMuli.Genshin.Base.Response>}
* @returns {Promise<TGApp.App.Account.BriefInfo | TGApp.BBS.Response.Base>}
*/
export async function getUserInfoByCookie (cookie_token: string, account_id: string): Promise<BTMuli.User.Base.BriefInfo | BTMuli.Genshin.Base.Response> {
export async function getUserInfoByCookie (cookie_token: string, account_id: string): Promise<TGApp.App.Account.BriefInfo | TGApp.BBS.Response.Base> {
const cookie = {
cookie_token,
account_id,
};
const url = TGApi.GameData.byCookie.getUserInfo;
const params = { gids: 2 };
const params = { gids: "2" };
const header = TGUtils.User.getSignHeader(cookie, "GET", {}, "common");
return await http.fetch<UserResponse>(url, {
method: "GET",
headers: header,
body: http.Body.json(params),
query: params,
}).then((res) => {
if (res.data.retcode !== 0) return res.data;
const info = res.data.data.user_info;

View File

@@ -2,7 +2,7 @@
* @file web request initCookie.ts
* @description 首次输入 cookie 后的一系列请求
* @author BTMuli<bt-muli@outlook.com>
* @since Alpha v0.2.0
* @since Alpha v0.1.5
*/
// utils
@@ -14,14 +14,14 @@ import { verifyLToken } from "./verifyLToken";
/**
* @description 根据输入 cookie 获取一堆 token
* @since Alpha v0.2.0
* @since Alpha v0.1.5
* @param {string} ticket login_ticket
* @param {string} uid login_uid
* @returns {Promise<void>}
*/
async function initCookie (ticket: string, uid: string): Promise<void> {
const tokenRes = await getTokensByLoginTicket(ticket, uid);
const cookie: BTMuli.User.Base.Cookie = {
const cookie: TGApp.BBS.Constant.Cookie = {
account_id: uid,
cookie_token: "",
login_ticket: ticket,

View File

@@ -2,7 +2,7 @@
* @file web request verifyLToken.ts
* @description 验证 stoken 的请求函数
* @author BTMuli<bt-muli@outlook.com>
* @since Alpha v0.2.0
* @since Alpha v0.1.5
*/
// tauri
@@ -14,12 +14,12 @@ import TGUtils from "../utils/TGUtils";
/**
* @description 验证 ltoken 有效性,返回 mid
* @since Alpha v0.2.0
* @since Alpha v0.1.5
* @param {string} ltoken ltoken
* @param {string} ltuid 登录用户 uid
* @returns {Promise<string | BTMuli.Genshin.Base.Response>}
* @returns {Promise<string | TGApp.BBS.Response.Base>}
*/
export async function verifyLToken (ltoken: string, ltuid: string): Promise<string | BTMuli.Genshin.Base.Response> {
export async function verifyLToken (ltoken: string, ltuid: string): Promise<string | TGApp.BBS.Response.Base> {
const url = TGApi.GameTokens.verifyLToken;
const cookie = {
ltoken,
@@ -27,8 +27,7 @@ export async function verifyLToken (ltoken: string, ltuid: string): Promise<stri
};
const data = { ltoken };
const header = TGUtils.User.getHeader(cookie, "POST", data, "common");
console.log("header:", header);
return await http.fetch<BTMuli.User.Response.Verify>(url, {
return await http.fetch<TGApp.BBS.Response.verifyUserInfoBySToken>(url, {
method: "POST",
headers: header,
body: http.Body.json(data),

View File

@@ -2,7 +2,7 @@
* @file web utils backupData.ts
* @description 数据备份
* @author BTMuli<bt-muli@outlook.com>
* @since Alpha v0.2.0
* @since Alpha v0.1.5
*/
// tauri

View File

@@ -11,13 +11,13 @@ const defaultCover = "/source/UI/defaultCover.webp";
/**
* @description 将获取到的数据转为渲染用的卡片
* @since Alpha v0.1.2
* @param {BTMuli.Genshin.Announcement.ListData} data 公告数据
* @returns {BTMuli.Genshin.Announcement.ListCard[]} 渲染用的卡片
* @param {TGApp.BBS.Announcement.ListData[]} data 公告数据
* @returns {TGApp.App.Announcement.ListCard[]} 渲染用的卡片
*/
export function getAnnoCard (data: BTMuli.Genshin.Announcement.ListData): BTMuli.Genshin.Announcement.ListCard[] {
const cards: BTMuli.Genshin.Announcement.ListCard[] = [];
data.list.map((annoList: BTMuli.Genshin.Announcement) => {
return annoList.list.map((anno: BTMuli.Genshin.Announcement.ListItem) => {
export function getAnnoCard (data: TGApp.BBS.Announcement.ListData): TGApp.App.Announcement.ListCard[] {
const cards: TGApp.App.Announcement.ListCard[] = [];
data.list.map((annoList: TGApp.BBS.Announcement.ListItem) => {
return annoList.list.map((anno: TGApp.BBS.Announcement.AnnoSingle) => {
return cards.push({
id: anno.ann_id,
title: anno.title,