chat-app/src/pages/dialog/components/filePanel.vue

262 lines
7.8 KiB
Vue
Raw Normal View History

2024-12-06 08:55:15 +00:00
<template>
<div class="emojiRoot">
<div @click="choosePhoto" class="flex flex-col items-center">
<div class="w-[106rpx] h-[106rpx] bg-[#F9F9F9] rounded-[60rpx] flex-center">
<tm-image :width="53" :height="44" :src="photoAlbum"></tm-image>
</div>
<div class="mt-[6rpx] text-[#666666] text-[24rpx]">照片</div>
</div>
<div @click="takePhoto" class="flex flex-col items-center">
<div class="w-[106rpx] h-[106rpx] bg-[#F9F9F9] rounded-[60rpx] flex-center">
<tm-image :width="53" :height="44" :src="photoGraph"></tm-image>
</div>
<div class="mt-[6rpx] text-[#666666] text-[24rpx]">拍摄</div>
</div>
<div @click="chooseFile" class="flex flex-col items-center">
<div class="w-[106rpx] h-[106rpx] bg-[#F9F9F9] rounded-[60rpx] flex-center">
<tm-image :width="53" :height="44" :src="folder"></tm-image>
</div>
<div class="mt-[6rpx] text-[#666666] text-[24rpx]">文件</div>
</div>
</div>
</template>
<script setup>
import { ref, reactive, defineProps, defineEmits } from "vue"
import dayjs from "dayjs";
import { beautifyTime } from '@/utils/datetime'
import { useDialogueListStore, useDialogueStore, useUserStore } from '@/store'
import { useSessionMenu } from '@/hooks'
import photoAlbum from '@/static/image/chatList/photoAlbum.png'
import photoGraph from '@/static/image/chatList/photoGraph.png'
import folder from '@/static/image/chatList/folder.png'
import { uploadImg } from '@/api/chat'
import { uniqueId } from '@/utils'
2024-12-13 05:09:38 +00:00
import { getFileFromUrl } from '@/utils'
import { getVideoImage } from '@/utils/common'
2024-12-06 08:55:15 +00:00
const props = defineProps({
sendUserInfo: {
type: Object,
default: {},
required: true
}
});
2024-12-13 05:09:38 +00:00
const { addDialogueRecord, virtualList, updateUploadProgress } = useDialogueListStore()
2024-12-06 08:55:15 +00:00
const dialogueStore = useDialogueStore()
const userStore = useUserStore()
2024-12-13 05:09:38 +00:00
const emit = defineEmits(['selectImg'])
2024-12-06 08:55:15 +00:00
2024-12-13 05:09:38 +00:00
const onProgressFn = (progress, file, id) => {
console.log(progress.loaded / progress.total * 100, 'progress');
updateUploadProgress(id, progress.loaded / progress.total * 100)
2024-12-06 08:55:15 +00:00
}
2024-12-13 05:09:38 +00:00
const onUploadImageVideo = async (file, type = 'image') => {
console.log(file, 'file');
return new Promise(async (resolve) => {
if (type === 'image') {
let image = new Image()
image.src = URL.createObjectURL(file)
image.onload = () => {
const form = new FormData()
form.append('file', file)
form.append("source", "fonchain-chat");
form.append("urlParam", `width=${image.width}&height=${image.height}`);
let randomId = uniqueId()
let newItem = {
2024-12-06 08:55:15 +00:00
avatar: userStore.avatar,
created_at: dayjs().format('YYYY-MM-DD HH:mm:ss'),
extra: {
height: image.height,
name: "",
size: 0,
url: image.src,
width: image.width
},
float: "right",
isCheck: false,
is_mark: 0,
is_read: 0,
is_revoke: 0,
msg_id: randomId,
msg_type: 3,
nickname: userStore.nickname,
receiver_id: dialogueStore.talk.receiver_id,
sequence: -1,
talk_type: dialogueStore.talk.talk_type,
user_id: userStore.uid,
2024-12-13 05:09:38 +00:00
uploadCurrent: 0,
uploadStatus: 1, // 1 上传中 2 上传成功 3 上传失败
2024-12-06 08:55:15 +00:00
}
2024-12-13 05:09:38 +00:00
virtualList.value.unshift(newItem)
uploadImg(form, (e, file) => onProgressFn(e, file, randomId)).then(({ status, data, msg }) => {
if (status == 0) {
resolve({
type: 'image',
url: data.ori_url,
size: file.size,
width: image.width,
height: image.height
})
} else {
resolve('')
message.error(msg)
}
})
}
} else {
let resp = await getVideoImage(file)
const form = new FormData()
form.append('file', file)
form.append("source", "fonchain-chat");
form.append("type", "video");
form.append("urlParam", `width=${resp.width}&height=${resp.height}`);
let randomId = uniqueId()
let newItem = {
avatar: userStore.avatar,
created_at: dayjs().format('YYYY-MM-DD HH:mm:ss'),
extra: {
duration: parseInt(resp.duration),
height: resp.height,
name: "",
url: '',
cover: resp.url,
width: resp.width
},
float: "right",
isCheck: false,
is_mark: 0,
is_read: 0,
is_revoke: 0,
msg_id: randomId,
msg_type: 5,
nickname: userStore.nickname,
receiver_id: dialogueStore.talk.receiver_id,
sequence: -1,
talk_type: dialogueStore.talk.talk_type,
user_id: userStore.uid,
uploadCurrent: 0,
uploadStatus: 1, // 1 上传中 2 上传成功 3 上传失败
}
virtualList.value.unshift(newItem)
2024-12-06 08:55:15 +00:00
uploadImg(form, (e, file) => onProgressFn(e, file, randomId)).then(({ status, data, msg }) => {
if (status == 0) {
2024-12-13 05:09:38 +00:00
console.log(data);
2024-12-06 08:55:15 +00:00
resolve({
2024-12-13 05:09:38 +00:00
type: 'video',
2024-12-06 08:55:15 +00:00
url: data.ori_url,
2024-12-13 05:09:38 +00:00
cover: data.cover_url,
duration: parseInt(resp.duration),
size: file.size
2024-12-06 08:55:15 +00:00
})
} else {
2024-12-13 05:09:38 +00:00
// resolve('')
// message.error(msg)
2024-12-06 08:55:15 +00:00
}
})
}
})
}
2024-12-13 05:09:38 +00:00
const base64ToFile = (base64) => {
// base64转file
const [header, base64String] = base64.split(";base64,");
const imageType = header.split(":")[1];
const byteCharacters = atob(base64String);
const byteArray = new Uint8Array(
Array.from(byteCharacters, (char) => char.charCodeAt(0))
);
return new File(
[new Blob([byteArray], { type: imageType })],
"example.png",
{ type: imageType }
);
}
2024-12-06 08:55:15 +00:00
2024-12-13 05:09:38 +00:00
const choosePhoto = () => {
window.plus?.gallery.pick((res) => {
console.log(res);
res.files.forEach(async (filePath) => {
const suffix = filePath.split('.').pop()?.toLowerCase() || ''
if (['jpg', 'png'].includes(suffix)) {
console.log("进入图片")
window.plus?.io?.resolveLocalFileSystemURL(filePath, async (entry) => {
entry.file((file) => {
const fileReader = new plus.io.FileReader();
fileReader.readAsDataURL(file);
fileReader.onloadend = async (e) => {
const base64Url = e.target.result;
const fileObj = base64ToFile(base64Url);
let data = await onUploadImageVideo(fileObj, 'image')
emit('selectImg', data)
};
})
},
(err) => {
console.log(err);
}
)
}
if (['mp4', 'flv'].includes(suffix)) {
console.log(filePath,"进入视频")
window.plus?.io?.resolveLocalFileSystemURL(filePath, async (entry) => {
entry.file((file) => {
console.log(file,'file');
const fileReader = new plus.io.FileReader();
fileReader.readAsDataURL(file);
fileReader.onloadend = async (e) => {
const base64Url = e.target.result;
const fileObj = base64ToFile(base64Url);
let data = await onUploadImageVideo(fileObj, 'video')
emit('selectImg', data)
};
})
},
(err) => {
console.log(err);
}
)
}
})
}, (err) => {
console.log(err);
},
{
filter: 'none',
maximum: 9,
multiple: true,
2024-12-06 08:55:15 +00:00
}
2024-12-13 05:09:38 +00:00
)
2024-12-06 08:55:15 +00:00
}
const takePhoto = () => {
}
const chooseFile = () => {
2024-12-13 05:09:38 +00:00
window.plus?.io.requestFileSystem(
3,
(res) => {
console.log(res);
}, (err) => {
console.log(err);
},
)
2024-12-06 08:55:15 +00:00
}
</script>
<style lang="scss" scoped>
.emojiRoot {
width: 100%;
height: 232rpx;
padding: 20rpx 130rpx 0 130rpx;
display: flex;
justify-content: space-between;
align-items: flex-start;
}
</style>