2024-11-22 01:06:37 +00:00
|
|
|
|
<template>
|
|
|
|
|
<div class="outer-layer">
|
|
|
|
|
<div>
|
2024-11-22 09:00:03 +00:00
|
|
|
|
<tm-navbar :hideBack="false" hideHome title="" :leftWidth="220">
|
|
|
|
|
<div class="flex flex-col items-center justify-center">
|
|
|
|
|
<div class="text-[34rpx] font-bold">{{ talkParams.username }}</div>
|
|
|
|
|
<div v-if="true" class="text-[24rpx] text-[#999999]">公司群</div>
|
2024-11-22 01:06:37 +00:00
|
|
|
|
</div>
|
|
|
|
|
<template v-slot:right>
|
|
|
|
|
<div class="mr-[36rpx]">
|
2025-01-02 08:01:36 +00:00
|
|
|
|
<tm-icon color="rgb(51, 51, 51)" :font-size="36" name="tmicon-gengduo" @click="toChatSettingsPage"></tm-icon>
|
2024-11-22 01:06:37 +00:00
|
|
|
|
</div>
|
2024-11-22 09:00:03 +00:00
|
|
|
|
</template>
|
2024-11-22 01:06:37 +00:00
|
|
|
|
</tm-navbar>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="root">
|
2024-11-22 09:00:03 +00:00
|
|
|
|
<div class="dialogBox">
|
2024-12-19 03:02:47 +00:00
|
|
|
|
<ZPaging :fixed="false" use-chat-record-mode :use-page-scroll="false" :refresher-enabled="false"
|
|
|
|
|
:show-scrollbar="false" :loading-more-enabled="false" :hide-empty-view="true" height="100%" ref="zpagingRef"
|
2024-12-20 08:59:58 +00:00
|
|
|
|
:use-virtual-list="true" :preload-page="1" cell-height-mode="dynamic" virtual-scroll-fps="80"
|
2024-12-19 03:02:47 +00:00
|
|
|
|
:loading-more-custom-style="{ display: 'none', height: '0' }" @virtualListChange="virtualListChange"
|
|
|
|
|
@scrolltolower="onRefreshLoad">
|
2024-12-06 08:55:15 +00:00
|
|
|
|
<!-- <template #top>
|
|
|
|
|
<div class="load-toolbar pointer">
|
|
|
|
|
<span v-if="loadConfig.status == 0"> 正在加载数据中 ... </span>
|
|
|
|
|
<span v-else-if="loadConfig.status == 1" @click="onRefreshLoad"> 查看更多消息 ... </span>
|
|
|
|
|
<span v-else class="no-more"> 没有更多消息了 </span>
|
|
|
|
|
</div>
|
|
|
|
|
</template> -->
|
|
|
|
|
|
2024-11-26 08:51:36 +00:00
|
|
|
|
<!-- 数据加载状态栏 -->
|
2024-12-19 03:02:47 +00:00
|
|
|
|
<div class="message-item" v-for="item in virtualList" :id="`zp-id-${item.zp_index}`" :key="item.zp_index"
|
|
|
|
|
style="transform: scaleY(-1);">
|
2024-11-26 08:51:36 +00:00
|
|
|
|
<!-- 系统消息 -->
|
|
|
|
|
<div v-if="item.msg_type >= 1000" class="message-box">
|
|
|
|
|
<component :is="MessageComponents[item.msg_type] || 'unknown-message'" :extra="item.extra" :data="item" />
|
|
|
|
|
</div>
|
|
|
|
|
<!-- 撤回消息 -->
|
|
|
|
|
<div v-else-if="item.is_revoke == 1" class="message-box">
|
2024-12-06 08:55:15 +00:00
|
|
|
|
<revoke-message :login_uid="userStore.uid" :user_id="item.user_id" :nickname="item.nickname"
|
2024-11-26 08:51:36 +00:00
|
|
|
|
:talk_type="item.talk_type" :datetime="item.created_at" />
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div v-else class="message-box record-box" :class="{
|
|
|
|
|
'direction-rt': item.float == 'right',
|
|
|
|
|
'multi-select': dialogueStore.isOpenMultiSelect,
|
|
|
|
|
'multi-select-check': item.isCheck
|
|
|
|
|
}">
|
|
|
|
|
<!-- 多选按钮 -->
|
2024-12-19 03:02:47 +00:00
|
|
|
|
<aside v-if="dialogueStore.isOpenMultiSelect" class="checkbox-column">
|
|
|
|
|
<!-- <n-checkbox size="small" :checked="item.isCheck" @update:checked="item.isCheck = !item.isCheck" /> -->
|
|
|
|
|
<tm-checkbox :round="10" :defaultChecked="item.isCheck"
|
|
|
|
|
@update:modelValue="item.isCheck = !item.isCheck" :size="42" color="#46299D"></tm-checkbox>
|
|
|
|
|
</aside>
|
2024-11-26 08:51:36 +00:00
|
|
|
|
|
|
|
|
|
<!-- 头像信息 -->
|
|
|
|
|
<aside class="avatar-column">
|
|
|
|
|
<im-avatar class="pointer" :src="item.avatar" :size="80" :username="item.nickname"
|
|
|
|
|
@click="showUserInfoModal(item.user_id)" />
|
|
|
|
|
</aside>
|
|
|
|
|
|
|
|
|
|
<!-- 主体信息 -->
|
|
|
|
|
<main class="main-column">
|
|
|
|
|
<div class="talk-title">
|
2024-12-06 08:55:15 +00:00
|
|
|
|
<span class="nickname pointer" v-show="talkParams.type == 2 && item.float == 'left'"
|
2024-11-26 08:51:36 +00:00
|
|
|
|
@click="onClickNickname(item)">
|
|
|
|
|
<span class="at">@</span>{{ item.nickname }}
|
|
|
|
|
</span>
|
|
|
|
|
<span>{{ parseTime(item.created_at, '{m}/{d} {h}:{i}') }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="talk-content" :class="{ pointer: dialogueStore.isOpenMultiSelect }">
|
2024-12-24 08:28:44 +00:00
|
|
|
|
<deepBubble
|
2024-12-20 08:59:58 +00:00
|
|
|
|
@clickMenu="(menuType) => onContextMenu(menuType, item)"
|
|
|
|
|
:isShowCopy="isShowCopy(item)"
|
|
|
|
|
:isShowWithdraw="isRevoke(talkParams.uid,item)"
|
|
|
|
|
>
|
|
|
|
|
<component class="component-content" :key="item.zp_index"
|
|
|
|
|
:is="MessageComponents[item.msg_type] || 'unknown-message'" :extra="item.extra" :data="item"
|
|
|
|
|
:max-width="true" :source="'panel'" />
|
|
|
|
|
</deepBubble>
|
2024-12-06 08:55:15 +00:00
|
|
|
|
<!-- <div class="talk-tools">
|
|
|
|
|
<template v-if="talkParams.type == 1 && item.float == 'right'">
|
2024-12-19 03:02:47 +00:00
|
|
|
|
<loading theme="outline" size="19" fill="#000" :sxtrokeWidth="1" class="icon-rotate"
|
2024-11-26 08:51:36 +00:00
|
|
|
|
v-show="item.send_status == 1" />
|
2024-11-22 09:00:03 +00:00
|
|
|
|
|
2024-11-26 08:51:36 +00:00
|
|
|
|
<span v-show="item.send_status == 1"> 正在发送... </span>
|
2024-12-06 08:55:15 +00:00
|
|
|
|
<span v-show="item.send_status != 1"> 已送达 </span>
|
2024-11-26 08:51:36 +00:00
|
|
|
|
</template>
|
|
|
|
|
|
2024-12-06 08:55:15 +00:00
|
|
|
|
</div> -->
|
2024-11-22 09:00:03 +00:00
|
|
|
|
</div>
|
2024-11-22 01:06:37 +00:00
|
|
|
|
|
2024-11-26 08:51:36 +00:00
|
|
|
|
<div v-if="item.extra.reply" class="talk-reply pointer"
|
|
|
|
|
@click="onJumpMessage(item.extra?.reply?.msg_id)">
|
2024-11-28 08:55:45 +00:00
|
|
|
|
<!-- <n-icon :component="ToTop" size="14" class="icon-top" /> -->
|
2024-11-26 08:51:36 +00:00
|
|
|
|
<span class="ellipsis">
|
|
|
|
|
回复 {{ item.extra?.reply?.nickname }}:
|
|
|
|
|
{{ item.extra?.reply?.content }}
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
</main>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
<div class="load-toolbar pointer" style="transform: scaleY(-1);">
|
2024-12-19 03:02:47 +00:00
|
|
|
|
<span v-if="loadConfig.status == 0"> 正在加载数据中 ... </span>
|
|
|
|
|
<span v-else-if="loadConfig.status == 1" @click="onRefreshLoad"> 查看更多消息 ... </span>
|
|
|
|
|
<span v-else class="no-more"> 没有更多消息了 </span>
|
|
|
|
|
</div>
|
2024-12-06 08:55:15 +00:00
|
|
|
|
|
2024-11-26 08:51:36 +00:00
|
|
|
|
</ZPaging>
|
2024-11-22 01:06:37 +00:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2024-11-22 09:00:03 +00:00
|
|
|
|
<div class="footBox">
|
2024-12-19 03:02:47 +00:00
|
|
|
|
<div v-if="!dialogueStore.isOpenMultiSelect">
|
|
|
|
|
<div class="mt-[16rpx] ml-[32rpx] mr-[32rpx] flex items-center justify-between">
|
|
|
|
|
<div class="flex-1 quillBox">
|
|
|
|
|
<QuillEditor ref="editor" id="editor" :options="editorOption" @editorChange="onEditorChange"
|
|
|
|
|
style="height: 100%; border: none" />
|
|
|
|
|
<!-- <tm-input type=textarea autoHeight focusColor="#F9F9F9" color="#F9F9F9" :inputPadding="[12]"
|
|
|
|
|
placeholder=""></tm-input> -->
|
|
|
|
|
</div>
|
|
|
|
|
<tm-image :margin="[10, 0]" @click="handleEmojiPanel" :width="52" :height="52" :round="12"
|
|
|
|
|
:src="state.isOpenEmojiPanel ? keyboard : smile"></tm-image>
|
|
|
|
|
<tm-image @click="handleFilePanel" :margin="[10, 0]" :width="52" :height="52" :round="12"
|
|
|
|
|
:src="addCircleGray"></tm-image>
|
|
|
|
|
<tm-button @click="onSendMessageClick" :margin="[0, 0]" :padding="[0, 30]" color="#46299D" :fontSize="28"
|
|
|
|
|
size="mini" :shadow="0" label="发送"></tm-button>
|
|
|
|
|
</div>
|
|
|
|
|
<div v-if="state.isOpenEmojiPanel" class="mt-[50rpx]">
|
|
|
|
|
<emojiPanel @on-select="onEmoticonEvent" />
|
|
|
|
|
</div>
|
|
|
|
|
<div v-if="state.isOpenFilePanel" class="mt-[16rpx]">
|
|
|
|
|
<filePanel @selectImg="handleSelectImg" :talkParams="talkParams" />
|
|
|
|
|
|
2024-11-22 01:06:37 +00:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2024-12-19 03:02:47 +00:00
|
|
|
|
<div v-else class="h-[232rpx]">
|
|
|
|
|
<div class="flex items-center justify-center mt-[12rpx] text-[24rpx] text-[#747474] leading-[44rpx]">
|
|
|
|
|
<div class="mr-[8rpx]">已选中:</div>
|
|
|
|
|
<div>{{ selectedMessage.length }}条消息</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="flex items-center justify-around pl-[128rpx] pr-[128rpx] mt-[18rpx] text-[20rpx] text-[#737373] ">
|
|
|
|
|
<div @click="handleMergeForward" class="flex flex-col items-center justify-center">
|
|
|
|
|
<tm-image :width="68" :height="68" :src="zu6050"></tm-image>
|
|
|
|
|
<div class="mt-[6rpx]">合并转发</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div @click="handleSingleForward" class="flex flex-col items-center justify-center">
|
|
|
|
|
<tm-image :width="68" :height="68" :src="zu6051"></tm-image>
|
|
|
|
|
<div class="mt-[6rpx]">逐条转发</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div @click="handleWechatForward" class="flex flex-col items-center justify-center">
|
|
|
|
|
<tm-image :width="68" :height="68" :src="zu6052"></tm-image>
|
|
|
|
|
<div class="mt-[6rpx]">微信</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div @click="handleDelete" class="flex flex-col items-center justify-center">
|
|
|
|
|
<tm-image :width="68" :height="68" :src="zu6053"></tm-image>
|
|
|
|
|
<div class="mt-[6rpx]">删除</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2024-12-06 08:55:15 +00:00
|
|
|
|
</div>
|
|
|
|
|
|
2024-11-26 08:51:36 +00:00
|
|
|
|
<!--底部安全区-->
|
|
|
|
|
<div class="content-placeholder"></div>
|
2024-12-24 08:28:44 +00:00
|
|
|
|
<tm-drawer
|
|
|
|
|
placement="bottom"
|
|
|
|
|
v-model:show="state.showWin"
|
|
|
|
|
:hideHeader="true"
|
|
|
|
|
:height="416"
|
|
|
|
|
:round="6"
|
|
|
|
|
>
|
|
|
|
|
<div class="w-full h-full flex flex-col items-center" >
|
|
|
|
|
<div class="mt-[46rpx] mb-[44rpx] leading-[48rpx] text-[#747474] text-[24rpx]" >
|
|
|
|
|
撤回该条消息?
|
|
|
|
|
</div>
|
|
|
|
|
<div class="divider" ></div>
|
|
|
|
|
<div @click="withdrawerConfirm" class="mt-[32rpx] mb-[32rpx] text-[32rpx] text-[#CF3050] leading-[48rpx]">
|
|
|
|
|
撤回
|
|
|
|
|
</div>
|
|
|
|
|
<div class="divider" ></div>
|
|
|
|
|
<div @click="state.showWin = false" class="mt-[32rpx] mb-[32rpx] text-[32rpx] text-[#000000] leading-[48rpx]">
|
|
|
|
|
取消
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</tm-drawer>
|
2024-11-22 01:06:37 +00:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<script setup>
|
2024-12-19 03:02:47 +00:00
|
|
|
|
import { ref, reactive, watch, computed, onMounted, onUnmounted, nextTick } from 'vue';
|
2024-11-26 08:51:36 +00:00
|
|
|
|
import { QuillEditor, Quill } from '@vueup/vue-quill'
|
2024-11-28 08:55:45 +00:00
|
|
|
|
import EmojiBlot from './formats/emoji'
|
2024-11-22 01:06:37 +00:00
|
|
|
|
import { useChatList } from "@/store/chatList/index.js";
|
2024-11-22 09:00:03 +00:00
|
|
|
|
import { useAuth } from "@/store/auth";
|
2024-12-20 08:59:58 +00:00
|
|
|
|
import {
|
|
|
|
|
useUserStore,
|
|
|
|
|
useDialogueStore,
|
|
|
|
|
useUploadsStore,
|
|
|
|
|
useEditorDraftStore,
|
|
|
|
|
useTalkStore,
|
|
|
|
|
useSettingsStore,
|
|
|
|
|
useDialogueListStore
|
|
|
|
|
} from '@/store'
|
2024-11-22 01:06:37 +00:00
|
|
|
|
import addCircleGray from "@/static/image/chatList/addCircleGray.png";
|
|
|
|
|
import { MessageComponents, ForwardableMessageType } from '@/constant/message'
|
2024-11-22 09:00:03 +00:00
|
|
|
|
import { formatTime, parseTime } from '@/utils/datetime'
|
2024-11-26 08:51:36 +00:00
|
|
|
|
import { deltaToMessage, deltaToString, isEmptyDelta } from './util'
|
2024-11-22 01:06:37 +00:00
|
|
|
|
import smile from "@/static/image/chatList/smile@2x.png";
|
2024-11-26 08:51:36 +00:00
|
|
|
|
import keyboard from "@/static/image/chatList/keyboard@2x.png";
|
2024-11-22 01:06:37 +00:00
|
|
|
|
import { useInject, useTalkRecord } from '@/hooks'
|
2024-11-28 08:55:45 +00:00
|
|
|
|
import { emitCall } from '@/utils/common'
|
2024-11-26 08:51:36 +00:00
|
|
|
|
import ZPaging from "@/uni_modules/z-paging/components/z-paging/z-paging.vue";
|
|
|
|
|
import useZPaging from "@/uni_modules/z-paging/components/z-paging/js/hooks/useZPaging.js";
|
|
|
|
|
import emojiPanel from './components/emojiPanel.vue'
|
2024-12-06 08:55:15 +00:00
|
|
|
|
import filePanel from './components/filePanel.vue'
|
2024-11-28 08:55:45 +00:00
|
|
|
|
import lodash from "lodash";
|
|
|
|
|
import { ServePublishMessage } from '@/api/chat'
|
2024-12-19 03:02:47 +00:00
|
|
|
|
import copy07 from "@/static/image/chatList/copy07@2x.png"
|
|
|
|
|
import multipleChoices from "@/static/image/chatList/multipleChoices@2x.png"
|
|
|
|
|
import cite from "@/static/image/chatList/cite@2x.png"
|
|
|
|
|
import withdraw from "@/static/image/chatList/withdraw@2x.png"
|
|
|
|
|
import delete07 from "@/static/image/chatList/delete@2x.png"
|
|
|
|
|
import zu6050 from "@/static/image/chatList/zu6050@2x.png"
|
|
|
|
|
import zu6051 from "@/static/image/chatList/zu6051@2x.png"
|
|
|
|
|
import zu6052 from "@/static/image/chatList/zu6052@2x.png"
|
|
|
|
|
import zu6053 from "@/static/image/chatList/zu6053@2x.png"
|
2024-12-20 08:59:58 +00:00
|
|
|
|
import deepBubble from "@/components/deep-bubble/deep-bubble.vue"
|
|
|
|
|
import {isRevoke } from './menu'
|
2024-12-24 08:28:44 +00:00
|
|
|
|
import useConfirm from '@/components/x-confirm/useConfirm.js'
|
2025-01-06 10:55:00 +00:00
|
|
|
|
import { onLoad as uniOnload } from '@dcloudio/uni-app'
|
2024-11-22 01:06:37 +00:00
|
|
|
|
|
2024-11-28 08:55:45 +00:00
|
|
|
|
Quill.register('formats/emoji', EmojiBlot)
|
|
|
|
|
|
2024-12-19 03:02:47 +00:00
|
|
|
|
const { getDialogueList, updateZpagingRef, virtualList } = useDialogueListStore()
|
2024-11-28 08:55:45 +00:00
|
|
|
|
const talkStore = useTalkStore()
|
2024-12-24 08:28:44 +00:00
|
|
|
|
const { showConfirm } = useConfirm();
|
2024-11-28 08:55:45 +00:00
|
|
|
|
const settingsStore = useSettingsStore()
|
2024-11-22 01:06:37 +00:00
|
|
|
|
const userStore = useUserStore()
|
|
|
|
|
const dialogueStore = useDialogueStore()
|
2024-11-26 08:51:36 +00:00
|
|
|
|
const editorDraftStore = useEditorDraftStore()
|
|
|
|
|
const editor = ref()
|
2024-12-10 03:31:36 +00:00
|
|
|
|
const zpagingRef = ref()
|
2024-12-06 08:55:15 +00:00
|
|
|
|
useZPaging(zpagingRef)
|
2024-11-26 08:51:36 +00:00
|
|
|
|
const indexName = computed(() => dialogueStore.index_name)
|
2024-11-22 01:06:37 +00:00
|
|
|
|
const talkParams = reactive({
|
|
|
|
|
uid: computed(() => userStore.uid),
|
|
|
|
|
index_name: computed(() => dialogueStore.index_name),
|
|
|
|
|
type: computed(() => dialogueStore.talk.talk_type),
|
|
|
|
|
receiver_id: computed(() => dialogueStore.talk.receiver_id),
|
|
|
|
|
username: computed(() => dialogueStore.talk.username),
|
|
|
|
|
online: computed(() => dialogueStore.online),
|
|
|
|
|
keyboard: computed(() => dialogueStore.keyboard),
|
|
|
|
|
num: computed(() => dialogueStore.members.length)
|
|
|
|
|
})
|
|
|
|
|
|
2024-11-26 08:51:36 +00:00
|
|
|
|
const state = ref({
|
2024-12-06 08:55:15 +00:00
|
|
|
|
isOpenEmojiPanel: false,
|
2024-12-19 03:02:47 +00:00
|
|
|
|
isOpenFilePanel: false,
|
2024-12-24 08:28:44 +00:00
|
|
|
|
showWin: false,
|
|
|
|
|
onfocusItem: null,
|
2025-01-06 10:55:00 +00:00
|
|
|
|
sessionId: ''
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
uniOnload((options) => {
|
|
|
|
|
if (options.sessionId) {
|
|
|
|
|
state.sessionId = options.sessionId
|
|
|
|
|
}
|
2024-11-26 08:51:36 +00:00
|
|
|
|
})
|
|
|
|
|
|
2024-12-06 08:55:15 +00:00
|
|
|
|
const handleEmojiPanel = () => {
|
|
|
|
|
state.value.isOpenFilePanel = false;
|
|
|
|
|
state.value.isOpenEmojiPanel = !state.value.isOpenEmojiPanel
|
|
|
|
|
}
|
|
|
|
|
const handleFilePanel = () => {
|
|
|
|
|
state.value.isOpenEmojiPanel = false;
|
|
|
|
|
state.value.isOpenFilePanel = !state.value.isOpenFilePanel
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-13 05:09:38 +00:00
|
|
|
|
const onSendMessage = (data = {}) => {
|
2024-11-28 08:55:45 +00:00
|
|
|
|
let message = {
|
|
|
|
|
...data,
|
|
|
|
|
receiver: {
|
|
|
|
|
receiver_id: talkParams.receiver_id,
|
|
|
|
|
talk_type: talkParams.type
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ServePublishMessage(message)
|
|
|
|
|
.then(({ code, message }) => {
|
|
|
|
|
if (code == 200) {
|
2024-12-13 05:09:38 +00:00
|
|
|
|
// callBack(true)
|
2024-11-28 08:55:45 +00:00
|
|
|
|
} else {
|
|
|
|
|
message.warning(message)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch(() => {
|
|
|
|
|
message.warning('网络繁忙,请稍后重试!')
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const onSendMessageClick = () => {
|
|
|
|
|
let delta = getQuill().getContents()
|
|
|
|
|
let data = deltaToMessage(delta)
|
|
|
|
|
|
|
|
|
|
if (data.items.length === 0) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (data.msgType) {
|
|
|
|
|
case 1: // 文字消息
|
|
|
|
|
if (data.items[0].content.length > 1024) {
|
|
|
|
|
return message.info('发送内容超长,请分条发送')
|
|
|
|
|
}
|
2024-12-19 03:02:47 +00:00
|
|
|
|
onSendTextEvent({
|
|
|
|
|
data, callBack: (ok) => {
|
|
|
|
|
if (!ok) return
|
|
|
|
|
getQuill().setContents([], Quill.sources.USER)
|
|
|
|
|
}
|
|
|
|
|
})
|
2024-11-28 08:55:45 +00:00
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 发送文本消息
|
|
|
|
|
const onSendTextEvent = lodash.throttle((value) => {
|
|
|
|
|
let { data, callBack } = value
|
|
|
|
|
|
|
|
|
|
let message = {
|
|
|
|
|
type: 'text',
|
|
|
|
|
content: data.items[0].content,
|
|
|
|
|
quote_id: data.quoteId,
|
|
|
|
|
mentions: data.mentionUids
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-13 05:09:38 +00:00
|
|
|
|
onSendMessage(message)
|
2024-11-28 08:55:45 +00:00
|
|
|
|
}, 1000)
|
|
|
|
|
|
|
|
|
|
// 编辑器输入事件
|
|
|
|
|
const onInputEvent = ({ data }) => {
|
|
|
|
|
talkStore.updateItem({
|
|
|
|
|
index_name: indexName.value,
|
|
|
|
|
draft_text: data
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// 判断对方是否在线和是否需要推送
|
|
|
|
|
// 3秒时间内推送一次
|
|
|
|
|
if (settingsStore.isKeyboard && props.online) {
|
|
|
|
|
onKeyboardPush()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 发送表情消息
|
2024-12-13 05:09:38 +00:00
|
|
|
|
const onSendEmoticonEvent = ({ data }) => {
|
|
|
|
|
onSendMessage({ type: 'emoticon', emoticon_id: data })
|
2024-11-28 08:55:45 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 注册事件
|
|
|
|
|
const evnets = {
|
|
|
|
|
text_event: onSendTextEvent,
|
|
|
|
|
input_event: onInputEvent,
|
|
|
|
|
emoticon_event: onSendEmoticonEvent,
|
|
|
|
|
history_event: () => {
|
|
|
|
|
isShowHistory.value = true
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-22 01:06:37 +00:00
|
|
|
|
const { loadConfig, records, onLoad, onRefreshLoad, onJumpMessage } = useTalkRecord(talkParams.uid)
|
2024-11-26 08:51:36 +00:00
|
|
|
|
|
|
|
|
|
const getQuill = () => {
|
|
|
|
|
return editor.value?.getQuill()
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-20 08:59:58 +00:00
|
|
|
|
const isShowCopy = (item) => {
|
|
|
|
|
switch (item.msg_type) {
|
|
|
|
|
case 1:
|
|
|
|
|
return true
|
|
|
|
|
case 3:
|
|
|
|
|
return true
|
|
|
|
|
case 5:
|
|
|
|
|
return true
|
|
|
|
|
case 6:
|
|
|
|
|
return true
|
|
|
|
|
default:
|
|
|
|
|
return false
|
|
|
|
|
}
|
2024-12-24 08:28:44 +00:00
|
|
|
|
|
2024-12-20 08:59:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-12-19 03:02:47 +00:00
|
|
|
|
const selectedMessage = computed(() => {
|
|
|
|
|
return virtualList.value.filter(item => item.isCheck)
|
|
|
|
|
})
|
|
|
|
|
|
2024-11-28 08:55:45 +00:00
|
|
|
|
// 编辑器事件
|
|
|
|
|
const onEditorEvent = (msg) => {
|
|
|
|
|
evnets[msg.event] && evnets[msg.event](msg)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const getQuillSelectionIndex = () => {
|
|
|
|
|
let quill = getQuill()
|
|
|
|
|
return (quill.getSelection() || {}).index
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const onEmoticonEvent = (data) => {
|
|
|
|
|
if (data.type == 1) {
|
|
|
|
|
const quill = getQuill()
|
|
|
|
|
let index = getQuillSelectionIndex()
|
|
|
|
|
|
|
|
|
|
if (index == 1 && quill.getLength() == 1 && quill.getText(0, 1) == '\n') {
|
|
|
|
|
quill.deleteText(0, 1)
|
|
|
|
|
index = 0
|
|
|
|
|
}
|
|
|
|
|
if (data.img) {
|
|
|
|
|
quill.insertEmbed(index, 'emoji', {
|
|
|
|
|
alt: data.value,
|
|
|
|
|
src: data.img,
|
|
|
|
|
})
|
|
|
|
|
} else {
|
|
|
|
|
quill.insertText(index, data.value)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
quill.setSelection(index + 1, 0, 'user')
|
|
|
|
|
} else {
|
2024-12-19 03:02:47 +00:00
|
|
|
|
let fn = emitCall('emoticon_event', data.value, () => { })
|
2024-11-28 08:55:45 +00:00
|
|
|
|
emit('editor-event', fn)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-26 08:51:36 +00:00
|
|
|
|
const onEditorChange = () => {
|
|
|
|
|
let delta = getQuill().getContents()
|
|
|
|
|
|
|
|
|
|
let text = deltaToString(delta)
|
|
|
|
|
|
|
|
|
|
if (!isEmptyDelta(delta)) {
|
|
|
|
|
editorDraftStore.items[indexName.value || ''] = JSON.stringify({
|
|
|
|
|
text: text,
|
|
|
|
|
ops: delta.ops
|
|
|
|
|
})
|
|
|
|
|
} else {
|
|
|
|
|
// 删除 editorDraftStore.items 下的元素
|
|
|
|
|
delete editorDraftStore.items[indexName.value || '']
|
|
|
|
|
}
|
2024-11-28 08:55:45 +00:00
|
|
|
|
onEditorEvent(emitCall('input_event', text))
|
2024-11-26 08:51:36 +00:00
|
|
|
|
// emit('editor-event', emitCall('input_event', text))
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-28 08:55:45 +00:00
|
|
|
|
const onClipboardMatcher = (node, Delta) => {
|
|
|
|
|
const ops = []
|
|
|
|
|
|
|
|
|
|
Delta.ops.forEach((op) => {
|
|
|
|
|
// 如果粘贴了图片,这里会是一个对象,所以可以这样处理
|
|
|
|
|
if (op.insert && typeof op.insert === 'string') {
|
|
|
|
|
ops.push({
|
|
|
|
|
insert: op.insert, // 文字内容
|
|
|
|
|
attributes: {} //文字样式(包括背景色和文字颜色等)
|
|
|
|
|
})
|
|
|
|
|
} else {
|
|
|
|
|
ops.push(op)
|
|
|
|
|
}
|
|
|
|
|
})
|
2024-11-26 08:51:36 +00:00
|
|
|
|
|
2024-11-28 08:55:45 +00:00
|
|
|
|
Delta.ops = ops
|
|
|
|
|
return Delta
|
2024-11-26 08:51:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const editorOption = {
|
|
|
|
|
debug: false,
|
|
|
|
|
modules: {
|
|
|
|
|
toolbar: false,
|
2024-11-28 08:55:45 +00:00
|
|
|
|
clipboard: {
|
|
|
|
|
// 粘贴版,处理粘贴时候的自带样式
|
|
|
|
|
matchers: [[Node.ELEMENT_NODE, onClipboardMatcher]]
|
|
|
|
|
},
|
2024-11-26 08:51:36 +00:00
|
|
|
|
|
|
|
|
|
keyboard: {
|
|
|
|
|
bindings: {
|
|
|
|
|
enter: {
|
|
|
|
|
key: 13,
|
2024-12-13 05:09:38 +00:00
|
|
|
|
handler: onSendMessageClick
|
2024-11-26 08:51:36 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// imageUploader: {
|
|
|
|
|
// upload: onEditorUpload
|
|
|
|
|
// },
|
|
|
|
|
|
|
|
|
|
// mention: {
|
|
|
|
|
// allowedChars: /^[\u4e00-\u9fa5]*$/,
|
|
|
|
|
// mentionDenotationChars: ['@'],
|
|
|
|
|
// positioningStrategy: 'fixed',
|
|
|
|
|
// renderItem: (data) => {
|
|
|
|
|
// const el = document.createElement('div')
|
|
|
|
|
// el.className = 'ed-member-item'
|
|
|
|
|
// el.innerHTML = `<img src="${data.avatar}" class="avator"/>`
|
|
|
|
|
// el.innerHTML += `<span class="nickname">${data.nickname}</span>`
|
|
|
|
|
// return el
|
|
|
|
|
// },
|
|
|
|
|
// source: function (searchTerm, renderList) {
|
|
|
|
|
// if (!props.members.length) {
|
|
|
|
|
// return renderList([])
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// let list = [
|
|
|
|
|
// { id: 0, nickname: '所有人', avatar: defAvatar, value: '所有人' },
|
|
|
|
|
// ...props.members
|
|
|
|
|
// ]
|
|
|
|
|
|
|
|
|
|
// const items = list.filter(
|
|
|
|
|
// (item) => item.nickname.toLowerCase().indexOf(searchTerm) !== -1
|
|
|
|
|
// )
|
|
|
|
|
|
|
|
|
|
// renderList(items)
|
|
|
|
|
// },
|
|
|
|
|
// mentionContainerClass: 'ql-mention-list-container me-scrollbar me-scrollbar-thumb'
|
|
|
|
|
// }
|
|
|
|
|
},
|
|
|
|
|
placeholder: '',
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-06 08:55:15 +00:00
|
|
|
|
const handleSelectImg = (data) => {
|
2024-12-13 05:09:38 +00:00
|
|
|
|
onSendMessage({ ...data })
|
2024-12-06 08:55:15 +00:00
|
|
|
|
}
|
2024-11-26 08:51:36 +00:00
|
|
|
|
|
2024-12-06 08:55:15 +00:00
|
|
|
|
const virtualListChange = (vList) => {
|
|
|
|
|
virtualList.value = vList
|
|
|
|
|
}
|
2024-11-26 08:51:36 +00:00
|
|
|
|
|
2024-12-20 08:59:58 +00:00
|
|
|
|
const onContextMenu = (menuType, item) => {
|
|
|
|
|
console.log(menuType, item, 'item');
|
|
|
|
|
switch (menuType) {
|
|
|
|
|
case 'actionCopy':
|
|
|
|
|
actionCopy(item)
|
|
|
|
|
break;
|
|
|
|
|
case 'multipleChoose':
|
|
|
|
|
multipleChoose(item)
|
|
|
|
|
break;
|
|
|
|
|
case 'actionCite':
|
|
|
|
|
actionCite(item)
|
|
|
|
|
break;
|
|
|
|
|
case 'actionWithdraw':
|
|
|
|
|
actionWithdraw(item)
|
|
|
|
|
break;
|
|
|
|
|
case 'actionDelete':
|
|
|
|
|
actionDelete(item)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
2024-12-19 03:02:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const actionCopy = (item) => {
|
|
|
|
|
console.log('复制');
|
|
|
|
|
let content = ''
|
|
|
|
|
switch (item.msg_type) {
|
|
|
|
|
case 1:
|
|
|
|
|
content = item.extra.content
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
|
|
|
|
content = item.extra.url
|
|
|
|
|
break;
|
|
|
|
|
case 5:
|
|
|
|
|
content = item.extra.url
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
uni.setClipboardData({
|
|
|
|
|
data: content,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const multipleChoose = (item) => {
|
|
|
|
|
item.isCheck = true
|
|
|
|
|
dialogueStore.setMultiSelect(true)
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-20 08:59:58 +00:00
|
|
|
|
const actionCite = (item) => {
|
2024-12-19 03:02:47 +00:00
|
|
|
|
console.log('引用');
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-20 08:59:58 +00:00
|
|
|
|
const actionWithdraw = (item) => {
|
2024-12-19 03:02:47 +00:00
|
|
|
|
console.log('撤回');
|
2024-12-24 08:28:44 +00:00
|
|
|
|
state.value.onfocusItem = item
|
|
|
|
|
state.value.showWin = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const withdrawerConfirm = () => {
|
|
|
|
|
dialogueStore.ApiRevokeRecord(state.value.onfocusItem.msg_id)
|
|
|
|
|
state.value.onfocusItem = null
|
|
|
|
|
state.value.showWin = false;
|
2024-12-19 03:02:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-12-20 08:59:58 +00:00
|
|
|
|
const actionDelete = (item) => {
|
2024-12-19 03:02:47 +00:00
|
|
|
|
console.log('删除');
|
2024-12-20 08:59:58 +00:00
|
|
|
|
item.isCheck = true
|
|
|
|
|
handleDelete()
|
2024-12-19 03:02:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const handleMergeForward = () => {
|
|
|
|
|
if (selectedMessage.value.length == 0) {
|
|
|
|
|
return message.warning('未选择消息')
|
|
|
|
|
}
|
|
|
|
|
console.log('合并转发');
|
|
|
|
|
dialogueStore.setForwardType(2)
|
|
|
|
|
dialogueStore.setForwardMessages(selectedMessage.value)
|
|
|
|
|
uni.navigateTo({
|
|
|
|
|
url: '/pages/chooseChat/index',
|
|
|
|
|
success: function (res) {
|
|
|
|
|
clearMultiSelect()
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const handleSingleForward = () => {
|
|
|
|
|
if (selectedMessage.value.length == 0) {
|
|
|
|
|
return message.warning('未选择消息')
|
|
|
|
|
}
|
|
|
|
|
console.log('逐条转发');
|
2024-12-20 08:59:58 +00:00
|
|
|
|
dialogueStore.setForwardType(1)
|
|
|
|
|
dialogueStore.setForwardMessages(selectedMessage.value)
|
|
|
|
|
uni.navigateTo({
|
|
|
|
|
url: '/pages/chooseChat/index',
|
|
|
|
|
success: function (res) {
|
|
|
|
|
clearMultiSelect()
|
|
|
|
|
}
|
|
|
|
|
})
|
2024-12-19 03:02:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const handleWechatForward = () => {
|
|
|
|
|
if (selectedMessage.value.length == 0) {
|
|
|
|
|
return message.warning('未选择消息')
|
|
|
|
|
}
|
|
|
|
|
console.log('微信转发');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const handleDelete = () => {
|
|
|
|
|
if (selectedMessage.value.length == 0) {
|
|
|
|
|
return message.warning('未选择消息')
|
|
|
|
|
}
|
|
|
|
|
console.log('删除');
|
2024-12-24 08:28:44 +00:00
|
|
|
|
showConfirm({
|
|
|
|
|
content: '确定删除聊天记录',
|
|
|
|
|
confirmText:'删除',
|
|
|
|
|
confirmColor:'#CF3050',
|
|
|
|
|
onConfirm: async () => {
|
|
|
|
|
const msgIds = selectedMessage.value.map(item => item.msg_id)
|
|
|
|
|
virtualList.value = virtualList.value.filter(item => !msgIds.includes(item.msg_id))
|
|
|
|
|
dialogueStore.ApiDeleteRecord(msgIds)
|
|
|
|
|
clearMultiSelect()
|
|
|
|
|
},
|
|
|
|
|
onCancel: () => {
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
2024-12-19 03:02:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-12-06 08:55:15 +00:00
|
|
|
|
|
2024-12-10 03:31:36 +00:00
|
|
|
|
watch(() => zpagingRef.value, (newValue, oldValue) => {
|
|
|
|
|
if (newValue) {
|
|
|
|
|
updateZpagingRef(newValue)
|
|
|
|
|
}
|
|
|
|
|
})
|
2024-11-22 01:06:37 +00:00
|
|
|
|
|
2024-12-19 03:02:47 +00:00
|
|
|
|
const clearMultiSelect = () => {
|
|
|
|
|
dialogueStore.setMultiSelect(false)
|
|
|
|
|
virtualList.value.forEach(item => {
|
|
|
|
|
item.isCheck = false
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const initData = async () => {
|
2024-12-10 03:31:36 +00:00
|
|
|
|
const dialogueList = getDialogueList(talkParams.index_name)
|
2024-11-22 01:06:37 +00:00
|
|
|
|
|
|
|
|
|
let objT = {
|
|
|
|
|
uid: talkParams.uid,
|
|
|
|
|
talk_type: talkParams.type,
|
|
|
|
|
receiver_id: talkParams.receiver_id,
|
2024-12-06 08:55:15 +00:00
|
|
|
|
index_name: talkParams.index_name,
|
2024-12-19 03:02:47 +00:00
|
|
|
|
direction: dialogueList ? 'down' : 'up',
|
|
|
|
|
no_limit: dialogueList ? 1 : 0,
|
2024-11-22 01:06:37 +00:00
|
|
|
|
}
|
2024-12-10 03:31:36 +00:00
|
|
|
|
await onLoad({ ...objT })
|
2024-12-13 05:09:38 +00:00
|
|
|
|
zpagingRef.value?.complete(records.value)
|
2024-12-10 03:31:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2025-01-02 08:01:36 +00:00
|
|
|
|
//点击跳转到聊天设置页面
|
|
|
|
|
const toChatSettingsPage = () => {
|
|
|
|
|
uni.navigateTo({
|
2025-01-06 10:55:00 +00:00
|
|
|
|
url: '/pages/chatSettings/index?groupId=' + talkParams?.receiver_id + '&sessionId=' + state.sessionId
|
2025-01-02 08:01:36 +00:00
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-19 03:02:47 +00:00
|
|
|
|
onMounted(async () => {
|
2024-12-10 03:31:36 +00:00
|
|
|
|
initData()
|
2024-11-22 01:06:37 +00:00
|
|
|
|
})
|
|
|
|
|
|
2024-12-06 08:55:15 +00:00
|
|
|
|
onUnmounted(() => {
|
|
|
|
|
dialogueStore.setDialogue({})
|
2024-12-19 03:02:47 +00:00
|
|
|
|
clearMultiSelect()
|
2024-12-06 08:55:15 +00:00
|
|
|
|
})
|
2024-11-22 01:06:37 +00:00
|
|
|
|
</script>
|
2024-11-22 09:00:03 +00:00
|
|
|
|
<style scoped lang="less">
|
2024-11-26 08:51:36 +00:00
|
|
|
|
uni-page-body,
|
|
|
|
|
page {
|
|
|
|
|
height: 100%;
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-22 01:06:37 +00:00
|
|
|
|
.outer-layer {
|
|
|
|
|
flex: 1;
|
|
|
|
|
background-image: url("@/static/image/clockIn/z3280@3x.png");
|
|
|
|
|
background-size: cover;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
2024-11-26 08:51:36 +00:00
|
|
|
|
overflow: hidden;
|
2024-11-22 01:06:37 +00:00
|
|
|
|
}
|
2024-11-22 09:00:03 +00:00
|
|
|
|
|
2024-11-22 01:06:37 +00:00
|
|
|
|
.root {
|
|
|
|
|
flex: 1;
|
|
|
|
|
padding: 20rpx 32rpx;
|
2024-11-26 08:51:36 +00:00
|
|
|
|
min-height: 0;
|
2024-11-22 01:06:37 +00:00
|
|
|
|
}
|
2024-11-22 09:00:03 +00:00
|
|
|
|
|
2024-11-22 01:06:37 +00:00
|
|
|
|
.searchRoot {
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
padding: 22rpx 18rpx;
|
|
|
|
|
}
|
2024-11-22 09:00:03 +00:00
|
|
|
|
|
2024-11-22 01:06:37 +00:00
|
|
|
|
.contentRoot {
|
|
|
|
|
margin-top: 20rpx;
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
}
|
2024-11-22 09:00:03 +00:00
|
|
|
|
|
2024-11-22 01:06:37 +00:00
|
|
|
|
.footBox {
|
2024-11-26 08:51:36 +00:00
|
|
|
|
min-height: 162rpx;
|
2024-11-22 01:06:37 +00:00
|
|
|
|
background-color: #fff;
|
|
|
|
|
}
|
2024-11-22 09:00:03 +00:00
|
|
|
|
|
|
|
|
|
.dialogBox {
|
2024-11-22 01:06:37 +00:00
|
|
|
|
height: 100%;
|
2024-11-26 08:51:36 +00:00
|
|
|
|
min-height: 0;
|
|
|
|
|
overflow: auto;
|
|
|
|
|
|
|
|
|
|
// 添加以下样式来隐藏滚动条
|
|
|
|
|
&::-webkit-scrollbar {
|
|
|
|
|
display: none;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
-ms-overflow-style: none;
|
|
|
|
|
/* IE and Edge */
|
|
|
|
|
scrollbar-width: none;
|
|
|
|
|
/* Firefox */
|
2024-11-22 01:06:37 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-11-22 09:00:03 +00:00
|
|
|
|
.load-toolbar {
|
2024-11-26 08:51:36 +00:00
|
|
|
|
height: 50rpx;
|
2024-11-22 09:00:03 +00:00
|
|
|
|
color: #409eff;
|
|
|
|
|
text-align: center;
|
2024-11-26 08:51:36 +00:00
|
|
|
|
line-height: 50rpx;
|
|
|
|
|
font-size: 24rpx;
|
2024-11-22 09:00:03 +00:00
|
|
|
|
|
|
|
|
|
.no-more {
|
|
|
|
|
color: #b9b3b3;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.message-item {
|
|
|
|
|
&.border {
|
2024-11-26 08:51:36 +00:00
|
|
|
|
border-radius: 16rpx;
|
2024-11-22 09:00:03 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.message-box {
|
|
|
|
|
width: 100%;
|
2024-11-26 08:51:36 +00:00
|
|
|
|
min-height: 30rpx;
|
|
|
|
|
margin-bottom: 5rpx;
|
2024-11-22 09:00:03 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.record-box {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: row;
|
|
|
|
|
align-items: flex-start;
|
2024-11-26 08:51:36 +00:00
|
|
|
|
|
2024-11-22 09:00:03 +00:00
|
|
|
|
.checkbox-column {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: center;
|
2024-12-19 03:02:47 +00:00
|
|
|
|
width: 42rpx;
|
2024-11-22 09:00:03 +00:00
|
|
|
|
order: 1;
|
|
|
|
|
user-select: none;
|
2024-12-19 03:02:47 +00:00
|
|
|
|
margin-top: 20rpx;
|
|
|
|
|
margin-right: 20rpx;
|
2024-11-22 09:00:03 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.avatar-column {
|
|
|
|
|
width: 80rpx;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
order: 2;
|
|
|
|
|
user-select: none;
|
|
|
|
|
margin-top: 16rpx;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.main-column {
|
|
|
|
|
flex: 1 auto;
|
|
|
|
|
order: 3;
|
|
|
|
|
position: relative;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
padding: 16rpx 20rpx 14rpx 20rpx;
|
2024-12-19 03:02:47 +00:00
|
|
|
|
// overflow: hidden;
|
2024-11-22 09:00:03 +00:00
|
|
|
|
min-height: 30px;
|
|
|
|
|
|
|
|
|
|
.talk-title {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
margin-bottom: 6rpx;
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
user-select: none;
|
|
|
|
|
color: #BABABA;
|
|
|
|
|
opacity: 1;
|
|
|
|
|
|
|
|
|
|
&.show {
|
|
|
|
|
opacity: 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.nickname {
|
|
|
|
|
color: var(--im-text-color);
|
2024-11-26 08:51:36 +00:00
|
|
|
|
margin-right: 5rpx;
|
2024-11-22 09:00:03 +00:00
|
|
|
|
|
|
|
|
|
.at {
|
|
|
|
|
display: none;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
|
color: var(--im-primary-color);
|
|
|
|
|
|
|
|
|
|
.at {
|
|
|
|
|
display: inline-block;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
span {
|
|
|
|
|
transform: scale(0.88);
|
|
|
|
|
transform-origin: left center;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.talk-content {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: flex-start;
|
|
|
|
|
align-items: flex-end;
|
|
|
|
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
|
|
|
|
.talk-tools {
|
|
|
|
|
display: flex;
|
2024-11-26 08:51:36 +00:00
|
|
|
|
margin: 0 16rpx;
|
2024-11-22 09:00:03 +00:00
|
|
|
|
color: #a79e9e;
|
2024-11-26 08:51:36 +00:00
|
|
|
|
font-size: 24rpx;
|
2024-11-22 09:00:03 +00:00
|
|
|
|
user-select: none;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: space-around;
|
|
|
|
|
|
|
|
|
|
.more-tools {
|
|
|
|
|
visibility: hidden;
|
2024-11-26 08:51:36 +00:00
|
|
|
|
margin-left: 5rpx;
|
2024-11-22 09:00:03 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.talk-reply {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: flex-start;
|
|
|
|
|
align-items: center;
|
|
|
|
|
width: fit-content;
|
2024-11-26 08:51:36 +00:00
|
|
|
|
padding: 8rpx;
|
|
|
|
|
margin-top: 6rpx;
|
2024-11-22 09:00:03 +00:00
|
|
|
|
margin-right: auto;
|
2024-11-26 08:51:36 +00:00
|
|
|
|
font-size: 24rpx;
|
2024-11-22 09:00:03 +00:00
|
|
|
|
color: #8f8f8f;
|
|
|
|
|
word-break: break-all;
|
|
|
|
|
background-color: var(--im-message-left-bg-color);
|
2024-11-26 08:51:36 +00:00
|
|
|
|
border-radius: 10rpx;
|
|
|
|
|
max-width: 450rpx;
|
2024-11-22 09:00:03 +00:00
|
|
|
|
overflow: hidden;
|
|
|
|
|
user-select: none;
|
|
|
|
|
|
|
|
|
|
.icon-top {
|
2024-11-26 08:51:36 +00:00
|
|
|
|
margin-right: 6rpx;
|
2024-11-22 09:00:03 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.ellipsis {
|
|
|
|
|
display: -webkit-inline-box;
|
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
-webkit-line-clamp: 3;
|
|
|
|
|
-webkit-box-orient: vertical;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
|
.talk-title {
|
|
|
|
|
opacity: 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.more-tools {
|
|
|
|
|
visibility: visible !important;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&.direction-rt {
|
|
|
|
|
.avatar-column {
|
|
|
|
|
order: 3;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.main-column {
|
|
|
|
|
order: 2;
|
|
|
|
|
|
|
|
|
|
.talk-title {
|
|
|
|
|
justify-content: flex-end;
|
|
|
|
|
|
|
|
|
|
span {
|
|
|
|
|
transform-origin: right center;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.talk-content {
|
|
|
|
|
flex-direction: row-reverse;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.talk-reply {
|
|
|
|
|
margin-right: 0;
|
|
|
|
|
margin-left: auto;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&.multi-select {
|
|
|
|
|
border-radius: 5px;
|
|
|
|
|
|
|
|
|
|
&:hover,
|
|
|
|
|
&.multi-select-check {
|
|
|
|
|
background-color: var(--im-active-bg-color);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-11-26 08:51:36 +00:00
|
|
|
|
|
|
|
|
|
.content-placeholder {
|
|
|
|
|
height: 58rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.quillBox {
|
|
|
|
|
:deep(.ql-clipboard) {
|
2024-11-28 08:55:45 +00:00
|
|
|
|
position: relative;
|
|
|
|
|
opacity: 0;
|
|
|
|
|
height: 1rpx;
|
|
|
|
|
overflow: auto;
|
2024-11-26 08:51:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
:deep(.ql-editor) {
|
|
|
|
|
padding: 14rpx 22rpx;
|
|
|
|
|
background-color: #F9F9F9;
|
|
|
|
|
border-radius: 8rpx;
|
|
|
|
|
outline: none !important;
|
2024-11-28 08:55:45 +00:00
|
|
|
|
max-height: 294rpx;
|
|
|
|
|
overflow: auto;
|
|
|
|
|
line-height: 44rpx;
|
|
|
|
|
font-size: 32rpx;
|
2024-12-19 03:02:47 +00:00
|
|
|
|
|
|
|
|
|
p {
|
2024-11-28 08:55:45 +00:00
|
|
|
|
display: inline-flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: flex-start;
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
white-space: normal;
|
|
|
|
|
word-break: break-all;
|
2024-12-19 03:02:47 +00:00
|
|
|
|
|
|
|
|
|
.ed-emoji {
|
2024-11-28 08:55:45 +00:00
|
|
|
|
width: 44rpx;
|
|
|
|
|
height: 44rpx;
|
|
|
|
|
display: inline-block;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-11-26 08:51:36 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-12-19 03:02:47 +00:00
|
|
|
|
|
|
|
|
|
:deep(.wd-action-sheet) {
|
|
|
|
|
background-color: #8b8b8b !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
:deep(.wd-action-sheet__panel-title) {
|
|
|
|
|
color: #fff !important;
|
|
|
|
|
}
|
2024-12-20 08:59:58 +00:00
|
|
|
|
|
|
|
|
|
.component-content {
|
|
|
|
|
position: relative;
|
|
|
|
|
z-index: 1;
|
|
|
|
|
/* 确保 z-index 低于 deepBubble */
|
|
|
|
|
}
|
2024-12-24 08:28:44 +00:00
|
|
|
|
.divider {
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 1rpx;
|
|
|
|
|
background-color: #E7E7E7;
|
|
|
|
|
}
|
2024-11-22 01:06:37 +00:00
|
|
|
|
</style>
|