|
@@ -1,38 +1,57 @@
|
|
<template>
|
|
<template>
|
|
<view class="container">
|
|
<view class="container">
|
|
- <view class="cm_ai_container_main">
|
|
|
|
- <view class="cm_ai_container">
|
|
|
|
|
|
+ <!-- <chatCustom @showDr="handleShowDrawer"/> -->
|
|
|
|
+ <!-- <view class="cm_ai_container_main" :style="{ paddingBottom: isIphoneX ? '208rpx' : '174rpx', paddingTop:CustomBar+'px' }"> -->
|
|
|
|
+ <view class="cm_ai_container_main" :style="{ paddingBottom: isIphoneX ? '208rpx' : '174rpx' }">
|
|
|
|
+ <scroll-view class="cm_ai_container" scroll-y="true" show-scrollbar="true" ref="scrollView" id="scrollChatView">
|
|
<!--提问回答element-->
|
|
<!--提问回答element-->
|
|
<view class="cm_ai_answer_main" id="cm_ai_answer">
|
|
<view class="cm_ai_answer_main" id="cm_ai_answer">
|
|
- <chat-html ref="chatHtml" :messages='messages' />
|
|
|
|
|
|
+ <chat-html ref="chatHtml" :messages='messages' @scrollUpdate="scrollToBottom" />
|
|
</view>
|
|
</view>
|
|
- <!--提问文本框-->
|
|
|
|
- <view class="cm_ai_content">
|
|
|
|
- <view class="cm_ai_input">
|
|
|
|
- <input class="cm_ai_textarea" v-model="questionTextarea" placeholder="请输入您想了解的内容"
|
|
|
|
- @confirm="handleAskQuestion" />
|
|
|
|
- <view class="cm_ai_button" :class="isLoading ? 'none' : ''" @click="handleAskQuestion">
|
|
|
|
- <text class="iconfont icon-fasong"></text>
|
|
|
|
- </view>
|
|
|
|
|
|
+ </scroll-view>
|
|
|
|
+ <!--提问文本框-->
|
|
|
|
+ <view class="cm_ai_content" :style="{ height: isIphoneX ? (120+68) +'rpx' : (120+34) +'rpx', paddingBottom: isIphoneX ? '68rpx' : '34rpx' }">
|
|
|
|
+ <view class="cm_ai_input">
|
|
|
|
+ <input class="cm_ai_textarea" v-model="questionTextarea" cursor-spacing="30" confirm-type="send" maxlength="200"
|
|
|
|
+ placeholder="请输入您想了解的内容" @confirm="handleAskQuestion" />
|
|
|
|
+ <view class="cm_ai_button" :class="isLoading ? 'none' : ''" @click="handleAskQuestion">
|
|
|
|
+ <text class="iconfont icon-fasong"></text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
+ <!-- 对话记录 -->
|
|
|
|
+ <!-- <chatDrawer :rightDrawer="isRightDrawer"/> -->
|
|
</view>
|
|
</view>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
<script>
|
|
<script>
|
|
import { mapState, mapMutations } from 'vuex'
|
|
import { mapState, mapMutations } from 'vuex'
|
|
|
|
+ import chatCustom from './components/chat-custom' //地址信息
|
|
|
|
+ import chatDrawer from './components/chat-drawer' //地址信息
|
|
import chatHtml from './components/chat-html' //地址信息
|
|
import chatHtml from './components/chat-html' //地址信息
|
|
export default {
|
|
export default {
|
|
components: {
|
|
components: {
|
|
|
|
+ chatCustom,
|
|
|
|
+ chatDrawer,
|
|
chatHtml
|
|
chatHtml
|
|
},
|
|
},
|
|
data() {
|
|
data() {
|
|
return {
|
|
return {
|
|
StaticUrl: this.$Static,
|
|
StaticUrl: this.$Static,
|
|
isIphoneX: this.$store.state.isIphoneX,
|
|
isIphoneX: this.$store.state.isIphoneX,
|
|
|
|
+ CustomBar:this.CustomBar,// 顶部导航栏高度
|
|
|
|
+ isRightDrawer:false,
|
|
isLoading: false,
|
|
isLoading: false,
|
|
|
|
+ nvabarData: { //顶部自定义导航
|
|
|
|
+ haveBack:true,
|
|
|
|
+ haveHome:true,
|
|
|
|
+ showCapsule:1, // 是否显示左上角图标 1表示显示 0表示不显示,
|
|
|
|
+ showSearch: 0,
|
|
|
|
+ title: '', // 导航栏 中间的标题
|
|
|
|
+ bgColor: '#f5f4f6 ', // 导航栏 中间的标题
|
|
|
|
+ textLeft:this.$store.state.isIphone
|
|
|
|
+ },
|
|
chatParams: {
|
|
chatParams: {
|
|
userId: '',
|
|
userId: '',
|
|
question: ''
|
|
question: ''
|
|
@@ -40,7 +59,7 @@
|
|
questionTextarea: '',
|
|
questionTextarea: '',
|
|
probeChatId: '',
|
|
probeChatId: '',
|
|
probeIndex: 0,
|
|
probeIndex: 0,
|
|
- messages: []
|
|
|
|
|
|
+ messages: [],
|
|
}
|
|
}
|
|
},
|
|
},
|
|
onLoad(option) {
|
|
onLoad(option) {
|
|
@@ -53,37 +72,59 @@
|
|
...mapState(['hasLogin', 'userInfo', ])
|
|
...mapState(['hasLogin', 'userInfo', ])
|
|
},
|
|
},
|
|
methods: {
|
|
methods: {
|
|
|
|
+ // 初始化
|
|
async initGetStotage() {
|
|
async initGetStotage() {
|
|
const userInfo = await this.$api.getStorage()
|
|
const userInfo = await this.$api.getStorage()
|
|
this.chatParams.userId = userInfo.userId
|
|
this.chatParams.userId = userInfo.userId
|
|
this.questionTextarea = ''
|
|
this.questionTextarea = ''
|
|
|
|
+ this.probeIndex = 0
|
|
|
|
+ this.messages = []
|
|
},
|
|
},
|
|
|
|
+ // 发送
|
|
async handleAskQuestion() {
|
|
async handleAskQuestion() {
|
|
- this.chatParams.question = this.questionTextarea
|
|
|
|
- if (this.isLoading) { return }
|
|
|
|
- if (!this.chatParams.question) {
|
|
|
|
- this.$util.msg('请输入内容', 2000)
|
|
|
|
|
|
+ if (!this.hasLogin) {
|
|
|
|
+ this.$util.msg('请您登陆后使用AI助手', 2000)
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ this.$api.navigateTo('/pages/login/login')
|
|
|
|
+ }, 2000)
|
|
return
|
|
return
|
|
- }
|
|
|
|
- this.messages.push({ question: this.chatParams.question, from: 'me', typing: false,
|
|
|
|
- currentLength: 0 })
|
|
|
|
- if (this.probeIndex === 0) {
|
|
|
|
- this.messages.push({ question: `老板,稍等一下哈,我为你查询一下${this.chatParams.question}的相关信息。`, from: 'bot',
|
|
|
|
- typing: false, currentLength: 0 })
|
|
|
|
- }
|
|
|
|
- this.isLoading = true
|
|
|
|
- setTimeout(() => {
|
|
|
|
|
|
+ } else {
|
|
|
|
+ this.chatParams.question = this.questionTextarea
|
|
|
|
+ if (this.isLoading) {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ if (!this.chatParams.question) {
|
|
|
|
+ this.$util.msg('请输入内容', 2000)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ this.messages.push({
|
|
|
|
+ question: this.chatParams.question,
|
|
|
|
+ from: 'me',
|
|
|
|
+ typing: false,
|
|
|
|
+ currentLength: 0
|
|
|
|
+ })
|
|
if (this.probeIndex === 0) {
|
|
if (this.probeIndex === 0) {
|
|
- this.handleUserNewChat(this.chatParams)
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
- this.handleUserSecondChat({ chatId: this.probeChatId, ...this.chatParams })
|
|
|
|
|
|
+ this.messages.push({
|
|
|
|
+ question: `老板,稍等一下哈,为你查询${this.chatParams.question}的相关信息。`,
|
|
|
|
+ from: 'bot',
|
|
|
|
+ typing: false,
|
|
|
|
+ currentLength: 0
|
|
|
|
+ })
|
|
}
|
|
}
|
|
- }, 1000)
|
|
|
|
|
|
+ this.questionTextarea = ''
|
|
|
|
+ this.isLoading = true
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ if (this.probeIndex === 0) {
|
|
|
|
+ this.handleUserNewChat(this.chatParams)
|
|
|
|
+ } else {
|
|
|
|
+ this.handleUserSecondChat({ chatId: this.probeChatId, ...this.chatParams })
|
|
|
|
+ }
|
|
|
|
+ }, 1000)
|
|
|
|
+ }
|
|
},
|
|
},
|
|
|
|
+ //初次提问
|
|
async handleUserNewChat(chatParams) {
|
|
async handleUserNewChat(chatParams) {
|
|
try {
|
|
try {
|
|
- this.questionTextarea = ''
|
|
|
|
const res = await this.UserService.userNewChat(chatParams)
|
|
const res = await this.UserService.userNewChat(chatParams)
|
|
const data = res.data
|
|
const data = res.data
|
|
this.probeIndex++
|
|
this.probeIndex++
|
|
@@ -91,21 +132,59 @@
|
|
this.messages.push({ question: data.result, from: 'bot', typing: false, currentLength: 0 })
|
|
this.messages.push({ question: data.result, from: 'bot', typing: false, currentLength: 0 })
|
|
this.isLoading = false
|
|
this.isLoading = false
|
|
} catch (error) {
|
|
} catch (error) {
|
|
- console.error('Error fetching new chats:', error)
|
|
|
|
|
|
+ console.log('error',error)
|
|
|
|
+ const msgMap = {
|
|
|
|
+ '-1':`您好,目前没有找到与${chatParams.question}相关的信息,可以换个说法试试。`,
|
|
|
|
+ '-2':'您的此次对话已超出对话轮次上限,可以刷新页面或新建对话重试。',
|
|
|
|
+ '-3':'您的单日对话次数已超出上限,请明日再来尝试提问。'
|
|
|
|
+ }
|
|
|
|
+ this.messages.push({ question: msgMap[error.code], from: 'bot', typing: false, currentLength: 0 })
|
|
|
|
+ this.isLoading = false
|
|
}
|
|
}
|
|
},
|
|
},
|
|
|
|
+ // 追问
|
|
async handleUserSecondChat(chatParams) {
|
|
async handleUserSecondChat(chatParams) {
|
|
try {
|
|
try {
|
|
- this.questionTextarea = ''
|
|
|
|
const res = await this.UserService.userSecondChat(chatParams)
|
|
const res = await this.UserService.userSecondChat(chatParams)
|
|
const data = res.data
|
|
const data = res.data
|
|
this.messages.push({ question: data.result, from: 'bot', typing: false, currentLength: 0 })
|
|
this.messages.push({ question: data.result, from: 'bot', typing: false, currentLength: 0 })
|
|
this.isLoading = false
|
|
this.isLoading = false
|
|
} catch (error) {
|
|
} catch (error) {
|
|
- console.error('Error fetching new chats:', error)
|
|
|
|
|
|
+ console.log('error',error)
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ handleShowDrawer(){
|
|
|
|
+ this.isRightDrawer = true
|
|
|
|
+ },
|
|
|
|
+ scrollToBottom(flag) {
|
|
|
|
+ // console.log('flag',flag)
|
|
|
|
+ // this.$nextTick( async () => {
|
|
|
|
+ // const scrollChatView = await this.$util.boundingClientRect(this, '#scrollChatView', false)
|
|
|
|
+ // // console.log('scrollChatView',scrollChatView.height)
|
|
|
|
+ // uni.pageScrollTo({
|
|
|
|
+ // duration: 300, //过渡时间必须为0,uniapp bug,否则运行到手机会报错
|
|
|
|
+ // scrollTop: scrollChatView.height,
|
|
|
|
+ // })
|
|
|
|
+ // // this.$refs.scrollView.scrollTop = lastCHatMain.top + lastCHatMain.height
|
|
|
|
+ // })
|
|
|
|
+ },
|
|
|
|
+ //滑动到最底部
|
|
|
|
+ async handleScrollUpdate(flag) {
|
|
|
|
+ if (flag) {
|
|
|
|
+ this.$refs.scrollView.scrollIntoView('#lastElementId', {
|
|
|
|
+ behavior: 'smooth' // 平滑滚动
|
|
|
|
+ })
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
},
|
|
|
|
+ onPullDownRefresh() {
|
|
|
|
+ // 下拉刷新
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ this.probeIndex = 0
|
|
|
|
+ this.messages = []
|
|
|
|
+ uni.stopPullDownRefresh()
|
|
|
|
+ }, 200)
|
|
|
|
+ },
|
|
onShow() {
|
|
onShow() {
|
|
this.initGetStotage()
|
|
this.initGetStotage()
|
|
}
|
|
}
|
|
@@ -116,86 +195,85 @@
|
|
page {
|
|
page {
|
|
width: 100%;
|
|
width: 100%;
|
|
height: 100%;
|
|
height: 100%;
|
|
- background-color: #FFFFFF;
|
|
|
|
|
|
+ background-color: #e6ebf7 !important;
|
|
}
|
|
}
|
|
|
|
|
|
.cm_ai_container_main {
|
|
.cm_ai_container_main {
|
|
width: 100%;
|
|
width: 100%;
|
|
height: 100%;
|
|
height: 100%;
|
|
|
|
+ box-sizing: border-box;
|
|
background-image: radial-gradient(circle at 14% 85%, #e7ecf7 0, rgba(231, 236, 247, 0) 37%), radial-gradient(circle at 3.4% 3.7%, rgba(245, 237, 241, .5) 0, rgba(245, 237, 241, 0) 28%), radial-gradient(circle at 100% 18%, #e8ebea 0, hsla(160, 7%, 92%, 0) 30%), linear-gradient(180deg, #f5f4f6, #e6ebf7);
|
|
background-image: radial-gradient(circle at 14% 85%, #e7ecf7 0, rgba(231, 236, 247, 0) 37%), radial-gradient(circle at 3.4% 3.7%, rgba(245, 237, 241, .5) 0, rgba(245, 237, 241, 0) 28%), radial-gradient(circle at 100% 18%, #e8ebea 0, hsla(160, 7%, 92%, 0) 30%), linear-gradient(180deg, #f5f4f6, #e6ebf7);
|
|
-
|
|
|
|
- .cm_ai_container {
|
|
|
|
|
|
+ .cm_ai_content {
|
|
width: 100%;
|
|
width: 100%;
|
|
- height: 100%;
|
|
|
|
- display: flex;
|
|
|
|
- flex-direction: column;
|
|
|
|
|
|
+ padding:20rpx 24rpx 0 24rpx;
|
|
|
|
+ background-color: #e6ebf7 !important;
|
|
box-sizing: border-box;
|
|
box-sizing: border-box;
|
|
- padding: 0 24rpx 40rpx 24rpx;
|
|
|
|
-
|
|
|
|
- .cm_ai_content {
|
|
|
|
|
|
+ position: fixed;
|
|
|
|
+ left: 0;
|
|
|
|
+ bottom: 0;
|
|
|
|
+ .cm_ai_input {
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ justify-content: space-between;
|
|
width: 100%;
|
|
width: 100%;
|
|
- height: 88rpx;
|
|
|
|
|
|
+ height: 100%;
|
|
background-color: #FFFFFF;
|
|
background-color: #FFFFFF;
|
|
box-shadow: 0 16rpx 20rpx 0 rgba(174, 167, 223, .2);
|
|
box-shadow: 0 16rpx 20rpx 0 rgba(174, 167, 223, .2);
|
|
- border-radius: 40rpx;
|
|
|
|
|
|
+ border-radius: 50rpx;
|
|
box-sizing: border-box;
|
|
box-sizing: border-box;
|
|
- padding: 14rpx 24rpx;
|
|
|
|
- margin: 20rpx 0;
|
|
|
|
|
|
+ padding: 10rpx 100rpx 10rpx 10rpx;
|
|
position: relative;
|
|
position: relative;
|
|
|
|
|
|
- .cm_ai_input {
|
|
|
|
- display: flex;
|
|
|
|
- align-items: center;
|
|
|
|
- justify-content: space-between;
|
|
|
|
|
|
+ .cm_ai_textarea {
|
|
width: 100%;
|
|
width: 100%;
|
|
- height: 60rpx;
|
|
|
|
- overflow: hidden;
|
|
|
|
|
|
+ height: 80rpx !important;
|
|
|
|
+ font-size: 30rpx;
|
|
|
|
+ line-height: 80rpx;
|
|
|
|
+ background-color: transparent;
|
|
|
|
+ border: none;
|
|
|
|
+ box-shadow: none;
|
|
|
|
+ overflow: auto;
|
|
|
|
+ scrollbar-width: none;
|
|
|
|
+ resize: none;
|
|
box-sizing: border-box;
|
|
box-sizing: border-box;
|
|
- padding-right: 60rpx;
|
|
|
|
- position: relative;
|
|
|
|
-
|
|
|
|
- input {
|
|
|
|
- width: 100%;
|
|
|
|
- height: 60rpx !important;
|
|
|
|
- font-size: 24rpx;
|
|
|
|
- line-height: 60rpx;
|
|
|
|
- background-color: transparent;
|
|
|
|
- border: none;
|
|
|
|
- box-shadow: none;
|
|
|
|
- overflow: auto;
|
|
|
|
- scrollbar-width: none;
|
|
|
|
- resize: none;
|
|
|
|
- box-sizing: border-box;
|
|
|
|
- padding-left: 4rpx;
|
|
|
|
- }
|
|
|
|
|
|
+ padding-left: 24rpx;
|
|
|
|
+ }
|
|
|
|
|
|
- .cm_ai_button {
|
|
|
|
- width: 60rpx;
|
|
|
|
- height: 60rpx;
|
|
|
|
- line-height: 60rpx;
|
|
|
|
- border-radius: 20rpx;
|
|
|
|
- display: inline-flex;
|
|
|
|
- align-items: center;
|
|
|
|
- justify-content: center;
|
|
|
|
- font-size: 24rpx;
|
|
|
|
- position: absolute;
|
|
|
|
- right: 0;
|
|
|
|
|
|
+ .cm_ai_button {
|
|
|
|
+ width: 100rpx;
|
|
|
|
+ height: 100rpx;
|
|
|
|
+ line-height: 100rpx;
|
|
|
|
+ border-radius: 20rpx;
|
|
|
|
+ display: inline-flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ justify-content: center;
|
|
|
|
+ font-size: 24rpx;
|
|
|
|
+ position: absolute;
|
|
|
|
+ right: 0;
|
|
|
|
|
|
- &.none {
|
|
|
|
- background-image: radial-gradient(circle at 14% 85%, #e7ecf7 0, rgba(231, 236, 247, 0) 37%);
|
|
|
|
-
|
|
|
|
- .icon-fasong {
|
|
|
|
- color: #e6e6e6;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ &.none {
|
|
|
|
+ background-image: radial-gradient(circle at 14% 85%, #e7ecf7 0, rgba(231, 236, 247, 0) 37%);
|
|
|
|
|
|
.icon-fasong {
|
|
.icon-fasong {
|
|
- font-size: 50rpx;
|
|
|
|
- color: #ff5b00;
|
|
|
|
|
|
+ color: #e6e6e6;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ .icon-fasong {
|
|
|
|
+ font-size: 50rpx;
|
|
|
|
+ color: #ff5b00;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .cm_ai_container {
|
|
|
|
+ width: 100%;
|
|
|
|
+ height: 100%;
|
|
|
|
+ display: flex;
|
|
|
|
+ flex-direction: column;
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
+ padding: 0 24rpx;
|
|
|
|
|
|
.cm_ai_answer_main {
|
|
.cm_ai_answer_main {
|
|
width: 100%;
|
|
width: 100%;
|