搜索结果列表页面开发
This commit is contained in:
178
src/views/User/components/UserInfo.vue
Normal file
178
src/views/User/components/UserInfo.vue
Normal 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>
|
||||
Reference in New Issue
Block a user