✨ feat(im): 增加群聊消息的管理
parent
dfbae06afa
commit
d64a695673
|
|
@ -0,0 +1,160 @@
|
||||||
|
<template>
|
||||||
|
<!-- 文本 / 系统提示文本:直接显示纯文本 -->
|
||||||
|
<span v-if="isText" class="whitespace-pre-wrap break-all">{{ textContent }}</span>
|
||||||
|
|
||||||
|
<!-- 图片:缩略图 + 点击放大 -->
|
||||||
|
<el-image
|
||||||
|
v-else-if="isImage && imagePayload"
|
||||||
|
class="w-60px h-60px rounded align-middle"
|
||||||
|
:src="imagePayload.thumbnailUrl || imagePayload.url"
|
||||||
|
:preview-src-list="[imagePayload.url]"
|
||||||
|
:preview-teleported="true"
|
||||||
|
fit="cover"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 文件:图标 + 名称 + 大小,单行内显示 -->
|
||||||
|
<span v-else-if="isFile && filePayload" class="inline-flex gap-1.5 items-center">
|
||||||
|
<Icon :icon="fileIconInfo.icon" :color="fileIconInfo.color" :size="18" />
|
||||||
|
<span class="max-w-200px truncate">{{ filePayload.name }}</span>
|
||||||
|
<span v-if="filePayload.size" class="text-12px text-[var(--el-text-color-secondary)]">
|
||||||
|
{{ formatFileSize(filePayload.size) }}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<!-- 语音:图标 + 时长 -->
|
||||||
|
<span v-else-if="isVoice && voicePayload" class="inline-flex gap-1.5 items-center">
|
||||||
|
<Icon icon="ant-design:audio-outlined" :size="16" color="#606266" />
|
||||||
|
<span>{{ formatSeconds(voicePayload.duration ?? 0) }}</span>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<!-- 视频:图标 + 占位文案 + 大小 -->
|
||||||
|
<span v-else-if="isVideo" class="inline-flex gap-1.5 items-center">
|
||||||
|
<Icon icon="ant-design:video-camera-filled" :size="16" color="#9c27b0" />
|
||||||
|
<span>[视频]</span>
|
||||||
|
<span v-if="videoPayload?.size" class="text-12px text-[var(--el-text-color-secondary)]">
|
||||||
|
{{ formatFileSize(videoPayload.size) }}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<!-- 控制类消息:撤回 / 已读 / 回执 -->
|
||||||
|
<span
|
||||||
|
v-else-if="props.type === ImMessageType.RECALL"
|
||||||
|
class="text-12px text-[var(--el-text-color-secondary)]"
|
||||||
|
>
|
||||||
|
[消息已撤回]
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
v-else-if="props.type === ImMessageType.READ"
|
||||||
|
class="text-12px text-[var(--el-text-color-secondary)]"
|
||||||
|
>
|
||||||
|
[已读回执]
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
v-else-if="props.type === ImMessageType.RECEIPT"
|
||||||
|
class="text-12px text-[var(--el-text-color-secondary)]"
|
||||||
|
>
|
||||||
|
[回执]
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<!-- 系统事件类(FRIEND_* / GROUP_*):content 通常是结构化 JSON,回退原始预览 -->
|
||||||
|
<span v-else class="whitespace-pre-wrap break-all">{{ fallbackText }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import Icon from '@/components/Icon/src/Icon.vue'
|
||||||
|
import { formatFileSize } from '@/utils/file'
|
||||||
|
import { formatSeconds } from '@/utils/formatTime'
|
||||||
|
import { ImMessageType } from '@/views/im/utils/constants'
|
||||||
|
import {
|
||||||
|
parseMessage,
|
||||||
|
resolveTipText,
|
||||||
|
type ImageMessage,
|
||||||
|
type FileMessage,
|
||||||
|
type AudioMessage,
|
||||||
|
type VideoMessage
|
||||||
|
} from '@/views/im/utils/message'
|
||||||
|
|
||||||
|
defineOptions({ name: 'ImMessageContentPreview' })
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
/** 消息类型,对应 ImMessageType */
|
||||||
|
type?: number
|
||||||
|
/** 消息 content(JSON 字符串或裸文本) */
|
||||||
|
content?: string
|
||||||
|
}>()
|
||||||
|
|
||||||
|
/** 各类型判定 */
|
||||||
|
const isText = computed(
|
||||||
|
() => props.type === ImMessageType.TEXT || props.type === ImMessageType.TIP_TEXT
|
||||||
|
)
|
||||||
|
const isImage = computed(() => props.type === ImMessageType.IMAGE)
|
||||||
|
const isFile = computed(() => props.type === ImMessageType.FILE)
|
||||||
|
const isVoice = computed(() => props.type === ImMessageType.VOICE)
|
||||||
|
const isVideo = computed(() => props.type === ImMessageType.VIDEO)
|
||||||
|
|
||||||
|
/** 文本内容:兼容 JSON 包裹和裸字符串两种形态 */
|
||||||
|
const textContent = computed(() => resolveTipText(props.content || ''))
|
||||||
|
|
||||||
|
const imagePayload = computed(() =>
|
||||||
|
isImage.value ? parseMessage<ImageMessage>(props.content || '') : null
|
||||||
|
)
|
||||||
|
const filePayload = computed(() =>
|
||||||
|
isFile.value ? parseMessage<FileMessage>(props.content || '') : null
|
||||||
|
)
|
||||||
|
const voicePayload = computed(() =>
|
||||||
|
isVoice.value ? parseMessage<AudioMessage>(props.content || '') : null
|
||||||
|
)
|
||||||
|
const videoPayload = computed(() =>
|
||||||
|
isVideo.value ? parseMessage<VideoMessage>(props.content || '') : null
|
||||||
|
)
|
||||||
|
|
||||||
|
/** 文件图标:按扩展名分配 icon + 颜色,对齐 home 端 MessageItem 的观感 */
|
||||||
|
const fileIconInfo = computed<{ icon: string; color: string }>(() => {
|
||||||
|
const name = filePayload.value?.name || ''
|
||||||
|
const ext = name.split('.').pop()?.toLowerCase() || ''
|
||||||
|
if (ext === 'pdf') {
|
||||||
|
return { icon: 'ant-design:file-pdf-filled', color: '#ed5757' }
|
||||||
|
}
|
||||||
|
if (['doc', 'docx'].includes(ext)) {
|
||||||
|
return { icon: 'ant-design:file-word-filled', color: '#2b7cd3' }
|
||||||
|
}
|
||||||
|
if (['xls', 'xlsx'].includes(ext)) {
|
||||||
|
return { icon: 'ant-design:file-excel-filled', color: '#1f7244' }
|
||||||
|
}
|
||||||
|
if (['ppt', 'pptx'].includes(ext)) {
|
||||||
|
return { icon: 'ant-design:file-ppt-filled', color: '#d24726' }
|
||||||
|
}
|
||||||
|
if (['zip', 'rar', '7z', 'tar', 'gz'].includes(ext)) {
|
||||||
|
return { icon: 'ant-design:file-zip-filled', color: '#f0ad4e' }
|
||||||
|
}
|
||||||
|
if (['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg'].includes(ext)) {
|
||||||
|
return { icon: 'ant-design:file-image-filled', color: '#9c27b0' }
|
||||||
|
}
|
||||||
|
if (['mp4', 'mov', 'avi', 'mkv', 'wmv', 'flv'].includes(ext)) {
|
||||||
|
return { icon: 'ant-design:video-camera-filled', color: '#9c27b0' }
|
||||||
|
}
|
||||||
|
if (['mp3', 'wav', 'ogg', 'flac', 'aac'].includes(ext)) {
|
||||||
|
return { icon: 'ant-design:audio-filled', color: '#9c27b0' }
|
||||||
|
}
|
||||||
|
if (['txt', 'md', 'log', 'json', 'xml'].includes(ext)) {
|
||||||
|
return { icon: 'ant-design:file-text-filled', color: '#909399' }
|
||||||
|
}
|
||||||
|
return { icon: 'ant-design:file-filled', color: '#909399' }
|
||||||
|
})
|
||||||
|
|
||||||
|
/** 系统事件 / 未知类型 fallback:取 JSON 首层 content,否则原文 */
|
||||||
|
const fallbackText = computed(() => {
|
||||||
|
const raw = props.content || ''
|
||||||
|
if (!raw) {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(raw)
|
||||||
|
if (parsed && typeof parsed === 'object' && parsed.content) {
|
||||||
|
return String(parsed.content)
|
||||||
|
}
|
||||||
|
} catch {}
|
||||||
|
return raw
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
<template>
|
||||||
|
<el-dialog v-model="dialogVisible" title="群聊消息详情" width="700">
|
||||||
|
<el-descriptions :column="2" border>
|
||||||
|
<el-descriptions-item label="编号">{{ detail.id }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="客户端编号">{{ detail.clientMessageId || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="群">
|
||||||
|
{{ detail.groupName }} ({{ detail.groupId }})
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="发送人">
|
||||||
|
{{ detail.senderNickname }} ({{ detail.senderId }})
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="类型">
|
||||||
|
<dict-tag :type="DICT_TYPE.IM_MESSAGE_TYPE" :value="detail.type" />
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="状态">
|
||||||
|
<dict-tag :type="DICT_TYPE.IM_GROUP_MESSAGE_STATUS" :value="detail.status" />
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="@用户" :span="2">
|
||||||
|
<template v-if="detail.atUserIds?.length">
|
||||||
|
<span v-for="(userId, idx) in detail.atUserIds" :key="userId">
|
||||||
|
<span v-if="idx > 0">、</span>
|
||||||
|
<template v-if="userId === IM_AT_ALL_USER_ID">@{{ IM_AT_ALL_NICKNAME }}</template>
|
||||||
|
<template v-else>
|
||||||
|
@{{ detail.atUserNicknames?.[idx] || userId }}
|
||||||
|
<span class="text-gray-400">({{ userId }})</span>
|
||||||
|
</template>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
<span v-else>-</span>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="发送时间" :span="2">
|
||||||
|
{{ formatDate(detail.sendTime) }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="消息内容" :span="2">
|
||||||
|
<MessageContentPreview :type="detail.type" :content="detail.content" />
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="原始 JSON" :span="2">
|
||||||
|
<pre class="content-pre">{{ formatJson(detail.content) }}</pre>
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { formatDate } from '@/utils/formatTime'
|
||||||
|
import { DICT_TYPE } from '@/utils/dict'
|
||||||
|
import { IM_AT_ALL_NICKNAME, IM_AT_ALL_USER_ID } from '@/views/im/utils/constants'
|
||||||
|
import { formatJson } from '@/views/im/utils/message'
|
||||||
|
import * as ManagerGroupMessageApi from '@/api/im/manager/message/group'
|
||||||
|
import MessageContentPreview from '../MessageContentPreview.vue'
|
||||||
|
|
||||||
|
defineOptions({ name: 'ImGroupMessageDetailDialog' })
|
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的显示
|
||||||
|
const detail = ref<ManagerGroupMessageApi.ImManagerGroupMessageVO>(
|
||||||
|
{} as ManagerGroupMessageApi.ImManagerGroupMessageVO
|
||||||
|
) // 当前详情数据
|
||||||
|
|
||||||
|
/** 打开详情弹窗 */
|
||||||
|
const open = (row: ManagerGroupMessageApi.ImManagerGroupMessageVO) => {
|
||||||
|
detail.value = row
|
||||||
|
dialogVisible.value = true
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.content-pre {
|
||||||
|
margin: 0;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-break: break-all;
|
||||||
|
font-family: 'Menlo', 'Consolas', monospace;
|
||||||
|
font-size: 12px;
|
||||||
|
background: #f5f5f5;
|
||||||
|
padding: 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
:model="queryParams"
|
:model="queryParams"
|
||||||
ref="queryFormRef"
|
ref="queryFormRef"
|
||||||
:inline="true"
|
:inline="true"
|
||||||
label-width="80px"
|
label-width="88px"
|
||||||
>
|
>
|
||||||
<el-form-item label="群编号" prop="groupId">
|
<el-form-item label="群编号" prop="groupId">
|
||||||
<el-input
|
<el-input
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
placeholder="请输入群编号"
|
placeholder="请输入群编号"
|
||||||
clearable
|
clearable
|
||||||
@keyup.enter="handleQuery"
|
@keyup.enter="handleQuery"
|
||||||
class="!w-200px"
|
class="!w-240px"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="发送人编号" prop="senderId">
|
<el-form-item label="发送人编号" prop="senderId">
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
placeholder="请输入发送人用户编号"
|
placeholder="请输入发送人用户编号"
|
||||||
clearable
|
clearable
|
||||||
@keyup.enter="handleQuery"
|
@keyup.enter="handleQuery"
|
||||||
class="!w-200px"
|
class="!w-240px"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="消息类型" prop="type">
|
<el-form-item label="消息类型" prop="type">
|
||||||
|
|
@ -31,7 +31,7 @@
|
||||||
v-model="queryParams.type"
|
v-model="queryParams.type"
|
||||||
placeholder="请选择消息类型"
|
placeholder="请选择消息类型"
|
||||||
clearable
|
clearable
|
||||||
class="!w-160px"
|
class="!w-240px"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in getIntDictOptions(DICT_TYPE.IM_MESSAGE_TYPE)"
|
v-for="dict in getIntDictOptions(DICT_TYPE.IM_MESSAGE_TYPE)"
|
||||||
|
|
@ -46,10 +46,10 @@
|
||||||
v-model="queryParams.status"
|
v-model="queryParams.status"
|
||||||
placeholder="请选择消息状态"
|
placeholder="请选择消息状态"
|
||||||
clearable
|
clearable
|
||||||
class="!w-160px"
|
class="!w-240px"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in getIntDictOptions(DICT_TYPE.IM_MESSAGE_STATUS)"
|
v-for="dict in getIntDictOptions(DICT_TYPE.IM_GROUP_MESSAGE_STATUS)"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
:label="dict.label"
|
:label="dict.label"
|
||||||
:value="dict.value"
|
:value="dict.value"
|
||||||
|
|
@ -95,24 +95,9 @@
|
||||||
<dict-tag :type="DICT_TYPE.IM_MESSAGE_TYPE" :value="row.type" />
|
<dict-tag :type="DICT_TYPE.IM_MESSAGE_TYPE" :value="row.type" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="内容预览" align="left" min-width="240" show-overflow-tooltip>
|
<el-table-column label="内容预览" align="left" min-width="240">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
{{ getContentPreview(row.content) }}
|
<MessageContentPreview :type="row.type" :content="row.content" />
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="@" align="center" width="80">
|
|
||||||
<template #default="{ row }">
|
|
||||||
{{ row.atUserIds?.length ? row.atUserIds.length : '-' }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="回执" align="center" prop="receiptStatus" width="100">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<dict-tag :type="DICT_TYPE.IM_GROUP_MESSAGE_RECEIPT_STATUS" :value="row.receiptStatus" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="状态" align="center" prop="status" width="100">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<dict-tag :type="DICT_TYPE.IM_MESSAGE_STATUS" :value="row.status" />
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
|
|
@ -122,6 +107,31 @@
|
||||||
width="180"
|
width="180"
|
||||||
:formatter="dateFormatter"
|
:formatter="dateFormatter"
|
||||||
/>
|
/>
|
||||||
|
<el-table-column label="@用户" align="left" min-width="200" show-overflow-tooltip>
|
||||||
|
<template #default="{ row }">
|
||||||
|
<template v-if="row.atUserIds?.length">
|
||||||
|
<span v-for="(userId, idx) in row.atUserIds" :key="userId">
|
||||||
|
<span v-if="idx > 0">、</span>
|
||||||
|
<template v-if="userId === IM_AT_ALL_USER_ID">@{{ IM_AT_ALL_NICKNAME }}</template>
|
||||||
|
<template v-else>
|
||||||
|
@{{ row.atUserNicknames?.[idx] || userId }}
|
||||||
|
<span class="text-gray-400">({{ userId }})</span>
|
||||||
|
</template>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
<span v-else>-</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="回执" align="center" prop="receiptStatus" width="110">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<dict-tag :type="DICT_TYPE.IM_GROUP_MESSAGE_RECEIPT_STATUS" :value="row.receiptStatus" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="状态" align="center" prop="status" width="100">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<dict-tag :type="DICT_TYPE.IM_GROUP_MESSAGE_STATUS" :value="row.status" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column label="操作" align="center" width="100" fixed="right">
|
<el-table-column label="操作" align="center" width="100" fixed="right">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-button
|
<el-button
|
||||||
|
|
@ -135,6 +145,7 @@
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
<!-- 分页 -->
|
||||||
<Pagination
|
<Pagination
|
||||||
:total="total"
|
:total="total"
|
||||||
v-model:page="queryParams.pageNo"
|
v-model:page="queryParams.pageNo"
|
||||||
|
|
@ -143,36 +154,17 @@
|
||||||
/>
|
/>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
|
|
||||||
<!-- 详情弹窗 -->
|
<!-- 详情 -->
|
||||||
<el-dialog v-model="detailVisible" title="群聊消息详情" width="700">
|
<GroupMessageDetail ref="detailRef" />
|
||||||
<el-descriptions :column="2" border>
|
|
||||||
<el-descriptions-item label="编号">{{ detail.id }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="客户端编号">{{ detail.clientMessageId || '-' }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="群">{{ detail.groupName }} ({{ detail.groupId }})</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="发送人">{{ detail.senderNickname }} ({{ detail.senderId }})</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="类型">
|
|
||||||
<dict-tag :type="DICT_TYPE.IM_MESSAGE_TYPE" :value="detail.type" />
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="状态">
|
|
||||||
<dict-tag :type="DICT_TYPE.IM_MESSAGE_STATUS" :value="detail.status" />
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="@ 用户" :span="2">
|
|
||||||
{{ detail.atUserIds?.length ? detail.atUserIds.join(', ') : '-' }}
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="发送时间">{{ formatDate(detail.sendTime) }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="创建时间">{{ formatDate(detail.createTime) }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="消息内容(原始 JSON)" :span="2">
|
|
||||||
<pre class="content-pre">{{ formatJson(detail.content) }}</pre>
|
|
||||||
</el-descriptions-item>
|
|
||||||
</el-descriptions>
|
|
||||||
</el-dialog>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { dateFormatter, formatDate } from '@/utils/formatTime'
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
|
import { IM_AT_ALL_NICKNAME, IM_AT_ALL_USER_ID } from '@/views/im/utils/constants'
|
||||||
import * as ManagerGroupMessageApi from '@/api/im/manager/message/group'
|
import * as ManagerGroupMessageApi from '@/api/im/manager/message/group'
|
||||||
import { getContentPreview, formatJson } from '@/views/im/utils/message'
|
import MessageContentPreview from '../MessageContentPreview.vue'
|
||||||
|
import GroupMessageDetail from './GroupMessageDetail.vue'
|
||||||
|
|
||||||
defineOptions({ name: 'ImGroupMessage' })
|
defineOptions({ name: 'ImGroupMessage' })
|
||||||
|
|
||||||
|
|
@ -214,16 +206,10 @@ const resetQuery = () => {
|
||||||
handleQuery()
|
handleQuery()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 详情弹窗 */
|
|
||||||
const detailVisible = ref(false) // 详情弹窗的显示
|
|
||||||
const detail = ref<ManagerGroupMessageApi.ImManagerGroupMessageVO>(
|
|
||||||
{} as ManagerGroupMessageApi.ImManagerGroupMessageVO
|
|
||||||
) // 当前详情数据
|
|
||||||
|
|
||||||
/** 打开详情弹窗 */
|
/** 打开详情弹窗 */
|
||||||
|
const detailRef = ref<InstanceType<typeof GroupMessageDetail>>() // 详情弹窗 Ref
|
||||||
const openDetail = (row: ManagerGroupMessageApi.ImManagerGroupMessageVO) => {
|
const openDetail = (row: ManagerGroupMessageApi.ImManagerGroupMessageVO) => {
|
||||||
detail.value = row
|
detailRef.value?.open(row)
|
||||||
detailVisible.value = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 初始化 */
|
/** 初始化 */
|
||||||
|
|
@ -231,16 +217,3 @@ onMounted(() => {
|
||||||
getList()
|
getList()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.content-pre {
|
|
||||||
margin: 0;
|
|
||||||
white-space: pre-wrap;
|
|
||||||
word-break: break-all;
|
|
||||||
font-family: 'Menlo', 'Consolas', monospace;
|
|
||||||
font-size: 12px;
|
|
||||||
background: #f5f5f5;
|
|
||||||
padding: 8px;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue