mirror of
https://github.com/Megghy/vtsuru.live.git
synced 2025-12-06 18:36:55 +08:00
Compare commits
7 Commits
a75f7b6572
...
60af90486c
| Author | SHA1 | Date | |
|---|---|---|---|
| 60af90486c | |||
| 1bf2a40516 | |||
| 1276cc0381 | |||
| 08d8ca577d | |||
| 2a67d20e66 | |||
| 0beb49e589 | |||
| 3a73801340 |
@@ -510,23 +510,15 @@ function confirmTest() {
|
|||||||
:name="type"
|
:name="type"
|
||||||
>
|
>
|
||||||
<template #tab>
|
<template #tab>
|
||||||
<NSpace
|
<span
|
||||||
align="center"
|
:style="{
|
||||||
size="small"
|
color: enabledTriggerTypes && enabledTriggerTypes[type] ? '#18a058' : '#d03050',
|
||||||
inline
|
fontWeight: 'medium'
|
||||||
|
}"
|
||||||
|
:title="enabledTriggerTypes && enabledTriggerTypes[type] ? '已启用' : '已禁用'"
|
||||||
>
|
>
|
||||||
{{ label }}
|
{{ label }}
|
||||||
<span
|
</span>
|
||||||
:style="{
|
|
||||||
color: enabledTriggerTypes && enabledTriggerTypes[type] ? '#18a058' : '#d03050',
|
|
||||||
fontSize: '14px', // Adjust size as needed
|
|
||||||
verticalAlign: 'middle'
|
|
||||||
}"
|
|
||||||
:title="enabledTriggerTypes && enabledTriggerTypes[type] ? '已启用' : '已禁用'"
|
|
||||||
>
|
|
||||||
●
|
|
||||||
</span>
|
|
||||||
</NSpace>
|
|
||||||
</template>
|
</template>
|
||||||
<NSpace vertical>
|
<NSpace vertical>
|
||||||
<NSpace
|
<NSpace
|
||||||
|
|||||||
@@ -208,15 +208,22 @@ export const useWebFetcher = defineStore('WebFetcher', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let isConnectingSignalR = false;
|
||||||
/**
|
/**
|
||||||
* 连接 SignalR 服务器
|
* 连接 SignalR 服务器
|
||||||
*/
|
*/
|
||||||
async function connectSignalR() {
|
async function connectSignalR(): Promise<boolean> {
|
||||||
|
if (isConnectingSignalR) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
isConnectingSignalR = true;
|
||||||
if (signalRClient.value && signalRClient.value.state !== signalR.HubConnectionState.Disconnected) {
|
if (signalRClient.value && signalRClient.value.state !== signalR.HubConnectionState.Disconnected) {
|
||||||
console.log(prefix.value + "SignalR 已连接或正在连接");
|
console.log(prefix.value + "SignalR 已连接或正在连接");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
signalRClient.value?.stop();
|
||||||
|
signalRClient.value = undefined;
|
||||||
|
signalRConnectionId.value = undefined;
|
||||||
console.log(prefix.value + '正在连接到 vtsuru 服务器...');
|
console.log(prefix.value + '正在连接到 vtsuru 服务器...');
|
||||||
const connection = new signalR.HubConnectionBuilder()
|
const connection = new signalR.HubConnectionBuilder()
|
||||||
.withUrl(BASE_HUB_URL + 'web-fetcher?token=' + (route.query.token ?? account.value.token), { // 使用 account.token
|
.withUrl(BASE_HUB_URL + 'web-fetcher?token=' + (route.query.token ?? account.value.token), { // 使用 account.token
|
||||||
@@ -232,48 +239,11 @@ export const useWebFetcher = defineStore('WebFetcher', () => {
|
|||||||
.withHubProtocol(new msgpack.MessagePackHubProtocol()) // 使用 MessagePack 协议
|
.withHubProtocol(new msgpack.MessagePackHubProtocol()) // 使用 MessagePack 协议
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// --- SignalR 事件监听 ---
|
|
||||||
connection.onreconnecting(error => {
|
|
||||||
console.log(prefix.value + `与服务器断开,正在尝试重连... ${error?.message || ''}`);
|
|
||||||
state.value = 'connecting'; // 更新状态为连接中
|
|
||||||
signalRConnectionId.value = undefined; // 连接断开,ID失效
|
|
||||||
});
|
|
||||||
|
|
||||||
connection.onreconnected(async connectionId => {
|
|
||||||
console.log(prefix.value + `与服务器重新连接成功! ConnectionId: ${connectionId}`);
|
|
||||||
signalRConnectionId.value = connectionId ?? undefined;
|
|
||||||
state.value = 'connected'; // 更新状态为已连接
|
|
||||||
signalRId.value = connectionId ?? await sendSelfInfo(connection); // 更新连接ID
|
|
||||||
connection.send('Reconnected').catch(err => console.error(prefix.value + "Send Reconnected failed: " + err));
|
|
||||||
});
|
|
||||||
|
|
||||||
connection.onclose(async (error) => {
|
|
||||||
// 只有在不是由 Stop() 或服务器明确要求断开时才记录错误并尝试独立重连(虽然 withAutomaticReconnect 应该处理)
|
|
||||||
if (state.value !== 'disconnected' && !disconnectedByServer) {
|
|
||||||
console.error(prefix.value + `与服务器连接关闭: ${error?.message || '未知原因'}. 自动重连将处理.`);
|
|
||||||
state.value = 'connecting'; // 标记为连接中,等待自动重连
|
|
||||||
signalRConnectionId.value = undefined;
|
|
||||||
await connection.start();
|
|
||||||
} else if (disconnectedByServer) {
|
|
||||||
console.log(prefix.value + `连接已被服务器关闭.`);
|
|
||||||
//Stop(); // 服务器要求断开,则彻底停止
|
|
||||||
} else {
|
|
||||||
console.log(prefix.value + `连接已手动关闭.`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
connection.on('Disconnect', (reason: unknown) => {
|
connection.on('Disconnect', (reason: unknown) => {
|
||||||
console.log(prefix.value + '被服务器断开连接: ' + reason);
|
console.log(prefix.value + '被服务器断开连接: ' + reason);
|
||||||
disconnectedByServer = true; // 标记是服务器主动断开
|
disconnectedByServer = true; // 标记是服务器主动断开
|
||||||
window.$message.error(`被服务器要求断开连接: ${reason}, 为保证可用性, 30秒后将自动重启`);
|
window.$message.error(`被服务器要求断开连接: ${reason}`);
|
||||||
//Stop(); // 服务器要求断开,调用 Stop 清理所有资源
|
|
||||||
setTimeout(() => {
|
|
||||||
console.log(prefix.value + '尝试重启...');
|
|
||||||
connectSignalR(); // 30秒后尝试重启
|
|
||||||
}, 30 * 1000); // 30秒后自动重启
|
|
||||||
});
|
});
|
||||||
connection.on('Request', async (url: string, method: string, body: string, useCookie: boolean) => onRequest(url, method, body, useCookie));
|
|
||||||
connection.on('Notification', (type: string, data: any) => { onReceivedNotification(type, data); });
|
|
||||||
// --- 尝试启动连接 ---
|
// --- 尝试启动连接 ---
|
||||||
try {
|
try {
|
||||||
await connection.start();
|
await connection.start();
|
||||||
@@ -281,6 +251,47 @@ export const useWebFetcher = defineStore('WebFetcher', () => {
|
|||||||
signalRId.value = await sendSelfInfo(connection); // 发送客户端信息
|
signalRId.value = await sendSelfInfo(connection); // 发送客户端信息
|
||||||
await connection.send('Finished'); // 通知服务器已准备好
|
await connection.send('Finished'); // 通知服务器已准备好
|
||||||
signalRClient.value = connection; // 保存实例
|
signalRClient.value = connection; // 保存实例
|
||||||
|
|
||||||
|
// --- SignalR 事件监听 ---
|
||||||
|
connection.onreconnecting(error => {
|
||||||
|
console.log(prefix.value + `与服务器断开,正在尝试重连... ${error?.message || ''}`);
|
||||||
|
state.value = 'connecting'; // 更新状态为连接中
|
||||||
|
signalRConnectionId.value = undefined; // 连接断开,ID失效
|
||||||
|
});
|
||||||
|
|
||||||
|
connection.onreconnected(async connectionId => {
|
||||||
|
console.log(prefix.value + `与服务器重新连接成功! ConnectionId: ${connectionId}`);
|
||||||
|
signalRConnectionId.value = connectionId ?? undefined;
|
||||||
|
state.value = 'connected'; // 更新状态为已连接
|
||||||
|
signalRId.value = connectionId ?? await sendSelfInfo(connection); // 更新连接ID
|
||||||
|
connection.send('Reconnected').catch(err => console.error(prefix.value + "Send Reconnected failed: " + err));
|
||||||
|
});
|
||||||
|
|
||||||
|
connection.onclose(async (error) => {
|
||||||
|
// 只有在不是由 Stop() 或服务器明确要求断开时才记录错误并尝试独立重连(虽然 withAutomaticReconnect 应该处理)
|
||||||
|
if (state.value !== 'disconnected' && !disconnectedByServer) {
|
||||||
|
console.error(prefix.value + `与服务器连接关闭: ${error?.message || '未知原因'}. 30秒后将自动重启`);
|
||||||
|
//state.value = 'connecting'; // 标记为连接中,等待自动重连
|
||||||
|
//signalRConnectionId.value = undefined;
|
||||||
|
//await connection.start();
|
||||||
|
// 停止 SignalR 连接
|
||||||
|
signalRClient.value?.stop();
|
||||||
|
signalRClient.value = undefined;
|
||||||
|
signalRConnectionId.value = undefined;
|
||||||
|
setTimeout(() => {
|
||||||
|
console.log(prefix.value + '尝试重启...');
|
||||||
|
connectSignalR(); // 30秒后尝试重启
|
||||||
|
}, 30 * 1000); // 30秒后自动重启
|
||||||
|
} else if (disconnectedByServer) {
|
||||||
|
console.log(prefix.value + `连接已被服务器关闭.`);
|
||||||
|
//Stop(); // 服务器要求断开,则彻底停止
|
||||||
|
} else {
|
||||||
|
console.log(prefix.value + `连接已手动关闭.`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connection.on('Request', async (url: string, method: string, body: string, useCookie: boolean) => onRequest(url, method, body, useCookie));
|
||||||
|
connection.on('Notification', (type: string, data: any) => { onReceivedNotification(type, data); });
|
||||||
|
|
||||||
console.log(prefix.value + '已连接到 vtsuru 服务器, ConnectionId: ' + signalRId.value); // 调试输出连接状态
|
console.log(prefix.value + '已连接到 vtsuru 服务器, ConnectionId: ' + signalRId.value); // 调试输出连接状态
|
||||||
// state.value = 'connected'; // 状态将在 Start 函数末尾统一设置
|
// state.value = 'connected'; // 状态将在 Start 函数末尾统一设置
|
||||||
return true;
|
return true;
|
||||||
@@ -290,6 +301,8 @@ export const useWebFetcher = defineStore('WebFetcher', () => {
|
|||||||
signalRClient.value = undefined;
|
signalRClient.value = undefined;
|
||||||
// state.value = 'disconnected'; // 保持 connecting 或由 Start 控制
|
// state.value = 'disconnected'; // 保持 connecting 或由 Start 控制
|
||||||
return false;
|
return false;
|
||||||
|
} finally {
|
||||||
|
isConnectingSignalR = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async function sendSelfInfo(client: signalR.HubConnection) {
|
async function sendSelfInfo(client: signalR.HubConnection) {
|
||||||
|
|||||||
@@ -243,7 +243,9 @@ onMounted(async () => {
|
|||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
>
|
>
|
||||||
<NAlert type="success">
|
<NAlert type="success">
|
||||||
你已完成验证! 请妥善保存你的登陆链接, 请勿让其他人获取. 丢失后可以再次通过认证流程获得. 把这个链接复制到浏览器打开即可登录
|
你已完成验证! 请妥善保存你的登陆链接, 请勿让其他人获取. 丢失后可以再次通过认证流程获得.
|
||||||
|
<br>
|
||||||
|
要在其他地方登陆, 或者需要重新登陆的话把这个链接复制到浏览器地址栏打开即可
|
||||||
</NAlert>
|
</NAlert>
|
||||||
<NText> 你的登陆链接为: </NText>
|
<NText> 你的登陆链接为: </NText>
|
||||||
<NInputGroup>
|
<NInputGroup>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { ResponsePointOrder2UserModel } from '@/api/api-models'
|
|||||||
import PointOrderCard from '@/components/manage/PointOrderCard.vue'
|
import PointOrderCard from '@/components/manage/PointOrderCard.vue'
|
||||||
import { POINT_API_URL } from '@/data/constants'
|
import { POINT_API_URL } from '@/data/constants'
|
||||||
import { useAuthStore } from '@/store/useAuthStore'
|
import { useAuthStore } from '@/store/useAuthStore'
|
||||||
import { NEmpty, NSpin, useMessage } from 'naive-ui'
|
import { NButton, NEmpty, NFlex, NSpin, useMessage } from 'naive-ui'
|
||||||
import { onMounted, ref } from 'vue'
|
import { onMounted, ref } from 'vue'
|
||||||
|
|
||||||
const message = useMessage()
|
const message = useMessage()
|
||||||
@@ -12,11 +12,17 @@ const useAuth = useAuthStore()
|
|||||||
const orders = ref<ResponsePointOrder2UserModel[]>([])
|
const orders = ref<ResponsePointOrder2UserModel[]>([])
|
||||||
const isLoading = ref(false)
|
const isLoading = ref(false)
|
||||||
|
|
||||||
|
// 定义加载完成的事件
|
||||||
|
const emit = defineEmits(['dataLoaded'])
|
||||||
|
|
||||||
async function getOrders() {
|
async function getOrders() {
|
||||||
try {
|
try {
|
||||||
isLoading.value = true
|
isLoading.value = true
|
||||||
const data = await useAuth.QueryBiliAuthGetAPI<ResponsePointOrder2UserModel[]>(POINT_API_URL + 'user/get-orders')
|
const data = await useAuth.QueryBiliAuthGetAPI<ResponsePointOrder2UserModel[]>(POINT_API_URL + 'user/get-orders')
|
||||||
if (data.code == 200) {
|
if (data.code == 200) {
|
||||||
|
orders.value = data.data
|
||||||
|
// 触发数据加载完成事件
|
||||||
|
emit('dataLoaded')
|
||||||
return data.data
|
return data.data
|
||||||
} else {
|
} else {
|
||||||
message.error('获取订单失败: ' + data.message)
|
message.error('获取订单失败: ' + data.message)
|
||||||
@@ -30,6 +36,17 @@ async function getOrders() {
|
|||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 提供给父组件调用的重置方法
|
||||||
|
function reset() {
|
||||||
|
orders.value = []
|
||||||
|
}
|
||||||
|
|
||||||
|
// 暴露方法给父组件
|
||||||
|
defineExpose({
|
||||||
|
getOrders,
|
||||||
|
reset
|
||||||
|
})
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
orders.value = await getOrders()
|
orders.value = await getOrders()
|
||||||
})
|
})
|
||||||
@@ -37,6 +54,9 @@ onMounted(async () => {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<NSpin :show="isLoading">
|
<NSpin :show="isLoading">
|
||||||
|
<NFlex justify="end" style="margin-bottom: 10px">
|
||||||
|
<NButton size="small" type="primary" @click="getOrders">刷新订单</NButton>
|
||||||
|
</NFlex>
|
||||||
<NEmpty
|
<NEmpty
|
||||||
v-if="orders.length == 0"
|
v-if="orders.length == 0"
|
||||||
description="暂无订单"
|
description="暂无订单"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { ResponsePointHisrotyModel } from '@/api/api-models'
|
|||||||
import PointHistoryCard from '@/components/manage/PointHistoryCard.vue'
|
import PointHistoryCard from '@/components/manage/PointHistoryCard.vue'
|
||||||
import { POINT_API_URL } from '@/data/constants'
|
import { POINT_API_URL } from '@/data/constants'
|
||||||
import { useAuthStore } from '@/store/useAuthStore'
|
import { useAuthStore } from '@/store/useAuthStore'
|
||||||
import { NSpin, useMessage } from 'naive-ui'
|
import { NButton, NEmpty, NFlex, NSpin, useMessage } from 'naive-ui'
|
||||||
import { onMounted, ref } from 'vue'
|
import { onMounted, ref } from 'vue'
|
||||||
|
|
||||||
const message = useMessage()
|
const message = useMessage()
|
||||||
@@ -12,6 +12,9 @@ const isLoading = ref(false)
|
|||||||
|
|
||||||
const history = ref<ResponsePointHisrotyModel[]>([])
|
const history = ref<ResponsePointHisrotyModel[]>([])
|
||||||
|
|
||||||
|
// 定义加载完成的事件
|
||||||
|
const emit = defineEmits(['dataLoaded'])
|
||||||
|
|
||||||
// 获取积分历史记录
|
// 获取积分历史记录
|
||||||
async function getHistories() {
|
async function getHistories() {
|
||||||
try {
|
try {
|
||||||
@@ -19,6 +22,9 @@ async function getHistories() {
|
|||||||
const data = await useAuth.QueryBiliAuthGetAPI<ResponsePointHisrotyModel[]>(POINT_API_URL + 'user/get-histories')
|
const data = await useAuth.QueryBiliAuthGetAPI<ResponsePointHisrotyModel[]>(POINT_API_URL + 'user/get-histories')
|
||||||
if (data.code == 200) {
|
if (data.code == 200) {
|
||||||
console.log('[point] 已获取积分历史')
|
console.log('[point] 已获取积分历史')
|
||||||
|
history.value = data.data
|
||||||
|
// 触发数据加载完成事件
|
||||||
|
emit('dataLoaded')
|
||||||
return data.data
|
return data.data
|
||||||
} else {
|
} else {
|
||||||
message.error('获取积分历史失败: ' + data.message)
|
message.error('获取积分历史失败: ' + data.message)
|
||||||
@@ -33,6 +39,17 @@ async function getHistories() {
|
|||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 提供给父组件调用的重置方法
|
||||||
|
function reset() {
|
||||||
|
history.value = []
|
||||||
|
}
|
||||||
|
|
||||||
|
// 暴露方法给父组件
|
||||||
|
defineExpose({
|
||||||
|
getHistories,
|
||||||
|
reset
|
||||||
|
})
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
history.value = await getHistories()
|
history.value = await getHistories()
|
||||||
})
|
})
|
||||||
@@ -40,7 +57,15 @@ onMounted(async () => {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<NSpin :show="isLoading">
|
<NSpin :show="isLoading">
|
||||||
|
<NFlex justify="end" style="margin-bottom: 10px">
|
||||||
|
<NButton size="small" type="primary" @click="getHistories">刷新记录</NButton>
|
||||||
|
</NFlex>
|
||||||
|
<NEmpty
|
||||||
|
v-if="history.length == 0"
|
||||||
|
description="暂无积分记录"
|
||||||
|
/>
|
||||||
<PointHistoryCard
|
<PointHistoryCard
|
||||||
|
v-else
|
||||||
:histories="history"
|
:histories="history"
|
||||||
/>
|
/>
|
||||||
</NSpin>
|
</NSpin>
|
||||||
|
|||||||
@@ -22,14 +22,32 @@ import {
|
|||||||
NTabPane,
|
NTabPane,
|
||||||
NTabs,
|
NTabs,
|
||||||
NText,
|
NText,
|
||||||
|
NTag,
|
||||||
useMessage,
|
useMessage,
|
||||||
} from 'naive-ui'
|
} from 'naive-ui'
|
||||||
import { computed, h, onMounted, ref } from 'vue'
|
import { computed, h, onMounted, ref, watch } from 'vue'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import PointOrderView from './PointOrderView.vue'
|
import PointOrderView from './PointOrderView.vue'
|
||||||
import PointUserHistoryView from './PointUserHistoryView.vue'
|
import PointUserHistoryView from './PointUserHistoryView.vue'
|
||||||
import PointUserSettings from './PointUserSettings.vue'
|
import PointUserSettings from './PointUserSettings.vue'
|
||||||
|
|
||||||
|
// 定义组件接口
|
||||||
|
interface ComponentWithReset {
|
||||||
|
reset: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface OrderViewInstance extends ComponentWithReset {
|
||||||
|
getOrders: () => Promise<any>;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface HistoryViewInstance extends ComponentWithReset {
|
||||||
|
getHistories: () => Promise<any>;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SettingsViewInstance extends ComponentWithReset {
|
||||||
|
// 设置组件可能需要的方法
|
||||||
|
}
|
||||||
|
|
||||||
const useAuth = useAuthStore()
|
const useAuth = useAuthStore()
|
||||||
const message = useMessage()
|
const message = useMessage()
|
||||||
const realHash = useRouteHash('points', {
|
const realHash = useRouteHash('points', {
|
||||||
@@ -48,6 +66,19 @@ const router = useRouter()
|
|||||||
const biliAuth = computed(() => useAuth.biliAuth)
|
const biliAuth = computed(() => useAuth.biliAuth)
|
||||||
const isLoading = ref(false)
|
const isLoading = ref(false)
|
||||||
const points = ref<{ owner: UserInfo; points: number }[]>([])
|
const points = ref<{ owner: UserInfo; points: number }[]>([])
|
||||||
|
const isFirstMounted = ref(true)
|
||||||
|
// 分别定义各组件引用,使用正确的类型
|
||||||
|
const orderViewRef = ref<OrderViewInstance | null>(null)
|
||||||
|
const historyViewRef = ref<HistoryViewInstance | null>(null)
|
||||||
|
const settingsViewRef = ref<SettingsViewInstance | null>(null)
|
||||||
|
|
||||||
|
// 跟踪各标签页数据是否已加载
|
||||||
|
const tabDataLoaded = ref({
|
||||||
|
points: false,
|
||||||
|
orders: false,
|
||||||
|
histories: false,
|
||||||
|
settings: true // 设置页面不需要加载数据
|
||||||
|
})
|
||||||
|
|
||||||
const pointColumn = [
|
const pointColumn = [
|
||||||
{
|
{
|
||||||
@@ -89,6 +120,7 @@ async function getAllPoints() {
|
|||||||
if (data.code == 200) {
|
if (data.code == 200) {
|
||||||
console.log('[point] 已获取积分')
|
console.log('[point] 已获取积分')
|
||||||
points.value = data.data
|
points.value = data.data
|
||||||
|
tabDataLoaded.value.points = true
|
||||||
return data.data
|
return data.data
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -99,21 +131,81 @@ async function getAllPoints() {
|
|||||||
}
|
}
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 重置所有数据
|
||||||
|
function resetData() {
|
||||||
|
points.value = []
|
||||||
|
isFirstMounted.value = true
|
||||||
|
// 重置数据加载状态
|
||||||
|
Object.keys(tabDataLoaded.value).forEach(key => {
|
||||||
|
tabDataLoaded.value[key as keyof typeof tabDataLoaded.value] = false
|
||||||
|
})
|
||||||
|
tabDataLoaded.value.settings = true // 设置页不需要加载数据
|
||||||
|
// 重置所有子组件的数据
|
||||||
|
orderViewRef.value?.reset?.()
|
||||||
|
historyViewRef.value?.reset?.()
|
||||||
|
settingsViewRef.value?.reset?.()
|
||||||
|
}
|
||||||
|
|
||||||
function switchAuth(token: string) {
|
function switchAuth(token: string) {
|
||||||
if (token == useAuth.biliToken) {
|
if (token == useAuth.biliToken) {
|
||||||
message.info('当前正在使用该账号')
|
message.info('当前正在使用该账号')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
resetData()
|
||||||
useAuth.setCurrentAuth(token)
|
useAuth.setCurrentAuth(token)
|
||||||
message.success('已选择账号')
|
message.success('已选择账号')
|
||||||
}
|
}
|
||||||
let isFirstMounted = true
|
|
||||||
function onAllPointPaneMounted() {
|
function onAllPointPaneMounted() {
|
||||||
if (!isFirstMounted) return
|
if (!isFirstMounted.value) return
|
||||||
isFirstMounted = false
|
isFirstMounted.value = false
|
||||||
getAllPoints()
|
getAllPoints()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理选项卡切换
|
||||||
|
function onTabChange(tabName: string) {
|
||||||
|
// 只在数据未加载时刷新
|
||||||
|
switch(tabName) {
|
||||||
|
case 'points':
|
||||||
|
if (!tabDataLoaded.value.points) {
|
||||||
|
getAllPoints()
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'orders':
|
||||||
|
if (!tabDataLoaded.value.orders && orderViewRef.value) {
|
||||||
|
orderViewRef.value.getOrders()
|
||||||
|
tabDataLoaded.value.orders = true
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'histories':
|
||||||
|
if (!tabDataLoaded.value.histories && historyViewRef.value) {
|
||||||
|
historyViewRef.value.getHistories()
|
||||||
|
tabDataLoaded.value.histories = true
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听 biliToken 变化
|
||||||
|
watch(() => useAuth.biliToken, (newToken) => {
|
||||||
|
if (newToken) {
|
||||||
|
resetData()
|
||||||
|
getAllPoints()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 手动刷新当前标签页数据
|
||||||
|
function refreshCurrentTab() {
|
||||||
|
if (!hash.value) return
|
||||||
|
|
||||||
|
// 将当前标签设为未加载状态
|
||||||
|
tabDataLoaded.value[hash.value as keyof typeof tabDataLoaded.value] = false
|
||||||
|
|
||||||
|
// 触发刷新
|
||||||
|
onTabChange(hash.value)
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
if (route.query.auth) {
|
if (route.query.auth) {
|
||||||
@@ -205,10 +297,28 @@ onMounted(async () => {
|
|||||||
style="padding: 10px"
|
style="padding: 10px"
|
||||||
bordered
|
bordered
|
||||||
>
|
>
|
||||||
<NFlex justify="center">
|
<NFlex
|
||||||
|
justify="space-between"
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
<NButton
|
||||||
|
type="primary"
|
||||||
|
secondary
|
||||||
|
@click="$router.back()"
|
||||||
|
>
|
||||||
|
返回
|
||||||
|
</NButton>
|
||||||
<NText style="font-size: 24px">
|
<NText style="font-size: 24px">
|
||||||
认证用户个人中心
|
认证用户个人中心
|
||||||
</NText>
|
</NText>
|
||||||
|
<NButton
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
:disabled="!hash"
|
||||||
|
@click="refreshCurrentTab"
|
||||||
|
>
|
||||||
|
刷新数据
|
||||||
|
</NButton>
|
||||||
</NFlex>
|
</NFlex>
|
||||||
</NLayoutHeader>
|
</NLayoutHeader>
|
||||||
<NLayoutContent content-style="padding: 24px;">
|
<NLayoutContent content-style="padding: 24px;">
|
||||||
@@ -236,6 +346,20 @@ onMounted(async () => {
|
|||||||
<NDescriptionsItem label="OpenId">
|
<NDescriptionsItem label="OpenId">
|
||||||
{{ biliAuth.openId }}
|
{{ biliAuth.openId }}
|
||||||
</NDescriptionsItem>
|
</NDescriptionsItem>
|
||||||
|
<NDescriptionsItem label="状态">
|
||||||
|
<NTag
|
||||||
|
v-if="biliAuth.id > 0"
|
||||||
|
type="success"
|
||||||
|
>
|
||||||
|
已认证
|
||||||
|
</NTag>
|
||||||
|
<NTag
|
||||||
|
v-else
|
||||||
|
type="error"
|
||||||
|
>
|
||||||
|
未认证
|
||||||
|
</NTag>
|
||||||
|
</NDescriptionsItem>
|
||||||
</NDescriptions>
|
</NDescriptions>
|
||||||
</NCard>
|
</NCard>
|
||||||
<NDivider />
|
<NDivider />
|
||||||
@@ -244,6 +368,7 @@ onMounted(async () => {
|
|||||||
v-model:value="hash"
|
v-model:value="hash"
|
||||||
default-value="points"
|
default-value="points"
|
||||||
animated
|
animated
|
||||||
|
@update:value="onTabChange"
|
||||||
>
|
>
|
||||||
<NTabPane
|
<NTabPane
|
||||||
name="points"
|
name="points"
|
||||||
@@ -252,15 +377,21 @@ onMounted(async () => {
|
|||||||
@vue:mounted="onAllPointPaneMounted"
|
@vue:mounted="onAllPointPaneMounted"
|
||||||
>
|
>
|
||||||
<NDivider style="margin-top: 10px" />
|
<NDivider style="margin-top: 10px" />
|
||||||
<NButton
|
<NFlex
|
||||||
|
justify="end"
|
||||||
style="margin-bottom: 10px"
|
style="margin-bottom: 10px"
|
||||||
size="small"
|
|
||||||
type="primary"
|
|
||||||
@click="getAllPoints()"
|
|
||||||
>
|
>
|
||||||
刷新
|
<NButton
|
||||||
</NButton>
|
size="small"
|
||||||
<NDivider />
|
type="primary"
|
||||||
|
@click="() => {
|
||||||
|
tabDataLoaded.points = false;
|
||||||
|
getAllPoints();
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
刷新积分
|
||||||
|
</NButton>
|
||||||
|
</NFlex>
|
||||||
<NFlex justify="center">
|
<NFlex justify="center">
|
||||||
<NDataTable
|
<NDataTable
|
||||||
:loading="isLoading"
|
:loading="isLoading"
|
||||||
@@ -278,7 +409,10 @@ onMounted(async () => {
|
|||||||
display-directive="show:lazy"
|
display-directive="show:lazy"
|
||||||
>
|
>
|
||||||
<NDivider style="margin-top: 10px" />
|
<NDivider style="margin-top: 10px" />
|
||||||
<PointOrderView />
|
<PointOrderView
|
||||||
|
ref="orderViewRef"
|
||||||
|
@data-loaded="tabDataLoaded.orders = true"
|
||||||
|
/>
|
||||||
</NTabPane>
|
</NTabPane>
|
||||||
<NTabPane
|
<NTabPane
|
||||||
name="histories"
|
name="histories"
|
||||||
@@ -286,7 +420,10 @@ onMounted(async () => {
|
|||||||
display-directive="show:lazy"
|
display-directive="show:lazy"
|
||||||
>
|
>
|
||||||
<NDivider style="margin-top: 10px" />
|
<NDivider style="margin-top: 10px" />
|
||||||
<PointUserHistoryView />
|
<PointUserHistoryView
|
||||||
|
ref="historyViewRef"
|
||||||
|
@data-loaded="tabDataLoaded.histories = true"
|
||||||
|
/>
|
||||||
</NTabPane>
|
</NTabPane>
|
||||||
<NTabPane
|
<NTabPane
|
||||||
name="settings"
|
name="settings"
|
||||||
@@ -294,7 +431,7 @@ onMounted(async () => {
|
|||||||
display-directive="show:lazy"
|
display-directive="show:lazy"
|
||||||
>
|
>
|
||||||
<NDivider style="margin-top: 10px" />
|
<NDivider style="margin-top: 10px" />
|
||||||
<PointUserSettings />
|
<PointUserSettings ref="settingsViewRef" />
|
||||||
</NTabPane>
|
</NTabPane>
|
||||||
</NTabs>
|
</NTabs>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -252,6 +252,19 @@ function switchAuth(token: string) {
|
|||||||
function logout() {
|
function logout() {
|
||||||
useAuth.logout()
|
useAuth.logout()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 提供给父组件调用的重置方法
|
||||||
|
function reset() {
|
||||||
|
// 重置表单数据或其他状态
|
||||||
|
currentAddress.value = {} as AddressInfo
|
||||||
|
userAgree.value = false
|
||||||
|
// 可能还需要重置其他状态
|
||||||
|
}
|
||||||
|
|
||||||
|
// 暴露方法给父组件
|
||||||
|
defineExpose({
|
||||||
|
reset
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
Reference in New Issue
Block a user