第一部分:下拉刷新
我这里就把主要的下拉刷新的写一下,上拉是一样的道理,就不写了
<div class="talk_top" ref="listWrapper" id="listWrapper">
<div class="loadingpic" v-loading="loading"></div>
<div v-for="message in messages" :key="message.id" class="message">
<div class="minetext" v-html="message.text"></div>
</div>
</div>
<script>
export default {
data() {
return {
loading: false, // 加载中
messages:[],
}
},
mounted() {
this.$nextTick(() => {
this.getAiLogsByTopicId(); // 初始化数据
this.re();
});
},
methods: {
//这是放在mounted中获取初始数据
getAiLogsByTopicId() {
this.$axios
.get("/userApp/ai/getAiLogsByTopicId", {
params: {
TopicId: this.topic.topicId,
pageNum: 1,
pageSize: this.page.pageSize
}
})
.then(res => {
if (res.code === 200) {
this.messages = res.rows.reverse();
// console.log(res.rows);
this.total = Number(res.total);
}
});
},
//放在re()里面的数据接口
getlist() {
if (this.total >= this.messages.length) {
this.page.pageNum++;
this.loading = true;
this.$axios
.get("/userApp/ai/getAiLogsByTopicId", {
params: {
TopicId: this.topic.topicId,
pageNum: this.page.pageNum,
pageSize: this.page.pageSize
}
})
.then(res => {
if (res.code === 200) {
if (this.page.pageNum >= Number(res.allPage)) {
this.$message.success("数据到底啦");
this.loading = false;
return;
} else {
this.messages = [...res.rows.reverse(), ...this.messages];
this.total = Number(res.total);
// console.log(this.messages);
this.loading = false;
}
}
})
.catch(error => {
this.$message.error(error.msg);
this.loading = false;
});
} else {
this.$message.success("数据到底啦");
// this.showdown = true;
this.loading = false;
}
},
// 下拉、上拉刷新
re() {
var flag = false;
var PstartX;
var PstartY;
var PMoveX;
var PMoveY;
var PendX;
var PendY;
let that = this;
document.onmousedown = function(ev) {
flag = true;
PstartX = ev.pageX;
PstartY = ev.pageY;
// console.log("start:" + PstartX, PstartY);
document.onmousemove = function(ev) {
PMoveX = ev.pageX;
PMoveY = ev.pageY;
if (flag) {
// console.log("move:" + PMoveX, PMoveY);
var resutl = getpostion(PMoveY, PstartY);
switch (resutl) {
case 0:
// console.log("无操作");
break;
case 1:
// console.log("向上");
break;
case 2:
// console.log("向下");
if (PMoveY - PstartY > 0) {
if (PMoveY - PstartY >= 50) {
document.getElementById("listWrapper").style.marginTop =
PMoveY - PstartY + "px";
}
that.loading = true;
// document.getElementById("loadingpic").style.display = "block";
}
break;
}
}
};
document.onmouseup = function(ev) {
flag = false;
PendX = ev.pageX;
PendY = ev.pageY;
// console.log("end:" + PendX, PendY);
var resutl = getpostion(PMoveY, PstartY);
switch (resutl) {
case 0:
// console.log("无操作");
break;
case 1:
// console.log("向上");
break;
case 2:
// console.log("向下");
// location.reload();
setTimeout(() => {
that.getlist(); //调用接口
//回弹到初始位置
document.getElementById("listWrapper").style.marginTop = "0px";
}, 500);
break;
}
};
// 判断是上拉还是下拉
function getpostion(PMoveY, PstartY) {
if (PMoveY - PstartY == 0) {
return 0; //无操作
}
if (PMoveY - PstartY < 0) {
return 1; //向上
}
if (PMoveY - PstartY > 0) {
return 2; //向下
}
}
};
},
}
}
</script>
在他的基础上修改了一下,他的上面有点小问题https://www.cnblogs.com/zmcxsf/p/10443189.html
第二部分:滚动条到底部
1、调用接口数据,然后调用re()方法,如果不调用re方法,页面没反应
2、在 mounted中获取滚动区域的document,然后让调用方法,让盒子滚动到底部,这样页面一打开,滚动条就在底部了
3、监听滚动事件,判断用户滚动状态
<template>
<div class="chat">
<div class="center">
<div v-if="pasId === 0">
<div class="talk_history" id="chat">
<div class="talk_top" ref="listWrapper" id="listWrapper">
<div class="loadingpic" v-loading="loading"></div>
<div v-for="message in messages" :key="message.id" class="message">
。。。。内容
</div>
</div>
</div>
<div class="talk_huifu">
<div style="border-bottom:1px solid #f8f8f8;display:flex">
<el-upload
ref="upload"
class="upload-demo"
action="https://jsonplaceholder.typicode.com/posts/"
:show-file-list="false"
:file-list="fileList"
accept=".pdf"
:on-change="talkchange"
:http-request="http"
>
<img
style="margin:0 15px 0 10px"
src="../../assets/img/wenjianjia.png"
title="发送文件"
/>
</el-upload>
</div>
<div align="right">
<el-input
type="textarea"
v-model="talk"
:maxlength="4000"
:rows="3"
resize="none"
placeholder="有什么我可以帮您?"
></el-input>
<el-button size="medium" :disabled="disabled" @click="sub(0)"
>发送</el-button
>
</div>
</div>
</div>
</div>
</template>
<script>
let source = null;
var AIurl = "http://192.168.4.172:8081/userApp/ai/sse";
var resultUrl = "http://192.168.4.172:8081/userApp/ai/aiHelp";
import { EventSourcePolyfill } from "event-source-polyfill";
export default {
layout: "AI2",
name: "",
data() {
return {
disabled: false, //ai回答结束,按钮取消禁用
showdown: false, //数据到底啦
chatContent: null,
isScrolling: true,
loading: false, // 加载中
page: 1,
total: 0, //总条数
talk: "", //发送的聊天信息
len: true, //发送信息的次数
fileList: [], //发送文件
topic: {}, //新建对话的信息
word: {}, //文件的信息
messages: [], //聊天历史
page: {
pageNum: 0,
pageSize: 10
},
total: 0,
pasId: 0, //上一页的id
};
},
mounted() {
this.getAiLogsByTopicId(); // 初始化数据
this.re();
setTimeout(() => {
this.chatContent = document.getElementsByClassName("talk_top")[0];
this.scrollToBottom();
// 监听滚动事件,判断用户滚动状态
this.chatContent.addEventListener("scroll", this.handleScroll);
}, 1000);
},
watch: {
disabled: {
handler(newval, oldval) {
this.disabled = newval;
},
deep: true,
immediate: true
}
},
methods: {
// 定义将滚动条定位在底部的方法
scrollToBottom() {
var that = this;
this.$nextTick(() => {
if (that.isScrolling) {
that.chatContent.scrollTop =
that.chatContent.scrollHeight - that.chatContent.offsetHeight;
// console.log(that.chatContent.scrollTop);
}
});
},
handleScroll() {
const scrollContainer = this.chatContent;
const scrollTop = scrollContainer.scrollTop;
const scrollHeight = scrollContainer.scrollHeight;
const offsetHeight = scrollContainer.offsetHeight;
if (scrollTop + offsetHeight < scrollHeight) {
// 用户开始滚动并在最底部之上,取消保持在最底部的效果
this.isScrolling = true;
} else {
// 用户停止滚动并滚动到最底部,开启保持到最底部的效果
this.isScrolling = false;
}
},
// 发送对话---------------------------------------------------
// 加载数据对话
getAiLogsByTopicId() {
this.$axios
.get("/userApp/ai/getAiLogsByTopicId", {
params: {
TopicId: this.topic.topicId,
pageNum: 1,
pageSize: this.page.pageSize
}
})
.then(res => {
if (res.code === 200) {
this.messages = res.rows.reverse();
// console.log(res.rows);
this.total = Number(res.total);
}
});
},
getlist() {
if (this.total >= this.messages.length) {
this.page.pageNum++;
this.loading = true;
this.$axios
.get("/userApp/ai/getAiLogsByTopicId", {
params: {
TopicId: this.topic.topicId,
pageNum: this.page.pageNum,
pageSize: this.page.pageSize
}
})
.then(res => {
if (res.code === 200) {
if (this.page.pageNum >= Number(res.allPage)) {
this.$message.success("数据到底啦");
this.loading = false;
return;
} else {
this.messages = [...res.rows.reverse(), ...this.messages];
this.total = Number(res.total);
// console.log(this.messages);
this.loading = false;
}
}
})
.catch(error => {
this.$message.error(error.msg);
this.loading = false;
});
} else {
this.$message.success("数据到底啦");
// this.showdown = true;
this.loading = false;
}
},
// 下拉、上拉刷新
re() {
var flag = false;
var PstartX;
var PstartY;
var PMoveX;
var PMoveY;
var PendX;
var PendY;
let that = this;
document.onmousedown = function(ev) {
flag = true;
PstartX = ev.pageX;
PstartY = ev.pageY;
// console.log("start:" + PstartX, PstartY);
document.onmousemove = function(ev) {
PMoveX = ev.pageX;
PMoveY = ev.pageY;
if (flag) {
// console.log("move:" + PMoveX, PMoveY);
var resutl = getpostion(PMoveY, PstartY);
switch (resutl) {
case 0:
// console.log("无操作");
break;
case 1:
// console.log("向上");
break;
case 2:
// console.log("向下");
if (PMoveY - PstartY > 0) {
if (PMoveY - PstartY >= 50) {
document.getElementById("listWrapper").style.marginTop =
PMoveY - PstartY + "px";
}
that.loading = true;
// document.getElementById("loadingpic").style.display = "block";
}
break;
}
}
};
document.onmouseup = function(ev) {
flag = false;
PendX = ev.pageX;
PendY = ev.pageY;
// console.log("end:" + PendX, PendY);
var resutl = getpostion(PMoveY, PstartY);
switch (resutl) {
case 0:
// console.log("无操作");
break;
case 1:
// console.log("向上");
break;
case 2:
// console.log("向下");
// location.reload();
setTimeout(() => {
that.getlist(); //调用接口
//回弹到初始位置
document.getElementById("listWrapper").style.marginTop = "0px";
}, 500);
break;
}
};
// 判断是上拉还是下拉
function getpostion(PMoveY, PstartY) {
if (PMoveY - PstartY == 0) {
return 0; //无操作
}
if (PMoveY - PstartY < 0) {
return 1; //向上
}
if (PMoveY - PstartY > 0) {
return 2; //向下
}
}
};
},
sub(type) {
let that = this;
// 判断次数,在发送
if (type === 1) {
this.messages.push({
aiId: "", //编号
userId: "", //用户id
userAsk: "", //用户询问
aiReply: "", //ai回复
askTime: "", //询问时间
isPdf: true, //是否是pdf
fileName: this.word.fileName, //文件名称
fileSize: this.word.fileSize, //文件大小
aiTopicId: this.topic.topicId //话题编号
});
this.$message.success("请稍等,正在响应中");
this.load(this.messages[this.messages.length - 1], 1, that.chatContent);//调用接口
setTimeout(() => {
that.chatContent.scrollTop = that.chatContent.scrollHeight + 150;
}, 500);
this.word = {};
} else {
if (this.talk === "") {
this.$message.error("请填写内容");
} else {
this.messages.push({
aiId: "", //编号
userId: "", //用户id
userAsk: this.talk, //用户询问
aiReply: "", //ai回复
askTime: "", //询问时间
isPdf: false, //是否是pdf
fileName: null, //文件名称
fileSize: null, //文件大小
aiTopicId: this.topic.topicId //话题编号
});
this.$message.success("请稍等,正在响应中");
this.load(
this.messages[this.messages.length - 1],
0,
that.chatContent
);
setTimeout(() => {
that.chatContent.scrollTop = that.chatContent.scrollHeight + 150;
}, 500);
}
this.talk = "";
}
},
// 获取ai结果
load(item, type, chatContent) {
this.disabled = true;
if (type === 1) {
source = new EventSourcePolyfill(
Url +
"userApp/ai/sse?question=" +
this.word.fileDownloadPath +
"&fileName=" +
this.word.fileName +
"&fileSize=" +
this.word.fileSize +
"&isPdf=true&aiTopicId=" +
this.topic.topicId,
{
headers: {
token: this.$cookies.get("userToken")
}
}
);
} else {
source = new EventSourcePolyfill(
Url +
"userApp/ai/sse?question=" +
this.talk +
"&isPdf=false&aiTopicId=" +
this.topic.topicId,
{
headers: {
token: this.$cookies.get("userToken")
}
}
);
}
// open:订阅成功(和后端连接成功)
source.addEventListener("open", function(e) {});
source.onmessage = e => {
// console.log(JSON.parse(e.data));
if (JSON.parse(e.data).end) {
// 结束了
item.aiId = JSON.parse(e.data).end;
this.disabled = false;
return;
} else if (JSON.parse(e.data).error) {
this.$message.error(JSON.parse(e.data).error);
this.disabled = false;
return;
} else {
item.aiReply += JSON.parse(e.data).content.replace(/\\n/g, "\n");
if (this.isScrolling) {
chatContent.scrollTop = chatContent.scrollHeight;
}
}
};
source.onerror = event => {
if (event.error !== undefined) {
this.$message.error("出错了,请联系客服人员");
}
this.disabled = false;
event.target.close();
};
},
// 上传文件
talkchange(file, fileList) {
this.$refs.upload.uploadFiles = [];
this.fileList = [];
this.fileList = fileList;
},
async http(file, fileList) {
var formData = new FormData();
formData.append("files", file.file);
this.$axios.post("/dev/file/uploadFile", formData).then(res => {
if (res.code === 200) {
this.word = {
fileName: res.data[0].fileName,
fileSize: res.data[0].fileSize,
fileDownloadPath: res.data[0].fileDownloadPath
};
// this.$message.success("上传成功");
this.sub(1);
}
});
},
}
};
</script>