增加新 选择视频和图片的插件
This commit is contained in:
221
src/components/chooseMedia.vue
Normal file
221
src/components/chooseMedia.vue
Normal file
@@ -0,0 +1,221 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user