更新
Some checks failed
Check / lint (push) Has been cancelled
Check / typecheck (push) Has been cancelled
Check / build (build, 18.x, ubuntu-latest) (push) Has been cancelled
Check / build (build, 18.x, windows-latest) (push) Has been cancelled
Check / build (build:app, 18.x, ubuntu-latest) (push) Has been cancelled
Check / build (build:app, 18.x, windows-latest) (push) Has been cancelled
Check / build (build:mp-weixin, 18.x, ubuntu-latest) (push) Has been cancelled
Check / build (build:mp-weixin, 18.x, windows-latest) (push) Has been cancelled
Some checks failed
Check / lint (push) Has been cancelled
Check / typecheck (push) Has been cancelled
Check / build (build, 18.x, ubuntu-latest) (push) Has been cancelled
Check / build (build, 18.x, windows-latest) (push) Has been cancelled
Check / build (build:app, 18.x, ubuntu-latest) (push) Has been cancelled
Check / build (build:app, 18.x, windows-latest) (push) Has been cancelled
Check / build (build:mp-weixin, 18.x, ubuntu-latest) (push) Has been cancelled
Check / build (build:mp-weixin, 18.x, windows-latest) (push) Has been cancelled
This commit is contained in:
parent
a000ee9718
commit
62f540c65c
2
env/.env.test
vendored
2
env/.env.test
vendored
@ -9,3 +9,5 @@ VITE_SHOW_SOURCEMAP = true
|
|||||||
VITE_BASEURL = 'http://192.168.88.59:9503'
|
VITE_BASEURL = 'http://192.168.88.59:9503'
|
||||||
#VITE_SOCKET_API
|
#VITE_SOCKET_API
|
||||||
VITE_SOCKET_API = 'ws://192.168.88.59:9504'
|
VITE_SOCKET_API = 'ws://192.168.88.59:9504'
|
||||||
|
# EPRAPI baseUrl
|
||||||
|
VITE_EPR_BASEURL = 'http://114.218.158.24:9020'
|
||||||
|
@ -28,12 +28,14 @@
|
|||||||
"@uni-helper/axios-adapter": "^1.5.2",
|
"@uni-helper/axios-adapter": "^1.5.2",
|
||||||
"@uni-helper/localforage-adapter": "^1.0.2",
|
"@uni-helper/localforage-adapter": "^1.0.2",
|
||||||
"@uni-helper/uni-use": "^0.19.12",
|
"@uni-helper/uni-use": "^0.19.12",
|
||||||
|
"@vueup/vue-quill": "^1.2.0",
|
||||||
"@vueuse/core": "^9.13.0",
|
"@vueuse/core": "^9.13.0",
|
||||||
"axios": "^1.7.2",
|
"axios": "^1.7.2",
|
||||||
"dayjs": "^1.11.12",
|
"dayjs": "^1.11.12",
|
||||||
"less": "^4.2.0",
|
"less": "^4.2.0",
|
||||||
"nzh": "^1.0.13",
|
"nzh": "^1.0.13",
|
||||||
"pinia-plugin-persistedstate": "^4.1.3",
|
"pinia-plugin-persistedstate": "^4.1.3",
|
||||||
|
"quill-mention": "^6.0.2",
|
||||||
"vconsole": "^3.15.1",
|
"vconsole": "^3.15.1",
|
||||||
"vue": "^3.3.8",
|
"vue": "^3.3.8",
|
||||||
"vue-i18n": "^9.6.5"
|
"vue-i18n": "^9.6.5"
|
||||||
|
@ -1,31 +1,31 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { NImage } from 'naive-ui'
|
|
||||||
import { getImageInfo } from '@/utils/functions'
|
import { getImageInfo } from '@/utils/functions'
|
||||||
import { ITalkRecordExtraImage, ITalkRecord } from '@/types/chat'
|
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
extra: ITalkRecordExtraImage
|
extra: any
|
||||||
data: ITalkRecord
|
data: any
|
||||||
maxWidth?: Boolean
|
maxWidth?: Boolean
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const img = (src: string, width = 200) => {
|
const img = (src: string, width = 200) => {
|
||||||
const info = getImageInfo(src)
|
const info = getImageInfo(src)
|
||||||
|
|
||||||
if (info.width == 0 || info.height == 0) {
|
if (info.width == 0 || info.height == 0) {
|
||||||
return {}
|
return {
|
||||||
|
width: 450,
|
||||||
|
height: 298
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.width < width) {
|
if (info.width < width) {
|
||||||
return {
|
return {
|
||||||
width: `${info.width}px`,
|
width: info.width,
|
||||||
height: `${info.height}px`
|
height: info.height
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
width: width + 'px',
|
width: width,
|
||||||
height: `${info.height / (info.width / width)}px`
|
height: info.height / (info.width / width)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -33,28 +33,22 @@ const img = (src: string, width = 200) => {
|
|||||||
<section
|
<section
|
||||||
class="im-message-image"
|
class="im-message-image"
|
||||||
:class="{ left: data.float === 'left' }"
|
:class="{ left: data.float === 'left' }"
|
||||||
:style="img(extra.url, 350)"
|
|
||||||
>
|
>
|
||||||
<n-image :src="extra.url" />
|
<tm-image preview :width="img(extra.url,450).width" :height="img(extra.url,450).height" :src="extra.url" />
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.im-message-image {
|
.im-message-image {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding: 5px;
|
padding: 20rpx 18rpx;
|
||||||
border-radius: 5px;
|
border-radius: 16rpx 0 16rpx 16rpx;
|
||||||
background: var(--im-message-left-bg-color);
|
background-color: #46299D;
|
||||||
min-width: 30px;
|
min-width: 40rpx;
|
||||||
min-height: 30px;
|
min-height: 40rpx;
|
||||||
|
|
||||||
&.left {
|
&.left {
|
||||||
background: var(--im-message-right-bg-color);
|
background-color: #fff;
|
||||||
}
|
border-radius: 0 16rpx 16rpx 16rpx;
|
||||||
|
|
||||||
:deep(.n-image img) {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { NImage } from 'naive-ui'
|
|
||||||
import { textReplaceEmoji } from '@/utils/emojis'
|
import { textReplaceEmoji } from '@/utils/emojis'
|
||||||
import { textReplaceLink } from '@/utils/strings'
|
import { textReplaceLink } from '@/utils/strings'
|
||||||
import { getImageInfo } from '@/utils/functions'
|
import { getImageInfo } from '@/utils/functions'
|
||||||
@ -13,25 +12,26 @@ const props = defineProps<{
|
|||||||
|
|
||||||
const float = props.data.float
|
const float = props.data.float
|
||||||
|
|
||||||
const img = (src, width = 200) => {
|
const img = (src: string, width = 200) => {
|
||||||
const info = getImageInfo(src)
|
const info = getImageInfo(src)
|
||||||
|
|
||||||
if (info.width == 0 || info.height == 0) {
|
if (info.width == 0 || info.height == 0) {
|
||||||
return {}
|
return {
|
||||||
|
width: 200,
|
||||||
|
height: 200
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.width < width) {
|
if (info.width < width) {
|
||||||
return {
|
return {
|
||||||
width: `${info.width}px`,
|
width: info.width,
|
||||||
height: `${info.height}px`
|
height: info.height
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let h = info.height / (info.width / width)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
width: width + 'px',
|
width: width,
|
||||||
height: h + 'px'
|
height: info.height / (info.width / width)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -54,10 +54,9 @@ const img = (src, width = 200) => {
|
|||||||
|
|
||||||
<template v-else-if="item.type === 3">
|
<template v-else-if="item.type === 3">
|
||||||
<div
|
<div
|
||||||
:style="img(item.content, 300)"
|
style="display: flex; margin: 5px 0;border-radius: 8px;overflow: hidden;"
|
||||||
style="display: flex; margin: 5px 0;border-radius: 8px;overflow: hidden;;"
|
|
||||||
>
|
>
|
||||||
<n-image :src="item.content"></n-image>
|
<tm-image :src="item.content" :width="img(item.content,450).width" :height="img(item.content,450).height" ></tm-image>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
@ -67,16 +66,16 @@ const img = (src, width = 200) => {
|
|||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.im-message-mixed {
|
.im-message-mixed {
|
||||||
min-width: 30px;
|
min-width: 40rpx;
|
||||||
min-height: 30px;
|
min-height: 40rpx;
|
||||||
padding: 3px;
|
padding: 20rpx 18rpx;
|
||||||
color: var(--im-message-left-text-color);
|
color: #000000;
|
||||||
background: var(--im-message-left-bg-color);
|
background-color: #FFFFFF;
|
||||||
border-radius: 0px 10px 10px 10px;
|
border-radius: 0 16rpx 16rpx 16rpx;
|
||||||
|
|
||||||
&.right {
|
&.right {
|
||||||
background-color: var(--im-message-right-bg-color);
|
background-color: #46299D;
|
||||||
color: var(--im-message-right-text-color);
|
color: #FFFFFF;
|
||||||
border-radius: 10px 0px 10px 10px;
|
border-radius: 10px 0px 10px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,17 +39,17 @@ textContent = textReplaceEmoji(textContent)
|
|||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.im-message-text {
|
.im-message-text {
|
||||||
min-width: 30px;
|
min-width: 40rpx;
|
||||||
min-height: 30px;
|
min-height: 40rpx;
|
||||||
padding: 22rpx 30rpx;
|
padding: 22rpx 30rpx;
|
||||||
color: #1A1A1A;
|
color: #1A1A1A;
|
||||||
background: #FFFFFF;
|
background: #FFFFFF;
|
||||||
border-radius: 0px 10px 10px 10px;
|
border-radius: 0 16rpx 16rpx 16rpx;
|
||||||
|
|
||||||
&.right {
|
&.right {
|
||||||
background-color: #46299D;
|
background-color: #46299D;
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
border-radius: 10px 0px 10px 10px;
|
border-radius: 16rpx 0 16rpx 16rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.maxwidth {
|
&.maxwidth {
|
||||||
|
@ -1,106 +1,86 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import 'xgplayer/dist/index.min.css'
|
import { ref, nextTick,getCurrentInstance } from 'vue'
|
||||||
import { ref, nextTick } from 'vue'
|
|
||||||
import { NImage, NModal, NCard } from 'naive-ui'
|
|
||||||
import { Play, Close } from '@icon-park/vue-next'
|
|
||||||
import { getImageInfo } from '@/utils/functions'
|
import { getImageInfo } from '@/utils/functions'
|
||||||
import Player from 'xgplayer'
|
import playCircle from "@/static/image/chatList/playCircle@2x.png";
|
||||||
import { ITalkRecordExtraVideo, ITalkRecord } from '@/types/chat'
|
import { useStatus } from "@/store/status";
|
||||||
|
|
||||||
|
const { statusBarHeight } = useStatus()
|
||||||
|
const instance = getCurrentInstance()
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
extra: ITalkRecordExtraVideo
|
extra: any
|
||||||
data: ITalkRecord
|
data: any
|
||||||
maxWidth?: Boolean
|
maxWidth?: Boolean
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
const videoRef = ref()
|
||||||
|
const videoContext = ref()
|
||||||
|
const open = ref(false)
|
||||||
|
|
||||||
const img = (src: string, width = 200) => {
|
const img = (src: string, width = 200) => {
|
||||||
|
console.log(props);
|
||||||
|
|
||||||
const info: any = getImageInfo(src)
|
const info: any = getImageInfo(src)
|
||||||
|
|
||||||
if (info.width == 0 || info.height == 0) {
|
if (info.width == 0 || info.height == 0) {
|
||||||
return {}
|
return {}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.height > 300) {
|
|
||||||
return {
|
|
||||||
height: '300px'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info.width < width) {
|
if (info.width < width) {
|
||||||
return {
|
return {
|
||||||
width: `${info.width}px`,
|
width: info.width,
|
||||||
height: `${info.height}px`
|
height: info.height
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
width: width + 'px',
|
width: width,
|
||||||
height: info.height / (info.width / width) + 'px'
|
height: info.height / (info.width / width)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const open = ref(false)
|
const fullscreenchange = (e) => {
|
||||||
|
if(!e.detail.fullScreen){
|
||||||
|
videoContext.value.stop()
|
||||||
|
open.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function onPlay() {
|
async function onPlay() {
|
||||||
|
videoContext.value = uni.createVideoContext(props.extra.url,instance);
|
||||||
|
videoContext.value.requestFullScreen({ direction: 2 });
|
||||||
|
videoContext.value.play()
|
||||||
open.value = true
|
open.value = true
|
||||||
|
|
||||||
await nextTick()
|
|
||||||
|
|
||||||
new Player({
|
|
||||||
id: 'im-xgplayer',
|
|
||||||
url: props.extra.url,
|
|
||||||
fluid: true,
|
|
||||||
autoplay: true,
|
|
||||||
lang: 'zh-cn'
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<section
|
<section class="im-message-video" :class="{ left: data.float === 'left' }" @click="onPlay">
|
||||||
class="im-message-video"
|
<tm-image :src="extra.cover" :width="img(extra.cover, 350).width" :height="img(extra.cover, 350).height" />
|
||||||
:class="{ left: data.float === 'left' }"
|
|
||||||
:style="img(extra.cover, 350)"
|
|
||||||
@click="onPlay"
|
|
||||||
>
|
|
||||||
<n-image :src="extra.cover" preview-disabled />
|
|
||||||
|
|
||||||
<div class="btn-video">
|
<div class="btn-video">
|
||||||
<n-icon :component="Play" size="36" />
|
<tm-image :src="playCircle" :width="80" :height="80" />
|
||||||
</div>
|
</div>
|
||||||
|
<div v-show="open">
|
||||||
<n-modal v-model:show="open">
|
<video ref="videoRef" :src="props.extra.url" controls @fullscreenchange="fullscreenchange"
|
||||||
<n-card
|
:id="props.extra.url">
|
||||||
style="width: 800px; min-height: 300px; background-color: #ffffff; position: relative"
|
</video>
|
||||||
role="dialog"
|
|
||||||
aria-modal="true"
|
|
||||||
>
|
|
||||||
<div id="im-xgplayer"></div>
|
|
||||||
<div class="im-xgplayer-close" @click="open = false">
|
|
||||||
<n-icon :component="Close" size="18" />
|
|
||||||
</div>
|
</div>
|
||||||
</n-card>
|
|
||||||
</n-modal>
|
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.im-message-video {
|
.im-message-video {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding: 5px;
|
padding: 20rpx 18rpx;
|
||||||
border-radius: 5px;
|
background: #46299D;
|
||||||
background: var(--im-message-left-bg-color);
|
min-width: 30rpx;
|
||||||
min-width: 30px;
|
min-height: 30rpx;
|
||||||
min-height: 30px;
|
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
border-radius: 16rpx 0 16rpx 16rpx;
|
||||||
|
|
||||||
&.left {
|
&.left {
|
||||||
background: var(--im-message-right-bg-color);
|
border-radius: 0 16rpx 16rpx 16rpx;
|
||||||
}
|
background: #fff;
|
||||||
|
|
||||||
:deep(.n-image img) {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-video {
|
.btn-video {
|
||||||
@ -134,4 +114,5 @@ async function onPlay() {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
64
src/pages/dialog/components/emojiPanel.vue
Normal file
64
src/pages/dialog/components/emojiPanel.vue
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
<template>
|
||||||
|
<div class="emojiRoot">
|
||||||
|
<div v-for="(img, key) in emojis" v-html="img" :key="key" @click="onSendEmoticon(1, key, img)"
|
||||||
|
class="option pointer flex-center" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, defineProps } from "vue"
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import { beautifyTime } from '@/utils/datetime'
|
||||||
|
import { useTalkStore } from '@/store'
|
||||||
|
import { useSessionMenu } from '@/hooks'
|
||||||
|
import { emojis } from '@/utils/emojis'
|
||||||
|
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
data: {
|
||||||
|
type: Object,
|
||||||
|
default: {},
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const onSendEmoticon = (type, value, img = '') => {
|
||||||
|
if (img) {
|
||||||
|
const imgSrcReg = /<img.*?src='(.*?)'/g
|
||||||
|
let match = imgSrcReg.exec(img)
|
||||||
|
if (match) {
|
||||||
|
emit('on-select', { type, value, img: match[1] })
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
emit('on-select', { type, value, img })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.emojiRoot {
|
||||||
|
width: 100%;
|
||||||
|
height: 420rpx;
|
||||||
|
padding: 5rpx 32rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option {
|
||||||
|
width: 14.28%;
|
||||||
|
height: 42rpx;
|
||||||
|
margin: 20rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.emoji) {
|
||||||
|
vertical-align: text-bottom;
|
||||||
|
margin: 0 10rpx;
|
||||||
|
width: 52rpx;
|
||||||
|
height: 52rpx;
|
||||||
|
}
|
||||||
|
</style>
|
@ -15,19 +15,12 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="root">
|
<div class="root">
|
||||||
<div class="dialogBox">
|
<div class="dialogBox">
|
||||||
<!-- <div v-if="loadConfig.status == 0" class="h-[240rpx] flex items-center justify-center flex-col" >
|
<ZPaging :fixed="false" use-chat-record-mode :use-page-scroll="false" :refresher-enabled="false"
|
||||||
<wd-loading />
|
:show-scrollbar="false" :loading-more-enabled="true" :hide-empty-view="true" height="100%" ref="pagingRef"
|
||||||
<div class="text-[#959598] mt-[20rpx] text-[28rpx]" > 正在加载中... </div>
|
@scrolltolower="onRefreshLoad">
|
||||||
</div>
|
|
||||||
<div v-else-if="loadConfig.status == 1" @click="onRefreshLoad" >查看更多消息 ...</div>
|
|
||||||
<span v-else class="no-more"> 没有更多消息了 </span> -->
|
|
||||||
<!-- 数据加载状态栏 -->
|
<!-- 数据加载状态栏 -->
|
||||||
<div class="load-toolbar pointer">
|
<div class="message-item" v-for="(item, index) in reversedRecords" style="transform: scaleY(-1);"
|
||||||
<span v-if="loadConfig.status == 0"> 正在加载数据中 ... </span>
|
:key="item.msg_id" :id="item.msg_id">
|
||||||
<span v-else-if="loadConfig.status == 1" @click="onRefreshLoad"> 查看更多消息 ... </span>
|
|
||||||
<span v-else class="no-more"> 没有更多消息了 </span>
|
|
||||||
</div>
|
|
||||||
<div class="message-item" v-for="(item, index) in records" :key="item.msg_id" :id="item.msg_id">
|
|
||||||
<!-- 系统消息 -->
|
<!-- 系统消息 -->
|
||||||
<div v-if="item.msg_type >= 1000" class="message-box">
|
<div v-if="item.msg_type >= 1000" class="message-box">
|
||||||
<component :is="MessageComponents[item.msg_type] || 'unknown-message'" :extra="item.extra" :data="item" />
|
<component :is="MessageComponents[item.msg_type] || 'unknown-message'" :extra="item.extra" :data="item" />
|
||||||
@ -64,9 +57,10 @@
|
|||||||
<span>{{ parseTime(item.created_at, '{m}/{d} {h}:{i}') }}</span>
|
<span>{{ parseTime(item.created_at, '{m}/{d} {h}:{i}') }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="talk-content" :class="{ pointer: dialogueStore.isOpenMultiSelect }" @click="onRowClick(item)">
|
<div class="talk-content" :class="{ pointer: dialogueStore.isOpenMultiSelect }">
|
||||||
<component :is="MessageComponents[item.msg_type] || 'unknown-message'" :extra="item.extra" :data="item"
|
<component :is="MessageComponents[item.msg_type] || 'unknown-message'" :extra="item.extra"
|
||||||
:max-width="true" :source="'panel'" @contextmenu.prevent="onContextMenu($event, item)" />
|
:data="item" :max-width="true" :source="'panel'"
|
||||||
|
@contextmenu.prevent="onContextMenu($event, item)" />
|
||||||
|
|
||||||
<div class="talk-tools">
|
<div class="talk-tools">
|
||||||
<template v-if="talk_type == 1 && item.float == 'right'">
|
<template v-if="talk_type == 1 && item.float == 'right'">
|
||||||
@ -80,7 +74,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="item.extra.reply" class="talk-reply pointer" @click="onJumpMessage(item.extra?.reply?.msg_id)">
|
<div v-if="item.extra.reply" class="talk-reply pointer"
|
||||||
|
@click="onJumpMessage(item.extra?.reply?.msg_id)">
|
||||||
<n-icon :component="ToTop" size="14" class="icon-top" />
|
<n-icon :component="ToTop" size="14" class="icon-top" />
|
||||||
<span class="ellipsis">
|
<span class="ellipsis">
|
||||||
回复 {{ item.extra?.reply?.nickname }}:
|
回复 {{ item.extra?.reply?.nickname }}:
|
||||||
@ -91,33 +86,58 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="load-toolbar pointer" style="transform: scaleY(-1);">
|
||||||
|
<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>
|
||||||
|
</ZPaging>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="footBox">
|
<div class="footBox">
|
||||||
<div class="mt-[16rpx] ml-[32rpx] mr-[32rpx] flex items-center justify-between">
|
<div class="mt-[16rpx] ml-[32rpx] mr-[32rpx] flex items-center justify-between">
|
||||||
<div class="w-[534rpx]">
|
<div class="w-[534rpx] quillBox" >
|
||||||
<tm-input :height="72" placeholder=""></tm-input>
|
<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>
|
</div>
|
||||||
<tm-image :width="52" :height="52" :round="12" :src="smile"></tm-image>
|
<tm-image @click="state.isOpenEmojiPanel = !state.isOpenEmojiPanel" :width="52" :height="52" :round="12"
|
||||||
|
:src="state.isOpenEmojiPanel ? keyboard : smile"></tm-image>
|
||||||
<tm-image :width="52" :height="52" :round="12" :src="addCircleGray"></tm-image>
|
<tm-image :width="52" :height="52" :round="12" :src="addCircleGray"></tm-image>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="state.isOpenEmojiPanel" class="mt-[50rpx]">
|
||||||
|
<emoji-panel />
|
||||||
|
</div>
|
||||||
|
<!--底部安全区-->
|
||||||
|
<div class="content-placeholder"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive, watch, computed, onMounted } from 'vue';
|
import { ref, reactive, watch, computed, onMounted } from 'vue';
|
||||||
|
import { QuillEditor, Quill } from '@vueup/vue-quill'
|
||||||
import { useChatList } from "@/store/chatList/index.js";
|
import { useChatList } from "@/store/chatList/index.js";
|
||||||
import { useAuth } from "@/store/auth";
|
import { useAuth } from "@/store/auth";
|
||||||
import { useUserStore, useDialogueStore, useUploadsStore } from '@/store'
|
import { useUserStore, useDialogueStore, useUploadsStore, useEditorDraftStore } from '@/store'
|
||||||
import addCircleGray from "@/static/image/chatList/addCircleGray.png";
|
import addCircleGray from "@/static/image/chatList/addCircleGray.png";
|
||||||
import { MessageComponents, ForwardableMessageType } from '@/constant/message'
|
import { MessageComponents, ForwardableMessageType } from '@/constant/message'
|
||||||
import { formatTime, parseTime } from '@/utils/datetime'
|
import { formatTime, parseTime } from '@/utils/datetime'
|
||||||
|
import { deltaToMessage, deltaToString, isEmptyDelta } from './util'
|
||||||
import smile from "@/static/image/chatList/smile@2x.png";
|
import smile from "@/static/image/chatList/smile@2x.png";
|
||||||
|
import keyboard from "@/static/image/chatList/keyboard@2x.png";
|
||||||
import { useInject, useTalkRecord } from '@/hooks'
|
import { useInject, useTalkRecord } from '@/hooks'
|
||||||
|
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'
|
||||||
|
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
const dialogueStore = useDialogueStore()
|
const dialogueStore = useDialogueStore()
|
||||||
|
const editorDraftStore = useEditorDraftStore()
|
||||||
|
const editor = ref()
|
||||||
|
const pagingRef = ref(null)
|
||||||
|
useZPaging(pagingRef)
|
||||||
|
const indexName = computed(() => dialogueStore.index_name)
|
||||||
const talkParams = reactive({
|
const talkParams = reactive({
|
||||||
uid: computed(() => userStore.uid),
|
uid: computed(() => userStore.uid),
|
||||||
index_name: computed(() => dialogueStore.index_name),
|
index_name: computed(() => dialogueStore.index_name),
|
||||||
@ -129,7 +149,141 @@ const talkParams = reactive({
|
|||||||
num: computed(() => dialogueStore.members.length)
|
num: computed(() => dialogueStore.members.length)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const state = ref({
|
||||||
|
isOpenEmojiPanel: false
|
||||||
|
})
|
||||||
|
|
||||||
const { loadConfig, records, onLoad, onRefreshLoad, onJumpMessage } = useTalkRecord(talkParams.uid)
|
const { loadConfig, records, onLoad, onRefreshLoad, onJumpMessage } = useTalkRecord(talkParams.uid)
|
||||||
|
|
||||||
|
// 添加计算属性来反转records数组
|
||||||
|
const reversedRecords = computed(() => {
|
||||||
|
return [...records.value].reverse()
|
||||||
|
})
|
||||||
|
|
||||||
|
const getQuill = () => {
|
||||||
|
return editor.value?.getQuill()
|
||||||
|
}
|
||||||
|
|
||||||
|
const onEditorChange = () => {
|
||||||
|
debugger
|
||||||
|
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 || '']
|
||||||
|
}
|
||||||
|
|
||||||
|
// emit('editor-event', emitCall('input_event', text))
|
||||||
|
}
|
||||||
|
|
||||||
|
const onSendMessage = () => {
|
||||||
|
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 window['$message'].info('发送内容超长,请分条发送')
|
||||||
|
}
|
||||||
|
|
||||||
|
emit(
|
||||||
|
'editor-event',
|
||||||
|
emitCall('text_event', data, (ok) => {
|
||||||
|
ok && getQuill().setContents([], Quill.sources.USER)
|
||||||
|
})
|
||||||
|
)
|
||||||
|
break
|
||||||
|
case 3: // 图片消息
|
||||||
|
emit(
|
||||||
|
'editor-event',
|
||||||
|
emitCall(
|
||||||
|
'image_event',
|
||||||
|
{ ...getImageInfo(data.items[0].content), url: data.items[0].content, size: 10000 },
|
||||||
|
(ok) => {
|
||||||
|
ok && getQuill().setContents([])
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
break
|
||||||
|
case 12: // 图文消息
|
||||||
|
emit(
|
||||||
|
'editor-event',
|
||||||
|
emitCall('mixed_event', data, (ok) => {
|
||||||
|
ok && getQuill().setContents([])
|
||||||
|
})
|
||||||
|
)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const editorOption = {
|
||||||
|
debug: false,
|
||||||
|
modules: {
|
||||||
|
toolbar: false,
|
||||||
|
// clipboard: {
|
||||||
|
// // 粘贴版,处理粘贴时候的自带样式
|
||||||
|
// matchers: [[Node.ELEMENT_NODE, onClipboardMatcher]]
|
||||||
|
// },
|
||||||
|
|
||||||
|
keyboard: {
|
||||||
|
bindings: {
|
||||||
|
enter: {
|
||||||
|
key: 13,
|
||||||
|
handler: onSendMessage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 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: '',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
watch(() => records, (newValue, oldValue) => {
|
watch(() => records, (newValue, oldValue) => {
|
||||||
console.log(newValue);
|
console.log(newValue);
|
||||||
|
|
||||||
@ -157,18 +311,24 @@ onMounted(() => {
|
|||||||
|
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
|
uni-page-body,
|
||||||
|
page {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.outer-layer {
|
.outer-layer {
|
||||||
overflow-y: auto;
|
|
||||||
flex: 1;
|
flex: 1;
|
||||||
background-image: url("@/static/image/clockIn/z3280@3x.png");
|
background-image: url("@/static/image/clockIn/z3280@3x.png");
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.root {
|
.root {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
padding: 20rpx 32rpx;
|
padding: 20rpx 32rpx;
|
||||||
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.searchRoot {
|
.searchRoot {
|
||||||
@ -182,20 +342,32 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.footBox {
|
.footBox {
|
||||||
height: 162rpx;
|
min-height: 162rpx;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialogBox {
|
.dialogBox {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
min-height: 0;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
// 添加以下样式来隐藏滚动条
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
-ms-overflow-style: none;
|
||||||
|
/* IE and Edge */
|
||||||
|
scrollbar-width: none;
|
||||||
|
/* Firefox */
|
||||||
}
|
}
|
||||||
|
|
||||||
.load-toolbar {
|
.load-toolbar {
|
||||||
height: 38px;
|
height: 50rpx;
|
||||||
color: #409eff;
|
color: #409eff;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
line-height: 38px;
|
line-height: 50rpx;
|
||||||
font-size: 13px;
|
font-size: 24rpx;
|
||||||
|
|
||||||
.no-more {
|
.no-more {
|
||||||
color: #b9b3b3;
|
color: #b9b3b3;
|
||||||
@ -204,37 +376,28 @@ onMounted(() => {
|
|||||||
|
|
||||||
.message-item {
|
.message-item {
|
||||||
&.border {
|
&.border {
|
||||||
border-radius: 10px;
|
border-radius: 16rpx;
|
||||||
border: 1px solid var(--im-primary-color);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.message-box {
|
.message-box {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-height: 30px;
|
min-height: 30rpx;
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5rpx;
|
||||||
}
|
|
||||||
|
|
||||||
.datetime {
|
|
||||||
height: 30px;
|
|
||||||
line-height: 30px;
|
|
||||||
color: #ccc9c9;
|
|
||||||
font-size: 12px;
|
|
||||||
text-align: center;
|
|
||||||
margin: 5px 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.record-box {
|
.record-box {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
|
||||||
.checkbox-column {
|
.checkbox-column {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 35px;
|
width: 35rpx;
|
||||||
order: 1;
|
order: 1;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
padding-top: 12px;
|
padding-top: 12rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar-column {
|
.avatar-column {
|
||||||
@ -271,7 +434,7 @@ onMounted(() => {
|
|||||||
|
|
||||||
.nickname {
|
.nickname {
|
||||||
color: var(--im-text-color);
|
color: var(--im-text-color);
|
||||||
margin-right: 5px;
|
margin-right: 5rpx;
|
||||||
|
|
||||||
.at {
|
.at {
|
||||||
display: none;
|
display: none;
|
||||||
@ -302,16 +465,16 @@ onMounted(() => {
|
|||||||
|
|
||||||
.talk-tools {
|
.talk-tools {
|
||||||
display: flex;
|
display: flex;
|
||||||
margin: 0 8px;
|
margin: 0 16rpx;
|
||||||
color: #a79e9e;
|
color: #a79e9e;
|
||||||
font-size: 12px;
|
font-size: 24rpx;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-around;
|
justify-content: space-around;
|
||||||
|
|
||||||
.more-tools {
|
.more-tools {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
margin-left: 5px;
|
margin-left: 5rpx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -321,20 +484,20 @@ onMounted(() => {
|
|||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
padding: 4px;
|
padding: 8rpx;
|
||||||
margin-top: 3px;
|
margin-top: 6rpx;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
font-size: 12px;
|
font-size: 24rpx;
|
||||||
color: #8f8f8f;
|
color: #8f8f8f;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
background-color: var(--im-message-left-bg-color);
|
background-color: var(--im-message-left-bg-color);
|
||||||
border-radius: 5px;
|
border-radius: 10rpx;
|
||||||
max-width: 300px;
|
max-width: 450rpx;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
||||||
.icon-top {
|
.icon-top {
|
||||||
margin-right: 3px;
|
margin-right: 6rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ellipsis {
|
.ellipsis {
|
||||||
@ -392,4 +555,22 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.content-placeholder {
|
||||||
|
height: 58rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quillBox {
|
||||||
|
:deep(.ql-clipboard) {
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.ql-editor) {
|
||||||
|
padding: 14rpx 22rpx;
|
||||||
|
background-color: #F9F9F9;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
outline: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
175
src/pages/dialog/util.ts
Normal file
175
src/pages/dialog/util.ts
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
import { Delta } from '@vueup/vue-quill'
|
||||||
|
|
||||||
|
interface Item {
|
||||||
|
type: number
|
||||||
|
content: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface AnalysisResp {
|
||||||
|
items: Item[]
|
||||||
|
mentions: any[]
|
||||||
|
mentionUids: number[]
|
||||||
|
msgType: number // 1 文本;2:图片;3图文混合消息
|
||||||
|
quoteId: string // 引用的消息ID
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeLeadingNewlines(str: string) {
|
||||||
|
return str.replace(/^[\n\s]+/, '')
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeTrailingNewlines(str: string) {
|
||||||
|
return str.replace(/[\n\s]+$/, '')
|
||||||
|
}
|
||||||
|
|
||||||
|
export function deltaToMessage(delta: Delta): AnalysisResp {
|
||||||
|
const resp: AnalysisResp = {
|
||||||
|
items: [],
|
||||||
|
mentions: [],
|
||||||
|
mentionUids: [],
|
||||||
|
quoteId: '',
|
||||||
|
msgType: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const iterator of delta.ops) {
|
||||||
|
const insert: any = iterator.insert
|
||||||
|
|
||||||
|
let node: any = null
|
||||||
|
if (resp.items.length) {
|
||||||
|
node = resp.items[resp.items.length - 1]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof insert === 'string') {
|
||||||
|
if (!insert || insert == '\n') continue
|
||||||
|
|
||||||
|
if (node && node.type == 1) {
|
||||||
|
node.content = node.content + insert
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.items.push({
|
||||||
|
type: 1,
|
||||||
|
content: insert
|
||||||
|
})
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// @好友
|
||||||
|
if (insert && insert.mention) {
|
||||||
|
const mention = insert.mention
|
||||||
|
|
||||||
|
resp.mentions.push({
|
||||||
|
name: `${mention.denotationChar}${mention.value}`,
|
||||||
|
atid: parseInt(mention.id)
|
||||||
|
})
|
||||||
|
|
||||||
|
if (node && node.type == 1) {
|
||||||
|
node.content = node.content + ` ${mention.denotationChar}${mention.value}`
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.items.push({
|
||||||
|
type: 1,
|
||||||
|
content: `${mention.denotationChar}${mention.value}`
|
||||||
|
})
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// 图片
|
||||||
|
if (insert && insert.image) {
|
||||||
|
resp.items.push({
|
||||||
|
type: 3,
|
||||||
|
content: insert.image
|
||||||
|
})
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表情
|
||||||
|
if (insert && insert.emoji) {
|
||||||
|
const { emoji } = insert
|
||||||
|
|
||||||
|
if (node && node.type == 1) {
|
||||||
|
node.content = node.content + emoji.alt
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.items.push({
|
||||||
|
type: 1,
|
||||||
|
content: emoji.alt
|
||||||
|
})
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (insert && insert.quote) {
|
||||||
|
resp.quoteId = insert.quote.id
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 去除前后多余空格
|
||||||
|
if (resp.items.length) {
|
||||||
|
if (resp.items[0].type == 1) {
|
||||||
|
resp.items[0].content = removeLeadingNewlines(resp.items[0].content)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resp.items[resp.items.length - 1].type == 1) {
|
||||||
|
resp.items[resp.items.length - 1].content = removeTrailingNewlines(
|
||||||
|
resp.items[resp.items.length - 1].content
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resp.items.length > 1) {
|
||||||
|
resp.msgType = 12
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resp.items.length == 1) {
|
||||||
|
resp.msgType = resp.items[0].type
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.mentionUids = resp.mentions.map((item) => item.atid)
|
||||||
|
|
||||||
|
return resp
|
||||||
|
}
|
||||||
|
|
||||||
|
export function deltaToString(delta: Delta): string {
|
||||||
|
let content = ''
|
||||||
|
|
||||||
|
for (const o of delta.ops) {
|
||||||
|
const insert: any = o.insert
|
||||||
|
|
||||||
|
if (typeof insert === 'string') {
|
||||||
|
if (!insert || insert == '\n') continue
|
||||||
|
|
||||||
|
content += insert
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// @好友
|
||||||
|
if (insert && insert.mention) {
|
||||||
|
const { mention } = insert
|
||||||
|
content += ` ${mention.denotationChar}${mention.value} `
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// 图片
|
||||||
|
if (insert && insert.image) {
|
||||||
|
content += '[图片]'
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表情
|
||||||
|
if (insert && insert.emoji) {
|
||||||
|
content += insert.emoji.alt
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return content
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isEmptyDelta(delta: Delta): boolean {
|
||||||
|
return delta.ops.length == 1 && delta.ops[0].insert == '\n'
|
||||||
|
}
|
@ -63,6 +63,9 @@ watch(() => talkStore, (newValue, oldValue) => {
|
|||||||
|
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
uni-page-body,page{
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
.outer-layer {
|
.outer-layer {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
BIN
src/static/image/chatList/keyboard@2x.png
Normal file
BIN
src/static/image/chatList/keyboard@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.5 KiB |
BIN
src/static/image/chatList/playCircle@2x.png
Normal file
BIN
src/static/image/chatList/playCircle@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
@ -4,7 +4,7 @@ import {uniStorage} from "@/utils/uniStorage.js"
|
|||||||
import {ref} from 'vue'
|
import {ref} from 'vue'
|
||||||
export const useAuth = createGlobalState(() => {
|
export const useAuth = createGlobalState(() => {
|
||||||
// const token = useStorage('token', '', uniStorage)
|
// const token = useStorage('token', '', uniStorage)
|
||||||
const token = ref('30119d9978a6f3321fb4779c0040e997df4dd0dd0cf6b71119657617d2249ed783f940b0050d5be7e758740ea467afdf3eeb4d28fb5ea234af60ebe51fb218ffea38d3362de44912166520e87a6f38da2162e348845fabbb0db3604d4a2e7e543f680408fdbb166cbc70418235831e0b95aed8016b4a3b75feeec68212e4824da6e28c747409384ce136db6b9cd6e688cc40db73794e69f51be0920811cc437e51ca29fc82fccc1e98cb39b2577ef5b574460c853336d6afbe13149711d5e3fe')
|
const token = ref('30119d9978a6f3321fb4779c0040e997df4dd0dd0cf6b71119657617d2249ed783f940b0050d5be7e758740ea467afdf3eeb4d28fb5ea234af60ebe51fb218ffea38d3362de44912166520e87a6f38da5fa465eedb17110c9d5a7bb18d2a526249de3c56b42ad044dfada705af255bf9b021020b5f62f3bb26adf451d2736228924fc801fe89c57eaf8165fff1723136f4085f0a369bd83bf3abf52fa2e079f1241f62b1502a440bca65e0e954bd4e46b63a5bfc16ac9aec3104bd29b763bf03')
|
||||||
const refreshToken = useStorage('refreshToken', '', uniStorage)
|
const refreshToken = useStorage('refreshToken', '', uniStorage)
|
||||||
const userInfo = useStorage('userInfo', {}, uniStorage)
|
const userInfo = useStorage('userInfo', {}, uniStorage)
|
||||||
const leaderList = useStorage('leaderList', [], uniStorage)
|
const leaderList = useStorage('leaderList', [], uniStorage)
|
||||||
|
@ -3,6 +3,6 @@ export * from '@/store/modules/user'
|
|||||||
export * from '@/store/modules/talk'
|
export * from '@/store/modules/talk'
|
||||||
// export * from '@/store/modules/editor'
|
// export * from '@/store/modules/editor'
|
||||||
export * from '@/store/modules/dialogue'
|
export * from '@/store/modules/dialogue'
|
||||||
// export * from '@/store/modules/editor-draft'
|
export * from '@/store/modules/editor-draft'
|
||||||
export * from '@/store/modules/uploads'
|
export * from '@/store/modules/uploads'
|
||||||
// export * from '@/store/modules/note'
|
// export * from '@/store/modules/note'
|
||||||
|
@ -1,9 +1,117 @@
|
|||||||
|
import wx001 from '@/static/image/emoji/001_微笑.png'
|
||||||
|
import pz002 from '@/static/image/emoji/002_撇嘴.png'
|
||||||
|
import se003 from '@/static/image/emoji/003_色.png'
|
||||||
|
import fd004 from '@/static/image/emoji/004_发呆.png'
|
||||||
|
import dd005 from '@/static/image/emoji/005_得意.png'
|
||||||
|
import ll006 from '@/static/image/emoji/006_流泪.png'
|
||||||
|
import hs007 from '@/static/image/emoji/007_害羞.png'
|
||||||
|
import bz008 from '@/static/image/emoji/008_闭嘴.png'
|
||||||
|
import sh009 from '@/static/image/emoji/009_睡.png'
|
||||||
|
import dc010 from '@/static/image/emoji/010_大哭.png'
|
||||||
|
import gg011 from '@/static/image/emoji/011_尴尬.png'
|
||||||
|
import fl012 from '@/static/image/emoji/012_发怒.png'
|
||||||
|
import tp013 from '@/static/image/emoji/013_调皮.png'
|
||||||
|
import cz014 from '@/static/image/emoji/014_呲牙.png'
|
||||||
|
import jy015 from '@/static/image/emoji/015_惊讶.png'
|
||||||
|
import nd016 from '@/static/image/emoji/016_难过.png'
|
||||||
|
import jiong017 from '@/static/image/emoji/017_囧.png'
|
||||||
|
import zk018 from '@/static/image/emoji/018_抓狂.png'
|
||||||
|
import t019 from '@/static/image/emoji/019_吐.png'
|
||||||
|
import tx020 from '@/static/image/emoji/020_偷笑.png'
|
||||||
|
import ak021 from '@/static/image/emoji/021_愉快.png'
|
||||||
|
import by022 from '@/static/image/emoji/022_白眼.png'
|
||||||
|
import am023 from '@/static/image/emoji/023_傲慢.png'
|
||||||
|
import k024 from '@/static/image/emoji/024_困.png'
|
||||||
|
import jk025 from '@/static/image/emoji/025_惊恐.png'
|
||||||
|
import hx026 from '@/static/image/emoji/026_憨笑.png'
|
||||||
|
import db027 from '@/static/image/emoji/027_悠闲.png'
|
||||||
|
import zm028 from '@/static/image/emoji/028_咒骂.png'
|
||||||
|
import yw029 from '@/static/image/emoji/029_疑问.png'
|
||||||
|
import x030 from '@/static/image/emoji/030_嘘.png'
|
||||||
|
import y031 from '@/static/image/emoji/031_晕.png'
|
||||||
|
import s032 from '@/static/image/emoji/032_衰.png'
|
||||||
|
import kt033 from '@/static/image/emoji/033_骷髅.png'
|
||||||
|
import qd034 from '@/static/image/emoji/034_敲打.png'
|
||||||
|
import zj035 from '@/static/image/emoji/035_再见.png'
|
||||||
|
import ch036 from '@/static/image/emoji/036_擦汗.png'
|
||||||
|
import kb037 from '@/static/image/emoji/037_抠鼻.png'
|
||||||
|
import zz038 from '@/static/image/emoji/038_鼓掌.png'
|
||||||
|
import hx039 from '@/static/image/emoji/039_坏笑.png'
|
||||||
|
import rh040 from '@/static/image/emoji/040_右哼哼.png'
|
||||||
|
import bs041 from '@/static/image/emoji/041_鄙视.png'
|
||||||
|
import wq042 from '@/static/image/emoji/042_委屈.png'
|
||||||
|
import kq043 from '@/static/image/emoji/043_快哭了.png'
|
||||||
|
import xs044 from '@/static/image/emoji/044_阴险.png'
|
||||||
|
import qq045 from '@/static/image/emoji/045_亲亲.png'
|
||||||
|
import kl046 from '@/static/image/emoji/046_可怜.png'
|
||||||
|
import xl047 from '@/static/image/emoji/047_笑脸.png'
|
||||||
|
import sb048 from '@/static/image/emoji/048_生病.png'
|
||||||
|
import lh049 from '@/static/image/emoji/049_脸红.png'
|
||||||
|
import ptwx050 from '@/static/image/emoji/050_破涕为笑.png'
|
||||||
|
import kj051 from '@/static/image/emoji/051_恐惧.png'
|
||||||
|
import sw052 from '@/static/image/emoji/052_失望.png'
|
||||||
|
import wy053 from '@/static/image/emoji/053_无语.png'
|
||||||
|
import hh054 from '@/static/image/emoji/054_嘿哈.png'
|
||||||
|
import wl055 from '@/static/image/emoji/055_捂脸.png'
|
||||||
|
import jx056 from '@/static/image/emoji/056_奸笑.png'
|
||||||
|
import jz057 from '@/static/image/emoji/057_机智.png'
|
||||||
|
import zm058 from '@/static/image/emoji/058_皱眉.png'
|
||||||
|
import ye059 from '@/static/image/emoji/059_耶.png'
|
||||||
|
import cg060 from '@/static/image/emoji/060_吃瓜.png'
|
||||||
|
import jy061 from '@/static/image/emoji/061_加油.png'
|
||||||
|
import han062 from '@/static/image/emoji/062_汗.png'
|
||||||
|
import ta063 from '@/static/image/emoji/063_天啊.png'
|
||||||
|
import emm064 from '@/static/image/emoji/064_Emm.png'
|
||||||
|
import shh065 from '@/static/image/emoji/065_社会社会.png'
|
||||||
|
import wc066 from '@/static/image/emoji/066_旺柴.png'
|
||||||
|
import hd067 from '@/static/image/emoji/067_好的.png'
|
||||||
|
import df068 from '@/static/image/emoji/068_打脸.png'
|
||||||
|
import w069 from '@/static/image/emoji/069_哇.png'
|
||||||
|
import fb070 from '@/static/image/emoji/070_翻白眼.png'
|
||||||
|
import lz071 from '@/static/image/emoji/071_666.png'
|
||||||
|
import mkwk072 from '@/static/image/emoji/072_让我看看.png'
|
||||||
|
import tx073 from '@/static/image/emoji/073_叹气.png'
|
||||||
|
import gs074 from '@/static/image/emoji/074_苦涩.png'
|
||||||
|
import lk075 from '@/static/image/emoji/075_裂开.png'
|
||||||
|
import pf076 from '@/static/image/emoji/076_嘴唇.png'
|
||||||
|
import ax077 from '@/static/image/emoji/077_爱心.png'
|
||||||
|
import xz078 from '@/static/image/emoji/078_心碎.png'
|
||||||
|
import b079 from '@/static/image/emoji/079_拥抱.png'
|
||||||
|
import qz080 from '@/static/image/emoji/080_强.png'
|
||||||
|
import r081 from '@/static/image/emoji/081_弱.png'
|
||||||
|
import ws082 from '@/static/image/emoji/082_握手.png'
|
||||||
|
import ss083 from '@/static/image/emoji/083_胜利.png'
|
||||||
|
import bq084 from '@/static/image/emoji/084_抱拳.png'
|
||||||
|
import g085 from '@/static/image/emoji/085_勾引.png'
|
||||||
|
import qd086 from '@/static/image/emoji/086_拳头.png'
|
||||||
|
import ok087 from '@/static/image/emoji/087_OK.png'
|
||||||
|
import h088 from '@/static/image/emoji/088_合十.png'
|
||||||
|
import pj089 from '@/static/image/emoji/089_啤酒.png'
|
||||||
|
import kf090 from '@/static/image/emoji/090_咖啡.png'
|
||||||
|
import dg091 from '@/static/image/emoji/091_蛋糕.png'
|
||||||
|
import mz092 from '@/static/image/emoji/092_玫瑰.png'
|
||||||
|
import j093 from '@/static/image/emoji/093_凋谢.png'
|
||||||
|
import c094 from '@/static/image/emoji/094_菜刀.png'
|
||||||
|
import zz095 from '@/static/image/emoji/095_炸弹.png'
|
||||||
|
import bb096 from '@/static/image/emoji/096_便便.png'
|
||||||
|
import yl097 from '@/static/image/emoji/097_月亮.png'
|
||||||
|
import ty098 from '@/static/image/emoji/098_太阳.png'
|
||||||
|
import qz099 from '@/static/image/emoji/099_庆祝.png'
|
||||||
|
import lw100 from '@/static/image/emoji/100_礼物.png'
|
||||||
|
import hb101 from '@/static/image/emoji/101_红包.png'
|
||||||
|
import f102 from '@/static/image/emoji/102_發.png'
|
||||||
|
import fu103 from '@/static/image/emoji/103_福.png'
|
||||||
|
import yh104 from '@/static/image/emoji/104_烟花.png'
|
||||||
|
import bz105 from '@/static/image/emoji/105_爆竹.png'
|
||||||
|
import zt106 from '@/static/image/emoji/106_猪头.png'
|
||||||
|
import tt107 from '@/static/image/emoji/107_跳跳.png'
|
||||||
|
import fd108 from '@/static/image/emoji/108_发抖.png'
|
||||||
|
import zq109 from '@/static/image/emoji/109_转圈.png'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
/**
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 动态表情
|
* 动态表情
|
||||||
*/
|
*/
|
||||||
@ -13,167 +121,219 @@ export const emojis = {
|
|||||||
'[撇嘴]':
|
'[撇嘴]':
|
||||||
`<img class='emoji' src='${pz002}'>`,
|
`<img class='emoji' src='${pz002}'>`,
|
||||||
'[色]':
|
'[色]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/2.gif'>",
|
`<img class='emoji' src='${se003}'>`,
|
||||||
'[发呆]':
|
'[发呆]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/3.gif'>",
|
`<img class='emoji' src='${fd004}'>`,
|
||||||
'[得意]':
|
'[得意]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/4.gif'>",
|
`<img class='emoji' src='${dd005}'>`,
|
||||||
'[流泪]':
|
'[流泪]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/5.gif'>",
|
`<img class='emoji' src='${ll006}'>`,
|
||||||
'[害羞]':
|
'[害羞]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/6.gif'>",
|
`<img class='emoji' src='${hs007}'>`,
|
||||||
'[闭嘴]':
|
'[闭嘴]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/7.gif'>",
|
`<img class='emoji' src='${bz008}'>`,
|
||||||
'[睡]':
|
'[睡]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/8.gif'>",
|
`<img class='emoji' src='${sh009}'>`,
|
||||||
'[大哭]':
|
'[大哭]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/9.gif'>",
|
`<img class='emoji' src='${dc010}'>`,
|
||||||
'[尴尬]':
|
'[尴尬]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/10.gif'>",
|
`<img class='emoji' src='${gg011}'>`,
|
||||||
'[发怒]':
|
'[发怒]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/11.gif'>",
|
`<img class='emoji' src='${fl012}'>`,
|
||||||
'[调皮]':
|
'[调皮]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/12.gif'>",
|
`<img class='emoji' src='${tp013}'>`,
|
||||||
'[呲牙]':
|
'[呲牙]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/13.gif'>",
|
`<img class='emoji' src='${cz014}'>`,
|
||||||
'[惊讶]':
|
'[惊讶]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/14.gif'>",
|
`<img class='emoji' src='${jy015}'>`,
|
||||||
'[难过]':
|
'[难过]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/15.gif'>",
|
`<img class='emoji' src='${nd016}'>`,
|
||||||
'[酷]':
|
'[囧]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/16.gif'>",
|
`<img class='emoji' src='${jiong017}'>`,
|
||||||
'[冷汗]':
|
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/17.gif'>",
|
|
||||||
'[抓狂]':
|
'[抓狂]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/18.gif'>",
|
`<img class='emoji' src='${zk018}'>`,
|
||||||
'[吐]':
|
'[吐]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/19.gif'>",
|
`<img class='emoji' src='${t019}'>`,
|
||||||
'[偷笑]':
|
'[偷笑]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/20.gif'>",
|
`<img class='emoji' src='${tx020}'>`,
|
||||||
'[可爱]':
|
'[可爱]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/21.gif'>",
|
`<img class='emoji' src='${ak021}'>`,
|
||||||
'[白眼]':
|
'[白眼]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/22.gif'>",
|
`<img class='emoji' src='${by022}'>`,
|
||||||
'[傲慢]':
|
'[傲慢]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/23.gif'>",
|
`<img class='emoji' src='${am023}'>`,
|
||||||
'[饥饿]':
|
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/24.gif'>",
|
|
||||||
'[困]':
|
'[困]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/25.gif'>",
|
`<img class='emoji' src='${k024}'>`,
|
||||||
'[惊恐]':
|
'[惊恐]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/26.gif'>",
|
`<img class='emoji' src='${jk025}'>`,
|
||||||
'[流汗]':
|
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/27.gif'>",
|
|
||||||
'[憨笑]':
|
'[憨笑]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/28.gif'>",
|
`<img class='emoji' src='${hx026}'>`,
|
||||||
'[大兵]':
|
'[大兵]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/29.gif'>",
|
`<img class='emoji' src='${db027}'>`,
|
||||||
'[奋斗]':
|
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/30.gif'>",
|
|
||||||
'[咒骂]':
|
'[咒骂]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/31.gif'>",
|
`<img class='emoji' src='${zm028}'>`,
|
||||||
'[疑问]':
|
'[疑问]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/32.gif'>",
|
`<img class='emoji' src='${yw029}'>`,
|
||||||
'[嘘]':
|
'[嘘]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/33.gif'>",
|
`<img class='emoji' src='${x030}'>`,
|
||||||
'[晕]':
|
'[晕]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/34.gif'>",
|
`<img class='emoji' src='${y031}'>`,
|
||||||
'[折磨]':
|
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/35.gif'>",
|
|
||||||
'[衰]':
|
'[衰]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/36.gif'>",
|
`<img class='emoji' src='${s032}'>`,
|
||||||
'[骷髅]':
|
'[骷髅]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/37.gif'>",
|
`<img class='emoji' src='${kt033}'>`,
|
||||||
'[敲打]':
|
'[敲打]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/38.gif'>",
|
`<img class='emoji' src='${qd034}'>`,
|
||||||
'[再见]':
|
'[再见]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/39.gif'>",
|
`<img class='emoji' src='${zj035}'>`,
|
||||||
'[擦汗]':
|
'[擦汗]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/40.gif'>",
|
`<img class='emoji' src='${ch036}'>`,
|
||||||
'[抠鼻]':
|
'[抠鼻]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/41.gif'>",
|
`<img class='emoji' src='${kb037}'>`,
|
||||||
'[鼓掌]':
|
'[鼓掌]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/42.gif'>",
|
`<img class='emoji' src='${zz038}'>`,
|
||||||
'[糗大了]':
|
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/43.gif'>",
|
|
||||||
'[坏笑]':
|
'[坏笑]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/44.gif'>",
|
`<img class='emoji' src='${hx039}'>`,
|
||||||
'[左哼哼]':
|
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/45.gif'>",
|
|
||||||
'[右哼哼]':
|
'[右哼哼]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/46.gif'>",
|
`<img class='emoji' src='${rh040}'>`,
|
||||||
'[哈欠]':
|
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/47.gif'>",
|
|
||||||
'[鄙视]':
|
'[鄙视]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/48.gif'>",
|
`<img class='emoji' src='${bs041}'>`,
|
||||||
'[委屈]':
|
'[委屈]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/49.gif'>",
|
`<img class='emoji' src='${wq042}'>`,
|
||||||
'[快哭了]':
|
'[快哭了]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/50.gif'>",
|
`<img class='emoji' src='${kq043}'>`,
|
||||||
'[阴险]':
|
'[阴险]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/51.gif'>",
|
`<img class='emoji' src='${xs044}'>`,
|
||||||
'[亲亲]':
|
'[亲亲]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/52.gif'>",
|
`<img class='emoji' src='${qq045}'>`,
|
||||||
'[吓]':
|
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/53.gif'>",
|
|
||||||
'[可怜]':
|
'[可怜]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/54.gif'>",
|
`<img class='emoji' src='${kl046}'>`,
|
||||||
'[菜刀]':
|
'[笑脸]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/55.gif'>",
|
`<img class='emoji' src='${xl047}'>`,
|
||||||
'[西瓜]':
|
'[生病]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/56.gif'>",
|
`<img class='emoji' src='${sb048}'>`,
|
||||||
'[啤酒]':
|
'[脸红]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/57.gif'>",
|
`<img class='emoji' src='${lh049}'>`,
|
||||||
'[篮球]':
|
'[破涕为笑]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/58.gif'>",
|
`<img class='emoji' src='${ptwx050}'>`,
|
||||||
'[咖啡]':
|
'[恐惧]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/60.gif'>",
|
`<img class='emoji' src='${kj051}'>`,
|
||||||
'[饭]':
|
'[失望]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/61.gif'>",
|
`<img class='emoji' src='${sw052}'>`,
|
||||||
'[玫瑰]':
|
'[无语]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/63.gif'>",
|
`<img class='emoji' src='${wy053}'>`,
|
||||||
'[凋谢]':
|
'[嘿哈]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/64.gif'>",
|
`<img class='emoji' src='${hh054}'>`,
|
||||||
'[示爱]':
|
'[捂脸]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/65.gif'>",
|
`<img class='emoji' src='${wl055}'>`,
|
||||||
|
'[奸笑]':
|
||||||
|
`<img class='emoji' src='${jx056}'>`,
|
||||||
|
'[机智]':
|
||||||
|
`<img class='emoji' src='${jz057}'>`,
|
||||||
|
'[皱眉]':
|
||||||
|
`<img class='emoji' src='${zm058}'>`,
|
||||||
|
'[耶]':
|
||||||
|
`<img class='emoji' src='${ye059}'>`,
|
||||||
|
'[吃瓜]':
|
||||||
|
`<img class='emoji' src='${cg060}'>`,
|
||||||
|
'[加油]':
|
||||||
|
`<img class='emoji' src='${jy061}'>`,
|
||||||
|
'[汗]':
|
||||||
|
`<img class='emoji' src='${han062}'>`,
|
||||||
|
'[天啊]':
|
||||||
|
`<img class='emoji' src='${ta063}'>`,
|
||||||
|
'[Emm]':
|
||||||
|
`<img class='emoji' src='${emm064}'>`,
|
||||||
|
'[社会社会]':
|
||||||
|
`<img class='emoji' src='${shh065}'>`,
|
||||||
|
'[旺柴]':
|
||||||
|
`<img class='emoji' src='${wc066}'>`,
|
||||||
|
'[好的]':
|
||||||
|
`<img class='emoji' src='${hd067}'>`,
|
||||||
|
'[打脸]':
|
||||||
|
`<img class='emoji' src='${df068}'>`,
|
||||||
|
'[哇]':
|
||||||
|
`<img class='emoji' src='${w069}'>`,
|
||||||
|
'[翻白眼]':
|
||||||
|
`<img class='emoji' src='${fb070}'>`,
|
||||||
|
'[666]':
|
||||||
|
`<img class='emoji' src='${lz071}'>`,
|
||||||
|
'[让我看看]':
|
||||||
|
`<img class='emoji' src='${mkwk072}'>`,
|
||||||
|
'[叹气]':
|
||||||
|
`<img class='emoji' src='${tx073}'>`,
|
||||||
|
'[苦涩]':
|
||||||
|
`<img class='emoji' src='${gs074}'>`,
|
||||||
|
'[裂开]':
|
||||||
|
`<img class='emoji' src='${lk075}'>`,
|
||||||
|
'[嘴唇]':
|
||||||
|
`<img class='emoji' src='${pf076}'>`,
|
||||||
'[爱心]':
|
'[爱心]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/66.gif'>",
|
`<img class='emoji' src='${ax077}'>`,
|
||||||
'[心碎]':
|
'[心碎]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/67.gif'>",
|
`<img class='emoji' src='${xz078}'>`,
|
||||||
'[蛋糕]':
|
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/68.gif'>",
|
|
||||||
'[炸弹]':
|
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/70.gif'>",
|
|
||||||
'[刀]':
|
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/71.gif'>",
|
|
||||||
'[足球]':
|
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/72.gif'>",
|
|
||||||
'[礼物]':
|
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/77.gif'>",
|
|
||||||
'[拥抱]':
|
'[拥抱]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/78.gif'>",
|
`<img class='emoji' src='${b079}'>`,
|
||||||
'[强]':
|
'[强]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/79.gif'>",
|
`<img class='emoji' src='${qz080}'>`,
|
||||||
'[弱]':
|
'[弱]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/80.gif'>",
|
`<img class='emoji' src='${r081}'>`,
|
||||||
'[握手]':
|
'[握手]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/81.gif'>",
|
`<img class='emoji' src='${ws082}'>`,
|
||||||
'[胜利]':
|
'[胜利]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/82.gif'>",
|
`<img class='emoji' src='${ss083}'>`,
|
||||||
'[抱拳]':
|
'[抱拳]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/83.gif'>",
|
`<img class='emoji' src='${bq084}'>`,
|
||||||
'[勾引]':
|
'[勾引]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/84.gif'>",
|
`<img class='emoji' src='${g085}'>`,
|
||||||
'[拳头]':
|
'[拳头]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/85.gif'>",
|
`<img class='emoji' src='${qd086}'>`,
|
||||||
'[差劲]':
|
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/86.gif'>",
|
|
||||||
'[爱你]':
|
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/87.gif'>",
|
|
||||||
'[NO]':
|
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/88.gif'>",
|
|
||||||
'[OK]':
|
'[OK]':
|
||||||
"<img class='emoji' src='https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/89.gif'>"
|
`<img class='emoji' src='${ok087}'>`,
|
||||||
|
'[合十]':
|
||||||
|
`<img class='emoji' src='${h088}'>`,
|
||||||
|
'[啤酒]':
|
||||||
|
`<img class='emoji' src='${pj089}'>`,
|
||||||
|
'[咖啡]':
|
||||||
|
`<img class='emoji' src='${kf090}'>`,
|
||||||
|
'[蛋糕]':
|
||||||
|
`<img class='emoji' src='${dg091}'>`,
|
||||||
|
'[玫瑰]':
|
||||||
|
`<img class='emoji' src='${mz092}'>`,
|
||||||
|
'[凋谢]':
|
||||||
|
`<img class='emoji' src='${j093}'>`,
|
||||||
|
'[菜刀]':
|
||||||
|
`<img class='emoji' src='${c094}'>`,
|
||||||
|
'[炸弹]':
|
||||||
|
`<img class='emoji' src='${zz095}'>`,
|
||||||
|
'[便便]':
|
||||||
|
`<img class='emoji' src='${bb096}'>`,
|
||||||
|
'[月亮]':
|
||||||
|
`<img class='emoji' src='${yl097}'>`,
|
||||||
|
'[太阳]':
|
||||||
|
`<img class='emoji' src='${ty098}'>`,
|
||||||
|
'[庆祝]':
|
||||||
|
`<img class='emoji' src='${qz099}'>`,
|
||||||
|
'[礼物]':
|
||||||
|
`<img class='emoji' src='${lw100}'>`,
|
||||||
|
'[红包]':
|
||||||
|
`<img class='emoji' src='${hb101}'>`,
|
||||||
|
'[發]':
|
||||||
|
`<img class='emoji' src='${f102}'>`,
|
||||||
|
'[福]':
|
||||||
|
`<img class='emoji' src='${fu103}'>`,
|
||||||
|
'[烟花]':
|
||||||
|
`<img class='emoji' src='${yh104}'>`,
|
||||||
|
'[爆竹]':
|
||||||
|
`<img class='emoji' src='${bz105}'>`,
|
||||||
|
'[猪头]':
|
||||||
|
`<img class='emoji' src='${zt106}'>`,
|
||||||
|
'[跳跳]':
|
||||||
|
`<img class='emoji' src='${tt107}'>`,
|
||||||
|
'[发抖]':
|
||||||
|
`<img class='emoji' src='${fd108}'>`,
|
||||||
|
'[转圈]':
|
||||||
|
`<img class='emoji' src='${zq109}'>`,
|
||||||
}
|
}
|
||||||
|
|
||||||
const emojisKeys = Object.keys(emojis)
|
const emojisKeys = Object.keys(emojis)
|
||||||
|
124
src/utils/functions.js
Normal file
124
src/utils/functions.js
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
import {useAuth} from "@/store/auth";
|
||||||
|
|
||||||
|
const { token } = useAuth()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过图片url获取图片大小
|
||||||
|
*
|
||||||
|
* @param {String} imgsrc 例如图片名: D8x5f13a53dbc4b9_350x345.png
|
||||||
|
*/
|
||||||
|
export function getImageInfo(imgsrc) {
|
||||||
|
let data = {
|
||||||
|
width: 0,
|
||||||
|
height: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// 尝试从URL参数中获取
|
||||||
|
if (imgsrc.includes('?')) {
|
||||||
|
const urlParams = new URLSearchParams(imgsrc.split('?')[1])
|
||||||
|
const width = urlParams.get('width')
|
||||||
|
const height = urlParams.get('height')
|
||||||
|
|
||||||
|
if (width && height) {
|
||||||
|
return {
|
||||||
|
width: parseInt(width)*1.5,
|
||||||
|
height: parseInt(height)*1.5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果URL参数获取失败,尝试从文件名格式获取
|
||||||
|
// let arr = imgsrc.split('_')
|
||||||
|
// if (arr.length == 1) return data
|
||||||
|
|
||||||
|
// let info = arr[arr.length - 1].match(/\d+x\d+/g)
|
||||||
|
// if (info == null) return data
|
||||||
|
|
||||||
|
// info = info[0].split('x')
|
||||||
|
|
||||||
|
// return {
|
||||||
|
// width: parseInt(info[0]),
|
||||||
|
// height: parseInt(info[1])
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件下载方法
|
||||||
|
*
|
||||||
|
* @param {Number} msgid
|
||||||
|
*/
|
||||||
|
export function download(msg_id) {
|
||||||
|
try {
|
||||||
|
let link = document.createElement('a')
|
||||||
|
// link.target = '_blank'
|
||||||
|
link.href = `${
|
||||||
|
import.meta.env.VITE_BASE_API
|
||||||
|
}/api/v1/talk/records/file/download?msg_id=${msg_id}&token=${token.value}`
|
||||||
|
link.click()
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function insertText(obj, str) {
|
||||||
|
if (document.selection) {
|
||||||
|
let sel = document.selection.createRange()
|
||||||
|
sel.text = str
|
||||||
|
} else if (typeof obj.selectionStart === 'number' && typeof obj.selectionEnd === 'number') {
|
||||||
|
let startPos = obj.selectionStart,
|
||||||
|
endPos = obj.selectionEnd,
|
||||||
|
cursorPos = startPos,
|
||||||
|
tmpStr = obj.value
|
||||||
|
obj.value = tmpStr.substring(0, startPos) + str + tmpStr.substring(endPos, tmpStr.length)
|
||||||
|
cursorPos += str.length
|
||||||
|
obj.selectionStart = obj.selectionEnd = cursorPos
|
||||||
|
|
||||||
|
obj.focus()
|
||||||
|
} else {
|
||||||
|
obj.value += str
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function countDownTime(second = 0) {
|
||||||
|
// 小于10 加0 处理
|
||||||
|
function formate0to9(arg) {
|
||||||
|
return arg < 10 ? `0${arg}` : arg
|
||||||
|
}
|
||||||
|
|
||||||
|
const hours = parseInt((second / 60 / 60) % 24, 10) //剩余的小时
|
||||||
|
const minutes = parseInt((second / 60) % 60, 10) //剩余的分钟
|
||||||
|
const seconds = parseInt(second % 60, 10) //剩余的秒数
|
||||||
|
|
||||||
|
return `${formate0to9(hours)}:${formate0to9(minutes)}:${formate0to9(seconds)}`
|
||||||
|
}
|
||||||
|
|
||||||
|
export function removeTags(str) {
|
||||||
|
return str.replace(/<\/?[^>]+>/gi, '')
|
||||||
|
}
|
||||||
|
|
||||||
|
export function downloadImage(src, name) {
|
||||||
|
let image = new Image()
|
||||||
|
image.setAttribute('crossOrigin', 'anonymous')
|
||||||
|
image.onload = function () {
|
||||||
|
let canvas = document.createElement('canvas')
|
||||||
|
canvas.width = image.width
|
||||||
|
canvas.height = image.height
|
||||||
|
let context = canvas.getContext('2d')
|
||||||
|
context.drawImage(image, 0, 0, image.width, image.height)
|
||||||
|
let url = canvas.toDataURL('image/png')
|
||||||
|
let a = document.createElement('a')
|
||||||
|
let event = new MouseEvent('click')
|
||||||
|
a.download = name || 'image.png'
|
||||||
|
a.href = url
|
||||||
|
a.dispatchEvent(event)
|
||||||
|
}
|
||||||
|
image.src = src
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取文件名后缀
|
||||||
|
export const getFileNameSuffix = (name) => {
|
||||||
|
const arr = name.split('.')
|
||||||
|
return arr[arr.length - 1]
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user