Browse Source

滑动节流,防止用户重复提交

hxl
hongxilin 2 months ago
parent
commit
00be6bcd56
  1. 1
      README.md
  2. 6
      package-lock.json
  3. 1
      package.json
  4. 14
      src/store/chat.js
  5. 15
      src/views/AIchat.vue
  6. 29
      src/views/homePage.vue

1
README.md

@ -16,3 +16,4 @@ npm install katex 数学公式 解析数学公式样式
npm install @coze/api
npm install html-to-text
npm install echarts
npm install lodash 安装 lodash 组件,解决数据处理问题

6
package-lock.json

@ -20,6 +20,7 @@
"howler": "^2.2.4",
"html-to-text": "^9.0.5",
"katex": "^0.16.21",
"lodash": "^4.17.21",
"marked": "^15.0.7",
"mitt": "^3.0.1",
"pinia": "^2.3.1",
@ -4926,8 +4927,9 @@
},
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
"resolved": "https://mirrors.huaweicloud.com/repository/npm/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"license": "MIT"
},
"node_modules/lodash-es": {
"version": "4.17.21",

1
package.json

@ -27,6 +27,7 @@
"howler": "^2.2.4",
"html-to-text": "^9.0.5",
"katex": "^0.16.21",
"lodash": "^4.17.21",
"marked": "^15.0.7",
"mitt": "^3.0.1",
"pinia": "^2.3.1",

14
src/store/chat.js

@ -2,8 +2,20 @@ import { defineStore } from 'pinia';
export const useChatStore = defineStore('chat', {
state: () => ({
messages: []
messages: [],
isLoading: false // 新增加载状态
}),
actions: {
setLoading(status) {
this.isLoading = status
},
isLoadingT() {
this.isLoading = true;
},
isLoadingF() {
this.isLoading = false;
}
},
persist: {
enabled: true,
strategies: [

15
src/views/AIchat.vue

@ -34,7 +34,7 @@ const showQuestions = (questions) => {
currentQuestions.value = questions;
//
emit("updateMessage", questions.title);
emit("sendMessage");
// emit("sendMessage");
};
//
@ -78,9 +78,6 @@ const props = defineProps({
messages: Array,
});
//
const isLoading = ref(false);
//
const typewriterContent = ref("")
const isTyping = ref(false)
@ -116,7 +113,6 @@ watch(
if (newVal.length > 0) {
console.log("消息列表已更新,最新消息:", newVal[newVal.length - 1])
chatStore.messages.push(newVal[newVal.length - 1])
isLoading.value = true;
console.log("消息列表已更新,最新消息:", chatMsg[chatMsg.length - 1]);
@ -300,13 +296,10 @@ watch(
return match;
}
});
chatStore.setLoading(false);
});
}
}, 50); // 50ms/
//
isLoading.value = false;
}
catch (e) {
console.error('请求失败:', e);
@ -314,11 +307,9 @@ watch(
sender: "ai",
content: "AI思考失败,请稍后再试... ",
});
chatStore.setLoading(false);
}
}
},
{ deep: true }
);

29
src/views/homePage.vue

@ -9,8 +9,10 @@ import { useAppBridge } from '../assets/js/useAppBridge.js'
import { useDataStore } from '@/store/dataList.js'
import { useChatStore } from '../store/chat'
import { useAudioStore } from '../store/audio'
import _ from "lodash";
// import { useUserStore } from "../store/userPessionCode.js";
const { getQueryVariable } = useDataStore()
//
//
const audioStore = useAudioStore()
@ -88,7 +90,7 @@ const message = ref("");
//
const messages = ref([]);
//
const isLoading = ref(false);
const isLoading = computed(() => { chatStore.isLoading });
//
const updateMessage = (title) => {
@ -100,7 +102,11 @@ const sendMessage = async () => {
ensureAIchat();
if (!message.value) return;
if (isLoading.value) return;
if (chatStore.isLoading) return;
console.log(chatStore.isLoading, 'isLoading.value1111');
chatStore.setLoading(true);
console.log(chatStore.isLoading, 'isLoading.value2222');
// isLoading true
messages.value = [
@ -160,13 +166,14 @@ const smoothScrollToBottom = async () => {
}
const throttledSmoothScrollToBottom = _.throttle(smoothScrollToBottom, 500, { trailing: false });
const handleScroll = function () {
const scrollContainer = tabContent.value
const scrollTop = scrollContainer.scrollTop
const scrollHeight = scrollContainer.scrollHeight
const offsetHeight = scrollContainer.offsetHeight
console.log(scrollTop, scrollHeight, offsetHeight, "scrollTop, scrollHeight, offsetHeight");
// console.log(scrollTop, scrollHeight, offsetHeight, "scrollTop, scrollHeight, offsetHeight");
if (scrollTop + offsetHeight < scrollHeight) {
//
isScrolling.value = true
@ -174,14 +181,14 @@ const handleScroll = function () {
//
isScrolling.value = false
}
console.log(isScrolling.value)
// console.log(isScrolling.value)
}
watch(
() => chatStore.messages,
() => {
smoothScrollToBottom();
throttledSmoothScrollToBottom();
},
{ deep: true, immediate: true }
);
@ -190,7 +197,7 @@ watch(
watch(
activeTab,
async (newVal) => {
smoothScrollToBottom();
throttledSmoothScrollToBottom();
});
@ -230,7 +237,7 @@ const fnGetToken = () => {
onMounted(async () => {
setHeight(document.getElementById("testId")); //
getUserCount();
smoothScrollToBottom();
throttledSmoothScrollToBottom();
//
tabContent.value.addEventListener('scroll', handleScroll)
@ -288,7 +295,13 @@ onMounted(async () => {
<img v-else src="src\assets\img\homePage\tail\voice-no-active.png" @click="toggleVoice"
class="action-btn" />
</div>
<img src="src\assets\img\homePage\tail\send.png" @click="sendMessage" class="action-btn send-btn" />
<img v-if="!chatStore.isLoading" src="src\assets\img\homePage\tail\send.png" @click="sendMessage"
class="action-btn send-btn" />
<div v-else>
<el-icon class="is-loading">
<Loading />
</el-icon>
</div>
</div>
<!-- 第二行输入框 -->

Loading…
Cancel
Save