179 lines
4.9 KiB
Vue
179 lines
4.9 KiB
Vue
<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>
|