264 lines
5.6 KiB
Plaintext
264 lines
5.6 KiB
Plaintext
|
|
<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>
|