154 lines
3.4 KiB
TypeScript
154 lines
3.4 KiB
TypeScript
|
import { reactive, computed, nextTick } from 'vue'
|
||
|
import { ServeTalkRecords } from '@/api/chat'
|
||
|
import { useDialogueStore } from '@/store'
|
||
|
import { ITalkRecord } from '@/types/chat'
|
||
|
import { formatTalkRecord } from '@/utils/talk'
|
||
|
import { addClass, removeClass } from '@/utils/dom'
|
||
|
|
||
|
interface Params {
|
||
|
receiver_id: number
|
||
|
talk_type: number
|
||
|
limit: number
|
||
|
}
|
||
|
|
||
|
export const useTalkRecord = (uid: number) => {
|
||
|
const dialogueStore = useDialogueStore()
|
||
|
|
||
|
const records = computed((): ITalkRecord[] => dialogueStore.records)
|
||
|
|
||
|
const location = reactive({
|
||
|
msgid: '',
|
||
|
num: 0
|
||
|
})
|
||
|
|
||
|
const loadConfig = reactive({
|
||
|
receiver_id: 0,
|
||
|
talk_type: 0,
|
||
|
status: 0,
|
||
|
cursor: 0
|
||
|
})
|
||
|
|
||
|
const onJumpMessage = (msgid: string) => {
|
||
|
const element = document.getElementById(msgid)
|
||
|
if (!element) {
|
||
|
if (location.msgid == '') {
|
||
|
location.msgid = msgid
|
||
|
location.num = 3
|
||
|
} else {
|
||
|
location.num--
|
||
|
|
||
|
if (location.num === 0) {
|
||
|
location.msgid = ''
|
||
|
location.num = 0
|
||
|
window['$message'].info('仅支持查看最近300条的记录')
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const el = document.getElementById('imChatPanel')
|
||
|
|
||
|
return el?.scrollTo({
|
||
|
top: 0,
|
||
|
behavior: 'smooth'
|
||
|
})
|
||
|
}
|
||
|
|
||
|
location.msgid = ''
|
||
|
location.num = 0
|
||
|
|
||
|
element?.scrollIntoView({
|
||
|
behavior: 'smooth'
|
||
|
})
|
||
|
|
||
|
addClass(element, 'border')
|
||
|
|
||
|
setTimeout(() => {
|
||
|
element && removeClass(element, 'border')
|
||
|
}, 3000)
|
||
|
}
|
||
|
|
||
|
// 加载数据列表
|
||
|
const load = async (params: Params) => {
|
||
|
const request = {
|
||
|
talk_type: params.talk_type,
|
||
|
receiver_id: params.receiver_id,
|
||
|
cursor: loadConfig.cursor,
|
||
|
limit: 30
|
||
|
}
|
||
|
|
||
|
loadConfig.status = 0
|
||
|
|
||
|
let scrollHeight = 0
|
||
|
const el = document.getElementById('imChatPanel')
|
||
|
if (el) {
|
||
|
scrollHeight = el.scrollHeight
|
||
|
}
|
||
|
|
||
|
const { data, code } = await ServeTalkRecords(request)
|
||
|
if (code != 200) {
|
||
|
return (loadConfig.status = 1)
|
||
|
}
|
||
|
|
||
|
// 防止对话切换过快,数据渲染错误
|
||
|
if (
|
||
|
request.talk_type != loadConfig.talk_type ||
|
||
|
request.receiver_id != loadConfig.receiver_id
|
||
|
) {
|
||
|
return (location.msgid = '')
|
||
|
}
|
||
|
|
||
|
const items = (data.items || []).map((item: ITalkRecord) => formatTalkRecord(uid, item))
|
||
|
|
||
|
if (request.cursor == 0) {
|
||
|
// 判断是否是初次加载
|
||
|
dialogueStore.clearDialogueRecord()
|
||
|
}
|
||
|
|
||
|
dialogueStore.unshiftDialogueRecord(items.reverse())
|
||
|
|
||
|
loadConfig.status = items.length >= request.limit ? 1 : 2
|
||
|
|
||
|
loadConfig.cursor = data.cursor
|
||
|
|
||
|
nextTick(() => {
|
||
|
const el = document.getElementById('imChatPanel')
|
||
|
|
||
|
if (el) {
|
||
|
if (request.cursor == 0) {
|
||
|
el.scrollTop = el.scrollHeight
|
||
|
|
||
|
setTimeout(() => {
|
||
|
el.scrollTop = el.scrollHeight + 1000
|
||
|
}, 50)
|
||
|
} else {
|
||
|
el.scrollTop = el.scrollHeight - scrollHeight
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (location.msgid) {
|
||
|
onJumpMessage(location.msgid)
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
|
||
|
const onRefreshLoad = () => {
|
||
|
if (loadConfig.status == 1) {
|
||
|
load({
|
||
|
receiver_id: loadConfig.receiver_id,
|
||
|
talk_type: loadConfig.talk_type,
|
||
|
limit: 30
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const onLoad = (params: Params) => {
|
||
|
loadConfig.cursor = 0
|
||
|
loadConfig.receiver_id = params.receiver_id
|
||
|
loadConfig.talk_type = params.talk_type
|
||
|
|
||
|
load(params)
|
||
|
}
|
||
|
|
||
|
return { loadConfig, records, onLoad, onRefreshLoad, onJumpMessage }
|
||
|
}
|