Compare commits

..

No commits in common. "31dcd0ebca60f5d10c60354ad767c593a66efd6b" and "96c4fbaad998dcf92e3a83713a394a2a37846cc2" have entirely different histories.

40 changed files with 275 additions and 1298 deletions

3
components.d.ts vendored
View File

@ -8,8 +8,6 @@ export {}
/* prettier-ignore */ /* prettier-ignore */
declare module 'vue' { declare module 'vue' {
export interface GlobalComponents { export interface GlobalComponents {
AsyncError: typeof import('./src/components/async-error/index.vue')['default']
AsyncLoading: typeof import('./src/components/async-loading/index.vue')['default']
AudioMessage: typeof import('./src/components/talk/message/AudioMessage.vue')['default'] AudioMessage: typeof import('./src/components/talk/message/AudioMessage.vue')['default']
Avatar: typeof import('./src/components/base/Avatar.vue')['default'] Avatar: typeof import('./src/components/base/Avatar.vue')['default']
AvatarCropper: typeof import('./src/components/base/AvatarCropper.vue')['default'] AvatarCropper: typeof import('./src/components/base/AvatarCropper.vue')['default']
@ -39,7 +37,6 @@ declare module 'vue' {
SysGroupAdminMessage: typeof import('./src/components/talk/message/system/SysGroupAdminMessage.vue')['default'] SysGroupAdminMessage: typeof import('./src/components/talk/message/system/SysGroupAdminMessage.vue')['default']
SysGroupCancelMutedMessage: typeof import('./src/components/talk/message/system/SysGroupCancelMutedMessage.vue')['default'] SysGroupCancelMutedMessage: typeof import('./src/components/talk/message/system/SysGroupCancelMutedMessage.vue')['default']
SysGroupCreateMessage: typeof import('./src/components/talk/message/system/SysGroupCreateMessage.vue')['default'] SysGroupCreateMessage: typeof import('./src/components/talk/message/system/SysGroupCreateMessage.vue')['default']
SysGroupDismissed: typeof import('./src/components/talk/message/system/SysGroupDismissed.vue')['default']
SysGroupInfoChangeMessage: typeof import('./src/components/talk/message/system/SysGroupInfoChangeMessage.vue')['default'] SysGroupInfoChangeMessage: typeof import('./src/components/talk/message/system/SysGroupInfoChangeMessage.vue')['default']
SysGroupJoinMessage: typeof import('./src/components/talk/message/system/SysGroupJoinMessage.vue')['default'] SysGroupJoinMessage: typeof import('./src/components/talk/message/system/SysGroupJoinMessage.vue')['default']
SysGroupMemberCancelMutedMessage: typeof import('./src/components/talk/message/system/SysGroupMemberCancelMutedMessage.vue')['default'] SysGroupMemberCancelMutedMessage: typeof import('./src/components/talk/message/system/SysGroupMemberCancelMutedMessage.vue')['default']

7
env/.env.prod vendored
View File

@ -5,9 +5,4 @@ VITE_SHOW_CONSOLE = false
# 是否开启sourcemap # 是否开启sourcemap
VITE_SHOW_SOURCEMAP = false VITE_SHOW_SOURCEMAP = false
# baseUrl # baseUrl
VITE_BASEURL = 'https://chat-out.szjixun.cn' #体制外 VITE_BASEURL = 'https://oa-a.szjixun.cn/api'
#VITE_SOCKET_API
VITE_SOCKET_API = 'wss://chat-out.szjixun.cn' #体制外
# EPRAPI baseUrl
VITE_EPR_BASEURL = 'https://erpapi-out.szjixun.cn' #体制外

View File

@ -1,11 +1,10 @@
<script setup> <script setup>
import { useStatus } from '@/store/status' import { useStatus } from '@/store/status'
import { useUserStore, useDialogueListStore } from '@/store' import { useUserStore } from '@/store'
import { useProvideUserModal } from '@/hooks' import { useProvideUserModal } from '@/hooks'
import {useAuth} from "@/store/auth"; import {useAuth} from "@/store/auth";
const {token} = useAuth() const {token} = useAuth()
import ws from '@/connect' import ws from '@/connect'
import {uniStorage} from "@/utils/uniStorage.js"
const { statusBarHeight } = useStatus() const { statusBarHeight } = useStatus()
const { uid, isShow } = useProvideUserModal() const { uid, isShow } = useProvideUserModal()
const userStore = useUserStore() const userStore = useUserStore()
@ -20,14 +19,10 @@ const handleWebview = () => {
// }) // })
console.log("webview", webview) console.log("webview", webview)
token.value = webview.token token.value = webview.token
if(webview?.doClearDialogueList){
useDialogueListStore().dialogueList.value = []
uniStorage.removeItem('dialogueList')
}
userStore.loadSetting()
ws.connect()
} }
const init = () => { const init = () => {
userStore.loadSetting()
ws.connect()
if (typeof plus !== 'undefined') { if (typeof plus !== 'undefined') {
handleWebview() handleWebview()
} else { } else {

View File

@ -1,9 +1,5 @@
import request from '@/service/index.js' import request from '@/service/index.js'
import qs from 'qs' import qs from 'qs'
import {
useTalkStore,
useDialogueStore
} from '@/store'
// 获取聊天列表服务接口 // 获取聊天列表服务接口
export const ServeGetTalkList = (data) => { export const ServeGetTalkList = (data) => {
@ -42,27 +38,7 @@ export const ServeTopTalkList = (data) => {
} }
// 清除聊天消息未读数服务接口 // 清除聊天消息未读数服务接口
export const ServeClearTalkUnreadNum = (data, unReadNum) => { export const ServeClearTalkUnreadNum = (data) => {
console.log('=======chatApp==UnreadNum', unReadNum)
if(!useTalkStore().items[useTalkStore().findTalkIndex(useDialogueStore().index_name)]?.is_disturb){
if (typeof plus !== 'undefined') {
let OAWebView = plus.webview.all()
OAWebView.forEach((webview) => {
if (webview.id === 'webviewId1') {
webview.evalJS(`updateUnreadMsgNumReduce('${unReadNum}')`)
}
})
} else {
document.addEventListener('plusready', () => {
let OAWebView = plus.webview.all()
OAWebView.forEach((webview) => {
if (webview.id === 'webviewId1') {
webview.evalJS(`updateUnreadMsgNumReduce('${unReadNum}')`)
}
})
})
}
}
return request({ return request({
url: '/api/v1/talk/unread/clear', url: '/api/v1/talk/unread/clear',
method: 'POST', method: 'POST',
@ -193,15 +169,14 @@ export const ServeConfirmVoteHandle = (data) => {
}) })
} }
export const uploadImg = (data, onProgressFn) => { export const uploadImg = (data,onProgressFn) => {
return request({ return request({
url: '/upload/img', url: '/upload/img',
method: 'POST', method: 'POST',
data: data, data:data,
baseURL: import.meta.env.VITE_EPR_BASEURL, baseURL:import.meta.env.VITE_EPR_BASEURL,
isFormData: true, isFormData:true,
onUploadProgress: (progressEvent) => onUploadProgress:(progressEvent)=>onProgressFn(progressEvent,data.get('file'))
onProgressFn(progressEvent, data.get('file')),
}) })
} }
// 根据msg_id获取消息 // 根据msg_id获取消息

View File

@ -1,79 +0,0 @@
<script setup>
import { computed } from 'vue';
location.reload(true);
</script>
<template>
<div class="loader">
<p class="heading">加载中</p>
<div class="loading">
<div class="load"></div>
<div class="load"></div>
<div class="load"></div>
<div class="load"></div>
</div>
</div>
</template>
<!-- 重启页面 -->
<style scoped lang="scss">
.loader {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
}
.heading {
color: black;
letter-spacing: 0.2em;
margin-bottom: 1em;
}
.loading {
display: flex;
width: 5em;
align-items: center;
justify-content: center;
}
.load {
width: 23px;
height: 3px;
background-color: limegreen;
animation: 1s move_5011 infinite;
border-radius: 5px;
margin: 0.1em;
}
.load:nth-child(1) {
animation-delay: 0.2s;
}
.load:nth-child(2) {
animation-delay: 0.4s;
}
.load:nth-child(3) {
animation-delay: 0.6s;
}
@keyframes move_5011 {
0% {
width: 0.2em;
}
25% {
width: 0.7em;
}
50% {
width: 1.5em;
}
100% {
width: 0.2em;
}
}
</style>

View File

@ -1,78 +0,0 @@
<script setup>
import { computed } from 'vue';
</script>
<template>
<div class="loader">
<p class="heading">加载中</p>
<div class="loading">
<div class="load"></div>
<div class="load"></div>
<div class="load"></div>
<div class="load"></div>
</div>
</div>
</template>
<style scoped lang="scss">
.loader {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
}
.heading {
color: black;
letter-spacing: 0.2em;
margin-bottom: 1em;
}
.loading {
display: flex;
width: 5em;
align-items: center;
justify-content: center;
}
.load {
width: 23px;
height: 3px;
background-color: limegreen;
animation: 1s move_5011 infinite;
border-radius: 5px;
margin: 0.1em;
}
.load:nth-child(1) {
animation-delay: 0.2s;
}
.load:nth-child(2) {
animation-delay: 0.4s;
}
.load:nth-child(3) {
animation-delay: 0.6s;
}
@keyframes move_5011 {
0% {
width: 0.2em;
}
25% {
width: 0.7em;
}
50% {
width: 1.5em;
}
100% {
width: 0.2em;
}
}
</style>

View File

@ -1,6 +1,7 @@
<template> <template>
<tm-navbar <tm-navbar
:hideBack="props.hideBack" :hideBack="props.hideBack"
hideHome
:title="props.title" :title="props.title"
:shadow="props.shadowNum" :shadow="props.shadowNum"
:fontSize="34" :fontSize="34"

View File

@ -55,7 +55,7 @@ const getFileTypeIMG = computed(() => {
default: default:
objT.finishedImg = filePaperOther objT.finishedImg = filePaperOther
objT.blankImg = filePaperOtherBlank objT.blankImg = filePaperOtherBlank
objT.progressColor = '#46299d' objT.progressColor = '#747474'
} }
return objT return objT
}) })
@ -132,7 +132,7 @@ const downloadAndOpenFile = () => {
:height="95" :height="95"
:src="getFileTypeIMG.blankImg" :src="getFileTypeIMG.blankImg"
></tm-image> ></tm-image>
<wd-circle v-if="data.uploadStatus === 1" <wd-circle
customClass="circleProgress" customClass="circleProgress"
:modelValue="data.uploadCurrent" :modelValue="data.uploadCurrent"
layerColor="#E3E3E3" layerColor="#E3E3E3"
@ -140,9 +140,6 @@ const downloadAndOpenFile = () => {
:strokeWidth="3" :strokeWidth="3"
:size="20" :size="20"
></wd-circle> ></wd-circle>
<div class="upload-failed" v-if="data.uploadStatus === 3">
<tm-icon :font-size="20" name="tmicon-times" color="#fff"></tm-icon>
</div>
</div> </div>
</div> </div>
<div class="divider mt-[28rpx]"></div> <div class="divider mt-[28rpx]"></div>
@ -291,20 +288,4 @@ const downloadAndOpenFile = () => {
width: 40rpx !important; width: 40rpx !important;
height: 40rpx !important; height: 40rpx !important;
} }
.upload-failed {
position: absolute;
top: 120rpx;
right: 52rpx;
transform: translate(-50%, -50%);
z-index: 1;
width: 40rpx;
height: 40rpx;
display: flex;
align-items: center;
justify-content: center;
color: #ff4d4f;
background: #ff4d4f;
border-radius: 50%;
}
</style> </style>

View File

@ -12,40 +12,40 @@ const img = computed(() => {
// console.log(props.extra); // console.log(props.extra);
let info = { let info = {
width: 0, width: 0,
height: 0, height: 0
} }
if (props.extra.url.includes('blob:http://')) { if (props.extra.url.includes('blob:http://')) {
info = { info = {
width: props.extra.width, width: props.extra.width,
height: props.extra.height, height: props.extra.height
} }
} else { }else {
info = getImageInfo(props.extra.url) info = getImageInfo(props.extra.url)
} }
if (info.width == 0 || info.height == 0) { if (info.width == 0 || info.height == 0) {
return { return {
width: 450, width: 450,
height: 298, height: 298
} }
} }
if (info.width < 300) { if(info.width<300){
return { return {
width: 300, width: 300,
height: info.height / (info.width / 300), height: info.height / (info.width / 300)
} }
} }
if (info.width < 350) { if (info.width < 350) {
return { return {
width: info.width, width: info.width,
height: info.height, height: info.height
} }
} }
return { return {
width: 350, width: 350,
height: info.height / (info.width / 350), height: info.height / (info.width / 350)
} }
}) })
</script> </script>
@ -54,30 +54,13 @@ const img = computed(() => {
class="im-message-image" class="im-message-image"
:class="{ :class="{
left: data.float === 'left', left: data.float === 'left',
right: data.float === 'right', right: data.float === 'right'
}" }"
> >
<div class="image-container"> <div class="image-container">
<div class="relative"> <tm-image preview :width="img.width" :height="img.height" :src="extra.url" />
<tm-image <wd-circle custom-class="circleProgress" v-if="props.data.uploadCurrent && props.data.uploadCurrent<100" v-model="props.data.uploadCurrent" color="#ffffff" layer-color="#E3E3E3"></wd-circle>
preview </div>
:width="img.width"
:height="img.height"
:src="extra.url"
model="aspectFill"
/>
<wd-circle
custom-class="circleProgress"
v-if="data.uploadStatus === 1"
v-model="props.data.uploadCurrent"
color="#46299d"
layer-color="#E3E3E3"
></wd-circle>
<div class="upload-failed" v-if="data.uploadStatus === 3">
<tm-icon :font-size="20" name="tmicon-times" color="#fff"></tm-icon>
</div>
</div>
</div>
</section> </section>
</template> </template>
<style lang="less" scoped> <style lang="less" scoped>
@ -96,12 +79,12 @@ const img = computed(() => {
} }
&.right { &.right {
background-color: #46299d; background-color: #46299D;
border-radius: 16rpx 0 16rpx 16rpx; border-radius: 16rpx 0 16rpx 16rpx;
} }
} }
.image-container { .image-container {
position: relative; position: relative;
.circleProgress { .circleProgress {
position: absolute; position: absolute;
@ -111,18 +94,4 @@ const img = computed(() => {
z-index: 1; z-index: 1;
} }
} }
.upload-failed {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 1;
width: 40rpx;
height: 40rpx;
display: flex;
align-items: center;
justify-content: center;
background: #ff4d4f;
border-radius: 50%;
}
</style> </style>

View File

@ -15,7 +15,7 @@ const float = props.data.float
const textContent = computed(() => { const textContent = computed(() => {
let text = props.extra?.content || '' let text = props.extra?.content || ''
// text = textReplaceLink(text) text = textReplaceLink(text)
if (props.data.talk_type == 2) { if (props.data.talk_type == 2) {
text = textReplaceMention(text, '#1890ff') text = textReplaceMention(text, '#1890ff')
} }

View File

@ -1,8 +1,8 @@
<script lang="ts" setup> <script lang="ts" setup>
import { ref, nextTick, getCurrentInstance, computed, onMounted } from 'vue' import { ref, nextTick, getCurrentInstance, computed, onMounted } from 'vue'
import { getImageInfo } from '@/utils/functions' import { getImageInfo } from '@/utils/functions'
import playCircle from '@/static/image/chatList/playCircle@2x.png' import playCircle from "@/static/image/chatList/playCircle@2x.png";
import { useStatus } from '@/store/status' import { useStatus } from "@/store/status";
const { statusBarHeight } = useStatus() const { statusBarHeight } = useStatus()
const instance = getCurrentInstance() const instance = getCurrentInstance()
@ -20,12 +20,12 @@ const open = ref(false)
const img = computed(() => { const img = computed(() => {
let info = { let info = {
width: 0, width: 0,
height: 0, height: 0
} }
if (props.extra.url.includes('blob:http://')) { if (props.extra.url.includes('blob:http://')) {
info = { info = {
width: props.extra.width, width: props.extra.width,
height: props.extra.height, height: props.extra.height
} }
} else { } else {
info = getImageInfo(props.extra.url) info = getImageInfo(props.extra.url)
@ -34,26 +34,26 @@ const img = computed(() => {
if (info.width == 0 || info.height == 0) { if (info.width == 0 || info.height == 0) {
return { return {
width: 450, width: 450,
height: 298, height: 298
} }
} }
if (info.width < 300) { if (info.width < 300) {
return { return {
width: 300, width: 300,
height: info.height / (info.width / 300), height: info.height / (info.width / 300)
} }
} }
if (info.width < 350) { if (info.width < 350) {
return { return {
width: info.width, width: info.width,
height: info.height, height: info.height
} }
} }
return { return {
width: 350, width: 350,
height: info.height / (info.width / 350), height: info.height / (info.width / 350)
} }
}) })
@ -67,98 +67,57 @@ const fullscreenchange = (e) => {
/* 视频播放 获取第一帧 */ /* 视频播放 获取第一帧 */
const canplay = (e) => { const canplay = (e) => {
console.log('Video can play:', e) console.log('Video can play:', e);
if (e.target) { if (e.target) {
setTimeout(() => { setTimeout(() => {
e.target.pause() e.target.pause();
}, 200) }, 200);
} }
} };
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()
videoContext.value = uni.createVideoContext(props.extra.url, instance)
setTimeout(() => {
//
videoContext.value.requestFullScreen({ direction: 2 })
//
setTimeout(() => {
videoContext.value.play()
}, 100)
}, 200)
} }
onMounted(() => { onMounted(() => {
videoRef.value = uni.createVideoContext(props.data.msg_id) videoRef.value = uni.createVideoContext(props.data.msg_id);
videoRef.value.play() videoRef.value.play()
setTimeout(() => { setTimeout(() => {
videoRef.value.pause() videoRef.value.pause()
}, 200) }, 200);
}) })
</script> </script>
<template> <template>
<section <section class="im-message-video" :class="{ left: data.float === 'left' }" @click="onPlay">
class="im-message-video" <div class="coverVideo" :style="{
:class="{ left: data.float === 'left' }" width: img.width + 'rpx',
@click="onPlay" height: img.height + 'rpx'
> }" v-if="props.extra.url.includes('blob:http://')">
<div <video :id="data.msg_id" :autoplay="false" disablepictureinpicture muted :src="props.extra.url" width="100%"
class="coverVideo" height="100%" playsinline preload="auto" controls="false" x5-playsinline
:style="{ webkit-playsinline style="object-fit: cover; pointer-events: none;">
width: img.width + 'rpx', </video>
height: img.height + 'rpx',
}"
v-if="props.extra.url.includes('blob:http://')"
>
<video
:id="data.msg_id"
:autoplay="false"
disablepictureinpicture
muted
:src="props.extra.url"
width="100%"
height="100%"
playsinline
preload="auto"
controls="false"
x5-playsinline
webkit-playsinline
style="object-fit: cover; pointer-events: none;"
></video>
</div> </div>
<wd-img <wd-img v-else :width="`${img.width}rpx`" :height="`${img.height}rpx`" :src="data.extra.cover" />
v-else <div v-if="data.uploadStatus === 2 || !data.uploadStatus" class="btn-video" :style="{
:width="`${img.width}rpx`" width: img.width + 'rpx',
:height="`${img.height}rpx`" height: img.height + 'rpx'
:src="data.extra.cover" }">
/>
<div
v-if="data.uploadStatus === 2 || !data.uploadStatus"
class="btn-video"
:style="{
width: img.width + 'rpx',
height: img.height + 'rpx',
}"
>
<tm-image :src="playCircle" :width="80" :height="80" /> <tm-image :src="playCircle" :width="80" :height="80" />
</div> </div>
<div <div v-else class="btn-video" :style="{
v-else width: img.width + 'rpx',
class="btn-video" height: img.height + 'rpx'
:style="{ }" >
width: img.width + 'rpx',
height: img.height + 'rpx',
}"
>
<wd-circle <wd-circle
v-if="data.uploadStatus === 1"
v-model="props.data.uploadCurrent" v-model="props.data.uploadCurrent"
customClass="circleProgress" customClass="circleProgress"
color="#46299d" layerColor="#E3E3E3"
layer-color="#E3E3E3" color="#FFFFFF"
:strokeWidth="6" :strokeWidth="6"
:size="40" :size="40"
></wd-circle> ></wd-circle>
@ -172,32 +131,18 @@ onMounted(() => {
:width="70" :width="70"
:percent="props.data.uploadCurrent"> :percent="props.data.uploadCurrent">
</tm-progress> --> </tm-progress> -->
<div class="upload-failed" v-if="data.uploadStatus === 3"> </div>
<tm-icon :font-size="20" name="tmicon-times" color="#fff"></tm-icon> <div v-show="open">
</div> <video :src="props.extra.url" controls @fullscreenchange="fullscreenchange" :id="props.extra.url">
</video>
</div> </div>
</section> </section>
<teleport to="body">
<div v-show="open" class="video-container">
<video
:src="props.extra.url"
controls
@fullscreenchange="fullscreenchange"
:id="props.extra.url"
playsinline
webkit-playsinline
x5-playsinline
class="fullscreen-video"
></video>
</div>
</teleport>
</template> </template>
<style lang="less" scoped> <style lang="less" scoped>
.im-message-video { .im-message-video {
overflow: hidden; overflow: hidden;
padding: 20rpx 18rpx; padding: 20rpx 18rpx;
background: #46299d; background: #46299D;
min-width: 30rpx; min-width: 30rpx;
min-height: 30rpx; min-height: 30rpx;
display: inline-flex; display: inline-flex;
@ -255,43 +200,10 @@ onMounted(() => {
:deep(.uni-video-bar) { :deep(.uni-video-bar) {
display: none; display: none;
} }
} }
.circleProgress { .circleProgress {
width: 80rpx !important; width: 80rpx !important;
height: 80rpx !important; height: 80rpx !important;
} }
.video-container {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: #000;
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
}
.fullscreen-video {
width: 100%;
height: 100%;
object-fit: contain;
}
.upload-failed {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 1;
width: 40rpx;
height: 40rpx;
display: flex;
align-items: center;
justify-content: center;
background: #ff4d4f;
border-radius: 50%;
}
</style> </style>

View File

@ -1,19 +0,0 @@
<script setup>
import './sys-message.less'
import { useInject } from '@/hooks'
const { showUserInfoModal } = useInject()
defineProps({
extra: Object,
data: Object
})
</script>
<template>
<div class="im-message-sys-text">
<div class="sys-text">
<span>{{ extra.content }}</span>
</div>
</div>
</template>

View File

@ -85,7 +85,7 @@ export const MessageComponents = {
[ChatMsgSysGroupMemberQuit]: 'sys-group-member-quit-message', [ChatMsgSysGroupMemberQuit]: 'sys-group-member-quit-message',
[ChatMsgSysGroupMemberKicked]: 'sys-group-member-kicked-message', [ChatMsgSysGroupMemberKicked]: 'sys-group-member-kicked-message',
// [ChatMsgSysGroupMessageRevoke]: '[撤回消息]', // [ChatMsgSysGroupMessageRevoke]: '[撤回消息]',
[ChatMsgSysGroupDismissed]: 'sys-group-dismissed', // [ChatMsgSysGroupDismissed]: '[群解散消息]',
[ChatMsgSysGroupMuted]: 'sys-group-muted-message', [ChatMsgSysGroupMuted]: 'sys-group-muted-message',
[ChatMsgSysGroupCancelMuted]: 'sys-group-cancel-muted-message', [ChatMsgSysGroupCancelMuted]: 'sys-group-cancel-muted-message',
[ChatMsgSysGroupMemberMuted]: 'sys-group-member-muted-message', [ChatMsgSysGroupMemberMuted]: 'sys-group-member-muted-message',

View File

@ -5,16 +5,8 @@ import { parseTime } from '@/utils/datetime'
import * as message from '@/constant/message' import * as message from '@/constant/message'
import { formatTalkItem, palyMusic, formatTalkRecord } from '@/utils/talk' import { formatTalkItem, palyMusic, formatTalkRecord } from '@/utils/talk'
// import { isElectronMode } from '@/utils/common' // import { isElectronMode } from '@/utils/common'
import { import { ServeClearTalkUnreadNum, ServeCreateTalkList } from '@/api/chat/index.js'
ServeClearTalkUnreadNum, import { useTalkStore, useDialogueStore,useDialogueListStore,useGroupStore } from '@/store'
ServeCreateTalkList,
} from '@/api/chat/index.js'
import {
useTalkStore,
useDialogueStore,
useDialogueListStore,
useGroupStore,
} from '@/store'
/** /**
* 好友状态事件 * 好友状态事件
@ -57,7 +49,7 @@ class Talk extends Base {
this.receiver_id = resource.receiver_id this.receiver_id = resource.receiver_id
this.talk_type = resource.talk_type this.talk_type = resource.talk_type
// this.fileNum = resource.file_num // this.fileNum = resource.file_num
if (resource.file_num) { if(resource.file_num){
resource.data.file_num = resource.file_num resource.data.file_num = resource.file_num
} }
this.resource = resource.data this.resource = resource.data
@ -106,10 +98,11 @@ class Talk extends Base {
play() { play() {
// 客户端有消息提示 // 客户端有消息提示
// if (isElectronMode()) return // if (isElectronMode()) return
// useSettingsStore().isPromptTone && palyMusic() // useSettingsStore().isPromptTone && palyMusic()
} }
async handle() { handle() {
// 不是自己发送的消息则需要播放提示音 // 不是自己发送的消息则需要播放提示音
if (!this.isCurrSender()) { if (!this.isCurrSender()) {
this.play() this.play()
@ -117,21 +110,7 @@ class Talk extends Base {
// 判断会话列表是否存在,不存在则创建 // 判断会话列表是否存在,不存在则创建
if (useTalkStore().findTalkIndex(this.getIndexName()) == -1) { if (useTalkStore().findTalkIndex(this.getIndexName()) == -1) {
if (this.resource.msg_type == 1102) { return this.addTalkItem()
//被邀请进入群聊时,需要热更新会话列表
await useTalkStore().loadTalkList()
} else if (this.resource.msg_type == 1106) {
//群解散时,需要热更新会话列表
await useTalkStore().loadTalkList()
} else if (
this.resource.msg_type == 1104 ||
this.resource.msg_type == 1115
) {
//群成员被移出时,需要热更新会话列表
await useTalkStore().loadTalkList()
} else {
return this.addTalkItem()
}
} }
// 判断当前是否正在和好友对话 // 判断当前是否正在和好友对话
@ -139,33 +118,6 @@ class Talk extends Base {
this.insertTalkRecord() this.insertTalkRecord()
} else { } else {
this.updateTalkItem() this.updateTalkItem()
if (
!useTalkStore().items[useTalkStore().findTalkIndex(this.getIndexName())]
?.is_disturb
) {
this.updateUnreadMsgNumAdd()
}
}
}
//更新未读数量+1
updateUnreadMsgNumAdd() {
if (typeof plus !== 'undefined') {
let OAWebView = plus.webview.all()
OAWebView.forEach((webview) => {
if (webview.id === 'webviewId1') {
webview.evalJS(`updateUnreadMsgNumAdd()`)
}
})
} else {
document.addEventListener('plusready', () => {
let OAWebView = plus.webview.all()
OAWebView.forEach((webview) => {
if (webview.id === 'webviewId1') {
webview.evalJS(`updateUnreadMsgNumAdd()`)
}
})
})
} }
} }
@ -180,6 +132,7 @@ class Talk extends Base {
// lang: 'zh-CN', // lang: 'zh-CN',
// body: '您有新的消息请注意查收' // body: '您有新的消息请注意查收'
// }) // })
// notification.onclick = () => { // notification.onclick = () => {
// notification.close() // notification.close()
// } // }
@ -207,16 +160,12 @@ class Talk extends Base {
ServeCreateTalkList({ ServeCreateTalkList({
talk_type, talk_type,
receiver_id, receiver_id
}).then(async ({ code, data }) => { }).then(({ code, data }) => {
if (code == 200) { if (code == 200) {
let item = formatTalkItem(data) let item = formatTalkItem(data)
if (!item?.is_disturb) { item.unread_num = 1
item.unread_num = 1
this.updateUnreadMsgNumAdd()
}
useTalkStore().addItem(item) useTalkStore().addItem(item)
await useTalkStore().loadTalkList()
} }
}) })
} }
@ -226,36 +175,12 @@ class Talk extends Base {
*/ */
insertTalkRecord() { insertTalkRecord() {
let record = this.resource let record = this.resource
let newRecord = formatTalkRecord(this.getAccountId(), this.resource) let newRecord = formatTalkRecord(this.getAccountId(), this.resource);
const { addDialogueRecord, addChatRecord } = useDialogueListStore() const {addDialogueRecord,addChatRecord} = useDialogueListStore()
// 群成员变化的消息,需要更新群成员列表 // 群成员变化的消息,需要更新群成员列表
if ([1102, 1103, 1104, 1115].includes(record.msg_type)) { if ([1102, 1103, 1104, 1115].includes(record.msg_type)) {
useDialogueStore().updateGroupMembers() useDialogueStore().updateGroupMembers()
} }
//群解散时,需要更新群成员权限
if ([1106].includes(record.msg_type)) {
useDialogueStore().updateDismiss()
}
//群成员被移出时,需要更新群成员权限
if ([1104, 1115].includes(record.msg_type)) {
useDialogueStore().updateQuit()
}
//群禁言变化时,需要更新群禁言状态——即更新群成员列表
if ([1107, 1108, 1109, 1110].includes(record.msg_type)) {
useDialogueStore().updateGroupMembers()
}
//群公告变化时,需要更新群公告(新增和修改有热更新,删除没有)
if ([13].includes(record.msg_type)) {
useGroupStore().ServeGetGroupNotices()
}
//群管理员变化时,需要更新群管理员列表——即更新群成员列表,同时更新群信息
if ([1114].includes(record.msg_type)) {
useDialogueStore().updateGroupMembers()
useGroupStore().ServeGroupDetail()
}
if ([1116].includes(record.msg_type)) { if ([1116].includes(record.msg_type)) {
// 更新会话信息 // 更新会话信息
useDialogueStore().setDialogue({ useDialogueStore().setDialogue({
@ -269,15 +194,13 @@ class Talk extends Base {
avatar: record.extra.group_avatar, avatar: record.extra.group_avatar,
}) })
// 更新会话列表中的会话信息 // 更新会话列表中的会话信息
const dialogue = useDialogueListStore().getDialogueList( const dialogue = useDialogueListStore().getDialogueList(`${record.talk_type}_${record.receiver_id}`)
`${record.talk_type}_${record.receiver_id}`,
)
if (dialogue) { if (dialogue) {
dialogue.talk.username = record.extra.group_name dialogue.talk.username = record.extra.group_name
} }
} }
addDialogueRecord([newRecord], 'add') addDialogueRecord([newRecord],'add')
addChatRecord(this.getIndexName(), newRecord) addChatRecord(this.getIndexName(),newRecord)
useDialogueStore().addDialogueRecord(newRecord) useDialogueStore().addDialogueRecord(newRecord)
if (!this.isCurrSender()) { if (!this.isCurrSender()) {
@ -285,7 +208,7 @@ class Talk extends Base {
setTimeout(() => { setTimeout(() => {
ws.emit('im.message.read', { ws.emit('im.message.read', {
receiver_id: this.sender_id, receiver_id: this.sender_id,
msg_ids: [this.resource.msg_id], msg_ids: [this.resource.msg_id]
}) })
}, 1000) }, 1000)
} }
@ -295,8 +218,7 @@ class Talk extends Base {
if (!el) return if (!el) return
// 判断的滚动条是否在底部 // 判断的滚动条是否在底部
const isBottom = const isBottom = Math.ceil(el.scrollTop) + el.clientHeight >= el.scrollHeight
Math.ceil(el.scrollTop) + el.clientHeight >= el.scrollHeight
if (isBottom || record.user_id == this.getAccountId()) { if (isBottom || record.user_id == this.getAccountId()) {
nextTick(() => { nextTick(() => {
@ -309,15 +231,14 @@ class Talk extends Base {
useTalkStore().updateItem({ useTalkStore().updateItem({
index_name: this.getIndexName(), index_name: this.getIndexName(),
msg_text: this.getTalkText(), msg_text: this.getTalkText(),
updated_at: parseTime(new Date()), updated_at: parseTime(new Date())
}) })
if (this.talk_type == 1 && this.getAccountId() !== this.sender_id) { if (this.talk_type == 1 && this.getAccountId() !== this.sender_id) {
//不在此处维护未读消息数量 ServeClearTalkUnreadNum({
// ServeClearTalkUnreadNum({ talk_type: 1,
// talk_type: 1, receiver_id: this.sender_id
// receiver_id: this.sender_id, })
// })
} }
} }
@ -328,26 +249,11 @@ class Talk extends Base {
useTalkStore().updateMessage({ useTalkStore().updateMessage({
index_name: this.getIndexName(), index_name: this.getIndexName(),
msg_text: this.getTalkText(), msg_text: this.getTalkText(),
updated_at: parseTime(new Date()), updated_at: parseTime(new Date())
}) })
//收到新消息时,同时判断是否有人@我 if(this.resource.msg_type == 1116){
if (
this.resource.msg_type === 1 &&
this.resource?.extra?.mentions?.length > 0
) {
const findMention = this.resource?.extra?.mentions?.find(
(mention) => mention === this.getAccountId(),
)
//有人@我或者@所有人,则更新会话列表
if (findMention || this.resource?.extra?.mentions?.includes(0)) {
useTalkStore().loadTalkList()
}
}
if (this.resource.msg_type == 1116) {
// 更新会话列表中的会话信息 // 更新会话列表中的会话信息
const dialogue = useDialogueListStore().getDialogueList( const dialogue = useDialogueListStore().getDialogueList(`${this.resource.talk_type}_${this.resource.receiver_id}`)
`${this.resource.talk_type}_${this.resource.receiver_id}`,
)
if (dialogue) { if (dialogue) {
dialogue.talk.username = this.resource.extra.group_name dialogue.talk.username = this.resource.extra.group_name
} }

View File

@ -11,12 +11,7 @@ import { reactive, nextTick, computed, h, inject } from 'vue'
// EditTwo, // EditTwo,
// IdCard // IdCard
// } from '@icon-park/vue-next' // } from '@icon-park/vue-next'
import { import { ServeTopTalkList, ServeDeleteTalkList, ServeSetNotDisturb } from '@/api/chat'
ServeTopTalkList,
ServeDeleteTalkList,
ServeSetNotDisturb,
ServeClearTalkUnreadNum,
} from '@/api/chat'
import { useDialogueStore, useTalkStore, useDialogueListStore } from '@/store' import { useDialogueStore, useTalkStore, useDialogueListStore } from '@/store'
import { ServeSecedeGroup } from '@/api/group' import { ServeSecedeGroup } from '@/api/group'
// import { ServeDeleteContact, ServeEditContactRemark } from '@/api/contact' // import { ServeDeleteContact, ServeEditContactRemark } from '@/api/contact'
@ -28,7 +23,7 @@ export function useSessionMenu() {
show: false, show: false,
x: 0, x: 0,
y: 0, y: 0,
item: {}, item: {}
}) })
const dialogueStore = useDialogueStore() const dialogueStore = useDialogueStore()
@ -123,22 +118,10 @@ export function useSessionMenu() {
// 移除会话 // 移除会话
const onRemoveTalk = (item) => { const onRemoveTalk = (item) => {
ServeDeleteTalkList({ ServeDeleteTalkList({
list_id: item.id, list_id: item.id
}).then(({ code }) => { }).then(({ code }) => {
if (code == 200) { if (code == 200) {
onDeleteTalk(item.index_name) onDeleteTalk(item.index_name)
console.error(item, 'item')
if (item.unread_num > 0) {
//同时已读
ServeClearTalkUnreadNum(
{
talk_type: item.talk_type,
receiver_id: item.receiver_id,
},
item.unread_num,
).then(() => {
})
}
} }
}) })
} }
@ -148,13 +131,13 @@ export function useSessionMenu() {
ServeSetNotDisturb({ ServeSetNotDisturb({
talk_type: item.talk_type, talk_type: item.talk_type,
receiver_id: item.receiver_id, receiver_id: item.receiver_id,
is_disturb: item.is_disturb == 0 ? 1 : 0, is_disturb: item.is_disturb == 0 ? 1 : 0
}).then(({ code, message }) => { }).then(({ code, message }) => {
if (code == 200) { if (code == 200) {
message.success('设置成功!') message.success('设置成功!')
talkStore.updateItem({ talkStore.updateItem({
index_name: item.index_name, index_name: item.index_name,
is_disturb: item.is_disturb == 0 ? 1 : 0, is_disturb: item.is_disturb == 0 ? 1 : 0
}) })
} else { } else {
message.error(message) message.error(message)
@ -170,12 +153,12 @@ export function useSessionMenu() {
ServeTopTalkList({ ServeTopTalkList({
list_id: item.id, list_id: item.id,
type: item.is_top == 0 ? 1 : 2, type: item.is_top == 0 ? 1 : 2
}).then(({ code, message }) => { }).then(({ code, message }) => {
if (code == 200) { if (code == 200) {
talkStore.updateItem({ talkStore.updateItem({
index_name: item.index_name, index_name: item.index_name,
is_top: item.is_top == 0 ? 1 : 0, is_top: item.is_top == 0 ? 1 : 0
}) })
} else { } else {
message.error(message) message.error(message)
@ -218,7 +201,7 @@ export function useSessionMenu() {
negativeText: '取消', negativeText: '取消',
onPositiveClick: () => { onPositiveClick: () => {
ServeSecedeGroup({ ServeSecedeGroup({
group_id: item.receiver_id, group_id: item.receiver_id
}).then(({ code, message }) => { }).then(({ code, message }) => {
if (code == 200) { if (code == 200) {
message.success('已退出群聊') message.success('已退出群聊')
@ -227,7 +210,7 @@ export function useSessionMenu() {
message.error(message) message.error(message)
} }
}) })
}, }
}) })
} }
@ -276,18 +259,12 @@ export function useSessionMenu() {
disturb: onSetDisturb, disturb: onSetDisturb,
signout_group: onSignOutGroup, signout_group: onSignOutGroup,
delete_contact: onDeleteContact, delete_contact: onDeleteContact,
remark: onChangeRemark, remark: onChangeRemark
} }
dropdown.show = false dropdown.show = false
evnets[key] && evnets[key](dropdown.item) evnets[key] && evnets[key](dropdown.item)
} }
return { return { dropdown, onCloseContextMenu, onContextMenuTalkHandle, onToTopTalk, onRemoveTalk }
dropdown,
onCloseContextMenu,
onContextMenuTalkHandle,
onToTopTalk,
onRemoveTalk,
}
} }

View File

@ -10,8 +10,6 @@ import tmui from '@/uni_modules/tmui'
import { config } from '@/config/tmui/index.js' import { config } from '@/config/tmui/index.js'
import 'dayjs/locale/zh-cn' import 'dayjs/locale/zh-cn'
import xLoaderror from '@/components/x-loaderror/index.vue' import xLoaderror from '@/components/x-loaderror/index.vue'
import asyncLoading from '@/components/async-loading/index.vue'
import asyncError from '@/components/async-error/index.vue'
import { vLoading } from '@/components/x-loading/index.js' import { vLoading } from '@/components/x-loading/index.js'
import messagePopup from '@/components/x-message/useMessagePopup' import messagePopup from '@/components/x-message/useMessagePopup'
import pageAnimation from '@/components/page-animation/index.vue' import pageAnimation from '@/components/page-animation/index.vue'
@ -31,8 +29,6 @@ export function createApp() {
app.mixin(pageAnimation) app.mixin(pageAnimation)
app.component('customNavbar', customNavbar) app.component('customNavbar', customNavbar)
app.component('x-loaderror', xLoaderror) app.component('x-loaderror', xLoaderror)
app.component('AsyncLoading', asyncLoading)
app.component('AsyncError', asyncError)
app.directive('no-space', { app.directive('no-space', {
mounted(el) { mounted(el) {
el.addEventListener('input', (e) => { el.addEventListener('input', (e) => {
@ -64,20 +60,16 @@ export function createApp() {
) { ) {
return return
} }
console.log('===准备创建本地通知栏消息')
let OAWebView = plus.webview.all() let OAWebView = plus.webview.all()
OAWebView.forEach((webview, index) => { //all里面第一个是入口webview
if (webview.id === 'webviewId1') { OAWebView[0].evalJS(`doCreatePushMessage('${msg}')`)
webview.evalJS(`doCreatePushMessage('${msg}')`)
}
})
} }
//处理聊天推送弹窗点开 //处理聊天推送弹窗点开
window.openUniPushMsg = (msg) => { window.openUniPushMsg = (msg) => {
console.log('=====点击通知栏消息') console.log("=====点击通知栏消息")
let pushMsg = JSON.parse(decodeURIComponent(msg)) let pushMsg = JSON.parse(decodeURIComponent(msg))
console.log('=====pushMsg', pushMsg) console.log("=====pushMsg",pushMsg)
//由于弹窗前处理了不该弹窗的场景,因此这里弹窗可以一并处理 //由于弹窗前处理了不该弹窗的场景,因此这里弹窗可以一并处理
//也就是都跳转到聊天页面 //也就是都跳转到聊天页面
const talkStore = useTalkStore() const talkStore = useTalkStore()

View File

@ -53,7 +53,7 @@
> >
<div class="group-member-each"> <div class="group-member-each">
<div class="group-member-avatar" :style="{ background: 'unset' }"> <div class="group-member-avatar" :style="{ background: 'unset' }">
<img src="@/static/image/chatSettings/add-member.png" /> <img src="/src/static/image/chatSettings/add-member.png" />
</div> </div>
<div class="group-member-name"> <div class="group-member-name">
<span class="text-[24rpx] font-regular">添加</span> <span class="text-[24rpx] font-regular">添加</span>
@ -71,7 +71,7 @@
> >
<div class="group-member-each"> <div class="group-member-each">
<div class="group-member-avatar" :style="{ background: 'unset' }"> <div class="group-member-avatar" :style="{ background: 'unset' }">
<img src="@/static/image/chatSettings/remove-member.png" /> <img src="/src/static/image/chatSettings/remove-member.png" />
</div> </div>
<div class="group-member-name"> <div class="group-member-name">
<span class="text-[24rpx] font-regular">移除</span> <span class="text-[24rpx] font-regular">移除</span>

View File

@ -49,7 +49,7 @@
props?.memberItem?.is_mine && props?.manageType === 'removeMembers' props?.memberItem?.is_mine && props?.manageType === 'removeMembers'
" "
> >
<img src="@/static/image/chatSettings/is-mine.png" /> <img src="/src/static/image/chatSettings/is-mine.png" />
</div> </div>
<div <div
class="is-admin-tag" class="is-admin-tag"

View File

@ -158,7 +158,6 @@ import customInput from '@/components/custom-input/custom-input.vue'
import selectMemberItem from '../components/select-member-item.vue' import selectMemberItem from '../components/select-member-item.vue'
import ZPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue' 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 useZPaging from '@/uni_modules/z-paging/components/z-paging/js/hooks/useZPaging.js'
import groupAllMember from '@/static/image/chatList/groupAllMember.png'
import { import {
computed, computed,
onMounted, onMounted,
@ -266,7 +265,7 @@ watch(
key: '0', key: '0',
memberList: [ memberList: [
{ {
avatar: groupAllMember, avatar: '/src/static/image/chatList/groupAllMember.png',
erp_user_id: 0, erp_user_id: 0,
gender: 0, gender: 0,
is_mute: 0, is_mute: 0,
@ -466,7 +465,7 @@ const assembleAlphabetMemberList = async (newMemberList) => {
key: '0', key: '0',
memberList: [ memberList: [
{ {
avatar: groupAllMember, avatar: '/src/static/image/chatList/groupAllMember.png',
erp_user_id: 0, erp_user_id: 0,
gender: 0, gender: 0,
is_mute: 0, is_mute: 0,

View File

@ -19,7 +19,7 @@
(props?.item?.label !== $t('chat.settings.groupName') || (props?.item?.label !== $t('chat.settings.groupName') ||
props?.item?.label !== $t('chat.settings.groupType')))) props?.item?.label !== $t('chat.settings.groupType'))))
" "
src="@/static/image/chatSettings/pointer.png" src="/src/static/image/chatSettings/pointer.png"
/> />
<tm-switch <tm-switch
:width="88" :width="88"

View File

@ -35,7 +35,7 @@
<img <img
v-if="state.groupName" v-if="state.groupName"
class="groupName-input-clearBtn" class="groupName-input-clearBtn"
src="@/static/image/chatSettings/clear-btn.png" src="/src/static/image/chatSettings/clear-btn.png"
@click="clearGroupNameInput" @click="clearGroupNameInput"
/> />
</div> </div>

View File

@ -46,7 +46,7 @@
<div class="group-admin-list-each-btns"> <div class="group-admin-list-each-btns">
<img <img
v-if="item.is_mine" v-if="item.is_mine"
src="@/static/image/chatSettings/is-mine.png" src="/src/static/image/chatSettings/is-mine.png"
/> />
<div <div
class="group-admin-list-each-btns-each" class="group-admin-list-each-btns-each"
@ -67,7 +67,7 @@
margin: state?.groupAdminList.length == 0 ? '20rpx 0 0' : '', margin: state?.groupAdminList.length == 0 ? '20rpx 0 0' : '',
}" }"
> >
<img src="@/static/image/chatSettings/add-btn.png" /> <img src="/src/static/image/chatSettings/add-btn.png" />
<span class="text-[28rpx] font-medium"> <span class="text-[28rpx] font-medium">
{{ $t('chat.manage.addAdmin') }} {{ $t('chat.manage.addAdmin') }}
</span> </span>

View File

@ -42,7 +42,7 @@
class="add-silence-member-btn chat-settings-card" class="add-silence-member-btn chat-settings-card"
@click="toSelectMembersPage" @click="toSelectMembersPage"
> >
<img src="@/static/image/chatSettings/add-btn.png" /> <img src="/src/static/image/chatSettings/add-btn.png" />
<span class="text-[28rpx] font-medium"> <span class="text-[28rpx] font-medium">
{{ $t('chat.manage.addSilenceMember') }} {{ $t('chat.manage.addSilenceMember') }}
</span> </span>

View File

@ -54,7 +54,7 @@
@click="toEditGroupInfoPage" @click="toEditGroupInfoPage"
v-if="groupParams?.groupInfo?.is_manager" v-if="groupParams?.groupInfo?.is_manager"
> >
<img src="@/static/image/chatSettings/edit-btn.png" /> <img src="/src/static/image/chatSettings/edit-btn.png" />
</div> </div>
</div> </div>
<div class="chat-group-members chat-group-infos chat-settings-card"> <div class="chat-group-members chat-group-infos chat-settings-card">
@ -267,8 +267,8 @@ onLoad(async (options) => {
if (options.groupId) { if (options.groupId) {
console.log(options.groupId) console.log(options.groupId)
state.groupId = Number(options.groupId) state.groupId = Number(options.groupId)
await groupStore.ServeGroupDetail()
if (dialogueParams.type === 2) { if (dialogueParams.type === 2) {
await groupStore.ServeGroupDetail()
await groupStore.ServeGetGroupNotices() await groupStore.ServeGetGroupNotices()
} }
} }
@ -566,10 +566,7 @@ const showConfirmPrompt = (flag) => {
confirmContent = t('group.dismiss.confirm') confirmContent = t('group.dismiss.confirm')
} else if (flag === 3) { } else if (flag === 3) {
//退 //退
if ( if (dialogueParams.adminList.length === 1 && dialogueParams.adminList[0].id === dialogueParams.uid) {
dialogueParams.adminList.length === 1 &&
dialogueParams.adminList[0].id === dialogueParams.uid
) {
// //
confirmContent = t('ok') + t('group.quit.btn') confirmContent = t('ok') + t('group.quit.btn')
subContent = t('groupManage.disband.hint') subContent = t('groupManage.disband.hint')
@ -607,10 +604,7 @@ const showConfirmPrompt = (flag) => {
} }
} else if (flag === 3) { } else if (flag === 3) {
//退 //退
if ( if (dialogueParams.adminList.length === 1 && dialogueParams.adminList[0].id === dialogueParams.uid) {
dialogueParams.adminList.length === 1 &&
dialogueParams.adminList[0].id === dialogueParams.uid
) {
// //
let params = { let params = {
group_id: dialogueParams.receiver_id, //id group_id: dialogueParams.receiver_id, //id
@ -630,9 +624,7 @@ const showConfirmPrompt = (flag) => {
group_id: dialogueParams.receiver_id, group_id: dialogueParams.receiver_id,
}).then(({ code, message }) => { }).then(({ code, message }) => {
if (code == 200) { if (code == 200) {
uni.navigateBack({ // dialogueStore.apiClearRecord()
delta: 2,
})
} else { } else {
} }
}) })

View File

@ -17,17 +17,10 @@
</div> </div>
<div class="avatarImg"> <div class="avatarImg">
<avatarModule <avatarModule
:mode="props?.data?.group_type === 0 ? 1 : 2" :mode="2"
:avatar="props?.data?.avatar" :avatar="props?.data?.avatar"
:groupType="props?.data?.group_type" :groupType="props?.data?.group_type"
:userName="props?.data?.name"
:customStyle="{ width: '96rpx', height: '96rpx' }" :customStyle="{ width: '96rpx', height: '96rpx' }"
:customTextStyle="{
fontSize: '32rpx',
fontWeight: 'bold',
color: '#fff',
lineHeight: '44rpx',
}"
></avatarModule> ></avatarModule>
</div> </div>
<div class="chatInfo"> <div class="chatInfo">
@ -37,18 +30,16 @@
class="text-[#171717] text-[32rpx] font-medium leading-[44rpx]" class="text-[#171717] text-[32rpx] font-medium leading-[44rpx]"
> >
<span>{{ props.data.name }}</span> <span>{{ props.data.name }}</span>
<span v-if="props.data.talk_type === 2"> <span v-if="props.data.talk_type === 2">{{ props.data.group_member_num }}</span>
{{ props.data.group_member_num }}
</span>
<span v-if="props.data.group_type === 2" class="depTag tag"> <span v-if="props.data.group_type === 2" class="depTag tag">
部门 部门
</span> </span>
<span v-if="props.data.group_type === 3" class="projectTag tag"> <span v-if="props.data.group_type === 3" class="projectTag tag">
项目 项目
</span> </span>
<span v-if="props.data.group_type === 4" class="companyTag tag"> <span v-if="props.data.group_type === 4" class="companyTag tag">
公司 公司
</span> </span>
</div> </div>
</div> </div>
</div> </div>
@ -136,7 +127,7 @@ const cellClick = () => {
opacity: 40%; opacity: 40%;
} }
.tag { .tag{
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
text-align: center; text-align: center;
@ -151,16 +142,16 @@ const cellClick = () => {
font-weight: bold; font-weight: bold;
} }
.companyTag { .companyTag {
border: 1px solid #7a58de; border: 1px solid #7a58de;
color: #7a58de; color: #7a58de;
} }
.depTag { .depTag {
border: 1px solid #377ec6; border: 1px solid #377ec6;
color: #377ec6; color: #377ec6;
} }
.projectTag { .projectTag {
border: 1px solid #c1681c; border: 1px solid #c1681c;
color: #c1681c; color: #c1681c;
} }
.textEllipsis { .textEllipsis {

View File

@ -219,7 +219,7 @@ watch(
onMounted(() => { onMounted(() => {
talkStore.loadTalkList() talkStore.loadTalkList()
console.log(talkStore.talkItems) console.log(talkStore.talkItems)
items.value = lodash.cloneDeep(talkStore.talkItems).filter(item=>item.is_dismiss === 0 && item.is_quit === 0) items.value = lodash.cloneDeep(talkStore.talkItems)
}) })
onUnmounted(() => { onUnmounted(() => {
dialogueStore.setForwardType('') dialogueStore.setForwardType('')

View File

@ -72,7 +72,7 @@ const props = defineProps({
}) })
const state = reactive({ const state = reactive({
base64Url: '', base64Url: ''
}) })
const uploadsStore = useUploadsStore() const uploadsStore = useUploadsStore()
@ -94,69 +94,17 @@ const onProgressFn = (progress, id) => {
const photoActionsSelect = (index) => { const photoActionsSelect = (index) => {
if (index === 0) { if (index === 0) {
if (typeof plus === 'undefined') { uni.chooseImage({
uni.chooseImage({ sourceType: ['album'],
sourceType: ['album'], count: 9,
count: 9, success: async (res) => {
success: async (res) => { console.log(res, 'res')
console.log(res, 'res') res.tempFiles.forEach(async (file) => {
res.tempFiles.forEach(async (file) => { let data = await onUploadImageVideo(file, 'image')
const fileSizeInMB = (file.size / (1024 * 1024)).toFixed(2) emit('selectImg', data, data.file_num)
if (fileSizeInMB > 100) { })
plus.nativeUI.toast('图片大小不能超过100MB') },
return })
}
let data = await onUploadImageVideo(file, 'image')
emit('selectImg', data, data.file_num)
})
},
})
} else {
plus?.gallery.pick(
(res) => {
console.log(res, 'res')
res.files.reverse()
res.files.forEach(async (filePath) => {
plus?.io?.resolveLocalFileSystemURL(
filePath,
async (entry) => {
entry.file((file) => {
const fileReader = new plus.io.FileReader()
fileReader.readAsDataURL(file)
fileReader.onloadend = async (e) => {
const base64Url = e.target.result
const fileObj = base64ToFile(base64Url)
const fileSizeInMB = (fileObj.size / (1024 * 1024)).toFixed(
2,
)
if (fileSizeInMB > 100) {
plus.nativeUI.toast('图片大小不能超过100MB')
return
}
let data = await onUploadImageVideo(fileObj, 'image')
emit('selectImg', data, data.file_num)
}
})
},
(err) => {
console.log(err)
},
)
})
},
(err) => {
console.log(err)
},
{
filter: 'image',
maximum: 9,
multiple: true,
onmaxed: () => {
plus.nativeUI.toast('最多只能选择9张图片')
},
},
)
}
} else { } else {
uni.chooseVideo({ uni.chooseVideo({
sourceType: ['album'], sourceType: ['album'],
@ -164,11 +112,6 @@ const photoActionsSelect = (index) => {
maxDuration: 60, maxDuration: 60,
success: async (res) => { success: async (res) => {
console.log(res, 'res') console.log(res, 'res')
const fileSizeInMB = (res.tempFile.size / (1024 * 1024)).toFixed(2)
if (fileSizeInMB > 100) {
plus.nativeUI.toast('视频大小不能超过100MB')
return
}
let data = await onUploadImageVideo( let data = await onUploadImageVideo(
res.tempFile, res.tempFile,
'video', 'video',
@ -181,13 +124,12 @@ const photoActionsSelect = (index) => {
} }
const onUploadImageVideo = async (file, type = 'image', fileUrl) => { const onUploadImageVideo = async (file, type = 'image', fileUrl) => {
console.log('开始上传文件:', file.name) console.log(file, 'file')
uploadsStore.updateUploadStatus(true)
return new Promise(async (resolve) => { return new Promise(async (resolve) => {
if (type === 'image') { if (type === 'image') {
let image = new Image() let image = new Image()
image.src = URL.createObjectURL(file) image.src = URL.createObjectURL(file)
image.onload = async () => { image.onload = () => {
const form = new FormData() const form = new FormData()
form.append('file', file) form.append('file', file)
form.append('source', 'fonchain-chat') form.append('source', 'fonchain-chat')
@ -221,62 +163,29 @@ const onUploadImageVideo = async (file, type = 'image', fileUrl) => {
} }
virtualList.value.unshift(newItem) virtualList.value.unshift(newItem)
uploadImg(form, (e) => onProgressFn(e, randomId)).then(
try { ({ status, data, msg }) => {
const result = await uploadImg(form, (e) => onProgressFn(e, randomId)) if (status == 0) {
console.log('上传完成,结果:', result) resolve({
type: 'image',
if (result.status === 0) { url: data.ori_url,
// size: file.size,
const index = virtualList.value.findIndex( width: image.width,
(item) => item.file_num === randomId, height: image.height,
) file_num: randomId,
if (index !== -1) { })
virtualList.value[index].uploadStatus = 2 } else {
virtualList.value[index].uploadCurrent = 100 resolve('')
message.error(msg)
} }
},
// )
resolve({
type: 'image',
url: result.data.ori_url,
size: file.size,
width: image.width,
height: image.height,
file_num: randomId,
})
} else {
uploadsStore.updateUploadStatus(false)
//
const index = virtualList.value.findIndex(
(item) => item.file_num === randomId,
)
if (index !== -1) {
virtualList.value[index].uploadStatus = 3
}
message.error(result.msg)
resolve('')
}
} catch (error) {
console.error('上传出错:', error)
uploadsStore.updateUploadStatus(false)
//
const index = virtualList.value.findIndex(
(item) => item.file_num === randomId,
)
if (index !== -1) {
virtualList.value[index].uploadStatus = 3
}
message.error('上传失败')
resolve('')
}
} }
} else { } else {
uni.getVideoInfo({ uni.getVideoInfo({
src: fileUrl, src: fileUrl,
success: async (resp) => { success: (resp) => {
console.log('视频信息:', resp) console.log(resp)
const form = new FormData()
form.append('file', file) form.append('file', file)
form.append('source', 'fonchain-chat') form.append('source', 'fonchain-chat')
form.append('type', 'video') form.append('type', 'video')
@ -306,65 +215,30 @@ const onUploadImageVideo = async (file, type = 'image', fileUrl) => {
talk_type: dialogueStore.talk.talk_type, talk_type: dialogueStore.talk.talk_type,
user_id: userStore.uid, user_id: userStore.uid,
uploadCurrent: 0, uploadCurrent: 0,
uploadStatus: 1, uploadStatus: 1, // 1 2 3
} }
virtualList.value.unshift(newItem) virtualList.value.unshift(newItem)
uploadImg(form, (e) => onProgressFn(e, randomId)).then(
try { ({ status, data, msg }) => {
const result = await uploadImg(form, (e) => onProgressFn(e, randomId)) if (status == 0) {
console.log('视频上传完成,结果:', result) console.log(data)
resolve({
if (result.status === 0) { type: 'video',
// url: data.ori_url,
const index = virtualList.value.findIndex( cover: data.cover_url,
(item) => item.file_num === randomId, duration: parseInt(resp.duration),
) size: file.size,
if (index !== -1) { file_num: randomId,
virtualList.value[index].uploadStatus = 2 })
virtualList.value[index].uploadCurrent = 100 } else {
// resolve('')
// message.error(msg)
} }
},
resolve({ )
type: 'video',
url: result.data.ori_url,
cover: result.data.cover_url,
duration: parseInt(resp.duration),
size: file.size,
file_num: randomId,
})
} else {
uploadsStore.updateUploadStatus(false)
//
const index = virtualList.value.findIndex(
(item) => item.file_num === randomId,
)
if (index !== -1) {
virtualList.value[index].uploadStatus = 3
}
message.error(result.msg)
resolve('')
}
} catch (error) {
console.error('视频上传出错:', error)
uploadsStore.updateUploadStatus(false)
//
const index = virtualList.value.findIndex(
(item) => item.file_num === randomId,
)
if (index !== -1) {
virtualList.value[index].uploadStatus = 3
}
message.error('上传失败')
resolve('')
}
}, },
fail: (error) => {
console.error('获取视频信息失败:', error)
uploadsStore.updateUploadStatus(false)
message.error('获取视频信息失败')
resolve('')
}
}) })
const form = new FormData()
} }
}) })
} }
@ -515,11 +389,6 @@ const chooseFile = () => {
count: 1, count: 1,
extension: [''], extension: [''],
success: (res) => { success: (res) => {
const fileSizeInMB = (res.tempFiles[0].size / (1024 * 1024)).toFixed(2)
if (fileSizeInMB > 100) {
plus.nativeUI.toast('文件大小不能超过100MB')
return
}
let randomId = uniqueId() let randomId = uniqueId()
let newItem = { let newItem = {
avatar: userStore.avatar, avatar: userStore.avatar,
@ -547,34 +416,7 @@ const chooseFile = () => {
uploadStatus: 1, // 1 2 3 uploadStatus: 1, // 1 2 3
} }
virtualList.value.unshift(newItem) virtualList.value.unshift(newItem)
uploadsStore.updateUploadStatus(true) uploadsStore.initUploadFile(res.tempFiles[0], props.talkParams, randomId)
uploadsStore.initUploadFile(
res.tempFiles[0],
props.talkParams,
randomId,
(status, data, msg) => {
if (status === 0) {
//
const index = virtualList.value.findIndex(
(item) => item.file_num === randomId,
)
if (index !== -1) {
virtualList.value[index].uploadStatus = 2
virtualList.value[index].uploadCurrent = 100
}
} else {
uploadsStore.updateUploadStatus(false)
//
const index = virtualList.value.findIndex(
(item) => item.file_num === randomId,
)
if (index !== -1) {
virtualList.value[index].uploadStatus = 3
}
message.error(msg)
}
},
)
}, },
}) })
} }

View File

@ -37,7 +37,7 @@
</div> </div>
<div class="user-info-main user-info-card"> <div class="user-info-main user-info-card">
<div class="user-info-main-title"> <div class="user-info-main-title">
<img src="@/static/image/mine/ming001@3x.png" /> <img src="/src/static/image/mine/ming001@3x.png" />
<span class="text-[28rpx] font-medium"> <span class="text-[28rpx] font-medium">
{{ $t('index.mine.basic') }} {{ $t('index.mine.basic') }}
</span> </span>
@ -84,7 +84,7 @@
<div class="do-phone-call-header"> <div class="do-phone-call-header">
<span>{{ $t('popup.title.phone') }}</span> <span>{{ $t('popup.title.phone') }}</span>
<img <img
src="@/static/image/login/check-circle-filled@3x.png" src="/src/static/image/login/check-circle-filled@3x.png"
@click="hidePhoneCallPopup" @click="hidePhoneCallPopup"
/> />
</div> </div>

View File

@ -16,19 +16,7 @@
@scrolltoupper="onScrollToUpper" @scrolltoupper="onScrollToUpper"
> >
<template #top> <template #top>
<customNavbar <customNavbar :title="talkParams.username" id="navBarArea">
:title="talkParams.username"
id="navBarArea"
:hideBack="dialogueStore.isOpenMultiSelect"
>
<template #left v-if="dialogueStore.isOpenMultiSelect">
<text
class="ml-[36rpx]"
@click="dialogueStore.isOpenMultiSelect = false"
>
取消
</text>
</template>
<template <template
#subTitle #subTitle
v-if="talkStore?.findItem(talkParams.index_name)?.group_type === 4" v-if="talkStore?.findItem(talkParams.index_name)?.group_type === 4"
@ -216,28 +204,17 @@
</div> </div>
<template #bottom> <template #bottom>
<div class="footBox" id="footBoxArea"> <div class="footBox" id="footBoxArea">
<span
class="flex items-center justify-center text-[24rpx] text-[#999999]"
style="background-color: #e5e5e5; padding: 12rpx 24rpx;"
v-if="uploadsParams.isUploading"
>
{{
'正在发送中,剩余' +
uploadsParams.uploadingNum +
'个...请不要离开哦~'
}}
</span>
<div v-if="!dialogueStore.isOpenMultiSelect"> <div v-if="!dialogueStore.isOpenMultiSelect">
<div <div
class="pt-[16rpx] ml-[32rpx] mr-[32rpx] flex items-start justify-between" class="pt-[16rpx] ml-[32rpx] mr-[32rpx] flex items-start justify-between"
> >
<div class="flex-1 quillBox" style=""> <div class="flex-1 quillBox">
<QuillEditor <QuillEditor
ref="editor" ref="editor"
id="editor" id="editor"
:options="editorOption" :options="editorOption"
@editorChange="onEditorChange" @editorChange="onEditorChange"
style="width: 100%; flex: 1; height: 100%;" style="width: 100%; flex: 1; height: 100%; border: none;"
@click="onEditorClick" @click="onEditorClick"
/> />
<!-- <tm-input type=textarea autoHeight focusColor="#F9F9F9" color="#F9F9F9" :inputPadding="[12]" <!-- <tm-input type=textarea autoHeight focusColor="#F9F9F9" color="#F9F9F9" :inputPadding="[12]"
@ -254,7 +231,7 @@
}} }}
</span> </span>
<span <span
v-if="state?.quoteInfo?.msg_type !== 1" v-if="state?.quoteInfo"
class="text-[28rpx] text-[#999]" class="text-[28rpx] text-[#999]"
> >
{{ {{
@ -266,7 +243,7 @@
<img <img
@click="clearQuoteInfo" @click="clearQuoteInfo"
style="width: 30rpx; height: 30rpx;" style="width: 30rpx; height: 30rpx;"
src="@/static/image/login/check-circle-filled@3x.png" src="/src/static/image/login/check-circle-filled@3x.png"
/> />
</div> </div>
</div> </div>
@ -333,13 +310,13 @@
<tm-image :width="68" :height="68" :src="zu6051"></tm-image> <tm-image :width="68" :height="68" :src="zu6051"></tm-image>
<div class="mt-[6rpx]">逐条转发</div> <div class="mt-[6rpx]">逐条转发</div>
</div> </div>
<!-- <div <div
@click="handleWechatForward" @click="handleWechatForward"
class="flex flex-col items-center justify-center" class="flex flex-col items-center justify-center"
> >
<tm-image :width="68" :height="68" :src="zu6052"></tm-image> <tm-image :width="68" :height="68" :src="zu6052"></tm-image>
<div class="mt-[6rpx]">微信</div> <div class="mt-[6rpx]">微信</div>
</div> --> </div>
<div <div
@click="handleDelete" @click="handleDelete"
class="flex flex-col items-center justify-center" class="flex flex-col items-center justify-center"
@ -405,7 +382,7 @@
> >
<img <img
style="width: 40rpx; height: 40rpx;" style="width: 40rpx; height: 40rpx;"
src="@/static/image/chatList/mention_select_hide_bg.png" src="/src/static/image/chatList/mention_select_hide_bg.png"
/> />
<img <img
style=" style="
@ -415,7 +392,7 @@
margin-left: -9rpx; margin-left: -9rpx;
margin-top: -5rpx; margin-top: -5rpx;
" "
src="@/static/image/chatList/mention_select_hide_icon.png" src="/src/static/image/chatList/mention_select_hide_icon.png"
/> />
</div> </div>
<span <span
@ -551,7 +528,6 @@ const settingsStore = useSettingsStore()
const userStore = useUserStore() const userStore = useUserStore()
const dialogueStore = useDialogueStore() const dialogueStore = useDialogueStore()
const editorDraftStore = useEditorDraftStore() const editorDraftStore = useEditorDraftStore()
const uploadsStore = useUploadsStore()
const editor = ref() const editor = ref()
const zpagingRef = ref() const zpagingRef = ref()
useZPaging(zpagingRef) useZPaging(zpagingRef)
@ -568,12 +544,6 @@ const talkParams = reactive({
isDismiss: computed(() => dialogueStore.isDismiss), isDismiss: computed(() => dialogueStore.isDismiss),
isQuit: computed(() => dialogueStore.isQuit), isQuit: computed(() => dialogueStore.isQuit),
adminList: computed(() => dialogueStore.getAdminList), adminList: computed(() => dialogueStore.getAdminList),
unReadNum: computed(() => dialogueStore.unreadNum),
})
const uploadsParams = reactive({
isUploading: computed(() => uploadsStore.isUploading),
uploadingNum: computed(() => uploadsStore.uploadingNum),
}) })
const state = ref({ const state = ref({
@ -597,10 +567,6 @@ const state = ref({
lastCursorIndex: undefined, // lastCursorIndex: undefined, //
mentionUserIds: [], //@ID mentionUserIds: [], //@ID
isInsertingMention: false, //mention isInsertingMention: false, //mention
showMentionSelectTimer: null, //
lastMentionText: '', // @
lastMentionTriggered: false, // @
lastMentionPosition: -1, // @
}) })
uniOnload(async (options) => { uniOnload(async (options) => {
@ -628,18 +594,14 @@ uniOnload(async (options) => {
}) })
uniOnUnload(() => { uniOnUnload(() => {
console.log('onUnload') console.log('onUnload')
ServeClearTalkUnreadNum( ServeClearTalkUnreadNum({
{ talk_type: Number(talkParams.type),
talk_type: Number(talkParams.type), receiver_id: Number(talkParams.receiver_id),
receiver_id: Number(talkParams.receiver_id), }).then(() => {
},
talkParams.unReadNum,
).then(() => {
talkStore.updateItem({ talkStore.updateItem({
index_name: talkParams.index_name, index_name: talkParams.index_name,
unread_num: 0, unread_num: 0,
}) })
dialogueStore.clearUnreadNum()
}) })
}) })
const handleEmojiPanel = () => { const handleEmojiPanel = () => {
@ -660,11 +622,6 @@ const handleHidePanel = () => {
// //
const onEditorClick = () => { const onEditorClick = () => {
handleHidePanel() handleHidePanel()
const quill = getQuill()
// if (quill.getText().endsWith('@\n')) {
// showMentionSelectDebounced(quill)
// }
quill.focus()
} }
const onSendMessage = (data = {}, callBack) => { const onSendMessage = (data = {}, callBack) => {
@ -679,17 +636,14 @@ const onSendMessage = (data = {}, callBack) => {
ServePublishMessage(message) ServePublishMessage(message)
.then(({ code, message }) => { .then(({ code, message }) => {
if (code == 200) { if (code == 200) {
uploadsStore.updateUploadStatus(false)
if (callBack) { if (callBack) {
callBack(true) callBack(true)
} }
} else { } else {
uploadsStore.updateUploadStatus(false)
message.warning(message) message.warning(message)
} }
}) })
.catch(() => { .catch(() => {
uploadsStore.updateUploadStatus(false)
message.warning('网络繁忙,请稍后重试!') message.warning('网络繁忙,请稍后重试!')
}) })
} }
@ -716,11 +670,8 @@ const onSendMessageClick = () => {
switch (data.msgType) { switch (data.msgType) {
case 1: // case 1: //
if (data.items[0].content.trim() === '') {
return
}
if (data.items[0].content.length > 1024) { if (data.items[0].content.length > 1024) {
return message.warning('发送内容超长,请分条发送') return message.info('发送内容超长,请分条发送')
} }
onSendTextEvent({ onSendTextEvent({
data, data,
@ -847,9 +798,6 @@ const onEmoticonEvent = (data) => {
} }
const onEditorChange = () => { const onEditorChange = () => {
if (getQuill().getText() !== state.value.lastMentionText) {
state.value.lastMentionTriggered = false
}
let delta = getQuill().getContents() let delta = getQuill().getContents()
let text = deltaToString(delta) let text = deltaToString(delta)
@ -939,9 +887,9 @@ const editorOption = {
if (range) { if (range) {
state.value.lastCursorIndex = range.index state.value.lastCursorIndex = range.index
} }
state.value.isShowMentionSelect = true
// 使 //
showMentionSelectDebounced(quill) quill.blur()
}, },
mentionContainerClass: '', mentionContainerClass: '',
}, },
@ -1387,12 +1335,9 @@ const getMentionSelectLists = (mentionSelectList) => {
// mention // mention
mentionSelectList.forEach((mentionSelectItem) => { mentionSelectList.forEach((mentionSelectItem) => {
// @ id 0
const id =
mentionSelectItem?.nickname === '所有人' ? 0 : mentionSelectItem?.id
mention.insertItem( mention.insertItem(
{ {
id: id, id: mentionSelectItem?.id,
denotationChar: '@', denotationChar: '@',
value: mentionSelectItem?.nickname + ' ', value: mentionSelectItem?.nickname + ' ',
}, },
@ -1426,21 +1371,12 @@ const updateMentionUserIds = () => {
// @IDnumber // @IDnumber
ops.forEach((op) => { ops.forEach((op) => {
if (op.insert && op.insert.mention) { if (op.insert && op.insert.mention) {
const id = Number(op.insert.mention.id) currentMentions.add(Number(op.insert.mention.id))
// null
if (!isNaN(id)) {
currentMentions.add(id)
}
} }
}) })
// @0 // 使mentionsmentionUserIds
if (currentMentions.has(0)) { state.value.mentionUserIds = Array.from(currentMentions)
state.value.mentionUserIds = [0]
} else {
// @
state.value.mentionUserIds = Array.from(currentMentions)
}
} }
//msgsequence //msgsequence
@ -1592,9 +1528,6 @@ const isLeader = computed(() => {
//@ //@
const doMentionUser = (mentionSelect) => { const doMentionUser = (mentionSelect) => {
console.log(mentionSelect) console.log(mentionSelect)
if (talkParams.type === 1) {
return
}
// mention // mention
const mentionObj = { const mentionObj = {
id: mentionSelect.user_id, // 使 user_id erp_user_id id: mentionSelect.user_id, // 使 user_id erp_user_id
@ -1665,36 +1598,7 @@ onUnmounted(() => {
if (avatarPressTimer) { if (avatarPressTimer) {
clearTimeout(avatarPressTimer) clearTimeout(avatarPressTimer)
} }
//
if (state.value.showMentionSelectTimer) {
clearTimeout(state.value.showMentionSelectTimer)
}
if (uploadsStore.isUploading) {
uploadsStore.clearUpload()
}
}) })
//
const showMentionSelectDebounced = (quill) => {
const text = quill.getText()
//
if (text !== state.value.lastMentionText) {
state.value.lastMentionTriggered = false
}
//
if (state.value.lastMentionTriggered) {
console.log('return')
return
}
//
state.value.lastMentionText = text
state.value.lastMentionTriggered = true
state.value.isShowMentionSelect = true
quill.blur()
}
</script> </script>
<style scoped lang="less"> <style scoped lang="less">
.dialog-page { .dialog-page {
@ -1749,16 +1653,13 @@ const showMentionSelectDebounced = (quill) => {
justify-content: space-between; justify-content: space-between;
overflow: hidden; overflow: hidden;
width: 100%; width: 100%;
span { span {
display: -webkit-inline-box; display: -webkit-inline-box;
text-overflow: ellipsis; text-overflow: ellipsis;
-webkit-line-clamp: 2; -webkit-line-clamp: 2;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
width: 100%; width: 100%;
word-break: break-all;
} }
img { img {
margin: 0 0 0 30rpx; margin: 0 0 0 30rpx;
flex-shrink: 0; flex-shrink: 0;
@ -1971,7 +1872,6 @@ const showMentionSelectDebounced = (quill) => {
flex-direction: column; flex-direction: column;
align-items: flex-start; align-items: flex-start;
justify-content: center; justify-content: center;
:deep(.ql-clipboard) { :deep(.ql-clipboard) {
position: relative; position: relative;
opacity: 0; opacity: 0;
@ -2023,7 +1923,6 @@ const showMentionSelectDebounced = (quill) => {
z-index: 1; z-index: 1;
/* 确保 z-index 低于 deepBubble */ /* 确保 z-index 低于 deepBubble */
} }
.divider { .divider {
width: 100%; width: 100%;
height: 1rpx; height: 1rpx;
@ -2036,24 +1935,20 @@ const showMentionSelectDebounced = (quill) => {
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
padding: 36rpx 32rpx 0; padding: 36rpx 32rpx 0;
.cancel-btns { .cancel-btns {
flex-shrink: 0; flex-shrink: 0;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
.hide-btn { .hide-btn {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
position: relative; position: relative;
text { text {
} }
img { img {
width: 18rpx; width: 18rpx;
height: 10rpx; height: 10rpx;
@ -2070,7 +1965,6 @@ const showMentionSelectDebounced = (quill) => {
background-color: #f3f3f3; background-color: #f3f3f3;
border-radius: 8rpx; border-radius: 8rpx;
flex-shrink: 0; flex-shrink: 0;
span { span {
color: #bababa; color: #bababa;
line-height: 40rpx; line-height: 40rpx;
@ -2080,7 +1974,6 @@ const showMentionSelectDebounced = (quill) => {
.mention-done-btn-can-do { .mention-done-btn-can-do {
background-color: #46299d; background-color: #46299d;
span { span {
color: #fff; color: #fff;
} }
@ -2092,13 +1985,11 @@ const showMentionSelectDebounced = (quill) => {
align-items: center; align-items: center;
justify-content: flex-end; justify-content: flex-end;
flex-shrink: 0; flex-shrink: 0;
span { span {
flex-shrink: 0; flex-shrink: 0;
} }
} }
} }
:deep(.mention) { :deep(.mention) {
color: #1890ff; color: #1890ff;
} }

View File

@ -1,5 +1,4 @@
<script lang="ts" setup> <script lang="ts" setup>
import zPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue'
import { ref, onMounted } from 'vue' import { ref, onMounted } from 'vue'
import { ServeGetForwardRecords } from '@/api/chat' import { ServeGetForwardRecords } from '@/api/chat'
import { MessageComponents } from '@/constant/message' import { MessageComponents } from '@/constant/message'
@ -48,12 +47,12 @@ onMounted(() => {
</script> </script>
<template> <template>
<div class="forward-record-page"> <div class="outer-layer">
<zPaging ref="zPaging" :show-scrollbar="false"> <div>
<template #top> <tm-navbar :hideBack="false" hideHome :title="`${title}的会话记录`" >
<customNavbar :title="`${title}的会话记录`"></customNavbar> </tm-navbar>
</template> </div>
<div class="main-box"> <div class="main-box">
<div v-if="items.length === 0" class="flex justify-center items-center w-full mt-[200rpx]"> <div v-if="items.length === 0" class="flex justify-center items-center w-full mt-[200rpx]">
<wd-loading /> <wd-loading />
</div> </div>
@ -77,15 +76,16 @@ onMounted(() => {
</div> </div>
</div> </div>
</div> </div>
</zPaging>
</div> </div>
</template> </template>
<style lang="less" scoped> <style lang="less" scoped>
.forward-record-page { .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;
padding: 0 66rpx 20rpx 50rpx;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
@ -96,7 +96,7 @@ onMounted(() => {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow: auto; overflow: auto;
padding: 28rpx 66rpx 20rpx 50rpx; padding-top: 28rpx;
} }
.message-item { .message-item {

View File

@ -65,9 +65,6 @@
</div> </div>
<div class="chatInfo_2 w-full mr-[6rpx]"> <div class="chatInfo_2 w-full mr-[6rpx]">
<div class="w-full chatInfo_2_1 textEllipsis"> <div class="w-full chatInfo_2_1 textEllipsis">
<span v-if="props.data.atsign_num" style="color: red;">
[有人@]
</span>
{{ props.data.msg_text }} {{ props.data.msg_text }}
</div> </div>
</div> </div>
@ -110,9 +107,6 @@ import { useSessionMenu } from '@/hooks'
const talkStore = useTalkStore() const talkStore = useTalkStore()
const { onToTopTalk, onRemoveTalk } = useSessionMenu() const { onToTopTalk, onRemoveTalk } = useSessionMenu()
const dialogueStore = useDialogueStore() const dialogueStore = useDialogueStore()
const dialogueParams = reactive({
unReadNum: computed(() => dialogueStore.unreadNum),
})
const props = defineProps({ const props = defineProps({
data: { data: {
type: Object, type: Object,
@ -138,18 +132,14 @@ const cellClick = () => {
// //
if (props.data.unread_num > 0) { if (props.data.unread_num > 0) {
ServeClearTalkUnreadNum( ServeClearTalkUnreadNum({
{ talk_type: props.data.talk_type,
talk_type: props.data.talk_type, receiver_id: props.data.receiver_id,
receiver_id: props.data.receiver_id, }).then(() => {
},
dialogueParams.unReadNum,
).then(() => {
talkStore.updateItem({ talkStore.updateItem({
index_name: props.data.index_name, index_name: props.data.index_name,
unread_num: 0, unread_num: 0,
}) })
dialogueStore.clearUnreadNum()
}) })
} }
uni.navigateTo({ uni.navigateTo({
@ -265,7 +255,6 @@ const handleDelete = () => {
display: -webkit-box; display: -webkit-box;
-webkit-line-clamp: 1; -webkit-line-clamp: 1;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
word-break: break-all;
} }
.divider { .divider {

View File

@ -138,9 +138,6 @@ const isEmptyViewShow = ref(false)
const talkStore = useTalkStore() const talkStore = useTalkStore()
const userStore = useUserStore() const userStore = useUserStore()
const dialogueStore = useDialogueStore() const dialogueStore = useDialogueStore()
const dialogueParams = reactive({
unReadNum: computed(() => dialogueStore.unreadNum),
})
const { userInfo } = useAuth() const { userInfo } = useAuth()
const topItems = computed(() => talkStore.topItems) const topItems = computed(() => talkStore.topItems)
@ -247,12 +244,11 @@ onLoad((options) => {
ServeClearTalkUnreadNum({ ServeClearTalkUnreadNum({
talk_type: openSession.talk_type, talk_type: openSession.talk_type,
receiver_id: openSession.receiver_id, receiver_id: openSession.receiver_id,
},dialogueParams.unReadNum).then(() => { }).then(() => {
talkStore.updateItem({ talkStore.updateItem({
index_name: openSession.index_name, index_name: openSession.index_name,
unread_num: 0, unread_num: 0,
}) })
dialogueStore.clearUnreadNum()
}) })
} }
uni.navigateTo({ uni.navigateTo({

View File

@ -9,7 +9,7 @@
:default-page-size="props.searchResultPageSize" :default-page-size="props.searchResultPageSize"
:loading-more-default-as-loading="true" :loading-more-default-as-loading="true"
:inside-more="true" :inside-more="true"
:empty-view-img="searchNoData" :empty-view-img="'/src/static//image/search/search-no-data.png'"
:empty-view-text="$t('search.hint')" :empty-view-text="$t('search.hint')"
:empty-view-img-style="{ width: '476rpx', height: '261rpx' }" :empty-view-img-style="{ width: '476rpx', height: '261rpx' }"
:empty-view-title-style="{ :empty-view-title-style="{
@ -113,7 +113,6 @@
</div> </div>
</template> </template>
<script setup> <script setup>
import searchNoData from '@/static/image/search/search-no-data.png'
import customInput from '@/components/custom-input/custom-input.vue' import customInput from '@/components/custom-input/custom-input.vue'
import ZPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue' 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 useZPaging from '@/uni_modules/z-paging/components/z-paging/js/hooks/useZPaging.js'
@ -361,16 +360,9 @@ const queryAllSearch = (pageNum, searchResultPageSize) => {
// //
const cancelSearch = () => { const cancelSearch = () => {
const pages = getCurrentPages() uni.navigateBack({
if (pages.length > 1) { delta: 1,
uni.navigateBack({ })
delta: 1,
})
} else {
uni.reLaunch({
url: '/pages/index/index'
})
}
} }
//key //key
@ -440,7 +432,7 @@ const getHasMoreResult = (searchResultKey) => {
case 'general_infos': case 'general_infos':
if ( if (
state.searchResult['record_count'] && state.searchResult['record_count'] &&
state.searchResult['record_count'] >= 3 state.searchResult['record_count'] > 3
) { ) {
has_more_result = t('has_more') + t('chat.type.record') has_more_result = t('has_more') + t('chat.type.record')
} }

View File

@ -17,9 +17,7 @@ import { ServeSeachQueryAll, ServeGetSessionId } from '@/api/search/index'
import { onMounted } from 'vue' import { onMounted } from 'vue'
import { handleSetWebviewStyle } from '@/utils/common' import { handleSetWebviewStyle } from '@/utils/common'
import { useDialogueStore, useTalkStore } from '@/store' import { useDialogueStore } from '@/store'
import { ServeCreateTalkList } from '@/api/chat/index.js'
import { formatTalkItem } from '@/utils/talk'
const dialogueStore = useDialogueStore() const dialogueStore = useDialogueStore()
@ -52,18 +50,6 @@ const clickSearchItem = async (
console.log(talk_type, receiver_id) console.log(talk_type, receiver_id)
const sessionId = await getSessionId(talk_type, receiver_id) const sessionId = await getSessionId(talk_type, receiver_id)
if (searchResultKey === 'user_infos') { if (searchResultKey === 'user_infos') {
if (useTalkStore().findTalkIndex(`${talk_type}_${receiver_id}`) === -1) {
ServeCreateTalkList({
talk_type,
receiver_id,
erp_user_id: result.erp_user_id,
}).then(async ({ code, data }) => {
if (code == 200) {
let item = formatTalkItem(data)
useTalkStore().addItem(item)
}
})
}
dialogueStore.setDialogue({ dialogueStore.setDialogue({
name: result.nickname, name: result.nickname,
talk_type: 1, talk_type: 1,
@ -79,7 +65,7 @@ const clickSearchItem = async (
receiver_id: result.group_id || result.id, receiver_id: result.group_id || result.id,
}) })
uni.navigateTo({ uni.navigateTo({
url: '/pages/dialog/index?sessionId=' + sessionId, url: '/pages/dialog/index?sessionId=' + sessionId
}) })
} else if (searchResultKey === 'general_infos') { } else if (searchResultKey === 'general_infos') {
uni.navigateTo({ uni.navigateTo({

View File

@ -25,9 +25,7 @@ import {
} from '@/api/search/index' } from '@/api/search/index'
import { reactive } from 'vue' import { reactive } from 'vue'
import { useDialogueStore, useTalkStore } from '@/store' import { useDialogueStore } from '@/store'
import { ServeCreateTalkList } from '@/api/chat/index.js'
import { formatTalkItem } from '@/utils/talk'
const dialogueStore = useDialogueStore() const dialogueStore = useDialogueStore()
@ -77,13 +75,7 @@ onLoad((options) => {
}) })
//id //id
const lastIdChange = ( const lastIdChange = (last_id, last_group_id, last_member_id, last_receiver_user_name, last_receiver_group_name) => {
last_id,
last_group_id,
last_member_id,
last_receiver_user_name,
last_receiver_group_name,
) => {
let idChanges = { let idChanges = {
last_id, last_id,
last_group_id, last_group_id,
@ -116,18 +108,6 @@ const clickSearchItem = async (
console.log(talk_type, receiver_id) console.log(talk_type, receiver_id)
const sessionId = await getSessionId(talk_type, receiver_id) const sessionId = await getSessionId(talk_type, receiver_id)
if (state.searchResultKey === 'user_infos') { if (state.searchResultKey === 'user_infos') {
if (useTalkStore().findTalkIndex(`${talk_type}_${receiver_id}`) === -1) {
ServeCreateTalkList({
talk_type,
receiver_id,
erp_user_id: result.erp_user_id,
}).then(async ({ code, data }) => {
if (code == 200) {
let item = formatTalkItem(data)
useTalkStore().addItem(item)
}
})
}
dialogueStore.setDialogue({ dialogueStore.setDialogue({
name: result.nickname, name: result.nickname,
talk_type: 1, talk_type: 1,

View File

@ -42,7 +42,7 @@
<span class="text-[28rpx] font-regular"> <span class="text-[28rpx] font-regular">
{{ state.selectedMonth }} {{ state.selectedMonth }}
</span> </span>
<img src="@/static/image/search/down-pointer.png" /> <img src="/src/static/image/search/down-pointer.png" />
</div> </div>
</tm-time-picker> </tm-time-picker>
<tm-calendar-view <tm-calendar-view
@ -123,10 +123,7 @@
state.condition === 'imgAndVideo' ? '0 0 10rpx' : '', state.condition === 'imgAndVideo' ? '0 0 10rpx' : '',
}" }"
> >
<div <div class="condition-result-member">
class="condition-result-member"
v-if="state.condition === 'member'"
>
<searchItem <searchItem
@click="toDialogueByMember(item)" @click="toDialogueByMember(item)"
:searchResultKey="'search_by_member_condition'" :searchResultKey="'search_by_member_condition'"
@ -160,27 +157,17 @@
class="condition-result-imgAndVideo-area" class="condition-result-imgAndVideo-area"
v-if="item?.extra?.url" v-if="item?.extra?.url"
> >
<template v-if="item?.msg_type === 3"> <tm-image
<tm-image preview
preview :src="
:src="item?.extra?.url" item?.msg_type === 3
model="aspectFill" ? item?.extra?.url
/> : item?.msg_type === 5
</template> ? item?.extra?.cover
<template v-else-if="item?.msg_type === 5"> : ''
<div "
class="video-preview" model="aspectFill"
@click="onPlay(item?.extra?.url)" />
>
<tm-image
:src="item?.extra?.cover"
model="aspectFill"
/>
<div class="play-icon">
<img :src="playCircle" />
</div>
</div>
</template>
</div> </div>
</div> </div>
<div <div
@ -212,7 +199,7 @@
v-if="state.condition === 'file'" v-if="state.condition === 'file'"
/> />
<img <img
src="@/static/image/search/result-link-icon.png" src="/src/static/image/search/result-link-icon.png"
v-if="state.condition === 'link'" v-if="state.condition === 'link'"
/> />
</div> </div>
@ -267,20 +254,6 @@
</div> </div>
</div> </div>
</ZPaging> </ZPaging>
<teleport to="body">
<div v-show="open" class="video-container">
<video
:src="currentVideoUrl"
controls
@fullscreenchange="fullscreenchange"
:id="currentVideoUrl"
playsinline
webkit-playsinline
x5-playsinline
class="fullscreen-video"
></video>
</div>
</teleport>
</div> </div>
</div> </div>
</template> </template>
@ -290,14 +263,13 @@ import fileType_EXCEL from '@/static/image/search/fileType_EXCEL.png'
import fileType_WORD from '@/static/image/search/fileType_WORD.png' import fileType_WORD from '@/static/image/search/fileType_WORD.png'
import fileType_PDF from '@/static/image/search/fileType_PDF.png' import fileType_PDF from '@/static/image/search/fileType_PDF.png'
import fileType_Files from '@/static/image/search/fileType_Files.png' import fileType_Files from '@/static/image/search/fileType_Files.png'
import playCircle from '@/static/image/chatList/playCircle@2x.png'
import { fileFormatSize, fileSuffix } from '@/utils/strings' import { fileFormatSize, fileSuffix } from '@/utils/strings'
import searchItem from '../components/searchItem.vue' import searchItem from '../components/searchItem.vue'
import customInput from '@/components/custom-input/custom-input.vue' import customInput from '@/components/custom-input/custom-input.vue'
import ZPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue' 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 useZPaging from '@/uni_modules/z-paging/components/z-paging/js/hooks/useZPaging.js'
import { parseTime } from '@/utils/datetime' import { parseTime } from '@/utils/datetime'
import { onMounted, reactive, computed, ref, nextTick } from 'vue' import { onMounted, reactive, computed, ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app' import { onLoad } from '@dcloudio/uni-app'
import { ServeTalkDate, ServeGetSessionId } from '@/api/search/index' import { ServeTalkDate, ServeGetSessionId } from '@/api/search/index'
import { ServeFindTalkRecords } from '@/api/chat/index' import { ServeFindTalkRecords } from '@/api/chat/index'
@ -336,39 +308,6 @@ const state = reactive({
flatList: [], // flatList: [], //
}) })
const videoContext = ref()
const open = ref(false)
const currentVideoUrl = ref('')
const fullscreenchange = (e) => {
if (!e.detail.fullScreen) {
videoContext.value.stop()
videoContext.value.seek(0)
open.value = false
}
}
async function onPlay(url) {
currentVideoUrl.value = url
open.value = true
// DOM
await nextTick()
//
videoContext.value = uni.createVideoContext(url, getCurrentInstance())
setTimeout(() => {
//
videoContext.value.requestFullScreen({ direction: 2 })
//
setTimeout(() => {
videoContext.value.play()
}, 100)
}, 200)
}
onLoad((options) => { onLoad((options) => {
console.log(options) console.log(options)
if (options.condition) { if (options.condition) {
@ -561,16 +500,9 @@ const inputSearchText = (e) => {
// //
const cancelSearch = () => { const cancelSearch = () => {
const pages = getCurrentPages() uni.navigateBack({
if (pages.length > 1) { delta: 1,
uni.navigateBack({ })
delta: 1,
})
} else {
uni.reLaunch({
url: '/pages/index/index',
})
}
} }
// //
@ -897,26 +829,6 @@ body::v-deep .round-3 {
width: 164rpx !important; width: 164rpx !important;
height: 164rpx !important; height: 164rpx !important;
} }
.video-preview {
position: relative;
width: 164rpx;
height: 164rpx;
cursor: pointer;
.play-icon {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
align-items: center;
justify-content: center;
img {
width: 80rpx !important;
height: 80rpx !important;
}
}
}
} }
} }
} }
@ -925,23 +837,4 @@ body::v-deep .round-3 {
} }
} }
} }
.video-container {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: #000;
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
}
.fullscreen-video {
width: 100%;
height: 100%;
object-fit: contain;
}
</style> </style>

View File

@ -15,10 +15,6 @@ import { useAuth } from '../auth/index'
// let keyboardTimeout = null // let keyboardTimeout = null
export const useDialogueStore = defineStore('dialogue', { export const useDialogueStore = defineStore('dialogue', {
// 添加持久化配置
persist: {
paths: ['talk.talk_type', 'talk.receiver_id']
},
state: () => { state: () => {
return { return {
// 对话索引(聊天对话的唯一索引) // 对话索引(聊天对话的唯一索引)
@ -58,9 +54,6 @@ export const useDialogueStore = defineStore('dialogue', {
//是否退群/移出群 //是否退群/移出群
isQuit: false, isQuit: false,
//未读消息数量
unreadNum:0,
// 群成员列表 // 群成员列表
members: [], members: [],
@ -97,21 +90,6 @@ export const useDialogueStore = defineStore('dialogue', {
this.online = status this.online = status
}, },
// 更新未读消息数量-清空未读
clearUnreadNum() {
this.unreadNum = 0
},
// 更新群解散状态
updateDismiss() {
this.isDismiss = true
},
// 更新群成员退出状态
updateQuit() {
this.isQuit = true
},
// 更新对话信息 // 更新对话信息
setDialogue(data = {}) { setDialogue(data = {}) {
this.online = data.is_online == 1 this.online = data.is_online == 1
@ -129,10 +107,8 @@ export const useDialogueStore = defineStore('dialogue', {
this.isDismiss = data?.is_dismiss === 1 ? true : false this.isDismiss = data?.is_dismiss === 1 ? true : false
this.isQuit = data?.is_quit === 1 ? true : false this.isQuit = data?.is_quit === 1 ? true : false
this.unreadNum = data?.unread_num || 0
this.members = [] this.members = []
if (data.talk_type == 2 && !this.isDismiss && !this.isQuit) { if (data.talk_type == 2) {
this.updateGroupMembers() this.updateGroupMembers()
} }
}, },

View File

@ -42,7 +42,6 @@ export const useDialogueListStore = createGlobalState(() => {
isShowSessionList: dialogue.isShowSessionList, isShowSessionList: dialogue.isShowSessionList,
isDismiss: dialogue.isDismiss, isDismiss: dialogue.isDismiss,
isQuit: dialogue.isQuit, isQuit: dialogue.isQuit,
unreadNum: dialogue.unreadNum,
members: dialogue.members.map(member => ({ members: dialogue.members.map(member => ({
id: member.id, id: member.id,
nickname: member.nickname, nickname: member.nickname,
@ -141,8 +140,6 @@ export const useDialogueListStore = createGlobalState(() => {
...virtualList.value[index], // 保留原有不需要修改的字段 ...virtualList.value[index], // 保留原有不需要修改的字段
...item, // 覆盖需要更新的字段 ...item, // 覆盖需要更新的字段
}) })
} else {
zpagingRef.value?.addChatRecordData(item, false, false)
} }
} else { } else {
zpagingRef.value?.addChatRecordData(item, false, false) zpagingRef.value?.addChatRecordData(item, false, false)

View File

@ -33,9 +33,7 @@ export const useUploadsStore = defineStore('uploads', {
state: () => { state: () => {
return { return {
isShow: false, isShow: false,
items: [], items: []
isUploading: false,//当前是否正在上传
uploadingNum: 0//当前正在上传数量
} }
}, },
getters: { getters: {
@ -76,11 +74,7 @@ export const useUploadsStore = defineStore('uploads', {
this.triggerUpload(upload_id,msgId) this.triggerUpload(upload_id,msgId)
this.isShow = true this.isShow = true
} else {
this.updateUploadStatus(false)
} }
}).catch(()=> {
this.updateUploadStatus(false)
}) })
}, },
@ -97,19 +91,7 @@ export const useUploadsStore = defineStore('uploads', {
item.status = 1 item.status = 1
// 开始上传时就更新进度 ServeFileSubareaUpload(form)
const currentPercentage = (item.uploadIndex / item.files.length) * 100
item.percentage = currentPercentage.toFixed(1)
updateUploadProgress(msgId, currentPercentage)
ServeFileSubareaUpload(form, (progressEvent) => {
// 计算当前分片的进度
const currentChunkProgress = (progressEvent.loaded / progressEvent.total) * 100
// 计算总体进度:已完成分片 + 当前分片的进度
const totalProgress = ((item.uploadIndex + currentChunkProgress / 100) / item.files.length) * 100
item.percentage = totalProgress.toFixed(1)
updateUploadProgress(msgId, totalProgress)
})
.then((res) => { .then((res) => {
if (res.code == 200) { if (res.code == 200) {
item.uploadIndex++ item.uploadIndex++
@ -121,38 +103,21 @@ export const useUploadsStore = defineStore('uploads', {
updateUploadProgress(msgId,100) updateUploadProgress(msgId,100)
this.sendUploadMessage(item, msgId) this.sendUploadMessage(item, msgId)
// 更新虚拟列表中的状态
const { virtualList } = useDialogueListStore()
const index = virtualList.value.findIndex(item => item.file_num === msgId)
if (index !== -1) {
virtualList.value[index].uploadStatus = 2
virtualList.value[index].uploadCurrent = 100
}
} else { } else {
// 继续上传下一个分片 const percentage = (item.uploadIndex / item.files.length) * 100
this.triggerUpload(uploadId, msgId) item.percentage = percentage.toFixed(1)
console.log(msgId,'msgId');
console.log(percentage,'percentage');
updateUploadProgress(msgId,percentage)
this.triggerUpload(uploadId,msgId)
} }
} else { } else {
this.updateUploadStatus(false)
item.status = 3 item.status = 3
// 更新虚拟列表中的状态为失败
const { virtualList } = useDialogueListStore()
const index = virtualList.value.findIndex(item => item.file_num === msgId)
if (index !== -1) {
virtualList.value[index].uploadStatus = 3
}
} }
}) })
.catch(() => { .catch(() => {
this.updateUploadStatus(false)
item.status = 3 item.status = 3
// 更新虚拟列表中的状态为失败
const { virtualList } = useDialogueListStore()
const index = virtualList.value.findIndex(item => item.file_num === msgId)
if (index !== -1) {
virtualList.value[index].uploadStatus = 3
}
}) })
}, },
@ -163,38 +128,7 @@ export const useUploadsStore = defineStore('uploads', {
receiver_id: item.receiver_id, receiver_id: item.receiver_id,
talk_type: item.talk_type, talk_type: item.talk_type,
file_num: file_num file_num: file_num
}).then((res) => {
console.log(res, 'res')
if(res.code == 200){
this.updateUploadStatus(false)
}else{
this.updateUploadStatus(false)
}
}).catch(() => {
this.updateUploadStatus(false)
}) })
},
//更新资源上传状态
updateUploadStatus(isUploading: boolean){
if(isUploading){
this.uploadingNum++
this.isUploading = true
}else{
this.uploadingNum--
if(this.uploadingNum < 0){
this.uploadingNum = 0
}
if(this.uploadingNum === 0){
this.isUploading = false
}
}
},
// 清除上传
clearUpload(){
this.isUploading = false
this.uploadingNum = 0
} }
} }
}) })

View File

@ -104,11 +104,6 @@ export const upload = (url, data = {}, options = {}) => {
url, url,
method: 'post', method: 'post',
data: data, data: data,
onUploadProgress: (progressEvent) => {
if (options.onProgress) {
options.onProgress(progressEvent)
}
},
...options ...options
}) })
} }