拍照拍视频
<template>
<view class="content-pages">
<NavbarFull title="拍照" :color="navBarColor" :bgcolor="navBarBgColor" :opacity="navBarOpacity" leftIcon="back"
@back="back" />
<div class="content-box">
<uni-forms
ref="form"
label-position="top"
:rules="rules"
:modelValue="params"
label-width="100%"
>
<uni-forms-item label="备注" name="supplementRemark">
<uni-easyinput
type="textarea"
v-model="params.supplementRemark"
placeholder="请输入"
/>
</uni-forms-item>
<uni-forms-item label="图片" name="images">
<h5Img
v-model="params.images"
:limit="9"
tips="支持扩展名:jpg、jpeg、gif、png,最多支持9张图片"
/>
</uni-forms-item>
<uni-forms-item label="视频" name="videos">
<h5Video
v-model="params.videos"
:limit="3"
tips="支持扩展名:mp4,最多支持3个视频"
/>
</uni-forms-item>
</uni-forms>
</div>
<view class="row-gap-6"></view>
<view class="submit-btn-box">
<button class="btn" type="default" @click="back">取消</button>
<button class="btn" type="primary" @click="submit">提交</button>
</view>
<view class="row-gap-30"></view>
</view>
</template>
<script>
import NavbarFull from "@/components/navbar/main.vue";
import h5Img from "@/components/upload/h5-img";
import h5Video from "@/components/upload/h5-video";
import {deleteFishPondSupplement,addFishPondSupplement } from "@/api/breed/pond";
import {
rules,
params
} from "./data";
import {
getInfo,
checkUpdate,
addEnterprise,
editEnterprise
} from "@/api/system/subject";
import {
breedDropDown
} from "@/api/system/breed";
export default {
components: {
NavbarFull,
h5Img,
h5Video,
},
data() {
return {
navBarOpacity: 0,
navBarBgColor: "rgba(255, 255, 255,0)",
navBarColor: "rgb(255, 255, 255)",
keyword: "",
rules: rules,
params: {
...params
},
detail: "",
breedList: [],
userInfo: {},
addSubjectId: '',
enterpriseName: '',
pondId:'',
};
},
onPageScroll({
scrollTop
}) {
const max = 60;
if (scrollTop < max) {
const num = scrollTop / max;
const c = 255 - parseInt((255 - 51) * num);
this.navBarColor = `rgb(${c}, ${c}, ${c})`;
this.navBarBgColor = `rgba(255, 255, 255,${num})`;
this.navBarOpacity = num.toFixed(3);
} else {
this.navBarColor = "rgb(51, 51, 51)";
this.navBarBgColor = "rgba(255, 255, 255,1)";
this.navBarOpacity = 1;
}
},
async onLoad(options) {
// console.log(options.data);
console.log('this.pondId-**-*-*-*-*-',options)
// const params = options.data ? JSON.parse(decodeURIComponent(options.data)) : {};
// console.log( JSON.parse(options.data));
this.pondId =options.id
},
methods: {
init() {
this.userInfo = uni.getStorageSync("userInfo");
if (uni.getStorageSync("addSubjectId")) {
this.addSubjectId = uni.getStorageSync("addSubjectId")
}
if (uni.getStorageSync("addSubjectName")) {
this.enterpriseName = uni.getStorageSync("addSubjectName")
}
if (this.userInfo.subjectId) {
this.getInfo(this.userInfo.subjectId);
}
this.$refs.base && this.$refs.base.init(data);
},
initDetail() {
const data = JSON.parse(this.detail);
this.$refs.base && this.$refs.base.init(data);
},
async getInfo(id) {
try {
const {
code,
data
} = await getInfo(id);
if (code === "200") {
this.detail = JSON.stringify(data);
this.breedList = [];
this.breedDropDown(data.projectId);
this.initDetail();
}
} catch (error) {}
},
async breedDropDown(projectId) {
try {
const {
code,
data
} = await breedDropDown({
projectId
});
if (code === "200" && Array.isArray(data)) {
data.forEach((item) => {
item.breedId = item.id;
});
this.breedList = data;
} else {
this.breedList = [];
}
} catch (error) {
this.breedList = [];
}
},
async submit() {
console.log(params, '提交中')
let obj = this.params;
let arr= [],arr1 = []
this.params.videos.map(item => arr.push(item.uuid))
this.params.images.map(item => arr1.push(item.id))
const data = {
pondId:this.pondId,
videos:arr,
images:arr1,
supplementRemark:obj.supplementRemark,
}
console.log(data);
const result = await addFishPondSupplement(data);
console.log(result, '已提交')
if (result.code === "200") {
uni.hideLoading();
this.back()
// uni.reLaunch({
// url: '/pages/center/index',
// success() {
// uni.showToast({
// title: result.message,
// mask: true
// });
// }
// })
// this.$refs.base.resetFieldForm();
} else {
console.log(result, '已提交')
uni.hideLoading();
uni.showToast({
title: result.message,
icon: "none",
});
}
},
back() {
uni.navigateBack();
},
go(path) {
uni.navigateTo({
url: path,
});
},
},
};
</script>
<style lang="scss">
@import "./style.scss";
</style>
h5-img.vue
<template>
<view class="video-upload-box" :data-tips="tips">
<view class="video-list">
<view
class="video-item-box"
v-for="(item, index) in list"
:key="item.key"
>
<view class="video-item">
<view class="icon-del-box" @click="deleteFile(item)">
<view class="icon-del"></view>
<view class="icon-del rotate"></view>
</view>
<image
@click="preview(item.url, index)"
:src="item.url"
class="video"
></image>
</view>
</view>
<view class="video-item-box" v-if="limit && list.length < limit">
<view class="video-item add-box" @click="selectImg">
<view class="is-add">
<view class="icon-add"></view>
<view class="icon-add rotate"></view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
const {
HOST,
HOST_FFC,
HOST_BQCB,
ENV,
HOST_PROXY,
HOST_FFC_PROXY,
HOST_BQCB_PROXY,
} = require("@/config");
const uploadFile = require("@/libs/oss");
const { uploadFileApi, saveUploadFile } = require("@/api/bqcb");
// import { getStsToken } from "@/components/minio/init.js";
export default {
model: {
prop: "value", // 默认是value
event: "value", // 默认是value
},
props: {
value: {
type: Array,
default() {
return [];
},
},
limit: {
type: Number,
default: 1,
},
tips: {
type: String,
default: "",
},
tokenType: {
type: String,
default: "",
},
name: {
type: String,
default: "paramskey",
},
},
data() {
return {
list: [],
};
},
watch: {
value: function (val) {
const list = val || [];
const KEY = Date.now().toString().slice(6);
list.forEach((item, index) => {
item.key = item.uuid || item.id || KEY + index;
item.url = item.url.split("?")[0];
});
this.list = list;
},
},
mounted() {
// getStsToken()
},
methods: {
getToken() {
switch (this.tokenType) {
case "ffc":
return uni.getStorageSync("modeltoken");
case "bqcb":
return uni.getStorageSync("bqcbtoken");
default:
return uni.getStorageSync("token");
}
},
getuploadUrl() {
let urls;
// resource/file/upload/getOssPolicy
switch (this.tokenType) {
case "ffc":
urls = `${HOST_FFC}/common/upload`;
break;
case "bqcb":
// urls = uploadFileApi;
urls = `${HOST_BQCB}/zuul/service-file/file/upload`;
break;
default:
urls`${HOST}/resource/file/upload/getOssSetting`;
}
return ENV === "H5"
? urls
.replace(HOST_BQCB, HOST_BQCB_PROXY)
.replace(HOST_FFC, HOST_FFC_PROXY)
.replace(HOST, HOST_PROXY)
: urls;
},
async ffcUpload(event) {
const token = this.getToken();
// const url = this.getuploadUrl();
const imgList = [];
uni.showLoading({
title: "上传中...",
mask: true,
});
try {
const [err, res] = await uni.uploadFile({
url: `${HOST}/resource/file/upload`,
filePath: event.path,
name: "file",
header: {
Authorization: token,
},
});
if (res && (res.statusCode === 200)) {
const result = JSON.parse(res.data);
if (result.code == 200) {
let res1 = JSON.parse(res.data);
res1.data.uuid = res1.data.id;
res1.data.paramskey = event.name;
imgList.push(res1.data);
const list = [...this.list, ...imgList];
this.$emit("value", list);
this.$emit("change", list);
this.$emit("upload", imgList);
} else {
wx.showToast({
icon: "none",
title: result.msg,
});
}
} else {
wx.showToast({
icon: "error",
title: "上传失败",
});
}
} catch (error) {
console.log(error)
}
uni.hideLoading();
this.$emit("upload", imgList);
},
async bqcbUpload(event) {
const token = this.getToken();
const url = this.getuploadUrl();
const imgList = [];
uni.showLoading({
title: "上传中...",
mask: true,
});
try {
const [, res] = await uni.uploadFile({
url: `${HOST}/resource/file/upload`,
filePath: event,
name: "file",
header: {
Authorization: token,
},
});
if (res.statusCode === 200) {
const result = JSON.parse(res.data);
const params = {};
params.name = result.data.content.url.split("/").slice(-1)[0];
params.url = result.data.content.url;
params.uuid = Date.now().toString().slice(6);
params.paramskey = this.name;
params.uid = params.uuid;
params.dataId = params.name;
imgList.push(params);
}
} catch (error) {
console.error(error);
}
uni.hideLoading();
const list = [...this.list, ...imgList];
this.$emit("value", list);
this.$emit("change", list);
this.$emit("upload", imgList);
},
async defaultUpload(event) {
const imgList = [];
uni.showLoading({
title: "上传中...",
mask: true,
});
try {
// const result = await uploadFile(getApp(),event);
const token = this.getToken();
uni.uploadFile({
url: `${HOST}/resource/file/upload`,
filePath: event.path, // 随便填,不为空即可
name: "file", // 随便填,不为空即可
// header: header, // 可以加access_token等
header: {
"content-type": "multipart/form-data",
Authorization: token,
},
data: JSON.stringify(event), // 接口参数,json格式,底层自动转为FormData的格式数据
complete: (res) => {
if (res.statusCode === 200) {
let res1 = JSON.parse(res.data);
res1.data.uuid = res1.data.id;
res1.data.paramskey = event.name;
imgList.push(res1.data);
const list = [...this.list, ...imgList];
this.$emit("value", list);
this.$emit("change", list);
this.$emit("upload", imgList);
}
},
});
} catch (error) {
console.error(error);
}
uni.hideLoading();
},
async upload(event) {
// switch (this.tokenType) {
// case "ffc":
// this.ffcUpload(event);
// break;
// case "bqcb":
// this.bqcbUpload(event);
// break;
// default:
// this.defaultUpload(event);
this.ffcUpload(event);
// }
},
deleteFile(event) {
const list = this.list.filter(
(item) => event.uuid !== item.uuid || (item.id && event.id !== item.id)
);
this.$emit("value", list);
this.$emit("delete", event.tempFile);
this.$emit("change", list);
},
preview(url, index) {
const list = this.list.map((item) => item.url);
uni.previewImage({
current: index,
urls: list,
});
},
saveFileSync(tempFilePath){
return new Promise((resolve, reject) => {
uni.saveFile({
tempFilePath,
success: function (file) {
resolve(file.savedFilePath)
},
fail: function (error) {
reject(error)
}
})
})
},
pathToBase64(path){
// 省略其他代码
if (typeof plus === 'object') {
plus.io.resolveLocalFileSystemURL(
getLocalFilePath(path),
function(entry) {
entry.file(
function(file) {
var fileReader = new plus.io.FileReader()
fileReader.onload = function(data) {
resolve(data.target.result)
}
fileReader.onerror = function(error) {
reject(error)
}
fileReader.readAsDataURL(file)
},
function(error) {
reject(error)
}
)
},
function(error) {
reject(error)
}
)
return
}
// 省略其他代码
},
selectImg() {
const that = this;
uni.chooseImage({
count: 1, //默认9
sizeType: ["compressed"], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['camera','album'],
success: async function(result) {
let ewm = result.tempFiles[0]
const path = await that.saveFileSync(ewm.path)
console.log(path, "path*********************---------------");
// let ewms =that.pathToBase64(path)
// console.log(ewms,'ewms******');
if (result.errMsg === "chooseImage:ok") {
result.tempFiles[0].path=path
// that.upload(path);
that.upload(result.tempFiles[0]);
} else {
uni.showToast({
title: "图片上传失败",
icon: "none",
});
}
},
fail(err) {
uni.showToast({
title: "取消上传",
icon: "none",
});
},
});
},
},
};
</script>
<style lang="scss">
.uni-file-picker {
&::after {
content: attr(data-tips);
font-size: 28rpx;
font-family: PingFang SC;
font-weight: 500;
color: #999999;
line-height: 48rpx;
padding-top: 20rpx;
}
::v-deep .file-picker__box .file-picker__box-content {
border: none !important;
&.is-add {
border: 1px dashed #c1c1c1 !important;
.is-add {
.icon-add {
width: 60rpx;
height: 4rpx;
background-color: #c1c1c1;
border-radius: 2px;
}
}
}
}
::v-deep .icon-del-box {
width: 32rpx;
height: 32rpx;
.icon-del {
width: 20rpx;
}
}
::v-deep .file-picker__progress {
display: none;
}
}
.video-upload-box {
&::after {
content: attr(data-tips);
font-size: 28rpx;
font-family: PingFang SC;
font-weight: 500;
color: #999999;
line-height: 48rpx;
padding-top: 20rpx;
}
.video-list {
display: flex;
box-sizing: border-box;
flex-wrap: wrap;
margin: -5px;
.video-item-box {
width: 33.3%;
padding-top: 33.33%;
height: 0;
position: relative;
}
.video-item {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: 5px;
border: none;
border-radius: 5px;
overflow: hidden;
&.add-box {
border: 1px dashed #c1c1c1 !important;
display: flex;
align-items: center;
justify-content: center;
.is-add {
display: flex;
align-items: center;
justify-content: center;
.icon-add {
width: 60rpx;
height: 4rpx;
background-color: #c1c1c1;
border-radius: 2px;
}
}
}
.video {
display: block;
width: 100%;
height: 100%;
}
}
}
.icon-del-box {
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 3px;
right: 3px;
width: 32rpx;
height: 32rpx;
border-radius: 50%;
background-color: rgba(0, 0, 0, 0.5);
z-index: 3;
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
.icon-del {
width: 20rpx;
height: 2px;
background-color: #fff;
border-radius: 2px;
}
}
.rotate {
transform: rotate(90deg);
position: absolute;
}
.player {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
.img {
display: block;
width: 26px;
height: 30px;
}
}
}
.upload-btn {
opacity: 0;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 10;
::v-deep .uni-file-picker__files,
::v-deep .uni-file-picker__files .files-button {
width: 100%;
height: 100%;
}
}
.preview-video {
width: 100vw;
height: 60vw;
.video {
width: 100%;
height: 100%;
}
}
.preview-close {
position: fixed;
box-sizing: border-box;
top: 0;
right: 0;
width: 44px;
height: 44px;
padding: 6px;
line-height: 32px;
font-size: 26px;
color: #fff;
text-align: center;
cursor: pointer;
z-index: 3;
}
</style>
h5-video.vue
<template>
<view class="video-upload-box" :data-tips="tips">
<view class="video-list">
<view class="video-item-box" v-for="item in list" :key="item.key">
<view class="video-item">
<view class="icon-del-box" @click="deleteFile(item)">
<view class="icon-del"></view>
<view class="icon-del rotate"></view>
</view>
<image
:src="item.url + '?x-oss-process=video/snapshot,t_0,f_jpg'"
class="video"
></image>
<view class="player">
<image
class="img"
src="/static/video/play.png"
@click="preview(item.url)"
></image>
</view>
</view>
</view>
<view class="video-item-box" v-if="limit && list.length < limit">
<view class="video-item add-box" @click="selectVideo">
<view class="is-add">
<view class="icon-add"></view>
<view class="icon-add rotate"></view>
</view>
</view>
</view>
</view>
<uni-popup
ref="Dialog"
type="dialog"
:is-mask-click="false"
mask-background-color="rgba(0,0,0,0.9)"
>
<view class="preview-video">
<video
class="video"
:src="videoPreview"
autoplay
page-gesture
show-mute-btn
enable-play-gesture
vslide-gesture
></video>
</view>
<view class="preview-close" @click="closePreview">
<uni-icons type="closeempty" size="26" color="white"></uni-icons>
</view>
</uni-popup>
</view>
</template>
<script>
const { HOST, HOST_FFC } = require("@/config");
const uploadFile = require("@/libs/oss");
const { uploadBlob } = require("@/utils/upload");
export default {
model: {
prop: "value", // 默认是value
event: "value", // 默认是value
},
props: {
value: {
type: Array,
default() {
return [];
},
},
limit: {
type: Number,
default: 1,
},
tips: {
type: String,
default: "",
},
tokenType: {
type: String,
default: "",
},
name: {
type: String,
default: "paramskey",
},
fileType: {
type: String,
default: "mp4",
},
},
data() {
return {
videoPreview: "",
list: [],
};
},
watch: {
value: function (val) {
const list = val || [];
const KEY = Date.now().toString().slice(6);
list.forEach((item, index) => {
item.key = item.uuid || item.id || KEY + index;
item.url = item.url.split("?")[0];
});
this.list = list;
},
},
methods: {
getToken() {
switch (this.tokenType) {
// case "ffc":
// return uni.getStorageSync("modeltoken");
default:
return uni.getStorageSync("token");
}
},
getuploadUrl() {
switch (this.tokenType) {
// case "ffc":
// return `${HOST_FFC}/common/upload`;
default:
return `${HOST}/resource/file/upload/getOssSetting`;
}
},
async ffcUpload(event) {
const token = this.getToken();
const url = this.getuploadUrl();
const imgList = [];
uni.showLoading({
title: "上传中...",
mask: true,
});
try {
const file = event;
const [, res] = await uni.uploadFile({
url: url,
filePath: file.url,
name: "file",
header: {
Authorization: token,
},
});
if (res.statusCode === 200) {
const result = JSON.parse(res.data);
result.uuid = file.uuid || Date.now().toString().slice(6);
result.key = file.uuid;
result.type = "video";
result.paramskey = this.name;
delete result.code;
delete result.msg;
imgList.push(result);
}
} catch (error) {
console.log(error);
}
// }
uni.hideLoading();
this.$emit("upload", imgList);
},
async defaultUpload(event) {
const imgList = [];
const token = this.getToken();
uni.showLoading({
title: "上传中...",
mask: true,
});
try {
const res= await uni.uploadFile({
url: `${HOST}/resource/file/upload`,
filePath: event.tempFilePath,
name: "file",
header: {
Authorization: token,
},
});
console.log(res,'resresres**---*-s');
if (res[1] && (res[1].statusCode == 200)) {
const result = JSON.parse(res[1].data);
console.log(result,'resresresres**---*-s');
if (result.code == 200) {
// const result = JSON.parse(res[1].data);
// result.uuid = file.uuid || Date.now().toString().slice(6);
console.log(result.data,'result.data');
let obj={
uuid:"",
key:"",
type:"",
url:"",
}
obj.uuid = result.data.id || Date.now().toString().slice(6);
obj.key = result.data.fileKey;
obj.type = "video";
obj.paramskey = result.data.originalName;
obj.url = result.data.url;
imgList.push(obj);
const list = [...this.list, ...imgList];
console.log(list,'listlistlist**---*-s');
this.$emit("value", list);
this.$emit("change", list);
this.$emit("upload", imgList);
}
}
} catch (error) {
console.log(error);
}
uni.hideLoading();
},
async upload(event) {
this.defaultUpload(event);
},
deleteFile(event) {
const list = this.list.filter(
(item) => event.uuid !== item.uuid || (item.id && event.id !== item.id)
);
this.$emit("value", list);
this.$emit("delete", event);
this.$emit("change", list);
},
saveFileSync(tempFilePath){
return new Promise((resolve, reject) => {
uni.saveFile({
tempFilePath,
success: function (file) {
resolve(file.savedFilePath)
},
fail: function (error) {
reject(error)
}
})
})
},
selectVideo() {
const that = this;
uni.chooseVideo({
async success(res) {
if(res.errMsg==='chooseVideo:ok'){
// that.upload(res.tempFilePath);
console.log(res,'res-------------------*****');
let ewm = res
const path = await that.saveFileSync(ewm.tempFilePath)
ewm.tempFilePath=path
// that.upload(path);
that.upload(ewm);
}
},
fail(){
uni.showToast({
title:"取消上传",
icon:'none'
})
}
})
},
preview(url) {
this.videoPreview = url;
this.$refs.Dialog.open("center");
},
closePreview() {
this.$refs.Dialog.close();
},
},
};
</script>
<style lang="scss">
.video-upload-box {
&::after {
content: attr(data-tips);
font-size: 28rpx;
font-family: PingFang SC;
font-weight: 500;
color: #999999;
line-height: 48rpx;
padding-top: 20rpx;
}
.video-list {
display: flex;
box-sizing: border-box;
flex-wrap: wrap;
margin: -5px;
.video-item-box {
width: 33.3%;
padding-top: 33.33%;
height: 0;
position: relative;
}
.video-item {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: 5px;
border: none;
border-radius: 5px;
overflow: hidden;
&.add-box {
border: 1px dashed #c1c1c1 !important;
display: flex;
align-items: center;
justify-content: center;
.is-add {
display: flex;
align-items: center;
justify-content: center;
.icon-add {
width: 60rpx;
height: 4rpx;
background-color: #c1c1c1;
border-radius: 2px;
}
}
}
.video {
display: block;
width: 100%;
height: 100%;
}
}
}
.icon-del-box {
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 3px;
right: 3px;
width: 32rpx;
height: 32rpx;
border-radius: 50%;
background-color: rgba(0, 0, 0, 0.5);
z-index: 3;
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
.icon-del {
width: 20rpx;
height: 2px;
background-color: #fff;
border-radius: 2px;
}
}
.rotate {
transform: rotate(90deg);
position: absolute;
}
.player {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
.img {
display: block;
width: 26px;
height: 30px;
}
}
}
.upload-btn {
opacity: 0;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 10;
::v-deep .uni-file-picker__files,
::v-deep .uni-file-picker__files .files-button {
width: 100%;
height: 100%;
}
}
.preview-video {
width: 100vw;
height: 60vw;
.video {
width: 100%;
height: 100%;
}
}
.preview-close {
position: fixed;
box-sizing: border-box;
top: 0;
right: 0;
width: 44px;
height: 44px;
padding: 6px;
line-height: 32px;
font-size: 26px;
color: #fff;
text-align: center;
cursor: pointer;
z-index: 3;
}
</style>