2024-11-22 01:06:37 +00:00
|
|
|
import { defineStore } from 'pinia'
|
|
|
|
import { ServeFindFileSplitInfo, ServeFileSubareaUpload } from '@/api/upload'
|
|
|
|
import { ServeSendTalkFile } from '@/api/chat'
|
2024-12-19 03:02:47 +00:00
|
|
|
import { useDialogueListStore } from '@/store/modules/dialogueList'
|
2024-11-22 01:06:37 +00:00
|
|
|
|
|
|
|
// @ts-ignore
|
|
|
|
const message = window.$message
|
2024-12-19 03:02:47 +00:00
|
|
|
const {updateUploadProgress} = useDialogueListStore()
|
2024-11-22 01:06:37 +00:00
|
|
|
|
|
|
|
// 处理拆分上传文件
|
|
|
|
function fileSlice(file: File, uploadId: string, eachSize: number) {
|
|
|
|
const splitNum = Math.ceil(file.size / eachSize) // 分片总数
|
|
|
|
const items: FormData[] = []
|
|
|
|
|
|
|
|
// 处理每个分片的上传操作
|
|
|
|
for (let i = 0; i < splitNum; i++) {
|
|
|
|
const start = i * eachSize
|
|
|
|
const end = Math.min(file.size, start + eachSize)
|
|
|
|
|
|
|
|
const form = new FormData()
|
|
|
|
form.append('file', file.slice(start, end))
|
|
|
|
form.append('upload_id', uploadId)
|
|
|
|
form.append('split_index', `${i + 1}`)
|
|
|
|
form.append('split_num', `${splitNum}`)
|
|
|
|
|
|
|
|
items.push(form)
|
|
|
|
}
|
|
|
|
|
|
|
|
return items
|
|
|
|
}
|
|
|
|
|
|
|
|
export const useUploadsStore = defineStore('uploads', {
|
|
|
|
state: () => {
|
|
|
|
return {
|
|
|
|
isShow: false,
|
|
|
|
items: []
|
|
|
|
}
|
|
|
|
},
|
|
|
|
getters: {
|
|
|
|
successCount: (state) => {
|
|
|
|
return state.items.filter((item: any) => {
|
|
|
|
return item.status === 2
|
|
|
|
}).length
|
|
|
|
}
|
|
|
|
},
|
|
|
|
actions: {
|
|
|
|
close() {
|
|
|
|
this.isShow = false
|
|
|
|
},
|
|
|
|
|
|
|
|
// 初始化上传
|
2024-12-19 03:02:47 +00:00
|
|
|
initUploadFile(file: File, talkParams: any, msgId: string) {
|
|
|
|
const {type:talkType,receiver_id:receiverId,username} = talkParams;
|
2024-11-22 01:06:37 +00:00
|
|
|
ServeFindFileSplitInfo({
|
|
|
|
file_name: file.name,
|
|
|
|
file_size: file.size
|
|
|
|
}).then((res) => {
|
|
|
|
if (res.code == 200) {
|
|
|
|
const { upload_id, split_size } = res.data
|
|
|
|
|
|
|
|
// @ts-ignore
|
|
|
|
this.items.unshift({
|
|
|
|
file: file,
|
|
|
|
talk_type: talkType,
|
|
|
|
receiver_id: receiverId,
|
|
|
|
upload_id: upload_id,
|
|
|
|
uploadIndex: 0,
|
|
|
|
percentage: 0,
|
|
|
|
status: 0, // 文件上传状态 0:等待上传 1:上传中 2:上传完成 3:网络异常
|
|
|
|
files: fileSlice(file, upload_id, split_size),
|
|
|
|
avatar: '',
|
|
|
|
username: username
|
|
|
|
})
|
|
|
|
|
2024-12-19 03:02:47 +00:00
|
|
|
this.triggerUpload(upload_id,msgId)
|
2024-11-22 01:06:37 +00:00
|
|
|
this.isShow = true
|
2025-03-26 11:51:07 +00:00
|
|
|
}
|
2024-11-22 01:06:37 +00:00
|
|
|
})
|
|
|
|
},
|
|
|
|
|
|
|
|
// 获取分片文件数组索引
|
|
|
|
findItem(uploadId: string): any {
|
|
|
|
return this.items.find((item: any) => item.upload_id === uploadId)
|
|
|
|
},
|
|
|
|
|
|
|
|
// 触发上传
|
2024-12-19 03:02:47 +00:00
|
|
|
triggerUpload(uploadId: string,msgId: string) {
|
2024-11-22 01:06:37 +00:00
|
|
|
const item = this.findItem(uploadId)
|
|
|
|
|
|
|
|
const form = item.files[item.uploadIndex]
|
|
|
|
|
|
|
|
item.status = 1
|
|
|
|
|
2025-03-26 11:51:07 +00:00
|
|
|
// 开始上传时就更新进度
|
|
|
|
const currentPercentage = (item.uploadIndex / item.files.length) * 100
|
|
|
|
item.percentage = currentPercentage.toFixed(1)
|
|
|
|
updateUploadProgress(msgId, currentPercentage)
|
|
|
|
|
|
|
|
ServeFileSubareaUpload(form, (progressEvent) => {
|
|
|
|
// 计算当前分片的进度
|
|
|
|
const currentChunkProgress = (progressEvent.loaded / progressEvent.total) * 100
|
|
|
|
// 计算总体进度:已完成分片 + 当前分片的进度
|
|
|
|
const totalProgress = ((item.uploadIndex + currentChunkProgress / 100) / item.files.length) * 100
|
|
|
|
item.percentage = totalProgress.toFixed(1)
|
|
|
|
updateUploadProgress(msgId, totalProgress)
|
|
|
|
})
|
2024-11-22 01:06:37 +00:00
|
|
|
.then((res) => {
|
|
|
|
if (res.code == 200) {
|
|
|
|
item.uploadIndex++
|
|
|
|
|
|
|
|
if (item.uploadIndex === item.files.length) {
|
|
|
|
item.status = 2
|
|
|
|
item.percentage = 100
|
2024-12-19 03:02:47 +00:00
|
|
|
console.log(msgId,'msgId');
|
|
|
|
|
|
|
|
updateUploadProgress(msgId,100)
|
2025-03-15 08:44:40 +00:00
|
|
|
this.sendUploadMessage(item, msgId)
|
2024-12-19 03:02:47 +00:00
|
|
|
|
2025-03-26 11:51:07 +00:00
|
|
|
// 更新虚拟列表中的状态
|
|
|
|
const { virtualList } = useDialogueListStore()
|
|
|
|
const index = virtualList.value.findIndex(item => item.file_num === msgId)
|
|
|
|
if (index !== -1) {
|
|
|
|
virtualList.value[index].uploadStatus = 2
|
|
|
|
virtualList.value[index].uploadCurrent = 100
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// 继续上传下一个分片
|
|
|
|
this.triggerUpload(uploadId, msgId)
|
2024-11-22 01:06:37 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
item.status = 3
|
2025-03-26 11:51:07 +00:00
|
|
|
// 更新虚拟列表中的状态为失败
|
|
|
|
const { virtualList } = useDialogueListStore()
|
|
|
|
const index = virtualList.value.findIndex(item => item.file_num === msgId)
|
|
|
|
if (index !== -1) {
|
|
|
|
virtualList.value[index].uploadStatus = 3
|
|
|
|
}
|
2024-11-22 01:06:37 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
.catch(() => {
|
|
|
|
item.status = 3
|
2025-03-26 11:51:07 +00:00
|
|
|
// 更新虚拟列表中的状态为失败
|
|
|
|
const { virtualList } = useDialogueListStore()
|
|
|
|
const index = virtualList.value.findIndex(item => item.file_num === msgId)
|
|
|
|
if (index !== -1) {
|
|
|
|
virtualList.value[index].uploadStatus = 3
|
|
|
|
}
|
2024-11-22 01:06:37 +00:00
|
|
|
})
|
|
|
|
},
|
|
|
|
|
|
|
|
// 发送上传消息
|
2025-03-15 08:44:40 +00:00
|
|
|
sendUploadMessage(item: any, file_num: String) {
|
2024-11-22 01:06:37 +00:00
|
|
|
ServeSendTalkFile({
|
|
|
|
upload_id: item.upload_id,
|
|
|
|
receiver_id: item.receiver_id,
|
2025-03-15 08:44:40 +00:00
|
|
|
talk_type: item.talk_type,
|
|
|
|
file_num: file_num
|
2024-11-22 01:06:37 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|