diff --git a/components.d.ts b/components.d.ts index 0dae289..5202040 100644 --- a/components.d.ts +++ b/components.d.ts @@ -30,6 +30,8 @@ declare module 'vue' { LoginMessage: typeof import('./src/components/talk/message/LoginMessage.vue')['default'] Message: typeof import('./src/components/x-message/message/index.vue')['default'] MixedMessage: typeof import('./src/components/talk/message/MixedMessage.vue')['default'] + NButton: typeof import('naive-ui')['NButton'] + NIcon: typeof import('naive-ui')['NIcon'] PageAnimation: typeof import('./src/components/page-animation/index.vue')['default'] RevokeMessage: typeof import('./src/components/talk/message/RevokeMessage.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] diff --git a/src/main.js b/src/main.js index b6e6ad7..160aa0a 100644 --- a/src/main.js +++ b/src/main.js @@ -14,6 +14,7 @@ import { vLoading } from '@/components/x-loading/index.js' import messagePopup from '@/components/x-message/useMessagePopup' import pageAnimation from '@/components/page-animation/index.vue' import * as plugins from './plugins' +import { useDialogueStore, useTalkStore } from '@/store' const { showMessage } = messagePopup() dayjs.locale('zh-cn') if (import.meta.env.VITE_SHOW_CONSOLE === 'true') { @@ -40,6 +41,41 @@ export function createApp() { }) }, }) + + //获取当前聊天页面所在页面,并通过当前的receiver_id判断是否要创建本地通知栏消息 + window.getCurrentChatRoute = (msg) => { + let pushMsg = JSON.parse(decodeURIComponent(msg)) + //当前所在聊天会话的receiver_id + const receiver_id = pushMsg?.payload?.receiver_id + // 获取当前页面路径 + const pages = getCurrentPages() + const page = pages[pages.length - 1] + console.log(page.route) + + const dialogueStore = useDialogueStore() + console.log(dialogueStore?.talk?.receiver_id) + if ( + page?.route === 'pages/dialog/index' && + receiver_id === dialogueStore?.talk?.receiver_id + ) { + return + } + let OAWebView = plus.webview.all() + //all里面第一个是入口webview + OAWebView[0].evalJS(`doCreatePushMessage('${msg}')`) + } + + //处理聊天推送弹窗点开 + window.openUniPushMsg = (msg) => { + console.log("=====点击通知栏消息") + let pushMsg = JSON.parse(decodeURIComponent(msg)) + console.log("=====pushMsg",pushMsg) + //由于弹窗前处理了不该弹窗的场景,因此这里弹窗可以一并处理 + //也就是都跳转到聊天页面 + const talkStore = useTalkStore() + talkStore.toTalk(pushMsg?.payload?.talk_type, pushMsg?.payload?.receiver_id) + } + window.message = ['success', 'error', 'warning'].reduce((acc, type) => { acc[type] = (message) => { if (typeof message === 'string') { diff --git a/src/pages/chatSettings/components/selectMemberByAlphabet.vue b/src/pages/chatSettings/components/selectMemberByAlphabet.vue index 72547bf..6c8780f 100644 --- a/src/pages/chatSettings/components/selectMemberByAlphabet.vue +++ b/src/pages/chatSettings/components/selectMemberByAlphabet.vue @@ -381,7 +381,7 @@ const handleClickItem = (item) => { } if(props?.manageType === 'searchRecord'){ uni.navigateTo({ - url: '/pages/search/searchByCondition/index?condition=member' + url: '/pages/search/searchByCondition/index?condition=member&groupMemberId=' + item.id }) return } diff --git a/src/pages/chatSettings/index.vue b/src/pages/chatSettings/index.vue index fb3b9da..370556f 100644 --- a/src/pages/chatSettings/index.vue +++ b/src/pages/chatSettings/index.vue @@ -504,8 +504,7 @@ const toSearchByConditionPage = (flag) => { condition = 'link' } uni.navigateTo({ - url: - '/pages/search/searchByCondition/index?condition=' + condition + url: '/pages/search/searchByCondition/index?condition=' + condition, }) } } @@ -644,7 +643,8 @@ const toSearchPage = () => { '/pages/search/moreResult/moreResultDetail?talk_type=' + dialogueParams.type + '&receiver_id=' + - dialogueParams.receiver_id, + dialogueParams.receiver_id + + '&hideFirstRecord=1', }) } diff --git a/src/pages/dialog/index.vue b/src/pages/dialog/index.vue index e027ce7..c0d97be 100644 --- a/src/pages/dialog/index.vue +++ b/src/pages/dialog/index.vue @@ -561,13 +561,18 @@ const state = ref({ useCustomLoadMore: false, //是否使用自定义加载更多事件(下拉刷新、上拉加载) recordDate: "", //按日期查询聊天记录的开始日期 serveFindRecord: [], //调用接口查找到的聊天记录 -}); + middleMsg: {}, //缓存中没有时,调用接口初次使用的依据记录 + keepDialogInfo: false, //是否保存会话信息 +}) uniOnload(async (options) => { - console.log("onLoad" + options); + console.log('onLoad' + JSON.stringify(options)) if (options.sessionId) { state.value.sessionId = options.sessionId; } + if (options.keepDialogInfo) { + state.value.keepDialogInfo = options.keepDialogInfo === '1' ? true : false + } if (options.msgInfo) { const msgInfo = JSON.parse(decodeURIComponent(options.msgInfo)); queryRecordsByMsgInfo(msgInfo); @@ -970,11 +975,11 @@ const withdrawerConfirm = () => { // 添加检查是否可以重新编辑撤回消息的函数 const canEditRevokedMessage = (item) => { - console.log(item); + // console.log(item) if (item.is_revoke === 1 && item.msg_type === 1) { - const now = new Date().getTime(); - const revokeTime = new Date(item.created_at).getTime(); - console.log(now); + const now = new Date().getTime() + const revokeTime = new Date(item.created_at).getTime() + // console.log(now) // 检查是否在5分钟内 return now - revokeTime <= 5 * 60 * 1000; } @@ -1095,14 +1100,17 @@ watch( state.value.localPageLoadDone = true; return; } - if ( - newValue[newValue.length - 1]?.sequence === - dialogueList?.records?.[0]?.sequence - ) { - //相同意味着分页加载缓存中的聊天记录完毕 - state.value.localPageLoadDone = true; - } else { - state.value.localPageLoadDone = false; + // 只在正常加载模式下检查是否加载完缓存数据 + if (!state.value.useCustomLoadMore) { + if ( + newValue[newValue.length - 1]?.sequence === + dialogueList?.records?.[0]?.sequence + ) { + //相同意味着分页加载缓存中的聊天记录完毕 + state.value.localPageLoadDone = true + } else { + state.value.localPageLoadDone = false + } } } }, @@ -1130,7 +1138,13 @@ const onScrollToLower = async () => { ); console.log(moreRecords); - virtualList.value = moreRecords.concat(tempVirtualList).reverse(); + // 格式化新加载的消息 + const formattedMoreRecords = moreRecords.map((item) => ({ + ...item, + float: item.user_id === talkParams.uid ? 'right' : 'left', + })) + + virtualList.value = formattedMoreRecords.concat(tempVirtualList).reverse() console.log(virtualList.value); } else { @@ -1174,12 +1188,19 @@ const onScrollToUpper = async () => { const moreRecords = await findTalkRecords( "", false, - tempVirtualList[tempVirtualList.length - 1].sequence - ); - console.log(moreRecords); + tempVirtualList[tempVirtualList.length - 1].sequence, + ) + console.log(moreRecords) + + // 格式化新加载的消息 + const formattedMoreRecords = moreRecords.map((item) => ({ + ...item, + float: item.user_id === talkParams.uid ? 'right' : 'left', + })) + virtualList.value = tempVirtualList - .concat(moreRecords.reverse()) - .reverse(); + .concat(formattedMoreRecords.reverse()) + .reverse() console.log(virtualList.value); @@ -1307,8 +1328,9 @@ const getMentionSelectLists = (mentionSelectList) => { //根据msg信息找到对应的聊天记录,并根据sequence等查看上下文 const queryRecordsByMsgInfo = async (msgInfo) => { - console.log(msgInfo); - const dialogueList = getDialogueList(talkParams.index_name); + console.log(msgInfo) + state.value.middleMsg = msgInfo + const dialogueList = getDialogueList(talkParams.index_name) const recordIndex = dialogueList?.records?.findIndex( (record) => record.msg_id === msgInfo.msg_id ); @@ -1324,6 +1346,15 @@ const queryRecordsByMsgInfo = async (msgInfo) => { // console.log(recordIndex-startRecordIndex) recordsList = dialogueList.records.slice(startRecordIndex, endRecordIndex); } + + // 格式化消息,确保每条消息都有正确的 float + recordsList = recordsList.map((item) => { + return { + ...item, + float: item.user_id === talkParams.uid ? 'right' : 'left', + } + }) + nextTick(() => { zpagingRef.value.complete(recordsList.reverse()); loadConfig.status = dialogueList?.records?.[0]?.sequence > 1 ? 1 : 2; @@ -1374,8 +1405,9 @@ const findTalkRecords = (record, isMiddle, sequence, appointParams) => { start_time: "", end_time: "", group_member_user_id: 0, //群成员id,当查询群历史消息的时候,需要指定群成员的时候送 - sort_sequence: "asc", - }; + sort_sequence: 'asc', + create_time: state.value.middleMsg.created_at, + } if (record) { params = Object.assign({}, params, { start_time: record, @@ -1473,8 +1505,8 @@ const rpxToPx = (rpx) => { }; onUnmounted(() => { - if (!state.value.recordDate) { - dialogueStore.setDialogue({}); + if (!state.value.keepDialogInfo) { + dialogueStore.setDialogue({}) } clearMultiSelect(); }); diff --git a/src/pages/index/components/chatItem.vue b/src/pages/index/components/chatItem.vue index 0558a11..de994cd 100644 --- a/src/pages/index/components/chatItem.vue +++ b/src/pages/index/components/chatItem.vue @@ -1,43 +1,50 @@ diff --git a/src/pages/index/index.vue b/src/pages/index/index.vue index b7f90fa..4122846 100644 --- a/src/pages/index/index.vue +++ b/src/pages/index/index.vue @@ -125,6 +125,7 @@ import { ref, watch, computed } from 'vue' import { onShow, onLoad } from '@dcloudio/uni-app' import { useChatList } from '@/store/chatList/index.js' import { useAuth } from '@/store/auth' +import { ServeClearTalkUnreadNum } from '@/api/chat' import { useTalkStore, useUserStore, useDialogueStore } from '@/store' import chatItem from './components/chatItem.vue' import addCircle from '@/static/image/chatList/addCircle.png' @@ -237,21 +238,23 @@ onLoad((options) => { if (items?.value?.length > 0) { items.value.forEach((openSession) => { if (openSession.index_name === options?.openSessionIndexName) { - dialogueStore.setDialogue(openSession) - if (openSession.unread_num > 0) { - ServeClearTalkUnreadNum({ - talk_type: openSession.talk_type, - receiver_id: openSession.receiver_id, - }).then(() => { - talkStore.updateItem({ - index_name: openSession.index_name, - unread_num: 0, + setTimeout(() => { + dialogueStore.setDialogue(openSession) + if (openSession.unread_num > 0) { + ServeClearTalkUnreadNum({ + talk_type: openSession.talk_type, + receiver_id: openSession.receiver_id, + }).then(() => { + talkStore.updateItem({ + index_name: openSession.index_name, + unread_num: 0, + }) }) + } + uni.navigateTo({ + url: `/pages/dialog/index?sessionId=${openSession.id}`, }) - } - uni.navigateTo({ - url: `/pages/dialog/index?sessionId=${openSession.id}`, - }) + }, 500) } }) } diff --git a/src/pages/search/components/searchItem.vue b/src/pages/search/components/searchItem.vue index fadbcf3..e7bc426 100644 --- a/src/pages/search/components/searchItem.vue +++ b/src/pages/search/components/searchItem.vue @@ -96,6 +96,7 @@ import { import HighlightText from './highLightText.vue' import { useI18n } from 'vue-i18n' import { beautifyTime } from '@/utils/datetime' +import { ChatMsgTypeMapping } from '@/constant/message' const { t } = useI18n() const props = defineProps({ searchItem: Object | Number, @@ -175,6 +176,13 @@ const keyMapping = { name: 'receiver_name', group_num: 'group_num', }, + search_by_member_condition: { + avatar: 'avatar', + name: 'nickname', + created_at: 'created_at', + msg_type: 'msg_type', + detailKey: 'chatMessageType', + }, } //获取key对应值 const getKeyValue = (keys) => { @@ -254,6 +262,12 @@ const resultDetail = computed(() => { case 'extra': result_detail = props.searchItem?.extra break + case 'chatMessageType': + result_detail = + props.searchItem?.msg_type === 1 + ? props.searchItem?.extra?.content + : ChatMsgTypeMapping[props.searchItem?.msg_type] + break default: result_detail = '' } diff --git a/src/pages/search/components/searchList.vue b/src/pages/search/components/searchList.vue index 02fc90f..fea0221 100644 --- a/src/pages/search/components/searchList.vue +++ b/src/pages/search/components/searchList.vue @@ -36,7 +36,10 @@ -
+
userStore.uid), //当前用户id + hideFirstRecord: false, //是否隐藏前缀及搜索群/用户主体信息 }) onLoad((options) => { @@ -55,6 +57,10 @@ onLoad((options) => { } console.log(JSON.parse(decodeURIComponent(state.apiParams))) + + if (options.hideFirstRecord) { + state.hideFirstRecord = options.hideFirstRecord === '1' ? true : false + } }) //分页查询时,最后一条id变化 @@ -116,7 +122,7 @@ const clickSearchItem = ( }) } else { uni.navigateTo({ - url: '/pages/dialog/index?msgInfo=' + res, + url: '/pages/dialog/index?msgInfo=' + res + '&keepDialogInfo=1', }) } } diff --git a/src/pages/search/searchByCondition/index.vue b/src/pages/search/searchByCondition/index.vue index f424d2e..1cae687 100644 --- a/src/pages/search/searchByCondition/index.vue +++ b/src/pages/search/searchByCondition/index.vue @@ -9,6 +9,7 @@ :auto="false" :loading-more-default-as-loading="true" :inside-more="true" + v-model="state.flatList" >