@@ -11,7 +11,17 @@ export function getModeList(sex) { | |||
method: 'get' | |||
}) | |||
} | |||
/** | |||
* @description 获取模板列表(新) | |||
* @param {number} sex | |||
* @returns data | |||
*/ | |||
export function getModeList1(sex) { | |||
return request({ | |||
url: `/api/personPatch/list?sex=${sex}&pageNum=1&pageSize=10`, | |||
method: 'get' | |||
}) | |||
} | |||
/** | |||
* @description:根据id获取模板详情 | |||
* @param {number} id | |||
@@ -0,0 +1,280 @@ | |||
<template> | |||
<div class="uploder"> | |||
<div class="change-photo-setter"> | |||
<van-uploader class="sett-item" :before-read="beforeRead"> | |||
<div style="height: 100%"><img :src="ImgUrl" alt="" /></div> | |||
<img src="https://img01.yzcdn.cn/vant/leaf.jpg" alt="" /> | |||
</van-uploader> | |||
</div> | |||
<div class="uploadava"> | |||
<van-popup | |||
duration="0" | |||
v-model="showCropper" | |||
position="top" | |||
:style="{ height: '100%' }" | |||
> | |||
<div class="cropper-container"> | |||
<van-loading | |||
v-show="loadingShow" | |||
size="50" | |||
color="#fff" | |||
vertical | |||
text-color="#fff" | |||
>上传中...</van-loading | |||
> | |||
<vueCropper | |||
ref="cropper" | |||
:img="option.img" | |||
:outputSize="option.outputSize" | |||
:outputType="option.outputType" | |||
:info="option.info" | |||
:full="option.full" | |||
:autoCropWidth="option.autoCropWidth" | |||
:autoCropHeight="option.autoCropHeight" | |||
:canMove="option.canMove" | |||
:canMoveBox="option.canMoveBox" | |||
:original="option.original" | |||
:autoCrop="option.autoCrop" | |||
:fixed="option.fixed" | |||
:fixedNumber="option.fixedNumber" | |||
:centerBox="option.centerBox" | |||
:infoTrue="option.infoTrue" | |||
:fixedBox="option.fixedBox" | |||
:high="option.high" | |||
:mode="option.mode" | |||
/> | |||
<van-nav-bar | |||
left-text="取消" | |||
right-text="确定" | |||
@click-left="onClickLeft" | |||
@click-right="onClickRight" | |||
/> | |||
</div> | |||
</van-popup> | |||
</div> | |||
</div> | |||
</template> | |||
<script> | |||
import { awsImgUpload } from '@/api/editModel' | |||
import { Toast } from 'vant' | |||
import { VueCropper } from 'vue-cropper' | |||
export default { | |||
name: 'uploadAva', | |||
components: { | |||
VueCropper | |||
}, | |||
props: { | |||
showAta: { | |||
default: false, | |||
type: Boolean | |||
}, | |||
avaUrl: { | |||
default: '', | |||
type: String | |||
} | |||
}, | |||
data() { | |||
return { | |||
ImgUrl: '', | |||
show: true, // 上传类型的弹窗 | |||
imageFileName: '', | |||
showCropper: false, // 裁剪的弹窗 | |||
option: { | |||
img: '', | |||
outputSize: 0.8, | |||
info: false, // 裁剪框的大小信息 | |||
outputType: 'jpeg', // 裁剪生成图片的格式 | |||
canScale: true, // 图片是否允许滚轮缩放 | |||
autoCrop: true, // 是否默认生成截图框 | |||
autoCropWidth: window.innerWidth - 100 + 'px', // 默认生成截图框宽度 | |||
autoCropHeight: window.innerWidth - 100 + 'px', // 默认生成截图框高度 | |||
high: true, // 是否按照设备的dpr 输出等比例图片 | |||
fixedBox: false, // 固定截图框大小 不允许改变 | |||
fixed: true, // 是否开启截图框宽高固定比例 | |||
fixedNumber: [1, 1], // 截图框的宽高比例 | |||
full: true, // 是否输出原图比例的截图 | |||
canMoveBox: true, // 截图框能否拖动 | |||
original: false, // 上传图片按照原始比例渲染 | |||
centerBox: true, // 截图框是否被限制在图片里面 | |||
infoTrue: false, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高 | |||
mode: '100% auto' // 图片默认渲染方式 | |||
}, | |||
loadingShow: false // 是否展示loading | |||
} | |||
}, | |||
methods: { | |||
beforeRead(file) { | |||
console.log(file) | |||
if (file.type !== 'image/jpeg' && file.type !== 'image/png') { | |||
this.$toast('请上传 jpg/png 格式图片') | |||
return false | |||
} | |||
let data = window.URL.createObjectURL(new Blob([file])) | |||
this.option.img = data //给裁剪图片的路径 | |||
this.showCropper = true | |||
return false | |||
}, | |||
// 点击裁剪的选择 | |||
onClickRight() { | |||
let that = this | |||
this.loadingShow = true | |||
this.$refs.cropper.getCropBlob(async (data) => { | |||
let formData = new FormData() | |||
formData.append('file', data) | |||
let file = formData.get('file') | |||
// 转为 base64 | |||
let reader = new FileReader() | |||
reader.onload = async () => { | |||
// base64结果 | |||
that.ImgUrl = this.result | |||
that.loading = false | |||
} | |||
reader.readAsDataURL(file) | |||
// await that.toBase64(file) | |||
console.log(that.ImgUrl, 'dasdasd') | |||
// 发请求 | |||
const AccessToken = localStorage.getItem('AccessToken') | |||
that | |||
.$axios({ | |||
method: 'post', | |||
url: `https://smapitest.malls.iformall.com/C/api/upload/awsImgUpload`, | |||
headers: { | |||
// 'Content-Type': 'application/json;charset=UTF-8', | |||
'content-type': 'multipart/form-data', | |||
token: AccessToken, | |||
'Access-Control-Allow-Credentials': true | |||
}, | |||
data: { file: that.base64ToBinary(that.ImgUrl) } | |||
}) | |||
.then((res) => { | |||
console.log(res) | |||
console.log(that.ImgUrl) | |||
console.log(that.base64ToBinary(that.ImgUrl)) | |||
that.loadingShow = false | |||
that.showCropper = false | |||
Toast.success('上传成功') | |||
}) | |||
}) | |||
}, | |||
// 点击取消 | |||
onClickLeft() { | |||
this.loadingShow = false | |||
this.showCropper = false | |||
this.$parent.showPhotoUploader = false | |||
}, | |||
// 上传图片 | |||
async pushImg(data) { | |||
try { | |||
const res = await awsImgUpload(data) | |||
this.loadingShow = false | |||
this.showCropper = false | |||
Toast.success('上传成功') | |||
} catch (error) { | |||
console.log(error, 'error') | |||
Toast.fail(error.message) | |||
} | |||
}, | |||
//图片转base64,异步 | |||
toBase64(file) { | |||
let that = this | |||
return new Promise((resolve, reject) => { | |||
const reader = new FileReader() | |||
reader.onload = () => { | |||
// base64结果 | |||
that.ImgUrl = this.result | |||
that.loading = false | |||
} | |||
reader.onerror = reject | |||
reader.readAsDataURL(file) | |||
}) | |||
}, | |||
// base64 转二进制 | |||
base64ToBinary(base64) { | |||
console.log(base64) | |||
const binaryString = window.atob(base64) | |||
const binaryLength = binaryString.length | |||
const bytes = new Uint8Array(binaryLength) | |||
for (let i = 0; i < binaryLength; i++) { | |||
bytes[i] = binaryString.charCodeAt(i) | |||
} | |||
return bytes | |||
} | |||
} | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
// .uploder{ | |||
// overflow: hidden; | |||
// } | |||
/deep/.cropper-view-box { | |||
outline: 2px dashed #fff !important; | |||
} | |||
/deep/.crop-point { | |||
background-color: auto !important; | |||
} | |||
/deep/.van-loading { | |||
position: absolute; | |||
// color: red; | |||
z-index: 9999; | |||
left: 50%; | |||
top: 50%; | |||
margin-left: -55px; | |||
margin-top: -30px; | |||
background: rgba(0, 0, 0, 0.3); | |||
padding: 10px 30px; | |||
border-radius: 25px; | |||
} | |||
.uploadava { | |||
.update-avatar { | |||
height: 100%; | |||
text-align: center; | |||
.update-avatar-line { | |||
width: 100%; | |||
height: 1px; | |||
background-color: #979797; | |||
} | |||
.avatar-select-type { | |||
background-color: #fff; | |||
width: 346px; | |||
border-radius: 12px; | |||
padding-bottom: 4px; | |||
.upload-avator { | |||
padding: 14px; | |||
} | |||
} | |||
p { | |||
margin: 15px 0 30px; | |||
background-color: #fff; | |||
width: 346px; | |||
border-radius: 12px; | |||
padding: 15px 0 18px; | |||
} | |||
} | |||
.cropper-container { | |||
height: 94vh; | |||
.van-nav-bar { | |||
background-color: rgba(0, 0, 0, 0.87); | |||
:global(.van-nav-bar__text) { | |||
color: #fff; | |||
// font-size: $font-size-normal-x; | |||
} | |||
:global(.van-nav-bar__text:nth-child(2)) { | |||
color: #000; | |||
font-weight: 500; | |||
} | |||
// :global(.van-icon) { | |||
// color: red; | |||
// } | |||
} | |||
} | |||
.vue-cropper { | |||
background: #000; | |||
height: 100%; | |||
padding-top: 46px; | |||
box-sizing: border-box; | |||
} | |||
} | |||
</style> |
@@ -0,0 +1,272 @@ | |||
<template> | |||
<div class="uploder"> | |||
<div class="change-photo-setter"> | |||
<van-uploader class="sett-item" :before-read="beforeRead"> | |||
<div style="height: 100%"><img :src="ImgUrl" alt="" /></div> | |||
<img src="https://img01.yzcdn.cn/vant/leaf.jpg" alt="" /> | |||
</van-uploader> | |||
</div> | |||
<div class="uploadava"> | |||
<van-popup | |||
duration="0" | |||
v-model="showCropper" | |||
position="top" | |||
:style="{ height: '100%' }" | |||
> | |||
<div class="cropper-container"> | |||
<van-loading | |||
v-show="loadingShow" | |||
size="50" | |||
color="#fff" | |||
vertical | |||
text-color="#fff" | |||
>上传中...</van-loading | |||
> | |||
<vueCropper | |||
ref="cropper" | |||
:img="option.img" | |||
:outputSize="option.outputSize" | |||
:outputType="option.outputType" | |||
:info="option.info" | |||
:full="option.full" | |||
:autoCropWidth="option.autoCropWidth" | |||
:autoCropHeight="option.autoCropHeight" | |||
:canMove="option.canMove" | |||
:canMoveBox="option.canMoveBox" | |||
:original="option.original" | |||
:autoCrop="option.autoCrop" | |||
:fixed="option.fixed" | |||
:fixedNumber="option.fixedNumber" | |||
:centerBox="option.centerBox" | |||
:infoTrue="option.infoTrue" | |||
:fixedBox="option.fixedBox" | |||
:high="option.high" | |||
:mode="option.mode" | |||
/> | |||
<van-nav-bar | |||
left-text="取消" | |||
right-text="选择" | |||
@click-left="onClickLeft" | |||
@click-right="onClickRight" | |||
/> | |||
</div> | |||
</van-popup> | |||
</div> | |||
</div> | |||
</template> | |||
<script> | |||
import { awsImgUpload } from '@/api/editModel' | |||
import { Toast } from 'vant' | |||
import { VueCropper } from 'vue-cropper' | |||
export default { | |||
name: 'uploadAva', | |||
components: { | |||
VueCropper | |||
}, | |||
props: { | |||
showAta: { | |||
default: false, | |||
type: Boolean | |||
}, | |||
avaUrl: { | |||
default: '', | |||
type: String | |||
} | |||
}, | |||
data() { | |||
return { | |||
ImgUrl: '', | |||
show: true, // 上传类型的弹窗 | |||
imageFileName: '', | |||
showCropper: false, // 裁剪的弹窗 | |||
option: { | |||
img: '', | |||
outputSize: 0.8, | |||
info: false, // 裁剪框的大小信息 | |||
outputType: 'jpeg', // 裁剪生成图片的格式 | |||
canScale: true, // 图片是否允许滚轮缩放 | |||
autoCrop: true, // 是否默认生成截图框 | |||
autoCropWidth: window.innerWidth - 100 + 'px', // 默认生成截图框宽度 | |||
autoCropHeight: window.innerWidth - 100 + 'px', // 默认生成截图框高度 | |||
high: true, // 是否按照设备的dpr 输出等比例图片 | |||
fixedBox: false, // 固定截图框大小 不允许改变 | |||
fixed: true, // 是否开启截图框宽高固定比例 | |||
fixedNumber: [1, 1], // 截图框的宽高比例 | |||
full: true, // 是否输出原图比例的截图 | |||
canMoveBox: true, // 截图框能否拖动 | |||
original: false, // 上传图片按照原始比例渲染 | |||
centerBox: true, // 截图框是否被限制在图片里面 | |||
infoTrue: false, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高 | |||
mode: '100% auto' // 图片默认渲染方式 | |||
}, | |||
loadingShow: false // 是否展示loading | |||
} | |||
}, | |||
methods: { | |||
beforeRead(file) { | |||
console.log(file) | |||
if (file.type !== 'image/jpeg' && file.type !== 'image/png') { | |||
this.$toast('请上传 jpg/png 格式图片') | |||
return false | |||
} | |||
// console.log(111, file) | |||
this.showCropper = true | |||
this.imageToBase64(file) | |||
this.imageFileName = file.name | |||
}, | |||
imageToBase64(file) { | |||
let reader = new FileReader() | |||
console.log(reader) | |||
reader.readAsDataURL(file) | |||
reader.onload = () => { | |||
this.option.img = reader.result | |||
} | |||
}, | |||
onClickRight() { | |||
// let formData = new FormData() | |||
this.loadingShow = true | |||
console.log(this.option) | |||
// const AccessToken = localStorage.getItem('AccessToken') | |||
// this.$axios({ | |||
// method: 'post', | |||
// url: `https://smapitest.malls.iformall.com/C/api/upload/awsImgUpload`, | |||
// headers: { | |||
// // 'Content-Type': 'application/json;charset=UTF-8', | |||
// 'content-type': 'multipart/form-data', | |||
// token: AccessToken, | |||
// 'Access-Control-Allow-Credentials': true | |||
// }, | |||
// data: { file: this.option.img } | |||
// }).then((res) => { | |||
// console.log(res) | |||
// this.loadingShow = false | |||
// this.showCropper = false | |||
// Toast.success('上传成功') | |||
// }) | |||
// this.pushImg({ file: this.option.img }) | |||
// this.pushImg({ file: require('../assets/icon/icon-yes.png') }) | |||
// this.$refs.cropper.getCropBlob((data) => { | |||
console.log(this.$refs.cropper) | |||
this.$refs.cropper.getCroppedCanvas((data) => { | |||
this.ImgUrl = data | |||
console.log(data, 'blob') | |||
// let blob = window.URL.createObjectURL(data) | |||
// console.log(blob) | |||
// formData.append('File', data, this.imageFileName) | |||
// formData.append('id', this.$store.getters.user.userId) | |||
// console.log(formData.getAll('File')) | |||
// console.log(data) | |||
// this.pushImg({ file: blob }) | |||
// uploadAva(formData).then((res) => { | |||
// this.showCropper = false | |||
// this.$emit('update:showAta', false) | |||
// this.$emit('update:avaUrl', res.data) | |||
// }) | |||
}) | |||
// this.$refs.cropper.getCroppedCanvas().toBlob((blob) => { | |||
// const formData = new FormData() | |||
// formData.append('file', blob, 'avatar.png') | |||
// this.pushImg({ file: blob }) | |||
// }) | |||
}, | |||
onClickLeft() { | |||
this.loadingShow = false | |||
this.showCropper = false | |||
this.$parent.showPhotoUploader = false | |||
}, | |||
// 上传图片 | |||
async pushImg(data) { | |||
try { | |||
const res = await awsImgUpload(data) | |||
this.loadingShow = false | |||
this.showCropper = false | |||
Toast.success('上传成功') | |||
} catch (error) { | |||
console.log(error, 'error') | |||
Toast.fail(error.message) | |||
} | |||
} | |||
} | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
// .uploder{ | |||
// overflow: hidden; | |||
// } | |||
/deep/.cropper-view-box { | |||
outline: 2px dashed #fff !important; | |||
} | |||
/deep/.crop-point { | |||
background-color: auto !important; | |||
} | |||
/deep/.van-loading { | |||
position: absolute; | |||
// color: red; | |||
z-index: 9999; | |||
left: 50%; | |||
top: 50%; | |||
margin-left: -55px; | |||
margin-top: -30px; | |||
background: rgba(0, 0, 0, 0.3); | |||
padding: 10px 30px; | |||
border-radius: 25px; | |||
} | |||
.uploadava { | |||
.update-avatar { | |||
height: 100%; | |||
text-align: center; | |||
.update-avatar-line { | |||
width: 100%; | |||
height: 1px; | |||
background-color: #979797; | |||
} | |||
.avatar-select-type { | |||
background-color: #fff; | |||
width: 346px; | |||
border-radius: 12px; | |||
padding-bottom: 4px; | |||
.upload-avator { | |||
padding: 14px; | |||
} | |||
} | |||
p { | |||
margin: 15px 0 30px; | |||
background-color: #fff; | |||
width: 346px; | |||
border-radius: 12px; | |||
padding: 15px 0 18px; | |||
} | |||
} | |||
.cropper-container { | |||
height: 94vh; | |||
.van-nav-bar { | |||
background-color: rgba(0, 0, 0, 0.87); | |||
:global(.van-nav-bar__text) { | |||
color: #fff; | |||
// font-size: $font-size-normal-x; | |||
} | |||
:global(.van-nav-bar__text:nth-child(2)) { | |||
color: #000; | |||
font-weight: 500; | |||
} | |||
// :global(.van-icon) { | |||
// color: red; | |||
// } | |||
} | |||
} | |||
.vue-cropper { | |||
background: #000; | |||
height: 100%; | |||
padding-top: 46px; | |||
box-sizing: border-box; | |||
} | |||
} | |||
</style> |
@@ -2,7 +2,7 @@ | |||
<div class="uploder"> | |||
<div class="change-photo-setter"> | |||
<van-uploader class="sett-item" :before-read="beforeRead"> | |||
<div style="height: 100%"></div> | |||
<div style="height: 100%"><img :src="ImgUrl" alt="" /></div> | |||
<img src="https://img01.yzcdn.cn/vant/leaf.jpg" alt="" /> | |||
</van-uploader> | |||
</div> | |||
@@ -45,7 +45,7 @@ | |||
/> | |||
<van-nav-bar | |||
left-text="取消" | |||
right-text="选择" | |||
right-text="确定" | |||
@click-left="onClickLeft" | |||
@click-right="onClickRight" | |||
/> | |||
@@ -76,6 +76,7 @@ export default { | |||
}, | |||
data() { | |||
return { | |||
ImgUrl: '', | |||
show: true, // 上传类型的弹窗 | |||
imageFileName: '', | |||
showCropper: false, // 裁剪的弹窗 | |||
@@ -109,67 +110,55 @@ export default { | |||
this.$toast('请上传 jpg/png 格式图片') | |||
return false | |||
} | |||
// console.log(111, file) | |||
let data = window.URL.createObjectURL(new Blob([file])) | |||
this.option.img = data //给裁剪图片的路径 | |||
this.showCropper = true | |||
this.imageToBase64(file) | |||
this.imageFileName = file.name | |||
}, | |||
imageToBase64(file) { | |||
let reader = new FileReader() | |||
console.log(reader) | |||
reader.readAsDataURL(file) | |||
reader.onload = () => { | |||
this.option.img = reader.result | |||
} | |||
return false | |||
}, | |||
// 点击裁剪的选择 | |||
onClickRight() { | |||
// let formData = new FormData() | |||
let that = this | |||
this.loadingShow = true | |||
console.log(this.option) | |||
const AccessToken = localStorage.getItem('AccessToken') | |||
this.$axios({ | |||
method: 'post', | |||
url: `https://smapitest.malls.iformall.com/C/api/upload/awsImgUpload`, | |||
headers: { | |||
// 'Content-Type': 'application/json;charset=UTF-8', | |||
'content-type': 'multipart/form-data', | |||
token: AccessToken, | |||
'Access-Control-Allow-Credentials': true | |||
}, | |||
data: { file: this.option.img } | |||
}).then((res) => { | |||
console.log(res) | |||
this.loadingShow = false | |||
this.showCropper = false | |||
Toast.success('上传成功') | |||
this.$refs.cropper.getCropBlob(async (data) => { | |||
let formData = new FormData() | |||
formData.append('file', data) | |||
let file = formData.get('file') | |||
// 转为 base64 | |||
let reader = new FileReader() | |||
const base64Data = await new Promise((resolve, reject) => { | |||
reader.onload = () => { | |||
resolve(reader.result) | |||
} | |||
reader.readAsDataURL(file) | |||
}) | |||
let imgBinary = await that.base64ToBinary(base64Data.substring(23)) | |||
// base64结果 | |||
that.ImgUrl = base64Data | |||
that.loading = false | |||
console.log(that.ImgUrl, 'dasdasd') | |||
// 发请求 | |||
const AccessToken = localStorage.getItem('AccessToken') | |||
that | |||
.$axios({ | |||
method: 'post', | |||
url: `https://smapitest.malls.iformall.com/C/api/upload/awsImgUpload`, | |||
headers: { | |||
'content-type': 'multipart/form-data', | |||
token: AccessToken, | |||
'Access-Control-Allow-Credentials': true | |||
}, | |||
data: formData | |||
}) | |||
.then((res) => { | |||
console.log(res) | |||
that.loadingShow = false | |||
that.showCropper = false | |||
Toast.success('上传成功') | |||
}) | |||
}) | |||
// this.pushImg({ file: this.option.img }) | |||
// this.pushImg({ file: require('../assets/icon/icon-yes.png') }) | |||
this.$refs.cropper.getCropBlob((data) => { | |||
console.log(data, 'blob') | |||
// let blob = window.URL.createObjectURL(data) | |||
// console.log(blob) | |||
// formData.append('File', data, this.imageFileName) | |||
// formData.append('id', this.$store.getters.user.userId) | |||
// console.log(formData.getAll('File')) | |||
// console.log(data) | |||
// this.pushImg({ file: blob }) | |||
// uploadAva(formData).then((res) => { | |||
// this.showCropper = false | |||
// this.$emit('update:showAta', false) | |||
// this.$emit('update:avaUrl', res.data) | |||
// }) | |||
}) | |||
// this.$refs.cropper.getCroppedCanvas().toBlob((blob) => { | |||
// const formData = new FormData() | |||
// formData.append('file', blob, 'avatar.png') | |||
// this.pushImg({ file: blob }) | |||
// }) | |||
}, | |||
// 点击取消 | |||
onClickLeft() { | |||
this.loadingShow = false | |||
this.showCropper = false | |||
@@ -186,6 +175,30 @@ export default { | |||
console.log(error, 'error') | |||
Toast.fail(error.message) | |||
} | |||
}, | |||
//图片转base64,异步 | |||
toBase64(file) { | |||
let that = this | |||
return new Promise((resolve, reject) => { | |||
const reader = new FileReader() | |||
reader.onload = () => { | |||
// base64结果 | |||
that.ImgUrl = this.result | |||
that.loading = false | |||
} | |||
reader.onerror = reject | |||
reader.readAsDataURL(file) | |||
}) | |||
}, | |||
// base64 转二进制 | |||
base64ToBinary(base64) { | |||
const binaryStr = window.atob(base64) | |||
const len = binaryStr.length | |||
const bytes = new Uint8Array(len) | |||
for (let i = 0; i < len; ++i) { | |||
bytes[i] = binaryStr.charCodeAt(i) | |||
} | |||
return bytes | |||
} | |||
} | |||
} | |||
@@ -68,6 +68,12 @@ const routes = [ | |||
name: 'editPosition-chatgpt', | |||
component: () => import("../views/model/editPosition-chatgpt"), | |||
}, | |||
// 编辑位置new | |||
{ | |||
path: '/videoDownload', | |||
name: 'videoDownload', | |||
component: () => import("../views/videoDownload/videoDownload"), | |||
}, | |||
// 聊天首页new | |||
{ | |||
path: '/chat', | |||
@@ -297,7 +297,7 @@ export default { | |||
codeInfo: '获取验证码', | |||
inPage: false, | |||
codeImg: '', //随机验证码图片 | |||
loginType: 6, //显示页面字符 | |||
loginType: 1, //显示页面字符 | |||
showCodeImg: true, // 控制验证码的刷新 | |||
// 短信验证码登录 | |||
form: { | |||
@@ -16,21 +16,6 @@ | |||
<van-tab v-for="item in tabList" :key="item" :title="item"> </van-tab> | |||
</van-tabs> | |||
<!-- <div class="title">选择模板</div> --> | |||
<!-- 老版吸顶tab栏 --> | |||
<!-- <div class="typeOutSide"> | |||
<div class="type"> | |||
<div :class="type == 0 ? 'active' : ''" @click="chooseType(0)"> | |||
全部模板 | |||
</div> | |||
<div :class="type == 2 ? 'active' : ''" @click="chooseType(2)"> | |||
女性模板 | |||
</div> | |||
<div :class="type == 1 ? 'active' : ''" @click="chooseType(1)"> | |||
男性模板 | |||
</div> | |||
</div> | |||
</div> --> | |||
<!-- 模板列表 --> | |||
<div class="choose"> | |||
<div class="modeList" v-masonry item-selector=".model" column-width="170"> | |||
@@ -43,9 +28,11 @@ | |||
:key="index" | |||
@click="selectModel(item.id)" | |||
> | |||
<img :src="item.coverImg" alt="" /> | |||
<div class="modelName">{{ item.title }}</div> | |||
<div class="setPaper">录入文案</div> | |||
<div class="model-padding"> | |||
<img :src="item.coverImg" alt="" /> | |||
<div class="modelName">{{ item.title }}</div> | |||
<div class="setPaper">录入文案</div> | |||
</div> | |||
</div> | |||
<div class="alt" v-if="modeList.length == 0">暂无可用模板</div> | |||
</div> | |||
@@ -62,6 +49,7 @@ import { Toast } from 'vant' | |||
import { scrollToID } from '../../utils' | |||
import { | |||
getModeList, | |||
getModeList1, | |||
getModeDetailById, | |||
saveOrUpdateUserVideo | |||
} from '../../api/chooseModel' | |||
@@ -122,7 +110,8 @@ export default { | |||
async loadModeList(sex) { | |||
try { | |||
sex = sex == 0 ? '' : sex | |||
const res = await getModeList(sex) | |||
// const res = await getModeList(sex) | |||
const res = await getModeList1(sex) | |||
console.log(res, '获取模板列表') | |||
this.modeList = res.data.list | |||
} catch (error) { | |||
@@ -296,18 +285,15 @@ export default { | |||
position: relative; | |||
text-align: left; | |||
margin-bottom: 15px; | |||
// border: 1px solid #00000028; | |||
// padding: 8px; | |||
// width: 154px; | |||
max-width: 170px; | |||
// height: 305px; | |||
max-height: 310px; | |||
// transition: all 0.3s; | |||
opacity: 0.9; | |||
padding: 5px; | |||
&-padding { | |||
} | |||
img { | |||
border-radius: 8px; | |||
width: 100%; | |||
height: 273px; | |||
// height: 273px; | |||
} | |||
.modelName { | |||
margin-top: 10px; | |||
@@ -58,11 +58,10 @@ export default { | |||
{ | |||
text: '小div1', | |||
url: 'img/BG@2x.b0cf224b.png', | |||
x: 300, | |||
x: 300, // 相对左上角XY坐标 | |||
y: 300, | |||
scale: 1, | |||
zIndex: 3, | |||
num: 1 | |||
scale: 1, //缩放 | |||
zIndex: 3 //层级 | |||
}, | |||
{ | |||
text: '小div2', | |||
@@ -39,25 +39,29 @@ | |||
:key="item.id ? item.id : index" | |||
@click="goDetail(item)" | |||
> | |||
<img :src="index == 1 ? defaultImg : defaultImg1" alt="" /> | |||
<!-- 渐变遮罩层 --> | |||
<div class="waterFall-item-mask"> | |||
<div>{{ item.title || '暂无' }}</div> | |||
<div>视频时长:{{ formatSeconds(item.videoTime) }}</div> | |||
<div>视频容量:{{ bytesToSize(item.videoSize) }}</div> | |||
<div> | |||
创建时间:{{ changeTime(item.createDate, 'YYYY-MM-DD hh:mm:ss') }} | |||
<div class="waterFall-item-paddding"> | |||
<img :src="index == 1 ? defaultImg : defaultImg1" alt="" /> | |||
<!-- 渐变遮罩层 --> | |||
<div class="waterFall-item-mask"> | |||
<div>{{ item.title || '暂无' }}</div> | |||
<div>视频时长:{{ formatSeconds(item.videoTime) }}</div> | |||
<div>视频容量:{{ bytesToSize(item.videoSize) }}</div> | |||
<div> | |||
创建时间:{{ | |||
changeTime(item.createDate, 'YYYY-MM-DD hh:mm:ss') | |||
}} | |||
</div> | |||
</div> | |||
<!-- 视频状态 草稿还是未完成还是失败 --> | |||
<div class="waterFall-item-state"> | |||
<div v-if="item.videoStatus == 0" class="cover">草稿</div> | |||
<div v-if="item.videoStatus == 1" class="cover">视频生成中</div> | |||
<div v-if="item.videoStatus == 3" class="cover">视频生成失败</div> | |||
</div> | |||
<!-- 删除 --> | |||
<div class="waterFall-item-del" @click.stop="goDelete(item.id)"> | |||
<img src="../../assets/icon/icon-trash.png" alt="" /> | |||
</div> | |||
</div> | |||
<!-- 视频状态 草稿还是未完成还是失败 --> | |||
<div class="waterFall-item-state"> | |||
<div v-if="item.videoStatus == 0" class="cover">草稿</div> | |||
<div v-if="item.videoStatus == 1" class="cover">视频生成中</div> | |||
<div v-if="item.videoStatus == 3" class="cover">视频生成失败</div> | |||
</div> | |||
<!-- 删除 --> | |||
<div class="waterFall-item-del" @click.stop="goDelete(item.id)"> | |||
<img src="../../assets/icon/icon-trash.png" alt="" /> | |||
</div> | |||
</div> | |||
</div> | |||
@@ -677,16 +681,21 @@ export default { | |||
display: flex; | |||
flex-wrap: wrap; | |||
justify-content: space-between; | |||
margin-right: -20px; | |||
width: 100%; | |||
&-item { | |||
// max-width: 355px; //非瀑布流 | |||
max-width: 170px; | |||
max-height: 300px; | |||
// background-color: red; | |||
padding: 5px; | |||
border-radius: 12px; | |||
margin-bottom: 10px; | |||
overflow: hidden; | |||
&-paddding { | |||
position: relative; | |||
border-radius: 12px; | |||
overflow: hidden; | |||
width: 160px; | |||
// padding: 5px; | |||
} | |||
img { | |||
max-width: 100%; | |||
max-height: 100%; | |||
@@ -0,0 +1,243 @@ | |||
<template> | |||
<div :class="inPage ? 'page active' : 'page'"> | |||
<div id="top"></div> | |||
<HeadTop /> | |||
<div class="content"> | |||
<!-- 视频 --> | |||
<div class="videoBox"> | |||
<video | |||
loop | |||
download | |||
ref="video" | |||
:src="videoSrc" | |||
@loadedmetadata="onVideoLoaded" | |||
@click.prevent="() => {}" | |||
@play="playing = true" | |||
@pause="playing = false" | |||
@timeupdate="onTimeUpdate" | |||
></video> | |||
<!-- 控制框 --> | |||
<div class="videoBox-controls"> | |||
<!-- 前进后退 --> | |||
<div class="videoBox-controls-left"> | |||
<div @click="seek(-10)"> | |||
<i class="el-icon-refresh-left"></i> | |||
</div> | |||
<div @click="togglePlay"> | |||
<i v-show="!this.playing" class="el-icon-video-play"></i> | |||
<i v-show="this.playing" class="el-icon-video-pause"></i> | |||
</div> | |||
<div @click="seek(10)"> | |||
<i class="el-icon-refresh-right"></i> | |||
</div> | |||
</div> | |||
<!-- 进度条 --> | |||
<div class="videoBox-controls-middle"> | |||
<div class="time">{{ formatTime(currentTime) }}</div> | |||
<van-slider | |||
active-color="#aa91a5" | |||
v-model="progress" | |||
:max="totalTime" | |||
:value="currentTime" | |||
@change="onProgressChange" | |||
></van-slider> | |||
<div class="time">{{ formatTime(totalTime) }}</div> | |||
</div> | |||
<!-- 全屏 --> | |||
<div class="videoBox-controls-right" @click="toggleScreen"> | |||
<van-icon name="enlarge" /> | |||
</div> | |||
</div> | |||
<!-- 下载按钮 --> | |||
<a :href="videoSrc" download class="videoBox-download"> | |||
<img src="../../assets/icon/icon-download.png" alt="" /> | |||
</a> | |||
</div> | |||
</div> | |||
</div> | |||
</template> | |||
<script> | |||
import Vue from 'vue' | |||
import { Toast } from 'vant' | |||
import { mapState, mapActions } from 'vuex' | |||
import HeadTop from './../../components/common/head.vue' | |||
// 工具 | |||
import { scrollToID } from '../../utils' | |||
Vue.use(Toast) | |||
export default { | |||
components: { | |||
HeadTop | |||
}, | |||
data() { | |||
return { | |||
inPage: false, | |||
videoSrc: | |||
'https://wenlian.wenzhou.gov.cn:8001//upload/video/%E3%80%8A%E7%93%AF%E8%B6%8A%E4%B9%8B%E5%8D%8E%E3%80%8B%E7%89%87%E8%8A%B11.mp4', | |||
showControls: false, // 控制台显示隐藏 | |||
playing: false, // 播放 | |||
isLandscape: false, | |||
progress: 0, | |||
currentTime: 0, | |||
totalTime: 0, | |||
progressChanging: false | |||
} | |||
}, | |||
computed: { | |||
...mapState({ | |||
characters: (state) => state.publicObj.characters | |||
}) | |||
}, | |||
mounted() { | |||
this.inPage = true | |||
scrollToID('top') | |||
this.$refs.video.addEventListener('timeupdate', this.onTimeUpdate) | |||
this.$refs.video.addEventListener('ended', this.onVideoEnded) | |||
screen.orientation.addEventListener('change', this.onOrientationChange) | |||
}, | |||
destroyed() { | |||
this.$refs.video.removeEventListener('timeupdate', this.onTimeUpdate) | |||
this.$refs.video.removeEventListener('ended', this.onVideoEnded) | |||
screen.orientation.removeEventListener('change', this.onOrientationChange) | |||
}, | |||
methods: { | |||
onVideoLoaded() { | |||
this.totalTime = this.$refs.video.duration | |||
}, | |||
// onTimeUpdate() { | |||
// if (!this.progressChanging) { | |||
// this.currentTime = this.$refs.video.currentTime | |||
// this.progress = this.currentTime | |||
// } | |||
// }, | |||
onVideoEnded() { | |||
this.playing = false | |||
}, | |||
// 播放&暂停 | |||
togglePlay() { | |||
this.playing = !this.playing | |||
if (this.playing) { | |||
this.$refs.video.play() | |||
} else { | |||
this.$refs.video.pause() | |||
} | |||
}, | |||
// 横屏 | |||
toggleScreen() { | |||
if (this.isLandscape) { | |||
screen.orientation.unlock() | |||
} else { | |||
screen.orientation.lock('landscape') | |||
} | |||
this.isLandscape = !this.isLandscape | |||
}, | |||
onOrientationChange() { | |||
this.fullScreen = screen.orientation.type.includes('landscape') | |||
}, | |||
// 控制快进后退 | |||
seek(seconds) { | |||
const newTime = Math.max( | |||
0, | |||
Math.min(this.totalTime, this.currentTime + seconds) | |||
) | |||
this.$refs.video.currentTime = newTime | |||
this.currentTime = newTime | |||
}, | |||
// 拖动滚动条 | |||
onProgressChange() { | |||
this.progressChanging = true | |||
this.$refs.video.currentTime = this.progress | |||
}, | |||
//实时更新时间 | |||
onTimeUpdate() { | |||
this.currentTime = this.$refs.video.currentTime | |||
this.progress = this.currentTime | |||
}, | |||
// 处理时间 | |||
formatTime(time) { | |||
const minutes = Math.floor(time / 60) | |||
const seconds = Math.round(time % 60) | |||
return `${minutes}:${seconds.toString().padStart(2, '0')}` | |||
}, | |||
...mapActions(['setCharacters']), | |||
go(url) { | |||
this.$router.push(url) | |||
} | |||
} | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
.page { | |||
width: 375px; | |||
height: 100vh; | |||
overflow-y: hidden; | |||
} | |||
.content { | |||
width: 100%; | |||
height: calc(100vh - 40px); | |||
overflow: hidden; | |||
} | |||
.videoBox { | |||
position: relative; | |||
width: 100%; | |||
height: 627px; | |||
background-color: #f8f9f9; | |||
video { | |||
width: 100%; | |||
height: 100%; | |||
} | |||
&-controls { | |||
display: flex; | |||
justify-content: space-between; | |||
align-items: center; | |||
padding: 6px 11px; | |||
position: absolute; | |||
left: 50%; | |||
bottom: 27px; | |||
transform: translateX(-50%); | |||
width: calc(100% - 20px); | |||
height: 26px; | |||
background: rgba(67, 68, 71, 0.7); | |||
border-radius: 9px; | |||
color: #fff; | |||
&-left { | |||
display: flex; | |||
justify-content: space-between; | |||
align-items: center; | |||
div { | |||
padding: 0 8px; | |||
} | |||
i { | |||
display: block; | |||
width: 11px; | |||
height: 11px; | |||
color: #fff; | |||
} | |||
} | |||
&-middle { | |||
flex: 1; | |||
display: flex; | |||
justify-content: space-between; | |||
align-items: center; | |||
.time { | |||
padding: 0 8px; | |||
} | |||
::v-deep .van-slider__button { | |||
width: 5px; | |||
height: 5px; | |||
border-radius: 50%; | |||
} | |||
} | |||
} | |||
&-download { | |||
position: absolute; | |||
right: 10px; | |||
top: 15px; | |||
display: inline-block; | |||
width: 24px; | |||
height: 24px; | |||
} | |||
} | |||
</style> |