♻️ 全面整理重构

This commit is contained in:
目棃
2024-12-13 16:15:01 +08:00
parent 86bfc80b57
commit 3ed6d503d4
229 changed files with 3105 additions and 4127 deletions

View File

@@ -37,9 +37,8 @@
v-model:cur="selectedSeries"
:series="item"
:uid="uidCur"
@click="selectSeries(item)"
@click="selectedSeries = item"
/>
<div style="height: 10px" />
</template>
</v-virtual-scroll>
<TuaAchiList
@@ -53,54 +52,45 @@
</template>
<script lang="ts" setup>
import showDialog from "@comp/func/dialog.js";
import showLoading from "@comp/func/loading.js";
import showSnackbar from "@comp/func/snackbar.js";
import TuaAchiList from "@comp/userAchi/tua-achi-list.vue";
import TuaSeries from "@comp/userAchi/tua-series.vue";
import TSUserAchi from "@Sqlite/modules/userAchi.js";
import { path } from "@tauri-apps/api";
import { listen, UnlistenFn } from "@tauri-apps/api/event";
import { listen, type UnlistenFn } from "@tauri-apps/api/event";
import { open, save } from "@tauri-apps/plugin-dialog";
import { writeTextFile } from "@tauri-apps/plugin-fs";
import { computed, onMounted, onUnmounted, ref, watch } from "vue";
import { computed, onMounted, onUnmounted, ref, shallowRef, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
import showDialog from "../../components/func/dialog.js";
import showLoading from "../../components/func/loading.js";
import showSnackbar from "../../components/func/snackbar.js";
import TuaAchiList from "../../components/userAchi/tua-achi-list.vue";
import TuaSeries from "../../components/userAchi/tua-series.vue";
import { AppAchievementSeriesData } from "../../data/index.js";
import TSUserAchi from "../../plugins/Sqlite/modules/userAchi.js";
import TGLogger from "../../utils/TGLogger.js";
import { AppAchievementSeriesData } from "@/data/index.js";
import TGLogger from "@/utils/TGLogger.js";
import {
getUiafHeader,
readUiafData,
verifyUiafData,
verifyUiafDataClipboard,
} from "../../utils/UIAF.js";
} from "@/utils/UIAF.js";
const seriesList = AppAchievementSeriesData.sort((a, b) => a.order - b.order).map((s) => s.id);
const route = useRoute();
const router = useRouter();
let achiListener: UnlistenFn | null = null;
const search = ref<string>("");
const isSearch = ref<boolean>(false);
const hideFin = ref<boolean>(false);
const uidList = ref<number[]>([]);
const uidCur = ref<number>(0);
const overview = ref<TGApp.Sqlite.Achievement.Overview>({ fin: 0, total: 1 });
const seriesList = AppAchievementSeriesData.sort((a, b) => a.order - b.order).map((s) => s.id);
const selectedSeries = ref<number>(-1);
const overview = shallowRef<TGApp.Sqlite.Achievement.Overview>({ fin: 0, total: 1 });
const title = computed<string>(() => {
const percentage = ((overview.value.fin * 100) / overview.value.total).toFixed(2);
return `${overview.value.fin}/${overview.value.total} ${percentage}%`;
});
const route = useRoute();
const router = useRouter();
let achiListener: UnlistenFn | null = null;
async function switchHideFin() {
const text = hideFin.value ? "显示已完成" : "隐藏已完成";
hideFin.value = !hideFin.value;
showSnackbar.success(`${text}`);
}
onMounted(async () => {
showLoading.start("正在加载成就数据...");
await TGLogger.Info("[Achievements][onMounted] 打开成就页面");
@@ -112,29 +102,21 @@ onMounted(async () => {
if (route.query.app && typeof route.query.app === "string") {
await handleImportOuter(route.query.app);
}
achiListener = await listen<number>("updateAchi", async () => await refreshOverview());
achiListener = await listen<void>("updateAchi", async () => await refreshOverview());
});
watch(
() => uidCur.value,
async () => await refreshOverview(),
);
watch(() => uidCur.value, refreshOverview);
onUnmounted(async () => {
if (achiListener !== null) {
achiListener();
achiListener = null;
}
});
function switchHideFin(): void {
const text = hideFin.value ? "显示已完成" : "隐藏已完成";
hideFin.value = !hideFin.value;
showSnackbar.success(`${text}`);
}
async function refreshOverview(): Promise<void> {
overview.value = await TSUserAchi.getOverview(uidCur.value);
}
function selectSeries(series: number): void {
selectedSeries.value = series;
}
async function importJson(): Promise<void> {
await TGLogger.Info("[Achievements][importJson] 导入 UIAF 数据");
const selectedFile = await open({
@@ -266,6 +248,13 @@ async function deleteUid(): Promise<void> {
if (uidList.value.length === 0) uidList.value = [0];
uidCur.value = uidList.value[0];
}
onUnmounted(async () => {
if (achiListener !== null) {
achiListener();
achiListener = null;
}
});
</script>
<style lang="css" scoped>
.achi-search {

View File

@@ -10,7 +10,7 @@
<v-select
class="anno-select"
:items="annoServerList"
v-model="curRegion"
v-model="server"
item-title="text"
item-value="value"
label="服务器"
@@ -20,7 +20,7 @@
<v-select
class="anno-select"
:items="annoLangList"
v-model="curLang"
v-model="lang"
item-title="text"
item-value="value"
label="语言"
@@ -30,10 +30,7 @@
</div>
</template>
<template #append>
<v-btn class="anno-switch-btn" @click="switchNews">
<template #prepend>
<v-icon>mdi-bullhorn</v-icon>
</template>
<v-btn class="anno-switch-btn" @click="switchNews" prepend-icon="mdi-bullhorn">
切换米游社咨讯
</v-btn>
</template>
@@ -45,8 +42,8 @@
v-for="item in annoCards[value]"
:key="item.id"
:model-value="item"
:region="curRegion"
:lang="curLang"
:region="server"
:lang="lang"
/>
</div>
</v-window-item>
@@ -54,21 +51,24 @@
</template>
<script lang="ts" setup>
import { nextTick, onMounted, ref, watch } from "vue";
import showLoading from "@comp/func/loading.js";
import showSnackbar from "@comp/func/snackbar.js";
import TaCard from "@comp/pageAnno/ta-card.vue";
import { storeToRefs } from "pinia";
import { onMounted, ref, shallowRef, watch } from "vue";
import { useRouter } from "vue-router";
import showLoading from "../../components/func/loading.js";
import showSnackbar from "../../components/func/snackbar.js";
import TaCard from "../../components/pageAnno/ta-card.vue";
import { useAppStore } from "../../store/modules/app.js";
import TGLogger from "../../utils/TGLogger.js";
import Hk4eApi, { AnnoLang, AnnoServer } from "../../web/request/hk4eReq.js";
import { getAnnoCard } from "../../web/utils/getAnnoCard.js";
import { decodeRegExp } from "../../web/utils/tools.js";
import { useAppStore } from "@/store/modules/app.js";
import TGLogger from "@/utils/TGLogger.js";
import Hk4eApi, { type AnnoLang, AnnoServer } from "@/web/request/hk4eReq.js";
import { getAnnoCard } from "@/web/utils/getAnnoCard.js";
import { decodeRegExp } from "@/web/utils/tools.js";
type AnnoSelect = { text: string; value: string };
type AnnoKey = keyof typeof AnnoType;
type AnnoCard = { [key in AnnoKey]: TGApp.App.Announcement.ListCard[] };
const annoServerList: AnnoSelect[] = [
const annoServerList: Array<AnnoSelect> = [
{ text: "国服-官方服", value: AnnoServer.CN_ISLAND },
{ text: "国服-渠道服", value: AnnoServer.CN_TREE },
{ text: "国际服-亚服", value: AnnoServer.OS_ASIA },
@@ -76,44 +76,28 @@ const annoServerList: AnnoSelect[] = [
{ text: "国际服-美服", value: AnnoServer.OS_USA },
{ text: "国际服-港澳台服", value: AnnoServer.OS_CHT },
];
const annoLangList: AnnoSelect[] = [
const annoLangList: Array<AnnoSelect> = [
{ text: "简体中文", value: "zh-cn" },
{ text: "繁体中文", value: "zh-tw" },
{ text: "English", value: "en" },
{ text: "日本語", value: "ja" },
];
// 类型定义
enum AnnoType {
activity = "活动公告",
game = "游戏公告",
}
type AnnoKey = keyof typeof AnnoType;
type AnnoCard = {
[key in AnnoKey]: TGApp.App.Announcement.ListCard[];
};
const appStore = useAppStore();
// 路由
const { server, lang } = storeToRefs(useAppStore());
const router = useRouter();
const curRegion = ref<AnnoServer>(appStore.server);
const curLang = ref<AnnoLang>(appStore.lang);
// 数据
const tabValues: Readonly<Array<AnnoKey>> = ["activity", "game"];
const tab = ref<AnnoKey>("activity");
const tabValues = ref<Array<AnnoKey>>(["activity", "game"]);
const annoCards = ref<AnnoCard>({
activity: [],
game: [],
});
const annoCards = shallowRef<AnnoCard>({ activity: [], game: [] });
watch(
() => curRegion.value,
() => server.value,
async () => {
appStore.server = curRegion.value;
const name = getRegionName(curRegion.value);
const name = getRegionName(server.value);
await TGLogger.Info(`[Announcements][watch][curRegionName] 切换服务器:${name}`);
await loadData();
showSnackbar.success(`服务器切换为:${name}`);
@@ -121,10 +105,9 @@ watch(
);
watch(
() => curLang.value,
() => lang.value,
async () => {
appStore.lang = curLang.value;
const name = getLangName(curLang.value);
const name = getLangName(lang.value);
await TGLogger.Info(`[Announcements][watch][curLangName] 切换语言:${name}`);
await loadData();
showSnackbar.success(`语言切换为:${name}`);
@@ -133,22 +116,20 @@ watch(
onMounted(async () => {
await TGLogger.Info("[Announcements][onMounted] 打开公告页面");
curRegion.value = appStore.server;
curLang.value = appStore.lang;
await loadData();
});
async function loadData(): Promise<void> {
showLoading.start(
"正在获取公告数据",
`服务器:${getRegionName(curRegion.value)},语言:${getLangName(curLang.value)}`,
`服务器:${getRegionName(server.value)},语言:${getLangName(lang.value)}`,
);
const annoData = await Hk4eApi.anno.list(curRegion.value, curLang.value);
const annoData = await Hk4eApi.anno.list(server.value, lang.value);
const listCards = getAnnoCard(annoData);
await Promise.all(
listCards.map(async (item) => {
if (item.typeLabel === AnnoType.game) return;
const detail = await Hk4eApi.anno.content(item.id, curRegion.value, "zh-cn");
const detail = await Hk4eApi.anno.content(item.id, server.value, "zh-cn");
const timeStr = getAnnoTime(detail.content);
if (timeStr !== false) item.timeStr = timeStr;
}),
@@ -157,8 +138,7 @@ async function loadData(): Promise<void> {
activity: listCards.filter((item) => item.typeLabel === AnnoType.activity),
game: listCards.filter((item) => item.typeLabel === AnnoType.game),
};
showLoading.update("正在渲染公告数据");
await nextTick(() => showLoading.end());
showLoading.end();
}
function getRegionName(value: AnnoServer): string {

View File

@@ -35,8 +35,8 @@
</template>
<template #append>
<v-switch
v-model="appStore.devMode"
:label="appStore.devMode ? '开启' : '关闭'"
v-model="devMode"
:label="devMode ? '开启' : '关闭'"
:inset="true"
color="#FAC51E"
@click="submitDevMode"
@@ -51,8 +51,8 @@
</template>
<template #append>
<v-switch
v-model="needResize"
:label="needResize ? '开启' : '关闭'"
v-model="isNeedResize"
:label="isNeedResize ? '开启' : '关闭'"
:inset="true"
color="#FAC51E"
@click="submitResize"
@@ -60,9 +60,7 @@
</template>
</v-list-item>
<v-list-item title="分享设置">
<template #subtitle>
默认保存到剪贴板超过{{ appStore.shareDefaultFile }}MB时保存到文件
</template>
<template #subtitle>默认保存到剪贴板超过{{ shareDefaultFile }}MB时保存到文件</template>
<template #prepend>
<div class="config-icon">
<v-icon>mdi-share-variant</v-icon>
@@ -81,8 +79,7 @@
<v-list-item-title @click="confirmUpdateDevice()">刷新设备信息</v-list-item-title>
<v-list-item-subtitle>
<!-- @ts-expect-error-next-line Deprecated symbol used -->
{{ appStore.deviceInfo.device_name }}({{ appStore.deviceInfo.product }}) -
{{ appStore.deviceInfo.device_fp }}
{{ deviceInfo.device_name }}({{ deviceInfo.product }}) - {{ deviceInfo.device_fp }}
</v-list-item-subtitle>
<template #append>
<v-icon @click="confirmUpdateDevice(true)">mdi-bug</v-icon>
@@ -121,38 +118,40 @@
</template>
<script lang="ts" setup>
import showDialog from "@comp/func/dialog.js";
import showLoading from "@comp/func/loading.js";
import showSnackbar from "@comp/func/snackbar.js";
import TcAppBadge from "@comp/pageConfig/tc-appBadge.vue";
import TcDataDir from "@comp/pageConfig/tc-dataDir.vue";
import TcGameBadge from "@comp/pageConfig/tc-gameBadge.vue";
import TcInfo from "@comp/pageConfig/tc-info.vue";
import TcUserBadge from "@comp/pageConfig/tc-userBadge.vue";
import TGSqlite from "@Sqlite/index.js";
import { core } from "@tauri-apps/api";
import { open } from "@tauri-apps/plugin-dialog";
import { remove } from "@tauri-apps/plugin-fs";
import { platform } from "@tauri-apps/plugin-os";
import { exit } from "@tauri-apps/plugin-process";
import { storeToRefs } from "pinia";
import { onMounted, ref } from "vue";
import showDialog from "../../components/func/dialog.js";
import showLoading from "../../components/func/loading.js";
import showSnackbar from "../../components/func/snackbar.js";
import TcAppBadge from "../../components/pageConfig/tc-appBadge.vue";
import TcDataDir from "../../components/pageConfig/tc-dataDir.vue";
import TcGameBadge from "../../components/pageConfig/tc-gameBadge.vue";
import TcInfo from "../../components/pageConfig/tc-info.vue";
import TcUserBadge from "../../components/pageConfig/tc-userBadge.vue";
import TGSqlite from "../../plugins/Sqlite/index.js";
import { useAppStore } from "../../store/modules/app.js";
import { useHomeStore } from "../../store/modules/home.js";
import { backUpUserData, restoreUserData } from "../../utils/dataBS.js";
import { getBuildTime } from "../../utils/TGBuild.js";
import TGLogger from "../../utils/TGLogger.js";
import { bytesToSize, getCacheDir, getDeviceInfo, getRandomString } from "../../utils/toolFunc.js";
import OtherApi from "../../web/request/otherReq.js";
import { useAppStore } from "@/store/modules/app.js";
import { useHomeStore } from "@/store/modules/home.js";
import { backUpUserData, restoreUserData } from "@/utils/dataBS.js";
import { getBuildTime } from "@/utils/TGBuild.js";
import TGLogger from "@/utils/TGLogger.js";
import { bytesToSize, getCacheDir, getDeviceInfo, getRandomString } from "@/utils/toolFunc.js";
import OtherApi from "@/web/request/otherReq.js";
// Store
const { needResize, devMode, deviceInfo, shareDefaultFile, userDir, buildTime } =
storeToRefs(useAppStore());
const appStore = useAppStore();
const homeStore = useHomeStore();
// @ts-expect-error-next-line
const isDevEnv = ref<boolean>(import.meta.env.MODE === "development");
const showReset = ref<boolean>(false);
const needResize = ref<boolean>(appStore.needResize !== "false");
const isNeedResize = ref<boolean>(needResize.value !== "false");
const cacheSize = ref<number>(0);
onMounted(async () => {
@@ -176,7 +175,7 @@ async function confirmBackup(): Promise<void> {
showSnackbar.cancel("已取消备份");
return;
}
let saveDir = appStore.userDir;
let saveDir = userDir.value;
if (!bcCheck) {
const dir: string | null = await open({
directory: true,
@@ -189,9 +188,7 @@ async function confirmBackup(): Promise<void> {
}
await TGLogger.Info(`[Config][confirmBackup] 选择备份路径 ${dir.toString()}`);
saveDir = dir;
} else {
await TGLogger.Info(`[Config][confirmBackup] 备份到默认路径 ${saveDir}`);
}
} else await TGLogger.Info(`[Config][confirmBackup] 备份到默认路径 ${saveDir}`);
showLoading.start("正在备份数据...");
await backUpUserData(saveDir);
showLoading.end();
@@ -206,7 +203,7 @@ async function confirmRestore(): Promise<void> {
showSnackbar.cancel("已取消恢复");
return;
}
let saveDir = appStore.userDir;
let saveDir = userDir.value;
if (!rsCheck) {
const dir: string | null = await open({
directory: true,
@@ -219,9 +216,7 @@ async function confirmRestore(): Promise<void> {
}
await TGLogger.Info(`[Config][confirmRestore] 选择恢复路径 ${dir.toString()}`);
saveDir = dir;
} else {
await TGLogger.Info(`[Config][confirmRestore] 恢复到默认路径 ${saveDir}`);
}
} else await TGLogger.Info(`[Config][confirmRestore] 恢复到默认路径 ${saveDir}`);
showLoading.start("正在恢复数据...");
await restoreUserData(saveDir);
showLoading.end();
@@ -238,7 +233,7 @@ async function confirmUpdate(title?: string): Promise<void> {
}
showLoading.start("正在更新数据库...");
await TGSqlite.update();
appStore.buildTime = getBuildTime();
buildTime.value = getBuildTime();
showLoading.end();
showSnackbar.success("数据库已更新!");
await TGLogger.Info("[Config][confirmUpdate] 数据库更新完成");
@@ -250,7 +245,7 @@ async function confirmShare(): Promise<void> {
const input = await showDialog.input(
"请输入分享文件大小阈值(MB)",
"阈值:",
appStore.shareDefaultFile.toString(),
shareDefaultFile.value.toString(),
);
if (input === undefined) {
showSnackbar.cancel("已取消修改分享设置");
@@ -264,7 +259,7 @@ async function confirmShare(): Promise<void> {
showSnackbar.error("阈值必须为数字!");
return;
}
if (Number(input) === appStore.shareDefaultFile) {
if (Number(input) === shareDefaultFile.value) {
showSnackbar.cancel("未修改分享设置");
return;
}
@@ -280,7 +275,7 @@ async function confirmShare(): Promise<void> {
showSnackbar.cancel("已取消修改分享设置");
return;
}
appStore.shareDefaultFile = Number(input);
shareDefaultFile.value = Number(input);
showSnackbar.success(`成功修改分享设置!新阈值为${input}MB`);
}
@@ -290,22 +285,20 @@ async function confirmUpdateDevice(force?: boolean): Promise<void> {
await TGLogger.Info("[Config][confirmUpdateDevice][force] 开始强制更新设备信息");
const forceCheck = await showDialog.check(
"确认强制更新设备信息吗?",
`DeviceFp:${appStore.deviceInfo.device_fp}`,
`DeviceFp:${deviceInfo.value.device_fp}`,
);
if (!forceCheck) {
showSnackbar.cancel("已取消强制更新设备信息");
await TGLogger.Info("[Config][confirmUpdateDevice][force] 取消强制更新设备信息");
return;
}
appStore.deviceInfo = await OtherApi.fp();
if (appStore.deviceInfo.device_fp === "0000000000000") {
appStore.deviceInfo.device_fp = getRandomString(13, "hex");
showSnackbar.warn(`设备信息获取失败!已使用随机值${appStore.deviceInfo.device_fp}代替`);
deviceInfo.value = await OtherApi.fp();
if (deviceInfo.value.device_fp === "0000000000000") {
deviceInfo.value.device_fp = getRandomString(13, "hex");
showSnackbar.warn(`设备信息获取失败!已使用随机值${deviceInfo.value.device_fp}代替`);
await TGLogger.Warn("[Config][confirmUpdateDevice][force] 设备信息获取失败!已使用随机值代替");
} else {
showSnackbar.success(`设备信息已更新! DeviceFp: ${appStore.deviceInfo.device_fp}`);
}
await TGSqlite.saveAppData("deviceInfo", JSON.stringify(appStore.deviceInfo));
} else showSnackbar.success(`设备信息已更新! DeviceFp: ${deviceInfo.value.device_fp}`);
await TGSqlite.saveAppData("deviceInfo", JSON.stringify(deviceInfo.value));
await TGLogger.Info("[Config][confirmUpdateDevice][force] 设备信息更新完成");
return;
}
@@ -319,17 +312,15 @@ async function confirmUpdateDevice(force?: boolean): Promise<void> {
return;
}
}
console.log(appStore.deviceInfo);
appStore.deviceInfo = await OtherApi.fp(appStore.deviceInfo);
console.log(appStore.deviceInfo);
if (appStore.deviceInfo.device_fp === "0000000000000") {
appStore.deviceInfo.device_fp = getRandomString(13, "hex");
showSnackbar.warn(`设备信息获取失败!已使用随机值${appStore.deviceInfo.device_fp}代替`);
deviceInfo.value = await OtherApi.fp(deviceInfo.value);
if (deviceInfo.value.device_fp === "0000000000000") {
deviceInfo.value.device_fp = getRandomString(13, "hex");
showSnackbar.warn(`设备信息获取失败!已使用随机值${deviceInfo.value.device_fp}代替`);
await TGLogger.Warn("[Config][confirmUpdateDevice] 设备信息获取失败!已使用随机值代替");
return;
}
showSnackbar.success(`设备信息已更新! DeviceFp: ${appStore.deviceInfo.device_fp}`);
await TGSqlite.saveAppData("deviceInfo", JSON.stringify(appStore.deviceInfo));
showSnackbar.success(`设备信息已更新! DeviceFp: ${deviceInfo.value.device_fp}`);
await TGSqlite.saveAppData("deviceInfo", JSON.stringify(deviceInfo.value));
await TGLogger.Info("[Config][confirmUpdateDevice] 设备信息更新完成");
}
@@ -433,8 +424,8 @@ function submitDevMode(): void {
// 开启窗口回正
function submitResize(): void {
appStore.needResize = (!needResize.value).toString();
if (needResize.value) {
appStore.needResize = (!isNeedResize.value).toString();
if (isNeedResize.value) {
showSnackbar.success("已关闭窗口回正!");
return;
}

View File

@@ -1,7 +1,7 @@
<template>
<div class="home-container">
<div class="home-top">
<div class="home-tools" v-if="appStore.isLogin">
<div class="home-tools" v-if="isLogin">
<v-select
v-model="curGid"
class="home-tool-select"
@@ -32,18 +32,19 @@
</template>
<script lang="ts" setup>
import TGameNav from "@comp/app/t-gameNav.vue";
import showLoading from "@comp/func/loading.js";
import showSnackbar from "@comp/func/snackbar.js";
import PhCompCalendar from "@comp/pageHome/ph-comp-calendar.vue";
import PhCompPool from "@comp/pageHome/ph-comp-pool.vue";
import PhCompPosition from "@comp/pageHome/ph-comp-position.vue";
import { storeToRefs } from "pinia";
import { type Component, computed, onMounted, ref, shallowRef, watch } from "vue";
import TGameNav from "../../components/app/t-gamenav.vue";
import showLoading from "../../components/func/loading.js";
import showSnackbar from "../../components/func/snackbar.js";
import PhCompCalendar from "../../components/pageHome/ph-comp-calendar.vue";
import PhCompPool from "../../components/pageHome/ph-comp-pool.vue";
import PhCompPosition from "../../components/pageHome/ph-comp-position.vue";
import { useAppStore } from "../../store/modules/app.js";
import { ShowItemEnum, useHomeStore } from "../../store/modules/home.js";
import TGLogger from "../../utils/TGLogger.js";
import TGConstant from "../../web/constant/TGConstant.js";
import { useAppStore } from "@/store/modules/app.js";
import { ShowItemEnum, useHomeStore } from "@/store/modules/home.js";
import TGLogger from "@/utils/TGLogger.js";
import TGConstant from "@/web/constant/TGConstant.js";
type SFComp = Component & {
__file?: string;
@@ -52,7 +53,7 @@ type SFComp = Component & {
__scopeId?: string;
};
const appStore = useAppStore();
const { devMode, isLogin } = storeToRefs(useAppStore());
const homeStore = useHomeStore();
const showItemsAll: Array<ShowItemEnum> = [
@@ -60,12 +61,12 @@ const showItemsAll: Array<ShowItemEnum> = [
ShowItemEnum.pool,
ShowItemEnum.position,
];
const showItems = computed<ShowItemEnum[]>({
const showItems = computed<Array<ShowItemEnum>>({
get: () => homeStore.getShowItems(),
set: (v: ShowItemEnum[]) => homeStore.setShowItems(v),
set: (v: Array<ShowItemEnum>) => homeStore.setShowItems(v),
});
const loadItems = shallowRef<ShowItemEnum[]>([]);
const components = shallowRef<SFComp[]>([]);
const loadItems = shallowRef<Array<ShowItemEnum>>([]);
const components = shallowRef<Array<SFComp>>([]);
const gameSelectList = TGConstant.BBS.CHANNELS;
const curGid = ref<string>(gameSelectList[0].gid);
@@ -74,7 +75,7 @@ onMounted(async () => {
showLoading.start("正在加载首页...");
// @ts-expect-error-next-line The import.meta meta-property is not allowed in files which will build into CommonJS output.
const isProdEnv = import.meta.env.MODE === "production";
if (isProdEnv && appStore.devMode) appStore.devMode = false;
if (isProdEnv && devMode.value) devMode.value = false;
await loadComp();
});
@@ -88,7 +89,7 @@ watch(
async function loadComp(): Promise<void> {
showLoading.start("正在加载首页...");
const temp: SFComp[] = [];
const temp: Array<SFComp> = [];
for (const item of showItems.value) {
switch (item) {
case "限时祈愿":

View File

@@ -94,47 +94,40 @@
<ToCollectPost @submit="load" :post="selectedPost" v-model="showOverlay" />
</template>
<script lang="ts" setup>
import TPostCard from "@comp/app/t-postcard.vue";
import showDialog from "@comp/func/dialog.js";
import showLoading from "@comp/func/loading.js";
import showSnackbar from "@comp/func/snackbar.js";
import ToCollectPost from "@comp/pageCollect/to-collectPost.vue";
import TSUserCollection from "@Sqlite/modules/userCollect.js";
import { event } from "@tauri-apps/api";
import { UnlistenFn } from "@tauri-apps/api/event";
import type { UnlistenFn } from "@tauri-apps/api/event";
import { storeToRefs } from "pinia";
import { computed, onMounted, onUnmounted, ref, watch } from "vue";
import { computed, onMounted, onUnmounted, ref, shallowRef, watch } from "vue";
import TPostCard from "../../components/app/t-postcard.vue";
import showDialog from "../../components/func/dialog.js";
import showLoading from "../../components/func/loading.js";
import showSnackbar from "../../components/func/snackbar.js";
import ToCollectPost from "../../components/pageCollect/to-collectPost.vue";
import TSUserCollection from "../../plugins/Sqlite/modules/userCollect.js";
import { useUserStore } from "../../store/modules/user.js";
import TGLogger from "../../utils/TGLogger.js";
import BBSApi from "../../web/request/bbsReq.js";
const userStore = storeToRefs(useUserStore());
const collections = ref<TGApp.Sqlite.UserCollection.UFCollection[]>([]);
const selected = ref<TGApp.Sqlite.UserCollection.UFPost[]>([]);
const curSelect = ref<string>("未分类");
const page = ref(1);
const length = computed(() => Math.ceil(selected.value.length / 12));
const view = computed(() => {
if (length.value === 1) return 0;
return length.value > 5 ? 5 : length.value;
});
const curPosts = computed<TGApp.Plugins.Mys.Post.FullData[]>(() => {
return selected.value
.slice((page.value - 1) * 12, page.value * 12)
.map((i) => JSON.parse(i.content));
});
const selectedMode = ref<boolean>(false);
const selectedPost = ref<Array<string>>([]);
const showOverlay = ref(false);
const sortId = ref<boolean>(false);
import { useUserStore } from "@/store/modules/user.js";
import TGLogger from "@/utils/TGLogger.js";
import BBSApi from "@/web/request/bbsReq.js";
const { cookie, briefInfo } = storeToRefs(useUserStore());
let collectListener: UnlistenFn | null = null;
const curSelect = ref<string>("未分类");
const page = ref<number>(1);
const selectedMode = ref<boolean>(false);
const showOverlay = ref<boolean>(false);
const sortId = ref<boolean>(false);
const selectedPost = shallowRef<Array<string>>([]);
const collections = shallowRef<Array<TGApp.Sqlite.UserCollection.UFCollection>>([]);
const selected = shallowRef<Array<TGApp.Sqlite.UserCollection.UFPost>>([]);
const length = computed<number>(() => Math.ceil(selected.value.length / 12));
const view = computed<number>(() => (length.value === 1 ? 1 : length.value > 5 ? 5 : length.value));
const curPosts = computed<Array<TGApp.Plugins.Mys.Post.FullData>>(() =>
selected.value.slice((page.value - 1) * 12, page.value * 12).map((i) => JSON.parse(i.content)),
);
onMounted(async () => {
collectListener = await event.listen("refreshCollect", async () => await load());
collectListener = await event.listen<void>("refreshCollect", load);
await load();
});
onUnmounted(() => {
@@ -144,27 +137,22 @@ onUnmounted(() => {
}
});
function handleSelected(v: string) {
if (selectedPost.value.includes(v)) {
selectedPost.value = selectedPost.value.filter((i) => i !== v);
} else {
selectedPost.value.push(v);
function handleSelected(v: string): void {
if (!selectedPost.value.includes(v)) {
selectedPost.value = [...selectedPost.value, v];
return;
}
selectedPost.value = selectedPost.value.filter((i) => i !== v);
}
function sortPost(value: boolean) {
function sortPost(value: boolean): void {
let ori = sortId.value;
sortId.value = value;
selected.value = selected.value.sort((a, b) => {
if (sortId.value) {
return Number(b.id) - Number(a.id);
} else {
return Number(b.updated) - Number(a.updated);
}
});
if (ori !== sortId.value) {
showSnackbar.success(`${sortId.value ? "按帖子ID排序" : "按更新时间排序"}`);
}
selected.value = selected.value.sort((a, b) =>
sortId.value ? Number(b.id) - Number(a.id) : Number(b.updated) - Number(a.updated),
);
if (ori === sortId.value) return;
showSnackbar.success(`${sortId.value ? "按帖子ID排序" : "按更新时间排序"}`);
}
async function load(): Promise<void> {
@@ -187,7 +175,7 @@ async function load(): Promise<void> {
showLoading.end();
}
function toSelect() {
function toSelect(): void {
if (selectedMode.value) {
selectedMode.value = false;
if (selectedPost.value.length === 0) return;
@@ -332,9 +320,7 @@ async function freshPost(select: string | null): Promise<void> {
if (select === "未分类") {
curSelect.value = "未分类";
selected.value = await TSUserCollection.getUnCollectPostList();
} else {
selected.value = await TSUserCollection.getCollectPostList(select);
}
} else selected.value = await TSUserCollection.getCollectPostList(select);
page.value = 1;
showLoading.end();
showSnackbar.success(`切换合集 ${select},共 ${selected.value.length} 条帖子`);
@@ -359,33 +345,26 @@ async function freshOther(): Promise<void> {
}
async function freshUser(uid?: string): Promise<void> {
if (!userStore.cookie.value) {
if (!cookie.value) {
showSnackbar.warn("请先登录");
return;
}
const uidReal = uid || userStore.briefInfo.value.uid;
const uidReal = uid || briefInfo.value.uid;
showLoading.start("获取用户收藏...", `UID: ${uidReal}`);
let res = await BBSApi.lovePost(userStore.cookie.value, uidReal);
let res = await BBSApi.lovePost(cookie.value, uidReal);
while (true) {
if ("retcode" in res) {
showLoading.end();
if (res.retcode === 1001) {
showSnackbar.warn("用户收藏已设为私密,无法获取");
} else {
showSnackbar.error(`[${res.retcode}] ${res.message}`);
}
if (res.retcode === 1001) showSnackbar.warn("用户收藏已设为私密,无法获取");
else showSnackbar.error(`[${res.retcode}] ${res.message}`);
break;
}
let posts = res.list;
showLoading.update("获取用户收藏...", `合并收藏帖子 [offset]${res.next_offset}...`);
await mergePosts(posts, uid || userStore.briefInfo.value.uid);
await mergePosts(posts, uid || briefInfo.value.uid);
if (res.is_last) break;
showLoading.update("获取用户收藏...", `[offset]${res.next_offset} [is_last]${res.is_last}`);
res = await BBSApi.lovePost(
userStore.cookie.value,
uid || userStore.briefInfo.value.uid,
res.next_offset,
);
res = await BBSApi.lovePost(cookie.value, uid || briefInfo.value.uid, res.next_offset);
}
showLoading.end();
showSnackbar.success("获取用户收藏成功");
@@ -394,16 +373,14 @@ async function freshUser(uid?: string): Promise<void> {
// 合并收藏帖子
async function mergePosts(
posts: TGApp.Plugins.Mys.Post.FullData[],
posts: Array<TGApp.Plugins.Mys.Post.FullData>,
collect: string,
): Promise<void> {
const title = `用户收藏-${collect}`;
for (const post of posts) {
showLoading.start("获取用户收藏...", `[POST]${post.post.subject} [collection]${title}`);
const res = await TSUserCollection.addCollect(post.post.post_id, post, title, true);
if (!res) {
await TGLogger.Error(`[PostCollect] mergePosts [${post.post.post_id}]`);
}
if (!res) await TGLogger.Error(`[PostCollect] mergePosts [${post.post.post_id}]`);
}
}
</script>

View File

@@ -67,71 +67,64 @@
<VpOverlaySearch :gid="curGid.toString()" v-model="showSearch" :keyword="search" />
</template>
<script setup lang="ts">
import { onMounted, ref, watch } from "vue";
import TGameNav from "@comp/app/t-gameNav.vue";
import TPostCard from "@comp/app/t-postcard.vue";
import showLoading from "@comp/func/loading.js";
import showSnackbar from "@comp/func/snackbar.js";
import VpOverlaySearch from "@comp/viewPost/vp-overlay-search.vue";
import Mys from "@Mys/index.js";
import { onMounted, ref, shallowRef, watch } from "vue";
import { useRoute } from "vue-router";
import TGameNav from "../../components/app/t-gamenav.vue";
import TPostCard from "../../components/app/t-postcard.vue";
import showLoading from "../../components/func/loading.js";
import showSnackbar from "../../components/func/snackbar.js";
import VpOverlaySearch from "../../components/viewPost/vp-overlay-search.vue";
import Mys from "../../plugins/Mys/index.js";
import TGLogger from "../../utils/TGLogger.js";
import { createPost } from "../../utils/TGWindow.js";
import { getGameName } from "../../web/utils/tools.js";
import TGLogger from "@/utils/TGLogger.js";
import { createPost } from "@/utils/TGWindow.js";
import { getGameName } from "@/web/utils/tools.js";
type SortSelect = {
text: string;
value: number;
};
type SortSelectGame = {
gid: number;
forum: SortSelect[];
text: string;
};
type SortSelect = { text: string; value: number };
type SortSelectGame = { gid: number; forum: Array<SortSelect>; text: string };
const sortOrderList: SortSelect[] = [
const sortOrderList: Array<SortSelect> = [
{ text: "最新回复", value: 1 },
{ text: "最新发布", value: 2 },
{ text: "热门", value: 3 },
];
const forumYsList: SortSelect[] = [
const forumYsList: Array<SortSelect> = [
{ text: "酒馆", value: 26 },
{ text: "攻略", value: 43 },
{ text: "同人图", value: 29 },
{ text: "COS", value: 49 },
{ text: "硬核", value: 50 },
];
const forumSrList: SortSelect[] = [
const forumSrList: Array<SortSelect> = [
{ text: "候车室", value: 52 },
{ text: "攻略", value: 61 },
{ text: "同人图", value: 56 },
{ text: "COS", value: 62 },
];
const forumBh3List: SortSelect[] = [
const forumBh3List: Array<SortSelect> = [
{ text: "甲板", value: 1 },
{ text: "攻略", value: 14 },
{ text: "同人图", value: 4 },
{ text: "同人文", value: 41 },
];
const forumBh2List: SortSelect[] = [
const forumBh2List: Array<SortSelect> = [
{ text: "学园", value: 30 },
{ text: "攻略", value: 51 },
{ text: "同人图", value: 40 },
];
const forumWdList: SortSelect[] = [
const forumWdList: Array<SortSelect> = [
{ text: "律所", value: 37 },
{ text: "攻略", value: 60 },
{ text: "同人文", value: 42 },
{ text: "同人图", value: 38 },
];
const forumZzzList: SortSelect[] = [
const forumZzzList: Array<SortSelect> = [
{ text: "咖啡馆", value: 57 },
{ text: "攻略", value: 64 },
{ text: "同人图", value: 59 },
{ text: "COS", value: 65 },
];
const forumDbyList: SortSelect[] = [
const forumDbyList: Array<SortSelect> = [
{ text: "校园", value: 54 },
{ text: "ACG", value: 35 },
{ text: "生活", value: 34 },
@@ -141,7 +134,7 @@ const forumDbyList: SortSelect[] = [
{ text: "科技", value: 55 },
{ text: "公告", value: 36 },
];
const sortGameList: SortSelectGame[] = [
const sortGameList: Readonly<Array<SortSelectGame>> = [
{ gid: 2, forum: forumYsList, text: "原神" },
{ gid: 6, forum: forumSrList, text: "崩坏:星穹铁道" },
{ gid: 8, forum: forumZzzList, text: "绝区零" },
@@ -150,47 +143,17 @@ const sortGameList: SortSelectGame[] = [
{ gid: 4, forum: forumWdList, text: "未定事件簿" },
{ gid: 5, forum: forumDbyList, text: "大别野" },
];
// 路由
const gid = useRoute().params.gid;
const forum = useRoute().params.forum;
function getGameForums(gid: number): SortSelect[] {
const game = sortGameList.find((item) => item.gid === gid);
if (game) return game.forum;
return [];
}
function getGameLabel(gid: number): string {
const game = sortGameList.find((item) => item.gid === gid);
if (game) return game.text;
return "";
}
function getForumLabel(gid: number, forum: number): string {
const forums = getGameForums(gid);
const forumItem = forums.find((item) => item.value === forum);
return forumItem ? forumItem.text : "";
}
function getSortLabel(value: number): string {
const order = sortOrderList.find((item) => item.value === value);
return order ? order.text : "";
}
// 渲染参数
const { gid, forum } = useRoute().params;
const curGid = ref<number>(2);
const curSortType = ref<number>(1);
const curForum = ref<number>(26);
const curForumLabel = ref<string>("");
// 渲染数据
const posts = ref<TGApp.Plugins.Mys.Post.FullData[]>([]);
const lastId = ref<string>("");
const isLast = ref<boolean>(false);
const search = ref<string>("");
const showSearch = ref<boolean>(false);
const firstLoad = ref<boolean>(false);
const posts = shallowRef<Array<TGApp.Plugins.Mys.Post.FullData>>([]);
onMounted(async () => {
if (gid && typeof gid === "string") curGid.value = Number(gid);
@@ -204,7 +167,6 @@ onMounted(async () => {
await freshPostData();
curForumLabel.value = forumLabel;
});
watch(
() => curGid.value,
() => {
@@ -236,6 +198,29 @@ watch(
},
);
function getGameForums(gid: number): SortSelect[] {
const game = sortGameList.find((item) => item.gid === gid);
if (game) return game.forum;
return [];
}
function getGameLabel(gid: number): string {
const game = sortGameList.find((item) => item.gid === gid);
if (game) return game.text;
return "";
}
function getForumLabel(gid: number, forum: number): string {
const forums = getGameForums(gid);
const forumItem = forums.find((item) => item.value === forum);
return forumItem ? forumItem.text : "";
}
function getSortLabel(value: number): string {
const order = sortOrderList.find((item) => item.value === value);
return order ? order.text : "";
}
async function freshPostData(): Promise<void> {
const gameLabel = getGameLabel(curGid.value);
const forumLabel = getForumLabel(curGid.value, curForum.value);
@@ -266,7 +251,6 @@ async function loadMore(): Promise<void> {
showLoading.end();
}
// 查询帖子
function searchPost(): void {
if (search.value === "") {
showSnackbar.warn("请输入搜索内容");

View File

@@ -25,16 +25,14 @@
/>
</template>
<template #append>
<v-btn class="post-news-btn" @click="firstLoad(tab, true)">
<v-icon>mdi-refresh</v-icon>
</v-btn>
<v-btn class="post-news-btn" @click="showList = true">
<v-icon>mdi-view-list</v-icon>
</v-btn>
<v-btn class="post-news-btn" @click="switchAnno" v-if="gid === '2'">
<template #prepend>
<v-icon>mdi-bullhorn</v-icon>
</template>
<v-btn class="post-news-btn" @click="firstLoad(tab, true)" icon="mdi-refresh" />
<v-btn class="post-news-btn" @click="showList = true" icon="mdi-view-list" />
<v-btn
class="post-news-btn"
@click="switchAnno"
v-if="gid === '2'"
prepend-icon="mdi-bullhorn"
>
切换游戏内公告
</v-btn>
</template>
@@ -56,51 +54,44 @@
<ToChannel v-model="showList" :gid="gid" />
<VpOverlaySearch :gid="gid" v-model="showSearch" :keyword="search" />
</template>
<script lang="ts" setup>
import { computed, nextTick, onMounted, ref } from "vue";
import TPostCard from "@comp/app/t-postcard.vue";
import showLoading from "@comp/func/loading.js";
import showSnackbar from "@comp/func/snackbar.js";
import ToChannel from "@comp/pageNews/to-channel.vue";
import VpOverlaySearch from "@comp/viewPost/vp-overlay-search.vue";
import Mys from "@Mys/index.js";
import { storeToRefs } from "pinia";
import { computed, onMounted, ref, shallowRef, triggerRef } from "vue";
import { useRoute, useRouter } from "vue-router";
import TPostCard from "../../components/app/t-postcard.vue";
import showLoading from "../../components/func/loading.js";
import showSnackbar from "../../components/func/snackbar.js";
import ToChannel from "../../components/pageNews/to-channel.vue";
import VpOverlaySearch from "../../components/viewPost/vp-overlay-search.vue";
import Mys from "../../plugins/Mys/index.js";
import { NewsType, NewsTypeEnum, useAppStore } from "../../store/modules/app.js";
import TGLogger from "../../utils/TGLogger.js";
import { createPost } from "../../utils/TGWindow.js";
import { getGameName } from "../../web/utils/tools.js";
import { type NewsType, NewsTypeEnum, useAppStore } from "@/store/modules/app.js";
import TGLogger from "@/utils/TGLogger.js";
import { createPost } from "@/utils/TGWindow.js";
import { getGameName } from "@/web/utils/tools.js";
type PostData = { [key in NewsType]: TGApp.Plugins.Mys.Post.FullData[] };
type RawData = {
[key in NewsType]: { isLast: boolean; name: string; lastId: number };
};
type PostData = { [key in NewsType]: Array<TGApp.Plugins.Mys.Post.FullData> };
type RawData = { [key in NewsType]: { isLast: boolean; name: string; lastId: number } };
const router = useRouter();
const appStore = useAppStore();
const gid = <string>useRoute().params.gid;
const { recentNewsType } = storeToRefs(useAppStore());
const tabValues: Readonly<Array<NewsType>> = ["notice", "activity", "news"];
const { gid } = <{ gid: string }>useRoute().params;
const gameName = getGameName(Number(gid));
const loading = ref<boolean>(false);
const tabValues: Readonly<Array<NewsType>> = ["notice", "activity", "news"];
const showList = ref<boolean>(false);
const showSearch = ref<boolean>(false);
const tab = computed<NewsType>({
get: () => {
if (!(appStore.recentNewsType satisfies NewsType)) return "notice";
return appStore.recentNewsType;
},
set: (v) => (appStore.recentNewsType = v),
});
// 渲染数据
const search = ref<string>("");
const postData = ref<PostData>({ notice: [], activity: [], news: [] });
const rawData = ref<RawData>({
const postData = shallowRef<PostData>({ notice: [], activity: [], news: [] });
const rawData = shallowRef<RawData>({
notice: { isLast: false, name: "公告", lastId: 0 },
activity: { isLast: false, name: "活动", lastId: 0 },
news: { isLast: false, name: "咨讯", lastId: 0 },
});
const tab = computed<NewsType>({
get: () => ((recentNewsType.value satisfies NewsType) ? recentNewsType.value : "notice"),
set: (v) => (recentNewsType.value = v),
});
onMounted(async () => await firstLoad(tab.value));
@@ -116,8 +107,9 @@ async function firstLoad(key: NewsType, refresh: boolean = false): Promise<void>
rawData.value[key].isLast = getData.is_last;
rawData.value[key].lastId = getData.list.length;
postData.value[key] = getData.list;
showLoading.update(`正在渲染${gameName}${rawData.value[key].name}数据...`);
await nextTick(() => showLoading.end());
triggerRef(postData);
triggerRef(rawData);
showLoading.end();
await TGLogger.Info(`[News][${gid}][firstLoad] 获取${rawData.value[key].name}数据成功`);
}
@@ -144,13 +136,15 @@ async function loadMore(key: NewsType): Promise<void> {
rawData.value[key].lastId = rawData.value[key].lastId + getData.list.length;
rawData.value[key].isLast = getData.is_last;
postData.value[key] = postData.value[key].concat(getData.list);
triggerRef(postData);
triggerRef(rawData);
if (rawData.value[key].isLast) {
showLoading.end();
showSnackbar.warn("已经是最后一页了");
loading.value = false;
return;
}
await nextTick(() => showLoading.end());
showLoading.end();
loading.value = false;
}
@@ -168,7 +162,6 @@ async function searchPost(): Promise<void> {
showSearch.value = false;
}
</script>
<style lang="css" scoped>
.news-tab {
margin-bottom: 10px;
@@ -178,6 +171,7 @@ async function searchPost(): Promise<void> {
.post-news-btn {
height: 40px;
border-radius: 3px;
margin-left: 15px;
background: var(--btn-bg-1);
color: var(--btn-text-1);

View File

@@ -42,10 +42,7 @@
@click:append="searchPost"
@keyup.enter="searchPost"
/>
<v-btn :rounded="true" class="post-topic-btn" @click="firstLoad()">
<v-icon>mdi-refresh</v-icon>
<span>刷新</span>
</v-btn>
<v-btn class="post-topic-btn" @click="firstLoad()" prepend-icon="mdi-refresh">刷新</v-btn>
</div>
</v-app-bar>
<div class="post-topic-grid">
@@ -54,39 +51,37 @@
</div>
</div>
<div class="load-more">
<v-btn class="post-topic-btn" :rounded="true" @click="freshPostData()">
<v-btn class="post-topic-btn" @click="freshPostData()">
已加载:{{ posts.length }},加载更多
</v-btn>
</div>
<VpOverlaySearch :gid="curGid.toString()" v-model="showSearch" :keyword="search" />
</template>
<script lang="ts" setup>
import { computed, onMounted, ref, toRaw, watch } from "vue";
import TGameNav from "@comp/app/t-gameNav.vue";
import TPostCard from "@comp/app/t-postcard.vue";
import showLoading from "@comp/func/loading.js";
import showSnackbar from "@comp/func/snackbar.js";
import VpOverlaySearch from "@comp/viewPost/vp-overlay-search.vue";
import Mys from "@Mys/index.js";
import { computed, onMounted, ref, shallowRef, watch } from "vue";
import { useRoute } from "vue-router";
import TGameNav from "../../components/app/t-gamenav.vue";
import TPostCard from "../../components/app/t-postcard.vue";
import showLoading from "../../components/func/loading.js";
import showSnackbar from "../../components/func/snackbar.js";
import VpOverlaySearch from "../../components/viewPost/vp-overlay-search.vue";
import Mys from "../../plugins/Mys/index.js";
import { createPost } from "../../utils/TGWindow.js";
import { createPost } from "@/utils/TGWindow.js";
const gid = <string>useRoute().params.gid;
const topic = <string>useRoute().params.topic;
type SortSelect = { text: string; value: number };
const { gid, topic } = <{ gid: string; topic: string }>useRoute().params;
const showSearch = ref<boolean>(false);
const curGid = ref<number>(Number(gid));
const curSortType = ref<0 | 1 | 2>(0);
const search = ref<string>("");
const topicInfo = ref<TGApp.Plugins.Mys.Topic.InfoData>();
const posts = ref<TGApp.Plugins.Mys.Post.FullData[]>([]);
const lastPostId = ref<string>();
const isLastPage = ref<boolean>(false);
const curGame = ref<TGApp.Plugins.Mys.Topic.GameInfo>();
type SortSelect = { text: string; value: number };
const sortList = computed<SortSelect[]>(() => {
const topicInfo = shallowRef<TGApp.Plugins.Mys.Topic.InfoData>();
const posts = shallowRef<Array<TGApp.Plugins.Mys.Post.FullData>>([]);
const curGame = shallowRef<TGApp.Plugins.Mys.Topic.GameInfo>();
const sortList = computed<Array<SortSelect>>(() => {
if (!topicInfo.value) return [];
if (!topicInfo.value.good_post_exist) {
return [
@@ -111,11 +106,12 @@ onMounted(async () => {
}
topicInfo.value = info;
if (curGame.value === undefined) {
curGame.value = toRaw(info.game_info_list.find((i) => i.id === curGid.value));
curGame.value = info.game_info_list.find((i) => i.id === curGid.value);
}
if (curGame.value === undefined) curGame.value = info.game_info_list[0];
await firstLoad();
});
watch(
() => curGame.value,
async () => {