mirror of
https://github.com/algerkong/AlgerMusicPlayer.git
synced 2026-04-05 07:20:50 +08:00
feat: 添加所有用户的关注和粉丝列表点击 优化播放排行获取和无权限展示
This commit is contained in:
@@ -18,12 +18,16 @@ export default {
|
||||
viewPlaylist: 'View Playlist',
|
||||
noFollowings: 'No Followings',
|
||||
loadMore: 'Load More',
|
||||
noSignature: 'This guy is lazy, nothing left'
|
||||
noSignature: 'This guy is lazy, nothing left',
|
||||
userFollowsTitle: '\'s Followings',
|
||||
myFollowsTitle: 'My Followings'
|
||||
},
|
||||
follower: {
|
||||
title: 'Follower List',
|
||||
noFollowers: 'No Followers',
|
||||
loadMore: 'Load More'
|
||||
loadMore: 'Load More',
|
||||
userFollowersTitle: '\'s Followers',
|
||||
myFollowersTitle: 'My Followers'
|
||||
},
|
||||
detail: {
|
||||
playlists: 'Playlists',
|
||||
@@ -32,7 +36,8 @@ export default {
|
||||
noRecords: 'No Listening History',
|
||||
artist: 'Artist',
|
||||
noSignature: 'This guy is lazy, nothing left',
|
||||
invalidUserId: 'Invalid User ID'
|
||||
invalidUserId: 'Invalid User ID',
|
||||
noRecordPermission: '{name} doesn\'t let you see your listening history'
|
||||
},
|
||||
message: {
|
||||
loadFailed: 'Failed to load user page',
|
||||
|
||||
@@ -18,12 +18,16 @@ export default {
|
||||
viewPlaylist: '查看歌单',
|
||||
noFollowings: '暂无关注',
|
||||
loadMore: '加载更多',
|
||||
noSignature: '这个家伙很懒,什么都没留下'
|
||||
noSignature: '这个家伙很懒,什么都没留下',
|
||||
userFollowsTitle: '的关注',
|
||||
myFollowsTitle: '我的关注'
|
||||
},
|
||||
follower: {
|
||||
title: '粉丝列表',
|
||||
noFollowers: '暂无粉丝',
|
||||
loadMore: '加载更多'
|
||||
loadMore: '加载更多',
|
||||
userFollowersTitle: '的粉丝',
|
||||
myFollowersTitle: '我的粉丝'
|
||||
},
|
||||
detail: {
|
||||
playlists: '歌单',
|
||||
@@ -32,7 +36,8 @@ export default {
|
||||
noRecords: '暂无听歌记录',
|
||||
artist: '歌手',
|
||||
noSignature: '这个人很懒,什么都没留下',
|
||||
invalidUserId: '用户ID无效'
|
||||
invalidUserId: '用户ID无效',
|
||||
noRecordPermission: '{name}不让你看听歌排行'
|
||||
},
|
||||
message: {
|
||||
loadFailed: '加载用户页面失败',
|
||||
|
||||
@@ -14,7 +14,11 @@ export function getUserPlaylist(uid: number, limit: number = 30, offset: number
|
||||
// 播放历史
|
||||
// /user/record?uid=32953014&type=1
|
||||
export function getUserRecord(uid: number, type: number = 0) {
|
||||
return request.get('/user/record', { params: { uid, type } });
|
||||
|
||||
return request.get('/user/record', {
|
||||
params: { uid, type },
|
||||
noRetry: true
|
||||
} as any);
|
||||
}
|
||||
|
||||
// 获取用户关注列表
|
||||
|
||||
@@ -4,7 +4,7 @@ const otherRouter = [
|
||||
name: 'userFollows',
|
||||
meta: {
|
||||
title: '关注列表',
|
||||
keepAlive: true,
|
||||
keepAlive: false,
|
||||
showInMenu: false,
|
||||
back: true
|
||||
},
|
||||
@@ -15,7 +15,7 @@ const otherRouter = [
|
||||
name: 'userFollowers',
|
||||
meta: {
|
||||
title: '粉丝列表',
|
||||
keepAlive: true,
|
||||
keepAlive: false,
|
||||
showInMenu: false,
|
||||
back: true
|
||||
},
|
||||
@@ -26,7 +26,7 @@ const otherRouter = [
|
||||
name: 'userDetail',
|
||||
meta: {
|
||||
title: '用户详情',
|
||||
keepAlive: true,
|
||||
keepAlive: false,
|
||||
showInMenu: false,
|
||||
back: true
|
||||
},
|
||||
|
||||
@@ -2,13 +2,14 @@ import axios, { InternalAxiosRequestConfig } from 'axios';
|
||||
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
|
||||
import { getSetData, isElectron } from '.';
|
||||
import { getSetData, isElectron, isMobile } from '.';
|
||||
|
||||
let setData: any = null;
|
||||
|
||||
// 扩展请求配置接口
|
||||
interface CustomAxiosRequestConfig extends InternalAxiosRequestConfig {
|
||||
retryCount?: number;
|
||||
noRetry?: boolean;
|
||||
}
|
||||
|
||||
const baseURL = window.electron
|
||||
@@ -22,7 +23,7 @@ const request = axios.create({
|
||||
});
|
||||
|
||||
// 最大重试次数
|
||||
const MAX_RETRIES = 3;
|
||||
const MAX_RETRIES = 1;
|
||||
// 重试延迟(毫秒)
|
||||
const RETRY_DELAY = 500;
|
||||
|
||||
@@ -42,7 +43,8 @@ request.interceptors.request.use(
|
||||
// 在get请求params中添加timestamp
|
||||
config.params = {
|
||||
...config.params,
|
||||
timestamp: Date.now()
|
||||
timestamp: Date.now(),
|
||||
device: isElectron ? 'pc' : isMobile ? 'mobile' : 'web'
|
||||
};
|
||||
const token = localStorage.getItem('token');
|
||||
if (token && config.method !== 'post') {
|
||||
@@ -100,7 +102,8 @@ request.interceptors.response.use(
|
||||
if (
|
||||
config.retryCount !== undefined &&
|
||||
config.retryCount < MAX_RETRIES &&
|
||||
!NO_RETRY_URLS.includes(config.url as string)
|
||||
!NO_RETRY_URLS.includes(config.url as string) &&
|
||||
!config.noRetry
|
||||
) {
|
||||
config.retryCount++;
|
||||
console.error(`请求重试第 ${config.retryCount} 次`);
|
||||
|
||||
@@ -26,11 +26,11 @@
|
||||
</n-tooltip>
|
||||
</div>
|
||||
<div class="user-info-stats">
|
||||
<div class="user-info-stat-item">
|
||||
<div class="user-info-stat-item" @click="showFollowerList">
|
||||
<div class="label">{{ userDetail.profile.followeds }}</div>
|
||||
<div>{{ t('user.profile.followers') }}</div>
|
||||
</div>
|
||||
<div class="user-info-stat-item">
|
||||
<div class="user-info-stat-item" @click="showFollowList">
|
||||
<div class="label">{{ userDetail.profile.follows }}</div>
|
||||
<div>{{ t('user.profile.following') }}</div>
|
||||
</div>
|
||||
@@ -50,10 +50,7 @@
|
||||
<n-tabs type="line" animated>
|
||||
<!-- 歌单列表 -->
|
||||
<n-tab-pane name="playlists" :tab="t('user.detail.playlists')">
|
||||
<div v-if="loading" class="loading-container">
|
||||
<n-spin size="medium" />
|
||||
</div>
|
||||
<div v-else-if="playList.length === 0" class="empty-message">
|
||||
<div v-if="playList.length === 0" class="empty-message">
|
||||
{{ t('user.detail.noPlaylists') }}
|
||||
</div>
|
||||
<div v-else class="playlist-grid" :class="setAnimationClass('animate__fadeInUp')">
|
||||
@@ -89,8 +86,11 @@
|
||||
|
||||
<!-- 听歌排行 -->
|
||||
<n-tab-pane name="records" :tab="t('user.detail.records')">
|
||||
<div v-if="loading" class="loading-container">
|
||||
<n-spin size="medium" />
|
||||
<div v-if="!hasRecordPermission" class="empty-message">
|
||||
<div class="no-permission">
|
||||
<i class="ri-lock-line text-2xl mr-2"></i>
|
||||
{{ t('user.detail.noRecordPermission', { name: userDetail.profile.nickname }) }}
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="!recordList || recordList.length === 0" class="empty-message">
|
||||
{{ t('user.detail.noRecords') }}
|
||||
@@ -103,10 +103,7 @@
|
||||
:class="setAnimationClass('animate__bounceInUp')"
|
||||
:style="setAnimationDelay(index, 25)"
|
||||
>
|
||||
<div class="play-score">
|
||||
{{ index + 1 }}
|
||||
</div>
|
||||
<song-item class="song-item" :item="item" mini @play="handlePlay" />
|
||||
<song-item class="song-item" :index="index" :item="item" compact @play="handlePlay" />
|
||||
</div>
|
||||
</div>
|
||||
</n-tab-pane>
|
||||
@@ -125,7 +122,7 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
@@ -150,12 +147,12 @@ const playerStore = usePlayerStore();
|
||||
|
||||
// 获取路由参数中的用户ID
|
||||
const userId = ref<number>(Number(route.params.uid));
|
||||
|
||||
// 用户数据
|
||||
const userDetail = ref<IUserDetail>();
|
||||
const playList = ref<any[]>([]);
|
||||
const recordList = ref<any[]>([]);
|
||||
const loading = ref(true);
|
||||
const hasRecordPermission = ref(true); // 是否有权限查看听歌记录
|
||||
|
||||
// 歌单详情相关
|
||||
const currentList = ref<Playlist>();
|
||||
@@ -171,34 +168,68 @@ const loadUserData = async () => {
|
||||
|
||||
try {
|
||||
loading.value = true;
|
||||
recordList.value = []; // 清空之前的记录
|
||||
hasRecordPermission.value = true; // 重置权限状态
|
||||
|
||||
// 使用 Promise.all 并行请求提高效率
|
||||
const [userDetailRes, playlistRes, recordRes] = await Promise.all([
|
||||
getUserDetail(userId.value),
|
||||
getUserPlaylist(userId.value),
|
||||
getUserRecord(userId.value)
|
||||
]);
|
||||
// 分开处理请求,处理可能的错误
|
||||
// 1. 获取用户详情和歌单列表
|
||||
try {
|
||||
const [userDetailRes, playlistRes] = await Promise.all([
|
||||
getUserDetail(userId.value),
|
||||
getUserPlaylist(userId.value)
|
||||
]);
|
||||
|
||||
userDetail.value = userDetailRes.data;
|
||||
playList.value = playlistRes.data.playlist;
|
||||
userDetail.value = userDetailRes.data;
|
||||
playList.value = playlistRes.data.playlist;
|
||||
} catch (error) {
|
||||
console.error('加载用户基本信息失败:', error);
|
||||
message.error(t('user.message.loadBasicInfoFailed'));
|
||||
return; // 如果基本信息加载失败,直接返回
|
||||
}
|
||||
|
||||
if (recordRes.data && recordRes.data.allData) {
|
||||
recordList.value = recordRes.data.allData.map((item: any) => ({
|
||||
...item,
|
||||
...item.song,
|
||||
picUrl: item.song.al.picUrl
|
||||
}));
|
||||
} else {
|
||||
recordList.value = [];
|
||||
// 2. 单独处理听歌记录请求,这个请求可能会无权限
|
||||
try {
|
||||
const recordRes = await getUserRecord(userId.value);
|
||||
|
||||
if (recordRes.data && recordRes.data.allData) {
|
||||
recordList.value = recordRes.data.allData.map((item: any) => ({
|
||||
...item,
|
||||
...item.song,
|
||||
picUrl: item.song.al.picUrl
|
||||
}));
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('加载听歌记录失败:', error);
|
||||
// 判断是否是无权限错误
|
||||
if (error.response?.data?.code === -2 || error.data?.code === -2) {
|
||||
hasRecordPermission.value = false;
|
||||
}
|
||||
// 不显示错误消息,因为这是预期的情况
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载用户数据失败:', error);
|
||||
message.error('加载用户数据失败');
|
||||
message.error(t('user.message.loadFailed'));
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 使用onMounted和watch结合的方式解决路由变化问题
|
||||
onMounted(() => {
|
||||
loadUserData();
|
||||
});
|
||||
|
||||
// 监听路由参数变化
|
||||
watch(
|
||||
() => route.params.uid,
|
||||
(newUid) => {
|
||||
if (newUid && Number(newUid) !== userId.value) {
|
||||
userId.value = Number(newUid);
|
||||
loadUserData();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// 替换显示歌单的方法
|
||||
const openPlaylist = (item: any) => {
|
||||
listLoading.value = true;
|
||||
@@ -226,15 +257,36 @@ const handlePlay = () => {
|
||||
playerStore.setPlayList(tracks);
|
||||
};
|
||||
|
||||
// 显示关注列表
|
||||
const showFollowList = () => {
|
||||
if (!userDetail.value) return;
|
||||
|
||||
router.push({
|
||||
path: `/user/follows`,
|
||||
query: {
|
||||
uid: userId.value.toString(),
|
||||
name: userDetail.value.profile.nickname
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 显示粉丝列表
|
||||
const showFollowerList = () => {
|
||||
if (!userDetail.value) return;
|
||||
|
||||
router.push({
|
||||
path: `/user/followers`,
|
||||
query: {
|
||||
uid: userId.value.toString(),
|
||||
name: userDetail.value.profile.nickname
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 判断是否为歌手
|
||||
const isArtist = (profile: any) => {
|
||||
return profile.userType === 4 || profile.userType === 2 || profile.accountType === 2;
|
||||
};
|
||||
|
||||
// 页面挂载时加载数据
|
||||
onMounted(() => {
|
||||
loadUserData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@@ -288,6 +340,11 @@ onMounted(() => {
|
||||
.label {
|
||||
@apply text-lg font-bold;
|
||||
}
|
||||
|
||||
&:nth-child(1), &:nth-child(2) {
|
||||
@apply cursor-pointer transition-all duration-200;
|
||||
@apply hover:bg-black hover:bg-opacity-20 rounded-lg px-2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -365,5 +422,14 @@ onMounted(() => {
|
||||
|
||||
.empty-message {
|
||||
@apply flex justify-center items-center p-8;
|
||||
|
||||
.no-permission {
|
||||
@apply flex flex-col items-center justify-center text-gray-500 dark:text-gray-400;
|
||||
@apply p-4 rounded-lg;
|
||||
|
||||
i {
|
||||
@apply text-3xl mb-2;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
<template>
|
||||
<div class="followers-page">
|
||||
<div class="content-wrapper">
|
||||
<div class="page-title" v-if="targetUserName">
|
||||
{{ targetUserName + t('user.follower.userFollowersTitle') }}
|
||||
</div>
|
||||
<div class="page-title" v-else>
|
||||
{{ t('user.follower.myFollowersTitle') }}
|
||||
</div>
|
||||
|
||||
<n-spin v-if="followerListLoading && followerList.length === 0" size="large" />
|
||||
<n-scrollbar v-else class="scrollbar-container">
|
||||
<div v-if="followerList.length === 0" class="empty-follower">
|
||||
@@ -60,9 +67,9 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import { computed, onMounted, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useRouter, useRoute } from 'vue-router';
|
||||
|
||||
import { getUserFollowers } from '@/api/user';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
@@ -77,6 +84,7 @@ const { t } = useI18n();
|
||||
const userStore = useUserStore();
|
||||
const router = useRouter();
|
||||
const message = useMessage();
|
||||
const route = useRoute();
|
||||
|
||||
// 粉丝列表相关
|
||||
const followerList = ref<IUserFollow[]>([]);
|
||||
@@ -84,9 +92,26 @@ const followerOffset = ref(0);
|
||||
const followerLimit = ref(30);
|
||||
const hasMoreFollowers = ref(false);
|
||||
const followerListLoading = ref(false);
|
||||
const targetUserId = ref<number | null>(null);
|
||||
const targetUserName = ref<string>('');
|
||||
|
||||
const user = computed(() => userStore.user);
|
||||
|
||||
// 检查是否有指定用户ID
|
||||
const checkTargetUser = () => {
|
||||
const uid = route.query.uid;
|
||||
const name = route.query.name;
|
||||
|
||||
if (uid && typeof uid === 'string') {
|
||||
targetUserId.value = parseInt(uid);
|
||||
targetUserName.value = typeof name === 'string' ? name : '';
|
||||
return true;
|
||||
}
|
||||
|
||||
// 如果没有指定用户ID,则显示当前登录用户的粉丝列表
|
||||
return checkLoginStatus();
|
||||
};
|
||||
|
||||
// 检查登录状态
|
||||
const checkLoginStatus = () => {
|
||||
const token = localStorage.getItem('token');
|
||||
@@ -107,12 +132,15 @@ const checkLoginStatus = () => {
|
||||
|
||||
// 加载粉丝列表
|
||||
const loadFollowerList = async () => {
|
||||
if (!user.value) return;
|
||||
// 确定要加载哪个用户的粉丝列表
|
||||
const userId = targetUserId.value || (user.value?.userId);
|
||||
|
||||
if (!userId) return;
|
||||
|
||||
try {
|
||||
followerListLoading.value = true;
|
||||
const { data } = await getUserFollowers(
|
||||
user.value.userId,
|
||||
userId,
|
||||
followerLimit.value,
|
||||
followerOffset.value
|
||||
);
|
||||
@@ -129,7 +157,7 @@ const loadFollowerList = async () => {
|
||||
hasMoreFollowers.value = newFollowers.length >= followerLimit.value;
|
||||
} catch (error) {
|
||||
console.error('加载粉丝列表失败:', error);
|
||||
message.error('加载粉丝列表失败');
|
||||
message.error(t('user.follower.loadFailed'));
|
||||
} finally {
|
||||
followerListLoading.value = false;
|
||||
}
|
||||
@@ -157,7 +185,17 @@ const isArtist = (user: IUserFollow) => {
|
||||
|
||||
// 页面挂载时加载数据
|
||||
onMounted(() => {
|
||||
if (checkLoginStatus()) {
|
||||
if (checkTargetUser()) {
|
||||
loadFollowerList();
|
||||
}
|
||||
});
|
||||
|
||||
// 监听路由变化重新加载数据
|
||||
watch(() => route.query, (newQuery) => {
|
||||
if (newQuery.uid && newQuery.uid !== targetUserId.value?.toString()) {
|
||||
followerList.value = []; // 清空列表
|
||||
followerOffset.value = 0; // 重置偏移量
|
||||
checkTargetUser();
|
||||
loadFollowerList();
|
||||
}
|
||||
});
|
||||
@@ -238,4 +276,9 @@ onMounted(() => {
|
||||
.loading-more {
|
||||
@apply my-4;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
@apply text-xl font-bold mb-4;
|
||||
@apply text-gray-900 dark:text-white;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
<template>
|
||||
<div class="follows-page">
|
||||
<div class="content-wrapper">
|
||||
<div class="page-title" v-if="targetUserName">
|
||||
{{ targetUserName + t('user.follow.userFollowsTitle') }}
|
||||
</div>
|
||||
<div class="page-title" v-else>
|
||||
{{ t('user.follow.myFollowsTitle') }}
|
||||
</div>
|
||||
|
||||
<n-spin v-if="followListLoading && followList.length === 0" size="large" />
|
||||
<n-scrollbar v-else class="scrollbar-container">
|
||||
<div v-if="followList.length === 0" class="empty-follow">
|
||||
@@ -60,9 +67,9 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import { computed, onMounted, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useRouter, useRoute } from 'vue-router';
|
||||
|
||||
import { getUserFollows } from '@/api/user';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
@@ -77,6 +84,7 @@ const { t } = useI18n();
|
||||
const userStore = useUserStore();
|
||||
const router = useRouter();
|
||||
const message = useMessage();
|
||||
const route = useRoute();
|
||||
|
||||
// 关注列表相关
|
||||
const followList = ref<IUserFollow[]>([]);
|
||||
@@ -84,9 +92,26 @@ const followOffset = ref(0);
|
||||
const followLimit = ref(30);
|
||||
const hasMoreFollows = ref(false);
|
||||
const followListLoading = ref(false);
|
||||
const targetUserId = ref<number | null>(null);
|
||||
const targetUserName = ref<string>('');
|
||||
|
||||
const user = computed(() => userStore.user);
|
||||
|
||||
// 检查是否有指定用户ID
|
||||
const checkTargetUser = () => {
|
||||
const uid = route.query.uid;
|
||||
const name = route.query.name;
|
||||
|
||||
if (uid && typeof uid === 'string') {
|
||||
targetUserId.value = parseInt(uid);
|
||||
targetUserName.value = typeof name === 'string' ? name : '';
|
||||
return true;
|
||||
}
|
||||
|
||||
// 如果没有指定用户ID,则显示当前登录用户的关注列表
|
||||
return checkLoginStatus();
|
||||
};
|
||||
|
||||
// 检查登录状态
|
||||
const checkLoginStatus = () => {
|
||||
const token = localStorage.getItem('token');
|
||||
@@ -107,11 +132,14 @@ const checkLoginStatus = () => {
|
||||
|
||||
// 加载关注列表
|
||||
const loadFollowList = async () => {
|
||||
if (!user.value) return;
|
||||
// 确定要加载哪个用户的关注列表
|
||||
const userId = targetUserId.value || (user.value?.userId);
|
||||
|
||||
if (!userId) return;
|
||||
|
||||
try {
|
||||
followListLoading.value = true;
|
||||
const { data } = await getUserFollows(user.value.userId, followLimit.value, followOffset.value);
|
||||
const { data } = await getUserFollows(userId, followLimit.value, followOffset.value);
|
||||
|
||||
if (!data || !data.follow) {
|
||||
hasMoreFollows.value = false;
|
||||
@@ -125,7 +153,7 @@ const loadFollowList = async () => {
|
||||
hasMoreFollows.value = newFollows.length >= followLimit.value;
|
||||
} catch (error) {
|
||||
console.error('加载关注列表失败:', error);
|
||||
message.error('加载关注列表失败');
|
||||
message.error(t('user.follow.loadFailed'));
|
||||
} finally {
|
||||
followListLoading.value = false;
|
||||
}
|
||||
@@ -153,7 +181,17 @@ const isArtist = (user: IUserFollow) => {
|
||||
|
||||
// 页面挂载时加载数据
|
||||
onMounted(() => {
|
||||
if (checkLoginStatus()) {
|
||||
if (checkTargetUser()) {
|
||||
loadFollowList();
|
||||
}
|
||||
});
|
||||
|
||||
// 监听路由变化重新加载数据
|
||||
watch(() => route.query, (newQuery) => {
|
||||
if (newQuery.uid && newQuery.uid !== targetUserId.value?.toString()) {
|
||||
followList.value = []; // 清空列表
|
||||
followOffset.value = 0; // 重置偏移量
|
||||
checkTargetUser();
|
||||
loadFollowList();
|
||||
}
|
||||
});
|
||||
@@ -234,4 +272,9 @@ onMounted(() => {
|
||||
.loading-more {
|
||||
@apply my-4;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
@apply text-xl font-bold mb-4;
|
||||
@apply text-gray-900 dark:text-white;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user