mirror of
http://112.124.100.131/ebiz-ai/ebiz-base-ai.git
synced 2025-12-09 02:46:50 +08:00
style(sass): 调整聊天图标样式
- 调整聊天图标的左右边距- 优化 voice.svg 图标的视觉效果 - 修复公告组件中的样式问题 - 优化热门产品、消息、导航列表等组件的样式
This commit is contained in:
2
.env.dev
2
.env.dev
@@ -3,5 +3,5 @@ NODE_ENV = 'dev' // 如果是生产环境,请记得切换为production
|
|||||||
|
|
||||||
# flag
|
# flag
|
||||||
VUE_APP_FLAG='dev'
|
VUE_APP_FLAG='dev'
|
||||||
VUE_APP_BASE='http://ebiz-fooge.320.io:7015'
|
VUE_APP_BASE='https://weixin.devops.ebiz-digits.com:7718'
|
||||||
|
|
||||||
|
|||||||
@@ -55,4 +55,7 @@ body{
|
|||||||
.chat-icon{
|
.chat-icon{
|
||||||
width: 16px;
|
width: 16px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
|
margin-left: 0!important;
|
||||||
|
margin-right: 2px!important;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
<svg t="1730875233854" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7506" width="30" height="30"><path d="M512 938.666667C277.333333 938.666667 85.333333 746.666667 85.333333 512S277.333333 85.333333 512 85.333333s426.666667 192 426.666667 426.666667-192 426.666667-426.666667 426.666667z m0-768c-187.733333 0-341.333333 153.6-341.333333 341.333333s153.6 341.333333 341.333333 341.333333 341.333333-153.6 341.333333-341.333333-153.6-341.333333-341.333333-341.333333z" fill="#707070" p-id="7507"></path><path d="M512 256c46.933333 0 85.333333 38.4 85.333333 85.333333v170.666667c0 46.933333-38.4 85.333333-85.333333 85.333333s-85.333333-38.4-85.333333-85.333333V341.333333c0-46.933333 38.4-85.333333 85.333333-85.333333z" fill="#707070" p-id="7508"></path><path d="M512 704c-106.666667 0-192-85.333333-192-192 0-12.8 8.533333-21.333333 21.333333-21.333333s21.333333 8.533333 21.333334 21.333333c0 81.066667 68.266667 149.333333 149.333333 149.333333s149.333333-68.266667 149.333333-149.333333c0-12.8 8.533333-21.333333 21.333334-21.333333s21.333333 8.533333 21.333333 21.333333c0 106.666667-85.333333 192-192 192z" fill="#707070" p-id="7509"></path><path d="M490.666667 682.666667h42.666666v170.666666h-42.666666z" fill="#707070" p-id="7510"></path></svg>
|
<svg t="1730875233854" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7506" width="40" height="40"><path d="M512 938.666667C277.333333 938.666667 85.333333 746.666667 85.333333 512S277.333333 85.333333 512 85.333333s426.666667 192 426.666667 426.666667-192 426.666667-426.666667 426.666667z m0-768c-187.733333 0-341.333333 153.6-341.333333 341.333333s153.6 341.333333 341.333333 341.333333 341.333333-153.6 341.333333-341.333333-153.6-341.333333-341.333333-341.333333z" fill="#707070" p-id="7507"></path><path d="M512 256c46.933333 0 85.333333 38.4 85.333333 85.333333v170.666667c0 46.933333-38.4 85.333333-85.333333 85.333333s-85.333333-38.4-85.333333-85.333333V341.333333c0-46.933333 38.4-85.333333 85.333333-85.333333z" fill="#707070" p-id="7508"></path><path d="M512 704c-106.666667 0-192-85.333333-192-192 0-12.8 8.533333-21.333333 21.333333-21.333333s21.333333 8.533333 21.333334 21.333333c0 81.066667 68.266667 149.333333 149.333333 149.333333s149.333333-68.266667 149.333333-149.333333c0-12.8 8.533333-21.333333 21.333334-21.333333s21.333333 8.533333 21.333333 21.333333c0 106.666667-85.333333 192-192 192z" fill="#707070" p-id="7509"></path><path d="M490.666667 682.666667h42.666666v170.666666h-42.666666z" fill="#707070" p-id="7510"></path></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
@@ -1,19 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="announcement" >
|
<div class="announcement">
|
||||||
<van-notice-bar
|
<van-notice-bar background="#2e5ca9" left-icon="volume-o" color="#fff" :text="announcements[0].content" />
|
||||||
background='#2e5ca9'
|
|
||||||
left-icon="volume-o"
|
|
||||||
color='#fff'
|
|
||||||
:text="announcements[0].content"/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { NoticeBar } from 'vant';
|
import { NoticeBar } from 'vant'
|
||||||
export default {
|
export default {
|
||||||
name: 'Announcement',
|
name: 'Announcement',
|
||||||
components: {
|
components: {
|
||||||
[NoticeBar.name]:NoticeBar
|
[NoticeBar.name]: NoticeBar,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -21,12 +17,12 @@ export default {
|
|||||||
{
|
{
|
||||||
title: '新功能上线',
|
title: '新功能上线',
|
||||||
content: '我们很高兴地宣布,全新的“智能问答”功能现已上线!您可以体验更高效、更智能的问答服务。',
|
content: '我们很高兴地宣布,全新的“智能问答”功能现已上线!您可以体验更高效、更智能的问答服务。',
|
||||||
date: '2023-09-25'
|
date: '2023-09-25',
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
};
|
}
|
||||||
}
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ export default {
|
|||||||
async getHotProducts() {
|
async getHotProducts() {
|
||||||
const res = await haslProducts()
|
const res = await haslProducts()
|
||||||
this.hotProducts = res.content
|
this.hotProducts = res.content
|
||||||
|
this.$emit('getHotList',this.hotProducts)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
|||||||
@@ -1,28 +1,27 @@
|
|||||||
<template>
|
<template>
|
||||||
<van-swipe class="my-swipe" >
|
<van-swipe class="my-swipe">
|
||||||
<van-swipe-item class='item'>
|
<van-swipe-item class="item">
|
||||||
<div v-for='item in navigationItems'>
|
<div v-for="item in navigationItems">
|
||||||
<div class='icon-contact mt20'>
|
<div class="icon-contact mt20">
|
||||||
<svg-icon :icon-class='item.icon' class-name='icon '></svg-icon>
|
<svg-icon :icon-class="item.icon" class-name="icon "></svg-icon>
|
||||||
</div>
|
|
||||||
<div class='nav-title mb10'>{{item.title}}</div>
|
|
||||||
</div>
|
</div>
|
||||||
</van-swipe-item>
|
<div class="nav-title mb10">{{ item.title }}</div>
|
||||||
<!-- <van-swipe-item>2</van-swipe-item>-->
|
</div>
|
||||||
</van-swipe>
|
</van-swipe-item>
|
||||||
|
<!-- <van-swipe-item>2</van-swipe-item>-->
|
||||||
|
</van-swipe>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {Swipe,SwipeItem} from 'vant'
|
import { Swipe, SwipeItem } from 'vant'
|
||||||
import SvgIcon from '@/components/svg-icon/index.vue'
|
import SvgIcon from '@/components/svg-icon/index.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'NavigationList',
|
name: 'NavigationList',
|
||||||
components: {
|
components: {
|
||||||
SvgIcon,
|
SvgIcon,
|
||||||
[Swipe.name]: Swipe,
|
[Swipe.name]: Swipe,
|
||||||
[SwipeItem.name]:SwipeItem,
|
[SwipeItem.name]: SwipeItem,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -32,56 +31,55 @@ export default {
|
|||||||
{ title: '停售产品', icon: 'stopSale' },
|
{ title: '停售产品', icon: 'stopSale' },
|
||||||
{ title: '服务中心', icon: 'service' },
|
{ title: '服务中心', icon: 'service' },
|
||||||
],
|
],
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
// 主题颜色定义
|
// 主题颜色定义
|
||||||
$primary-color: #2E5CA9;
|
$primary-color: #2e5ca9;
|
||||||
$primary-text-color: #F6AA21;
|
$primary-text-color: #f6aa21;
|
||||||
$primary-trans-color: #87A2D0;
|
$primary-trans-color: #87a2d0;
|
||||||
|
|
||||||
.my-swipe{
|
.my-swipe {
|
||||||
|
background: $primary-color;
|
||||||
background: $primary-color;
|
border-radius: 5px;
|
||||||
border-radius: 5px;
|
.item {
|
||||||
.item{
|
display: flex;
|
||||||
display: flex;
|
justify-content: space-around;
|
||||||
justify-content: space-around;
|
align-items: center;
|
||||||
align-items: center;
|
justify-items: center;
|
||||||
justify-items: center;
|
text-align: center;
|
||||||
text-align: center;
|
div {
|
||||||
div{
|
flex: 1;
|
||||||
flex:1;
|
padding: 10px 5px;
|
||||||
padding:10px 5px;
|
text-align: center;
|
||||||
text-align: center;
|
.icon-contact {
|
||||||
.icon-contact{
|
padding: 5px;
|
||||||
padding: 5px;
|
border-radius: 50%;
|
||||||
border-radius: 50%;
|
overflow: hidden;
|
||||||
overflow: hidden;
|
margin: 0 auto;
|
||||||
margin: 0 auto;
|
background: $primary-trans-color;
|
||||||
background: $primary-trans-color;
|
text-align: center;
|
||||||
text-align: center;
|
width: 35px;
|
||||||
width: 35px;
|
height: 35px;
|
||||||
height:35px;
|
display: flex;
|
||||||
display: flex;
|
//justify-items: center;
|
||||||
//justify-items: center;
|
align-items: center;
|
||||||
align-items: center;
|
justify-items: center;
|
||||||
justify-items: center;
|
.icon {
|
||||||
.icon{
|
|
||||||
flex: 1;
|
flex: 1;
|
||||||
width: 25px;
|
width: 25px;
|
||||||
height: 25px;
|
height: 25px;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
.nav-title{
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 600;
|
|
||||||
color:#fff;
|
|
||||||
}
|
}
|
||||||
}
|
.nav-title {
|
||||||
}
|
font-size: 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,105 +1,97 @@
|
|||||||
<template>
|
<template>
|
||||||
<div >
|
<div>
|
||||||
<div class='tab-box' v-for='item in list'>
|
<div class="tab-box" v-for="item in list">
|
||||||
<!-- <div class='box-title'>-->
|
<!-- <div class='box-title'>-->
|
||||||
<!-- {{item.title}}-->
|
<!-- {{item.title}}-->
|
||||||
<!-- </div>-->
|
<!-- </div>-->
|
||||||
<div class='box-container'>
|
<div class="box-container">
|
||||||
<van-cell v-for='list in item.list' :class='list.value?"link":"" ' @click='view(list)' is-link>
|
<van-cell v-for="list in item.list" :class="list.value ? 'link' : ''" @click="view(list)" is-link>
|
||||||
{{list.title}}
|
{{ list.title }}
|
||||||
</van-cell>
|
</van-cell>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<van-dialog v-model="show" width="90%" :title="title" confirm-button-color="#2E5CA9">
|
||||||
|
<div style="height: 70vh; overflow: scroll">
|
||||||
<van-dialog v-model="show" width='90%' :title='title' confirm-button-color='#2E5CA9'>
|
<pdf :url="url" v-if="show"></pdf>
|
||||||
<div style='height: 70vh;overflow: scroll' >
|
|
||||||
<pdf :url='url' v-if='show'></pdf>
|
|
||||||
</div>
|
</div>
|
||||||
</van-dialog>
|
</van-dialog>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import {Dialog,CellGroup,Cell} from 'vant'
|
import { Dialog, CellGroup, Cell } from 'vant'
|
||||||
import pdf from '@/views/AI/components/pdf.vue'
|
import pdf from '@/views/AI/components/pdf.vue'
|
||||||
export default {
|
export default {
|
||||||
name: 'box',
|
name: 'box',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
url:'',
|
url: '',
|
||||||
show:false,
|
show: false,
|
||||||
title:''
|
title: '',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
list: {
|
list: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => []
|
default: () => [],
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
watch: {},
|
watch: {},
|
||||||
components: {
|
components: {
|
||||||
[Dialog.name]:Dialog,
|
[Dialog.name]: Dialog,
|
||||||
[CellGroup.name]:CellGroup,
|
[CellGroup.name]: CellGroup,
|
||||||
[Cell.name]:Cell,
|
[Cell.name]: Cell,
|
||||||
pdf
|
pdf,
|
||||||
},
|
},
|
||||||
filters: {},
|
filters: {},
|
||||||
methods: {
|
methods: {
|
||||||
view(item){
|
view(item) {
|
||||||
console.log(item)
|
console.log(item)
|
||||||
if(!item.value) return
|
if (!item.value) return
|
||||||
this.url = item.value
|
this.url = item.value
|
||||||
this.title = item.title
|
this.title = item.title
|
||||||
this.show = true
|
this.show = true
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {},
|
||||||
},
|
mounted() {},
|
||||||
mounted() {
|
computed: {},
|
||||||
},
|
|
||||||
computed: {}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang='scss'>
|
<style scoped lang="scss">
|
||||||
// 主题颜色定义
|
// 主题颜色定义
|
||||||
$primary-color: #2E5CA9; // 修复了 SCSS 变量的定义方式
|
$primary-color: #2e5ca9; // 修复了 SCSS 变量的定义方式
|
||||||
$primary-text-color: #F6AA21; // 修复了 SCSS 变量的定义方式
|
$primary-text-color: #f6aa21; // 修复了 SCSS 变量的定义方式
|
||||||
$primary-trans-color: rgba(135, 162, 208, 0.5); // 使用rgba定义颜色,透明度为0.8
|
$primary-trans-color: rgba(135, 162, 208, 0.5); // 使用rgba定义颜色,透明度为0.8
|
||||||
|
|
||||||
.tab-box{
|
.tab-box {
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
//border: 1px solid $primary-trans-color;
|
//border: 1px solid $primary-trans-color;
|
||||||
.box-title{
|
.box-title {
|
||||||
padding: 10px 15px;
|
padding: 10px 15px;
|
||||||
background:$primary-trans-color ;
|
background: $primary-trans-color;
|
||||||
color : #2E5CA9; // 修复了 SCSS 变量的定义方式
|
color: #2e5ca9; // 修复了 SCSS 变量的定义方式
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
|
||||||
}
|
}
|
||||||
.box-container{
|
.box-container {
|
||||||
//padding: 10px;
|
//padding: 10px;
|
||||||
//display: flex;
|
//display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
//justify-content: space-between;
|
//justify-content: space-between;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
//gap: 8px;
|
//gap: 8px;
|
||||||
.link{
|
.link {
|
||||||
div,i{
|
div,
|
||||||
color:$primary-color;
|
i {
|
||||||
|
color: $primary-color;
|
||||||
}
|
}
|
||||||
//padding: 5px 12px;
|
//padding: 5px 12px;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
//background: $primary-trans-color;
|
//background: $primary-trans-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<section>
|
<section>
|
||||||
<div v-for="(message, index) in messagesList" :key="index" class="message-item ">
|
<div v-for="(message, index) in messagesList" :key="index" class="message-item">
|
||||||
<!--用户消息-->
|
<!--用户消息-->
|
||||||
<div v-if="message.type === 'user'" class="user-message mb10">
|
<div v-if="message.type === 'user'" class="user-message mb10">
|
||||||
<p>{{ message.text }}</p>
|
<p>{{ message.text }}</p>
|
||||||
@@ -18,15 +18,15 @@
|
|||||||
<p v-html="md.render(message.think)" v-if="message.think && message.showThink" class="thinkText" />
|
<p v-html="md.render(message.think)" v-if="message.think && message.showThink" class="thinkText" />
|
||||||
</span>
|
</span>
|
||||||
<div>
|
<div>
|
||||||
<p v-html="md.render(message.text)" v-if="message.text "></p>
|
<p v-html="md.render(message.text)" v-if="message.text"></p>
|
||||||
<span class="speakLoadingToast pv10" v-else-if='!message.text && !thinkOk && !message.isThink'>
|
<span class="speakLoadingToast pv10" v-else-if="!message.text && !thinkOk && !message.isThink">
|
||||||
<van-loading type="spinner" color="#2e5ca9" size="20px" v-if="!message.text" />
|
<van-loading type="spinner" color="#2e5ca9" size="20px" v-if="!message.text" />
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!--百宝箱-->
|
<!--百宝箱-->
|
||||||
<div v-else class='mb10'>
|
<div v-else class="mb10">
|
||||||
<treasure-box :item="message" @setProductName='setProductName'></treasure-box>
|
<treasure-box :item="message" @setProductName="setProductName"></treasure-box>
|
||||||
</div>
|
</div>
|
||||||
<!-- 新增点赞和踩按钮 -->
|
<!-- 新增点赞和踩按钮 -->
|
||||||
<div class="reaction-buttons mb10" v-if="message.type !== 'user'">
|
<div class="reaction-buttons mb10" v-if="message.type !== 'user'">
|
||||||
@@ -51,8 +51,7 @@ const md = new MarkdownIt({
|
|||||||
html: true,
|
html: true,
|
||||||
linkify: true,
|
linkify: true,
|
||||||
typographer: true,
|
typographer: true,
|
||||||
})
|
}).use(markdownItKatex)
|
||||||
.use(markdownItKatex)
|
|
||||||
export default {
|
export default {
|
||||||
name: 'message',
|
name: 'message',
|
||||||
components: { TreasureBox, [Icon.name]: Icon },
|
components: { TreasureBox, [Icon.name]: Icon },
|
||||||
@@ -76,8 +75,8 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
setProductName(e){
|
setProductName(e) {
|
||||||
this.$emit('setProductName',e)
|
this.$emit('setProductName', e)
|
||||||
},
|
},
|
||||||
|
|
||||||
showThink(message) {
|
showThink(message) {
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div style='height: 100%;'>
|
<div style="height: 100%">
|
||||||
<div v-if='!numPages' style='height: 100%;display: flex;align-items: center;justify-content: center;'>
|
<div v-if="!numPages" style="height: 100%; display: flex; align-items: center; justify-content: center">
|
||||||
<van-loading color="#2E5CA9" vertical>加载中...</van-loading>
|
<van-loading color="#2E5CA9" vertical>加载中...</van-loading>
|
||||||
</div>
|
</div>
|
||||||
<pdf-container :src="url" ref="pdfContainer" v-for="index in numPages" :key="index" :page="index" ></pdf-container>
|
<pdf-container :src="url" ref="pdfContainer" v-for="index in numPages" :key="index" :page="index"></pdf-container>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
@@ -14,17 +14,17 @@ export default {
|
|||||||
return {
|
return {
|
||||||
// url: 'https://www.gjtool.cn/pdfh5/git.pdf',
|
// url: 'https://www.gjtool.cn/pdfh5/git.pdf',
|
||||||
// url: 'http://storage.xuetangx.com/public_assets/xuetangx/PDF/PlayerAPI_v1.0.6.pdf',
|
// url: 'http://storage.xuetangx.com/public_assets/xuetangx/PDF/PlayerAPI_v1.0.6.pdf',
|
||||||
numPages: null
|
numPages: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
url: {
|
url: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: '',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
pdfContainer
|
pdfContainer,
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.getNumPages()
|
this.getNumPages()
|
||||||
@@ -32,17 +32,14 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
getNumPages() {
|
getNumPages() {
|
||||||
let loadingTask = pdfContainer.createLoadingTask(this.url)
|
let loadingTask = pdfContainer.createLoadingTask(this.url)
|
||||||
loadingTask.promise.then(pdf => {
|
loadingTask.promise.then((pdf) => {
|
||||||
this.numPages = pdf.numPages
|
this.numPages = pdf.numPages
|
||||||
this.url = loadingTask
|
this.url = loadingTask
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
})
|
})
|
||||||
// .catch(err => {
|
// .catch(err => {
|
||||||
// console.log('pdf加载失败', err)
|
// console.log('pdf加载失败', err)
|
||||||
// })
|
// })
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
194
src/views/AI/components/sticky.vue
Normal file
194
src/views/AI/components/sticky.vue
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="sticky"
|
||||||
|
v-if="productName"
|
||||||
|
:style="{
|
||||||
|
color: isDisabled ? '#999' : '#2e5ca9',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<!--产品选择-->
|
||||||
|
<van-dropdown-menu active-color="#2e5ca9" :disabled="isDisabled">
|
||||||
|
<van-dropdown-item v-model="value1" :options="options" @change="changeName" :disabled="isDisabled">
|
||||||
|
<template #title>
|
||||||
|
<div
|
||||||
|
class="fs14 title"
|
||||||
|
:style="{
|
||||||
|
color: isDisabled ? '#999' : '#2e5ca9',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
{{ value1 }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</van-dropdown-item>
|
||||||
|
</van-dropdown-menu>
|
||||||
|
<!--工具箱或其他模块-->
|
||||||
|
<van-dropdown-menu active-color="#2e5ca9" :disabled="isDisabled" style="width: 50px">
|
||||||
|
<template> </template>
|
||||||
|
<van-dropdown-item v-model="value2" :options="treasureList" @change="changeTreasureBox" :disabled="isDisabled" title-class="more-drown">
|
||||||
|
<template #title>
|
||||||
|
<van-icon name="ellipsis" class="more-treasure"></van-icon>
|
||||||
|
</template>
|
||||||
|
</van-dropdown-item>
|
||||||
|
</van-dropdown-menu>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { DropdownMenu, DropdownItem, Cell, Icon } from 'vant'
|
||||||
|
export default {
|
||||||
|
name: 'sticky',
|
||||||
|
components: {
|
||||||
|
[DropdownMenu.name]: DropdownMenu,
|
||||||
|
[DropdownItem.name]: DropdownItem,
|
||||||
|
[Cell.name]: Cell,
|
||||||
|
[Icon.name]: Icon,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
isDisabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
autoScrollEnabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
messagesList: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
hotList: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
productName: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
productName: {
|
||||||
|
handler(val) {
|
||||||
|
this.value1 = val
|
||||||
|
console.log(val)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
//
|
||||||
|
hotList: {
|
||||||
|
handler(val) {
|
||||||
|
if (val) {
|
||||||
|
this.options = val.map((item) => {
|
||||||
|
return {
|
||||||
|
text: item.productName,
|
||||||
|
value: item.productName,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
prdName: '',
|
||||||
|
value1: '',
|
||||||
|
options: [],
|
||||||
|
value2: '',
|
||||||
|
treasureList: [
|
||||||
|
{
|
||||||
|
text: '工具箱',
|
||||||
|
value: '1',
|
||||||
|
// icon: 'more-o',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
//
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
changeTreasureBox(item) {
|
||||||
|
switch (item) {
|
||||||
|
case '1':
|
||||||
|
// this.$emit('view', item)
|
||||||
|
this.messagesList.push({
|
||||||
|
type: 'box',
|
||||||
|
text: this.productName,
|
||||||
|
})
|
||||||
|
this.$emit('update:messageList', this.messagesList)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
this.value2 = ''
|
||||||
|
},
|
||||||
|
changeName(item) {
|
||||||
|
this.$emit('cellClick')
|
||||||
|
this.prdName = item
|
||||||
|
// this.messagesList.push({
|
||||||
|
// type: 'box',
|
||||||
|
// text: item,
|
||||||
|
// })
|
||||||
|
// this.$emit('update:messageList', this.messagesList)
|
||||||
|
// this.$emit('update:autoScrollEnabled', true)
|
||||||
|
// 只暴露名称
|
||||||
|
this.$emit('setProductName', item)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
//
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
//
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.title {
|
||||||
|
//width: 80%;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.sticky {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
position: sticky;
|
||||||
|
justify-content: space-between;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 10;
|
||||||
|
//height: 10px;
|
||||||
|
padding: 5px 10px;
|
||||||
|
background: #fff;
|
||||||
|
//gap: 10px;
|
||||||
|
}
|
||||||
|
::v-deep .more-treasure {
|
||||||
|
//flex:1;
|
||||||
|
//width: 20px;
|
||||||
|
font-size: 16px;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
::v-deep .van-dropdown-menu__bar {
|
||||||
|
box-shadow: unset;
|
||||||
|
}
|
||||||
|
::v-deep .van-dropdown-menu {
|
||||||
|
//flex: 1;
|
||||||
|
width: 85%;
|
||||||
|
}
|
||||||
|
::v-deep .van-dropdown-menu__bar {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
::v-deep .van-dropdown-menu__item {
|
||||||
|
justify-content: start;
|
||||||
|
}
|
||||||
|
::v-deep .van-dropdown-menu__title {
|
||||||
|
padding: 8px 12px 8px 8px;
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
::v-deep .van-cell {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .more-drown {
|
||||||
|
width: 100%;
|
||||||
|
&::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -2,62 +2,27 @@
|
|||||||
<div class="treasure-box">
|
<div class="treasure-box">
|
||||||
<h3>{{ item.text.indexOf('工具箱') !== -1 ? item.text : item.text + '工具箱' }}</h3>
|
<h3>{{ item.text.indexOf('工具箱') !== -1 ? item.text : item.text + '工具箱' }}</h3>
|
||||||
<van-tabs v-model="active" color="#2E5CA9" title-active-color="#2E5CA9" line-width="20">
|
<van-tabs v-model="active" color="#2E5CA9" title-active-color="#2E5CA9" line-width="20">
|
||||||
|
|
||||||
<!-- <van-tab title="爆款图文">-->
|
|
||||||
<!-- <TabBox></TabBox>-->
|
|
||||||
<!-- </van-tab>-->
|
|
||||||
<van-tab title="产品知识">
|
<van-tab title="产品知识">
|
||||||
|
<table style="border: 1px solid #b6ccd9; text-align: left; border-radius: 8px; overflow: hidden" cellspacing="0" cellpadding="0" class="my-table">
|
||||||
<!-- <van-collapse v-model="activeNames">-->
|
<tr v-for="item in knowledge">
|
||||||
<!-- <van-collapse-item :title="item.title" :name="index" v-for="(item, index) in knowledge" >-->
|
<th class="fs12 fw600">{{ item.title }}</th>
|
||||||
<!-- <span v-for="(it, index) in item.list" :key="index" :title="item.title" class='cells'>-->
|
<th class="fs12 flex">
|
||||||
<!-- {{ it.title}}-->
|
<span v-for="(it, index) in item.list" :key="index" :title="item.title" class="cells">
|
||||||
<!-- </span>-->
|
{{ it.title }}
|
||||||
<!-- </van-collapse-item>-->
|
|
||||||
<!-- </van-collapse>-->
|
|
||||||
<!-- -->
|
|
||||||
|
|
||||||
<table style='border :1px solid #b6ccd9;text-align: left;border-radius:8px;overflow: hidden ' cellspacing='0' cellpadding='0' class='my-table' >
|
|
||||||
<tr v-for='item in knowledge'>
|
|
||||||
<th class='fs12 fw600'>{{item.title}}</th>
|
|
||||||
<th class='fs12 flex '>
|
|
||||||
<span v-for="(it, index) in item.list" :key="index" :title="item.title" class='cells'>
|
|
||||||
{{ it.title}}
|
|
||||||
</span>
|
</span>
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- <van-cell-group>-->
|
|
||||||
<!-- <van-cell v-for="(item, index) in knowledge" :key="index" :title="item.title" class='cells'>-->
|
|
||||||
<!-- <template #default>-->
|
|
||||||
<!--<!– 截取钱10个–>-->
|
|
||||||
<!-- <span v-for='it in item.list'>{{-->
|
|
||||||
<!-- it.title.substring(0,8)}}...</span>-->
|
|
||||||
<!-- </template>-->
|
|
||||||
<!-- <template #right-icon>-->
|
|
||||||
<!-- <van-icon name="arrow" ></van-icon>-->
|
|
||||||
<!-- </template>-->
|
|
||||||
<!-- </van-cell>-->
|
|
||||||
<!-- </van-cell-group>-->
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- <TabBox :list='knowledge'></TabBox>-->
|
|
||||||
</van-tab>
|
</van-tab>
|
||||||
<van-tab title="常用工具">
|
<van-tab title="常用工具">
|
||||||
<TabBox :list='tools'></TabBox>
|
<TabBox :list="tools"></TabBox>
|
||||||
</van-tab>
|
</van-tab>
|
||||||
</van-tabs>
|
</van-tabs>
|
||||||
<!-- 在这里添加百宝箱的具体内容 -->
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { Tabs, Tab,CellGroup,Cell,Icon,Collapse, CollapseItem } from 'vant'
|
import { Tabs, Tab, CellGroup, Cell, Icon, Collapse, CollapseItem } from 'vant'
|
||||||
import TabBox from '@/views/AI/components/TabBox.vue'
|
import TabBox from '@/views/AI/components/TabBox.vue'
|
||||||
import { productDetail } from '@/api/generatedApi'
|
import { productDetail } from '@/api/generatedApi'
|
||||||
export default {
|
export default {
|
||||||
@@ -82,60 +47,57 @@ export default {
|
|||||||
return {
|
return {
|
||||||
active: 0,
|
active: 0,
|
||||||
// 可以在这里添加百宝箱相关的数据
|
// 可以在这里添加百宝箱相关的数据
|
||||||
// 工具列表
|
// 工具列表
|
||||||
tools: [],
|
tools: [],
|
||||||
knowledge: [],
|
knowledge: [],
|
||||||
activeNames:[1],
|
activeNames: [1],
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'item.text': {
|
'item.text': {
|
||||||
handler(newValue, oldValue) {
|
handler(newValue, oldValue) {
|
||||||
if(!this.item.detail){
|
if (!this.item.detail) {
|
||||||
this.getTreasureBox()
|
this.getTreasureBox()
|
||||||
} else {
|
} else {
|
||||||
this.setList(this.item.detail)
|
this.setList(this.item.detail)
|
||||||
this.$emit('setProductName',this.item.detail.productName)
|
this.$emit('setProductName', this.item.detail.productName)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
immediate: true,
|
immediate: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
setList(){
|
setList() {
|
||||||
this.tools = [
|
this.tools = [
|
||||||
{title: '工具',
|
{
|
||||||
list:[
|
title: '工具',
|
||||||
{value:this.item.detail.instructionUrl,title:'产品说明书' },
|
list: [
|
||||||
{value:this.item.detail.clauseUrl,title:'条款' },
|
{ value: this.item.detail.instructionUrl, title: '产品说明书' },
|
||||||
]},
|
{ value: this.item.detail.clauseUrl, title: '条款' },
|
||||||
|
],
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
this.knowledge = []
|
this.knowledge = []
|
||||||
|
|
||||||
for(let i in this.item.detail.knowledge){
|
for (let i in this.item.detail.knowledge) {
|
||||||
this.knowledge.push({
|
this.knowledge.push({
|
||||||
title:i,
|
title: i,
|
||||||
list:this.item.detail.knowledge[i].split(',').map(item=>{
|
list: this.item.detail.knowledge[i].split(',').map((item) => {
|
||||||
return {
|
return {
|
||||||
title:item,
|
title: item,
|
||||||
// value:item
|
// value:item
|
||||||
}
|
}
|
||||||
})
|
}),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 可以在这里添加百宝箱相关的功能方法
|
// 可以在这里添加百宝箱相关的功能方法
|
||||||
async getTreasureBox() {
|
async getTreasureBox() {
|
||||||
productDetail({ productName: this.item.text }).then((res) => {
|
productDetail({ productName: this.item.text }).then((res) => {
|
||||||
if(res){
|
if (res) {
|
||||||
this.$set(this.item,'detail',res.content)
|
this.$set(this.item, 'detail', res.content)
|
||||||
this.$emit('setProductName',res.content.productName)
|
this.$emit('setProductName', res.content.productName)
|
||||||
this.setList()
|
this.setList()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -169,43 +131,38 @@ $primary-trans-color: #87a2d0;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.cells{
|
.cells {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.my-table {
|
||||||
.my-table{
|
tr {
|
||||||
tr{
|
|
||||||
padding: 6px 8px;
|
padding: 6px 8px;
|
||||||
|
|
||||||
}
|
}
|
||||||
tr:nth-child(2n){
|
tr:nth-child(2n) {
|
||||||
background: #e9f3ff;
|
background: #e9f3ff;
|
||||||
|
|
||||||
}
|
}
|
||||||
tr:last-child{
|
tr:last-child {
|
||||||
th{
|
th {
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
th:nth-child(1){
|
th:nth-child(1) {
|
||||||
padding: 6px 8px;
|
padding: 6px 8px;
|
||||||
width:80px;
|
width: 80px;
|
||||||
background: #2976e8 ;
|
background: #2976e8;
|
||||||
color:#fff;
|
color: #fff;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
//border-right:1px solid #b6ccd9;
|
//border-right:1px solid #b6ccd9;
|
||||||
border-bottom:1px solid #b6ccd9;
|
border-bottom: 1px solid #b6ccd9;
|
||||||
}
|
}
|
||||||
th:nth-child(2){
|
th:nth-child(2) {
|
||||||
padding: 6px 8px;
|
padding: 6px 8px;
|
||||||
color:#253243;
|
color: #253243;
|
||||||
font-weight: unset;
|
font-weight: unset;
|
||||||
gap:5px;
|
gap: 5px;
|
||||||
border-bottom:1px solid #b6ccd9
|
border-bottom: 1px solid #b6ccd9;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,10 +1,25 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="chat-page">
|
<div class="chat-page">
|
||||||
|
<sticky
|
||||||
|
:hotList="hotList"
|
||||||
|
:productName="productName"
|
||||||
|
:messagesList.sync="messages"
|
||||||
|
:autoScrollEnabled.sync="autoScrollEnabled"
|
||||||
|
@setProductName="setProductName"
|
||||||
|
:isDisabled="messageStatus === 'send'"
|
||||||
|
></sticky>
|
||||||
|
|
||||||
<main class="chat-main">
|
<main class="chat-main">
|
||||||
<div class="chat-content">
|
<div class="chat-content">
|
||||||
<div class="message-area" ref="messageArea" @scroll="handleScroll">
|
<div class="message-area" ref="messageArea" @scroll="handleScroll">
|
||||||
<HotProducts class="mb10" :messagesList.sync="messages"></HotProducts>
|
<HotProducts class="mb10" :messagesList.sync="messages" @getHotList="getHotProducts"></HotProducts>
|
||||||
<messageComponent :messagesList="messages" :is-deep="isDeep" :is-search="isSearching" :think-ok='isThink' @setProductName='setProductName'></messageComponent>
|
<messageComponent
|
||||||
|
:messagesList="messages"
|
||||||
|
:is-deep="isDeep"
|
||||||
|
:is-search="isSearching"
|
||||||
|
:think-ok="isThink"
|
||||||
|
@setProductName="setProductName"
|
||||||
|
></messageComponent>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 滚动到顶部按钮 -->
|
<!-- 滚动到顶部按钮 -->
|
||||||
@@ -13,12 +28,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div v-if='isVoiceMode && newMessage' class='isVoiceModeText'>
|
<div v-if="isVoiceMode && newMessage" class="isVoiceModeText">
|
||||||
<textarea class="textarea" placeholder="请输入内容" v-model='newMessage' ></textarea>
|
<textarea class="textarea" placeholder="请输入内容" v-model="newMessage"></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<section class="section">
|
<section class="section">
|
||||||
<button @click="searchInternet" :class="{ active: isSearching }">
|
<button @click="searchInternet" :class="{ active: isSearching }" class="ml10">
|
||||||
<svg-icon icon-class="earth" class-name="chat-icon"></svg-icon>
|
<svg-icon icon-class="earth" class-name="chat-icon"></svg-icon>
|
||||||
联网搜索
|
联网搜索
|
||||||
</button>
|
</button>
|
||||||
@@ -33,48 +48,36 @@
|
|||||||
</section>
|
</section>
|
||||||
<footer class="chat-footer">
|
<footer class="chat-footer">
|
||||||
<!-- 输入框 or 按住说话提示 -->
|
<!-- 输入框 or 按住说话提示 -->
|
||||||
<div class="input-wrapper">
|
<div class="input-wrapper ml10">
|
||||||
<input
|
<input v-if="!isVoiceMode" type="text" v-model="newMessage" placeholder="请简短描述您的问题" @keyup.enter="sendMessage" />
|
||||||
v-if="!isVoiceMode"
|
<div
|
||||||
type="text"
|
v-else
|
||||||
v-model="newMessage"
|
class="voice-hint-container"
|
||||||
placeholder="请简短描述您的问题"
|
:class="{ disabled: messageStatus === 'send' }"
|
||||||
@keyup.enter="sendMessage"
|
@mousedown="startRecording"
|
||||||
/>
|
@selectstart="() => false"
|
||||||
<div v-else class="voice-hint-container"
|
@mouseup="stopRecording"
|
||||||
:class="{disabled:messageStatus === 'send' }"
|
@mouseleave="stopRecording"
|
||||||
@mousedown="startRecording"
|
@touchend="stopRecording"
|
||||||
@selectstart="() => false"
|
@touchstart="startRecording"
|
||||||
@mouseup="stopRecording"
|
>
|
||||||
@mouseleave="stopRecording"
|
<div class="waveform" :class="{ active: isRecording }">
|
||||||
@touchend="stopRecording"
|
|
||||||
@touchstart="startRecording">
|
|
||||||
<div class="waveform" :class="{ active: isRecording}" >
|
|
||||||
<span class="bar"></span>
|
<span class="bar"></span>
|
||||||
<span class="bar"></span>
|
<span class="bar"></span>
|
||||||
<span class="bar"></span>
|
<span class="bar"></span>
|
||||||
<span class="bar"></span>
|
<span class="bar"></span>
|
||||||
<span class="bar"></span>
|
<span class="bar"></span>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="hint-text" v-if='!isRecording'>按住说话</div>-->
|
<!-- <div class="hint-text" v-if='!isRecording'>按住说话</div>-->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 语音按钮:按住说话 -->
|
<!-- 语音按钮:按住说话 -->
|
||||||
<button
|
<button @click="isVoiceMode = !isVoiceMode" class="mic-button ml10 mr10">
|
||||||
@click='isVoiceMode = !isVoiceMode'
|
<svg-icon v-if="!isVoiceMode" icon-class="voice" class-name="chat-icon ml10" style="width: 25px; height: 25px"></svg-icon>
|
||||||
class="mic-button ml10 mr10"
|
<span v-else style="font-size: 20px; color: #707070" class="ml15 mr5">⌨</span>
|
||||||
>
|
|
||||||
<svg-icon v-if='!isVoiceMode' icon-class="voice" class-name="chat-icon" style='width: 20px;height: 20px'></svg-icon>
|
|
||||||
<span v-else style='font-size: 18px;color:#707070' class='ml5 mr5'>⌨</span>
|
|
||||||
</button>
|
</button>
|
||||||
<!-- 发送按钮 -->
|
<!-- 发送按钮 -->
|
||||||
<button
|
<button @click="sendMessage" :disabled="messageStatus === 'send'" :class="{ disabled: messageStatus === 'send' }" class="mr10 fs16">发送</button>
|
||||||
@click="sendMessage"
|
|
||||||
:disabled="messageStatus === 'send'"
|
|
||||||
:class="{ disabled: messageStatus === 'send' }"
|
|
||||||
>
|
|
||||||
发送
|
|
||||||
</button>
|
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -84,7 +87,8 @@ import { Icon } from 'vant'
|
|||||||
import messageComponent from './components/message.vue'
|
import messageComponent from './components/message.vue'
|
||||||
import SvgIcon from '@/components/svg-icon/index.vue'
|
import SvgIcon from '@/components/svg-icon/index.vue'
|
||||||
import HotProducts from '@/views/AI/components/HotProducts.vue'
|
import HotProducts from '@/views/AI/components/HotProducts.vue'
|
||||||
import { chat, chatProduct,audioToText } from '@/api/generatedApi'
|
import sticky from '@/views/AI/components/sticky.vue'
|
||||||
|
import { chat, chatProduct, audioToText } from '@/api/generatedApi'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@@ -92,13 +96,15 @@ export default {
|
|||||||
[Icon.name]: Icon,
|
[Icon.name]: Icon,
|
||||||
messageComponent,
|
messageComponent,
|
||||||
HotProducts,
|
HotProducts,
|
||||||
|
sticky,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
productName:'',
|
hotList: [],
|
||||||
answerMap:'',
|
productName: '',
|
||||||
timer:null,
|
answerMap: '',
|
||||||
answerIndex:0,
|
timer: null,
|
||||||
|
answerIndex: 0,
|
||||||
conversationId: '',
|
conversationId: '',
|
||||||
currentMessage: null,
|
currentMessage: null,
|
||||||
messageStatus: 'stop',
|
messageStatus: 'stop',
|
||||||
@@ -119,6 +125,10 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
getHotProducts(e) {
|
||||||
|
console.log(e)
|
||||||
|
this.hotList = e
|
||||||
|
},
|
||||||
deepInternet() {
|
deepInternet() {
|
||||||
this.isDeep = !this.isDeep
|
this.isDeep = !this.isDeep
|
||||||
},
|
},
|
||||||
@@ -131,15 +141,17 @@ export default {
|
|||||||
this.productName = ''
|
this.productName = ''
|
||||||
},
|
},
|
||||||
hasTreasureBox() {
|
hasTreasureBox() {
|
||||||
chatProduct({ query: this.newMessage }).then((res) => {
|
chatProduct({ query: this.newMessage })
|
||||||
if (res) {
|
.then((res) => {
|
||||||
|
if (res) {
|
||||||
|
this.messageStatus = 'stop'
|
||||||
|
this.messages.push({ type: 'box', text: this.newMessage, detail: res.content })
|
||||||
|
this.newMessage = ''
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
this.messageStatus = 'stop'
|
this.messageStatus = 'stop'
|
||||||
this.messages.push({ type: 'box', text: this.newMessage, detail: res.content })
|
})
|
||||||
this.newMessage = ''
|
|
||||||
}
|
|
||||||
}).catch(() => {
|
|
||||||
this.messageStatus = 'stop'
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
sendMessage() {
|
sendMessage() {
|
||||||
if (this.messageStatus === 'send') return
|
if (this.messageStatus === 'send') return
|
||||||
@@ -185,20 +197,18 @@ export default {
|
|||||||
const messageArea = this.$refs.messageArea
|
const messageArea = this.$refs.messageArea
|
||||||
if (!messageArea) return
|
if (!messageArea) return
|
||||||
const threshold = 10
|
const threshold = 10
|
||||||
const isAtBottom =
|
const isAtBottom = messageArea.scrollHeight - messageArea.clientHeight <= messageArea.scrollTop + threshold
|
||||||
messageArea.scrollHeight - messageArea.clientHeight <=
|
|
||||||
messageArea.scrollTop + threshold
|
|
||||||
this.autoScrollEnabled = isAtBottom
|
this.autoScrollEnabled = isAtBottom
|
||||||
this.scrollPosition = messageArea.scrollTop
|
this.scrollPosition = messageArea.scrollTop
|
||||||
},
|
},
|
||||||
async startRecording() {
|
async startRecording() {
|
||||||
if(this.messageStatus === 'send') return
|
if (this.messageStatus === 'send') return
|
||||||
if (this.isRecognizing) return
|
if (this.isRecognizing) return
|
||||||
try {
|
try {
|
||||||
const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
|
const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
|
||||||
this.mediaRecorder = new MediaRecorder(stream)
|
this.mediaRecorder = new MediaRecorder(stream)
|
||||||
this.audioChunks = []
|
this.audioChunks = []
|
||||||
this.mediaRecorder.ondataavailable = event => {
|
this.mediaRecorder.ondataavailable = (event) => {
|
||||||
if (event.data.size > 0) {
|
if (event.data.size > 0) {
|
||||||
this.audioChunks.push(event.data)
|
this.audioChunks.push(event.data)
|
||||||
}
|
}
|
||||||
@@ -238,17 +248,19 @@ export default {
|
|||||||
},
|
},
|
||||||
callVoiceRecognitionAPI(blob) {
|
callVoiceRecognitionAPI(blob) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const formData = new FormData();
|
const formData = new FormData()
|
||||||
formData.append('file', blob);
|
formData.append('file', blob)
|
||||||
formData.append('appType', 'haslBigHelper');
|
formData.append('appType', 'haslBigHelper')
|
||||||
formData.append('user', 'chenyuda');
|
formData.append('user', 'chenyuda')
|
||||||
audioToText(formData).then(res => {
|
audioToText(formData)
|
||||||
if(res){
|
.then((res) => {
|
||||||
resolve(res.content)
|
if (res) {
|
||||||
}
|
resolve(res.content)
|
||||||
}).catch(err => {
|
}
|
||||||
reject(err)
|
})
|
||||||
})
|
.catch((err) => {
|
||||||
|
reject(err)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
axiosGetAiChat() {
|
axiosGetAiChat() {
|
||||||
@@ -262,7 +274,7 @@ export default {
|
|||||||
think: '',
|
think: '',
|
||||||
isLike: false,
|
isLike: false,
|
||||||
isDisLike: false,
|
isDisLike: false,
|
||||||
})
|
}),
|
||||||
)
|
)
|
||||||
this.messages.push(this.currentMessage)
|
this.messages.push(this.currentMessage)
|
||||||
const params = {
|
const params = {
|
||||||
@@ -317,7 +329,7 @@ export default {
|
|||||||
const cleanLine = line.replace(/^data:\s*/, '')
|
const cleanLine = line.replace(/^data:\s*/, '')
|
||||||
if (!cleanLine) return null
|
if (!cleanLine) return null
|
||||||
const data = JSON.parse(cleanLine)
|
const data = JSON.parse(cleanLine)
|
||||||
console.log(data)
|
// console.log(data)
|
||||||
if (data.answer) {
|
if (data.answer) {
|
||||||
this.answerMap += data.answer
|
this.answerMap += data.answer
|
||||||
}
|
}
|
||||||
@@ -343,8 +355,8 @@ export default {
|
|||||||
this.messageStatus = 'stop'
|
this.messageStatus = 'stop'
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(answer)
|
// console.log(answer)
|
||||||
console.log(this.currentMessage)
|
// console.log(this.currentMessage)
|
||||||
if (!this.currentMessage || !answer) return
|
if (!this.currentMessage || !answer) return
|
||||||
const mode = this.isThink ? 'think' : 'text'
|
const mode = this.isThink ? 'think' : 'text'
|
||||||
this.currentMessage[mode] += answer
|
this.currentMessage[mode] += answer
|
||||||
@@ -382,7 +394,6 @@ $primary-trans-color: rgba(135, 162, 208, 0.5);
|
|||||||
background: #f7f8fa;
|
background: #f7f8fa;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
|
||||||
.button-container {
|
.button-container {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: 150px;
|
bottom: 150px;
|
||||||
@@ -399,10 +410,10 @@ $primary-trans-color: rgba(135, 162, 208, 0.5);
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.isVoiceModeText{
|
.isVoiceModeText {
|
||||||
display: flex;
|
display: flex;
|
||||||
textarea{
|
textarea {
|
||||||
flex:1;
|
flex: 1;
|
||||||
max-height: 80px;
|
max-height: 80px;
|
||||||
resize: none;
|
resize: none;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
@@ -421,7 +432,7 @@ $primary-trans-color: rgba(135, 162, 208, 0.5);
|
|||||||
gap: 10px;
|
gap: 10px;
|
||||||
|
|
||||||
button {
|
button {
|
||||||
padding: 5px 12px;
|
padding: 4px 8px;
|
||||||
border: none;
|
border: none;
|
||||||
background-color: $primary-trans-color;
|
background-color: $primary-trans-color;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
@@ -439,7 +450,9 @@ $primary-trans-color: rgba(135, 162, 208, 0.5);
|
|||||||
.chat-footer {
|
.chat-footer {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 10px;
|
padding: 10px 10px 20px 10px;
|
||||||
|
//padding-bottom: constant(safe-area-inset-bottom);
|
||||||
|
//padding-bottom: env(safe-area-inset-bottom);
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
|
|
||||||
.input-wrapper {
|
.input-wrapper {
|
||||||
@@ -474,7 +487,6 @@ $primary-trans-color: rgba(135, 162, 208, 0.5);
|
|||||||
background-color: #eaeaea;
|
background-color: #eaeaea;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.waveform {
|
.waveform {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
@@ -482,7 +494,7 @@ $primary-trans-color: rgba(135, 162, 208, 0.5);
|
|||||||
//height: 30px;
|
//height: 30px;
|
||||||
//width: 60px;
|
//width: 60px;
|
||||||
gap: 2px;
|
gap: 2px;
|
||||||
&.disabled{
|
&.disabled {
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
background: red;
|
background: red;
|
||||||
}
|
}
|
||||||
@@ -495,11 +507,26 @@ $primary-trans-color: rgba(135, 162, 208, 0.5);
|
|||||||
background-color: $primary-color;
|
background-color: $primary-color;
|
||||||
margin: 0 1px;
|
margin: 0 1px;
|
||||||
|
|
||||||
&:nth-child(1) { height: 10px; animation-delay: 0s; }
|
&:nth-child(1) {
|
||||||
&:nth-child(2) { height: 16px; animation-delay: 0.1s; }
|
height: 10px;
|
||||||
&:nth-child(3) { height: 12px; animation-delay: 0.2s; }
|
animation-delay: 0s;
|
||||||
&:nth-child(4) { height: 18px; animation-delay: 0.3s; }
|
}
|
||||||
&:nth-child(5) { height: 14px; animation-delay: 0.4s; }
|
&:nth-child(2) {
|
||||||
|
height: 16px;
|
||||||
|
animation-delay: 0.1s;
|
||||||
|
}
|
||||||
|
&:nth-child(3) {
|
||||||
|
height: 12px;
|
||||||
|
animation-delay: 0.2s;
|
||||||
|
}
|
||||||
|
&:nth-child(4) {
|
||||||
|
height: 18px;
|
||||||
|
animation-delay: 0.3s;
|
||||||
|
}
|
||||||
|
&:nth-child(5) {
|
||||||
|
height: 14px;
|
||||||
|
animation-delay: 0.4s;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -548,7 +575,8 @@ $primary-trans-color: rgba(135, 162, 208, 0.5);
|
|||||||
}
|
}
|
||||||
|
|
||||||
@keyframes wave-animation {
|
@keyframes wave-animation {
|
||||||
0%, 100% {
|
0%,
|
||||||
|
100% {
|
||||||
transform: scaleY(1);
|
transform: scaleY(1);
|
||||||
}
|
}
|
||||||
50% {
|
50% {
|
||||||
|
|||||||
Reference in New Issue
Block a user