Selaa lähdekoodia

Merge branch 'dev'

master
chutingting 1 vuosi sitten
vanhempi
commit
23b6dd85ee
13 muutettua tiedostoa jossa 743 lisäystä ja 278 poistoa
  1. +2
    -2
      README.md
  2. +42
    -42
      package.json
  3. BIN
      src/assets/icon/arrow-down-bold.png
  4. BIN
      src/assets/icon/arrow-up-bold.png
  5. BIN
      src/assets/icon/enter.png
  6. BIN
      src/assets/icon/input.png
  7. BIN
      src/assets/icon/voice.png
  8. BIN
      src/assets/icon/voice_close.png
  9. +157
    -1
      src/components/home/home.vue
  10. +6
    -0
      src/router/index.js
  11. +298
    -0
      src/views/realTimeChat/realTimeChat.vue
  12. +77
    -77
      vue.config.js
  13. +161
    -156
      yarn.lock

+ 2
- 2
README.md Näytä tiedosto

@@ -30,8 +30,8 @@ yarn config set ignore-engines true

### node-sass版本6.0.1

### 测试环境baseURL = 'https://smapitest.malls.iformall.com/C'
### 测试环境baseURL = 'https://mtest.metavatar.cc'

### 正式环境baseURL = 'http://m.metavatar.cc/C'
### 正式环境baseURL = 'https://m.metavatar.cc'

项目根目录下配置有模板vue文件“model.vue”,已配置进入动画、回到顶部等功能,可以此为基础添加页面。

+ 42
- 42
package.json Näytä tiedosto

@@ -1,42 +1,42 @@
{
"name": "Metavatar",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "vue-cli-service serve --mode development",
"build": "vue-cli-service build --mode test",
"build-test": "vue-cli-service build --mode test",
"build-prd": "vue-cli-service build --mode production"
},
"dependencies": {
"axios": "0.18.1",
"element-ui": "^2.15.12",
"file-saver": "^2.0.5",
"franc": "^6.1.0",
"image-webpack-loader": "^8.1.0",
"install": "^0.13.0",
"lib-flexible": "^0.3.2",
"mic-recorder-to-mp3": "^2.2.2",
"postcss-px2rem": "^0.3.0",
"register-service-worker": "^1.7.1",
"swiper": "^4.5.1",
"vant": "^2.12.48",
"vue": "^2.6.11",
"vue-cropper": "^0.5.11",
"vue-router": "^3.2.0",
"vue-waterfall2": "^1.10.6",
"vuex": "^3.4.0"
},
"devDependencies": {
"@vue/cli-plugin-pwa": "~4.5.13",
"@vue/cli-plugin-router": "~4.5.13",
"@vue/cli-plugin-vuex": "~4.5.13",
"@vue/cli-service": "~4.5.13",
"compression-webpack-plugin": "5.0.1",
"node-sass": "^6.0.1",
"sass": "^1.60.0",
"sass-loader": "^7.0.3",
"uglifyjs-webpack-plugin": "^2.2.0",
"vue-template-compiler": "^2.6.11"
}
}
{
"name": "Metavatar",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "vue-cli-service serve --mode development",
"build": "vue-cli-service build --mode test",
"build-test": "vue-cli-service build --mode test",
"build-prd": "vue-cli-service build --mode production"
},
"dependencies": {
"axios": "0.18.1",
"element-ui": "^2.15.12",
"file-saver": "^2.0.5",
"franc": "^6.1.0",
"image-webpack-loader": "^8.1.0",
"install": "^0.13.0",
"lib-flexible": "^0.3.2",
"mic-recorder-to-mp3": "^2.2.2",
"postcss-px2rem": "^0.3.0",
"register-service-worker": "^1.7.1",
"swiper": "^4.5.1",
"vant": "^2.12.48",
"vue": "^2.6.11",
"vue-cropper": "^0.5.11",
"vue-router": "^3.2.0",
"vue-waterfall2": "^1.10.6",
"vuex": "^3.4.0"
},
"devDependencies": {
"@vue/cli-plugin-pwa": "~4.5.13",
"@vue/cli-plugin-router": "~4.5.13",
"@vue/cli-plugin-vuex": "~4.5.13",
"@vue/cli-service": "~4.5.13",
"compression-webpack-plugin": "5.0.1",
"node-sass": "^6.0.1",
"sass": "^1.60.0",
"sass-loader": "^7.0.3",
"uglifyjs-webpack-plugin": "^2.2.0",
"vue-template-compiler": "^2.6.11"
}
}

BIN
src/assets/icon/arrow-down-bold.png Näytä tiedosto

Before After
Leveys: 400  |  Korkeus: 400  |  Koko: 7.6 KiB

BIN
src/assets/icon/arrow-up-bold.png Näytä tiedosto

Before After
Leveys: 400  |  Korkeus: 400  |  Koko: 6.0 KiB

BIN
src/assets/icon/enter.png Näytä tiedosto

Before After
Leveys: 400  |  Korkeus: 400  |  Koko: 8.1 KiB

BIN
src/assets/icon/input.png Näytä tiedosto

Before After
Leveys: 600  |  Korkeus: 600  |  Koko: 12 KiB

BIN
src/assets/icon/voice.png Näytä tiedosto

Before After
Leveys: 400  |  Korkeus: 400  |  Koko: 14 KiB

BIN
src/assets/icon/voice_close.png Näytä tiedosto

Before After
Leveys: 400  |  Korkeus: 400  |  Koko: 14 KiB

+ 157
- 1
src/components/home/home.vue Näytä tiedosto

@@ -13,6 +13,76 @@
</div>
</div>
<!-- isVX && videoPlayBtn -->
<div class="module_0">
<!-- <video id="video" ref="vidoe" src="../../assets/video/1.mp4" width="100%" height="100%" autoplay muted="muted" loop="loop" /> -->
<!-- <video ref="vidoe" src="https://video.metavatar.cc/sv/d51a6f6-187fa2dff79/d51a6f6-187fa2dff79.mp4" width="100%" height="100%" autoplay muted="muted" loop="loop" /> -->
<div class="vantLoadingBox" style="height: 550px" v-show="!loading">
<van-loading type="spinner" color="#52d4e5" class="vantLoading" />
</div>
<div
v-if="isVX && videoPlayBtn && !isAndroid"
@click="playVideo"
style="
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 999;
width: 100px;
height: 100px;
"
>
<img
src="../../assets/icon/icon-play.png"
alt=""
style="width: 100px; height: 100px"
/>
</div>
<video
@play="videoPlayBtn = false"
id="video"
v-if="loading"
:src="videoUrl"
ref="vidoe"
width="100%"
height="100%"
autoplay
muted="muted"
loop="loop"
playsinline
>
<!-- <source type="audio/ogg" /> -->
</video>
<div class="titleBox">
<div v-if="characters == 1">
<div class="text1">卓越之人</div>
<div class="text2">由ChatGPT强势驱动</div>
</div>
<div v-if="characters != 1">
<div class="text1">Powered By ChatGPT.</div>
<div class="text2">Make it human.</div>
</div>
</div>
<div
:class="isBtnActice ? 'title_btn active' : 'title_btn'"
@touchstart="chatTouchStart"
@click="goToChat"
@touchend="chatTouchEnd"
>
{{ characters == 1 ? "开始聊天" : "Let's Talk" }}
</div>
<div class="bottom">
<div v-if="characters == 1">
Explore our website, or click above to let Metavatar show you around
</div>
<div v-if="characters != 1">
Explore our website, or click above to let Metavatar show you around
</div>
</div>
</div>
<div class="module_1">
<!-- <video id="video" ref="vidoe" src="../../assets/video/1.mp4" width="100%" height="100%" autoplay muted="muted" loop="loop" /> -->
<!-- <video ref="vidoe" src="https://video.metavatar.cc/sv/d51a6f6-187fa2dff79/d51a6f6-187fa2dff79.mp4" width="100%" height="100%" autoplay muted="muted" loop="loop" /> -->
@@ -527,6 +597,7 @@ export default {
return {
isAndroid: false, //判断是不是ios
inPage: false,
isBtnActice: false,
loading: false, // 加载状态
videoUrl: "", // 视频路径
videoUrl2: "", // 视频路径
@@ -865,6 +936,22 @@ export default {
Toast.fail(err.message);
});
},
chatTouchStart() {
console.log("chatTouchStart");
this.isBtnActice = true;
},
chatTouchEnd() {
console.log("chatTouchEnd");
this.isBtnActice = false;
},
goToChat() {
console.log("goToChat");
this.isBtnActice = false;
this.$router.push("/realTimeChat");
},
},
computed: {
...mapState({
@@ -898,7 +985,6 @@ export default {
},
mounted() {
this.goView("top");
this.$nextTick(() => {
this.module_6_data = oneList;
this.carouselLsit = twoList;
@@ -1136,6 +1222,76 @@ export default {
height: 70px;
width: 100%;
}
.module_0 {
width: 100%;
background-color: #202020;
// height: 100vh;
// height: 640px;
// background-color: aquamarine;
// background-image: url("../../assets/img/bg.png");
background-repeat: no-repeat;
background-size: 100% 100%;
overflow: hidden;
position: relative;
border-bottom: 3px solid #c0c0c0;
.titleBox {
position: absolute;
color: #fff;
left: 50%;
bottom: 70%;
transform: translate(-50%, -50%);
font-size: 20px;
text-align: center;
.text1 {
margin-bottom: 10px;
}
.text2 {
text-align: center;
}
}
.title_btn {
position: absolute;
left: 50%;
bottom: 10%;
transform: translate(-50%, -50%);
height: 40px;
line-height: 35px;
width: 120px;
text-align: center;
color: #16e9d6;
border-radius: 16px;
border: #16e9d6 solid 2px;
font-size: 18px;
cursor: pointer;
transition: all 0.1s;
&.active {
color: #ffffff;
background-color: #16e9d6;
transform: translate(-50%, -50%) scale(0.9);
}
}
.bottom {
position: absolute;
color: #fff;
width: 300px;
text-align: center;
left: 50%;
bottom: 5%;
transform: translate(-50%, 0);
font-size: 20px;
font-size: 12px;
.text1 {
margin-bottom: 10px;
}
.text2 {
text-align: center;
}
}
}
.module_1 {
width: 100%;
background-color: #202020;


+ 6
- 0
src/router/index.js Näytä tiedosto

@@ -121,6 +121,12 @@ const routes = [
name: 'downloadVideo',
component: () => import("../views/model/downloadVideo"),
},
// 实时对话
{
path: '/realTimeChat',
name: 'realTimeChat',
component: () => import("../views/realTimeChat/realTimeChat"),
},
]
const router = new VueRouter({


+ 298
- 0
src/views/realTimeChat/realTimeChat.vue Näytä tiedosto

@@ -0,0 +1,298 @@
<template>
<div :class="inPage ? 'page active' : 'page'">
<div id="top"></div>
<top />
<video
@play="videoPlayBtn = false"
class="videoBox"
id="video"
v-if="loading"
:src="videoUrl"
ref="video"
autoplay
muted="muted"
loop="loop"
playsinline
:style="'width:100%;height:' + screenHeight + 'px;'"
></video>

<div class="controlBox" :style="'width:' + screenWidth + 'px;'">
<div :class="isExpend ? 'chatBox' : 'chatBox expand'">
<div class="item top">聊天记录</div>
<div
v-for="item in chatList"
:class="item.type == 0 ? 'item left' : 'item right'"
>
{{ item.type == 0 ? `我:${item.msg}` : `${item.msg}:你` }}
</div>
<div v-if="chatList.length > 0" class="item center">已经到底啦</div>
<div v-if="chatList.length == 0" class="item noMsg">暂无聊天记录哦</div>
</div>

<div class="itemBox left" @click="sendMessage">
<img src="../../assets/icon/enter.png" alt="" />
</div>

<input
v-model="inputText"
class="inputInside"
type="text"
placeholder="输入文字聊天"
/>

<img
:class="isExpend ? 'arrow' : 'arrow active'"
src="../../assets/icon/arrow-down-bold.png"
@click="expendChatBox"
/>

<div class="itemBox right" @click="setVoice">
<img v-if="!isVoiceClose" src="../../assets/icon/voice.png" alt="" />
<img
v-if="isVoiceClose"
src="../../assets/icon/voice_close.png"
alt=""
/>
</div>
</div>
</div>
</template>

<script>
// 组件
import Vue from "vue";
import { Toast } from "vant";
import { mapState, mapActions } from "vuex";
import top from "../../components/common/top";
// 工具
import { scrollToID } from "../../utils";
// import io from "socket.io";

Vue.use(Toast);
export default {
components: {
top,
},
data() {
return {
inPage: false,
videoUrl: "",
videoPlayBtn: true,
loading: false, // 加载状态
isVoiceClose: false,
isExpend: false, // 对话框展开状态
inputText: "",
screenWidth: document.documentElement.clientWidth,
screenHeight: document.documentElement.clientHeight,
socket: null,
chatList: [
{
type: 0,
msg: "你好!",
},
{
type: 1,
msg: "你好!",
},
{
type: 0,
msg: "你好!",
},
{
type: 1,
msg: "你好!",
},
],
};
},
computed: {
...mapState({
characters: (state) => state.publicObj.characters,
}),
},

methods: {
...mapActions(["setCharacters"]),

go(url) {
this.$router.push(url);
},

setVoice() {
this.isVoiceClose = !this.isVoiceClose;
Toast.success(this.isVoiceClose ? "麦克风已关闭" : "麦克风已开启");
},

sendMessage() {},

expendChatBox() {
this.isExpend = !this.isExpend;
},

socketOnLink() {
// const url = "wss://mtest.metavatar.cc/webrtc";
const url = document.location.host;
this.socket = new WebSocket("wss://" + url + "/webrtc");

this.socket.onopen = (success) => {
console.log(success, "连接成功!");
};

this.socket.onclose = (evt) => {
console.log(evt, "连接已断开!");
};

this.socket.onerror = (evt) => {
console.log(evt, "连接失败");
};

this.socket.onmessage = (e) => {
console.log(e, "e");
};
},

socketLogin() {
let req = new Object();
req.cmd = "CMD_USER_LOGIN";
req.username = "Passager";
req.password = "123456";
req.agent = "browser";
let str = JSON.stringify(req);
this.socket.send(str);
},
},
created() {},
mounted() {
this.inPage = true;
scrollToID("top");
this.videoUrl =
"https://video.metavatar.cc/sv/d51a6f6-187fa2dff79/d51a6f6-187fa2dff79.mp4";
this.loading = true;
this.socketOnLink();
},
};
</script>

<style lang="scss" scoped>
.page {
position: relative;
transform: translateX(30%);
opacity: 0;
transition: all 0.5s; // global-transition
&.active {
opacity: 1;
transform: translateX(0);
}
.videoBox {
position: absolute;
top: 0;
left: 0;
z-index: -1;
object-fit: fill;
}
.controlBox {
position: absolute;
bottom: -670px;
height: 300px;
.chatBox {
position: relative;
width: 100%;
height: 160px;
color: #ffffff;
padding: 15px 30px 15px 30px;
overflow: scroll;
background-color: #00000054;
opacity: 1;
transition: all 0.3s;
.item {
margin-bottom: 8px;

&.top {
position: sticky;
top: 0px;
text-align: center;
}
&.left {
text-align: left;
}
&.right {
text-align: right;
}
&.center {
text-align: center;
margin-top: 40px;
}
&.noMsg {
position: absolute;
left: 50%;
bottom: 0;
transform: translateX(-50%);
text-align: center;
}
}

&.expand {
transform: translateY(100px);
opacity: 0;
z-index: -1;
}
}
.itemBox {
position: absolute;
bottom: 50px;
width: 50px;
height: 50px;
border: 3.5px solid #ffffff;
border-radius: 50%;
text-align: center;
padding: 10px;
transition: all 0.3s;
cursor: pointer;
&.left {
left: 295px;
}
&.right {
right: 295px;
}
img {
width: 100%;
height: 100%;
}
&.active {
opacity: 0.8;
}
}

.arrow {
position: absolute;
bottom: 100px;
left: 50%;
transform: translateX(-50%);
width: 30px;
height: 30px;
transition: all 0.2s;

&.active {
transform: translateX(-50%) rotate(180deg);
}
}

.inputInside {
position: absolute;
bottom: 57px;
left: 50%;
transform: translateX(-50%);
width: 170px;
height: 35px;
border: 3.5px solid #ffffff;
border-radius: 7px;
padding-left: 10px;
color: #ffffff;
caret-color: #ffffff;
&::-webkit-input-placeholder {
color: #ffffffbb;
}
}
}
}
</style>

+ 77
- 77
vue.config.js Näytä tiedosto

@@ -45,11 +45,11 @@ module.exports = {
filename: `js/js[name].${timeStamp}.js`,
chunkFilename: `js/chunk.[id].${timeStamp}.js`,
},
resolve: {
alias: {
'@': path.resolve(__dirname, 'src')
}
},
resolve: {
alias: {
'@': path.resolve(__dirname, 'src')
}
},
externals,
},
css: {
@@ -57,70 +57,70 @@ module.exports = {
filename: `css/[name].${timeStamp}.css`,
chunkFilename: `css/chunk.[id].${timeStamp}.css`,
},
loaderOptions: {
css: {
},
// postcss: {
// // options here will be passed to postcss-loader
// plugins: [require('postcss-px2rem')({
// remUnit: 75
// })]
// }
}
},
loaderOptions: {
css: {
},
// postcss: {
// // options here will be passed to postcss-loader
// plugins: [require('postcss-px2rem')({
// remUnit: 75
// })]
// }
}
},

pwa: {
iconPaths: {
favicon32: 'favicon.ico',
favicon16: 'favicon.ico',
appleTouchIcon: 'favicon.ico',
maskIcon: 'favicon.ico',
msTileImage: 'favicon.ico'
}
pwa: {
iconPaths: {
favicon32: 'favicon.ico',
favicon16: 'favicon.ico',
appleTouchIcon: 'favicon.ico',
maskIcon: 'favicon.ico',
msTileImage: 'favicon.ico'
}
},
//http://www.metavatar.cc/
devServer: {
overlay: {
warnings: false,
errors: false
},
//http://www.metavatar.cc/
devServer: {
overlay: {
warnings: false,
errors: false
proxy: {
'/api': {
// target: 'https://smapitestmalls,iformall.com/C/api',
target: process.env.VUE_APP_API_ROOT + '/api',
changeOrigin: true,
pathRewrite: {
'^/api': ''
},
proxy: {
'/api': {
// target: 'https://smapitestmalls,iformall.com/C/api',
target: process.env.VUE_APP_API_ROOT+'/api',
changeOrigin: true,
pathRewrite: {
'^/api': ''
},
},
},

}
},
lintOnSave: false,
publicPath: './', // 打包后引用的资源路径
}
},
lintOnSave: false,
publicPath: './', // 打包后引用的资源路径

chainWebpack: config => {
// favicon图标
config.plugin('html').tap(args => {
args[0].favicon = './public/favicon.ico';
return args;
});
// 注入cdn变量 (打包时会执行)
config.plugin('html').tap(args => {
args[0].cdn = cdn // 配置cdn给插件
return args
})
// 图片路径
config.module.rule('images')
// favicon图标
config.plugin('html').tap(args => {
args[0].favicon = './public/favicon.ico';
return args;
});
// 注入cdn变量 (打包时会执行)
config.plugin('html').tap(args => {
args[0].cdn = cdn // 配置cdn给插件
return args
})
// 图片路径
config.module.rule('images')
.use('url-loader')
.tap(options => ({
name: './assets/images/[name].[ext]',
quality: 85,
limit: 0,
esModule: false,
name: './assets/images/[name].[ext]',
quality: 85,
limit: 0,
esModule: false,
}))
//图片压缩
config.module
//图片压缩
config.module
.rule('images')
.use('image-webpack-loader')
.loader('image-webpack-loader')
@@ -144,9 +144,9 @@ module.exports = {
}
})
.end();
// 压缩js,只能线上,本地会js访问错误,会将js压缩成.gz文件
if (process.env.VUE_APP_ENV != 'development') {
if (process.env.VUE_APP_ENV != 'development') {
config.plugin('compression-webpack-plugin').use(new CompressionWebpackPlugin({
test: /\.(js|css|scss|woff|woff2|ttf)$/, // 匹配文件名
threshold: 20480, // 对超过20k的数据压缩
@@ -164,19 +164,19 @@ module.exports = {
}


}
// configureWebpack: {
// plugins: [
// //打包环境去掉console.log
// new UglifyJsPlugin({
// uglifyOptions: {
// compress: {
// drop_console: true, //注释console
// drop_debugger: true, //注释debugger
// pure_funcs: ['console.log'], //移除console.log
// },
// },
// }),
// ],
// }
}
// configureWebpack: {
// plugins: [
// //打包环境去掉console.log
// new UglifyJsPlugin({
// uglifyOptions: {
// compress: {
// drop_console: true, //注释console
// drop_debugger: true, //注释debugger
// pure_funcs: ['console.log'], //移除console.log
// },
// },
// }),
// ],
// }
}

+ 161
- 156
yarn.lock
File diff suppressed because it is too large
Näytä tiedosto


Ladataan…
Peruuta
Tallenna