Files
ys-app/src/components/chooseMedia.vue

221 lines
5.7 KiB
Vue
Raw Normal View History

<template>
<!-- 自定义底部弹窗选择器 -->
<view class="picker-model" v-if="showPicker">
<view class="picker-content">
<view class="picker-item" @click="takePhoto">
<text>拍照</text>
</view>
<view class="picker-item" @click="choosePhoto">
<text>选择照片</text>
</view>
<view class="picker-item" @click="takeVideo">
<text>拍摄视频</text>
</view>
<view class="picker-item" @click="chooseVideoFromAlbum">
<text>选择视频</text>
</view>
<view class="picker-item" @click="closePicker">
<text>取消</text>
</view>
</view>
</view>
</template>
<script setup>
import { ref, watch } from "vue";
import {compressImageUni} from '@/utils/common.js'
import { minioUpload } from '@/api/polling.js'
let showPicker = ref(false);
const openPicker = () => {
showPicker.value = true;
}
const closePicker = () => {
showPicker.value = false;
emit("closeMedia")
}
const takePhoto = () => {
captureMedia("image", "camera");
}
const choosePhoto = () => {
captureMedia("image", "album");
}
const takeVideo = () => {
captureMedia("video", "camera");
}
const chooseVideoFromAlbum = () => {
captureMedia("video", "album");
}
const captureMedia = async (type, source) => {
showPicker.value = false;
try {
if (type === "image") {
const res = await uni.chooseImage({
count: 1,
sourceType: [source],
});
processMedia(res.tempFilePaths, "image", source);
} else {
const res = await uni.chooseVideo({
sourceType: [source],
// sourceType: ['album', 'camera'], // 来源:相册和相机
maxDuration: 60, // 最大时长(秒)
camera: 'back', // 使用后置摄像头
compressed: true, // 压缩视频
});
processMedia([res.tempFilePath], "video", source);
}
} catch (error) {
emit("closeMedia")
}
}
// 调用父组件的方法
const emit = defineEmits(['getMediaArr','closeMedia']);
// 执行压缩并上传
const processMedia = async(files, type, source) => {
let returnArr = [];
let res = files.map(async file=>{
return new Promise(async(resolve, reject) => {
try {
const info = {
path: file,
type: type,
source: source,
timestamp: Date.now(),
}
// #ifdef APP-PLUS
// 进行压缩图片
if(type=="image"){
info.path = await compressImageUni(file);
}
// #endif
// 保存选择记录
let data = await saveSelectionRecord(info);
returnArr.push({
fileName:data.fileName,
fileType:type
})
resolve(returnArr)
} catch (error) {
reject(error)
}
});
})
await Promise.all(res);
// console.log("returnArr=>",returnArr)
showPicker.value = false;
emit('getMediaArr',returnArr);
// 根据来源做不同处理
// if (source === "camera") {
// handleCameraMedia(info);
// } else {
// handleAlbumMedia(info);
// }
}
// 保存到云
const saveSelectionRecord = (info) => {
return new Promise(async (resolve, reject) => {
try {
// 执行上传
let param = {
filePath: info.path,
name: 'file',
formData: {
directory:'polling'
},
}
let res = await minioUpload(param);
resolve(res.data);
} catch (error) {
resolve(error);
}
// 保存到本地存储
// const records = uni.getStorageSync("mediaRecords") || [];
// records.unshift(info);
// uni.setStorageSync("mediaRecords", records.slice(0, 10)); // 只保留最近10条
})
}
const handleCameraMedia = (info) => {
// 从相机拍摄的媒体文件处理
if (info.type === "image") {
// 相机拍摄的照片可能有地理位置信息
extractImageMetadata(info.path);
} else {
// 相机拍摄的视频
uni.showToast({
title: "已保存拍摄的视频",
icon: "success",
});
}
}
const handleAlbumMedia = (info) => {
// 从相册选择的媒体文件处理
console.log("从相册选择:", info);
}
const extractImageMetadata = (filePath) => {
// 获取图片元数据(部分平台支持)
uni.getImageInfo({
src: filePath,
success: (res) => {
console.log("图片元数据:", res);
},
});
}
// 暴露方法给父组件
defineExpose({
openPicker
});
</script>
<style lang="scss" scoped>
.picker-model{
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: rgba(0, 0, 0, 0.4);
z-index: 9999;
.picker-content{
width:100%;
position: absolute;
bottom:0;
left:0;
background-color: #fff;
border-radius: 10rpx 10rpx 0 0;
.picker-item{
border-bottom:1px solid #E7E7E7;
text-align: center;
height:90rpx;
line-height: 90rpx;
// #ifdef APP-PLUS
height:120rpx;
line-height: 120rpx;
// #endif
&:last-child{
border-bottom: none;
}
text{
text-align: center;
}
}
}
}
</style>