diff --git a/src/components/MsgReadModal/index.vue b/src/components/MsgReadModal/index.vue index 33aba900..9bf8094e 100644 --- a/src/components/MsgReadModal/index.vue +++ b/src/components/MsgReadModal/index.vue @@ -56,6 +56,20 @@ watch(data, (val, oldVal) => { list[active.value].isLast = val.isLast }) +// 切换 Tab 也请求 +watch(active, (val, oldVal) => { + if (val !== oldVal && msgId.value) { + send({ + params: { + searchType: active.value, + pageSize: 20, + msgId: msgId.value, + cursor: curList.value.cursor || undefined, + }, + }) + } +}) + // 弹窗打开而且有 msgId 值就发送请求 watch(value, (val) => { if (val && msgId.value) { diff --git a/src/enums/index.ts b/src/enums/index.ts index 8a279c6a..fdd1c78c 100644 --- a/src/enums/index.ts +++ b/src/enums/index.ts @@ -90,3 +90,11 @@ export enum RoomTypeEnum { /** 2单聊 */ Single, } + +/** 变更类型 1 加入群组,2: 移除群组 */ +export enum ChangeTypeEnum { + /** 1 加入群组 */ + JOIN = 1, + /** 2 移除群组 */ + REMOVE, +} diff --git a/src/main.ts b/src/main.ts index 6212026b..a2b2b81c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -21,9 +21,9 @@ const pinia = createPinia() pinia.use(piniaPluginPersistedstate) // 数据持久化 const app = createApp(App) -app.use(pinia) -app.use(router) +app.use(pinia).use(router) app.directive('login', vLogin) // 登录权限指令-未登录先登录 app.directive('login-show', vLoginShow) // 登录权限指令-未登录先登录 app.directive('friends', vFriends) // 是否好友 app.mount('#app') +// router.isReady().then(() => app.mount('#app')) diff --git a/src/services/apis.ts b/src/services/apis.ts index 5ec4e2c6..d0a0a353 100644 --- a/src/services/apis.ts +++ b/src/services/apis.ts @@ -105,7 +105,10 @@ export default { deleteRequest(urls.inviteGroupMember, params), /** 群组详情 */ groupDetail: (params: { id: number }) => getRequest(urls.groupDetail, { params }), - /** 会话详情(联系人列表发消息用) */ - sessionDetail: (params: { uid: number }) => + /** 会话详情 */ + sessionDetail: (params: { id: number }) => getRequest(urls.sessionDetail, { params }), + /** 会话详情(联系人列表发消息用) */ + sessionDetailWithFriends: (params: { uid: number }) => + getRequest(urls.sessionDetailWithFriends, { params }), } diff --git a/src/services/urls.ts b/src/services/urls.ts index cbc4d023..7f0ed2d9 100644 --- a/src/services/urls.ts +++ b/src/services/urls.ts @@ -33,5 +33,6 @@ export default { getGroupUserList: `${prefix}/capi/room/public/group/member/page`, inviteGroupMember: `${prefix}/capi/room/group/member`, // 邀请群成员 groupDetail: `${prefix}/capi/room/public/group`, // 群组详情 - sessionDetail: `${prefix}/capi/chat/public/contact/detail/friend`, // 会话详情(联系人列表发消息用) + sessionDetail: `${prefix}/capi/chat/public/contact/detail`, // 会话详情 + sessionDetailWithFriends: `${prefix}/capi/chat/public/contact/detail/friend`, // 会话详情(联系人列表发消息用) } diff --git a/src/stores/chat.ts b/src/stores/chat.ts index 53ab8c05..ea5c4cd7 100644 --- a/src/stores/chat.ts +++ b/src/stores/chat.ts @@ -2,6 +2,7 @@ import { ref, reactive, computed, watch } from 'vue' import { defineStore } from 'pinia' import cloneDeep from 'lodash/cloneDeep' import { useRoute } from 'vue-router' +import Router from '@/router' import apis from '@/services/apis' import type { MessageType, MarkItemType, RevokedMsgType, SessionItem } from '@/services/types' import { MarkEnum, RoomTypeEnum } from '@/enums' @@ -19,11 +20,11 @@ export const pageSize = 20 let isFirstInit = false export const useChatStore = defineStore('chat', () => { + const route = useRoute() const cachedStore = useCachedStore() const userStore = useUserStore() const globalStore = useGlobalStore() const groupStore = useGroupStore() - const route = useRoute() const sessionList = reactive([]) // 会话列表 const sessionOptions = reactive({ isLast: false, isLoading: false, cursor: '' }) @@ -255,7 +256,7 @@ export const useChatStore = defineStore('chat', () => { sortAndUniqueSessionList() } - const pushMsg = (msg: MessageType) => { + const pushMsg = async (msg: MessageType) => { const current = messageMap.get(msg.message.roomId) current?.set(msg.message.id, msg) @@ -268,8 +269,17 @@ export const useChatStore = defineStore('chat', () => { // 发完消息就要刷新会话列表, // 如果当前会话已经置顶了,可以不用刷新 if (globalStore.currentSession && globalStore.currentSession.roomId !== msg.message.roomId) { - // getSessionList(true) - updateSessionLastActiveTime(msg.message.roomId) + let result = undefined + // 如果当前路由不是聊天,就开始拿会话详情,并手动新增一条会话记录 + if (route?.path && route?.path !== '/') { + globalStore.currentSession.roomId = msg.message.roomId + globalStore.currentSession.type = RoomTypeEnum.Single + if (!current) { + result = await apis.sessionDetail({ id: msg.message.roomId }).send() + } + Router.push('/') + } + updateSessionLastActiveTime(msg.message.roomId, result) } // 如果收到的消息里面是艾特自己的就发送系统通知 diff --git a/src/stores/contacts.ts b/src/stores/contacts.ts index 0796610c..f55fa097 100644 --- a/src/stores/contacts.ts +++ b/src/stores/contacts.ts @@ -1,11 +1,14 @@ import { reactive } from 'vue' import { defineStore } from 'pinia' import apis from '@/services/apis' +import { useGlobalStore } from '@/stores/global' +import { RequestFriendAgreeStatus } from '@/services/types' import type { ContactItem, RequestFriendItem } from '@/services/types' export const pageSize = 20 export const useContactStore = defineStore('contact', () => { + const globalStore = useGlobalStore() const contactsList = reactive([]) const requestFriendsList = reactive([]) @@ -13,7 +16,9 @@ export const useContactStore = defineStore('contact', () => { const requestFriendsOptions = reactive({ isLast: false, isLoading: false, cursor: '' }) const getContactList = async (isFresh = false) => { - if (contactsOptions.isLast || contactsOptions.isLoading) return + if (!isFresh) { + if (contactsOptions.isLast || contactsOptions.isLoading) return + } contactsOptions.isLoading = true const data = await apis .getContactList({ @@ -35,7 +40,9 @@ export const useContactStore = defineStore('contact', () => { } const getRequestFriendsList = async (isFresh = false) => { - if (requestFriendsOptions.isLast || requestFriendsOptions.isLoading) return + if (!isFresh) { + if (requestFriendsOptions.isLast || requestFriendsOptions.isLoading) return + } requestFriendsOptions.isLoading = true const data = await apis .requestFriendList({ @@ -56,8 +63,8 @@ export const useContactStore = defineStore('contact', () => { } // 默认执行一次 - getContactList() - getRequestFriendsList() + // getContactList() + // getRequestFriendsList() /** 接受好友请求 */ const onAcceptFriend = (applyId: number) => { @@ -70,6 +77,12 @@ export const useContactStore = defineStore('contact', () => { getRequestFriendsList(true) // 刷新好友列表 getContactList(true) + + // 标识为可以发消息的人 + if (globalStore.currentSelectedContact) { + // @ts-ignore + globalStore.currentSelectedContact.status = RequestFriendAgreeStatus.Agree + } }) } diff --git a/src/utils/websocket.ts b/src/utils/websocket.ts index 40e6e071..83c8e156 100644 --- a/src/utils/websocket.ts +++ b/src/utils/websocket.ts @@ -13,7 +13,7 @@ import type { OnStatusChangeType, } from './wsType' import type { MessageType, MarkItemType, RevokedMsgType } from '@/services/types' -import { OnlineEnum } from '@/enums' +import { OnlineEnum, ChangeTypeEnum, RoomTypeEnum } from '@/enums' import { computedToken } from '@/services/request' import { worker } from './initWorker' import shakeTitle from '@/utils/shakeTitle' @@ -169,15 +169,6 @@ class WS { emojiStore.getEmojiList() break } - // 用户 token 过期 - case WsResponseMessageType.TokenExpired: { - userStore.isSign = false - userStore.userInfo = {} - localStorage.removeItem('USER_INFO') - localStorage.removeItem('TOKEN') - loginStore.loginStatus = LoginStatus.Init - break - } // 收到消息 case WsResponseMessageType.ReceiveMessage: { chatStore.pushMsg(params.data as MessageType) @@ -191,6 +182,15 @@ class WS { groupStore.batchUpdateUserStatus(data.changeList) break } + // 用户 token 过期 + case WsResponseMessageType.TokenExpired: { + userStore.isSign = false + userStore.userInfo = {} + localStorage.removeItem('USER_INFO') + localStorage.removeItem('TOKEN') + loginStore.loginStatus = LoginStatus.Init + break + } // 小黑子的发言在禁用后,要删除他的发言 case WsResponseMessageType.InValidUser: { const data = params.data as { uid: number } @@ -225,6 +225,31 @@ class WS { }) break } + // 新好友申请 + case WsResponseMessageType.NewFriendSession: { + // changeType 1 加入群组,2: 移除群组 + const data = params.data as { + roomId: number + uid: number + changeType: ChangeTypeEnum + activeStatus: OnlineEnum + lastOptTime: number + } + if ( + data.roomId === globalStore.currentSession.roomId && + globalStore.currentSession.type === RoomTypeEnum.Group + ) { + if (data.changeType === ChangeTypeEnum.REMOVE) { + // 移除群成员 + groupStore.filterUser(data.uid) + // TODO 添加一条退出群聊的消息 + } else { + // TODO 添加群成员 + // TODO 添加一条入群的消息 + } + } + break + } default: { console.log('接收到未处理类型的消息:', params) break diff --git a/src/utils/wsType.ts b/src/utils/wsType.ts index dae89863..5b5774ff 100644 --- a/src/utils/wsType.ts +++ b/src/utils/wsType.ts @@ -22,6 +22,8 @@ export enum WsResponseMessageType { WSMsgRecall, /** 新好友申请 */ RequestNewFriend, + /** 新好友会话 */ + NewFriendSession, } /** diff --git a/src/views/Home/Contacts/components/ContactList/Content/index.vue b/src/views/Home/Contacts/components/ContactList/Content/index.vue index 1da044fb..79533849 100644 --- a/src/views/Home/Contacts/components/ContactList/Content/index.vue +++ b/src/views/Home/Contacts/components/ContactList/Content/index.vue @@ -37,7 +37,7 @@ const onDeleteContact = (uid: number) => { }) } const onStartSession = async (uid: number) => { - const result = await apis.sessionDetail({ uid }).send() + const result = await apis.sessionDetailWithFriends({ uid }).send() globalStore.currentSession.roomId = result.roomId globalStore.currentSession.type = RoomTypeEnum.Single chatStore.updateSessionLastActiveTime(result.roomId, result) diff --git a/src/views/Home/Contacts/components/ContactList/Side/ContactItem.vue b/src/views/Home/Contacts/components/ContactList/Side/ContactItem.vue index 343f5629..a9cb4f2c 100644 --- a/src/views/Home/Contacts/components/ContactList/Side/ContactItem.vue +++ b/src/views/Home/Contacts/components/ContactList/Side/ContactItem.vue @@ -1,5 +1,6 @@