更新头像模块,新增群聊类型标签显示功能,优化标签样式计算逻辑;调整视频消息组件,注释掉未使用的图像处理函数;更新对话存储,添加头像和群类型字段;修复消息视图中的头像显示逻辑。
This commit is contained in:
parent
ae23e0a1d1
commit
73063d1faf
@ -1,8 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<div class="relative">
|
||||||
<div class="avatar-module" :style="[customStyle, { background: avatar ? '#fff' : '' }]">
|
<div class="avatar-module" :style="[customStyle, { background: avatar ? '#fff' : '' }]">
|
||||||
<img :src="avatar" v-if="avatar" />
|
<img :src="avatar" v-if="avatar" />
|
||||||
<span v-else :style="customTextStyle">{{ text_avatar }}</span>
|
<span v-else :style="customTextStyle">{{ text_avatar }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="[2,3,4].includes(groupType)&&showGroupType"
|
||||||
|
class="absolute border-2px border-solid rounded-3px bg-#fff flex justify-center items-center leading-none"
|
||||||
|
:style="[
|
||||||
|
groupLabelStyle,
|
||||||
|
`color:${labelColor.find(x=>x.group_type===groupType)?.color};border-color:${labelColor.find(x=>x.group_type===groupType)?.color}`
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
{{ labelColor.find(x=>x.group_type===groupType)?.label }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
//群聊默认头像
|
//群聊默认头像
|
||||||
@ -11,13 +23,22 @@ import groupDepartment from '@/assets/image/groupDepartment.png'
|
|||||||
import groupProject from '@/assets/image/groupProject.png'
|
import groupProject from '@/assets/image/groupProject.png'
|
||||||
import groupCompany from '@/assets/image/groupCompany.png'
|
import groupCompany from '@/assets/image/groupCompany.png'
|
||||||
import { computed, defineProps } from 'vue'
|
import { computed, defineProps } from 'vue'
|
||||||
|
//群类型:1=普通群;2=部门群;3=项目群;4=总群/公司群
|
||||||
|
const labelColor=[
|
||||||
|
{group_type:2,color:'#377EC6',label:'部门'},
|
||||||
|
{group_type:3,color:'#C1691C',label:'项目'},
|
||||||
|
{group_type:4,color:'#7A58DE',label:'公司'},
|
||||||
|
]
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
mode: {
|
mode: {
|
||||||
//模式:1=人;2=群
|
//模式:1=人;2=群
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0,
|
default: 0,
|
||||||
},
|
},
|
||||||
|
showGroupType:{
|
||||||
|
type:Boolean,
|
||||||
|
default:false
|
||||||
|
},
|
||||||
avatar: {
|
avatar: {
|
||||||
//头像
|
//头像
|
||||||
type: String,
|
type: String,
|
||||||
@ -75,6 +96,34 @@ const text_avatar = computed(() => {
|
|||||||
? props?.userName.slice(-2)
|
? props?.userName.slice(-2)
|
||||||
: props?.userName
|
: props?.userName
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 计算群标签的动态样式
|
||||||
|
const groupLabelStyle = computed(() => {
|
||||||
|
// 获取头像的宽高
|
||||||
|
const avatarWidth = parseInt(props.customStyle.width) || 42
|
||||||
|
const avatarHeight = parseInt(props.customStyle.height) || 42
|
||||||
|
|
||||||
|
// 计算标签的尺寸比例(基于原始尺寸:头像42px,标签宽32px高18px,文字10px)
|
||||||
|
const widthRatio = avatarWidth / 42
|
||||||
|
const heightRatio = avatarHeight / 42
|
||||||
|
|
||||||
|
// 计算标签的尺寸
|
||||||
|
const labelWidth = Math.round(32 * widthRatio)
|
||||||
|
const labelHeight = Math.round(18 * heightRatio)
|
||||||
|
const fontSize = Math.round(10 * widthRatio)
|
||||||
|
|
||||||
|
// 计算标签的位置(基于原始位置:top-28px)
|
||||||
|
const topPosition = Math.round(28 * heightRatio)
|
||||||
|
|
||||||
|
return {
|
||||||
|
width: `${labelWidth}px`,
|
||||||
|
height: `${labelHeight}px`,
|
||||||
|
fontSize: `${fontSize}px`,
|
||||||
|
top: `${topPosition}px`,
|
||||||
|
left: '50%',
|
||||||
|
transform: 'translateX(-50%)'
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.avatar-module {
|
.avatar-module {
|
||||||
|
@ -19,31 +19,31 @@ const props = defineProps<{
|
|||||||
maxWidth?: Boolean
|
maxWidth?: Boolean
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const img = (src: string, width = 200) => {
|
// const img = (src: string, width = 200) => {
|
||||||
const info: any = getImageInfo(src)
|
// const info: any = getImageInfo(src)
|
||||||
|
|
||||||
if (info.width == 0 || info.height == 0) {
|
// if (info.width == 0 || info.height == 0) {
|
||||||
return {}
|
// return {}
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (info.height > 300) {
|
// if (info.height > 300) {
|
||||||
return {
|
// return {
|
||||||
height: '300px'
|
// height: '300px'
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (info.width < width) {
|
// if (info.width < width) {
|
||||||
return {
|
// return {
|
||||||
width: `${info.width}px`,
|
// width: `${info.width}px`,
|
||||||
height: `${info.height}px`
|
// height: `${info.height}px`
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
return {
|
// return {
|
||||||
width: width + 'px',
|
// width: width + 'px',
|
||||||
height: info.height / (info.width / width) + 'px'
|
// height: info.height / (info.width / width) + 'px'
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
const open = ref(false)
|
const open = ref(false)
|
||||||
const isPaused = ref(false)
|
const isPaused = ref(false)
|
||||||
@ -64,18 +64,18 @@ const updatePauseStatus = () => {
|
|||||||
// 初始化时检查状态
|
// 初始化时检查状态
|
||||||
updatePauseStatus()
|
updatePauseStatus()
|
||||||
|
|
||||||
// 监听关键道具变化
|
// // 监听关键道具变化
|
||||||
watch(() => props.extra.percentage, (newVal: number | undefined) => {
|
// watch(() => props.extra.percentage, (newVal: number | undefined) => {
|
||||||
// 确保进度更新时 UI 也实时更新
|
// // 确保进度更新时 UI 也实时更新
|
||||||
// 检测上传失败状态 (-1表示上传失败)
|
// // 检测上传失败状态 (-1表示上传失败)
|
||||||
if (newVal === -1) {
|
// if (newVal === -1) {
|
||||||
uploadFailed.value = true
|
// uploadFailed.value = true
|
||||||
// 显示上传失败提示
|
// // 显示上传失败提示
|
||||||
message.error('视频发送失败,请点击红色感叹号重试')
|
// message.error('视频发送失败,请点击红色感叹号重试')
|
||||||
} else if (newVal !== undefined && newVal > 0) {
|
// } else if (newVal !== undefined && newVal > 0) {
|
||||||
uploadFailed.value = false
|
// uploadFailed.value = false
|
||||||
}
|
// }
|
||||||
}, { immediate: true })
|
// }, { immediate: true })
|
||||||
|
|
||||||
async function onPlay() {
|
async function onPlay() {
|
||||||
// 如果视频正在上传,不执行播放操作
|
// 如果视频正在上传,不执行播放操作
|
||||||
@ -116,17 +116,17 @@ function resumeUpload(e) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 重新上传视频
|
// 重新上传视频
|
||||||
function retryUpload(e) {
|
// function retryUpload(e) {
|
||||||
e.stopPropagation()
|
// e.stopPropagation()
|
||||||
if (props.extra.upload_id) {
|
// if (props.extra.upload_id) {
|
||||||
// 重置失败状态
|
// // 重置失败状态
|
||||||
uploadFailed.value = false
|
// uploadFailed.value = false
|
||||||
|
|
||||||
// 恢复上传
|
// // 恢复上传
|
||||||
uploadsStore.resumeUpload(props.extra.upload_id)
|
// uploadsStore.resumeUpload(props.extra.upload_id)
|
||||||
message.success('正在重新上传视频...')
|
// message.success('正在重新上传视频...')
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<section
|
<section
|
||||||
|
@ -19,9 +19,11 @@ export const useDialogueStore = defineStore('dialogue', {
|
|||||||
|
|
||||||
// 对话节点
|
// 对话节点
|
||||||
talk: {
|
talk: {
|
||||||
|
avatar:'',
|
||||||
username: '',
|
username: '',
|
||||||
talk_type: 0, // 对话来源[1:私聊;2:群聊]
|
talk_type: 0, // 对话来源[1:私聊;2:群聊]
|
||||||
receiver_id: 0
|
receiver_id: 0,
|
||||||
|
group_type:0
|
||||||
},
|
},
|
||||||
|
|
||||||
// 好友是否正在输入文字
|
// 好友是否正在输入文字
|
||||||
@ -73,11 +75,15 @@ export const useDialogueStore = defineStore('dialogue', {
|
|||||||
|
|
||||||
// 更新对话信息
|
// 更新对话信息
|
||||||
setDialogue(data = {}) {
|
setDialogue(data = {}) {
|
||||||
|
|
||||||
|
console.log('data',data)
|
||||||
this.online = data.is_online == 1
|
this.online = data.is_online == 1
|
||||||
this.talk = {
|
this.talk = {
|
||||||
username: data.remark || data.name,
|
username: data.remark || data.name,
|
||||||
talk_type: data.talk_type,
|
talk_type: data.talk_type,
|
||||||
receiver_id: data.receiver_id
|
receiver_id: data.receiver_id,
|
||||||
|
avatar:data.avatar,
|
||||||
|
group_type:data.group_type
|
||||||
}
|
}
|
||||||
|
|
||||||
this.index_name = `${data.talk_type}_${data.receiver_id}`
|
this.index_name = `${data.talk_type}_${data.receiver_id}`
|
||||||
|
@ -18,7 +18,7 @@ export function isLoggedIn() {
|
|||||||
*/
|
*/
|
||||||
export function getAccessToken() {
|
export function getAccessToken() {
|
||||||
// return storage.get(AccessToken) || ''
|
// return storage.get(AccessToken) || ''
|
||||||
return JSON.parse(localStorage.getItem('token'))||'46d71a72d8d845ad7ed23eba9bdde260e635407190c2ce1bf7fd22088e41682ea07773ec65cae8946d2003f264d55961f96e0fc5da10eb96d3a348c1664e9644ce2108c311309f398ae8ea1b8200bfd490e5cb6e8c52c9e5d493cbabb163368f8351420451a631dbfa749829ee4cda49b77b5ed2d3dced5d0f2b7dd9ee76ba5465c84a17c23af040cd92b6b2a4ea48befbb5c729dcdad0a9c9668befe84074cc24f78899c1d947f8e7f94c7eda5325b8ed698df729e76febb98549ef3482ae942fb4f4a1c92d21836fa784728f0c5483aab2760a991b6b36e6b10c84f840a6433a6ecc31dee36e8f1c6158818bc89d22851b5e2f6cbf01ab4b3da6e3d06b57c8f750e106226a5a4b9d7fc1d381a54cb92375c09ba1fa8e5fde0392d919c2f2cbcc7e4e2eca8d9860749af00374b249f7d04e2bc43a1fa4e7d7384dde0212f0a5'
|
return JSON.parse(localStorage.getItem('token'))||'46d71a72d8d845ad7ed23eba9bdde260e635407190c2ce1bf7fd22088e41682ea07773ec65cae8946d2003f264d55961f96e0fc5da10eb96d3a348c1664e9644ce2108c311309f398ae8ea1b8200bfd490e5cb6e8c52c9e5d493cbabb163368f8351420451a631dbfa749829ee4cda49b77b5ed2d3dced5d0f2b7dd9ee76ba5465c84a17c23af040cd92b6b2a4ea48befbb5c729dcdad0a9c9668befe84074cc24f78899c1d947f8e7f94c7eda5325b8ed698df729e76febb98549ef3482ae942fb4f4a1c92d21836fa784728f0c5483aab2760a991b6b36e6b10c84f840a6433a6ecc31dee36e8f1c6158818bc89d22939bb2aea0008a0e4b687680750f2fcff1dd71da701d0a961f65313915a1712826f5c8d3d1fdf999ba3f94912e4744eea50d51ecd72470f47b87cc42ffad74ec3b3c7ff13a011bfbe3a816adfc923db8'
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -12,6 +12,7 @@ import UploadsModal from '@/components/base/UploadsModal.vue'
|
|||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
const dialogueStore = useDialogueStore()
|
const dialogueStore = useDialogueStore()
|
||||||
const uploadsStore = useUploadsStore()
|
const uploadsStore = useUploadsStore()
|
||||||
|
console.log('dialogueStore',dialogueStore);
|
||||||
|
|
||||||
const members = computed(() => dialogueStore.members)
|
const members = computed(() => dialogueStore.members)
|
||||||
const isShowEditor = computed(() => dialogueStore.isShowEditor)
|
const isShowEditor = computed(() => dialogueStore.isShowEditor)
|
||||||
@ -25,7 +26,8 @@ const talkParams = reactive({
|
|||||||
username: computed(() => dialogueStore.talk.username),
|
username: computed(() => dialogueStore.talk.username),
|
||||||
online: computed(() => dialogueStore.online),
|
online: computed(() => dialogueStore.online),
|
||||||
keyboard: computed(() => dialogueStore.keyboard),
|
keyboard: computed(() => dialogueStore.keyboard),
|
||||||
num: computed(() => dialogueStore.members.length)
|
num: computed(() => dialogueStore.members.length),
|
||||||
|
avatar:computed(() => dialogueStore.talk.avatar)
|
||||||
})
|
})
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
@ -59,12 +61,14 @@ const onPanelHeaderEvent = (eventType: string) => {
|
|||||||
<section id="drawer-container" class="el-container is-vertical">
|
<section id="drawer-container" class="el-container is-vertical">
|
||||||
<!-- 头部区域 -->
|
<!-- 头部区域 -->
|
||||||
<header class="el-header bdr-b">
|
<header class="el-header bdr-b">
|
||||||
|
|
||||||
<PanelHeader
|
<PanelHeader
|
||||||
:type="talkParams.type"
|
:type="talkParams.type"
|
||||||
:username="talkParams.username"
|
:username="talkParams.username"
|
||||||
:online="talkParams.online"
|
:online="talkParams.online"
|
||||||
:keyboard="talkParams.keyboard"
|
:keyboard="talkParams.keyboard"
|
||||||
:num="talkParams.num"
|
:num="talkParams.num"
|
||||||
|
:avatar="talkParams.avatar"
|
||||||
@evnet="onPanelHeaderEvent"
|
@evnet="onPanelHeaderEvent"
|
||||||
/>
|
/>
|
||||||
</header>
|
</header>
|
||||||
|
@ -239,9 +239,6 @@ const items = computed((): ISession[] => {
|
|||||||
return keyword.toLowerCase().indexOf(searchKeyword.value.toLowerCase()) != -1
|
return keyword.toLowerCase().indexOf(searchKeyword.value.toLowerCase()) != -1
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
setTimeout(() => {
|
|
||||||
console.log('items.value', items.value)
|
|
||||||
}, 1000)
|
|
||||||
watch(
|
watch(
|
||||||
() => talkStore,
|
() => talkStore,
|
||||||
(newValue, oldValue) => {
|
(newValue, oldValue) => {
|
||||||
@ -273,6 +270,8 @@ const indexName = computed(() => dialogueStore.index_name)
|
|||||||
|
|
||||||
// 切换会话
|
// 切换会话
|
||||||
const onTabTalk = (item: ISession, follow = false) => {
|
const onTabTalk = (item: ISession, follow = false) => {
|
||||||
|
console.log('onTabTalk');
|
||||||
|
|
||||||
if (item.index_name === indexName.value) return
|
if (item.index_name === indexName.value) return
|
||||||
|
|
||||||
searchKeyword.value = ''
|
searchKeyword.value = ''
|
||||||
|
@ -22,11 +22,11 @@ const labelColor=[
|
|||||||
<div class="talk pointer" :class="{ actived: active }" @click="emit('tab-talk', data)">
|
<div class="talk pointer" :class="{ actived: active }" @click="emit('tab-talk', data)">
|
||||||
<div class="avatar-box relative">
|
<div class="avatar-box relative">
|
||||||
|
|
||||||
<avatarModule :mode="data?.group_type === 0 ? 1 : 2"
|
<avatarModule showGroupType :mode="data?.group_type === 0 ? 1 : 2"
|
||||||
:avatar="data?.avatar"
|
:avatar="data?.avatar"
|
||||||
:groupType="data?.group_type"
|
:groupType="data?.group_type"
|
||||||
:userName="data?.name" :customStyle="{width:'42px',height:'42px'}"></avatarModule>
|
:userName="data?.name" :customStyle="{width:'42px',height:'42px'}"></avatarModule>
|
||||||
<div v-if="[2,3,4].includes(data.group_type)" class="absolute w-32px h-18px border-2px border-solid rounded-3px top-28px bg-#fff text-10px flex justify-center items-center leading-none" :style="`color:${labelColor.find(x=>x.group_type===data.group_type)?.color};border-color:${labelColor.find(x=>x.group_type===data.group_type)?.color}`">{{ labelColor.find(x=>x.group_type===data.group_type)?.label }}</div>
|
<!-- <div v-if="[2,3,4].includes(data.group_type)" class="absolute w-32px h-18px border-2px border-solid rounded-3px top-28px bg-#fff text-10px flex justify-center items-center leading-none" :style="`color:${labelColor.find(x=>x.group_type===data.group_type)?.color};border-color:${labelColor.find(x=>x.group_type===data.group_type)?.color}`">{{ labelColor.find(x=>x.group_type===data.group_type)?.label }}</div> -->
|
||||||
<!-- <im-avatar :src="avatar" :size="34" :username="data.name" /> -->
|
<!-- <im-avatar :src="avatar" :size="34" :username="data.name" /> -->
|
||||||
<!-- <div class="top-mask" @click.stop="emit('top-talk', data)">
|
<!-- <div class="top-mask" @click.stop="emit('top-talk', data)">
|
||||||
<n-icon :component="data.is_top == 1 ? ArrowDown : ArrowUp" />
|
<n-icon :component="data.is_top == 1 ? ArrowDown : ArrowUp" />
|
||||||
|
@ -19,6 +19,10 @@ defineProps({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
avatar:{
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
num: {
|
num: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
@ -41,14 +45,20 @@ const onSetMenu = () => {
|
|||||||
:size="22"
|
:size="22"
|
||||||
/>
|
/>
|
||||||
</div> -->
|
</div> -->
|
||||||
|
<div class="flex items-center">
|
||||||
<div class="module left-module">
|
<avatarModule class="mr-10px" :mode="dialogueStore.talk.talk_type"
|
||||||
|
:avatar="avatar"
|
||||||
|
:groupType="dialogueStore.talk?.group_type"
|
||||||
|
:userName="username" :customStyle="{width:'42px',height:'42px'}"></avatarModule>
|
||||||
|
<div class="module left-module">
|
||||||
<!-- <span class="tag" :class="{ red: type == 1 }">
|
<!-- <span class="tag" :class="{ red: type == 1 }">
|
||||||
{{ type == 1 ? '好友' : '群聊' }}
|
{{ type == 1 ? '好友' : '群聊' }}
|
||||||
</span> -->
|
</span> -->
|
||||||
<span class="nickname">{{ username }}</span>
|
<span class="nickname">{{ username }}</span>
|
||||||
<span class="num" v-show="type == 2 && num">({{ num }})</span>
|
<span class="num" v-show="type == 2 && num">({{ num }})</span>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="module center-module" v-if="type == 1">
|
<div class="module center-module" v-if="type == 1">
|
||||||
<p class="online">
|
<p class="online">
|
||||||
@ -125,6 +135,7 @@ const onSetMenu = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.nickname {
|
.nickname {
|
||||||
|
font-size: 14px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
Loading…
Reference in New Issue
Block a user