UserCard全局只放一个在顶层的LayoutContainer中,类似于单例组件的效果

This commit is contained in:
bob
2024-11-12 23:31:39 +08:00
parent a06d344b81
commit 962eeac3ef
10 changed files with 78 additions and 90 deletions

View File

@@ -7,10 +7,9 @@ import { ArrowRight } from '@element-plus/icons-vue'
import AvatarIcon from '@/components/common/AvatarIcon.vue'
import AddButton from '@/components/common/AddButton.vue'
import DeleteButton from '@/components/common/DeleteButton.vue'
import UserCard from '@/components/card/UserCard.vue'
import { combineId } from '@/js/utils/common'
import { userQueryService } from '@/api/user'
import { groupStore, userStore, messageStore } from '@/stores'
import { groupStore, userStore, messageStore, userCardStore } from '@/stores'
import SelectDialog from '../common/SelectDialog.vue'
import { groupAddMembersService, groupDelMembersService } from '@/api/group'
@@ -20,6 +19,7 @@ const emit = defineEmits(['close'])
const groupData = groupStore()
const userData = userStore()
const messageData = messageStore()
const userCardData = userCardStore()
const showDraw = ref(props.isShow)
const isShowSelectDialog = ref(false)
const method = ref('') //有加人减人两中method
@@ -83,8 +83,6 @@ const showMembersCount = computed(() => {
return totalCount
})
const isShowUserCard = ref(false)
const userInfo = ref()
const onShowUserCard = (account) => {
const sessionId = combineId(account, myAccount.value)
const loadingInstance = ElLoading.service(el_loading_options)
@@ -104,11 +102,11 @@ const onShowUserCard = (account) => {
}
})
}
userInfo.value = res.data.data
userCardData.setUserInfo(res.data.data)
})
.finally(() => {
loadingInstance.close()
isShowUserCard.value = true
userCardData.setIsShow(true)
})
}
@@ -272,11 +270,6 @@ const onConfirmSelect = (selected) => {
</div>
</div>
</el-drawer>
<UserCard
:isShow="isShowUserCard"
:userInfo="userInfo"
@close="isShowUserCard = false"
></UserCard>
<SelectDialog
v-model="isShowSelectDialog"
:options="selectDialogOptions"

View File

@@ -2,21 +2,19 @@
import { ref, computed, onMounted, onUnmounted, nextTick } from 'vue'
import { Close, Male, Female, Check, Edit } from '@element-plus/icons-vue'
import avatar from '@/assets/default_avatar.png'
import { userStore, messageStore } from '@/stores'
import { userStore, messageStore, userCardStore } from '@/stores'
import { combineId } from '@/js/utils/common'
import { MsgType } from '@/proto/msg'
import { msgChatCreateSessionService } from '@/api/message'
const props = defineProps(['isShow', 'userInfo'])
const emit = defineEmits(['close'])
const userData = userStore()
const messageData = messageStore()
const userCardData = userCardStore()
const userCardRef = ref()
const sessionId = computed(() => {
return combineId(userData.user.account, props.userInfo?.account)
return combineId(userData.user.account, userCardData.userInfo?.account)
})
const mark = computed(() => {
return messageData.sessionList[sessionId.value]?.mark || ''
@@ -35,7 +33,7 @@ const partitioEditing = ref(false)
const newPartitionId = ref(null)
const isSelf = computed(() => {
return userData.user.account === props.userInfo.account
return userData.user.account === userCardData.userInfo.account
})
const preventClose = (event) => {
@@ -43,7 +41,7 @@ const preventClose = (event) => {
}
const closeCardIfOutside = (event) => {
if (!props.isShow) return
if (!userCardData.isShow) return
if (
!event.target.closest('.user-card') &&
!event.target.closest('.avatar-session-item') &&
@@ -63,14 +61,14 @@ const handleEscEvent = (event) => {
}
const truncatedSignature = computed(() => {
const signature = props.userInfo.signature || 'TA还没有个性签名。'
const signature = userCardData.userInfo.signature || 'TA还没有个性签名。'
const lengthLimit = 50
return signature.length > lengthLimit ? signature.slice(0, lengthLimit) + '...' : signature
})
// 关闭的时候触发
const onClose = () => {
emit('close')
userCardData.setIsShow(false)
markEditing.value = false
}
@@ -88,7 +86,7 @@ const createSessionIfNotExist = async () => {
const res = await msgChatCreateSessionService({
sessionId: sessionId.value,
account: userData.user.account,
remoteId: props.userInfo.account,
remoteId: userCardData.userInfo.account,
sessionType: MsgType.CHAT
})
messageData.addSession(res.data.data)
@@ -144,17 +142,21 @@ onUnmounted(() => {
<template>
<div ref="userCardRef">
<transition name="fade">
<div class="user-card" v-if="props.isShow" @click.self="preventClose($event)">
<div class="user-card" v-if="userCardData.isShow" @click.self="preventClose($event)">
<div class="header">
<el-icon class="close-button" @click="onClose"><Close /></el-icon>
<div class="main">
<el-avatar class="avatar" :src="props.userInfo.avatarThumb || avatar" />
<el-avatar class="avatar" :src="userCardData.userInfo.avatarThumb || avatar" />
<div class="gender">
<el-icon v-if="props.userInfo.gender === 1" color="#508afe"><Male /></el-icon>
<el-icon v-if="props.userInfo.gender === 2" color="#ff5722"><Female /></el-icon>
<el-icon v-if="userCardData.userInfo.gender === 1" color="#508afe"><Male /></el-icon>
<el-icon v-if="userCardData.userInfo.gender === 2" color="#ff5722"
><Female
/></el-icon>
</div>
<div class="nickname">
{{ props.userInfo.nickName || '未设置昵称' }}({{ props.userInfo.account }})
{{ userCardData.userInfo.nickName || '未设置昵称' }}({{
userCardData.userInfo.account
}})
</div>
</div>
</div>
@@ -165,15 +167,15 @@ onUnmounted(() => {
</el-text>
<div class="info-item phone">
<span class="label">手机</span>
<span class="value">{{ props.userInfo.phoneNum || '-' }}</span>
<span class="value">{{ userCardData.userInfo.phoneNum || '-' }}</span>
</div>
<div class="info-item email">
<span class="label">邮箱</span>
<span class="value">{{ props.userInfo.email || '-' }}</span>
<span class="value">{{ userCardData.userInfo.email || '-' }}</span>
</div>
<div class="info-item nickname">
<span class="label">部门</span>
<span class="value">{{ props.userInfo.organize || '-' }}</span>
<span class="value">{{ userCardData.userInfo.organize || '-' }}</span>
</div>
<div v-if="!isSelf" class="info-item mark">
<span class="label">备注</span>

View File

@@ -10,3 +10,4 @@ export * from './group'
export * from './setting'
export * from './message'
export * from './search'
export * from './userCard'

26
src/stores/userCard.js Normal file
View File

@@ -0,0 +1,26 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'
import {} from '@/api/group'
// userCard用户详情卡片相关的缓存数据不持久化存储
export const userCardStore = defineStore('anyim-userCard', () => {
const isShow = ref(false)
const userInfo = ref({})
const setIsShow = (flag) => {
isShow.value = flag
}
const setUserInfo = (info) => {
userInfo.value = info
}
return {
isShow,
userInfo,
setIsShow,
setUserInfo
}
})

View File

@@ -3,9 +3,8 @@ import { ref, onMounted, computed } from 'vue'
import { Search } from '@element-plus/icons-vue'
import AddButton from '@/components/common/AddButton.vue'
import HashNoData from '@/components/common/HasNoData.vue'
import UserCard from '@/components/card/UserCard.vue'
import SelectDialog from '@/components/common/SelectDialog.vue'
import { groupStore, userStore, messageStore } from '@/stores'
import { groupStore, userStore, messageStore, userCardStore } from '@/stores'
import { combineId } from '@/js/utils/common'
import { userQueryService } from '@/api/user'
import { ElLoading, ElMessage } from 'element-plus'
@@ -19,6 +18,7 @@ const props = defineProps(['tab'])
const groupData = groupStore()
const userData = userStore()
const messageData = messageStore()
const userCardData = userCardStore()
const searchKey = ref('')
const isShowSelectDialog = ref(false)
const showData = ref({})
@@ -145,8 +145,6 @@ const onCreateGroup = () => {
isShowSelectDialog.value = true
}
const isShowUserCard = ref(false)
const userInfo = ref()
const onShowUserCard = (account) => {
const sessionId = combineId(account, userData.user.account)
const loadingInstance = ElLoading.service(el_loading_options)
@@ -166,11 +164,11 @@ const onShowUserCard = (account) => {
}
})
}
userInfo.value = res.data.data
userCardData.setUserInfo(res.data.data)
})
.finally(() => {
loadingInstance.close()
isShowUserCard.value = true
userCardData.setIsShow(true)
})
}
@@ -258,11 +256,6 @@ const onGroupCardClose = () => {
<div style="font-size: 16px; font-weight: bold; white-space: nowrap">创建群组</div>
</template>
</SelectDialog>
<UserCard
:isShow="isShowUserCard"
:userInfo="userInfo"
@close="isShowUserCard = false"
></UserCard>
<GroupCard
:isShow="isShowGroupCard"
:groupInfo="showGroupInfo"

View File

@@ -1,9 +1,8 @@
<script setup>
import { ref, onMounted, computed } from 'vue'
import { userQueryService } from '@/api/user'
import { messageStore } from '@/stores'
import { messageStore, userCardStore } from '@/stores'
import ContactListUserItem from '@/views/contactList/user/components/ContactListUserItem.vue'
import UserCard from '@/components/card/UserCard.vue'
import { ElLoading } from 'element-plus'
import { el_loading_options } from '@/const/commonConst'
import { Search } from '@element-plus/icons-vue'
@@ -11,6 +10,7 @@ import HashNoData from '@/components/common/HasNoData.vue'
import { MsgType } from '@/proto/msg'
const messageData = messageStore()
const userCardData = userCardStore()
const totalCount = computed(() => {
return Object.keys(allData.value).length
@@ -51,8 +51,6 @@ const allData = computed(() => {
}
})
const isShowUserCard = ref(false)
const userInfo = ref()
const onShowUserCard = ({ sessionId, account }) => {
const loadingInstance = ElLoading.service(el_loading_options)
userQueryService({ account: account })
@@ -69,11 +67,11 @@ const onShowUserCard = ({ sessionId, account }) => {
email: res.data.data.email
}
})
userInfo.value = messageData.sessionList[sessionId].objectInfo
userCardData.setUserInfo(messageData.sessionList[sessionId].objectInfo)
})
.finally(() => {
loadingInstance.close()
isShowUserCard.value = true
userCardData.setIsShow(true)
})
}
</script>
@@ -103,11 +101,6 @@ const onShowUserCard = ({ sessionId, account }) => {
<HashNoData v-else :size="100"></HashNoData>
</el-main>
</el-container>
<UserCard
:isShow="isShowUserCard"
:userInfo="userInfo"
@close="isShowUserCard = false"
></UserCard>
</template>
<style lang="scss" scoped>

View File

@@ -1,15 +1,15 @@
<script setup>
import { ref, onMounted, computed } from 'vue'
import { userQueryService } from '@/api/user'
import { messageStore } from '@/stores'
import { messageStore, userCardStore } from '@/stores'
import ContactListUserItem from '@/views/contactList/user/components/ContactListUserItem.vue'
import UserCard from '@/components/card/UserCard.vue'
import { ElLoading } from 'element-plus'
import { el_loading_options } from '@/const/commonConst'
import { Search } from '@element-plus/icons-vue'
import HashNoData from '@/components/common/HasNoData.vue'
const messageData = messageStore()
const userCardData = userCardStore()
const totalCount = computed(() => {
return Object.keys(markData.value).length
})
@@ -42,8 +42,6 @@ const markData = computed(() => {
return data
})
const isShowUserCard = ref(false)
const userInfo = ref()
const onShowUserCard = ({ sessionId, account }) => {
const loadingInstance = ElLoading.service(el_loading_options)
userQueryService({ account: account })
@@ -60,11 +58,11 @@ const onShowUserCard = ({ sessionId, account }) => {
email: res.data.data.email
}
})
userInfo.value = messageData.sessionList[sessionId].objectInfo
userCardData.setUserInfo(messageData.sessionList[sessionId].objectInfo)
})
.finally(() => {
loadingInstance.close()
isShowUserCard.value = true
userCardData.setIsShow(true)
})
}
</script>
@@ -95,11 +93,6 @@ const onShowUserCard = ({ sessionId, account }) => {
<HashNoData v-else :size="100"></HashNoData>
</el-main>
</el-container>
<UserCard
:isShow="isShowUserCard"
:userInfo="userInfo"
@close="isShowUserCard = false"
></UserCard>
</template>
<style lang="scss" scoped>

View File

@@ -6,7 +6,6 @@ import EditDialog from '@/components/common/EditDialog.vue'
import HashNoData from '@/components/common/HasNoData.vue'
import PartitionOprMenu from '@/views/contactList/user/components/PartitionOprMenu.vue'
import ContactListUserItem from '@/views/contactList/user/components/ContactListUserItem.vue'
import UserCard from '@/components/card/UserCard.vue'
import { userQueryService } from '@/api/user'
import {
msgCreatePartitionService,
@@ -15,7 +14,7 @@ import {
} from '@/api/message'
import { PARTITION_TYPE } from '@/const/userConst'
import { ElMessage, ElMessageBox } from 'element-plus'
import { messageStore, userStore } from '@/stores'
import { messageStore, userStore, userCardStore } from '@/stores'
import { ElLoading } from 'element-plus'
import { el_loading_options } from '@/const/commonConst'
import SelectDialog from '@/components/common/SelectDialog.vue'
@@ -23,6 +22,7 @@ import { combineId, highLightedText } from '@/js/utils/common'
const messageData = messageStore()
const userData = userStore()
const userCardData = userCardStore()
const partitionSearchKey = ref('')
const userSearchKey = ref('')
const isShowAddPartitionDialog = ref(false)
@@ -192,8 +192,6 @@ const onConfirmSelect = (selected) => {
isShowSelectDialog.value = false
}
const isShowUserCard = ref(false)
const userInfo = ref()
const onShowUserCard = ({ sessionId, account }) => {
const loadingInstance = ElLoading.service(el_loading_options)
userQueryService({ account: account })
@@ -210,11 +208,11 @@ const onShowUserCard = ({ sessionId, account }) => {
email: res.data.data.email
}
})
userInfo.value = messageData.sessionList[sessionId].objectInfo
userCardData.setUserInfo(messageData.sessionList[sessionId].objectInfo)
})
.finally(() => {
loadingInstance.close()
isShowUserCard.value = true
userCardData.setIsShow(true)
})
}
@@ -342,11 +340,6 @@ const onShowUserCardFromSelectDialog = (account) => {
</div>
</template>
</SelectDialog>
<UserCard
:isShow="isShowUserCard"
:userInfo="userInfo"
@close="isShowUserCard = false"
></UserCard>
</template>
<style lang="scss" scoped>

View File

@@ -24,6 +24,7 @@ import {
CREATE_WS_DELAY,
SYNC_STATUS_INTERVAL
} from '@/const/userConst'
import UserCard from '@/components/card/UserCard.vue'
const myCardDialog = ref()
const myAvatar = ref()
@@ -221,6 +222,7 @@ const onExit = async () => {
<router-view></router-view>
</el-main>
<MyCard ref="myCardDialog"></MyCard>
<UserCard></UserCard>
</el-container>
</template>

View File

@@ -23,9 +23,8 @@ import SessionItem from '@/views/message/components/SessionItem.vue'
import InputTool from '@/views/message/components/InputTool.vue'
import InputEditor from '@/views/message/components/InputEditor.vue'
import MessageItem from '@/views/message/components/MessageItem.vue'
import UserCard from '@/components/card/UserCard.vue'
import GroupCard from '@/components/card/GroupCard.vue'
import { userStore, settingStore, messageStore } from '@/stores'
import { userStore, settingStore, messageStore, userCardStore } from '@/stores'
import backgroupImage from '@/assets/messagebx_bg.webp'
import { msgChatPullMsgService, msgChatCreateSessionService } from '@/api/message'
import { MsgType } from '@/proto/msg'
@@ -43,6 +42,7 @@ import EditDialog from '@/components/common/EditDialog.vue'
const userData = userStore()
const settingData = settingStore()
const messageData = messageStore()
const userCardData = userCardStore()
const selectedSessionId = ref('') //当前被选中的session
const sessionListRef = ref()
@@ -456,9 +456,6 @@ const onClickMsgContainer = () => {
handleRead()
}
const isShowUserCard = ref(false)
const userInfoForShowCard = ref()
const isShowGroupCard = ref(false)
const groupInfoForShowCard = ref()
@@ -468,9 +465,9 @@ const onShowUserCard = async ({ sessionId, account }) => {
userData
.updateUser()
.then(() => {
userInfoForShowCard.value = userData.user
isShowGroupCard.value = false
isShowUserCard.value = true
userCardData.setUserInfo(userData.user)
userCardData.setIsShow(true)
})
.finally(() => {
//防止请求异常导致loading关不掉
@@ -491,9 +488,9 @@ const onShowUserCard = async ({ sessionId, account }) => {
email: res.data.data.email
}
})
userInfoForShowCard.value = messageData.sessionList[sessionId].objectInfo
isShowGroupCard.value = false
isShowUserCard.value = true
userCardData.setIsShow(true)
userCardData.setUserInfo(messageData.sessionList[sessionId].objectInfo)
})
.finally(() => {
//防止请求异常导致loading关不掉
@@ -528,15 +525,15 @@ const onUpdateMarkConfirm = (inputValue) => {
// TODO
const onShowGroupCard = () => {
isShowUserCard.value = false
userCardData.setIsShow(false)
isShowGroupCard.value = true
groupInfoForShowCard.value = {}
}
const onShowContactCard = (contactInfo) => {
userInfoForShowCard.value = contactInfo
userCardData.setUserInfo(contactInfo)
isShowGroupCard.value = false
isShowUserCard.value = true
userCardData.setIsShow(true)
}
const onOpenSession = async ({ msgType, objectInfo }) => {
@@ -794,11 +791,6 @@ const onNoneSelected = () => {
</el-container>
</el-main>
</el-container>
<UserCard
:isShow="isShowUserCard"
:userInfo="userInfoForShowCard"
@close="isShowUserCard = false"
></UserCard>
<GroupCard
:isShow="isShowGroupCard"
:groupInfo="groupInfoForShowCard"