| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437 |
- <template>
- <view class="box">
- <view class="flex-common-css iPhone-bottom box-border-box">
- <Nav title="AI助手" titleColor="#333" bgckgroundBox='#fff' :leftShow='false'></Nav>
- <scroll-view :scroll-y="true" id="scroll-view-css" class="scroll-view-css" :scroll-top="scrollTop"
- :scroll-with-animation="true" @scroll="scrolll">
- <view v-if="total > chatData.length" class="text-align-center fs-24 fc-9" @click="lookHistory">
- 查看历史消息
- </view>
- <view class="chat-box" id="chat-box">
- <msgItem v-for="(item,index) in chatData" :key="index" :item="item" :showType="item.showType"
- :msgText="item.content" @selectStyle="selectStyle" @refresh="refresh"></msgItem>
- </view>
- </scroll-view>
- <view class="bottom-box">
- <view class="input-box">
- <input type="text" v-model="chatText" placeholder="有问题尽管问我" class="input" cursor-spacing="20"
- @confirm="confirm" :disabled='!sendControl'>
- </view>
- </view>
- </view>
- </view>
- </template>
- <script>
- import tools from "@/service/tools.js";
- import msgItem from "./msg-item.vue";
- // import {
- // qianfanSend,
- // qianfanMsg_list,
- // } from "@/api/qianfan.js"
- import {
- aiSend,
- aiMsgList
- } from "@/api/ai.js"
- export default {
- components: {
- msgItem
- },
- data() {
- return {
- total: 0,
- page: 1,
- chatText: '',
- chatType: 1,
- scrollTop: 20,
- chatData: [],
- initialData: [],
- // loadingStyle: false,
- Ajax: false,
- timer: null, //settimeout
- showText: "",
- typeName: '',
- isScrolll: false,
- scrolllTimeServe: null,
- imgUrl: '',
- fileUrl: '',
- voiceUrl: '',
- inputHeadShow: true,
- sendControl: true
- };
- },
- onShow() {
- this.page = 1
- this.scrollTop = 20
- this.chatData = []
- this.aiMsgList()
- },
- onLoad() {},
- mounted() {},
- methods: {
- selectStyle(e) {
- this.chatType = e
- this.initialData.forEach((item) => {
- if (this.chatType === item.type) {
- this.typeName = item.name
- let data = {
- msg_type: 2,
- content: '您好,我是' + this.typeName + 'AI小助手,有什么能帮助您吗?',
- created_at: tools.getDate(),
- }
- this.chatData.push(data)
- }
- })
- // console.log(e);
- },
- aiSend() {
- let that = this
- let data = {
- msg_type: 2,
- content: '',
- created_at: tools.getDate(),
- showType: true,
- }
- this.chatData.push(data)
- let key = this.chatData.length - 1
- aiSend({
- content: this.chatText,
- }).then((res) => {
- if (res.code == 1) {
- this.imgUrl = ''
- this.fileUrl = ''
- this.voice_url = ''
- this.chatText = ''
- this.sendControl = true
- // this.chatData[key].voice_url = res.data.voice_url
- this.chatData[key].content = res.data.content
- this.$nextTick(() => {
- this.scrollToBottom()
- })
- } else {
- this.chatData[key].content = msg
- }
- })
- },
- refresh(num) {
- // this.$nextTick(() => {
- if (num) {
- // console.log("高度");
- // this.scrollTop = 99999
- console.log('最终')
- setTimeout(() => {
- this.scrollToBottom(50)
- }, 50)
- } else {
- console.log('回调执行')
- this.scrollToBottom(0)
- // setTimeout(()=>{
- // this.scrollToBottom()
- // },10)
- }
- // })
- },
- lookHistory() {
- if (this.total > this.chatData.length) {
- ++this.page
- this.aiMsgList()
- }
- },
- // aiMsgList() {
- // aiMsgList({
- // page: this.page
- // }).then((res) => {
- // if (res.code == 1) {
- // this.total = res.data.total
- // let data = res.data.items.reverse()
- // data.forEach((itm) => {
- // itm.showType = false
- // })
- // this.chatData.unshift(...data)
- // let that = this
- // // this.$nextTick(() => {
- // // this.scrollToBottom()
- // // })
- // setTimeout(() => {
- // that.scrollToBottom()
- // }, 50)
- // }
- // })
- // },
- aiMsgList() {
- aiMsgList({
- page: this.page
- }).then((res) => {
- if (res.code == 1) {
- this.total = res.data.total;
- let data = res.data.items.reverse();
- if (data.length === 0) {
- console.log('没有新数据加载');
- return;
- }
- if (data.length > 0) {
- data.forEach((itm) => {
- itm.showType = false;
- });
- if (this.page === 1) {
- this.chatData.unshift(...data);
- setTimeout(() => {
- this.scrollToBottom()
- }, 50)
- } else {
- // 记录当前 chat-box 的高度
- let lodQuery = uni.createSelectorQuery().in(this);
- lodQuery.select('#chat-box').boundingClientRect((rect) => {
- console.log(rect, 'rect');
- if (rect) {
- let oldHeight = rect.height; // 记录旧高度
- // 插入新数据
- this.chatData.unshift(...data);
- // 计算新高度并滚动到正确位置
- this.$nextTick(() => {
- lodQuery.select('#chat-box').boundingClientRect((newRect) => {
- if (newRect) {
- let newHeight = newRect.height;
- let scrollTop = newHeight - oldHeight; // 计算需要滚动的距离
- // 设置 scrollTop
- this.scrollTop = scrollTop;
- console.log(scrollTop,'???????????');
- this.$forceUpdate();
- }
- })
- });
- }
- }).exec()
- }
- }
- }
- })
- },
- leftClick() {
- uni.switchTab({
- url: 'pages/index/index'
- })
- // uni.showTabBar()
- },
- confirm(event) {
- if (this.sendControl) {
- if (event.target.value) {
- let timeData = tools.getDate()
- let text = {
- created_at: timeData,
- msg_type: 1,
- content: event.target.value,
- img_url: this.imgUrl,
- file_url: this.fileUrl
- }
- this.chatData.push(text)
- this.inputHeadShow = false
- this.sendControl = false
- this.$nextTick(() => {
- this.scrollToBottom()
- })
- this.aiSend()
- // this.lading()
- this.chatText = ''
- } else {
- uni.showToast({
- title: '请输入问题',
- icon: 'none',
- duration: 1000
- });
- }
- }
- },
- scrolll(e) {
- // console.log(e, 'eeee');
- },
- // scrollToBottom(num) {
- // let query = uni.createSelectorQuery().in(this)
- // query.select('#scroll-view-css').boundingClientRect()
- // query.select('#chat-box').boundingClientRect()
- // query.exec((res) => {
- // console.log(res[1].height, res[0].height, 'res[0].height');
- // //如果子元素高度大于父元素高度(显示高度)
- // if (res[1].height > res[0].height) {
- // //计算出二者差值就是需要滚动的距离
- // let scrollTop = res[1].height - res[0].height
- // let differenceNum = scrollTop - this.scrollTop
- // console.log(differenceNum, 'differenceNum');
- // console.log(scrollTop, 'scrollTop');
- // console.log(num, 'num');
- // if (differenceNum > 50) {
- // this.scrollTop = scrollTop + 50
- // console.log('differenceNum > 50 1111111111', this.scrollTop);
- // } else if (num > 0) {
- // this.scrollTop = scrollTop + num
- // console.log('num > 0');
- // } else {
- // this.scrollTop = scrollTop
- // console.log('differenceNum > 50 33333333333333', this.scrollTop);
- // }
- // } else {
- // this.scrollTop = 9999999999999
- // }
- // })
- // }
- scrollToBottom(num) {
- let query = uni.createSelectorQuery().in(this);
- query.select('#scroll-view-css').boundingClientRect();
- query.select('#chat-box').boundingClientRect();
- query.exec((res) => {
- if (res[1].height > res[0].height) {
- let scrollTop = res[1].height - res[0].height;
- let differenceNum = scrollTop - this.scrollTop;
- if (differenceNum > 50) {
- let topNUm = scrollTop
- this.scrollTop = topNUm + 50;
- console.log(scrollTop, 'scrollTop1111111111');
- } else if (num > 0) {
- let topNUm = scrollTop
- this.scrollTop = topNUm + num;
- console.log(scrollTop, 'scrollTop122222222');
- } else {
- let topNUm = scrollTop
- this.scrollTop = topNUm + 50;
- console.log(scrollTop, 'scrollTop333333333');
- }
- this.$forceUpdate();
- } else {
- this.scrollTop = 9999999999999;
- }
- });
- }
- },
- }
- </script>
- <style lang="scss" scoped>
- .box {
- background: #fff;
- position: relative;
- .popup-block {
- border-radius: 20rpx 20rpx 0rpx 0rpx;
- overflow: hidden;
- background-color: #f5f5f5;
- .popup-row {
- height: 100rpx;
- background-color: #fff;
- text-align: center;
- line-height: 100rpx;
- border-bottom: 2rpx solid #f5f5f5;
- &:nth-child(4) {
- margin-bottom: 20rpx;
- }
- &:last-child {
- height: 112rpx;
- border: none;
- line-height: 112rpx;
- }
- &:active {
- background-color: rgb(244, 244, 244);
- }
- }
- }
- .chat-box {
- padding: 22rpx 32rpx 1rpx;
- box-sizing: border-box;
- .dialogue-box {
- // width: 100%;
- height: auto;
- margin: 0 0 40rpx 0;
- display: flex;
- flex-direction: column;
- .time {
- font-size: 24rpx;
- color: #999999;
- margin: 0 0 8rpx 0;
- }
- .dialogue {
- padding: 24rpx;
- box-sizing: border-box;
- word-break: break-all;
- font-size: 30rpx;
- .dialogue-text {}
- .dialogue-text-one {
- color: #333333;
- }
- .dialogue-text-two {
- color: #FFFFFF;
- }
- .initial-box {
- .initial-title {
- font-size: 30rpx;
- font-weight: 600;
- color: #333333;
- margin: 0 0 12rpx 0;
- }
- .initial-style {
- font-size: 30rpx;
- color: #2F80ED;
- margin: 0 0 12rpx 0;
- }
- .initial-style:last-child {
- margin: 0;
- }
- }
- }
- .dialogue-one {
- background: #F7F8FC;
- border-radius: 10rpx 10rpx 10rpx 0;
- }
- .dialogue-two {
- background: #FDAB26;
- border-radius: 10rpx 10rpx 0 10rpx;
- }
- }
- .dialogue-box-one {
- align-items: flex-start;
- }
- }
- .bottom-box {
- position: relative;
- .input-box {
- width: 100%;
- height: 100rpx;
- height: auto;
- background: #fff;
- padding: 10rpx 32rpx;
- box-sizing: border-box;
- border-top: 1rpx solid #EEEEEE;
- transition: all .1s linear;
- }
- }
- }
- .input {
- background: #F2F2F2;
- border-radius: 200rpx;
- width: 100%;
- height: 100%;
- padding: 20rpx 170rpx 20rpx 24rpx;
- box-sizing: border-box;
- }
- </style>
|