搜索结果列表页面开发

This commit is contained in:
付民康
2025-03-12 18:41:20 +08:00
commit 7cebe8fc00
739 changed files with 88149 additions and 0 deletions

View File

@@ -0,0 +1,178 @@
<template>
<user-info-card
class="user-info"
v-bind="userInfoData"
:hideFollowData="hideFollowData"
:profileLoading="profileLoading"
:isPrivate="isPrivate"
>
<template v-if="!userInfoData.isSelf" #action>
<div class="user-info-actions">
<d-button :loading="loading" class="user-info-button" @click="onToggleStar">
<Icon
v-if="!loading"
:name="userInfoData.hasFollowed ? 'gt-starred-c' : 'gt-star'"
:color="userInfoData.hasFollowed ? 'var(--color-Y500)' : ''"
size="16px"
/>
<span class="ml-2">
{{ userInfoData.hasFollowed ? '已关注' : '关注' }}
</span>
</d-button>
</div>
</template>
</user-info-card>
</template>
<script lang="ts">
export default {
name: 'user-info'
};
</script>
<script setup lang="ts">
import { ref, onMounted, watch } from 'vue';
import { useUserInfo } from '@/views/User/hooks/useUserInfo';
import UserInfoCard from '@/components/UserInfoCard/index.vue';
import { getUserProfile } from '@/api/user';
import { reqCatch } from '@/utils/catch';
import { otherAccountStore } from '@/stores/user';
import type { UserProfile } from '@/api/user/types';
import type { AxiosResponse } from 'axios';
import { useStarFollow } from '@/views/User/hooks/useStarFollow';
import { useRouter } from 'vue-router';
import { xssPurify } from '@/utils';
import { useIsPrivate } from '@/views/User/hooks/useIsPrivate';
const { isPrivate } = useIsPrivate();
const router = useRouter();
// 状态仓库
const otherStore = otherAccountStore();
const emits = defineEmits<{(e: 'updateBanner', image: string): void; (e: 'updateInfo', data: any): void }>();
const profileLoading = ref(true);
// 用户信息
const userInfoData = ref({
name: '',
namespace: '',
avatarUrl: '',
description: '',
fansCount: 0,
followCount: 0,
tenant: '',
location: '',
email: '',
github: '',
blog: '',
username: '',
profile: {},
isFollow: false,
isSelf: false,
hasFollowed: false
});
const { isSelf, userInfo, namespace } = useUserInfo();
const { followCount, fanCount, hasFollowed, loading, hideFollowData, toggleStar, getAllCounts, checkFollowedUser } =
useStarFollow(
{
namespace,
username: userInfo.username
},
false
);
checkFollowedUser();
watch(() => [fanCount.value, followCount.value], () => {
userInfoData.value.fansCount = fanCount.value;
userInfoData.value.followCount = followCount.value;
userInfoData.value.hasFollowed = hasFollowed.value;
});
watch(
() => hasFollowed.value,
(val, oldVal) => {
getAllCounts();
}
);
watch(
() => otherStore.accountInfo.isFollow,
(val) => {
hasFollowed.value = val || false;
otherStore.saveFollowed(val);
}
);
const onToggleStar = () => {
if (loading.value) return false;
toggleStar(userInfo.username || '', namespace, !hasFollowed.value);
};
onMounted(async() => {
let userData = userInfo;
if (!isSelf) userData = {};
const username = namespace;
const res = await reqCatch(getUserProfile, { username });
if (!res.data) {
// 审核未通过跳404页
router.replace('/404');
}
const infoData = (res.data as AxiosResponse<UserProfile>).data || { avatar: '', profile: {}};
const $name = infoData.nickname || '';
userInfoData.value = {
name: $name ? xssPurify($name) : '',
namespace: infoData.username ? `@${infoData.username}` : `@${namespace}`,
avatarUrl: infoData.avatar || '',
description: infoData.profile.description || '',
fansCount: infoData.fans || 0,
followCount: infoData.concerns || 0,
tenant: infoData.profile.company || '',
location: infoData.profile.location || '',
email: !infoData.profile.email_private ? infoData.profile.show_email : '',
github: infoData.profile.github_account.replace(/(https?:\/\/)?github\.com\//, ''),
blog: infoData.profile.website || '',
username: infoData.username || namespace,
profile: infoData.profile,
isFollow: hasFollowed.value,
isSelf
};
profileLoading.value = false;
sessionStorage.setItem('curName', userInfoData.value.name);
emits('updateBanner', infoData.profile.bg_image);
emits('updateInfo', infoData);
otherStore.saveAccountInfo(userInfoData.value);
if (isSelf || !infoData?.profile?.setting_private) getAllCounts();
});
defineExpose({
getAllCounts
});
</script>
<style scoped lang="scss">
.user-info {
&-actions {
margin: 24px 0;
width: 100%;
}
&-button {
display: block;
width: 180px;
padding: 8px 16px;
line-height: 1 !important;
background-color: white;
border-color: var(--devui-line, #d7d8da);
color: var(--color-text);
:deep(.button-content) {
display: inline-flex;
align-items: center;
line-height: 1;
}
&:active,
&:hover {
color: var(--color-text) !important;
border-color: var(--devui-line, #d7d8da);
}
}
}
</style>