@@ -13,10 +13,10 @@ | |||||
"element-ui": "^2.15.12", | "element-ui": "^2.15.12", | ||||
"file-saver": "^2.0.5", | "file-saver": "^2.0.5", | ||||
"franc": "^6.1.0", | "franc": "^6.1.0", | ||||
"image-webpack-loader": "^8.1.0", | |||||
"install": "^0.13.0", | "install": "^0.13.0", | ||||
"lib-flexible": "^0.3.2", | "lib-flexible": "^0.3.2", | ||||
"mic-recorder-to-mp3": "^2.2.2", | "mic-recorder-to-mp3": "^2.2.2", | ||||
"npm": "^9.6.2", | |||||
"postcss-px2rem": "^0.3.0", | "postcss-px2rem": "^0.3.0", | ||||
"register-service-worker": "^1.7.1", | "register-service-worker": "^1.7.1", | ||||
"swiper": "^4.5.1", | "swiper": "^4.5.1", | ||||
@@ -32,10 +32,11 @@ | |||||
"@vue/cli-plugin-router": "~4.5.13", | "@vue/cli-plugin-router": "~4.5.13", | ||||
"@vue/cli-plugin-vuex": "~4.5.13", | "@vue/cli-plugin-vuex": "~4.5.13", | ||||
"@vue/cli-service": "~4.5.13", | "@vue/cli-service": "~4.5.13", | ||||
"compression-webpack-plugin": "5.0.1", | |||||
"node-sass": "^6.0.1", | "node-sass": "^6.0.1", | ||||
"sass": "^1.60.0", | "sass": "^1.60.0", | ||||
"sass-loader": "^7.0.3", | "sass-loader": "^7.0.3", | ||||
"uglifyjs-webpack-plugin": "^2.2.0", | "uglifyjs-webpack-plugin": "^2.2.0", | ||||
"vue-template-compiler": "^2.6.11" | "vue-template-compiler": "^2.6.11" | ||||
} | } | ||||
} | |||||
} |
@@ -0,0 +1,377 @@ | |||||
<template> | |||||
<div class="uploder"> | |||||
<div class="change-photo-setter" style="height: 240px; width: 160px"> | |||||
<van-uploader ref="uploader" class="sett-item" :before-read="beforeRead" style="height: 240px; width: 160px"> | |||||
<div style="height: 240px; width: 160px"> | |||||
<!-- <img :src="ImgUrl" alt="" /> --> | |||||
</div> | |||||
</van-uploader> | |||||
</div> | |||||
<div class="uploadava"> | |||||
<!-- van-popup有bug,某些1情况需要绑定app为根 --> | |||||
<van-popup :get-container="this.isAndroid ? '' : '#app'" class="vanPopup" duration="0" v-model="showCropper" position="top" :style="{ height: '100%' }"> | |||||
<div class="cropper-container" :style="{ height: '92vh', position: 'relative' }"> | |||||
<van-loading v-show="loadingShow" size="50" color="#fff" vertical text-color="#fff">上传中...</van-loading> | |||||
<!-- 切图组件 --> | |||||
<!-- :outputSize="option.outputSize" --> | |||||
<vueCropper | |||||
:style="{ backgroundImage: 'none', height: '92vh' }" | |||||
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" /> | |||||
<!-- <div style="display: flex; justify-content: space-between; padding: 10px; height: 8vh"> | |||||
<div @click="onClickLeft">取消</div> | |||||
<div @click="onClickRight">确定</div> | |||||
</div> --> | |||||
<van-nav-bar :style="{ height: '8vh', width: '100%', position: 'absolute' }" 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'; | |||||
import { scrollToID, getDeviceType } from '../utils'; | |||||
import { saveImgApi } from '../api/editModel'; | |||||
import { watch } from 'vue'; | |||||
export default { | |||||
name: 'uploadAva', | |||||
components: { | |||||
VueCropper | |||||
}, | |||||
props: { | |||||
showAta: { | |||||
default: false, | |||||
type: Boolean | |||||
}, | |||||
avaUrl: { | |||||
default: '', | |||||
type: String | |||||
}, | |||||
type: { | |||||
default: '', | |||||
type: Number | |||||
}, | |||||
videoType: { | |||||
default: null, | |||||
type: Number | |||||
} | |||||
}, | |||||
data() { | |||||
return { | |||||
isAndroid: false, //判断是不是ios | |||||
aaa: null, | |||||
ImgUrl: '', | |||||
show: true, // 上传类型的弹窗 | |||||
imageFileName: '', | |||||
showCropper: false, // 裁剪的弹窗 | |||||
option: { | |||||
img: '', | |||||
outputSize: 0.5, //图片质量 | |||||
info: false, // 裁剪框的大小信息 | |||||
// outputType: 'jpeg', // 裁剪生成图片的格式 | |||||
outputType: 'png', // 裁剪生成图片的格式 | |||||
canScale: true, // 图片是否允许滚轮缩放 | |||||
autoCrop: true, // 是否默认生成截图框 | |||||
autoCropWidth: window.innerWidth - 100 + 'px', // 默认生成截图框宽度 | |||||
autoCropHeight: window.innerWidth - 100 + 'px', // 默认生成截图框高度 | |||||
high: true, // 是否按照设备的dpr 输出等比例图片 | |||||
fixedBox: false, // 固定截图框大小 不允许改变 | |||||
fixed: false, // 是否开启截图框宽高固定比例 | |||||
// fixedNumber: [1, 1], // 截图框的宽高比例 | |||||
full: true, // 是否输出原图比例的截图 | |||||
canMoveBox: true, // 截图框能否拖动 | |||||
original: false, // 上传图片按照原始比例渲染 | |||||
centerBox: true, // 截图框是否被限制在图片里面 | |||||
infoTrue: false, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高 | |||||
mode: '100% auto' // 图片默认渲染方式 | |||||
}, | |||||
loadingShow: false // 是否展示loading | |||||
}; | |||||
}, | |||||
created() { | |||||
const deviceType = getDeviceType(); | |||||
this.isAndroid = false; | |||||
if (!deviceType) { | |||||
// 设备类型为pc | |||||
this.isAndroid = false; | |||||
} else { | |||||
if (deviceType[0] == 'Android') { | |||||
// 设备类型为安卓 | |||||
this.isAndroid = true; | |||||
} else { | |||||
// 其他设备 | |||||
this.isAndroid = false; | |||||
} | |||||
} | |||||
if (this.type == 4 && this.videoType == 1) { | |||||
this.option.autoCropWidth = 1080 + 'px'; // 默认生成截图框宽度 | |||||
this.option.autoCropHeight = 1920 + 'px'; // 默认生成截图框高度 | |||||
this.option.fixed = true; | |||||
this.option.fixedNumber = [1080, 1920]; | |||||
} | |||||
if (this.type == 4 && this.videoType == 2) { | |||||
this.option.autoCropWidth = 1920 + 'px'; // 默认生成截图框宽度 | |||||
this.option.autoCropHeight = 1080 + 'px'; // 默认生成截图框高度 | |||||
this.option.fixed = true; | |||||
this.option.fixedNumber = [1920, 1080]; | |||||
} | |||||
}, | |||||
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])); | |||||
let data = window.URL.createObjectURL(file); | |||||
console.log(data); | |||||
this.option.img = data; //给裁剪图片的路径 | |||||
this.showCropper = true; | |||||
return false; | |||||
}, | |||||
// 点击裁剪的选择 | |||||
onClickRight() { | |||||
const timestamp = Date.now(); | |||||
let that = this; | |||||
this.loadingShow = true; | |||||
// console.log(this.$refs.cropper); | |||||
this.$refs.cropper.getCropData(data => { | |||||
// do something | |||||
// console.log(data, 'base64'); | |||||
}); | |||||
this.$refs.cropper.getCropBlob(async data => { | |||||
console.log(data, '上传图片数据'); | |||||
// 利用canvas压缩图片 | |||||
const img = new Image(); | |||||
img.src = URL.createObjectURL(data); | |||||
const canvas = document.createElement('canvas'); | |||||
const context = canvas.getContext('2d'); | |||||
const getCanvasData = new Promise((resolve, reject) => { | |||||
canvas.width = img.width; | |||||
canvas.height = img.height; | |||||
img.onload = function () { | |||||
context.drawImage(img, 0, 0); | |||||
canvas.toBlob( | |||||
function (compressedBlob) { | |||||
resolve(compressedBlob); | |||||
}, | |||||
'png', | |||||
0.5 | |||||
); // 指定导出的图像类型和压缩质量 | |||||
}; | |||||
}); | |||||
const canvasData = await getCanvasData; | |||||
// --------------------------------------------- | |||||
let formData = new FormData(); | |||||
// formData.append('file', data, timestamp + '.png'); | |||||
console.log(canvasData, '压缩图片数据'); | |||||
formData.append('file', canvasData, timestamp + '.png'); | |||||
that.loading = false; | |||||
// console.log(that.ImgUrl, 'dasdasd') | |||||
// 发请求 | |||||
const AccessToken = localStorage.getItem('AccessToken'); | |||||
that | |||||
.$axios({ | |||||
method: 'post', | |||||
url: process.env.VUE_APP_API_ROOT + `/api/upload/awsImgUpload`, | |||||
headers: { | |||||
'content-type': 'multipart/form-data', | |||||
token: AccessToken, | |||||
'Access-Control-Allow-Credentials': true | |||||
}, | |||||
data: formData | |||||
}) | |||||
.then(async res => { | |||||
// console.log(res.data.data.url) | |||||
const res1 = await saveImgApi({ | |||||
type: that.type, | |||||
videoType: that.videoType, | |||||
material: res.data.data.url | |||||
}); | |||||
// 重新获取列表 | |||||
await that.$parent.$parent.getMyBGIListApi(); | |||||
await that.$parent.$parent.getMyScListApi(); | |||||
if (this.type == 4) { | |||||
that.$parent.$parent.changeShowBGIList(1); | |||||
} | |||||
if (this.type == 5) { | |||||
that.$parent.$parent.changeShowBGIList(3); | |||||
} | |||||
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) { | |||||
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; | |||||
} | |||||
}, | |||||
mounted() {} | |||||
}; | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
// /deep/.cropper-container { | |||||
// z-index: 2005 !important; | |||||
// } | |||||
// .uploder{ | |||||
// overflow: hidden; | |||||
// } | |||||
/deep/.van-nav-bar__content { | |||||
height: 8vh; | |||||
background-color: #ccc; | |||||
} | |||||
/deep/.van-hairline--bottom::after { | |||||
// height: 8vh; | |||||
} | |||||
/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 { | |||||
// width: 100%; | |||||
// width: 100vw; | |||||
height: 94vh; | |||||
.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 { | |||||
position: relative; | |||||
width: 100%; | |||||
height: 94vh; | |||||
// height: 100%; | |||||
/deep/ .van-nav-bar { | |||||
position: absolute; | |||||
z-index: 999; | |||||
width: 100%; | |||||
bottom: 0px; | |||||
left: 0px; | |||||
height: 6vh; | |||||
background-color: rgba(0, 0, 0, 0.87); | |||||
:global(.van-nav-bar__text) { | |||||
color: #000; | |||||
// 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; | |||||
width: 100%; | |||||
height: 88vh; | |||||
padding-top: 46px; | |||||
box-sizing: border-box; | |||||
} | |||||
} | |||||
</style> |
@@ -10,11 +10,12 @@ | |||||
<div class="uploadava"> | <div class="uploadava"> | ||||
<!-- van-popup有bug,某些1情况需要绑定app为根 --> | <!-- van-popup有bug,某些1情况需要绑定app为根 --> | ||||
<van-popup :get-container="this.isAndroid ? '' : '#app'" class="vanPopup" duration="0" v-model="showCropper" position="top" :style="{ height: '100%' }"> | <van-popup :get-container="this.isAndroid ? '' : '#app'" class="vanPopup" duration="0" v-model="showCropper" position="top" :style="{ height: '100%' }"> | ||||
<div class="cropper-container" :style="{ height: '94vh' }"> | |||||
<div class="cropper-container" :style="{ height: '92vh', position: 'relative' }"> | |||||
<van-loading v-show="loadingShow" size="50" color="#fff" vertical text-color="#fff">上传中...</van-loading> | <van-loading v-show="loadingShow" size="50" color="#fff" vertical text-color="#fff">上传中...</van-loading> | ||||
<!-- 切图组件 --> | <!-- 切图组件 --> | ||||
<!-- :outputSize="option.outputSize" --> | |||||
<vueCropper | <vueCropper | ||||
style="background-image: none" | |||||
:style="{ backgroundImage: 'none', height: '92vh' }" | |||||
ref="cropper" | ref="cropper" | ||||
:img="option.img" | :img="option.img" | ||||
:outputSize="option.outputSize" | :outputSize="option.outputSize" | ||||
@@ -38,7 +39,7 @@ | |||||
<div @click="onClickLeft">取消</div> | <div @click="onClickLeft">取消</div> | ||||
<div @click="onClickRight">确定</div> | <div @click="onClickRight">确定</div> | ||||
</div> --> | </div> --> | ||||
<van-nav-bar left-text="取消" right-text="确定" @click-left="onClickLeft" @click-right="onClickRight" /> | |||||
<van-nav-bar :style="{ height: '8vh', width: '100%', position: 'absolute' }" left-text="取消" right-text="确定" @click-left="onClickLeft" @click-right="onClickRight" /> | |||||
</div> | </div> | ||||
</van-popup> | </van-popup> | ||||
</div> | </div> | ||||
@@ -85,7 +86,7 @@ export default { | |||||
showCropper: false, // 裁剪的弹窗 | showCropper: false, // 裁剪的弹窗 | ||||
option: { | option: { | ||||
img: '', | img: '', | ||||
outputSize: 0.8, | |||||
outputSize: 0.5, //图片质量 | |||||
info: false, // 裁剪框的大小信息 | info: false, // 裁剪框的大小信息 | ||||
// outputType: 'jpeg', // 裁剪生成图片的格式 | // outputType: 'jpeg', // 裁剪生成图片的格式 | ||||
outputType: 'png', // 裁剪生成图片的格式 | outputType: 'png', // 裁剪生成图片的格式 | ||||
@@ -142,20 +143,27 @@ export default { | |||||
this.$toast('请上传 jpg/png 格式图片'); | this.$toast('请上传 jpg/png 格式图片'); | ||||
return false; | return false; | ||||
} | } | ||||
let data = window.URL.createObjectURL(new Blob([file])); | |||||
// let data = window.URL.createObjectURL(new Blob([file])); | |||||
let data = window.URL.createObjectURL(file); | |||||
console.log(data); | |||||
this.option.img = data; //给裁剪图片的路径 | this.option.img = data; //给裁剪图片的路径 | ||||
this.showCropper = true; | this.showCropper = true; | ||||
return false; | return false; | ||||
}, | }, | ||||
// 点击裁剪的选择 | // 点击裁剪的选择 | ||||
onClickRight() { | onClickRight() { | ||||
const timestamp = Date.now(); | |||||
let that = this; | let that = this; | ||||
this.loadingShow = true; | this.loadingShow = true; | ||||
console.log(this.$refs.cropper); | |||||
// console.log(this.$refs.cropper); | |||||
this.$refs.cropper.getCropData(data => { | |||||
// do something | |||||
// console.log(data, 'base64'); | |||||
}); | |||||
this.$refs.cropper.getCropBlob(async data => { | this.$refs.cropper.getCropBlob(async data => { | ||||
console.log(data, '图片数据'); | |||||
console.log(data, '上传图片数据'); | |||||
let formData = new FormData(); | let formData = new FormData(); | ||||
formData.append('file', data); | |||||
formData.append('file', data, timestamp + '.png'); | |||||
let file = formData.get('file'); | let file = formData.get('file'); | ||||
// 转为 base64 | // 转为 base64 | ||||
// let reader = new FileReader(); | // let reader = new FileReader(); | ||||
@@ -262,6 +270,14 @@ export default { | |||||
// .uploder{ | // .uploder{ | ||||
// overflow: hidden; | // overflow: hidden; | ||||
// } | // } | ||||
/deep/.van-nav-bar__content { | |||||
height: 8vh; | |||||
background-color: #ccc; | |||||
} | |||||
/deep/.van-hairline--bottom::after { | |||||
// height: 8vh; | |||||
} | |||||
/deep/.cropper-view-box { | /deep/.cropper-view-box { | ||||
outline: 2px dashed #fff !important; | outline: 2px dashed #fff !important; | ||||
} | } | ||||
@@ -86,7 +86,7 @@ export default { | |||||
showCropper: false, // 裁剪的弹窗 | showCropper: false, // 裁剪的弹窗 | ||||
option: { | option: { | ||||
img: '', | img: '', | ||||
outputSize: 0.01, //图片质量 | |||||
outputSize: 0.5, //图片质量 | |||||
info: false, // 裁剪框的大小信息 | info: false, // 裁剪框的大小信息 | ||||
// outputType: 'jpeg', // 裁剪生成图片的格式 | // outputType: 'jpeg', // 裁剪生成图片的格式 | ||||
outputType: 'png', // 裁剪生成图片的格式 | outputType: 'png', // 裁剪生成图片的格式 | ||||
@@ -143,7 +143,9 @@ export default { | |||||
this.$toast('请上传 jpg/png 格式图片'); | this.$toast('请上传 jpg/png 格式图片'); | ||||
return false; | return false; | ||||
} | } | ||||
let data = window.URL.createObjectURL(new Blob([file])); | |||||
// let data = window.URL.createObjectURL(new Blob([file])); | |||||
let data = window.URL.createObjectURL(file); | |||||
console.log(data); | |||||
this.option.img = data; //给裁剪图片的路径 | this.option.img = data; //给裁剪图片的路径 | ||||
this.showCropper = true; | this.showCropper = true; | ||||
return false; | return false; | ||||
@@ -160,20 +162,33 @@ export default { | |||||
}); | }); | ||||
this.$refs.cropper.getCropBlob(async data => { | this.$refs.cropper.getCropBlob(async data => { | ||||
console.log(data, '上传图片数据'); | console.log(data, '上传图片数据'); | ||||
// 利用canvas压缩图片 | |||||
const img = new Image(); | |||||
img.src = URL.createObjectURL(data); | |||||
const canvas = document.createElement('canvas'); | |||||
const context = canvas.getContext('2d'); | |||||
const getCanvasData = new Promise((resolve, reject) => { | |||||
img.onload = function () { | |||||
canvas.width = img.width; | |||||
canvas.height = img.height; | |||||
context.drawImage(img, 0, 0); | |||||
canvas.toBlob( | |||||
function (compressedBlob) { | |||||
resolve(compressedBlob); | |||||
}, | |||||
0.5 | |||||
); // 指定导出的图像类型和压缩质量 | |||||
}; | |||||
}); | |||||
// img.src = URL.createObjectURL(data); | |||||
const canvasData = await getCanvasData; | |||||
// --------------------------------------------- | |||||
let formData = new FormData(); | let formData = new FormData(); | ||||
formData.append('file', data, timestamp + '.png'); | |||||
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; | |||||
// formData.append('file', data, timestamp + '.png'); | |||||
console.log(canvasData, '压缩图片数据'); | |||||
formData.append('file', canvasData, timestamp + '.png'); | |||||
that.loading = false; | that.loading = false; | ||||
// console.log(that.ImgUrl, 'dasdasd') | // console.log(that.ImgUrl, 'dasdasd') | ||||
// 发请求 | // 发请求 | ||||
@@ -181,8 +196,7 @@ export default { | |||||
that | that | ||||
.$axios({ | .$axios({ | ||||
method: 'post', | method: 'post', | ||||
// url: `https://smapitest.malls.iformall.com/C/api/upload/awsImgUpload`, | |||||
// url: `http://m.metavatar.cc/C/api/upload/awsImgUpload`, | |||||
url: process.env.VUE_APP_API_ROOT + `/api/upload/awsImgUpload`, | url: process.env.VUE_APP_API_ROOT + `/api/upload/awsImgUpload`, | ||||
headers: { | headers: { | ||||
'content-type': 'multipart/form-data', | 'content-type': 'multipart/form-data', | ||||
@@ -5,9 +5,9 @@ | |||||
<div class="contnet"> | <div class="contnet"> | ||||
<!-- 头部 --> | <!-- 头部 --> | ||||
<div class="head"> | <div class="head"> | ||||
<img src="../../assets/icon/icon-loginout.png" alt=""> | |||||
<img src="../../assets/icon/icon-loginout.png" alt="" /> | |||||
<div class="head-exit"> | <div class="head-exit"> | ||||
<img src="../../assets/icon/icon-loginoutwhite.png" alt=""> | |||||
<img src="../../assets/icon/icon-loginoutwhite.png" alt="" /> | |||||
退出聊天 | 退出聊天 | ||||
</div> | </div> | ||||
</div> | </div> | ||||
@@ -17,40 +17,41 @@ | |||||
<div class="showBody-bottom"> | <div class="showBody-bottom"> | ||||
<!-- 更换人物模板列表 --> | <!-- 更换人物模板列表 --> | ||||
<div v-show="PersonButtonAction" class="showBody-modelList"> | <div v-show="PersonButtonAction" class="showBody-modelList"> | ||||
<div v-for="item,index in modelList" :key="item.name" class="showBody-modelList-item" @click="modelItemAction=index"> | |||||
<div class="modelName">{{ item.name }} | |||||
<div v-show="modelItemAction==index" class="showBody-modelList-item-boxBorder"></div> | |||||
<div v-for="(item, index) in modelList" :key="item.name" class="showBody-modelList-item" @click="modelItemAction = index"> | |||||
<div class="modelName"> | |||||
{{ item.name }} | |||||
<div v-show="modelItemAction == index" class="showBody-modelList-item-boxBorder"></div> | |||||
</div> | |||||
<img :src="item.url" alt="" /> | |||||
</div> | </div> | ||||
<img :src="item.url" alt=""> | |||||
</div> | |||||
</div> | </div> | ||||
<!-- 四大按钮 --> | <!-- 四大按钮 --> | ||||
<div class="showBody-bottom-buttons"> | <div class="showBody-bottom-buttons"> | ||||
<!-- --> | <!-- --> | ||||
<div class="showBody-bottom-buttons-item"> | <div class="showBody-bottom-buttons-item"> | ||||
<div :class="{'buleBtn':PersonButtonAction}" class="defaultBtn" @click="clickPersonButton"> | |||||
<img src="@/assets/icon/icon-person.png" alt=""> | |||||
<div :class="{ buleBtn: PersonButtonAction }" class="defaultBtn" @click="clickPersonButton"> | |||||
<img src="@/assets/icon/icon-person.png" alt="" /> | |||||
</div> | </div> | ||||
<p>更换人物模板</p> | <p>更换人物模板</p> | ||||
</div> | </div> | ||||
<!-- --> | <!-- --> | ||||
<div class="showBody-bottom-buttons-item"> | <div class="showBody-bottom-buttons-item"> | ||||
<div :class="{'buleBtn':CameraAction}" class="defaultBtn" @click="clickCameraButton"> | |||||
<img src="@/assets/icon/icon-openCamera.png" alt=""> | |||||
<div :class="{ buleBtn: CameraAction }" class="defaultBtn" @click="clickCameraButton"> | |||||
<img src="@/assets/icon/icon-openCamera.png" alt="" /> | |||||
</div> | </div> | ||||
<p>摄像头开启</p> | <p>摄像头开启</p> | ||||
</div> | </div> | ||||
<!-- --> | <!-- --> | ||||
<div class="showBody-bottom-buttons-item"> | <div class="showBody-bottom-buttons-item"> | ||||
<div :class="{'buleBtn':CloseChatAction}" class="defaultBtn" @click="clickCloseChatButton"> | |||||
<img src="@/assets/icon/icon-closeChat.png" alt=""> | |||||
<div :class="{ buleBtn: CloseChatAction }" class="defaultBtn" @click="clickCloseChatButton"> | |||||
<img src="@/assets/icon/icon-closeChat.png" alt="" /> | |||||
</div> | </div> | ||||
<p>对话框关闭</p> | <p>对话框关闭</p> | ||||
</div> | </div> | ||||
<!-- --> | <!-- --> | ||||
<div class="showBody-bottom-buttons-item"> | <div class="showBody-bottom-buttons-item"> | ||||
<div :class="{'buleBtn':GlobalAction}" class="defaultBtn" @click="clickGlobalButton"> | |||||
<img src="@/assets/icon/icon-global.png" alt=""> | |||||
<div :class="{ buleBtn: GlobalAction }" class="defaultBtn" @click="clickGlobalButton"> | |||||
<img src="@/assets/icon/icon-global.png" alt="" /> | |||||
</div> | </div> | ||||
<p>选择对话语言</p> | <p>选择对话语言</p> | ||||
</div> | </div> | ||||
@@ -64,14 +65,13 @@ | |||||
<div v-show="CloseChatAction" class="showBody-chatBox"> | <div v-show="CloseChatAction" class="showBody-chatBox"> | ||||
<!-- 关闭 --> | <!-- 关闭 --> | ||||
<div class="showBody-chatBox-close"> | <div class="showBody-chatBox-close"> | ||||
<i @click="CloseChatAction=false" class="el-icon-close"></i> | |||||
<i @click="CloseChatAction = false" class="el-icon-close"></i> | |||||
</div> | </div> | ||||
<!-- 聊天记录 --> | <!-- 聊天记录 --> | ||||
<div class="showBody-chatBox-record"> | <div class="showBody-chatBox-record"> | ||||
<div class="showBody-chatBox-record-my" :class="{'others':item.form!='me'}" v-for="item,index in chatRecordList" :key="index"> | |||||
<div class="showBody-chatBox-record-my" :class="{ others: item.form != 'me' }" v-for="(item, index) in chatRecordList" :key="index"> | |||||
<span>{{ item.message }}</span> | <span>{{ item.message }}</span> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<!-- 底部说话按钮 --> | <!-- 底部说话按钮 --> | ||||
<LanguageToText @getSonMessage="addMessageRecord(data)"></LanguageToText> | <LanguageToText @getSonMessage="addMessageRecord(data)"></LanguageToText> | ||||
@@ -82,14 +82,14 @@ | |||||
<div class="showBody-global-choose"> | <div class="showBody-global-choose"> | ||||
<div class="showBody-global-choose-language"> | <div class="showBody-global-choose-language"> | ||||
<div class="showBody-global-choose-language-item" v-for="item in languageList" :key="item.type"> | <div class="showBody-global-choose-language-item" v-for="item in languageList" :key="item.type"> | ||||
{{ item.type }} | |||||
{{ item.type }} | |||||
</div> | </div> | ||||
</div> | </div> | ||||
<div class="showBody-global-choose-btn"> | <div class="showBody-global-choose-btn"> | ||||
<div @click="GlobalAction=false" class="showBody-global-choose-btn-no">取消</div> | |||||
<div @click="GlobalAction = false" class="showBody-global-choose-btn-no">取消</div> | |||||
<div class="showBody-global-choose-btn-yes">确定</div> | <div class="showBody-global-choose-btn-yes">确定</div> | ||||
</div> | </div> | ||||
</div> | |||||
</div> | |||||
<!-- 底部说话按钮 --> | <!-- 底部说话按钮 --> | ||||
<LanguageToText></LanguageToText> | <LanguageToText></LanguageToText> | ||||
</div> | </div> | ||||
@@ -99,13 +99,13 @@ | |||||
</template> | </template> | ||||
<script> | <script> | ||||
import LanguageToText from '@/components/languageToText.vue' | |||||
import LanguageToText from '@/components/languageToText.vue'; | |||||
// 组件 | // 组件 | ||||
import Vue from "vue"; | |||||
import { Toast } from "vant"; | |||||
import { mapState, mapActions } from "vuex"; | |||||
import Vue from 'vue'; | |||||
import { Toast } from 'vant'; | |||||
import { mapState, mapActions } from 'vuex'; | |||||
// 工具 | // 工具 | ||||
import { scrollToID } from "../../utils"; | |||||
import { scrollToID } from '../../utils'; | |||||
Vue.use(Toast); | Vue.use(Toast); | ||||
export default { | export default { | ||||
@@ -115,18 +115,18 @@ export default { | |||||
data() { | data() { | ||||
return { | return { | ||||
inPage: false, | inPage: false, | ||||
PersonButtonAction: false,//个人按钮状态 | |||||
CameraAction:false,// 摄像头按钮状态 | |||||
CloseChatAction:false,// 聊天框按钮状态 | |||||
GlobalAction:false,// 语音按钮状态 | |||||
PersonButtonAction: false, //个人按钮状态 | |||||
CameraAction: false, // 摄像头按钮状态 | |||||
CloseChatAction: false, // 聊天框按钮状态 | |||||
GlobalAction: false, // 语音按钮状态 | |||||
// speakingAction: false, // 底部是否说话按钮状态 | // speakingAction: false, // 底部是否说话按钮状态 | ||||
modelList: [ | modelList: [ | ||||
{ name:'甘雨',url:require('../../assets/img/module_3_1.png')}, | |||||
{ name:'莫甘娜',url:require('../../assets/img/module_3_1.png')}, | |||||
{ name:'达尔文',url:require('../../assets/img/module_3_1.png')}, | |||||
{ name:'雨果',url:require('../../assets/img/module_3_1.png')}, | |||||
],// 人物模板列表 | |||||
modelItemAction: -1,// 人物模板列表选中高亮 | |||||
// { name:'甘雨',url:require('../../assets/img/module_3_1.png')}, | |||||
// { name:'莫甘娜',url:require('../../assets/img/module_3_1.png')}, | |||||
// { name:'达尔文',url:require('../../assets/img/module_3_1.png')}, | |||||
// { name:'雨果',url:require('../../assets/img/module_3_1.png')}, | |||||
], // 人物模板列表 | |||||
modelItemAction: -1, // 人物模板列表选中高亮 | |||||
chatRecordList: [ | chatRecordList: [ | ||||
{ form: 'me', message: '生于忧患死于安乐1生于忧患死于安乐1生于忧患死于安乐1生于忧患死于安乐1生于忧患死于安乐1' }, | { form: 'me', message: '生于忧患死于安乐1生于忧患死于安乐1生于忧患死于安乐1生于忧患死于安乐1生于忧患死于安乐1' }, | ||||
{ form: 'you', message: '生于忧患死于安乐2' }, | { form: 'you', message: '生于忧患死于安乐2' }, | ||||
@@ -134,59 +134,49 @@ export default { | |||||
{ form: 'you', message: '生于忧患死于安乐4' }, | { form: 'you', message: '生于忧患死于安乐4' }, | ||||
{ form: 'me', message: '生于忧患死于安乐5' }, | { form: 'me', message: '生于忧患死于安乐5' }, | ||||
{ form: 'me', message: '生于忧患死于安乐6' }, | { form: 'me', message: '生于忧患死于安乐6' }, | ||||
{ form: 'me', message: '生于忧患死于安乐7' }, | |||||
],// 聊天记录列表 | |||||
languageList: [ | |||||
{type:'AUTO'}, | |||||
{type:'璃月语'}, | |||||
{type:'JP语'}, | |||||
{type:'english'}, | |||||
{type:'中国话'}, | |||||
{type:'四川话'}, | |||||
{type:'东百话'}, | |||||
{type:'阿拉伯语'}, | |||||
{type:'朝鲜语'}, | |||||
], //语种列表 | |||||
{ form: 'me', message: '生于忧患死于安乐7' } | |||||
], // 聊天记录列表 | |||||
languageList: [{ type: 'AUTO' }, { type: '璃月语' }, { type: 'JP语' }, { type: 'english' }, { type: '中国话' }, { type: '四川话' }, { type: '东百话' }, { type: '阿拉伯语' }, { type: '朝鲜语' }] //语种列表 | |||||
}; | }; | ||||
}, | }, | ||||
computed: { | computed: { | ||||
...mapState({ | ...mapState({ | ||||
characters: (state) => state.publicObj.characters, | |||||
}), | |||||
characters: state => state.publicObj.characters | |||||
}) | |||||
}, | }, | ||||
methods: { | methods: { | ||||
...mapActions(["setCharacters"]), | |||||
...mapActions(['setCharacters']), | |||||
// 点击个人按钮事件 | // 点击个人按钮事件 | ||||
clickPersonButton() { | clickPersonButton() { | ||||
this.PersonButtonAction=!this.PersonButtonAction | |||||
this.PersonButtonAction = !this.PersonButtonAction; | |||||
}, | }, | ||||
// 点击摄像头按钮事件 | // 点击摄像头按钮事件 | ||||
clickCameraButton() { | clickCameraButton() { | ||||
this.CameraAction=!this.CameraAction | |||||
this.CameraAction = !this.CameraAction; | |||||
}, | }, | ||||
// 点击聊天框按钮事件 | // 点击聊天框按钮事件 | ||||
clickCloseChatButton() { | clickCloseChatButton() { | ||||
this.CloseChatAction=!this.CloseChatAction | |||||
this.CloseChatAction = !this.CloseChatAction; | |||||
}, | }, | ||||
// 点击语音按钮事件 | // 点击语音按钮事件 | ||||
clickGlobalButton() { | clickGlobalButton() { | ||||
this.GlobalAction=!this.GlobalAction | |||||
}, | |||||
this.GlobalAction = !this.GlobalAction; | |||||
}, | |||||
// 往聊天记录里添加内容 | // 往聊天记录里添加内容 | ||||
addMessageRecord(data) { | addMessageRecord(data) { | ||||
console.log(data); | console.log(data); | ||||
this.chatRecordList.push(data) | |||||
this.chatRecordList.push(data); | |||||
}, | }, | ||||
go(url) { | go(url) { | ||||
this.$router.push(url); | this.$router.push(url); | ||||
}, | |||||
} | |||||
}, | }, | ||||
created() {}, | created() {}, | ||||
mounted() { | mounted() { | ||||
this.inPage = true; | this.inPage = true; | ||||
scrollToID("top"); | |||||
}, | |||||
scrollToID('top'); | |||||
} | |||||
}; | }; | ||||
</script> | </script> | ||||
@@ -201,12 +191,11 @@ export default { | |||||
} | } | ||||
} | } | ||||
.contnet { | .contnet { | ||||
.head { | .head { | ||||
display: flex; | display: flex; | ||||
justify-content: space-between; | justify-content: space-between; | ||||
padding: 4px 10px; | padding: 4px 10px; | ||||
>img { | |||||
> img { | |||||
width: 36px; | width: 36px; | ||||
height: 36px; | height: 36px; | ||||
} | } | ||||
@@ -216,11 +205,11 @@ export default { | |||||
height: 28px; | height: 28px; | ||||
text-align: center; | text-align: center; | ||||
line-height: 28px; | line-height: 28px; | ||||
background: #24A9FF; | |||||
background: #24a9ff; | |||||
color: #fff; | color: #fff; | ||||
box-shadow: 0px 2px 4px 0px rgba(0,0,0,0.2); | |||||
box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.2); | |||||
border-radius: 33px; | border-radius: 33px; | ||||
>img { | |||||
> img { | |||||
margin-top: -2px; | margin-top: -2px; | ||||
margin-right: 4px; | margin-right: 4px; | ||||
} | } | ||||
@@ -229,7 +218,7 @@ export default { | |||||
.showBody { | .showBody { | ||||
position: relative; | position: relative; | ||||
width: 100%; | width: 100%; | ||||
height: calc(100vh - 44px) ; | |||||
height: calc(100vh - 44px); | |||||
background-color: red; | background-color: red; | ||||
&-bottom { | &-bottom { | ||||
position: absolute; | position: absolute; | ||||
@@ -237,7 +226,7 @@ export default { | |||||
width: 100%; | width: 100%; | ||||
// height: 150px; | // height: 150px; | ||||
padding-bottom: 33px; | padding-bottom: 33px; | ||||
background: linear-gradient(180deg, rgba(0,0,0,0) 0%, #000000 100%); | |||||
background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, #000000 100%); | |||||
&-buttons { | &-buttons { | ||||
display: flex; | display: flex; | ||||
justify-content: space-evenly; | justify-content: space-evenly; | ||||
@@ -260,7 +249,7 @@ export default { | |||||
align-items: center; | align-items: center; | ||||
width: 44px; | width: 44px; | ||||
height: 44px; | height: 44px; | ||||
background: rgba(0,0,0,0.3); | |||||
background: rgba(0, 0, 0, 0.3); | |||||
border-radius: 22px; | border-radius: 22px; | ||||
img { | img { | ||||
width: 24px; | width: 24px; | ||||
@@ -285,7 +274,7 @@ export default { | |||||
width: 123px; | width: 123px; | ||||
height: 183px; | height: 183px; | ||||
border-radius: 8px; | border-radius: 8px; | ||||
transition: all 0.5s; // | |||||
transition: all 0.5s; // | |||||
border: 3px solid #00ffe1; | border: 3px solid #00ffe1; | ||||
} | } | ||||
.modelName { | .modelName { | ||||
@@ -294,7 +283,7 @@ export default { | |||||
left: 0; | left: 0; | ||||
width: 48px; | width: 48px; | ||||
height: 28px; | height: 28px; | ||||
background: rgba(0,0,0,0.5); | |||||
background: rgba(0, 0, 0, 0.5); | |||||
border-radius: 8px 0px 8px 0px; | border-radius: 8px 0px 8px 0px; | ||||
color: #fff; | color: #fff; | ||||
font-size: 13px; | font-size: 13px; | ||||
@@ -304,10 +293,9 @@ export default { | |||||
img { | img { | ||||
width: 120px; | width: 120px; | ||||
height: 180px; | height: 180px; | ||||
border-radius:8px 5px 5px 8px; | |||||
border-radius: 8px 5px 5px 8px; | |||||
} | } | ||||
} | } | ||||
} | } | ||||
&-myCamera { | &-myCamera { | ||||
position: absolute; | position: absolute; | ||||
@@ -315,7 +303,7 @@ export default { | |||||
right: 0; | right: 0; | ||||
width: 96px; | width: 96px; | ||||
height: 180px; | height: 180px; | ||||
background-image:url(../../assets/img/bg.png); | |||||
background-image: url(../../assets/img/bg.png); | |||||
background-size: contain; | background-size: contain; | ||||
} | } | ||||
&-chatBox { | &-chatBox { | ||||
@@ -323,7 +311,7 @@ export default { | |||||
bottom: 0; | bottom: 0; | ||||
width: 100%; | width: 100%; | ||||
height: 375px; | height: 375px; | ||||
background-color: #ECECEC; | |||||
background-color: #ececec; | |||||
&-close { | &-close { | ||||
padding: 10px 15px; | padding: 10px 15px; | ||||
height: 35px; | height: 35px; | ||||
@@ -347,13 +335,13 @@ export default { | |||||
float: right; | float: right; | ||||
padding: 10px 20px; | padding: 10px 20px; | ||||
margin-bottom: 15px; | margin-bottom: 15px; | ||||
background: #9EE445; | |||||
background: #9ee445; | |||||
border-radius: 20px 20px 2px 20px; | border-radius: 20px 20px 2px 20px; | ||||
clear: both; | clear: both; | ||||
} | } | ||||
.others { | .others { | ||||
float: left; | float: left; | ||||
background: #FFFFFF; | |||||
background: #ffffff; | |||||
border-radius: 20px 20px 20px 2px; | border-radius: 20px 20px 20px 2px; | ||||
} | } | ||||
} | } | ||||
@@ -363,7 +351,7 @@ export default { | |||||
bottom: 0; | bottom: 0; | ||||
width: 100%; | width: 100%; | ||||
height: 385px; | height: 385px; | ||||
background-color: #ECECEC; | |||||
background-color: #ececec; | |||||
&-choose { | &-choose { | ||||
padding: 20px 36px 0; | padding: 20px 36px 0; | ||||
height: 304px; | height: 304px; | ||||
@@ -388,14 +376,14 @@ export default { | |||||
line-height: 70px; | line-height: 70px; | ||||
font-size: 14px; | font-size: 14px; | ||||
color: #333; | color: #333; | ||||
border: 1px solid #ECECEC; | |||||
border: 1px solid #ececec; | |||||
} | } | ||||
} | } | ||||
&-btn { | &-btn { | ||||
display: flex; | display: flex; | ||||
justify-content: space-between; | justify-content: space-between; | ||||
margin-top: 20px; | margin-top: 20px; | ||||
>div { | |||||
> div { | |||||
width: 139px; | width: 139px; | ||||
height: 37px; | height: 37px; | ||||
border-radius: 31px; | border-radius: 31px; | ||||
@@ -406,11 +394,11 @@ export default { | |||||
} | } | ||||
&-no { | &-no { | ||||
color: #333333; | color: #333333; | ||||
background: #FFFFFF; | |||||
background: #ffffff; | |||||
} | } | ||||
&-yes { | &-yes { | ||||
color: #FFFFFF; | |||||
background: #24A9FF; | |||||
color: #ffffff; | |||||
background: #24a9ff; | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -418,10 +406,10 @@ export default { | |||||
} | } | ||||
} | } | ||||
.showBody-modelList::-webkit-scrollbar { | .showBody-modelList::-webkit-scrollbar { | ||||
width:0; | |||||
width: 0; | |||||
} | } | ||||
.showBody-chatBox-record::-webkit-scrollbar { | .showBody-chatBox-record::-webkit-scrollbar { | ||||
width:0; | |||||
width: 0; | |||||
} | } | ||||
.defaultBtn { | .defaultBtn { | ||||
display: flex; | display: flex; | ||||
@@ -430,7 +418,7 @@ export default { | |||||
align-items: center; | align-items: center; | ||||
width: 44px; | width: 44px; | ||||
height: 44px; | height: 44px; | ||||
background: rgba(0,0,0,0.3); | |||||
background: rgba(0, 0, 0, 0.3); | |||||
border-radius: 22px; | border-radius: 22px; | ||||
img { | img { | ||||
width: 24px; | width: 24px; | ||||
@@ -5,9 +5,9 @@ | |||||
<div class="contnet"> | <div class="contnet"> | ||||
<!-- 头部 --> | <!-- 头部 --> | ||||
<div class="head"> | <div class="head"> | ||||
<img src="../../assets/icon/icon-loginout.png" alt=""> | |||||
<img src="../../assets/icon/icon-loginout.png" alt="" /> | |||||
<div class="head-exit"> | <div class="head-exit"> | ||||
<img src="../../assets/icon/icon-loginoutwhite.png" alt=""> | |||||
<img src="../../assets/icon/icon-loginoutwhite.png" alt="" /> | |||||
退出聊天 | 退出聊天 | ||||
</div> | </div> | ||||
</div> | </div> | ||||
@@ -17,40 +17,41 @@ | |||||
<div class="showBody-bottom"> | <div class="showBody-bottom"> | ||||
<!-- 更换人物模板列表 --> | <!-- 更换人物模板列表 --> | ||||
<div v-show="PersonButtonAction" class="showBody-modelList"> | <div v-show="PersonButtonAction" class="showBody-modelList"> | ||||
<div v-for="item,index in modelList" :key="item.name" class="showBody-modelList-item" @click="modelItemAction=index"> | |||||
<div class="modelName">{{ item.name }} | |||||
<div v-show="modelItemAction==index" class="showBody-modelList-item-boxBorder"></div> | |||||
<div v-for="(item, index) in modelList" :key="item.name" class="showBody-modelList-item" @click="modelItemAction = index"> | |||||
<div class="modelName"> | |||||
{{ item.name }} | |||||
<div v-show="modelItemAction == index" class="showBody-modelList-item-boxBorder"></div> | |||||
</div> | |||||
<img :src="item.url" alt="" /> | |||||
</div> | </div> | ||||
<img :src="item.url" alt=""> | |||||
</div> | |||||
</div> | </div> | ||||
<!-- 四大按钮 --> | <!-- 四大按钮 --> | ||||
<div class="showBody-bottom-buttons"> | <div class="showBody-bottom-buttons"> | ||||
<!-- --> | <!-- --> | ||||
<div class="showBody-bottom-buttons-item"> | <div class="showBody-bottom-buttons-item"> | ||||
<div :class="{'buleBtn':PersonButtonAction}" class="defaultBtn" @click="clickPersonButton"> | |||||
<img src="@/assets/icon/icon-person.png" alt=""> | |||||
<div :class="{ buleBtn: PersonButtonAction }" class="defaultBtn" @click="clickPersonButton"> | |||||
<img src="@/assets/icon/icon-person.png" alt="" /> | |||||
</div> | </div> | ||||
<p>更换人物模板</p> | <p>更换人物模板</p> | ||||
</div> | </div> | ||||
<!-- --> | <!-- --> | ||||
<div class="showBody-bottom-buttons-item"> | <div class="showBody-bottom-buttons-item"> | ||||
<div :class="{'buleBtn':CameraAction}" class="defaultBtn" @click="clickCameraButton"> | |||||
<img src="@/assets/icon/icon-openCamera.png" alt=""> | |||||
<div :class="{ buleBtn: CameraAction }" class="defaultBtn" @click="clickCameraButton"> | |||||
<img src="@/assets/icon/icon-openCamera.png" alt="" /> | |||||
</div> | </div> | ||||
<p>摄像头开启</p> | <p>摄像头开启</p> | ||||
</div> | </div> | ||||
<!-- --> | <!-- --> | ||||
<div class="showBody-bottom-buttons-item"> | <div class="showBody-bottom-buttons-item"> | ||||
<div :class="{'buleBtn':CloseChatAction}" class="defaultBtn" @click="clickCloseChatButton"> | |||||
<img src="@/assets/icon/icon-closeChat.png" alt=""> | |||||
<div :class="{ buleBtn: CloseChatAction }" class="defaultBtn" @click="clickCloseChatButton"> | |||||
<img src="@/assets/icon/icon-closeChat.png" alt="" /> | |||||
</div> | </div> | ||||
<p>对话框关闭</p> | <p>对话框关闭</p> | ||||
</div> | </div> | ||||
<!-- --> | <!-- --> | ||||
<div class="showBody-bottom-buttons-item"> | <div class="showBody-bottom-buttons-item"> | ||||
<div :class="{'buleBtn':GlobalAction}" class="defaultBtn" @click="clickGlobalButton"> | |||||
<img src="@/assets/icon/icon-global.png" alt=""> | |||||
<div :class="{ buleBtn: GlobalAction }" class="defaultBtn" @click="clickGlobalButton"> | |||||
<img src="@/assets/icon/icon-global.png" alt="" /> | |||||
</div> | </div> | ||||
<p>选择对话语言</p> | <p>选择对话语言</p> | ||||
</div> | </div> | ||||
@@ -59,13 +60,13 @@ | |||||
<div class="showBody-bottom-speakDiv"> | <div class="showBody-bottom-speakDiv"> | ||||
<!-- 没点麦克风 --> | <!-- 没点麦克风 --> | ||||
<div v-show="!speakingAction" class="showBody-bottom-speakDiv-text">点击语音按钮,快来跟我对话吧!</div> | <div v-show="!speakingAction" class="showBody-bottom-speakDiv-text">点击语音按钮,快来跟我对话吧!</div> | ||||
<div @click="speakingAction=!speakingAction" v-show="!speakingAction" class="defaultBtn buleBtn"> | |||||
<img src="../../assets/icon/icon-microphone2.png" alt=""> | |||||
<div @click="speakingAction = !speakingAction" v-show="!speakingAction" class="defaultBtn buleBtn"> | |||||
<img src="../../assets/icon/icon-microphone2.png" alt="" /> | |||||
</div> | </div> | ||||
<!-- 点了麦克风 --> | <!-- 点了麦克风 --> | ||||
<div v-show="speakingAction" class="showBody-bottom-speakDiv-text whiteDiv">按住说话</div> | <div v-show="speakingAction" class="showBody-bottom-speakDiv-text whiteDiv">按住说话</div> | ||||
<div @click="speakingAction=!speakingAction" v-show="speakingAction" class="defaultBtn buleBtn"> | |||||
<img src="../../assets/icon/icon-speaking.png" alt=""> | |||||
<div @click="speakingAction = !speakingAction" v-show="speakingAction" class="defaultBtn buleBtn"> | |||||
<img src="../../assets/icon/icon-speaking.png" alt="" /> | |||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
@@ -75,26 +76,25 @@ | |||||
<div v-show="CloseChatAction" class="showBody-chatBox"> | <div v-show="CloseChatAction" class="showBody-chatBox"> | ||||
<!-- 关闭 --> | <!-- 关闭 --> | ||||
<div class="showBody-chatBox-close"> | <div class="showBody-chatBox-close"> | ||||
<i @click="CloseChatAction=false" class="el-icon-close"></i> | |||||
<i @click="CloseChatAction = false" class="el-icon-close"></i> | |||||
</div> | </div> | ||||
<!-- 聊天记录 --> | <!-- 聊天记录 --> | ||||
<div class="showBody-chatBox-record"> | <div class="showBody-chatBox-record"> | ||||
<div class="showBody-chatBox-record-my" :class="{'others':item.form!='me'}" v-for="item,index in chatRecordList" :key="index"> | |||||
<div class="showBody-chatBox-record-my" :class="{ others: item.form != 'me' }" v-for="(item, index) in chatRecordList" :key="index"> | |||||
<span>{{ item.message }}</span> | <span>{{ item.message }}</span> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<!-- 底部说话按钮 --> | <!-- 底部说话按钮 --> | ||||
<div class="showBody-bottom-speakDiv"> | <div class="showBody-bottom-speakDiv"> | ||||
<!-- 没点麦克风 --> | <!-- 没点麦克风 --> | ||||
<div v-show="!speakingAction" class="showBody-bottom-speakDiv-text">点击语音按钮,快来跟我对话吧!</div> | <div v-show="!speakingAction" class="showBody-bottom-speakDiv-text">点击语音按钮,快来跟我对话吧!</div> | ||||
<div @click="speakingAction=!speakingAction" v-show="!speakingAction" class="defaultBtn buleBtn"> | |||||
<img src="../../assets/icon/icon-microphone2.png" alt=""> | |||||
<div @click="speakingAction = !speakingAction" v-show="!speakingAction" class="defaultBtn buleBtn"> | |||||
<img src="../../assets/icon/icon-microphone2.png" alt="" /> | |||||
</div> | </div> | ||||
<!-- 点了麦克风 --> | <!-- 点了麦克风 --> | ||||
<div v-show="speakingAction" class="showBody-bottom-speakDiv-text">按住说话</div> | <div v-show="speakingAction" class="showBody-bottom-speakDiv-text">按住说话</div> | ||||
<div @click="speakingAction=!speakingAction" v-show="speakingAction" class="defaultBtn buleBtn"> | |||||
<img src="../../assets/icon/icon-speaking.png" alt=""> | |||||
<div @click="speakingAction = !speakingAction" v-show="speakingAction" class="defaultBtn buleBtn"> | |||||
<img src="../../assets/icon/icon-speaking.png" alt="" /> | |||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
@@ -104,25 +104,25 @@ | |||||
<div class="showBody-global-choose"> | <div class="showBody-global-choose"> | ||||
<div class="showBody-global-choose-language"> | <div class="showBody-global-choose-language"> | ||||
<div class="showBody-global-choose-language-item" v-for="item in languageList" :key="item.type"> | <div class="showBody-global-choose-language-item" v-for="item in languageList" :key="item.type"> | ||||
{{ item.type }} | |||||
{{ item.type }} | |||||
</div> | </div> | ||||
</div> | </div> | ||||
<div class="showBody-global-choose-btn"> | <div class="showBody-global-choose-btn"> | ||||
<div @click="GlobalAction=false" class="showBody-global-choose-btn-no">取消</div> | |||||
<div @click="GlobalAction = false" class="showBody-global-choose-btn-no">取消</div> | |||||
<div class="showBody-global-choose-btn-yes">确定</div> | <div class="showBody-global-choose-btn-yes">确定</div> | ||||
</div> | </div> | ||||
</div> | |||||
</div> | |||||
<!-- 底部说话按钮 --> | <!-- 底部说话按钮 --> | ||||
<div class="showBody-bottom-speakDiv"> | <div class="showBody-bottom-speakDiv"> | ||||
<!-- 没点麦克风 --> | <!-- 没点麦克风 --> | ||||
<div v-show="!speakingAction" class="showBody-bottom-speakDiv-text">点击语音按钮,快来跟我对话吧!</div> | <div v-show="!speakingAction" class="showBody-bottom-speakDiv-text">点击语音按钮,快来跟我对话吧!</div> | ||||
<div @click="speakingAction=!speakingAction" v-show="!speakingAction" class="defaultBtn buleBtn"> | |||||
<img src="../../assets/icon/icon-microphone2.png" alt=""> | |||||
<div @click="speakingAction = !speakingAction" v-show="!speakingAction" class="defaultBtn buleBtn"> | |||||
<img src="../../assets/icon/icon-microphone2.png" alt="" /> | |||||
</div> | </div> | ||||
<!-- 点了麦克风 --> | <!-- 点了麦克风 --> | ||||
<div v-show="speakingAction" class="showBody-bottom-speakDiv-text">按住说话</div> | <div v-show="speakingAction" class="showBody-bottom-speakDiv-text">按住说话</div> | ||||
<div @click="speakingAction=!speakingAction" v-show="speakingAction" class="defaultBtn buleBtn"> | |||||
<img src="../../assets/icon/icon-speaking.png" alt=""> | |||||
<div @click="speakingAction = !speakingAction" v-show="speakingAction" class="defaultBtn buleBtn"> | |||||
<img src="../../assets/icon/icon-speaking.png" alt="" /> | |||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
@@ -132,30 +132,29 @@ | |||||
</template> | </template> | ||||
<script> | <script> | ||||
// 组件 | // 组件 | ||||
import Vue from "vue"; | |||||
import { Toast } from "vant"; | |||||
import { mapState, mapActions } from "vuex"; | |||||
import Vue from 'vue'; | |||||
import { Toast } from 'vant'; | |||||
import { mapState, mapActions } from 'vuex'; | |||||
// 工具 | // 工具 | ||||
import { scrollToID } from "../../utils"; | |||||
import { scrollToID } from '../../utils'; | |||||
Vue.use(Toast); | Vue.use(Toast); | ||||
export default { | export default { | ||||
data() { | data() { | ||||
return { | return { | ||||
inPage: false, | inPage: false, | ||||
PersonButtonAction: false,//个人按钮状态 | |||||
CameraAction:false,// 摄像头按钮状态 | |||||
CloseChatAction:false,// 聊天框按钮状态 | |||||
GlobalAction:false,// 语音按钮状态 | |||||
speakingAction: false, // 底部是否说话按钮状态 | |||||
PersonButtonAction: false, //个人按钮状态 | |||||
CameraAction: false, // 摄像头按钮状态 | |||||
CloseChatAction: false, // 聊天框按钮状态 | |||||
GlobalAction: false, // 语音按钮状态 | |||||
speakingAction: false, // 底部是否说话按钮状态 | |||||
modelList: [ | modelList: [ | ||||
{ name:'甘雨',url:require('../../assets/img/module_3_1.png')}, | |||||
{ name:'莫甘娜',url:require('../../assets/img/module_3_1.png')}, | |||||
{ name:'达尔文',url:require('../../assets/img/module_3_1.png')}, | |||||
{ name:'雨果',url:require('../../assets/img/module_3_1.png')}, | |||||
],// 人物模板列表 | |||||
modelItemAction: -1,// 人物模板列表选中高亮 | |||||
// { name:'甘雨',url:require('../../assets/img/module_3_1.png')}, | |||||
// { name:'莫甘娜',url:require('../../assets/img/module_3_1.png')}, | |||||
// { name:'达尔文',url:require('../../assets/img/module_3_1.png')}, | |||||
// { name:'雨果',url:require('../../assets/img/module_3_1.png')}, | |||||
], // 人物模板列表 | |||||
modelItemAction: -1, // 人物模板列表选中高亮 | |||||
chatRecordList: [ | chatRecordList: [ | ||||
{ form: 'me', message: '生于忧患死于安乐1生于忧患死于安乐1生于忧患死于安乐1生于忧患死于安乐1生于忧患死于安乐1' }, | { form: 'me', message: '生于忧患死于安乐1生于忧患死于安乐1生于忧患死于安乐1生于忧患死于安乐1生于忧患死于安乐1' }, | ||||
{ form: 'you', message: '生于忧患死于安乐2' }, | { form: 'you', message: '生于忧患死于安乐2' }, | ||||
@@ -163,54 +162,44 @@ export default { | |||||
{ form: 'you', message: '生于忧患死于安乐4' }, | { form: 'you', message: '生于忧患死于安乐4' }, | ||||
{ form: 'me', message: '生于忧患死于安乐5' }, | { form: 'me', message: '生于忧患死于安乐5' }, | ||||
{ form: 'me', message: '生于忧患死于安乐6' }, | { form: 'me', message: '生于忧患死于安乐6' }, | ||||
{ form: 'me', message: '生于忧患死于安乐7' }, | |||||
],// 聊天记录列表 | |||||
languageList: [ | |||||
{type:'AUTO'}, | |||||
{type:'璃月语'}, | |||||
{type:'JP语'}, | |||||
{type:'english'}, | |||||
{type:'中国话'}, | |||||
{type:'四川话'}, | |||||
{type:'东百话'}, | |||||
{type:'阿拉伯语'}, | |||||
{type:'朝鲜语'}, | |||||
], //语种列表 | |||||
{ form: 'me', message: '生于忧患死于安乐7' } | |||||
], // 聊天记录列表 | |||||
languageList: [{ type: 'AUTO' }, { type: '璃月语' }, { type: 'JP语' }, { type: 'english' }, { type: '中国话' }, { type: '四川话' }, { type: '东百话' }, { type: '阿拉伯语' }, { type: '朝鲜语' }] //语种列表 | |||||
}; | }; | ||||
}, | }, | ||||
computed: { | computed: { | ||||
...mapState({ | ...mapState({ | ||||
characters: (state) => state.publicObj.characters, | |||||
}), | |||||
characters: state => state.publicObj.characters | |||||
}) | |||||
}, | }, | ||||
methods: { | methods: { | ||||
...mapActions(["setCharacters"]), | |||||
...mapActions(['setCharacters']), | |||||
// 点击个人按钮事件 | // 点击个人按钮事件 | ||||
clickPersonButton() { | clickPersonButton() { | ||||
this.PersonButtonAction=!this.PersonButtonAction | |||||
this.PersonButtonAction = !this.PersonButtonAction; | |||||
}, | }, | ||||
// 点击摄像头按钮事件 | // 点击摄像头按钮事件 | ||||
clickCameraButton() { | clickCameraButton() { | ||||
this.CameraAction=!this.CameraAction | |||||
this.CameraAction = !this.CameraAction; | |||||
}, | }, | ||||
// 点击聊天框按钮事件 | // 点击聊天框按钮事件 | ||||
clickCloseChatButton() { | clickCloseChatButton() { | ||||
this.CloseChatAction=!this.CloseChatAction | |||||
this.CloseChatAction = !this.CloseChatAction; | |||||
}, | }, | ||||
// 点击语音按钮事件 | // 点击语音按钮事件 | ||||
clickGlobalButton() { | clickGlobalButton() { | ||||
this.GlobalAction=!this.GlobalAction | |||||
}, | |||||
this.GlobalAction = !this.GlobalAction; | |||||
}, | |||||
go(url) { | go(url) { | ||||
this.$router.push(url); | this.$router.push(url); | ||||
}, | |||||
} | |||||
}, | }, | ||||
created() {}, | created() {}, | ||||
mounted() { | mounted() { | ||||
this.inPage = true; | this.inPage = true; | ||||
scrollToID("top"); | |||||
}, | |||||
scrollToID('top'); | |||||
} | |||||
}; | }; | ||||
</script> | </script> | ||||
@@ -225,12 +214,11 @@ export default { | |||||
} | } | ||||
} | } | ||||
.contnet { | .contnet { | ||||
.head { | .head { | ||||
display: flex; | display: flex; | ||||
justify-content: space-between; | justify-content: space-between; | ||||
padding: 4px 10px; | padding: 4px 10px; | ||||
>img { | |||||
> img { | |||||
width: 36px; | width: 36px; | ||||
height: 36px; | height: 36px; | ||||
} | } | ||||
@@ -240,11 +228,11 @@ export default { | |||||
height: 28px; | height: 28px; | ||||
text-align: center; | text-align: center; | ||||
line-height: 28px; | line-height: 28px; | ||||
background: #24A9FF; | |||||
background: #24a9ff; | |||||
color: #fff; | color: #fff; | ||||
box-shadow: 0px 2px 4px 0px rgba(0,0,0,0.2); | |||||
box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.2); | |||||
border-radius: 33px; | border-radius: 33px; | ||||
>img { | |||||
> img { | |||||
margin-top: -2px; | margin-top: -2px; | ||||
margin-right: 4px; | margin-right: 4px; | ||||
} | } | ||||
@@ -253,7 +241,7 @@ export default { | |||||
.showBody { | .showBody { | ||||
position: relative; | position: relative; | ||||
width: 100%; | width: 100%; | ||||
height: calc(100vh - 44px) ; | |||||
height: calc(100vh - 44px); | |||||
background-color: red; | background-color: red; | ||||
&-bottom { | &-bottom { | ||||
position: absolute; | position: absolute; | ||||
@@ -261,7 +249,7 @@ export default { | |||||
width: 100%; | width: 100%; | ||||
// height: 150px; | // height: 150px; | ||||
padding-bottom: 33px; | padding-bottom: 33px; | ||||
background: linear-gradient(180deg, rgba(0,0,0,0) 0%, #000000 100%); | |||||
background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, #000000 100%); | |||||
&-buttons { | &-buttons { | ||||
display: flex; | display: flex; | ||||
justify-content: space-evenly; | justify-content: space-evenly; | ||||
@@ -284,7 +272,7 @@ export default { | |||||
align-items: center; | align-items: center; | ||||
width: 44px; | width: 44px; | ||||
height: 44px; | height: 44px; | ||||
background: rgba(0,0,0,0.3); | |||||
background: rgba(0, 0, 0, 0.3); | |||||
border-radius: 22px; | border-radius: 22px; | ||||
img { | img { | ||||
width: 24px; | width: 24px; | ||||
@@ -301,9 +289,9 @@ export default { | |||||
width: 290px; | width: 290px; | ||||
height: 36px; | height: 36px; | ||||
border-radius: 18px; | border-radius: 18px; | ||||
border: 1px solid #FFFFFF; | |||||
border: 1px solid #ffffff; | |||||
font-size: 14px; | font-size: 14px; | ||||
color: #FFFFFF; | |||||
color: #ffffff; | |||||
text-align: center; | text-align: center; | ||||
line-height: 34px; | line-height: 34px; | ||||
} | } | ||||
@@ -330,7 +318,7 @@ export default { | |||||
width: 123px; | width: 123px; | ||||
height: 183px; | height: 183px; | ||||
border-radius: 8px; | border-radius: 8px; | ||||
transition: all 0.5s; // | |||||
transition: all 0.5s; // | |||||
border: 3px solid #00ffe1; | border: 3px solid #00ffe1; | ||||
} | } | ||||
.modelName { | .modelName { | ||||
@@ -339,7 +327,7 @@ export default { | |||||
left: 0; | left: 0; | ||||
width: 48px; | width: 48px; | ||||
height: 28px; | height: 28px; | ||||
background: rgba(0,0,0,0.5); | |||||
background: rgba(0, 0, 0, 0.5); | |||||
border-radius: 8px 0px 8px 0px; | border-radius: 8px 0px 8px 0px; | ||||
color: #fff; | color: #fff; | ||||
font-size: 13px; | font-size: 13px; | ||||
@@ -349,10 +337,9 @@ export default { | |||||
img { | img { | ||||
width: 120px; | width: 120px; | ||||
height: 180px; | height: 180px; | ||||
border-radius:8px 5px 5px 8px; | |||||
border-radius: 8px 5px 5px 8px; | |||||
} | } | ||||
} | } | ||||
} | } | ||||
&-myCamera { | &-myCamera { | ||||
position: absolute; | position: absolute; | ||||
@@ -360,7 +347,7 @@ export default { | |||||
right: 0; | right: 0; | ||||
width: 96px; | width: 96px; | ||||
height: 180px; | height: 180px; | ||||
background-image:url(../../assets/img/bg.png); | |||||
background-image: url(../../assets/img/bg.png); | |||||
background-size: contain; | background-size: contain; | ||||
} | } | ||||
&-chatBox { | &-chatBox { | ||||
@@ -368,7 +355,7 @@ export default { | |||||
bottom: 0; | bottom: 0; | ||||
width: 100%; | width: 100%; | ||||
height: 375px; | height: 375px; | ||||
background-color: #ECECEC; | |||||
background-color: #ececec; | |||||
&-close { | &-close { | ||||
padding: 10px 15px; | padding: 10px 15px; | ||||
height: 35px; | height: 35px; | ||||
@@ -392,13 +379,13 @@ export default { | |||||
float: right; | float: right; | ||||
padding: 10px 20px; | padding: 10px 20px; | ||||
margin-bottom: 15px; | margin-bottom: 15px; | ||||
background: #9EE445; | |||||
background: #9ee445; | |||||
border-radius: 20px 20px 2px 20px; | border-radius: 20px 20px 2px 20px; | ||||
clear: both; | clear: both; | ||||
} | } | ||||
.others { | .others { | ||||
float: left; | float: left; | ||||
background: #FFFFFF; | |||||
background: #ffffff; | |||||
border-radius: 20px 20px 20px 2px; | border-radius: 20px 20px 20px 2px; | ||||
} | } | ||||
} | } | ||||
@@ -419,7 +406,7 @@ export default { | |||||
bottom: 0; | bottom: 0; | ||||
width: 100%; | width: 100%; | ||||
height: 385px; | height: 385px; | ||||
background-color: #ECECEC; | |||||
background-color: #ececec; | |||||
&-choose { | &-choose { | ||||
padding: 20px 36px 0; | padding: 20px 36px 0; | ||||
height: 304px; | height: 304px; | ||||
@@ -444,14 +431,14 @@ export default { | |||||
line-height: 70px; | line-height: 70px; | ||||
font-size: 14px; | font-size: 14px; | ||||
color: #333; | color: #333; | ||||
border: 1px solid #ECECEC; | |||||
border: 1px solid #ececec; | |||||
} | } | ||||
} | } | ||||
&-btn { | &-btn { | ||||
display: flex; | display: flex; | ||||
justify-content: space-between; | justify-content: space-between; | ||||
margin-top: 20px; | margin-top: 20px; | ||||
>div { | |||||
> div { | |||||
width: 139px; | width: 139px; | ||||
height: 37px; | height: 37px; | ||||
border-radius: 31px; | border-radius: 31px; | ||||
@@ -462,11 +449,11 @@ export default { | |||||
} | } | ||||
&-no { | &-no { | ||||
color: #333333; | color: #333333; | ||||
background: #FFFFFF; | |||||
background: #ffffff; | |||||
} | } | ||||
&-yes { | &-yes { | ||||
color: #FFFFFF; | |||||
background: #24A9FF; | |||||
color: #ffffff; | |||||
background: #24a9ff; | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -485,10 +472,10 @@ export default { | |||||
} | } | ||||
} | } | ||||
.showBody-modelList::-webkit-scrollbar { | .showBody-modelList::-webkit-scrollbar { | ||||
width:0; | |||||
width: 0; | |||||
} | } | ||||
.showBody-chatBox-record::-webkit-scrollbar { | .showBody-chatBox-record::-webkit-scrollbar { | ||||
width:0; | |||||
width: 0; | |||||
} | } | ||||
.defaultBtn { | .defaultBtn { | ||||
display: flex; | display: flex; | ||||
@@ -497,7 +484,7 @@ export default { | |||||
align-items: center; | align-items: center; | ||||
width: 44px; | width: 44px; | ||||
height: 44px; | height: 44px; | ||||
background: rgba(0,0,0,0.3); | |||||
background: rgba(0, 0, 0, 0.3); | |||||
border-radius: 22px; | border-radius: 22px; | ||||
img { | img { | ||||
width: 24px; | width: 24px; | ||||
@@ -191,10 +191,10 @@ export default { | |||||
GlobalAction: false, // 选择语言按钮状态 | GlobalAction: false, // 选择语言按钮状态 | ||||
// speakingAction: false, // 底部是否说话按钮状态 | // speakingAction: false, // 底部是否说话按钮状态 | ||||
modelList: [ | modelList: [ | ||||
{ name: "甘雨", url: require("../../assets/img/module_3_1.png") }, | |||||
{ name: "莫甘娜", url: require("../../assets/img/module_3_1.png") }, | |||||
{ name: "达尔文", url: require("../../assets/img/module_3_1.png") }, | |||||
{ name: "雨果", url: require("../../assets/img/module_3_1.png") }, | |||||
// { name: "甘雨", url: require("../../assets/img/module_3_1.png") }, | |||||
// { name: "莫甘娜", url: require("../../assets/img/module_3_1.png") }, | |||||
// { name: "达尔文", url: require("../../assets/img/module_3_1.png") }, | |||||
// { name: "雨果", url: require("../../assets/img/module_3_1.png") }, | |||||
], // 人物模板列表 | ], // 人物模板列表 | ||||
modelItemAction: -1, // 人物模板列表选中高亮 | modelItemAction: -1, // 人物模板列表选中高亮 | ||||
chatRecordList: [ | chatRecordList: [ | ||||
@@ -17,64 +17,40 @@ | |||||
<div class="showBody-bottom"> | <div class="showBody-bottom"> | ||||
<!-- 更换人物模板列表 --> | <!-- 更换人物模板列表 --> | ||||
<div v-show="PersonButtonAction" class="showBody-modelList"> | <div v-show="PersonButtonAction" class="showBody-modelList"> | ||||
<div | |||||
v-for="(item, index) in modelList" | |||||
:key="item.name" | |||||
class="showBody-modelList-item" | |||||
@click="modelItemAction = index" | |||||
> | |||||
<div v-for="(item, index) in modelList" :key="item.name" class="showBody-modelList-item" @click="modelItemAction = index"> | |||||
<div class="modelName"> | <div class="modelName"> | ||||
{{ item.name }} | {{ item.name }} | ||||
<div | |||||
v-show="modelItemAction == index" | |||||
class="showBody-modelList-item-boxBorder" | |||||
></div> | |||||
<div v-show="modelItemAction == index" class="showBody-modelList-item-boxBorder"></div> | |||||
</div> | </div> | ||||
<img :src="item.url" alt="" /> | <img :src="item.url" alt="" /> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<!-- 四大按钮 --> | <!-- 四大按钮 --> | ||||
<div v-show="!CloseChatAction&&!GlobalAction" class="showBody-bottom-buttons"> | |||||
<div v-show="!CloseChatAction && !GlobalAction" class="showBody-bottom-buttons"> | |||||
<!-- --> | <!-- --> | ||||
<div class="showBody-bottom-buttons-item"> | <div class="showBody-bottom-buttons-item"> | ||||
<div | |||||
:class="{ buleBtn: PersonButtonAction }" | |||||
class="defaultBtn" | |||||
@click="clickPersonButton" | |||||
> | |||||
<div :class="{ buleBtn: PersonButtonAction }" class="defaultBtn" @click="clickPersonButton"> | |||||
<img src="@/assets/icon/icon-person.png" alt="" /> | <img src="@/assets/icon/icon-person.png" alt="" /> | ||||
</div> | </div> | ||||
<p>更换人物模板</p> | <p>更换人物模板</p> | ||||
</div> | </div> | ||||
<!-- --> | <!-- --> | ||||
<div class="showBody-bottom-buttons-item"> | <div class="showBody-bottom-buttons-item"> | ||||
<div | |||||
:class="{ buleBtn: CameraAction }" | |||||
class="defaultBtn" | |||||
@click="clickCameraButton" | |||||
> | |||||
<div :class="{ buleBtn: CameraAction }" class="defaultBtn" @click="clickCameraButton"> | |||||
<img src="@/assets/icon/icon-openCamera.png" alt="" /> | <img src="@/assets/icon/icon-openCamera.png" alt="" /> | ||||
</div> | </div> | ||||
<p>摄像头开启</p> | <p>摄像头开启</p> | ||||
</div> | </div> | ||||
<!-- --> | <!-- --> | ||||
<div class="showBody-bottom-buttons-item"> | <div class="showBody-bottom-buttons-item"> | ||||
<div | |||||
:class="{ buleBtn: CloseChatAction }" | |||||
class="defaultBtn" | |||||
@click="clickCloseChatButton" | |||||
> | |||||
<div :class="{ buleBtn: CloseChatAction }" class="defaultBtn" @click="clickCloseChatButton"> | |||||
<img src="@/assets/icon/icon-closeChat.png" alt="" /> | <img src="@/assets/icon/icon-closeChat.png" alt="" /> | ||||
</div> | </div> | ||||
<p>对话框关闭</p> | <p>对话框关闭</p> | ||||
</div> | </div> | ||||
<!-- --> | <!-- --> | ||||
<div class="showBody-bottom-buttons-item"> | <div class="showBody-bottom-buttons-item"> | ||||
<div | |||||
:class="{ buleBtn: GlobalAction }" | |||||
class="defaultBtn" | |||||
@click="clickGlobalButton" | |||||
> | |||||
<div :class="{ buleBtn: GlobalAction }" class="defaultBtn" @click="clickGlobalButton"> | |||||
<img src="@/assets/icon/icon-global.png" alt="" /> | <img src="@/assets/icon/icon-global.png" alt="" /> | ||||
</div> | </div> | ||||
<p>选择对话语言</p> | <p>选择对话语言</p> | ||||
@@ -88,12 +64,7 @@ | |||||
</div> | </div> | ||||
<!-- 聊天记录 --> | <!-- 聊天记录 --> | ||||
<div ref="recordBox" class="showBody-chatBox-record"> | <div ref="recordBox" class="showBody-chatBox-record"> | ||||
<div | |||||
class="showBody-chatBox-record-my" | |||||
:class="{ others: item.form != 'me' }" | |||||
v-for="(item, index) in chatRecordList" | |||||
:key="index" | |||||
> | |||||
<div class="showBody-chatBox-record-my" :class="{ others: item.form != 'me' }" v-for="(item, index) in chatRecordList" :key="index"> | |||||
<span>{{ item.message }}</span> | <span>{{ item.message }}</span> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
@@ -103,30 +74,18 @@ | |||||
<!-- --> | <!-- --> | ||||
<div class="showBody-global-choose"> | <div class="showBody-global-choose"> | ||||
<div class="showBody-global-choose-language"> | <div class="showBody-global-choose-language"> | ||||
<div | |||||
class="showBody-global-choose-language-item" | |||||
v-for="item in languageList" | |||||
:key="item.type" | |||||
> | |||||
<div class="showBody-global-choose-language-item" v-for="item in languageList" :key="item.type"> | |||||
{{ item.type }} | {{ item.type }} | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<div class="showBody-global-choose-btn"> | <div class="showBody-global-choose-btn"> | ||||
<div | |||||
@click="GlobalAction = false" | |||||
class="showBody-global-choose-btn-no" | |||||
> | |||||
取消 | |||||
</div> | |||||
<div @click="GlobalAction = false" class="showBody-global-choose-btn-no">取消</div> | |||||
<div class="showBody-global-choose-btn-yes">确定</div> | <div class="showBody-global-choose-btn-yes">确定</div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<!-- 开麦和聊天输入 --> | <!-- 开麦和聊天输入 --> | ||||
<div | |||||
:class="{ chatBoxAction: CloseChatAction || GlobalAction }" | |||||
class="showBody-bottom-speakDiv" | |||||
> | |||||
<div :class="{ chatBoxAction: CloseChatAction || GlobalAction }" class="showBody-bottom-speakDiv"> | |||||
<!-- 没点麦克风 --> | <!-- 没点麦克风 --> | ||||
<el-input | <el-input | ||||
rows="1" | rows="1" | ||||
@@ -137,30 +96,14 @@ | |||||
class="" | class="" | ||||
placeholder="点击语音按钮,快来跟我对话吧" | placeholder="点击语音按钮,快来跟我对话吧" | ||||
v-model="chatInputContent" | v-model="chatInputContent" | ||||
@keydown.enter.native="addMessageRecord()" | |||||
></el-input> | |||||
@keydown.enter.native="addMessageRecord()"></el-input> | |||||
<div | |||||
@click="speakingAction = !speakingAction" | |||||
v-show="!speakingAction" | |||||
class="defaultBtn buleBtn" | |||||
> | |||||
<div @click="speakingAction = !speakingAction" v-show="!speakingAction" class="defaultBtn buleBtn"> | |||||
<img src="@/assets/icon/icon-microphone2.png" alt="" /> | <img src="@/assets/icon/icon-microphone2.png" alt="" /> | ||||
</div> | </div> | ||||
<!-- 点了麦克风 --> | <!-- 点了麦克风 --> | ||||
<div | |||||
v-show="speakingAction" | |||||
class="showBody-bottom-speakDiv-text" | |||||
@mousedown="startRecording" | |||||
@mouseup="stopRecording" | |||||
> | |||||
按住说话 | |||||
</div> | |||||
<div | |||||
@click="speakingAction = !speakingAction" | |||||
v-show="speakingAction" | |||||
class="defaultBtn buleBtn" | |||||
> | |||||
<div v-show="speakingAction" class="showBody-bottom-speakDiv-text" @mousedown="startRecording" @mouseup="stopRecording">按住说话</div> | |||||
<div @click="speakingAction = !speakingAction" v-show="speakingAction" class="defaultBtn buleBtn"> | |||||
<img src="@/assets/icon/icon-speaking.png" alt="" /> | <img src="@/assets/icon/icon-speaking.png" alt="" /> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
@@ -174,11 +117,11 @@ | |||||
<script> | <script> | ||||
// 组件 | // 组件 | ||||
import Vue from "vue"; | |||||
import { Toast } from "vant"; | |||||
import { mapState, mapActions } from "vuex"; | |||||
import Vue from 'vue'; | |||||
import { Toast } from 'vant'; | |||||
import { mapState, mapActions } from 'vuex'; | |||||
// 工具 | // 工具 | ||||
import { scrollToID } from "../../utils"; | |||||
import { scrollToID } from '../../utils'; | |||||
Vue.use(Toast); | Vue.use(Toast); | ||||
export default { | export default { | ||||
@@ -191,51 +134,40 @@ export default { | |||||
GlobalAction: false, // 选择语言按钮状态 | GlobalAction: false, // 选择语言按钮状态 | ||||
// speakingAction: false, // 底部是否说话按钮状态 | // speakingAction: false, // 底部是否说话按钮状态 | ||||
modelList: [ | modelList: [ | ||||
{ name: "甘雨", url: require("../../assets/img/module_3_1.png") }, | |||||
{ name: "莫甘娜", url: require("../../assets/img/module_3_1.png") }, | |||||
{ name: "达尔文", url: require("../../assets/img/module_3_1.png") }, | |||||
{ name: "雨果", url: require("../../assets/img/module_3_1.png") }, | |||||
// { name: "甘雨", url: require("../../assets/img/module_3_1.png") }, | |||||
// { name: "莫甘娜", url: require("../../assets/img/module_3_1.png") }, | |||||
// { name: "达尔文", url: require("../../assets/img/module_3_1.png") }, | |||||
// { name: "雨果", url: require("../../assets/img/module_3_1.png") }, | |||||
], // 人物模板列表 | ], // 人物模板列表 | ||||
modelItemAction: -1, // 人物模板列表选中高亮 | modelItemAction: -1, // 人物模板列表选中高亮 | ||||
chatRecordList: [ | chatRecordList: [ | ||||
{ | { | ||||
form: "me", | |||||
message: | |||||
"生于忧患死于安乐1生于忧患死于安乐1生于忧患死于安乐1生于忧患死于安乐1生于忧患死于安乐1", | |||||
form: 'me', | |||||
message: '生于忧患死于安乐1生于忧患死于安乐1生于忧患死于安乐1生于忧患死于安乐1生于忧患死于安乐1' | |||||
}, | }, | ||||
{ form: "you", message: "生于忧患死于安乐2" }, | |||||
{ form: "me", message: "生于忧患死于安乐3" }, | |||||
{ form: "you", message: "生于忧患死于安乐4" }, | |||||
{ form: "me", message: "生于忧患死于安乐5" }, | |||||
{ form: "me", message: "生于忧患死于安乐6" }, | |||||
{ form: "me", message: " " }, | |||||
{ form: 'you', message: '生于忧患死于安乐2' }, | |||||
{ form: 'me', message: '生于忧患死于安乐3' }, | |||||
{ form: 'you', message: '生于忧患死于安乐4' }, | |||||
{ form: 'me', message: '生于忧患死于安乐5' }, | |||||
{ form: 'me', message: '生于忧患死于安乐6' }, | |||||
{ form: 'me', message: ' ' } | |||||
], // 聊天记录列表 | ], // 聊天记录列表 | ||||
languageList: [ | |||||
{ type: "AUTO" }, | |||||
{ type: "璃月语" }, | |||||
{ type: "JP语" }, | |||||
{ type: "english" }, | |||||
{ type: "中国话" }, | |||||
{ type: "四川话" }, | |||||
{ type: "东百话" }, | |||||
{ type: "阿拉伯语" }, | |||||
{ type: "朝鲜语" }, | |||||
], //语种列表 | |||||
languageList: [{ type: 'AUTO' }, { type: '璃月语' }, { type: 'JP语' }, { type: 'english' }, { type: '中国话' }, { type: '四川话' }, { type: '东百话' }, { type: '阿拉伯语' }, { type: '朝鲜语' }], //语种列表 | |||||
recorder: null, | recorder: null, | ||||
isRecording: false, | isRecording: false, | ||||
audioUrl: null, | audioUrl: null, | ||||
speakingAction: false, // 底部是否说话按钮状态 | speakingAction: false, // 底部是否说话按钮状态 | ||||
chatInputContent: "", // 输入框内容 | |||||
chatInputContent: '' // 输入框内容 | |||||
}; | }; | ||||
}, | }, | ||||
computed: { | computed: { | ||||
...mapState({ | ...mapState({ | ||||
characters: (state) => state.publicObj.characters, | |||||
}), | |||||
characters: state => state.publicObj.characters | |||||
}) | |||||
}, | }, | ||||
methods: { | methods: { | ||||
...mapActions(["setCharacters"]), | |||||
...mapActions(['setCharacters']), | |||||
// 点击个人按钮事件 | // 点击个人按钮事件 | ||||
clickPersonButton() { | clickPersonButton() { | ||||
this.PersonButtonAction = !this.PersonButtonAction; | this.PersonButtonAction = !this.PersonButtonAction; | ||||
@@ -257,10 +189,10 @@ export default { | |||||
if (this.chatInputContent) { | if (this.chatInputContent) { | ||||
console.log(this.chatInputContent); | console.log(this.chatInputContent); | ||||
this.chatRecordList.push({ | this.chatRecordList.push({ | ||||
form: "me", | |||||
message: this.chatInputContent, | |||||
form: 'me', | |||||
message: this.chatInputContent | |||||
}); | }); | ||||
this.chatInputContent = ""; | |||||
this.chatInputContent = ''; | |||||
this.scrollToBottom(); | this.scrollToBottom(); | ||||
} | } | ||||
}, | }, | ||||
@@ -272,7 +204,7 @@ export default { | |||||
scrollElem.scrollTo({ | scrollElem.scrollTo({ | ||||
top: scrollElem.scrollHeight, | top: scrollElem.scrollHeight, | ||||
behavior: "smooth", | |||||
behavior: 'smooth' | |||||
}); | }); | ||||
}); | }); | ||||
}, | }, | ||||
@@ -283,9 +215,9 @@ export default { | |||||
this.recorder | this.recorder | ||||
.start() | .start() | ||||
.then(() => { | .then(() => { | ||||
console.log("Recording started"); | |||||
console.log('Recording started'); | |||||
}) | }) | ||||
.catch((err) => { | |||||
.catch(err => { | |||||
console.log(err); | console.log(err); | ||||
}); | }); | ||||
} | } | ||||
@@ -301,7 +233,7 @@ export default { | |||||
this.audioUrl = URL.createObjectURL(blob); | this.audioUrl = URL.createObjectURL(blob); | ||||
console.log(this.audioUrl); | console.log(this.audioUrl); | ||||
}) | }) | ||||
.catch((err) => { | |||||
.catch(err => { | |||||
console.log(err); | console.log(err); | ||||
}); | }); | ||||
} | } | ||||
@@ -309,14 +241,14 @@ export default { | |||||
go(url) { | go(url) { | ||||
this.$router.push(url); | this.$router.push(url); | ||||
}, | |||||
} | |||||
}, | }, | ||||
created() {}, | created() {}, | ||||
mounted() { | mounted() { | ||||
this.inPage = true; | this.inPage = true; | ||||
scrollToID("top"); | |||||
scrollToID('top'); | |||||
this.scrollToBottom(); | this.scrollToBottom(); | ||||
}, | |||||
} | |||||
}; | }; | ||||
</script> | </script> | ||||
@@ -361,7 +293,6 @@ export default { | |||||
} | } | ||||
} | } | ||||
::v-deep .el-textarea { | ::v-deep .el-textarea { | ||||
padding-top: 5px; | padding-top: 5px; | ||||
margin-right: 10px; | margin-right: 10px; | ||||
@@ -46,8 +46,6 @@ export default { | |||||
id: null, | id: null, | ||||
isAndroid: true, | isAndroid: true, | ||||
baseUrl: null, | baseUrl: null, | ||||
// 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', | |||||
videoSrc: null, //播放地址路径 | videoSrc: null, //播放地址路径 | ||||
videoId: null, //视频ID | videoId: null, //视频ID | ||||
title: null, // 视频名称 | title: null, // 视频名称 | ||||
@@ -1,4 +1,5 @@ | |||||
// const UglifyJsPlugin = require('uglifyjs-webpack-plugin') | // const UglifyJsPlugin = require('uglifyjs-webpack-plugin') | ||||
const CompressionWebpackPlugin = require('compression-webpack-plugin'); | |||||
const path = require('path'); | const path = require('path'); | ||||
const resolve = dir => { | const resolve = dir => { | ||||
return path.join(__dirname, dir) | return path.join(__dirname, dir) | ||||
@@ -7,7 +8,8 @@ let timeStamp = new Date().getTime(); | |||||
let externals = {} | let externals = {} | ||||
let cdn = { css: [], js: [] } | let cdn = { css: [], js: [] } | ||||
const isProduction = process.env.VUE_APP_ENV == 'production' // 判断是否是生产环境 | |||||
// const isProduction = process.env.VUE_APP_ENV == 'production' // 判断是否是生产环境 | |||||
const isProduction = true | |||||
if (isProduction) { | if (isProduction) { | ||||
externals = { | externals = { | ||||
/** | /** | ||||
@@ -17,6 +19,8 @@ if (isProduction) { | |||||
'vue': 'Vue', | 'vue': 'Vue', | ||||
'vant': 'vant', | 'vant': 'vant', | ||||
'element-ui': 'ELEMENT', | 'element-ui': 'ELEMENT', | ||||
'vuex': 'Vuex', | |||||
'vue-router': 'VueRouter', | |||||
} | } | ||||
cdn = { | cdn = { | ||||
css: [ | css: [ | ||||
@@ -27,11 +31,14 @@ if (isProduction) { | |||||
'https://unpkg.com/vue@2.6.12/dist/vue.js', // vuejs | 'https://unpkg.com/vue@2.6.12/dist/vue.js', // vuejs | ||||
'https://unpkg.com/vant@2.12/lib/vant.min.js', //vant | 'https://unpkg.com/vant@2.12/lib/vant.min.js', //vant | ||||
'https://unpkg.com/element-ui/lib/index.js', // element-ui js | 'https://unpkg.com/element-ui/lib/index.js', // element-ui js | ||||
'https://cdn.bootcdn.net/ajax/libs/vuex/4.0.0/vuex.global.min.js',//vuex | |||||
'https://cdn.bootcdn.net/ajax/libs/vue-router/4.0.6/vue-router.global.min.js',//vue-router | |||||
] | ] | ||||
} | } | ||||
} | } | ||||
module.exports = { | module.exports = { | ||||
configureWebpack: { | configureWebpack: { | ||||
output: { // 输出重构 打包编译后的js文件名称,添加时间戳. | output: { // 输出重构 打包编译后的js文件名称,添加时间戳. | ||||
filename: `js/js[name].${timeStamp}.js`, | filename: `js/js[name].${timeStamp}.js`, | ||||
@@ -91,7 +98,8 @@ module.exports = { | |||||
lintOnSave: false, | lintOnSave: false, | ||||
publicPath: './', // 打包后引用的资源路径 | publicPath: './', // 打包后引用的资源路径 | ||||
chainWebpack: config => { | |||||
chainWebpack: config => { | |||||
// favicon图标 | |||||
config.plugin('html').tap(args => { | config.plugin('html').tap(args => { | ||||
args[0].favicon = './public/favicon.ico'; | args[0].favicon = './public/favicon.ico'; | ||||
return args; | return args; | ||||
@@ -102,23 +110,15 @@ module.exports = { | |||||
args[0].cdn = cdn // 配置cdn给插件 | args[0].cdn = cdn // 配置cdn给插件 | ||||
return args | return args | ||||
}) | }) | ||||
config.module | |||||
.rule('svg') | |||||
.exclude.add(resolve('src/icons')) | |||||
.end() | |||||
config.module | |||||
.rule('icons') | |||||
.test(/\.svg$/) | |||||
.include.add(resolve('src/icons')) | |||||
.end() | |||||
.use('svg-sprite-loader') | |||||
.loader('svg-sprite-loader') | |||||
.options({ | |||||
symbolId: 'icon-[name]' | |||||
}) | |||||
.end() | |||||
// 压缩js | |||||
config.plugin('compression-webpack-plugin').use(new CompressionWebpackPlugin({ | |||||
test: /\.(js|css|scss)$/, // 匹配文件名 | |||||
threshold: 20480, // 对超过20k的数据压缩 | |||||
minRatio: 0.8, | |||||
deleteOriginalAssets: true // 删除源文件 | |||||
})) | |||||