mrr.sj.front/components/upload/media-upload.nvue

264 lines
5.6 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="upload-section">
<!-- 上传类型选择 -->
<view class="upload-header">
<text class="section-title">上传照片/视频</text>
<text class="upload-tip">(最多可上传9张图片或1个视频)</text>
</view>
<!-- 媒体列表 -->
<view class="media-list">
<view
v-for="(item, index) in mediaList"
:key="index"
class="media-item"
>
<!-- 图片预览 -->
<image
v-if="item.type === 'image'"
:src="item.url"
class="media-preview"
mode="aspectFill"
></image>
<!-- 视频预览 -->
<video
v-if="item.type === 'video'"
:src="item.url"
class="media-preview"
:poster="item.poster"
></video>
<!-- 删除按钮 -->
<view class="delete-btn" @click="deleteMedia(index)">
<text class="delete-icon">×</text>
</view>
</view>
<!-- 上传按钮 -->
<view
v-if="showUploadBtn"
class="upload-btn"
@click="showActionSheet"
>
<text class="plus-icon">+</text>
<text class="upload-text">上传照片/视频</text>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'media-upload',
data() {
return {
mediaList: [],
maxCount: 9, // 最大图片数量
maxVideo: 1, // 最大视频数量
}
},
computed: {
showUploadBtn() {
// 如果有视频,不显示上传按钮
if (this.mediaList.some(item => item.type === 'video')) {
return false
}
// 如果图片数量达到最大值,不显示上传按钮
if (this.mediaList.length >= this.maxCount) {
return false
}
return true
}
},
methods: {
showActionSheet() {
uni.showActionSheet({
itemList: ['拍摄', '从相册选择'],
success: (res) => {
if (res.tapIndex === 0) {
this.takePhoto()
} else {
this.chooseMedia()
}
}
})
},
// 拍摄照片或视频
takePhoto() {
uni.showActionSheet({
itemList: ['拍照', '录视频'],
success: (res) => {
if (res.tapIndex === 0) {
// 拍照
uni.chooseImage({
count: 1,
sourceType: ['camera'],
success: (res) => {
this.handleImageSuccess(res)
}
})
} else {
// 录视频
uni.chooseVideo({
sourceType: ['camera'],
maxDuration: 60,
camera: 'back',
success: (res) => {
this.handleVideoSuccess(res)
}
})
}
}
})
},
// 从相册选择
chooseMedia() {
uni.showActionSheet({
itemList: ['选择图片', '选择视频'],
success: (res) => {
if (res.tapIndex === 0) {
// 选择图片
uni.chooseImage({
count: this.maxCount - this.mediaList.length,
sourceType: ['album'],
success: (res) => {
this.handleImageSuccess(res)
}
})
} else {
// 选择视频
uni.chooseVideo({
sourceType: ['album'],
maxDuration: 60,
success: (res) => {
this.handleVideoSuccess(res)
}
})
}
}
})
},
// 处理图片选择结果
handleImageSuccess(res) {
const newImages = res.tempFilePaths.map(path => ({
type: 'image',
url: path
}))
this.mediaList = [...this.mediaList, ...newImages]
this.$emit('change', this.mediaList)
},
// 处理视频选择结果
handleVideoSuccess(res) {
this.mediaList = [{
type: 'video',
url: res.tempFilePath,
poster: res.thumbTempFilePath
}]
this.$emit('change', this.mediaList)
},
// 删除媒体文件
deleteMedia(index) {
uni.showModal({
title: '提示',
content: '确定要删除这个文件吗?',
success: (res) => {
if (res.confirm) {
this.mediaList.splice(index, 1)
this.$emit('change', this.mediaList)
}
}
})
}
}
}
</script>
<style>
.upload-section {
padding: 30rpx;
background-color: #ffffff;
}
.upload-header {
flex-direction: row;
align-items: center;
margin-bottom: 20rpx;
}
.section-title {
font-size: 28rpx;
color: #333;
font-weight: bold;
}
.upload-tip {
font-size: 24rpx;
color: #999;
margin-left: 20rpx;
}
.media-list {
flex-direction: row;
flex-wrap: wrap;
}
.media-item {
width: 220rpx;
height: 220rpx;
margin-right: 20rpx;
margin-bottom: 20rpx;
position: relative;
}
.media-preview {
width: 220rpx;
height: 220rpx;
border-radius: 12rpx;
background-color: #f5f6fa;
}
.delete-btn {
position: absolute;
right: -16rpx;
top: -16rpx;
width: 40rpx;
height: 40rpx;
background-color: rgba(0, 0, 0, 0.5);
border-radius: 20rpx;
justify-content: center;
align-items: center;
}
.delete-icon {
color: #ffffff;
font-size: 32rpx;
line-height: 32rpx;
}
.upload-btn {
width: 220rpx;
height: 220rpx;
background-color: #f5f6fa;
border-radius: 12rpx;
justify-content: center;
align-items: center;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.plus-icon {
font-size: 48rpx;
color: #999;
margin-bottom: 10rpx;
}
.upload-text {
font-size: 24rpx;
color: #999;
}
</style>