feat:0820需求
This commit is contained in:
+50
-13
@@ -281,6 +281,7 @@ export default {
|
||||
socketStatus: 'connecting',
|
||||
socket: null,
|
||||
pollingTimer: null,
|
||||
pageHidden: false,
|
||||
uploadingImage: false,
|
||||
uploadingAttachment: false,
|
||||
recording: false,
|
||||
@@ -411,20 +412,36 @@ export default {
|
||||
const page = pages.length ? pages[pages.length - 1] : null
|
||||
this.currentEntryOptions = { ...((page && page.options) || {}), ...(this.entryOptions || {}) }
|
||||
this.restorePendingContext()
|
||||
this.appShowHandler = () => {
|
||||
if (!this.pageHidden) this.resume({ forceReconnect: true })
|
||||
}
|
||||
this.appHideHandler = () => {
|
||||
if (!this.pageHidden) this.suspend()
|
||||
}
|
||||
uni.$on('kefu-app-show', this.appShowHandler)
|
||||
uni.$on('kefu-app-hide', this.appHideHandler)
|
||||
this.initialize()
|
||||
this.$nextTick(() => this.measureScrollViewport())
|
||||
},
|
||||
beforeUnmount() {
|
||||
this.unbindAppLifecycle()
|
||||
this.cancelVoiceRecording()
|
||||
this.stopRealtime()
|
||||
this.clearVirtualListTimers()
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.unbindAppLifecycle()
|
||||
this.cancelVoiceRecording()
|
||||
this.stopRealtime()
|
||||
this.clearVirtualListTimers()
|
||||
},
|
||||
methods: {
|
||||
unbindAppLifecycle() {
|
||||
if (this.appShowHandler) uni.$off('kefu-app-show', this.appShowHandler)
|
||||
if (this.appHideHandler) uni.$off('kefu-app-hide', this.appHideHandler)
|
||||
this.appShowHandler = null
|
||||
this.appHideHandler = null
|
||||
},
|
||||
async initialize() {
|
||||
// #ifdef H5
|
||||
const previewHash = typeof window !== 'undefined' ? window.location.hash : ''
|
||||
@@ -467,27 +484,39 @@ export default {
|
||||
async loadLatestMessages({ silent = false } = {}) {
|
||||
if (!this.member || !this.member.id) return
|
||||
try {
|
||||
let result = await getMessages({ userId: this.member.id, page: 1, pageSize: PAGE_SIZE })
|
||||
const firstPage = result.messages || {}
|
||||
const totalPage = Number(firstPage.totalPage || 1)
|
||||
if (totalPage > 1) {
|
||||
const knownLastPage = this.conversation && this.conversation.id && this.totalPage
|
||||
? Number(this.totalPage)
|
||||
: 1
|
||||
let result = await getMessages({
|
||||
userId: this.member.id,
|
||||
conversationId: this.conversation && this.conversation.id,
|
||||
page: knownLastPage,
|
||||
pageSize: PAGE_SIZE
|
||||
})
|
||||
let pageResult = result.messages || {}
|
||||
let totalPage = Number(pageResult.totalPage || 1)
|
||||
// 首次加载从第 1 页取得会话信息;只有确实存在后续页时才再查末页。
|
||||
// 后续轮询直接查已知末页,避免每 4 秒重复请求首页和末页。
|
||||
if (totalPage > knownLastPage) {
|
||||
result = await getMessages({
|
||||
userId: this.member.id,
|
||||
conversationId: result.conversation && result.conversation.id,
|
||||
page: totalPage,
|
||||
pageSize: PAGE_SIZE
|
||||
})
|
||||
pageResult = result.messages || {}
|
||||
totalPage = Number(pageResult.totalPage || totalPage)
|
||||
}
|
||||
this.conversation = result.conversation || this.conversation
|
||||
if (this.conversation && this.conversation.id) {
|
||||
await markMemberMessagesRead({ userId: this.member.id, conversationId: this.conversation.id }).catch(() => {})
|
||||
}
|
||||
const page = result.messages || {}
|
||||
const page = pageResult
|
||||
this.currentPage = Number(page.curPage || totalPage || 1)
|
||||
this.totalPage = Number(page.totalPage || totalPage || 1)
|
||||
this.hasEarlier = this.currentPage > 1
|
||||
const incoming = page.entitys || []
|
||||
const added = this.mergeMessages(incoming)
|
||||
if (added && this.conversation && this.conversation.id && incoming.some(item => Number(item.senderType) !== 2)) {
|
||||
await markMemberMessagesRead({ userId: this.member.id, conversationId: this.conversation.id }).catch(() => {})
|
||||
}
|
||||
if (added && this.userNearBottom) this.$nextTick(() => this.scrollToBottom(false))
|
||||
if (added && !this.userNearBottom) this.showNewMessageButton = true
|
||||
} catch (error) {
|
||||
@@ -582,7 +611,7 @@ export default {
|
||||
this.stopPolling()
|
||||
this.loadLatestMessages({ silent: true })
|
||||
}
|
||||
if (status === 'offline') this.startPolling()
|
||||
if (status === 'connecting' || status === 'offline') this.startPolling()
|
||||
},
|
||||
|
||||
handleSocketEvent(event) {
|
||||
@@ -623,7 +652,7 @@ export default {
|
||||
},
|
||||
|
||||
startPolling() {
|
||||
if (this.pollingTimer) return
|
||||
if (this.pageHidden || this.pollingTimer) return
|
||||
this.socketStatus = 'polling'
|
||||
this.loadLatestMessages({ silent: true })
|
||||
this.pollingTimer = setInterval(() => this.loadLatestMessages({ silent: true }), POLLING_INTERVAL)
|
||||
@@ -1507,15 +1536,23 @@ export default {
|
||||
redirectToLogin()
|
||||
},
|
||||
|
||||
async resume() {
|
||||
async resume({ forceReconnect = false, pageVisible = false } = {}) {
|
||||
if (pageVisible) this.pageHidden = false
|
||||
if (this.pageHidden) return
|
||||
if (this.previewMode) return
|
||||
// The socket is intentionally closed while the page is hidden. Reconcile any AI
|
||||
// messages created during that gap before reconnecting realtime delivery.
|
||||
if (this.member) await this.loadLatestMessages({ silent: true })
|
||||
if (this.member && !this.socket) this.connectSocket()
|
||||
if (!this.member) return
|
||||
if (!this.socket) {
|
||||
this.connectSocket()
|
||||
return
|
||||
}
|
||||
this.socket.reconnectNow(forceReconnect)
|
||||
},
|
||||
|
||||
suspend() {
|
||||
suspend({ pageHidden = false } = {}) {
|
||||
if (pageHidden) this.pageHidden = true
|
||||
this.stopRealtime()
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user