123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310 |
- <template>
- <view class="container">
- <chatCustom @showDr="handleShowDrawer"/>
- <view class="cm_ai_container_main" :style="{ paddingBottom: isIphoneX ? '208rpx' : '174rpx', paddingTop:CustomBar+'px' }">
- <scroll-view class="cm_ai_container" scroll-y="true" show-scrollbar="true" ref="scrollView" id="scrollChatView">
- <!--提问回答element-->
- <view class="cm_ai_answer_main" id="cm_ai_answer">
- <chat-html ref="chatHtml" :messages='messages' @scrollUpdate="scrollToBottom" />
- </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>
- <!-- 对话记录 -->
- <chatDrawer :rightDrawer="rightDrawer" :probeIndex="probeIndex" @chat-detail="handleCHatDetail" @chat-news="handleCreateChat" />
- </view>
- </template>
- <script>
- import { mapState, mapMutations } from 'vuex'
- import chatCustom from './components/chat-custom'
- import chatDrawer from './components/chat-drawer'
- import chatHtml from './components/chat-html'
- export default {
- components: {
- chatCustom,
- chatDrawer,
- chatHtml
- },
- data() {
- return {
- StaticUrl: this.$Static,
- isIphoneX: this.$store.state.isIphoneX,
- CustomBar:this.CustomBar,// 顶部导航栏高度
- rightDrawer:false,
- isLoading: false,
- nvabarData: { //顶部自定义导航
- haveBack:true,
- haveHome:true,
- showCapsule:1, // 是否显示左上角图标 1表示显示 0表示不显示,
- showSearch: 0,
- title: '', // 导航栏 中间的标题
- bgColor: '#f5f4f6 ', // 导航栏 中间的标题
- textLeft:this.$store.state.isIphone
- },
- chatParams: {
- userId: '',
- question: ''
- },
- questionTextarea: '',
- probeChatId: '',
- probeIndex: 0,
- messages: [],
- }
- },
- onLoad(option) {
- },
- filters: {
- },
- computed: {
- ...mapState(['hasLogin', 'userInfo', ])
- },
- methods: {
- // 初始化
- async initGetStotage() {
- const userInfo = await this.$api.getStorage()
- this.chatParams.userId = userInfo.userId
- this.questionTextarea = ''
- this.probeIndex = 0
- this.messages = []
- },
- // 发送
- async handleAskQuestion() {
- if (!this.hasLogin) {
- this.$util.msg('请您登陆后使用AI助手', 2000)
- setTimeout(() => {
- this.$api.navigateTo('/pages/login/login')
- }, 2000)
- return
- } 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) {
- this.messages.push({
- question: `老板,稍等一下哈,为你查询${this.chatParams.question}的相关信息。`,
- from: 'bot',
- typing: false,
- currentLength: 0
- })
- }
- 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) {
- try {
- const res = await this.UserService.userNewChat(chatParams)
- const data = res.data
- this.probeIndex++
- this.probeChatId = data.chatId
- this.messages.push({ question: data.result, from: 'bot', typing: false, currentLength: 0 })
- this.isLoading = false
- } catch (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) {
- try {
- const res = await this.UserService.userSecondChat(chatParams)
- const data = res.data
- this.messages.push({ question: data.result, from: 'bot', typing: false, currentLength: 0 })
- this.isLoading = false
- } catch (error) {
- console.log('error',error)
- }
- },
- handleShowDrawer(){
- this.rightDrawer = true
- },
- handleCreateChat(){
- //新建对话
- this.probeIndex = 0
- this.messages = []
- },
- handleCHatDetail(chatId){
- // 查看详情
- this.messages =[]
- this.probeIndex = 1
- this.probeChatId = chatId
- this.userNewChatDetail({ chatId : chatId ,userId:this.chatParams.userId })
- },
- // 查询详情
- async userNewChatDetail(params) {
- try {
- const res = await this.UserService.userNewChatDetail(params)
- const data = res.data
- data.forEach(chats => {
- let from = chats.identity === 0 ? 'me' : 'bot'
- this.messages.push({ question: chats.message,from: from,typing: false,currentLength: 0 })
- })
- } catch (error) {
- console.log('error',error)
- }
- },
- 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() {
- this.initGetStotage()
- }
- }
- </script>
- <style lang="scss">
- page {
- width: 100%;
- height: 100%;
- background-color: #e6ebf7 !important;
- }
- .cm_ai_container_main {
- width: 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);
- .cm_ai_content {
- width: 100%;
- padding:20rpx 24rpx 0 24rpx;
- background-color: #e6ebf7 !important;
- box-sizing: border-box;
- position: fixed;
- left: 0;
- bottom: 0;
- .cm_ai_input {
- display: flex;
- align-items: center;
- justify-content: space-between;
- width: 100%;
- height: 100%;
- background-color: #FFFFFF;
- box-shadow: 0 16rpx 20rpx 0 rgba(174, 167, 223, .2);
- border-radius: 50rpx;
- box-sizing: border-box;
- padding: 10rpx 100rpx 10rpx 10rpx;
- position: relative;
- .cm_ai_textarea {
- width: 100%;
- 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;
- padding-left: 24rpx;
- }
- .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;
- }
- }
- .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 {
- width: 100%;
- min-height: 600rpx;
- overflow-y: auto;
- flex: 9;
- }
- }
- }
- </style>
|