前景:
1、框架:taro、taroUI、react;
2、图片能点击放大
3、视频能全屏播放
4、能单独删除
一、upload.js
import { Image, View, Video } from '@tarojs/components';
import React, { useEffect, useState } from 'react';
import Taro from '@tarojs/taro';
import { deleteUrl, get, post } from '../../utils/request';
import Api from '../../utils/api';
import noImg from '../../static/img/noImg.png';
import upload from '../../static/img/uploadImgVideo.png';
import './uploadImgVideo.less';
// 目前只做了单附件上传,后续再添加多附件上传
export default function UploadFile({fileId }) {
// const [isHidden, setIsHidden] = useState(true);
const [fileCode, setFileCode] = useState('');
// const [sourceTypeVal] = useState(['camera']);
// const [countVal] = useState(1);
let [annexFiles, setAnnexFiles] = useState([]); // img
let [annexFilesVideo, setAnnexFilesVideo] = useState([]); // img
const [imgUrl, setImgUrl] = useState('');
useEffect(() => {
getFileCode();
}, [fileId]);
const getFileCode = () => {
get(Api.file.getFileCode).then((r) => {
if (r) {
// setImg(upload);
// setIsHidden(true);
setFileCode(r);
Taro.setStorageSync('fileCode', r);
}
});
}
// 根据fileId下载图片
const fileView = (fileId) => {
if (fileId) {
post(Api.file.download,{fileId}).then((r) => {
if (r.data) {
// setImg(`data:image/png;base64,${r.data}`);
setIsHidden(false);
}
});
}
}
const handelDel = (fileId, type, index) => {
deleteUrl(Api.file.deleteByFileId, fileId).then((r) => {
if (r.code === 200 && r.msg === '操作成功!') {
if (type === 'video') {
annexFilesVideo.splice(index, 1);
setAnnexFilesVideo(JSON.parse(JSON.stringify(annexFilesVideo)));
}
if (type === 'image') {
annexFiles.splice(index, 1);
setAnnexFiles(JSON.parse(JSON.stringify(annexFiles)));
}
}
});
};
const addAnnex = () => {
// let that = this;
wx.chooseMedia({
count: 1,
mediaType: ['image','video'],
sourceType: ['camera'],
sizeType: ['original', 'compressed'],
maxDuration: 20,
camera: 'back',
success(res) {
if (res && res.tempFiles && res.tempFiles.length > 0) {
let image = (res.type === "video") ? res.tempFiles[0].thumbTempFilePath : res.tempFiles[0].tempFilePath;
const tempFilePathVideo = res.tempFiles[0].tempFilePath;
if (res.type === "video") {
const strs = tempFilePathVideo.split("."); //字符分割
Taro.setStorageSync('fileCode', fileCode);
post(Api.file.uploadVideo, {
fileData: tempFilePathVideo,
fileCode: fileCode,
fileSuffixName: strs[1],
}).then((r) => {
if (r.code === 200 && r.msg === "上传成功!") {
annexFilesVideo.push({type: res.type, path: res.tempFiles[0].tempFilePath, iconPath: image, id: r.data});
setAnnexFilesVideo(JSON.parse(JSON.stringify(annexFilesVideo)));
}
});
} else {
const strs = res.tempFiles[0].tempFilePath.split("."); //字符分割
const base64 = Taro.getFileSystemManager().readFileSync(res.tempFiles[0].tempFilePath, 'base64');
post(Api.file.upload, {
// clientId: 'LS-WEIXIN-WEBAPP',
fileData: base64,
// fileName: 'tmpImg.jpg',
fileCode: fileCode,
fileSuffixName: strs[1],
}).then((r) => {
Taro.setStorageSync('fileCode', fileCode);
if (r.code === 200 && r.msg === "上传成功!") {
// fileView(r.data);
annexFiles.push({ type: res.type, path: res.tempFiles[0].tempFilePath, iconPath: image, id: r.data});
setAnnexFiles(JSON.parse(JSON.stringify(annexFiles)));
// files1[files1.length - 1].id = r.data
}
});
}
setImgUrl(image);
}
},
fail() {
Taro.showToast({
title: '附件添加失败!',
icon: 'none',
duration: 3000
})
}
});
}
return (
<View style={{ display: 'block' }}>
{/* {isHidden || <View className="at-icon at-icon-close-circle upload-close" onClick={handelDel} />} */}
<View className="imageCont">
<View>
{(annexFiles.length)
?
<View>
{/* <View className="at-row resultFont">
<View className="at-col at-col-11">上传附件1</View>
</View> */}
<View className="at-row at-relative at-row--wrap resultFont">
{annexFiles.map((item, index) => {
return (
<View className="at-col-class">
<View className="at-icon at-icon-close-circle upload-close" onClick={()=>handelDel(item.id, item.type, index)} />
<Image className="at-col-img" mode='aspectFit' src={item.iconPath}
onClick={() => {
Taro.previewImage({
current: imgUrl, // 当前显示图片的http链接
urls: [imgUrl],
});
}}
></Image>
</View>
)
}
)}
</View>
</View>
: ''
}
{(annexFilesVideo.length)
?
<View className="at-row at-relative at-row--wrap resultFont">
{annexFilesVideo.map((item, index) => {
return (
<View className="at-col-class">
<View className="at-icon at-icon-close-circle upload-close" onClick={() => handelDel(item.id, item.type, index)} />
<Video
className="videoStyle"
objectFit="cover"
src={item.path}
controls={true}
autoplay={true}
initialTime={0}
loop={false}
muted={false}
/>
</View>
)
}
)}
</View>
: ''
}
<View className="at-col-class {{addShow?'show':'hide'}}" onClick={addAnnex}>
<Image className="at-col-add-img" src={upload}></Image>
</View>
</View>
</View>
</View>
);
}
export function GetFile({ fileId, fileSuffixName }) {
let [img, setImg] = useState(noImg);
useEffect(() => {
if (fileId && fileSuffixName) {
if (fileSuffixName === 'mp4') {
post(Api.file.downloadVideo,{fileId}).then((r) => {
if (r.data) {
img = r.data;
setImg(JSON.parse(JSON.stringify(img)));
// setIsHidden(false);
}
});
}
if (fileSuffixName === 'jpg') {
post(Api.file.download,{fileId}).then((r) => {
if (r.data) {
setImg(`data:image/png;base64,${r.data}`);
// setIsHidden(false);
}
});
}
}
}, [fileId]);
return (
<View>
{fileSuffixName === 'mp4'
?
<Video
id="videoViewId"
className="upload-Image"
objectFit="cover"
src={img}
controls={true}
autoplay={true}
initialTime={0}
loop={false}
muted={false}
/>
:
<Image
src={img}
className="upload-Image"
onClick={() => {
Taro.previewImage({
current: img, // 当前显示图片的http链接
urls: [img],
});
}} />
}
</View>
);
}
二、uploadImgVideo.less
.at-row {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
width: 100%; }
.at-row__direction--row {
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row; }
.at-row__direction--column {
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column; }
.at-row__direction--row-reverse {
-webkit-box-orient: horizontal;
-webkit-box-direction: reverse;
-webkit-flex-direction: row-reverse;
-ms-flex-direction: row-reverse;
flex-direction: row-reverse; }
.at-row__direction--column-reverse {
-webkit-box-orient: vertical;
-webkit-box-direction: reverse;
-webkit-flex-direction: column-reverse;
-ms-flex-direction: column-reverse;
flex-direction: column-reverse; }
.at-row__align--start {
-webkit-align-items: flex-start;
-ms-flex-align: start;
align-items: flex-start;
-webkit-box-align: start; }
.at-row__align--end {
-webkit-align-items: flex-end;
-ms-flex-align: end;
align-items: flex-end;
-webkit-box-align: end; }
.at-row__align--center {
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-align: center; }
.at-row__align--stretch {
-webkit-align-items: stretch;
-ms-flex-align: stretch;
align-items: stretch;
-webkit-box-align: stretch; }
.at-row__align--baseline {
-webkit-align-items: baseline;
-ms-flex-align: baseline;
align-items: baseline;
-webkit-box-align: baseline; }
.at-row__justify--start {
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start;
-webkit-box-pack: start; }
.at-row__justify--end {
-webkit-justify-content: flex-end;
-ms-flex-pack: end;
justify-content: flex-end;
-webkit-box-pack: end; }
.at-row__justify--center {
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-box-pack: center; }
.at-row__justify--between {
-webkit-justify-content: space-between;
-ms-flex-pack: justify;
justify-content: space-between;
-webkit-box-pack: justify; }
.at-row__justify--around {
-webkit-justify-content: space-around;
-ms-flex-pack: distribute;
justify-content: space-around;
-webkit-box-pack: space-around; }
.at-row__align-content--start {
-webkit-align-content: flex-start;
-ms-flex-line-pack: start;
align-content: flex-start; }
.at-row__align-content--end {
-webkit-align-content: flex-end;
-ms-flex-line-pack: end;
align-content: flex-end; }
.at-row__align-content--center {
-webkit-align-content: center;
-ms-flex-line-pack: center;
align-content: center; }
.at-row__align-content--between {
-webkit-align-content: space-between;
-ms-flex-line-pack: justify;
align-content: space-between; }
.at-row__align-content--around {
-webkit-align-content: space-around;
-ms-flex-line-pack: distribute;
align-content: space-around; }
.at-row__align-content--stretch {
-webkit-align-content: stretch;
-ms-flex-line-pack: stretch;
align-content: stretch; }
.at-row--no-wrap {
-webkit-flex-wrap: nowrap;
-ms-flex-wrap: nowrap;
flex-wrap: nowrap; }
.at-row--wrap {
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap; }
.at-row--wrap-reverse {
-webkit-flex-wrap: wrap-reverse;
-ms-flex-wrap: wrap-reverse;
flex-wrap: wrap-reverse; }
.at-col {
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
-webkit-box-flex: 1;
width: 100%;
display: block;
white-space: nowrap;
-webkit-box-sizing: border-box;
box-sizing: border-box; }
.at-col-1 {
-webkit-flex: 0 0 8.33333%;
-ms-flex: 0 0 8.33333%;
flex: 0 0 8.33333%;
-webkit-box-flex: 0;
max-width: 8.33333%; }
.at-col__offset-1 {
margin-left: 8.33333%; }
.at-col-2 {
-webkit-flex: 0 0 16.66667%;
-ms-flex: 0 0 16.66667%;
flex: 0 0 16.66667%;
-webkit-box-flex: 0;
max-width: 16.66667%; }
.at-col__offset-2 {
margin-left: 16.66667%; }
.at-col-3 {
-webkit-flex: 0 0 25%;
-ms-flex: 0 0 25%;
flex: 0 0 25%;
-webkit-box-flex: 0;
max-width: 25%; }
.at-col__offset-3 {
margin-left: 25%; }
.at-col-4 {
-webkit-flex: 0 0 33.33333%;
-ms-flex: 0 0 33.33333%;
flex: 0 0 33.33333%;
-webkit-box-flex: 0;
max-width: 33.33333%; }
.at-col__offset-4 {
margin-left: 33.33333%; }
.at-col-5 {
-webkit-flex: 0 0 41.66667%;
-ms-flex: 0 0 41.66667%;
flex: 0 0 41.66667%;
-webkit-box-flex: 0;
max-width: 41.66667%; }
.at-col__offset-5 {
margin-left: 41.66667%; }
.at-col-6 {
-webkit-flex: 0 0 50%;
-ms-flex: 0 0 50%;
flex: 0 0 50%;
-webkit-box-flex: 0;
max-width: 50%; }
.at-col__offset-6 {
margin-left: 50%; }
.at-col-7 {
-webkit-flex: 0 0 58.33333%;
-ms-flex: 0 0 58.33333%;
flex: 0 0 58.33333%;
-webkit-box-flex: 0;
max-width: 58.33333%; }
.at-col__offset-7 {
margin-left: 58.33333%; }
.at-col-8 {
-webkit-flex: 0 0 66.66667%;
-ms-flex: 0 0 66.66667%;
flex: 0 0 66.66667%;
-webkit-box-flex: 0;
max-width: 66.66667%; }
.at-col__offset-8 {
margin-left: 66.66667%; }
.at-col-9 {
-webkit-flex: 0 0 75%;
-ms-flex: 0 0 75%;
flex: 0 0 75%;
-webkit-box-flex: 0;
max-width: 75%; }
.at-col__offset-9 {
margin-left: 75%; }
.at-col-10 {
-webkit-flex: 0 0 83.33333%;
-ms-flex: 0 0 83.33333%;
flex: 0 0 83.33333%;
-webkit-box-flex: 0;
max-width: 83.33333%; }
.at-col__offset-10 {
margin-left: 83.33333%; }
.at-col-11 {
-webkit-flex: 0 0 91.66667%;
-ms-flex: 0 0 91.66667%;
flex: 0 0 91.66667%;
-webkit-box-flex: 0;
max-width: 91.66667%; }
.at-col__offset-11 {
margin-left: 91.66667%; }
.at-col-12 {
-webkit-flex: 0 0 100%;
-ms-flex: 0 0 100%;
flex: 0 0 100%;
-webkit-box-flex: 0;
max-width: 100%; }
.at-col__offset-12 {
margin-left: 100%; }
.at-col__align--top {
-webkit-align-self: flex-start;
-ms-flex-item-align: start;
align-self: flex-start; }
.at-col__align--bottom {
-webkit-align-self: flex-end;
-ms-flex-item-align: end;
align-self: flex-end; }
.at-col__align--center {
-webkit-align-self: center;
-ms-flex-item-align: center;
align-self: center; }
.at-col--auto {
max-width: initial;
word-break: keep-all; }
.at-col--wrap {
white-space: normal;
word-wrap: break-word; }
.annex {
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
visibility: hidden;
-webkit-transition: visibility 200ms ease-in;
-o-transition: visibility 200ms ease-in;
transition: visibility 200ms ease-in;
z-index: 1000;
}
.annex--active {
visibility: visible;
}
.annex--active .annex__overlay,
.annex--active .annex__container {
opacity: 1;
}
.annex__overlay {
top: 0;
left: 0;
width: 100%;
height: 100%;
position: absolute;
background-color: rgba(0, 0, 0, 0.3);
}
.annex__container {
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
width: 600rpx;
max-height: calc(100vh - 300rpx);
overflow: hidden;
border-radius: 12rpx;
}
.annex__overlay, .annex__container {
opacity: 0;
-webkit-transition: opacity 200ms ease-in;
-o-transition: opacity 200ms ease-in;
transition: opacity 200ms ease-in;
}
.at-relative {
position: relative;
}
.at-col-class {
width: 222rpx !important;
height: 222rpx !important;
margin: 5rpx;
text-align: center;
border: 2rpx #d6e4ef solid;
position: relative;
display: block;
white-space: nowrap;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.at-col-img {
width: 218rpx !important;
height: 218rpx !important;
}
.at-col-close {
width: 36rpx;
height: 36rpx;
position: absolute;
top: 2rpx;
right: 2rpx;
border-radius: 100%;
background-color: #ffffff;
z-index: 99;
}
.at-col-add-img {
width:222rpx;
height:222rpx;
// margin: 69rpx 85rpx auto 85rpx;
}
.at-col-add-text {
margin-top: 30rpx;
color: #999999;
}
.resultFont {
font-size:32rpx;
margin-top:30rpx;
}
.count_color {
color: #CCCCCC;
}
// .hide {
// display: none !important;
// }
.show {
display: block;
}
.w100 {
width: 100%;
}
.videoStyle{
height: 220rpx;
width: 220rpx;
}
.upload-close {
font-size: 38rpx;
z-index: 999;
position: absolute;
top: 20rpx;
right: 40rpx;
color: #ccc;
margin: -20rpx -43rpx;
}
三、上传时直接引用
import UploadFile from '../../components/upload/upload';
<View className="uploadView">
<View>上传附件:</View>
<View>
<UploadFile fileCode={fileCode} />
</View>
</View>
四、上传效果
五、直接查看视频/图片
flieIds:后端传的视频\图片的ids
import { GetFile } from '../../components/upload/upload';
{
(flieIds.length) ?
<View className="uploadView">
<View>附件:</View>
<View>
{flieIds.map((item, index) => {
return (
<GetFile fileId = {item.fileId} fileSuffixName = {item.fileSuffixName}/>
)
})}
</View>
</View> : ''
}
六、图片(可直接点击下载)
1、import upload from '../../static/img/uploadImgVideo.png
2、import noImg from '../../static/img/noImg.png';