Browse Source

打字机效果按顺序输出

ds_hxl
no99 1 week ago
parent
commit
eec1174df3
  1. 636
      src/views/AIchat.vue
  2. 109
      src/views/homePage.vue

636
src/views/AIchat.vue

@ -22,7 +22,7 @@ import katex from "katex"; // 引入 KaTeX 库
import { htmlToText } from "html-to-text"; import { htmlToText } from "html-to-text";
import { Howl, Howler } from "howler"; import { Howl, Howler } from "howler";
import * as echarts from "echarts"; import * as echarts from "echarts";
import _ from "lodash";
import _, { add } from "lodash";
import moment from "moment"; import moment from "moment";
import AIgif1 from "@/assets/img/AIchat/AIgif1.gif"; import AIgif1 from "@/assets/img/AIchat/AIgif1.gif";
@ -212,6 +212,150 @@ const fnGetData = (data) => {
return sz.value; return sz.value;
}; };
const typingQueue = ref([]);
const isTypingInProgress = ref(false);
// Promise
const createTypingEffect = (message, content, speed) => {
return new Promise((resolve) => {
chatStore.messages.push(message);
if (content != "") {
let index = 0;
message.content = "";
message.isTyping = true;
const typingInterval = setInterval(() => {
if (index < content.length) {
message.content += content.charAt(index);
index++;
} else {
clearInterval(typingInterval);
message.isTyping = false;
// KaTeX
nextTick(() => {
if (message.content.includes("$$")) {
message.content = message.content.replace(
katexRegex,
(match, formula) => {
try {
return katex.renderToString(formula, {
throwOnError: false,
});
} catch (error) {
console.error("KaTeX 渲染错误:", error);
return match;
}
}
);
}
resolve(); // resolve
});
}
}, speed);
} else {
if (message.kline) {
if (message.klineType == 1) {
console.log("六色罗盘消息已添加到聊天列表");
//
nextTick(() => {
console.log("nextTick开始 - 准备渲染图表");
console.log("消息列表:", chatStore.messages);
// K线
let klineIndex = -1;
for (let i = 0; i < chatStore.messages.length; i++) {
if (chatStore.messages[i].messageId === message.messageId) {
klineIndex = i;
break;
}
}
console.log("找到的K线消息索引:", klineIndex);
if (klineIndex !== -1) {
const containerId = `kline-container-${klineIndex}`;
console.log("图表容器ID:", containerId);
// DOM
setTimeout(() => {
console.log("延时执行,确保DOM已渲染");
KlineCanvsEcharts(containerId);
}, 100); // DOM
} else {
console.warn("未找到K线消息");
}
});
} else {
console.log("K线消息已添加到聊天列表");
//
nextTick(() => {
console.log("nextTick开始 - 准备渲染图表");
console.log("消息列表:", chatStore.messages);
// K线
let klineIndex = -1;
for (let i = 0; i < chatStore.messages.length; i++) {
if (chatStore.messages[i].messageId === message.messageId) {
klineIndex = i;
break;
}
}
console.log("找到的K线消息索引:", klineIndex);
if (klineIndex !== -1) {
const containerId = `kline-container-${klineIndex}`;
console.log("图表容器ID:", containerId);
// DOM
setTimeout(() => {
console.log("延时执行,确保DOM已渲染");
KlineCanvsEcharts(containerId);
}, 100); // DOM
} else {
console.warn("未找到K线消息");
}
});
}
// 1resolve
setTimeout(() => {
resolve();
}, 1000);
} else {
// 1resolve
setTimeout(() => {
resolve();
}, 1000);
}
}
});
};
//
const processTypingQueue = async () => {
if (isTypingInProgress.value || typingQueue.value.length === 0) {
return;
}
isTypingInProgress.value = true;
while (typingQueue.value.length > 0) {
const task = typingQueue.value.shift();
await createTypingEffect(task.message, task.content, task.speed);
}
isTypingInProgress.value = false;
};
//
const addTypingTask = (message, content, speed = 50) => {
typingQueue.value.push({ message, content, speed });
processTypingQueue();
};
const hasValidData = ref(false); const hasValidData = ref(false);
// //
@ -352,13 +496,24 @@ watch(
// //
chatStore.messages.pop(); chatStore.messages.pop();
// //
chatStore.messages.push({
sender: "ai",
class: "title1",
type: "title1",
content: codeData.value.name + "全景作战报告",
date: moment().format("MM/DD/YYYY"),
});
addTypingTask(
{
sender: "ai",
class: "title1",
type: "title1",
content: codeData.value.name + "全景作战报告",
date: moment().format("MM/DD/YYYY"),
},
"",
50
);
// chatStore.messages.push({
// sender: "ai",
// class: "title1",
// type: "title1",
// content: codeData.value.name + "",
// date: moment().format("MM/DD/YYYY"),
// });
// //
const pc1 = marked( const pc1 = marked(
@ -385,18 +540,20 @@ watch(
content: "", content: "",
isTyping: true, isTyping: true,
}); });
chatStore.messages.push(aiMessage1);
// chatStore.messages.push(aiMessage1);
// let index1 = 0;
// const typingInterval1 = setInterval(() => {
// if (index1 < ac1.length) {
// aiMessage1.content += ac1.charAt(index1);
// index1++;
// } else {
// clearInterval(typingInterval1);
// aiMessage1.isTyping = false;
// }
// }, 50); // 50ms/
let index1 = 0;
const typingInterval1 = setInterval(() => {
if (index1 < ac1.length) {
aiMessage1.content += ac1.charAt(index1);
index1++;
} else {
clearInterval(typingInterval1);
aiMessage1.isTyping = false;
}
}, 50); // 50ms/
addTypingTask(aiMessage1, ac1, 50);
// chatStore.messages.push({ // chatStore.messages.push({
// sender: "ai", // sender: "ai",
@ -415,48 +572,62 @@ watch(
const klineMessageId1 = `kline-${Date.now()}`; const klineMessageId1 = `kline-${Date.now()}`;
console.log("生成K线消息ID:", klineMessageId1); console.log("生成K线消息ID:", klineMessageId1);
chatStore.messages.push({
sender: "ai",
class: "content1",
type: "content1",
kline: true,
chartData: sz,
messageId: klineMessageId1,
hasValidData: true,
klineType: 1,
});
addTypingTask(
{
sender: "ai",
class: "content1",
type: "content1",
kline: true,
chartData: sz,
messageId: klineMessageId1,
hasValidData: true,
klineType: 1,
},
"",
50
);
// chatStore.messages.push({
// sender: "ai",
// class: "content1",
// type: "content1",
// kline: true,
// chartData: sz,
// messageId: klineMessageId1,
// hasValidData: true,
// klineType: 1,
// });
console.log("六色罗盘消息已添加到聊天列表");
// console.log("");
//
nextTick(() => {
console.log("nextTick开始 - 准备渲染图表");
console.log("消息列表:", chatStore.messages);
// //
// nextTick(() => {
// console.log("nextTick - ");
// console.log(":", chatStore.messages);
// K线
let klineIndex = -1;
for (let i = 0; i < chatStore.messages.length; i++) {
if (chatStore.messages[i].messageId === klineMessageId1) {
klineIndex = i;
break;
}
}
// // K线
// let klineIndex = -1;
// for (let i = 0; i < chatStore.messages.length; i++) {
// if (chatStore.messages[i].messageId === klineMessageId1) {
// klineIndex = i;
// break;
// }
// }
console.log("找到的K线消息索引:", klineIndex);
// console.log("K线:", klineIndex);
if (klineIndex !== -1) {
const containerId = `kline-container-${klineIndex}`;
console.log("图表容器ID:", containerId);
// if (klineIndex !== -1) {
// const containerId = `kline-container-${klineIndex}`;
// console.log("ID:", containerId);
// DOM
setTimeout(() => {
console.log("延时执行,确保DOM已渲染");
KlineCanvsEcharts(containerId);
}, 100); // DOM
} else {
console.warn("未找到K线消息");
}
});
// // DOM
// setTimeout(() => {
// console.log("DOM");
// KlineCanvsEcharts(containerId);
// }, 100); // DOM
// } else {
// console.warn("K线");
// }
// });
// K线 // K线
const AIGoldBullData = JSON.parse(JSON.stringify(toRaw(AIGoldBull))); const AIGoldBullData = JSON.parse(JSON.stringify(toRaw(AIGoldBull)));
@ -485,56 +656,81 @@ watch(
const klineMessageId2 = `kline-${Date.now() + 1}`; const klineMessageId2 = `kline-${Date.now() + 1}`;
console.log("生成K线消息ID:", klineMessageId2); console.log("生成K线消息ID:", klineMessageId2);
chatStore.messages.push({
sender: "ai",
class: "content2",
type: "content2",
kline: true,
chartData: Kline20,
messageId: klineMessageId2,
hasValidData: true, // hasValidData
klineType: 2,
});
// chatStore.messages.push({
// sender: "ai",
// class: "content2",
// type: "content2",
// kline: true,
// chartData: Kline20,
// messageId: klineMessageId2,
// hasValidData: true, // hasValidData
// klineType: 2,
// });
console.log("K线消息已添加到聊天列表");
addTypingTask(
{
sender: "ai",
class: "content2",
type: "content2",
kline: true,
chartData: Kline20,
messageId: klineMessageId2,
hasValidData: true, // hasValidData
klineType: 2,
},
"",
50
);
//
nextTick(() => {
console.log("nextTick开始 - 准备渲染图表");
console.log("消息列表:", chatStore.messages);
// console.log("K线");
// K线
let klineIndex = -1;
for (let i = 0; i < chatStore.messages.length; i++) {
if (chatStore.messages[i].messageId === klineMessageId2) {
klineIndex = i;
break;
}
}
// //
// nextTick(() => {
// console.log("nextTick - ");
// console.log(":", chatStore.messages);
console.log("找到的K线消息索引:", klineIndex);
// // K线
// let klineIndex = -1;
// for (let i = 0; i < chatStore.messages.length; i++) {
// if (chatStore.messages[i].messageId === klineMessageId2) {
// klineIndex = i;
// break;
// }
// }
if (klineIndex !== -1) {
const containerId = `kline-container-${klineIndex}`;
console.log("图表容器ID:", containerId);
// console.log("K线:", klineIndex);
// DOM
setTimeout(() => {
console.log("延时执行,确保DOM已渲染");
KlineCanvsEcharts(containerId);
}, 100); // DOM
} else {
console.warn("未找到K线消息");
}
});
// if (klineIndex !== -1) {
// const containerId = `kline-container-${klineIndex}`;
// console.log("ID:", containerId);
// // DOM
// setTimeout(() => {
// console.log("DOM");
// KlineCanvsEcharts(containerId);
// }, 100); // DOM
// } else {
// console.warn("K线");
// }
// });
// 2 // 2
chatStore.messages.push({
sender: "ai",
class: "title2",
type: "title2",
content: "",
});
addTypingTask(
{
sender: "ai",
class: "title2",
type: "title2",
content: "",
},
"",
50
);
// chatStore.messages.push({
// sender: "ai",
// class: "title2",
// type: "title2",
// content: "",
// });
// 1 // 1
const pc2 = marked(result22.data.hxjzpg); const pc2 = marked(result22.data.hxjzpg);
console.log(pc2, "pc2"); console.log(pc2, "pc2");
@ -555,18 +751,19 @@ watch(
content: "", content: "",
isTyping: true, isTyping: true,
}); });
chatStore.messages.push(aiMessage2);
let index2 = 0;
const typingInterval2 = setInterval(() => {
if (index2 < ac2.length) {
aiMessage2.content += ac2.charAt(index2);
index2++;
} else {
clearInterval(typingInterval2);
aiMessage2.isTyping = false;
}
}, 50); // 50ms/
// chatStore.messages.push(aiMessage2);
// let index2 = 0;
// const typingInterval2 = setInterval(() => {
// if (index2 < ac2.length) {
// aiMessage2.content += ac2.charAt(index2);
// index2++;
// } else {
// clearInterval(typingInterval2);
// aiMessage2.isTyping = false;
// }
// }, 50); // 50ms/
addTypingTask(aiMessage2, ac2, 50);
// chatStore.messages.push({ // chatStore.messages.push({
// sender: "ai", // sender: "ai",
@ -575,12 +772,22 @@ watch(
// content: ac2, // content: ac2,
// }); // });
// 3-2 // 3-2
chatStore.messages.push({
sender: "ai",
class: "title3",
type: "title3",
content: title2,
});
addTypingTask(
{
sender: "ai",
class: "title3",
type: "title3",
content: title2,
},
"",
50
);
// chatStore.messages.push({
// sender: "ai",
// class: "title3",
// type: "title3",
// content: title2,
// });
// 2 // 2
// const pc3 = marked(result23.data.zhuli1+'\n'+result23.data.zhuli2+'\n'+result23.data.zhuli3); // const pc3 = marked(result23.data.zhuli1+'\n'+result23.data.zhuli2+'\n'+result23.data.zhuli3);
// const ac3 = pc3.replace( // const ac3 = pc3.replace(
@ -604,35 +811,20 @@ watch(
content: "", content: "",
isTyping: true, isTyping: true,
}); });
chatStore.messages.push(aiMessage3);
// chatStore.messages.push(aiMessage3);
let index3 = 0;
const typingInterval3 = setInterval(() => {
if (index3 < ac3.length) {
aiMessage3.content += ac3.charAt(index3);
index3++;
} else {
clearInterval(typingInterval3);
aiMessage3.isTyping = false;
// KaTeXDOM
nextTick(() => {
aiMessage3.content = aiMessage3.content.replace(
katexRegex,
(match, formula) => {
try {
return katex.renderToString(formula, {
throwOnError: false,
});
} catch (error) {
console.error("KaTeX 渲染错误:", error);
return match;
}
}
);
});
}
}, 50); // 50ms/
// let index3 = 0;
// const typingInterval3 = setInterval(() => {
// if (index3 < ac3.length) {
// aiMessage3.content += ac3.charAt(index3);
// index3++;
// } else {
// clearInterval(typingInterval3);
// aiMessage3.isTyping = false;
// }
// }, 50); // 50ms/
addTypingTask(aiMessage3, ac3, 50);
// chatStore.messages.push({ // chatStore.messages.push({
// sender: "ai", // sender: "ai",
@ -641,12 +833,22 @@ watch(
// content: ac3, // content: ac3,
// }); // });
// 3-3 // 3-3
chatStore.messages.push({
sender: "ai",
class: "title3",
type: "title3",
content: title3,
});
addTypingTask(
{
sender: "ai",
class: "title3",
type: "title3",
content: title3,
},
"",
50
);
// chatStore.messages.push({
// sender: "ai",
// class: "title3",
// type: "title3",
// content: title3,
// });
// 3 // 3
const arr = result23.data.kongjian.split(","); const arr = result23.data.kongjian.split(",");
const kongjian = `<p style="margin:0;color:#FADC0C;display:flex;justify-content:center;font-size:28px">【空间维度】</p><p style="display:flex;justify-content:center;">${arr[0]},${arr[1]}</p><p style="display:flex;justify-content:center;">${arr[2]},${arr[3]}</p>`; const kongjian = `<p style="margin:0;color:#FADC0C;display:flex;justify-content:center;font-size:28px">【空间维度】</p><p style="display:flex;justify-content:center;">${arr[0]},${arr[1]}</p><p style="display:flex;justify-content:center;">${arr[2]},${arr[3]}</p>`;
@ -678,35 +880,20 @@ watch(
content: "", content: "",
isTyping: true, isTyping: true,
}); });
chatStore.messages.push(aiMessage4);
// chatStore.messages.push(aiMessage4);
let index4 = 0;
const typingInterval4 = setInterval(() => {
if (index4 < ac4.length) {
aiMessage4.content += ac4.charAt(index4);
index4++;
} else {
clearInterval(typingInterval4);
aiMessage4.isTyping = false;
// KaTeXDOM
nextTick(() => {
aiMessage4.content = aiMessage4.content.replace(
katexRegex,
(match, formula) => {
try {
return katex.renderToString(formula, {
throwOnError: false,
});
} catch (error) {
console.error("KaTeX 渲染错误:", error);
return match;
}
}
);
});
}
}, 50); // 50ms/
// let index4 = 0;
// const typingInterval4 = setInterval(() => {
// if (index4 < ac4.length) {
// aiMessage4.content += ac4.charAt(index4);
// index4++;
// } else {
// clearInterval(typingInterval4);
// aiMessage4.isTyping = false;
// }
// }, 50); // 50ms/
addTypingTask(aiMessage4, ac4, 50);
// chatStore.messages.push({ // chatStore.messages.push({
// sender: "ai", // sender: "ai",
@ -715,6 +902,16 @@ watch(
// content: ac4, // content: ac4,
// }); // });
// 3-4 // 3-4
addTypingTask(
{
sender: "ai",
class: "title3",
type: "title3",
content: title4,
},
"",
50
);
chatStore.messages.push({ chatStore.messages.push({
sender: "ai", sender: "ai",
class: "title3", class: "title3",
@ -744,35 +941,20 @@ watch(
content: "", content: "",
isTyping: true, isTyping: true,
}); });
chatStore.messages.push(aiMessage5);
// chatStore.messages.push(aiMessage5);
let index5 = 0;
const typingInterval5 = setInterval(() => {
if (index5 < ac5.length) {
aiMessage5.content += ac5.charAt(index5);
index5++;
} else {
clearInterval(typingInterval5);
aiMessage5.isTyping = false;
// KaTeXDOM
nextTick(() => {
aiMessage5.content = aiMessage5.content.replace(
katexRegex,
(match, formula) => {
try {
return katex.renderToString(formula, {
throwOnError: false,
});
} catch (error) {
console.error("KaTeX 渲染错误:", error);
return match;
}
}
);
});
}
}, 50); // 50ms/
// let index5 = 0;
// const typingInterval5 = setInterval(() => {
// if (index5 < ac5.length) {
// aiMessage5.content += ac5.charAt(index5);
// index5++;
// } else {
// clearInterval(typingInterval5);
// aiMessage5.isTyping = false;
// }
// }, 50); // 50ms/
addTypingTask(aiMessage5, ac5, 50);
// chatStore.messages.push({ // chatStore.messages.push({
// sender: "ai", // sender: "ai",
@ -790,35 +972,20 @@ watch(
content: "", content: "",
isTyping: true, isTyping: true,
}); });
chatStore.messages.push(aiMessage6);
// chatStore.messages.push(aiMessage6);
let index6 = 0;
const typingInterval6 = setInterval(() => {
if (index6 < ac6.length) {
aiMessage6.content += ac6.charAt(index6);
index6++;
} else {
clearInterval(typingInterval6);
aiMessage6.isTyping = false;
// KaTeXDOM
nextTick(() => {
aiMessage6.content = aiMessage6.content.replace(
katexRegex,
(match, formula) => {
try {
return katex.renderToString(formula, {
throwOnError: false,
});
} catch (error) {
console.error("KaTeX 渲染错误:", error);
return match;
}
}
);
});
}
}, 50); // 50ms/
// let index6 = 0;
// const typingInterval6 = setInterval(() => {
// if (index6 < ac6.length) {
// aiMessage6.content += ac6.charAt(index6);
// index6++;
// } else {
// clearInterval(typingInterval6);
// aiMessage6.isTyping = false;
// }
// }, 50); // 50ms/
addTypingTask(aiMessage6, ac6, 100);
// chatStore.messages.push({ // chatStore.messages.push({
// sender: "ai", // sender: "ai",
@ -921,8 +1088,9 @@ watch(
// sender: "ai", // sender: "ai",
// content: "AI... ", // content: "AI... ",
// }); // });
chatStore.setLoading(false);
// chatStore.setLoading(false);
} finally { } finally {
chatStore.setLoading(false);
await chatStore.getUserCount(); await chatStore.getUserCount();
} }
} }

109
src/views/homePage.vue

@ -238,7 +238,7 @@ const smoothScrollToBottom = async () => {
} }
}; };
const throttledSmoothScrollToBottom = _.throttle(smoothScrollToBottom, 500, {
const throttledSmoothScrollToBottom = _.throttle(smoothScrollToBottom, 300, {
trailing: false, trailing: false,
}); });
@ -306,7 +306,7 @@ const fnGetToken = () => {
}; };
// console.log('') // console.log('')
// App // App
useAppBridge().packageFun("JWwebReady", () => { }, 5, {});
useAppBridge().packageFun("JWwebReady", () => {}, 5, {});
}; };
// setTimeout // setTimeout
@ -323,7 +323,7 @@ const heightListener = () => {
// //
const isBottom = const isBottom =
aftertop + tabContainer.offsetHeight + 50 >= tabContainer.scrollHeight;
aftertop + tabContainer.offsetHeight + 70 >= tabContainer.scrollHeight;
if (activeTab.value === "AIchat") { if (activeTab.value === "AIchat") {
if (aftertop - befortop > 0) { if (aftertop - befortop > 0) {
@ -526,8 +526,16 @@ onMounted(async () => {
<img :src="getCountAll" class="action-btn" /> <img :src="getCountAll" class="action-btn" />
<div class="count-number">{{ UserCount }}</div> <div class="count-number">{{ UserCount }}</div>
</div> </div>
<img :src="announcementBtn" class="announcement-btn action-btn" @click="showAnnouncement" />
<img :src="feedbackBtn" class="announcement-btn action-btn" @click="showFeedback" />
<img
:src="announcementBtn"
class="announcement-btn action-btn"
@click="showAnnouncement"
/>
<img
:src="feedbackBtn"
class="announcement-btn action-btn"
@click="showFeedback"
/>
</div> </div>
</el-header> </el-header>
@ -536,17 +544,28 @@ onMounted(async () => {
<div class="main-wrapper"> <div class="main-wrapper">
<section class="tab-section"> <section class="tab-section">
<div class="tab-container"> <div class="tab-container">
<div v-for="(tab, index) in tabs" :key="tab.name" @click="setActiveTab(tab.name, index)" :class="[
'tab-item',
{ active: activeIndex === index && !isAnnouncementVisible },
]">
<div
v-for="(tab, index) in tabs"
:key="tab.name"
@click="setActiveTab(tab.name, index)"
:class="[
'tab-item',
{ active: activeIndex === index && !isAnnouncementVisible },
]"
>
<span>{{ tab.label }}</span> <span>{{ tab.label }}</span>
</div> </div>
</div> </div>
</section> </section>
<div class="tab-content" ref="tabContent"> <div class="tab-content" ref="tabContent">
<component :is="activeComponent" :messages="messages" @updateMessage="updateMessage"
@sendMessage="sendMessage" @ensureAIchat="ensureAIchat" ref="aiEmotionRef" />
<component
:is="activeComponent"
:messages="messages"
@updateMessage="updateMessage"
@sendMessage="sendMessage"
@ensureAIchat="ensureAIchat"
ref="aiEmotionRef"
/>
</div> </div>
</div> </div>
</el-main> </el-main>
@ -559,16 +578,42 @@ onMounted(async () => {
<img v-else :src="thinkNoActive" @click="toggleThink" class="action-btn" /> <img v-else :src="thinkNoActive" @click="toggleThink" class="action-btn" />
<img :src="languageBtn" @click="changeLanguage" class="action-btn" /> --> <img :src="languageBtn" @click="changeLanguage" class="action-btn" /> -->
<!-- 夺宝奇兵大模型按钮 --> <!-- 夺宝奇兵大模型按钮 -->
<img :src="activeTab === 'AIchat' ? dbqbButton01 : dbqbButton02" @click="setActiveTab('AIchat', 0)"
class="action-btn model-btn" alt="夺宝奇兵大模型" />
<img
:src="activeTab === 'AIchat' ? dbqbButton01 : dbqbButton02"
@click="setActiveTab('AIchat', 0)"
class="action-btn model-btn"
alt="夺宝奇兵大模型"
/>
<!-- AI情绪大模型按钮 --> <!-- AI情绪大模型按钮 -->
<img :src="activeTab === 'AiEmotion' ? emotionButton01 : emotionButton02
" @click="setActiveTab('AiEmotion', 1)" class="action-btn model-btn" alt="AI情绪大模型" />
<img v-if="isVoice" :src="voice" @click="toggleVoice" class="action-btn" />
<img v-else :src="voiceNoActive" @click="toggleVoice" class="action-btn" />
<img
:src="
activeTab === 'AiEmotion' ? emotionButton01 : emotionButton02
"
@click="setActiveTab('AiEmotion', 1)"
class="action-btn model-btn"
alt="AI情绪大模型"
/>
<img
v-if="isVoice"
:src="voice"
@click="toggleVoice"
class="action-btn"
/>
<img
v-else
:src="voiceNoActive"
@click="toggleVoice"
class="action-btn"
/>
</div> </div>
<img v-if="!chatStore.isLoading" :src="sendBtn" @click="sendMessage" class="action-btn send-btn" />
<div v-else @click="chatStore.setLoading(false)">
<img
v-if="!chatStore.isLoading"
:src="sendBtn"
@click="sendMessage"
class="action-btn send-btn"
/>
<!-- <div v-else @click="chatStore.setLoading(false)"> -->
<div v-else>
<el-icon class="is-loading"> <el-icon class="is-loading">
<Loading /> <Loading />
</el-icon> </el-icon>
@ -578,9 +623,17 @@ onMounted(async () => {
<!-- 第二行输入框 --> <!-- 第二行输入框 -->
<div class="footer-second-line"> <div class="footer-second-line">
<img :src="msgBtn" class="msg-icon" /> <img :src="msgBtn" class="msg-icon" />
<el-input type="textarea" v-model="message" @focus="onFocus" @blur="onBlur"
:autosize="{ minRows: 1, maxRows: 4 }" placeholder="给AI小财神发消息..." class="msg-input"
@keydown.enter.exact.prevent="isLoading ? null : sendMessage()" resize="none">
<el-input
type="textarea"
v-model="message"
@focus="onFocus"
@blur="onBlur"
:autosize="{ minRows: 1, maxRows: 4 }"
placeholder="给AI小财神发消息..."
class="msg-input"
@keydown.enter.exact.prevent="isLoading ? null : sendMessage()"
resize="none"
>
</el-input> </el-input>
</div> </div>
</el-footer> </el-footer>
@ -598,8 +651,16 @@ onMounted(async () => {
<img :src="getCountAll" class="action-btn" /> <img :src="getCountAll" class="action-btn" />
<div class="count-number">{{ UserCount }}</div> <div class="count-number">{{ UserCount }}</div>
</div> </div>
<img :src="announcementBtn" class="announcement-btn action-btn" @click="showAnnouncement" />
<img :src="feedbackBtn" class="announcement-btn action-btn" @click="showFeedback" />
<img
:src="announcementBtn"
class="announcement-btn action-btn"
@click="showAnnouncement"
/>
<img
:src="feedbackBtn"
class="announcement-btn action-btn"
@click="showFeedback"
/>
</div> </div>
</el-header> </el-header>

Loading…
Cancel
Save