Compare commits
33 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
1a85e9d13e | ||
|
bab907a1e2 | ||
|
45e4415cec | ||
|
57e4ba69d9 | ||
|
88bbf16699 | ||
|
d46ced7614 | ||
|
044617580c | ||
|
54a46e2fb4 | ||
|
28938aba66 | ||
|
8e645226b8 | ||
|
4b5c160e94 | ||
|
ebd567a757 | ||
18871db6b6 | |||
|
1ae317dbb3 | ||
|
e4354d42cd | ||
|
8bba2d64af | ||
|
d4e52152ef | ||
|
bdf07155c8 | ||
|
b905db0cfa | ||
|
3b6d998ce1 | ||
|
5340461a7e | ||
|
45eec2ff22 | ||
|
9c34066128 | ||
|
628894a254 | ||
92fce58429 | |||
|
2e998a1174 | ||
|
60a2fb996b | ||
b282562cdd | |||
d0abf7d8ab | |||
|
409af72039 | ||
|
799599bd83 | ||
ec18d85546 | |||
|
a97f293a6c |
@ -26,6 +26,7 @@
|
||||
"@vueuse/core": "^10.7.0",
|
||||
"ant-design-vue": "^4.2.6",
|
||||
"axios": "^1.6.2",
|
||||
"dayjs": "^1.11.13",
|
||||
"highlight.js": "^11.5.0",
|
||||
"js-audio-recorder": "^1.0.7",
|
||||
"lodash-es": "^4.17.21",
|
||||
|
@ -44,6 +44,9 @@ importers:
|
||||
axios:
|
||||
specifier: ^1.6.2
|
||||
version: 1.9.0
|
||||
dayjs:
|
||||
specifier: ^1.11.13
|
||||
version: 1.11.13
|
||||
highlight.js:
|
||||
specifier: ^11.5.0
|
||||
version: 11.11.1
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -686,18 +686,13 @@ const fileTypeAvatar = (fileType) => {
|
||||
|
||||
const previewPDF = (item) => {
|
||||
console.log(item)
|
||||
// if (typeof plus !== 'undefined') {
|
||||
// downloadAndOpenFile(item)
|
||||
// } else {
|
||||
// document.addEventListener('plusready', () => {
|
||||
// downloadAndOpenFile(item)
|
||||
// })
|
||||
// }
|
||||
window.open(
|
||||
`${import.meta.env.VITE_PAGE_URL}/office?url=${item.extra.path}`,
|
||||
'_blank',
|
||||
'width=1200,height=900,left=200,top=200,toolbar=no,menubar=no,scrollbars=yes,resizable=yes,location=no,status=no'
|
||||
)
|
||||
if (typeof plus !== 'undefined') {
|
||||
downloadAndOpenFile(item)
|
||||
} else {
|
||||
document.addEventListener('plusready', () => {
|
||||
downloadAndOpenFile(item)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const downloadAndOpenFile = (item) => {
|
||||
@ -931,6 +926,7 @@ body:deep(.round-3) {
|
||||
}
|
||||
.condition-each-resultList {
|
||||
.condition-each-resultList-each {
|
||||
border-bottom: 1px solid #f8f8f8;
|
||||
.condition-each-result-main {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
@ -946,16 +942,9 @@ body:deep(.round-3) {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
padding: 14px 20px;
|
||||
padding: 14px 0;
|
||||
// background-color: #f3f3f3;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid #f8f8f8;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(70, 41, 157, 0.1)
|
||||
}
|
||||
|
||||
.attachment-avatar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
@ -1137,10 +1126,6 @@ body:deep(.round-3) {
|
||||
.image-container {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
border: 1px solid #46299d;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.n-image) {
|
||||
|
@ -69,43 +69,7 @@
|
||||
class="text-[12px] font-regular"
|
||||
:text="resultDetail"
|
||||
:searchText="props.searchText"
|
||||
v-if="props.searchItem?.msg_type !== 3 && props.searchItem?.msg_type !== 6"
|
||||
/>
|
||||
<div class="message-component-wrapper" v-if="props.searchItem?.msg_type === 3" @click.stop>
|
||||
<component
|
||||
:is="MessageComponents[props.searchItem?.msg_type] || 'unknown-message'"
|
||||
:extra="resultDetail"
|
||||
:data="props?.searchItem"
|
||||
/>
|
||||
</div>
|
||||
<div class="file-message-wrapper" v-if="props.searchItem?.msg_type === 6" @click.stop>
|
||||
<div class="condition-each-result-attachments" @click="previewPDF(resultDetail.path)">
|
||||
<div class="attachment-avatar">
|
||||
<img :src="resultDetail?.file_avatar" />
|
||||
</div>
|
||||
<div class="attachment-info">
|
||||
<div class="attachment-info-title">
|
||||
<span class="text-[14px] font-regular">
|
||||
{{ resultDetail?.name }}
|
||||
</span>
|
||||
<span
|
||||
class="text-[14px] font-regular"
|
||||
style="color: #999999; flex-shrink: 0; margin: 0 0 0 20px;"
|
||||
>
|
||||
{{ resultDetail?.dateTime }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="attachment-sub-info">
|
||||
<span class="text-[12px] font-regular">
|
||||
{{ resultDetail?.typeText }}
|
||||
</span>
|
||||
<span class="text-[12px] font-regular" style="flex-shrink: 0; margin: 0 0 0 20px;">
|
||||
{{ resultDetail?.fileSize }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="searchRecordDetail-fastLocal" v-if="searchRecordDetail">
|
||||
<span>定位到聊天位置</span>
|
||||
</div>
|
||||
@ -121,7 +85,7 @@ import avatarModule from '@/components/avatar-module/index.vue'
|
||||
import { ref, watch, computed, onMounted, onUnmounted, reactive, defineProps } from 'vue'
|
||||
import HighlightText from './highLightText.vue'
|
||||
import { beautifyTime } from '@/utils/datetime'
|
||||
import { ChatMsgTypeMapping, MessageComponents } from '@/constant/message'
|
||||
import { ChatMsgTypeMapping } from '@/constant/message'
|
||||
const props = defineProps({
|
||||
searchItem: Object | Number,
|
||||
searchResultKey: {
|
||||
@ -291,8 +255,6 @@ const resultDetail = computed(() => {
|
||||
result_detail =
|
||||
props.searchItem?.msg_type === 1
|
||||
? props.searchItem?.extra?.content
|
||||
: props.searchItem?.msg_type === 3 || props.searchItem?.msg_type === 6
|
||||
? props.searchItem?.extra
|
||||
: ChatMsgTypeMapping[props.searchItem?.msg_type]
|
||||
break
|
||||
default:
|
||||
@ -300,22 +262,6 @@ const resultDetail = computed(() => {
|
||||
}
|
||||
return result_detail
|
||||
})
|
||||
|
||||
const previewPDF = (item) => {
|
||||
console.log(item)
|
||||
// if (typeof plus !== 'undefined') {
|
||||
// downloadAndOpenFile(item)
|
||||
// } else {
|
||||
// document.addEventListener('plusready', () => {
|
||||
// downloadAndOpenFile(item)
|
||||
// })
|
||||
// }
|
||||
window.open(
|
||||
`${import.meta.env.VITE_PAGE_URL}/office?url=${item}`,
|
||||
'_blank',
|
||||
'width=1200,height=900,left=200,top=200,toolbar=no,menubar=no,scrollbars=yes,resizable=yes,location=no,status=no'
|
||||
)
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.search-item {
|
||||
@ -375,69 +321,6 @@ const previewPDF = (item) => {
|
||||
color: #999999;
|
||||
line-height: 20px;
|
||||
}
|
||||
.file-message-wrapper {
|
||||
.condition-each-result-attachments {
|
||||
width: 289px;
|
||||
height: 62px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
padding: 12px 15px;
|
||||
background-color: #f3f3f3;
|
||||
border-radius: 4px;
|
||||
border-bottom: 1px solid #f8f8f8;
|
||||
box-sizing: border-box;
|
||||
|
||||
.attachment-avatar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
img {
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
}
|
||||
}
|
||||
.attachment-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
margin: 0 0 0 11px;
|
||||
width: calc(100% - 38px - 11px);
|
||||
.attachment-info-title {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
width: 100%;
|
||||
span {
|
||||
line-height: 20px;
|
||||
color: #191919;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
.attachment-sub-info {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
width: 100%;
|
||||
span {
|
||||
line-height: 17px;
|
||||
color: #999999;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.info-detail-searchRecordDetail {
|
||||
display: flex;
|
||||
@ -497,31 +380,4 @@ const previewPDF = (item) => {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.message-component-wrapper {
|
||||
width: 154px;
|
||||
height: 100px;
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
.im-message-video,
|
||||
.im-message-image,
|
||||
.image-container {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
:deep(.n-image) {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
:deep(img),
|
||||
:deep(video) {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
object-fit: cover !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -16,16 +16,12 @@ const props = defineProps({
|
||||
createdAt: {
|
||||
type: String,
|
||||
required: false
|
||||
},
|
||||
modalTitle: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
}
|
||||
})
|
||||
const isShow=defineModel<boolean>('show')
|
||||
const { showUserInfoModal } = useInject()
|
||||
const items = ref<ITalkRecord[]>([])
|
||||
const title = ref(props?.modalTitle || '会话记录')
|
||||
const title = ref('会话记录')
|
||||
|
||||
const onMaskClick = () => {
|
||||
isShow.value=false
|
||||
@ -34,7 +30,7 @@ const onMaskClick = () => {
|
||||
const onLoadData = () => {
|
||||
ServeGetForwardRecords({
|
||||
msg_id: props.msgId,
|
||||
biz_date: parseTime(new Date(props.createdAt || ''), '{y}{m}')
|
||||
biz_date: parseTime(new Date(props.createdAt), '{y}{m}')
|
||||
}).then((res) => {
|
||||
if (res.code == 200) {
|
||||
items.value = res.data.items || []
|
||||
|
@ -12,13 +12,7 @@ const props = defineProps<{
|
||||
const isShowRecord = ref(false)
|
||||
|
||||
const title = computed(() => {
|
||||
const uniqueNames = [...new Set(props.extra.records.map(v => v.nickname))];
|
||||
if (uniqueNames.length <= 2) {
|
||||
return uniqueNames.join('和');
|
||||
} else {
|
||||
return uniqueNames.slice(0, 2).join('和') + '等';
|
||||
}
|
||||
// return [...new Set(props.extra.records.map((v) => v.nickname))].join('和')
|
||||
return [...new Set(props.extra.records.map((v) => v.nickname))].join('、')
|
||||
})
|
||||
|
||||
const onClick = () => {
|
||||
@ -27,7 +21,7 @@ const onClick = () => {
|
||||
</script>
|
||||
<template>
|
||||
<section class="im-message-forward pointer" @click="onClick">
|
||||
<div class="title">{{ extra.forward_name || title}}的会话记录</div>
|
||||
<div class="title">{{ title }} 的会话记录</div>
|
||||
<div class="list" v-for="(record, index) in extra.records" :key="index">
|
||||
<p>
|
||||
<span>{{ record.nickname }}: </span>
|
||||
@ -39,7 +33,7 @@ const onClick = () => {
|
||||
<span>转发:聊天会话记录 ({{ extra.msg_ids.length }}条)</span>
|
||||
</div>
|
||||
|
||||
<ForwardRecord v-model:show="isShowRecord" :msg-id="data.msg_id" @close="isShowRecord = false" :created-at="data.created_at" :modalTitle="(extra.forward_name || title) + '的会话记录'"/>
|
||||
<ForwardRecord v-model:show="isShowRecord" :msg-id="data.msg_id" @close="isShowRecord = false" :created-at="data.created_at"/>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
@ -47,21 +41,19 @@ const onClick = () => {
|
||||
.im-message-forward {
|
||||
width: 250px;
|
||||
min-height: 95px;
|
||||
max-height: 190px;
|
||||
max-height: 150px;
|
||||
border-radius: 10px;
|
||||
padding: 8px 10px;
|
||||
border: 1px solid var(--im-message-border-color);
|
||||
user-select: none;
|
||||
|
||||
.title {
|
||||
max-height: 60px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
font-size: 15px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
white-space: nowrap;
|
||||
font-weight: 400;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
@ -11,20 +11,12 @@ defineProps<{
|
||||
let show = ref(false)
|
||||
</script>
|
||||
<template>
|
||||
<section
|
||||
class="im-message-group-notice pointer"
|
||||
@click="show = !show"
|
||||
:class="{
|
||||
left: data.float === 'left',
|
||||
right: data.float === 'right'
|
||||
}"
|
||||
>
|
||||
<section class="im-message-group-notice pointer" @click="show = !show">
|
||||
<div class="title">
|
||||
<!-- <n-tag :bordered="false" size="small" type="primary"> 群公告 </n-tag>
|
||||
《{{ extra.title }}》 -->
|
||||
<text>群公告</text>
|
||||
<n-tag :bordered="false" size="small" type="primary"> 群公告 </n-tag>
|
||||
《{{ extra.title }}》
|
||||
</div>
|
||||
<div class="title" :class="{ ellipsis: !show }">
|
||||
<div class="content" :class="{ ellipsis: !show }">
|
||||
{{ extra.content }}
|
||||
</div>
|
||||
</section>
|
||||
@ -38,14 +30,14 @@ let show = ref(false)
|
||||
padding: 8px 10px;
|
||||
border: 1px solid var(--im-message-border-color);
|
||||
user-select: none;
|
||||
background-color: #fff;
|
||||
|
||||
.title {
|
||||
line-height: 44rpx;
|
||||
font-size: 32rpx;
|
||||
// overflow: hidden;
|
||||
// text-overflow: ellipsis;
|
||||
// white-space: nowrap;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
font-size: 14px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-weight: 400;
|
||||
margin-bottom: 5px;
|
||||
position: relative;
|
||||
@ -64,18 +56,5 @@ let show = ref(false)
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
&.left {
|
||||
background-color: #fff;
|
||||
border-radius: 0 16rpx 16rpx 16rpx;
|
||||
}
|
||||
|
||||
&.right {
|
||||
background-color: #46299d;
|
||||
border-radius: 16rpx 0 16rpx 16rpx;
|
||||
.title {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -38,7 +38,7 @@ const img = (src: string, width = 200) => {
|
||||
<div class="image-container">
|
||||
<n-image class="h-149px" :src="extra.url" />
|
||||
<!-- 上传中的loading蒙版 -->
|
||||
<div v-if="props.extra.is_uploading" class="loading-overlay">
|
||||
<div v-if="extra.is_uploading" class="loading-overlay">
|
||||
<n-spin size="large" />
|
||||
</div>
|
||||
</div>
|
||||
@ -53,7 +53,7 @@ const img = (src: string, width = 200) => {
|
||||
height:149px;
|
||||
|
||||
&.left {
|
||||
background: var(--im-message-right-bg-color);
|
||||
background: #F4F4FC;
|
||||
}
|
||||
|
||||
.image-container {
|
||||
|
@ -27,16 +27,6 @@ const props = defineProps({
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
revokeInfo: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
extra: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
|
||||
@ -52,104 +42,16 @@ const onRevoke = () => {
|
||||
</script>
|
||||
<template>
|
||||
<div class="im-message-revoke">
|
||||
<div class="content" v-if="JSON.stringify(revokeInfo) !== '{}'">
|
||||
<span v-if="talk_type === 1 && login_uid === revokeInfo.withdraw_id">
|
||||
你撤回了一条消息 | {{ formatTime(datetime) }}
|
||||
</span>
|
||||
<span v-if="talk_type === 1 && login_uid !== revokeInfo.withdraw_id">
|
||||
{{ revokeInfo.withdraw_name }}撤回了一条消息 | {{ formatTime(datetime) }}
|
||||
</span>
|
||||
<span
|
||||
v-if="
|
||||
talk_type === 2 &&
|
||||
login_uid === revokeInfo.withdraw_id &&
|
||||
login_uid === revokeInfo.retracted_id
|
||||
"
|
||||
>
|
||||
你撤回了一条消息 |
|
||||
{{ formatTime(datetime) }}
|
||||
<slot></slot>
|
||||
</span>
|
||||
<span
|
||||
v-if="
|
||||
talk_type === 2 &&
|
||||
login_uid === revokeInfo.withdraw_id &&
|
||||
login_uid !== revokeInfo.retracted_id
|
||||
"
|
||||
>
|
||||
你撤回了{{ revokeInfo.retracted_name }}一条消息 |
|
||||
{{ formatTime(datetime) }}
|
||||
</span>
|
||||
<span
|
||||
v-if="
|
||||
talk_type === 2 &&
|
||||
login_uid !== revokeInfo.withdraw_id &&
|
||||
revokeInfo.withdraw_id === revokeInfo.retracted_id
|
||||
"
|
||||
>
|
||||
{{ revokeInfo.withdraw_name }}撤回了一条消息 |
|
||||
{{ formatTime(datetime) }}
|
||||
</span>
|
||||
|
||||
<span
|
||||
v-if="
|
||||
talk_type === 2 &&
|
||||
login_uid !== revokeInfo.withdraw_id &&
|
||||
login_uid === revokeInfo.retracted_id &&
|
||||
revokeInfo.withdraw_id !== revokeInfo.retracted_id
|
||||
"
|
||||
>
|
||||
{{ revokeInfo.withdraw_name }}撤回了你一条消息 |
|
||||
{{ formatTime(datetime) }}
|
||||
</span>
|
||||
<span
|
||||
v-if="
|
||||
talk_type === 2 &&
|
||||
login_uid !== revokeInfo.withdraw_id &&
|
||||
login_uid !== revokeInfo.retracted_id &&
|
||||
revokeInfo.withdraw_id !== revokeInfo.retracted_id
|
||||
"
|
||||
>
|
||||
{{ revokeInfo.withdraw_name }}撤回了{{ revokeInfo.retracted_name }}一条消息 |
|
||||
{{ formatTime(datetime) }}
|
||||
</span>
|
||||
|
||||
<div style="display: inline-block;" v-if="login_uid === user_id">
|
||||
<n-button
|
||||
@click="onRevoke"
|
||||
v-if="data.msg_type === 1 && data.extra?.content"
|
||||
text
|
||||
class="text-#46299D text-11px"
|
||||
>重新编辑</n-button
|
||||
>
|
||||
<div class="content">
|
||||
<div v-if="login_uid === user_id">
|
||||
<span> 你撤回了一条消息 | {{ formatTime(datetime) }} </span>
|
||||
<n-button @click="onRevoke" v-if="data.msg_type === 1&&data.extra?.content&&data.is_self_action" text class="text-#46299D text-11px">重新编辑</n-button>
|
||||
</div>
|
||||
<!-- <span v-if="login_uid == user_idA"> 你撤回B了一条消息 | {{ formatTime(datetime) }} </span>
|
||||
<span v-else-if="login_uid == user_idB"> A撤回你了一条消息 | {{ formatTime(datetime) }} </span>
|
||||
<span v-else> A撤回B了一条消息 | {{ formatTime(datetime) }} </span> -->
|
||||
</div>
|
||||
<div class="content" v-if="JSON.stringify(revokeInfo) === '{}'">
|
||||
<span v-if="talk_type === 1 && login_uid === user_id">
|
||||
你撤回了一条消息 | {{ formatTime(datetime) }}
|
||||
<span v-else-if="talk_type == 1"> 对方撤回了一条消息 | {{ formatTime(datetime) }} </span>
|
||||
<span v-else>
|
||||
"{{ nickname }}" 撤回了一条消息 |
|
||||
{{ formatTime(datetime) }}
|
||||
</span>
|
||||
<span v-if="talk_type === 1 && login_uid !== user_id">
|
||||
{{ nickname }}撤回了一条消息 | {{ formatTime(datetime) }}
|
||||
</span>
|
||||
<span v-if="talk_type === 2 && !extra && login_uid === user_id">
|
||||
你撤回了一条消息 | {{ formatTime(datetime) }}
|
||||
</span>
|
||||
<span v-if="talk_type === 2 && !extra && login_uid !== user_id">
|
||||
{{ nickname }}撤回了一条消息 | {{ formatTime(datetime) }}
|
||||
</span>
|
||||
<span v-if="talk_type === 2 && extra"> {{ extra }} | {{ formatTime(datetime) }} </span>
|
||||
<div style="display: inline-block;" v-if="login_uid === user_id">
|
||||
<n-button
|
||||
@click="onRevoke"
|
||||
v-if="data.msg_type === 1 && data.extra?.content"
|
||||
text
|
||||
class="text-#46299D text-11px"
|
||||
>重新编辑</n-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<script lang="ts" setup>
|
||||
import 'xgplayer/dist/index.min.css'
|
||||
import { ref, nextTick, watch } from 'vue'
|
||||
import { ref, nextTick, watch, computed } from 'vue'
|
||||
import { NImage, NModal, NCard, NProgress, NPopconfirm } from 'naive-ui'
|
||||
import { Play, Close, Pause, Right, Attention } from '@icon-park/vue-next'
|
||||
import { getImageInfo } from '@/utils/functions'
|
||||
@ -64,6 +64,11 @@ const updatePauseStatus = () => {
|
||||
// 初始化时检查状态
|
||||
updatePauseStatus()
|
||||
|
||||
// 创建视频封面的URL
|
||||
const videoSrc = computed(() => {
|
||||
// 即使在上传过程中也返回视频URL,这样可以显示视频封面
|
||||
return props.extra.url || ''
|
||||
})
|
||||
// // 监听关键道具变化
|
||||
// watch(() => props.extra.percentage, (newVal: number | undefined) => {
|
||||
// // 确保进度更新时 UI 也实时更新
|
||||
@ -136,7 +141,7 @@ function resumeUpload(e) {
|
||||
>
|
||||
|
||||
<!-- <n-image :src="extra.cover" preview-disabled /> -->
|
||||
<video :src="props.extra.url" :controls="false"></video>
|
||||
<video :src="videoSrc" :controls="false"></video>
|
||||
<!-- 上传进度时的黑色半透明蒙层 -->
|
||||
<div v-if="extra.is_uploading && !uploadFailed" class="upload-mask"></div>
|
||||
<!-- 上传进度显示 -->
|
||||
@ -252,7 +257,7 @@ function resumeUpload(e) {
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.45);
|
||||
background: rgba(0, 0, 0, 0.3); /* 降低不透明度,从0.45改为0.3,让视频封面能够显示 */
|
||||
z-index: 1;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ const { showUserInfoModal } = useInject()
|
||||
<div class="sys-text">
|
||||
|
||||
<template v-for="(user, index) in extra.members" :key="index">
|
||||
<a @click="showUserInfoModal(user.erp_user_id,user.user_id)">{{ user.nickname }}</a>
|
||||
<a>{{ user.nickname }}</a>
|
||||
<em v-show="index < extra.members.length - 1">、</em>
|
||||
</template>
|
||||
|
||||
|
@ -13,7 +13,7 @@ defineProps({
|
||||
<template>
|
||||
<div class="im-message-sys-text">
|
||||
<div class="sys-text">
|
||||
<a @click="showUserInfoModal(extra.owner_id)">
|
||||
<a >
|
||||
{{ extra.owner_name }}
|
||||
</a>
|
||||
|
||||
|
@ -14,14 +14,14 @@ const { showUserInfoModal } = useInject()
|
||||
<div class="im-message-sys-text">
|
||||
<div class="sys-text">
|
||||
|
||||
<a @click="showUserInfoModal(extra.owner_id)">
|
||||
<a >
|
||||
{{ extra.owner_name }}
|
||||
</a>
|
||||
|
||||
<span>创建了群聊,并邀请了</span>
|
||||
|
||||
<template v-for="(user, index) in extra.members" :key="index">
|
||||
<a @click="showUserInfoModal(user.user_id)">{{ user.nickname }}</a>
|
||||
<a >{{ user.nickname }}</a>
|
||||
<em v-show="index < extra.members.length - 1">、</em>
|
||||
</template>
|
||||
</div>
|
||||
|
@ -13,7 +13,7 @@ defineProps({
|
||||
<template>
|
||||
<div class="im-message-sys-text">
|
||||
<div class="sys-text">
|
||||
<a @click="showUserInfoModal(data.user_id)">
|
||||
<a>
|
||||
<!-- {{ data.nickname }} -->
|
||||
管理员
|
||||
</a>
|
||||
|
@ -13,14 +13,14 @@ const { showUserInfoModal } = useInject()
|
||||
<template>
|
||||
<div class="im-message-sys-text">
|
||||
<div class="sys-text">
|
||||
<a @click="showUserInfoModal(extra.owner_id)">
|
||||
<a >
|
||||
{{ extra.owner_name }}
|
||||
</a>
|
||||
|
||||
<span>邀请了</span>
|
||||
|
||||
<template v-for="(user, index) in extra.members" :key="index">
|
||||
<a @click="showUserInfoModal(user.user_id)">{{ user.nickname }}</a>
|
||||
<a>{{ user.nickname }}</a>
|
||||
<em v-show="index < extra.members.length - 1">、</em>
|
||||
</template>
|
||||
|
||||
|
@ -13,14 +13,14 @@ const { showUserInfoModal } = useInject()
|
||||
<template>
|
||||
<div class="im-message-sys-text">
|
||||
<div class="sys-text">
|
||||
<a @click="showUserInfoModal(extra.owner_id)">
|
||||
<a >
|
||||
{{ extra.owner_name }}
|
||||
</a>
|
||||
|
||||
<span>解除了</span>
|
||||
|
||||
<template v-for="(user, index) in extra.members" :key="index">
|
||||
<a @click="showUserInfoModal(user.user_id)">{{ user.nickname }}</a>
|
||||
<a >{{ user.nickname }}</a>
|
||||
<em v-show="index < extra.members.length - 1">、</em>
|
||||
</template>
|
||||
|
||||
|
@ -13,14 +13,14 @@ const { showUserInfoModal } = useInject()
|
||||
<template>
|
||||
<div class="im-message-sys-text">
|
||||
<div class="sys-text">
|
||||
<a @click="showUserInfoModal(extra.owner_id)">
|
||||
<a>
|
||||
{{ extra.owner_name }}
|
||||
</a>
|
||||
|
||||
<span>将</span>
|
||||
|
||||
<template v-for="(user, index) in extra.members" :key="index">
|
||||
<a @click="showUserInfoModal(user.user_id)">{{ user.nickname }}</a>
|
||||
<a>{{ user.nickname }}</a>
|
||||
<em v-show="index < extra.members.length - 1">、</em>
|
||||
</template>
|
||||
|
||||
|
@ -13,14 +13,14 @@ const { showUserInfoModal } = useInject()
|
||||
<template>
|
||||
<div class="im-message-sys-text">
|
||||
<div class="sys-text">
|
||||
<a @click="showUserInfoModal(extra.owner_id)">
|
||||
<a>
|
||||
{{ extra.owner_name }}
|
||||
</a>
|
||||
|
||||
<span>设置了</span>
|
||||
|
||||
<template v-for="(user, index) in extra.members" :key="index">
|
||||
<a @click="showUserInfoModal(user.user_id)">{{ user.nickname }}</a>
|
||||
<a>{{ user.nickname }}</a>
|
||||
<em v-show="index < extra.members.length - 1">、</em>
|
||||
</template>
|
||||
|
||||
|
@ -13,7 +13,7 @@ const { showUserInfoModal } = useInject()
|
||||
<template>
|
||||
<div class="im-message-sys-text">
|
||||
<div class="sys-text">
|
||||
<a @click="showUserInfoModal(extra.owner_id)">
|
||||
<a >
|
||||
{{ extra.owner_name }}
|
||||
</a>
|
||||
|
||||
|
@ -14,7 +14,7 @@ defineProps({
|
||||
<div class="im-message-sys-text">
|
||||
<div class="sys-text">
|
||||
<template v-for="(user, index) in extra?.members" :key="index">
|
||||
<a @click="showUserInfoModal(user.user_id)">{{ user.nickname }}</a>
|
||||
<a >{{ user.nickname }}</a>
|
||||
<em v-show="index < extra.members.length - 1">、</em>
|
||||
</template>
|
||||
<span>已离开此群</span>
|
||||
|
@ -13,7 +13,7 @@ const { showUserInfoModal } = useInject()
|
||||
<template>
|
||||
<div class="im-message-sys-text">
|
||||
<div class="sys-text">
|
||||
<a @click="showUserInfoModal(extra.owner_id)">
|
||||
<a >
|
||||
{{ extra.owner_name }}
|
||||
</a>
|
||||
|
||||
|
@ -13,9 +13,9 @@ const { showUserInfoModal } = useInject()
|
||||
<template>
|
||||
<div class="im-message-sys-text">
|
||||
<div class="sys-text">
|
||||
<a @click="showUserInfoModal(extra.old_owner_id)">{{ extra.old_owner_name }}</a>
|
||||
<a >{{ extra.old_owner_name }}</a>
|
||||
<span>将群主转让给</span>
|
||||
<a @click="showUserInfoModal(extra.new_owner_id)">{{ extra.new_owner_name }}</a>
|
||||
<a >{{ extra.new_owner_name }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -10,7 +10,6 @@
|
||||
padding: 0 8px;
|
||||
word-wrap: break-word;
|
||||
color: #979191;
|
||||
user-select: none;
|
||||
font-weight: 300;
|
||||
display: inline-block;
|
||||
border-radius: 3px;
|
||||
@ -23,13 +22,11 @@
|
||||
|
||||
a {
|
||||
color: #939596;
|
||||
cursor: pointer;
|
||||
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
|
||||
&:hover {
|
||||
color: #462AA0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -131,8 +131,6 @@ const onSubmit = () => {
|
||||
talk_type: item.talk_type
|
||||
}
|
||||
})
|
||||
console.log('data', data);
|
||||
console.log('checkedFilter.value', checkedFilter.value);
|
||||
emit('on-submit', data)
|
||||
}
|
||||
|
||||
|
@ -96,6 +96,7 @@ export const MessageComponents = {
|
||||
|
||||
// 可转发的消息类型
|
||||
export const ForwardableMessageType = [
|
||||
ChatMsgTypeForward,
|
||||
ChatMsgTypeText,
|
||||
ChatMsgTypeCode,
|
||||
ChatMsgTypeImage,
|
||||
|
@ -70,12 +70,6 @@ class Revoke extends Base {
|
||||
useTalkStore().updateItem({
|
||||
index_name: this.getIndexName(),
|
||||
msg_text: this.resource.text,
|
||||
revokeInfo: {
|
||||
retracted_id: this.resource.retracted_id,
|
||||
retracted_name: this.resource.retracted_name,
|
||||
withdraw_id: this.resource.withdraw_id,
|
||||
withdraw_name: this.resource.withdraw_name,
|
||||
},
|
||||
updated_at: parseTime(new Date())
|
||||
})
|
||||
|
||||
@ -86,12 +80,6 @@ class Revoke extends Base {
|
||||
|
||||
useDialogueStore().updateDialogueRecord({
|
||||
msg_id: this.msg_id,
|
||||
revokeInfo: {
|
||||
retracted_id: this.resource.retracted_id,
|
||||
retracted_name: this.resource.retracted_name,
|
||||
withdraw_id: this.resource.withdraw_id,
|
||||
withdraw_name: this.resource.withdraw_name,
|
||||
},
|
||||
is_revoke: 1
|
||||
})
|
||||
}
|
||||
|
@ -245,8 +245,6 @@ export const useDialogueStore = defineStore('dialogue', {
|
||||
}).then((res) => {
|
||||
if (res.code == 200) {
|
||||
this.batchDelDialogueRecord(msgIds)
|
||||
} else {
|
||||
window['$message'].warning(res.message)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
@ -170,14 +170,14 @@ export const useUploadsStore = defineStore('uploads', {
|
||||
|
||||
// 更新状态为上传中
|
||||
currentItem.status = 1
|
||||
|
||||
const updatedItem:any = this.findItem(uploadId)
|
||||
// 上传当前分片
|
||||
try {
|
||||
|
||||
const res = await ServeFileSubareaUpload(form)
|
||||
|
||||
// 获取最新的项目状态,确保仍然存在且没有被暂停
|
||||
const updatedItem:any = this.findItem(uploadId)
|
||||
|
||||
if (res.code == 200) {
|
||||
// 当前分片上传成功,增加索引
|
||||
updatedItem.uploadIndex++
|
||||
@ -209,10 +209,12 @@ export const useUploadsStore = defineStore('uploads', {
|
||||
|
||||
}
|
||||
} catch (error) {
|
||||
updatedItem.onProgress(-1)
|
||||
console.error("分片上传错误:", error);
|
||||
|
||||
// 获取最新的项目状态
|
||||
const updatedItem = this.findItem(uploadId)
|
||||
// 这里不应该重新定义变量,而是使用已有的updatedItem
|
||||
// const updatedItem = this.findItem(uploadId)
|
||||
if (!updatedItem) return
|
||||
|
||||
// 如果是暂停导致的错误,不改变状态
|
||||
|
@ -51,8 +51,7 @@ export interface ITalkRecord {
|
||||
float: string,
|
||||
is_convert_text?:number//语音记录的 是否是在展示转文本状态 1:是 0:否,
|
||||
erp_user_id:number,
|
||||
read_total_num:number,
|
||||
revokeInfo?: any
|
||||
read_total_num:number
|
||||
}
|
||||
|
||||
export interface ITalkRecordExtraText {
|
||||
@ -82,7 +81,6 @@ export interface ITalkRecordExtraForward {
|
||||
}[]
|
||||
talk_type: number
|
||||
user_id: number
|
||||
forward_name?: any
|
||||
}
|
||||
|
||||
export interface ITalkRecordExtraGroupNotice {
|
||||
|
@ -18,7 +18,7 @@ export function isLoggedIn() {
|
||||
*/
|
||||
export function getAccessToken() {
|
||||
// return storage.get(AccessToken) || ''
|
||||
return JSON.parse(localStorage.getItem('token'))||'46d71a72d8d845ad7ed23eba9bdde260e635407190c2ce1bf7fd22088e41682ea07773ec65cae8946d2003f264d55961f96e0fc5da10eb96d3a348c1664e9644ce2108c311309f398ae8ea1b8200bfd490e5cb6e8c52c9e5d493cbabb163368f8351420451a631dbfa749829ee4cda49b77b5ed2d3dced5d0f2b7dd9ee76ba5465c84a17c23af040cd92b6b2a4ea48befbb5c729dcdad0a9c9668befe84074cc24f78899c1d947f8e7f94c7eda5325b8ed698df729e76febb98549ef3482ae942fb4f4a1c92d21836fa784728f0c5483aab2760a991b6b36e6b10c84f840a6433a6ecc31dee36e8f1c6158818bc89d22c9c2f9b60a57573e8b08cdf47105e1ba85550c21fa55526e8a00bf316c623eb67abf749622c48beab908d61d3db7b22ed3eb6aa8a08c77680ad4d8a3458c1e72f97ba2b8480674df77f0501a34e82b58'
|
||||
return JSON.parse(localStorage.getItem('token'))||'79b5c732d96d2b27a48a99dfd4a5566c43aaa5796242e854ebe3ffc198d6876b9628e7b764d9af65ab5dbb2d517ced88170491b74b048c0ba827c0d3741462cb89dc59ed46653a449af837a8262941caaef1334d640773710f8cd96473bacfb190cba595a5d6a9c87d70f0999a3ebb41147213b31b4bdccffca66a56acf3baab5af0154f0dce360079f37709f78e13711036899344bddb0fb4cf0f2890287cb62c3fcbe33368caa5e213624577be8b8420ab75b1f50775ee16142a4321c5d56995f37354a66a969da98d95ba6e65d142ed097e04b411c1ebad2f62866d0ec7e1838420530a9941dbbcd00490199f8b8993ebccf0349a53e3197efc45b9dbe3f2bf1dc0dddce6787811964e76efefec3b3fd39fce15d43989c156413f12de3f0c74c1ff1d3c5da214d3bcefef7546498e37fa73453c749a56ea66777488bd3550'
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -68,6 +68,11 @@ export function clipboard(text, callback) {
|
||||
}
|
||||
|
||||
export async function clipboardImage(src, callback) {
|
||||
// 在wujie环境下使用主应用的clipboard
|
||||
const clipboardObj = window.__POWERED_BY_WUJIE__
|
||||
? window.parent.navigator.clipboard
|
||||
: navigator.clipboard
|
||||
|
||||
const { state } = await navigator.permissions.query({
|
||||
name: 'clipboard-write'
|
||||
})
|
||||
@ -80,7 +85,7 @@ export async function clipboardImage(src, callback) {
|
||||
|
||||
// navigator.clipboard.write 仅支持 png 图片
|
||||
if (blob.type == 'image/png') {
|
||||
await navigator.clipboard.write([
|
||||
await clipboardObj.write([
|
||||
new ClipboardItem({
|
||||
[blob.type]: blob
|
||||
})
|
||||
@ -99,13 +104,13 @@ export async function clipboardImage(src, callback) {
|
||||
|
||||
canvas.width = img.width
|
||||
canvas.height = img.height
|
||||
ctx.drawImage(img, 0, 0)
|
||||
ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
|
||||
|
||||
canvas.toBlob(
|
||||
(blob) => {
|
||||
const data = [new ClipboardItem({ [blob.type]: blob })]
|
||||
|
||||
navigator.clipboard
|
||||
clipboardObj
|
||||
.write(data)
|
||||
.then(() => {
|
||||
callback()
|
||||
|
@ -53,7 +53,13 @@ request.interceptors.request.use((config) => {
|
||||
}, errorHandler)
|
||||
|
||||
// 响应拦截器
|
||||
request.interceptors.response.use((response) => response.data, errorHandler)
|
||||
request.interceptors.response.use((response) => {
|
||||
console.log('response.data.status',response.data.status)
|
||||
if(response.data.code !==200&&response.data.status!==0){
|
||||
window['$message'].warning(response.data.msg)
|
||||
}
|
||||
return response.data
|
||||
}, errorHandler)
|
||||
|
||||
/**
|
||||
* GET 请求
|
||||
|
@ -16,8 +16,6 @@ import avatarModule from '@/components/avatar-module/index.vue'
|
||||
const userStore = useUserStore()
|
||||
const dialogueStore = useDialogueStore()
|
||||
const uploadsStore = useUploadsStore()
|
||||
console.log('dialogueStore', dialogueStore)
|
||||
|
||||
const members = computed(() => dialogueStore.members)
|
||||
const membersByAlphabet = computed(() => {
|
||||
if (state.searchMemberByAlphabet) {
|
||||
|
@ -37,7 +37,6 @@ const labelColor=[
|
||||
<div class="header">
|
||||
<div class="title">
|
||||
<span class="nickname">{{ username }}</span>
|
||||
<span v-if="data.talk_type == 2">({{data.group_member_num}})</span>
|
||||
<!-- <span class="badge top" v-show="data.is_top">顶</span>
|
||||
<span class="badge roboot" v-show="data.is_robot">助</span>
|
||||
<span class="badge group" v-show="data.talk_type == 2">群</span> -->
|
||||
|
@ -59,7 +59,6 @@ const onContactModal = (data: { receiver_id: number; talk_type: number }[]) => {
|
||||
group_ids.push(o.receiver_id)
|
||||
}
|
||||
}
|
||||
console.log('user_ids',user_ids)
|
||||
dialogueStore.ApiForwardRecord({
|
||||
mode: forwardMode.value,
|
||||
message_ids: msg_ids,
|
||||
|
@ -182,7 +182,7 @@ const onCopyText = (data: ITalkRecord) => {
|
||||
return clipboard(htmlDecode(data.extra.content), () => useMessage.success('复制成功'))
|
||||
}
|
||||
}
|
||||
|
||||
console.log('data.extra?.url',data.extra?.url)
|
||||
if (data.extra?.url) {
|
||||
return clipboardImage(data.extra.url, () => {
|
||||
useMessage.success('复制成功')
|
||||
@ -330,6 +330,7 @@ const onContextMenuHandle = (key: string) => {
|
||||
|
||||
const onRowClick = (item: ITalkRecord) => {
|
||||
if (dialogueStore.isOpenMultiSelect) {
|
||||
console.log('item.msg_type',item.msg_type)
|
||||
if (ForwardableMessageType.includes(item.msg_type)) {
|
||||
item.isCheck = !item.isCheck
|
||||
} else {
|
||||
@ -766,8 +767,6 @@ const onCustomSkipBottomEvent = () => {
|
||||
:nickname="item.nickname"
|
||||
:talk_type="item.talk_type"
|
||||
:datetime="item.created_at"
|
||||
:revokeInfo="item.revokeInfo"
|
||||
:extra="item.extra"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
@ -101,10 +101,13 @@ const onSendImageEvent = ({ data, callBack }) => {
|
||||
|
||||
// 发送视频消息
|
||||
const onSendVideoEvent = async ({ data }) => {
|
||||
|
||||
|
||||
// 获取视频首帧作为封面图
|
||||
// let resp = await getVideoImage(data)
|
||||
let videoPreview = null
|
||||
try {
|
||||
videoPreview = await getVideoImage(data)
|
||||
} catch (error) {
|
||||
console.error('获取视频封面失败:', error)
|
||||
}
|
||||
|
||||
// 先创建一个带有上传ID的临时消息对象,用于显示进度
|
||||
const uploadId = `video-${Date.now()}-${Math.floor(Math.random() * 1000)}`
|
||||
@ -123,7 +126,7 @@ const onSendVideoEvent = async ({ data }) => {
|
||||
content: '',
|
||||
created_at: parseTime(new Date(), '{y}-{m}-{d} {h}:{i}'),
|
||||
extra: {
|
||||
url: '',
|
||||
url: videoPreview ? URL.createObjectURL(data) : '', // 使用本地视频URL作为预览
|
||||
size: data.size,
|
||||
is_uploading: true,
|
||||
upload_id: uploadId,
|
||||
|
@ -147,7 +147,6 @@ const onSetMenu = () => {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
margin: 0 5px 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { reactive } from 'vue'
|
||||
import dayjs from 'dayjs'
|
||||
import { useDialogueStore } from '@/store/modules/dialogue.js'
|
||||
|
||||
interface IDropdown {
|
||||
@ -9,16 +10,34 @@ interface IDropdown {
|
||||
item: any
|
||||
}
|
||||
|
||||
const isRevoke = (uid: any, item: any): boolean => {
|
||||
if (uid != item.user_id) {
|
||||
return false
|
||||
const isRevoke = (uid: number, item: any): boolean => {
|
||||
// 不是自己发的消息不能撤回
|
||||
if (uid !== item.user_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const datetime = item.created_at.replace(/-/g, '/')
|
||||
|
||||
const time = new Date().getTime() - Date.parse(datetime)
|
||||
|
||||
return Math.floor(time / 1000 / 60) <= 2
|
||||
|
||||
// 检查消息是否在撤回时间限制内(5分钟)
|
||||
const messageTime = dayjs(item.created_at);
|
||||
const now = dayjs();
|
||||
const diffInMinutes = now.diff(messageTime, 'minute');
|
||||
return diffInMinutes <= 5;
|
||||
}
|
||||
// 判断是否可以添加撤回选项的函数
|
||||
const canAddRevokeOption = (uid: number, item: any, isManager: boolean): boolean => {
|
||||
// 单聊情况:自己发的且在时间限制内
|
||||
if (item.talk_type === 1) {
|
||||
return isRevoke(uid, item) && item.float === 'right';
|
||||
}
|
||||
// 群聊情况
|
||||
else if (item.talk_type === 2) {
|
||||
// 管理员可以撤回任何消息
|
||||
if (isManager) {
|
||||
return true;
|
||||
}
|
||||
// 普通成员只能撤回自己的且在时间限制内的消息
|
||||
return isRevoke(uid, item) && item.float === 'right';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
const dialogueStore = useDialogueStore()
|
||||
export function useMenu() {
|
||||
@ -33,6 +52,7 @@ export function useMenu() {
|
||||
const showDropdownMenu = (e: any, uid: number, item: any) => {
|
||||
// dropdown.item = Object.assign({}, item)
|
||||
dropdown.item = item
|
||||
dropdown.item.is_self_action = true
|
||||
dropdown.options = []
|
||||
if ([4].includes(item.msg_type)) {
|
||||
if(item.is_convert_text === 1){
|
||||
@ -48,9 +68,10 @@ export function useMenu() {
|
||||
|
||||
dropdown.options.push({ label: '多选', key: 'multiSelect' })
|
||||
dropdown.options.push({ label: '引用', key: 'quote' })
|
||||
if (isRevoke(uid, item)|| (dialogueStore.groupInfo as any).is_manager) {
|
||||
dropdown.options.push({ label: `撤回`, key: 'revoke' })
|
||||
if (canAddRevokeOption(uid, item, (dialogueStore.groupInfo as any).is_manager)) {
|
||||
dropdown.options.push({ label: '撤回', key: 'revoke' });
|
||||
}
|
||||
|
||||
dropdown.options.push({ label: '删除', key: 'delete' })
|
||||
|
||||
|
||||
|
@ -46,9 +46,9 @@ export default defineConfig(({ mode }) => {
|
||||
vueJsx({}),
|
||||
compressPlugin(),
|
||||
UnoCSS(),
|
||||
vueDevTools({
|
||||
launchEditor: 'trae',
|
||||
})
|
||||
// vueDevTools({
|
||||
// launchEditor: 'trae',
|
||||
// })
|
||||
],
|
||||
define: {
|
||||
__APP_ENV__: env.APP_ENV
|
||||
|
Loading…
Reference in New Issue
Block a user