Files
workspace/code/link56/link56-frontend/src/components/CompanyUserProfileDialog.vue
T
2026-04-24 17:28:11 +08:00

277 lines
5.6 KiB
Vue

<script lang="ts" setup>
import type { CompanyUserProfile } from '@/types/company/user'
import { ElMessage } from 'element-plus'
import { ref } from 'vue'
import { getCompanyUserProfileApi } from '@/request/api/company/user'
import { createFriendApi } from '@/request/api/im'
import { useUserStore } from '@/store/user'
import SafeImage from './SafeImage.vue'
import SvgIcon from './SvgIcon.vue'
const props = defineProps({
userId: {
type: [Number, null],
required: true,
},
})
const emits = defineEmits<{
(e: 'startChat'): void
}>()
const userStore = useUserStore()
const loading = ref(false)
const profile = ref<CompanyUserProfile>({
company: {
id: 0,
name: '',
logo: '',
profile: '',
areas: [],
industries: [],
},
user: {
id: 0,
name: '',
position: '',
avatar: '',
email: '',
phone: '',
isOnline: false,
},
})
function onOpened() {
loading.value = true
if (!props.userId) {
return
}
getCompanyUserProfileApi(props.userId).then((res) => {
if (res.isSuccess) {
profile.value = res.data
loading.value = false
}
else {
ElMessage.error(res.message || '加载用户信息失败,请稍后再试')
}
}).catch((err) => {
console.log(err)
ElMessage.error('加载用户信息失败,请稍后再试')
})
}
function onClosed() {
loading.value = true
profile.value = {
company: {
id: 0,
name: '',
logo: '',
profile: '',
areas: [],
industries: [],
},
user: {
id: 0,
name: '',
position: '',
avatar: '',
email: '',
phone: '',
isOnline: false,
},
}
}
function handleChat() {
if (props.userId === null) {
return
}
if (props.userId === userStore.user.id) {
ElMessage.warning('无法与自己发起聊天')
return
}
// 创建好友关系
createFriendApi({
friendId: props.userId,
}).then((res) => {
if (res.isSuccess) {
emits('startChat')
}
else {
ElMessage.error(res.message || '发起聊天失败,请稍后再试')
}
}).catch((err) => {
console.log(err)
ElMessage.error('发起聊天失败,请稍后再试')
})
}
</script>
<template>
<el-dialog
width="700"
class="dlalog-wrapper"
@opened="onOpened"
@closed="onClosed"
>
<div v-if="loading" class="loading-wrapper">
<SvgIcon icon="svg-spinners:ring-resize" :size="20" />
</div>
<div v-else>
<div class="user">
<el-badge
is-dot
:color="profile.user.isOnline ? '#24e68a' : '#bfbfbf'"
:badge-style="{
width: '12px',
height: '12px',
}"
:offset="[-4, 42]"
>
<SafeImage
class="user-logo"
:size="52"
round
:url="profile.user.avatar"
:text="profile.user.name"
:textline="1"
:chars-per-line="1"
style="font-size: 24px; line-height: 28px;"
/>
</el-badge>
<div class="user-info">
<div class="user-line">
<span>{{ profile.user.name }}</span>
<span v-if="profile.user.position" class="position"> · {{ profile.user.position }}</span>
</div>
<div class="user-contract">
<div v-if="profile.user.phone" class="user-contract__item">
<SvgIcon icon="material-symbols:phone-android-outline" />
<span>{{ profile.user.phone }}</span>
</div>
<div v-if="profile.user.email" class="user-contract__item">
<SvgIcon icon="material-symbols:mail-outline" />
<span>{{ profile.user.email }}</span>
</div>
</div>
<div class="user-action">
<el-button size="small" type="primary" @click="handleChat">
发起聊天
</el-button>
</div>
</div>
</div>
<el-divider />
<div class="company">
<div class="company-name">
{{ profile.company.name }}
</div>
<div class="company-meta">
<span>{{ profile.company.industries.join(" / ") }}</span>
<span v-if="profile.company.areas.length > 0"> · {{ profile.company.areas[0] }} </span>
</div>
<div v-if="profile.company.profile" class="company-profile">
{{ profile.company.profile }}
</div>
</div>
</div>
</el-dialog>
</template>
<style lang="scss" scoped>
.dlalog-wrapper {
.el-divider {
margin: 16px 0px;
}
}
.loading-wrapper,
.empty-wrapper {
display: flex;
align-items: center;
justify-content: center;
height: 100px;
}
.empty-wrapper {
flex-direction: column;
.empty-tip {
margin-top: 8px;
}
}
.user {
display: flex;
.user-logo {
}
.user-info {
margin-left: 16px;
.user-line {
display: flex;
align-items: center;
font-size: 16px;
font-weight: 600;
color: #262626;
.position {
font-weight: 400;
color: #595959;
font-size: 14px;
}
}
.user-contract {
margin-top: 6px;
font-size: 13px;
color: #595959;
gap: 16px;
.user-contract__item {
display: flex;
align-items: center;
gap: 4px;
margin-top: 4px;
}
}
.user-action {
margin-top: 6px;
}
}
}
.company {
.company-name {
font-size: 14px;
font-weight: 500;
color: #262626;
}
.company-meta {
margin-top: 4px;
font-size: 12px;
color: #8c8c8c;
}
.company-profile {
margin-top: 8px;
font-size: 13px;
color: #595959;
line-height: 1.6;
}
}
</style>