434 lines
12 KiB
Vue
434 lines
12 KiB
Vue
<template>
|
|
<div class="emojiRoot">
|
|
<div
|
|
@click="() => photoActionsSelect(0)"
|
|
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="() => photoActionsSelect(1)"
|
|
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="videoImg"></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,
|
|
useUploadsStore,
|
|
} from '@/store'
|
|
import { useSessionMenu } from '@/hooks'
|
|
import photoAlbum from '@/static/image/chatList/photoAlbum.png'
|
|
import photoGraph from '@/static/image/chatList/photoGraph.png'
|
|
import videoImg from '@/static/image/chatList/video@2x.png'
|
|
import folder from '@/static/image/chatList/folder.png'
|
|
import { uploadImg } from '@/api/chat'
|
|
import { uniqueId } from '@/utils'
|
|
|
|
const props = defineProps({
|
|
sendUserInfo: {
|
|
type: Object,
|
|
default: {},
|
|
required: true,
|
|
},
|
|
talkParams: {
|
|
type: Object,
|
|
default: {},
|
|
required: true,
|
|
},
|
|
})
|
|
|
|
const state = reactive({
|
|
base64Url: ''
|
|
})
|
|
|
|
const uploadsStore = useUploadsStore()
|
|
const {
|
|
addDialogueRecord,
|
|
virtualList,
|
|
updateUploadProgress,
|
|
} = useDialogueListStore()
|
|
const dialogueStore = useDialogueStore()
|
|
const userStore = useUserStore()
|
|
|
|
const emit = defineEmits(['selectImg'])
|
|
|
|
const onProgressFn = (progress, id) => {
|
|
console.log((progress.loaded / progress.total) * 100, 'progress')
|
|
|
|
updateUploadProgress(id, (progress.loaded / progress.total) * 100)
|
|
}
|
|
|
|
const photoActionsSelect = (index) => {
|
|
if (index === 0) {
|
|
uni.chooseImage({
|
|
sourceType: ['album'],
|
|
count: 9,
|
|
success: async (res) => {
|
|
console.log(res, 'res')
|
|
res.tempFiles.forEach(async (file) => {
|
|
let data = await onUploadImageVideo(file, 'image')
|
|
emit('selectImg', data, data.file_num)
|
|
})
|
|
},
|
|
})
|
|
} else {
|
|
uni.chooseVideo({
|
|
sourceType: ['album'],
|
|
compressed: true,
|
|
maxDuration: 60,
|
|
success: async (res) => {
|
|
console.log(res, 'res')
|
|
let data = await onUploadImageVideo(
|
|
res.tempFile,
|
|
'video',
|
|
res.tempFilePath,
|
|
)
|
|
emit('selectImg', data, data.file_num)
|
|
},
|
|
})
|
|
}
|
|
}
|
|
|
|
const onUploadImageVideo = async (file, type = 'image', fileUrl) => {
|
|
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 = {
|
|
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,
|
|
file_num: 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,
|
|
uploadCurrent: 0,
|
|
uploadStatus: 1, // 1 上传中 2 上传成功 3 上传失败
|
|
}
|
|
|
|
virtualList.value.unshift(newItem)
|
|
uploadImg(form, (e) => onProgressFn(e, randomId)).then(
|
|
({ status, data, msg }) => {
|
|
if (status == 0) {
|
|
resolve({
|
|
type: 'image',
|
|
url: data.ori_url,
|
|
size: file.size,
|
|
width: image.width,
|
|
height: image.height,
|
|
file_num: randomId,
|
|
})
|
|
} else {
|
|
resolve('')
|
|
message.error(msg)
|
|
}
|
|
},
|
|
)
|
|
}
|
|
} else {
|
|
uni.getVideoInfo({
|
|
src: fileUrl,
|
|
success: (resp) => {
|
|
console.log(resp)
|
|
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: fileUrl,
|
|
width: resp.width,
|
|
},
|
|
float: 'right',
|
|
isCheck: false,
|
|
is_mark: 0,
|
|
is_read: 0,
|
|
is_revoke: 0,
|
|
msg_id: randomId,
|
|
file_num: 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)
|
|
uploadImg(form, (e) => onProgressFn(e, randomId)).then(
|
|
({ status, data, msg }) => {
|
|
if (status == 0) {
|
|
console.log(data)
|
|
resolve({
|
|
type: 'video',
|
|
url: data.ori_url,
|
|
cover: data.cover_url,
|
|
duration: parseInt(resp.duration),
|
|
size: file.size,
|
|
file_num: randomId,
|
|
})
|
|
} else {
|
|
// resolve('')
|
|
// message.error(msg)
|
|
}
|
|
},
|
|
)
|
|
},
|
|
})
|
|
const form = new FormData()
|
|
}
|
|
})
|
|
}
|
|
|
|
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,
|
|
})
|
|
}
|
|
|
|
const choosePhoto = (filter = 'none', maximum = 9, multiple = true) => {
|
|
window.plus?.gallery.pick(
|
|
(res) => {
|
|
console.log(res)
|
|
res.files.reverse()
|
|
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, '进入视频')
|
|
// const localUrl = plus.io.convertLocalFileSystemURL(filePath)
|
|
// console.log(localUrl);
|
|
|
|
plus.io.getVideoInfo({
|
|
filePath: filePath,
|
|
success: (event) => {
|
|
console.log(event)
|
|
},
|
|
fail: (err) => {
|
|
console.log(err)
|
|
},
|
|
})
|
|
// window.plus?.io?.resolveLocalFileSystemURL(localUrl, 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: filter,
|
|
maximum: maximum,
|
|
multiple: multiple,
|
|
},
|
|
)
|
|
}
|
|
|
|
const takePhoto = () => {
|
|
if (typeof plus !== 'undefined') {
|
|
getCamera()
|
|
} else {
|
|
document.addEventListener('plusready', () => {
|
|
getCamera()
|
|
})
|
|
}
|
|
}
|
|
|
|
const getCamera = () => {
|
|
const cmr = plus.camera.getCamera()
|
|
cmr.captureImage(
|
|
(p) => {
|
|
plus.io.resolveLocalFileSystemURL(
|
|
p,
|
|
(entry) => {
|
|
compressAndShowImage(entry.toLocalURL(), entry.name)
|
|
},
|
|
(err) => {
|
|
console.log(err)
|
|
},
|
|
)
|
|
},
|
|
() => {},
|
|
{ index: '2' },
|
|
)
|
|
}
|
|
|
|
const compressAndShowImage = (url, filename) => {
|
|
const dst = `_doc/upload/${filename}`
|
|
plus.zip.compressImage(
|
|
{ src: url, dst, quality: 10, overwrite: true },
|
|
(zip) => displayImage(zip.target),
|
|
(err) => {
|
|
console.log(err)
|
|
},
|
|
)
|
|
}
|
|
|
|
const displayImage = (url) => {
|
|
plus.io.resolveLocalFileSystemURL(url, (entry) => {
|
|
entry.file((file) => {
|
|
const fileReader = new plus.io.FileReader()
|
|
fileReader.readAsDataURL(file)
|
|
fileReader.onloadend = async (e) => {
|
|
state.base64Url = e.target.result
|
|
const imageFile = base64ToFile(state.base64Url)
|
|
let data = await onUploadImageVideo(imageFile, 'image')
|
|
emit('selectImg', data, data.file_num)
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
const chooseFile = () => {
|
|
uni.chooseFile({
|
|
count: 1,
|
|
extension: [''],
|
|
success: (res) => {
|
|
let randomId = uniqueId()
|
|
let newItem = {
|
|
avatar: userStore.avatar,
|
|
created_at: dayjs().format('YYYY-MM-DD HH:mm:ss'),
|
|
extra: {
|
|
drive: 3,
|
|
name: res.tempFiles[0].name,
|
|
size: res.tempFiles[0].size,
|
|
path: res.tempFilePaths[0],
|
|
},
|
|
float: 'right',
|
|
isCheck: false,
|
|
is_mark: 0,
|
|
is_read: 0,
|
|
is_revoke: 0,
|
|
msg_id: randomId,
|
|
file_num: randomId,
|
|
msg_type: 6,
|
|
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)
|
|
uploadsStore.initUploadFile(res.tempFiles[0], props.talkParams, randomId)
|
|
},
|
|
})
|
|
}
|
|
</script>
|
|
<style lang="scss" scoped>
|
|
.emojiRoot {
|
|
width: 100%;
|
|
height: 232rpx;
|
|
padding: 20rpx 62rpx 0 62rpx;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: flex-start;
|
|
}
|
|
</style>
|