From f17250f2368c9dc3c5f13239af408facf8bcd674 Mon Sep 17 00:00:00 2001 From: wangyifeng <812766448@qq.com> Date: Fri, 28 Mar 2025 16:13:45 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E5=A4=84=E7=90=86=E6=9C=AA=E8=AF=BB?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E6=95=B0=E9=87=8F=E6=98=BE=E7=A4=BA=E3=80=81?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=9B=9E=E8=AF=9D=E8=87=AA=E5=8A=A8=E5=B7=B2?= =?UTF-8?q?=E8=AF=BB=E3=80=81=E6=98=BE=E7=A4=BA=E6=A0=B7=E5=BC=8F=E7=AD=89?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useSessionMenu.js | 45 +++++++++---- src/pages/dialog/components/filePanel.vue | 79 +++++++++++++++++------ src/pages/dialog/index.vue | 51 ++++++++++----- src/pages/forwardRecord/index.vue | 20 +++--- src/pages/index/components/chatItem.vue | 1 + 5 files changed, 139 insertions(+), 57 deletions(-) diff --git a/src/hooks/useSessionMenu.js b/src/hooks/useSessionMenu.js index 1963d13..d7bff50 100644 --- a/src/hooks/useSessionMenu.js +++ b/src/hooks/useSessionMenu.js @@ -11,7 +11,12 @@ import { reactive, nextTick, computed, h, inject } from 'vue' // EditTwo, // IdCard // } from '@icon-park/vue-next' -import { ServeTopTalkList, ServeDeleteTalkList, ServeSetNotDisturb } from '@/api/chat' +import { + ServeTopTalkList, + ServeDeleteTalkList, + ServeSetNotDisturb, + ServeClearTalkUnreadNum, +} from '@/api/chat' import { useDialogueStore, useTalkStore, useDialogueListStore } from '@/store' import { ServeSecedeGroup } from '@/api/group' // import { ServeDeleteContact, ServeEditContactRemark } from '@/api/contact' @@ -23,7 +28,7 @@ export function useSessionMenu() { show: false, x: 0, y: 0, - item: {} + item: {}, }) const dialogueStore = useDialogueStore() @@ -118,10 +123,22 @@ export function useSessionMenu() { // 移除会话 const onRemoveTalk = (item) => { ServeDeleteTalkList({ - list_id: item.id + list_id: item.id, }).then(({ code }) => { if (code == 200) { 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(() => { + }) + } } }) } @@ -131,13 +148,13 @@ export function useSessionMenu() { ServeSetNotDisturb({ talk_type: item.talk_type, receiver_id: item.receiver_id, - is_disturb: item.is_disturb == 0 ? 1 : 0 + is_disturb: item.is_disturb == 0 ? 1 : 0, }).then(({ code, message }) => { if (code == 200) { message.success('设置成功!') talkStore.updateItem({ index_name: item.index_name, - is_disturb: item.is_disturb == 0 ? 1 : 0 + is_disturb: item.is_disturb == 0 ? 1 : 0, }) } else { message.error(message) @@ -153,12 +170,12 @@ export function useSessionMenu() { ServeTopTalkList({ list_id: item.id, - type: item.is_top == 0 ? 1 : 2 + type: item.is_top == 0 ? 1 : 2, }).then(({ code, message }) => { if (code == 200) { talkStore.updateItem({ index_name: item.index_name, - is_top: item.is_top == 0 ? 1 : 0 + is_top: item.is_top == 0 ? 1 : 0, }) } else { message.error(message) @@ -201,7 +218,7 @@ export function useSessionMenu() { negativeText: '取消', onPositiveClick: () => { ServeSecedeGroup({ - group_id: item.receiver_id + group_id: item.receiver_id, }).then(({ code, message }) => { if (code == 200) { message.success('已退出群聊') @@ -210,7 +227,7 @@ export function useSessionMenu() { message.error(message) } }) - } + }, }) } @@ -259,12 +276,18 @@ export function useSessionMenu() { disturb: onSetDisturb, signout_group: onSignOutGroup, delete_contact: onDeleteContact, - remark: onChangeRemark + remark: onChangeRemark, } dropdown.show = false evnets[key] && evnets[key](dropdown.item) } - return { dropdown, onCloseContextMenu, onContextMenuTalkHandle, onToTopTalk, onRemoveTalk } + return { + dropdown, + onCloseContextMenu, + onContextMenuTalkHandle, + onToTopTalk, + onRemoveTalk, + } } diff --git a/src/pages/dialog/components/filePanel.vue b/src/pages/dialog/components/filePanel.vue index 27470ad..33df9ad 100644 --- a/src/pages/dialog/components/filePanel.vue +++ b/src/pages/dialog/components/filePanel.vue @@ -101,6 +101,11 @@ const photoActionsSelect = (index) => { success: async (res) => { console.log(res, 'res') res.tempFiles.forEach(async (file) => { + const fileSizeInMB = (file.size / (1024 * 1024)).toFixed(2) + if (fileSizeInMB > 100) { + plus.nativeUI.toast('图片大小不能超过100MB') + return + } let data = await onUploadImageVideo(file, 'image') emit('selectImg', data, data.file_num) }) @@ -121,6 +126,13 @@ const photoActionsSelect = (index) => { 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) } @@ -152,6 +164,11 @@ const photoActionsSelect = (index) => { maxDuration: 60, success: async (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( res.tempFile, 'video', @@ -207,7 +224,9 @@ const onUploadImageVideo = async (file, type = 'image', fileUrl) => { ({ status, data, msg }) => { if (status == 0) { // 更新上传状态为成功 - const index = virtualList.value.findIndex(item => item.file_num === randomId) + const index = virtualList.value.findIndex( + (item) => item.file_num === randomId, + ) if (index !== -1) { virtualList.value[index].uploadStatus = 2 virtualList.value[index].uploadCurrent = 100 @@ -222,7 +241,9 @@ const onUploadImageVideo = async (file, type = 'image', fileUrl) => { }) } else { // 更新上传状态为失败 - const index = virtualList.value.findIndex(item => item.file_num === randomId) + const index = virtualList.value.findIndex( + (item) => item.file_num === randomId, + ) if (index !== -1) { virtualList.value[index].uploadStatus = 3 } @@ -273,7 +294,9 @@ const onUploadImageVideo = async (file, type = 'image', fileUrl) => { ({ status, data, msg }) => { if (status == 0) { // 更新上传状态为成功 - const index = virtualList.value.findIndex(item => item.file_num === randomId) + const index = virtualList.value.findIndex( + (item) => item.file_num === randomId, + ) if (index !== -1) { virtualList.value[index].uploadStatus = 2 virtualList.value[index].uploadCurrent = 100 @@ -289,7 +312,9 @@ const onUploadImageVideo = async (file, type = 'image', fileUrl) => { }) } else { // 更新上传状态为失败 - const index = virtualList.value.findIndex(item => item.file_num === randomId) + const index = virtualList.value.findIndex( + (item) => item.file_num === randomId, + ) if (index !== -1) { virtualList.value[index].uploadStatus = 3 } @@ -451,6 +476,11 @@ const chooseFile = () => { count: 1, extension: [''], success: (res) => { + const fileSizeInMB = (res.tempFiles[0].size / (1024 * 1024)).toFixed(2) + if (fileSizeInMB > 100) { + plus.nativeUI.toast('文件大小不能超过100MB') + return + } let randomId = uniqueId() let newItem = { avatar: userStore.avatar, @@ -478,23 +508,32 @@ const chooseFile = () => { uploadStatus: 1, // 1 上传中 2 上传成功 3 上传失败 } virtualList.value.unshift(newItem) - 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 + 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 { + // 更新上传状态为失败 + const index = virtualList.value.findIndex( + (item) => item.file_num === randomId, + ) + if (index !== -1) { + virtualList.value[index].uploadStatus = 3 + } + message.error(msg) } - } else { - // 更新上传状态为失败 - const index = virtualList.value.findIndex(item => item.file_num === randomId) - if (index !== -1) { - virtualList.value[index].uploadStatus = 3 - } - message.error(msg) - } - }) + }, + ) }, }) } diff --git a/src/pages/dialog/index.vue b/src/pages/dialog/index.vue index f26604a..c656d95 100644 --- a/src/pages/dialog/index.vue +++ b/src/pages/dialog/index.vue @@ -22,7 +22,12 @@ :hideBack="dialogueStore.isOpenMultiSelect" > diff --git a/src/event/talk.js b/src/event/talk.js index 256e4e7..cc3b6f1 100644 --- a/src/event/talk.js +++ b/src/event/talk.js @@ -211,8 +211,8 @@ class Talk extends Base { }).then(async ({ code, data }) => { if (code == 200) { let item = formatTalkItem(data) - item.unread_num = 1 if (!item?.is_disturb) { + item.unread_num = 1 this.updateUnreadMsgNumAdd() } useTalkStore().addItem(item) diff --git a/src/pages/search/index.vue b/src/pages/search/index.vue index 874d545..fc4f091 100644 --- a/src/pages/search/index.vue +++ b/src/pages/search/index.vue @@ -17,7 +17,9 @@ import { ServeSeachQueryAll, ServeGetSessionId } from '@/api/search/index' import { onMounted } from 'vue' import { handleSetWebviewStyle } from '@/utils/common' -import { useDialogueStore } from '@/store' +import { useDialogueStore, useTalkStore } from '@/store' +import { ServeCreateTalkList } from '@/api/chat/index.js' +import { formatTalkItem } from '@/utils/talk' const dialogueStore = useDialogueStore() @@ -50,6 +52,18 @@ const clickSearchItem = async ( console.log(talk_type, receiver_id) const sessionId = await getSessionId(talk_type, receiver_id) 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({ name: result.nickname, talk_type: 1, @@ -65,7 +79,7 @@ const clickSearchItem = async ( receiver_id: result.group_id || result.id, }) uni.navigateTo({ - url: '/pages/dialog/index?sessionId=' + sessionId + url: '/pages/dialog/index?sessionId=' + sessionId, }) } else if (searchResultKey === 'general_infos') { uni.navigateTo({ diff --git a/src/pages/search/moreResult/moreResult.vue b/src/pages/search/moreResult/moreResult.vue index 4cff530..cf63a00 100644 --- a/src/pages/search/moreResult/moreResult.vue +++ b/src/pages/search/moreResult/moreResult.vue @@ -25,7 +25,9 @@ import { } from '@/api/search/index' import { reactive } from 'vue' -import { useDialogueStore } from '@/store' +import { useDialogueStore, useTalkStore } from '@/store' +import { ServeCreateTalkList } from '@/api/chat/index.js' +import { formatTalkItem } from '@/utils/talk' const dialogueStore = useDialogueStore() @@ -75,7 +77,13 @@ onLoad((options) => { }) //分页查询时,最后一条id变化 -const lastIdChange = (last_id, last_group_id, last_member_id, last_receiver_user_name, last_receiver_group_name) => { +const lastIdChange = ( + last_id, + last_group_id, + last_member_id, + last_receiver_user_name, + last_receiver_group_name, +) => { let idChanges = { last_id, last_group_id, @@ -108,6 +116,18 @@ const clickSearchItem = async ( console.log(talk_type, receiver_id) const sessionId = await getSessionId(talk_type, receiver_id) 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({ name: result.nickname, talk_type: 1, diff --git a/src/pages/search/searchByCondition/index.vue b/src/pages/search/searchByCondition/index.vue index 0d52421..08dca10 100644 --- a/src/pages/search/searchByCondition/index.vue +++ b/src/pages/search/searchByCondition/index.vue @@ -168,7 +168,10 @@ /> @@ -285,7 +290,7 @@ import fileType_EXCEL from '@/static/image/search/fileType_EXCEL.png' import fileType_WORD from '@/static/image/search/fileType_WORD.png' import fileType_PDF from '@/static/image/search/fileType_PDF.png' import fileType_Files from '@/static/image/search/fileType_Files.png' -import playCircle from "@/static/image/chatList/playCircle@2x.png" +import playCircle from '@/static/image/chatList/playCircle@2x.png' import { fileFormatSize, fileSuffix } from '@/utils/strings' import searchItem from '../components/searchItem.vue' import customInput from '@/components/custom-input/custom-input.vue' @@ -353,13 +358,15 @@ async function onPlay(url) { // 创建新的视频上下文 videoContext.value = uni.createVideoContext(url, getCurrentInstance()) - // 先请求全屏 - videoContext.value.requestFullScreen({ direction: 2 }) - - // 延迟一下再播放,确保全屏已经完成 setTimeout(() => { - videoContext.value.play() - }, 100) + // 先请求全屏 + videoContext.value.requestFullScreen({ direction: 2 }) + + // 延迟一下再播放,确保全屏已经完成 + setTimeout(() => { + videoContext.value.play() + }, 100) + }, 200) } onLoad((options) => { @@ -561,7 +568,7 @@ const cancelSearch = () => { }) } else { uni.reLaunch({ - url: '/pages/index/index' + url: '/pages/index/index', }) } } @@ -904,7 +911,7 @@ body::v-deep .round-3 { align-items: center; justify-content: center; - img{ + img { width: 80rpx !important; height: 80rpx !important; } @@ -918,4 +925,23 @@ 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; +} From e7ec3877350002cb023f3e0f3d79bd0df014dff1 Mon Sep 17 00:00:00 2001 From: wangyifeng <812766448@qq.com> Date: Sun, 30 Mar 2025 16:22:29 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E5=A4=84=E7=90=86=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E4=B8=AD=E5=8F=8B=E5=A5=BD=E6=8F=90=E7=A4=BA?= =?UTF-8?q?=EF=BC=9B=E5=A4=84=E7=90=86=E6=96=87=E4=BB=B6=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5=E5=9C=BA=E6=99=AF=E5=9B=BE=E6=A0=87=E5=B1=95?= =?UTF-8?q?=E7=A4=BA=EF=BC=9B=E8=A7=A3=E5=86=B3=E5=9B=BE=E7=89=87=E4=B8=8A?= =?UTF-8?q?=E4=BC=A0loading=E9=97=AE=E9=A2=98=EF=BC=9B=E6=9B=BF=E6=8D=A2?= =?UTF-8?q?=E6=89=80=E6=9C=89=E8=BF=9B=E5=BA=A6=E6=9D=A1=E9=A2=9C=E8=89=B2?= =?UTF-8?q?=E6=9B=B4=E9=86=92=E7=9B=AE=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components.d.ts | 2 + src/components/async-error/index.vue | 79 ++++++++ src/components/async-loading/index.vue | 78 ++++++++ src/components/talk/message/FileMessage.vue | 23 ++- src/components/talk/message/ImageMessage.vue | 61 +++++-- src/components/talk/message/VideoMessage.vue | 123 +++++++++---- src/main.js | 4 + src/pages/dialog/components/filePanel.vue | 179 ++++++++++++------- src/pages/dialog/index.vue | 28 ++- src/store/modules/uploads.ts | 41 ++++- 10 files changed, 493 insertions(+), 125 deletions(-) create mode 100644 src/components/async-error/index.vue create mode 100644 src/components/async-loading/index.vue diff --git a/components.d.ts b/components.d.ts index 2f10b66..c5aef78 100644 --- a/components.d.ts +++ b/components.d.ts @@ -8,6 +8,8 @@ export {} /* prettier-ignore */ declare module 'vue' { 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'] Avatar: typeof import('./src/components/base/Avatar.vue')['default'] AvatarCropper: typeof import('./src/components/base/AvatarCropper.vue')['default'] diff --git a/src/components/async-error/index.vue b/src/components/async-error/index.vue new file mode 100644 index 0000000..a23dd6d --- /dev/null +++ b/src/components/async-error/index.vue @@ -0,0 +1,79 @@ + + + + + + diff --git a/src/components/async-loading/index.vue b/src/components/async-loading/index.vue new file mode 100644 index 0000000..5bb623b --- /dev/null +++ b/src/components/async-loading/index.vue @@ -0,0 +1,78 @@ + + + + + diff --git a/src/components/talk/message/FileMessage.vue b/src/components/talk/message/FileMessage.vue index 6735c14..0d121c3 100644 --- a/src/components/talk/message/FileMessage.vue +++ b/src/components/talk/message/FileMessage.vue @@ -55,7 +55,7 @@ const getFileTypeIMG = computed(() => { default: objT.finishedImg = filePaperOther objT.blankImg = filePaperOtherBlank - objT.progressColor = '#747474' + objT.progressColor = '#46299d' } return objT }) @@ -132,7 +132,7 @@ const downloadAndOpenFile = () => { :height="95" :src="getFileTypeIMG.blankImg" > - { :strokeWidth="3" :size="20" > +
+ +
@@ -288,4 +291,20 @@ const downloadAndOpenFile = () => { width: 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%; +} diff --git a/src/components/talk/message/ImageMessage.vue b/src/components/talk/message/ImageMessage.vue index 8a84a27..9f6a226 100644 --- a/src/components/talk/message/ImageMessage.vue +++ b/src/components/talk/message/ImageMessage.vue @@ -12,40 +12,40 @@ const img = computed(() => { // console.log(props.extra); let info = { width: 0, - height: 0 + height: 0, } if (props.extra.url.includes('blob:http://')) { info = { width: props.extra.width, - height: props.extra.height + height: props.extra.height, } - }else { + } else { info = getImageInfo(props.extra.url) } if (info.width == 0 || info.height == 0) { return { width: 450, - height: 298 + height: 298, } } - if(info.width<300){ + if (info.width < 300) { return { width: 300, - height: info.height / (info.width / 300) + height: info.height / (info.width / 300), } } if (info.width < 350) { return { width: info.width, - height: info.height + height: info.height, } } return { width: 350, - height: info.height / (info.width / 350) + height: info.height / (info.width / 350), } }) @@ -54,13 +54,30 @@ const img = computed(() => { class="im-message-image" :class="{ left: data.float === 'left', - right: data.float === 'right' + right: data.float === 'right', }" > -
- - -
+
+
+ + +
+ +
+
+
diff --git a/src/components/talk/message/VideoMessage.vue b/src/components/talk/message/VideoMessage.vue index a4dc217..a11ffcf 100644 --- a/src/components/talk/message/VideoMessage.vue +++ b/src/components/talk/message/VideoMessage.vue @@ -1,8 +1,8 @@