Browse Source

夺宝大模型数据展示

ds_hxl
no99 2 weeks ago
parent
commit
422fbc5e95
  1. 4
      .env.development
  2. 8
      package-lock.json
  3. 2
      package.json
  4. 59
      src/api/AIxiaocaishen.js
  5. 1
      src/utils/request.js
  6. 818
      src/views/AIchat.vue
  7. 372
      src/views/homePage.vue

4
.env.development

@ -5,8 +5,8 @@ VITE_OUTPUT_DIR = 'dev'
VITE_PUBLIC_PATH = / VITE_PUBLIC_PATH = /
#新数据接口 #新数据接口
# VITE_APP_API_BASE_URL = "http://39.101.133.168:8828/link"
VITE_APP_API_BASE_URL = "https://api.homilychart.com/link"
VITE_APP_API_BASE_URL = "http://39.101.133.168:8828/link"
# VITE_APP_API_BASE_URL = "https://api.homilychart.com/link"
VITE_APP_IMG_API_BASE_URL = "http://39.101.133.168:8828/hljw/api/aws/upload" VITE_APP_IMG_API_BASE_URL = "http://39.101.133.168:8828/hljw/api/aws/upload"
#MJ API #MJ API

8
package-lock.json

@ -21,7 +21,7 @@
"html-to-text": "^9.0.5", "html-to-text": "^9.0.5",
"katex": "^0.16.21", "katex": "^0.16.21",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"marked": "^15.0.7",
"marked": "^15.0.12",
"mitt": "^3.0.1", "mitt": "^3.0.1",
"moment": "^2.30.1", "moment": "^2.30.1",
"pinia": "^2.3.1", "pinia": "^2.3.1",
@ -5117,9 +5117,9 @@
} }
}, },
"node_modules/marked": { "node_modules/marked": {
"version": "15.0.7",
"resolved": "https://mirrors.huaweicloud.com/repository/npm/marked/-/marked-15.0.7.tgz",
"integrity": "sha512-dgLIeKGLx5FwziAnsk4ONoGwHwGPJzselimvlVskE9XLN4Orv9u2VA3GWw/lYUqjfA0rUT/6fqKwfZJapP9BEg==",
"version": "15.0.12",
"resolved": "https://mirrors.huaweicloud.com/repository/npm/marked/-/marked-15.0.12.tgz",
"integrity": "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==",
"license": "MIT", "license": "MIT",
"bin": { "bin": {
"marked": "bin/marked.js" "marked": "bin/marked.js"

2
package.json

@ -28,7 +28,7 @@
"html-to-text": "^9.0.5", "html-to-text": "^9.0.5",
"katex": "^0.16.21", "katex": "^0.16.21",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"marked": "^15.0.7",
"marked": "^15.0.12",
"mitt": "^3.0.1", "mitt": "^3.0.1",
"moment": "^2.30.1", "moment": "^2.30.1",
"pinia": "^2.3.1", "pinia": "^2.3.1",

59
src/api/AIxiaocaishen.js

@ -213,12 +213,53 @@ export const getMarketAndCodeAPI = function (params) {
}; };
// 登录获取次数接口 // 登录获取次数接口
export const addUsageAPI = function (params) { export const addUsageAPI = function (params) {
return request({
url: `${APIurl}/api/ai_god/addUsage`,
method: "POST",
data: new URLSearchParams(params),
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
});
};
return request({
url: `${APIurl}/api/ai_god/addUsage`,
method: "POST",
data: new URLSearchParams(params),
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
});
};
// duobao11
export const dbqbFirstAPI = function (params) {
return request({
url: `${APIurl}/api/workflow/dbqbFirst`,
method: "POST",
data: params,
});
};
// duobao21
export const dbqbSecondOneAPI = function (params) {
return request({
url: `${APIurl}/api/workflow/dbqbSecondOne`,
method: "POST",
data: params,
});
};
// duobao22
export const dbqbSecondTwoAPI = function (params) {
return request({
url: `${APIurl}/api/workflow/dbqbSecondTwo`,
method: "POST",
data: params,
});
};
// duobao23
export const dbqbSecondThreeAPI = function (params) {
return request({
url: `${APIurl}/api/workflow/dbqbSecondThree`,
method: "POST",
data: params,
});
};
// duobao24
export const dbqbSecondFourAPI = function (params) {
return request({
url: `${APIurl}/api/workflow/dbqbSecondFour`,
method: "POST",
data: params,
});
};

1
src/utils/request.js

@ -115,6 +115,7 @@ service.interceptors.response.use(
const errorMsg = res.msg || 'Unkonw error' const errorMsg = res.msg || 'Unkonw error'
// ElMessage.error(errorMsg) // ElMessage.error(errorMsg)
// return Promise.reject(new Error(res.msg || 'Error')) // return Promise.reject(new Error(res.msg || 'Error'))
return response.data
} else { } else {
return response.data return response.data
} }

818
src/views/AIchat.vue

@ -5,8 +5,12 @@ import {
getReplyStreamAPI, getReplyStreamAPI,
getReplyAPI, getReplyAPI,
TTSAPI, TTSAPI,
getQuestionAPI,
qsArpAamClickAPI, qsArpAamClickAPI,
dbqbFirstAPI,
dbqbSecondOneAPI,
dbqbSecondTwoAPI,
dbqbSecondThreeAPI,
dbqbSecondFourAPI,
} from "../api/AIxiaocaishen"; } from "../api/AIxiaocaishen";
import { useUserStore } from "../store/userPessionCode"; import { useUserStore } from "../store/userPessionCode";
import { useChatStore } from "../store/chat"; import { useChatStore } from "../store/chat";
@ -17,6 +21,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 moment from "moment";
import AIgif1 from "@/assets/img/AIchat/AIgif1.gif"; import AIgif1 from "@/assets/img/AIchat/AIgif1.gif";
import AIgif2 from "@/assets/img/AIchat/AIgif2.gif"; import AIgif2 from "@/assets/img/AIchat/AIgif2.gif";
@ -31,92 +36,15 @@ import title3 from "@/assets/img/AIchat/攻防三维.png";
import title4 from "@/assets/img/AIchat/综合作战.png"; import title4 from "@/assets/img/AIchat/综合作战.png";
const gifList = [AIgif1, AIgif2, AIgif3, AIgif4, AIgif5, AIgif6, AIgif7]; const gifList = [AIgif1, AIgif2, AIgif3, AIgif4, AIgif5, AIgif6, AIgif7];
const chatStore = useChatStore(); const chatStore = useChatStore();
const audioStore = useAudioStore(); const audioStore = useAudioStore();
const dataStore = useDataStore(); const dataStore = useDataStore();
// GIF // GIF
const currentGif = ref(""); const currentGif = ref("");
//
const questionsList = ref([]);
const getQuestionsList = async () => {
const result = await getQuestionAPI();
questionsList.value = result.data;
};
// //
const emit = defineEmits(["updateMessage", "sendMessage"]); const emit = defineEmits(["updateMessage", "sendMessage"]);
//
// const currentQuestions = ref("");
// const showQuestions = async (questions) => {
// const click = await qsArpAamClickAPI({
// token: localStorage.getItem("localToken"),
// id: questions.id,
// });
// console.log(click);
// currentQuestions.value = questions;
// //
// emit("updateMessage", questions.title);
// // emit("sendMessage");
// };
//
// const floatingTopMouseEnter = function () {
// const userAgent = navigator.userAgent.toLowerCase();
// const mobileKeywords = ["mobile", "android", "iphone", "ipad", "ipod"];
// const isMobile = mobileKeywords.some((keyword) =>
// userAgent.includes(keyword)
// );
// if (isMobile) {
// return;
// }
// console.log("");
// const floatTop = document.getElementById("top");
// floatTop.style.animationPlayState = "paused";
// };
// const floatingTopMouseLeave = function () {
// const userAgent = navigator.userAgent.toLowerCase();
// const mobileKeywords = ["mobile", "android", "iphone", "ipad", "ipod"];
// const isMobile = mobileKeywords.some((keyword) =>
// userAgent.includes(keyword)
// );
// if (isMobile) {
// return;
// }
// console.log("");
// const floatTop = document.getElementById("top");
// floatTop.style.animationPlayState = "running";
// };
// const floatingBottomMouseEnter = function () {
// const userAgent = navigator.userAgent.toLowerCase();
// const mobileKeywords = ["mobile", "android", "iphone", "ipad", "ipod"];
// const isMobile = mobileKeywords.some((keyword) =>
// userAgent.includes(keyword)
// );
// if (isMobile) {
// return;
// }
// console.log("");
// const floatBottom = document.getElementById("bottom");
// floatBottom.style.animationPlayState = "paused";
// };
// const floatingBottomMouseLeave = function () {
// const userAgent = navigator.userAgent.toLowerCase();
// const mobileKeywords = ["mobile", "android", "iphone", "ipad", "ipod"];
// const isMobile = mobileKeywords.some((keyword) =>
// userAgent.includes(keyword)
// );
// if (isMobile) {
// return;
// }
// console.log("");
// const floatBottom = document.getElementById("bottom");
// floatBottom.style.animationPlayState = "running";
// };
// //
const playAudio = (url) => { const playAudio = (url) => {
// //
@ -276,123 +204,45 @@ watch(
// //
const userStore = useUserStore(); const userStore = useUserStore();
const params = {
content: newVal[newVal.length - 1].content,
userData: {
token: localStorage.getItem("localToken"),
// language: "cn",
// brainPrivilegeState: userStore.brainPerssion,
// swordPrivilegeState: userStore.swordPerssion,
// stockForecastPrivile: userStore.pricePerssion,
// spaceForecastPrivile: userStore.timePerssion,
// aibullPrivilegeState: userStore.aibullPerssion,
// aigoldBullPrivilegeS: userStore.aiGnbullPerssion,
// airadarPrivilegeStat: userStore.airadarPerssion,
// marketList: "hk,cn,usa,my,sg,vi,in,gb"
// token: "+SsksARQgUHIbIG3rRnnbZi0+fEeMx8pywnIlrmTxo5EOPR/wjWDV7w7+ZUseiBtf9kFa/atmNx6QfSpv5w",
language: "cn",
brainPrivilegeState: "1",
swordPrivilegeState: "1",
stockForecastPrivile: "1",
spaceForecastPrivile: "1",
aibullPrivilegeState: "1",
aigoldBullPrivilegeS: "1",
airadarPrivilegeStat: "1",
marketList: "hk,cn,usa,my,sg,vi,in,gb",
const params1 = {
workflow_id: "7514939889071718438",
parameters: {
content: newVal[newVal.length - 1].content,
userData: {
language: "cn",
marketList: "hk,cn,usa,my,sg,vi,in,gb",
token: localStorage.getItem("localToken"),
// language: "cn",
// marketList: "hk,cn,usa,my,sg,vi,in,gb"
// token: "+SsksARQgUHIbIG3rRnnbZi0+fEeMx8pywnIlrmTxo5EOPR/wjWDV7w7+ZUseiBtf9kFa/atmNx6QfSpv5w",
},
}, },
}; };
//
let flag = true;
const codeData = ref();
// ,
try { try {
chatStore.messages.push({
class: "ing",
type: "ing",
content: "正在为您生成特斯拉全景作战报告",
});
chatStore.messages.push({
sender: "ai",
class: "title1",
type: "title1",
content: "特斯拉全景作战报告",
date: "05/06/2025",
});
chatStore.messages.push({
sender: "ai",
class: "title2",
type: "title2",
content: "",
});
chatStore.messages.push({
sender: "ai",
class: "title3",
type: "title3",
content: title2,
});
chatStore.messages.push({
sender: "ai",
class: "title3",
type: "title3",
content: title3,
});
chatStore.messages.push({
sender: "ai",
class: "title3",
type: "title3",
content: title4,
});
chatStore.messages.push({
sender: "ai",
class: "content1",
type: "content1",
content: "股票名称:tesla",
});
chatStore.messages.push({
sender: "ai",
class: "content2",
type: "content2",
content: "K线图",
});
chatStore.messages.push({
sender: "ai",
class: "content3",
type: "content3",
content: "(1)牛股评级:⭐⭐⭐⭐⭐",
});
chatStore.messages.push({
sender: "ai",
class: "mianze",
type: "mianze",
content: "内容由AI生成,请注意甄别",
});
// //
const result = (await getReplyAPI(params)).json();
//
const ans = ref();
await result.then((res) => {
// data JSON
ans.value = JSON.parse(res.data);
});
const AIcontent = ref("");
// answer
if (ans.value.resp !== "" && ans.value.resp !== null) {
const result = await dbqbFirstAPI(params1);
codeData.value = result.data;
console.log(codeData.value, "codeData");
//
if (result.code == 200) {
chatStore.messages.push({
class: "ing",
type: "ing",
flag: flag,
content: result.data.kaishi,
});
} else {
flag = false;
console.log("执行回绝话术"); console.log("执行回绝话术");
AIcontent.value = ans.value.resp;
const AIcontent = ref(result.msg);
// //
const processedContent = marked(AIcontent.value); const processedContent = marked(AIcontent.value);
const katexRegex = /\$\$(.*?)\$\$/g; const katexRegex = /\$\$(.*?)\$\$/g;
// const plainTextContent = htmlToText(processedContent);
const aiContent = processedContent.replace( const aiContent = processedContent.replace(
katexRegex, katexRegex,
(match, formula) => { (match, formula) => {
@ -404,193 +254,416 @@ watch(
} }
} }
); );
console.log(aiContent, "aiContent"); console.log(aiContent, "aiContent");
// chatStore.messages.pop();
chatStore.messages.push({ chatStore.messages.push({
sender: "ai",
class: "ing",
type: "ing",
flag: flag,
content: aiContent, content: aiContent,
}); });
chatStore.setLoading(false); chatStore.setLoading(false);
} else {
//
if (ans.value.answer !== "") {
AIcontent.value = ans.value.answer;
const type = ans.value.type;
const data = JSON.parse(ans.value.data);
console.log("处理 K 线数据 - 开始");
console.log(data, "data");
const Kline20 = {
name: data.data.HomePage.StockInformation.Name,
Kline: data.data,
type: type,
};
// K线
console.log("K线数据结构:", Kline20);
console.log("K线数据名称:", Kline20.name);
console.log("K线数据类型:", Kline20.type);
console.log("K线数据:", Kline20.Kline ? Kline20.Kline : null);
//
hasValidData.value = true;
console.log("hasValidData设置为:", hasValidData.value);
}
} catch (e) {
console.log(e, "意图识别失败");
}
// chatStore.messages.pop();
if (flag) {
const params2 = {
content: newVal[newVal.length - 1].content,
userData: {
aibullPrivilegeState: 1,
aigoldBullPrivilegeS: 1,
airadarPrivilegeStat: 1,
brainPrivilegeState: 1,
spaceForecastPrivile: 1,
stockForecastPrivile: 1,
swordPrivilegeState: 1,
language: "cn",
marketList: "hk,cn,usa,my,sg,vi,in,gb",
token: localStorage.getItem("localToken"),
// aibullPrivilegeState: userStore.aibullPrivilegeState,
// aigoldBullPrivilegeState: userStore.aigoldBullPrivilegeState,
// airadarPrivilegeState: userStore.airadarPrivilegeState,
// brainPrivilegeState: userStore.brainPrivilegeState,
// spaceForecastPrivilegeState: userStore.spaceForecastPrivilegeState,
// stockForecastPrivilegeState: userStore.stockForecastPrivilegeState,
// swordPrivilegeState: userStore.swordPrivilegeState,
// language: "cn",
// marketList: "hk,cn,usa,my,sg,vi,in,gb"
// token: "+SsksARQgUHIbIG3rRnnbZi0+fEeMx8pywnIlrmTxo5EOPR/wjWDV7w7+ZUseiBtf9kFa/atmNx6QfSpv5w",
},
name: codeData.value.name,
code: codeData.value.code,
market: codeData.value.market,
};
try {
const result21 = await dbqbSecondOneAPI({
workflow_id: "7514945685688025127",
parameters: params2,
});
const result22 = await dbqbSecondTwoAPI({
workflow_id: "7514945728733888575",
parameters: params2,
});
const result23 = await dbqbSecondThreeAPI({
workflow_id: "7514945758421811254",
parameters: params2,
});
const result24 = await dbqbSecondFourAPI({
workflow_id: "7514945791469223955",
parameters: params2,
});
// K线
const klineMessageId = `kline-${Date.now()}`;
console.log("生成K线消息ID:", klineMessageId);
const katexRegex = /\$\$(.*?)\$\$/g;
//
chatStore.messages.pop();
//
chatStore.messages.push({
sender: "ai",
class: "title1",
type: "title1",
content: codeData.value.name + "全景作战报告",
date: moment().format("MM/DD/YYYY"),
});
//
const pc1 = marked(
result21.data.name +
"\n" +
result21.data.price +
"\n" +
result21.data.data
);
const ac1 = pc1.replace(katexRegex, (match, formula) => {
try {
return katex.renderToString(formula, { throwOnError: false });
} catch (error) {
console.error("KaTeX 渲染错误:", error);
return match;
}
});
chatStore.messages.push({
sender: "ai",
type: "kline",
chartData: Kline20,
messageId: klineMessageId,
hasValidData: true, // hasValidData
});
chatStore.messages.push({
sender: "ai",
class: "content1",
type: "content1",
content: ac1,
});
//
chatStore.messages.push({
sender: "ai",
class: "content2",
type: "content2",
content: "K线图",
});
// K线
// 2
chatStore.messages.push({
sender: "ai",
class: "title2",
type: "title2",
content: "",
});
// 1
const pc2 = marked(result22.data.hxjzpg);
console.log(pc2, "pc2");
const ac2 = pc2.replace(katexRegex, (match, formula) => {
try {
return katex.renderToString(formula, { throwOnError: false });
} catch (error) {
console.error("KaTeX 渲染错误:", error);
return match;
}
});
chatStore.messages.push({
sender: "ai",
class: "content3",
type: "content3",
content: ac2,
});
// 3-2
chatStore.messages.push({
sender: "ai",
class: "title3",
type: "title3",
content: title2,
});
// 2
// const pc3 = marked(result23.data.zhuli1+'\n'+result23.data.zhuli2+'\n'+result23.data.zhuli3);
// const ac3 = pc3.replace(
// katexRegex,
// (match, formula) => {
// try {
// return katex.renderToString(formula, { throwOnError: false });
// } catch (error) {
// console.error("KaTeX :", error);
// return match;
// }
// }
// );
const ac3 = `<p style="margin:0;color:#FADC0C;display:flex;justify-content:center;font-size:28px">【主力行为】</p><p>${result23.data.zhuli1}</p><p>${result23.data.zhuli2}</p><p>${result23.data.zhuli3}</p>`;
chatStore.messages.push({
sender: "ai",
class: "content3",
type: "content3",
content: ac3,
});
// 3-3
chatStore.messages.push({
sender: "ai",
class: "title3",
type: "title3",
content: title3,
});
// 3
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 shijian = `<p style="margin:0;color:#FADC0C;display:flex;justify-content:center;font-size:28px">【时间维度】</p><p style="display:flex;justify-content:center;">${result23.data.shijian}</p>`;
const nengliang = `<p style="margin:0;color:#FADC0C;display:flex;justify-content:center;font-size:28px">【能量维度】</p><p>${result23.data.nengliang}</p>`;
const ac4 = kongjian + shijian + nengliang;
// const pc4 = marked(
// kongjian +
// "\n" +
// result23.data.shijian +
// "\n" +
// result23.data.nengliang
// );
// const ac4 = pc4.replace(katexRegex, (match, formula) => {
// try {
// return katex.renderToString(formula, { throwOnError: false });
// } catch (error) {
// console.error("KaTeX :", error);
// return match;
// }
// });
chatStore.messages.push({
sender: "ai",
class: "content3",
type: "content3",
content: ac4,
});
// 3-4
chatStore.messages.push({
sender: "ai",
class: "title3",
type: "title3",
content: title4,
});
// 4
const cftj = `<p style="margin:0;color:#FADC0C;display:flex;justify-content:center;font-size:28px">【触发条件】</p><p>${result24.data.cftl}</p>`;
const gfzl = `<p style="margin:0;color:#FADC0C;display:flex;justify-content:center;font-size:28px">【攻防指令】</p><p>${result24.data.gfzl}</p>`;
const ac5 = cftj + gfzl;
// const pc5 = marked(result24.data.cftl + "/n" + result24.data.gfzl);
// const ac5 = pc5.replace(katexRegex, (match, formula) => {
// try {
// return katex.renderToString(formula, { throwOnError: false });
// } catch (error) {
// console.error("KaTeX :", error);
// return match;
// }
// });
chatStore.messages.push({
sender: "ai",
class: "content3",
type: "content3",
content: ac5,
});
console.log("K线消息已添加到聊天列表");
chatStore.messages.push({
sender: "ai",
class: "mianze",
type: "mianze",
content: "内容由AI生成,请注意甄别",
});
//
chatStore.messages.push({
sender: "ai",
content: "AI正在思考中...",
});
//
const result = await getReplyAPI(params1);
//
const ans = ref();
await result.then((res) => {
// data JSON
ans.value = JSON.parse(res.data);
});
const AIcontent = ref("");
// answer
//
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 === klineMessageId) {
klineIndex = i;
break;
}
}
if (ans.value.resp !== "" && ans.value.resp !== null) {
} else {
//
if (ans.value.answer !== "") {
AIcontent.value = ans.value.answer;
const type = ans.value.type;
const data = JSON.parse(ans.value.data);
console.log("处理 K 线数据 - 开始");
console.log(data, "data");
const Kline20 = {
name: data.data.HomePage.StockInformation.Name,
Kline: data.data,
type: type,
};
// K线
console.log("K线数据结构:", Kline20);
console.log("K线数据名称:", Kline20.name);
console.log("K线数据类型:", Kline20.type);
console.log("K线数据:", Kline20.Kline ? Kline20.Kline : null);
//
hasValidData.value = true;
console.log("hasValidData设置为:", hasValidData.value);
// chatStore.messages.pop();
// K线
const klineMessageId = `kline-${Date.now()}`;
console.log("生成K线消息ID:", klineMessageId);
chatStore.messages.push({
sender: "ai",
type: "kline",
chartData: Kline20,
messageId: klineMessageId,
hasValidData: true, // hasValidData
});
console.log("找到的K线消息索引:", klineIndex);
console.log("K线消息已添加到聊天列表");
if (klineIndex !== -1) {
const containerId = `kline-container-${klineIndex}`;
console.log("图表容器ID:", containerId);
//
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 === klineMessageId) {
klineIndex = i;
break;
}
}
// DOM
setTimeout(() => {
console.log("延时执行,确保DOM已渲染");
KlineCanvsEcharts(containerId);
}, 100); // DOM
} else {
console.warn("未找到K线消息");
}
});
}
console.log("找到的K线消息索引:", klineIndex);
//
const processedContent = marked(AIcontent.value);
const katexRegex = /\$\$(.*?)\$\$/g;
const plainTextContent = htmlToText(processedContent);
//
const TTSResult = (
await TTSAPI({
language: "cn",
content: plainTextContent,
})
).json();
const tts = ref();
await TTSResult.then((res) => {
tts.value = JSON.parse(res.data);
});
if (klineIndex !== -1) {
const containerId = `kline-container-${klineIndex}`;
console.log("图表容器ID:", containerId);
const ttsUrl = ref();
if (tts.value.tts_cn !== null) {
audioStore.ttsUrl = tts.value.tts_cn.url;
ttsUrl.value = tts.value.tts_cn.url;
audioStore.isNewInstance = true;
} else if (tts.value.tts_en !== null) {
audioStore.ttsUrl = tts.value.tts_en.url;
ttsUrl.value = tts.value.tts_en.url;
audioStore.isNewInstance = true;
}
// DOM
setTimeout(() => {
console.log("延时执行,确保DOM已渲染");
KlineCanvsEcharts(containerId);
}, 100); // DOM
} else {
console.warn("未找到K线消息");
}
});
}
if (ttsUrl.value) {
nextTick(() => {
if (audioStore.isVoiceEnabled) {
console.log("ttsUrl.value", ttsUrl.value);
//
playAudio(ttsUrl.value);
}
//
const processedContent = marked(AIcontent.value);
const katexRegex = /\$\$(.*?)\$\$/g;
const plainTextContent = htmlToText(processedContent);
//
const TTSResult = (
await TTSAPI({
language: "cn",
content: plainTextContent,
})
).json();
const tts = ref();
await TTSResult.then((res) => {
tts.value = JSON.parse(res.data);
}); });
}
// chatStore.messages.pop();
//
const aiMessage = reactive({
sender: "ai",
content: "",
isTyping: true,
});
chatStore.messages.push(aiMessage);
let index = 0;
const typingInterval = setInterval(() => {
if (index < processedContent.length) {
aiMessage.content += processedContent.charAt(index);
index++;
} else {
clearInterval(typingInterval);
aiMessage.isTyping = false;
const ttsUrl = ref();
if (tts.value.tts_cn !== null) {
audioStore.ttsUrl = tts.value.tts_cn.url;
ttsUrl.value = tts.value.tts_cn.url;
audioStore.isNewInstance = true;
} else if (tts.value.tts_en !== null) {
audioStore.ttsUrl = tts.value.tts_en.url;
ttsUrl.value = tts.value.tts_en.url;
audioStore.isNewInstance = true;
}
// KaTeXDOM
if (ttsUrl.value) {
nextTick(() => { nextTick(() => {
aiMessage.content = aiMessage.content.replace(
katexRegex,
(match, formula) => {
try {
return katex.renderToString(formula, {
throwOnError: false,
});
} catch (error) {
console.error("KaTeX 渲染错误:", error);
return match;
}
}
);
chatStore.setLoading(false);
if (audioStore.isVoiceEnabled) {
console.log("ttsUrl.value", ttsUrl.value);
//
playAudio(ttsUrl.value);
}
}); });
} }
}, 50); // 50ms/
// } else {
// chatStore.messages.pop();
// chatStore.messages.push({
// sender: "ai",
// content: status.msg
// });
// chatStore.setLoading(false);
// }
// chatStore.messages.pop();
//
const aiMessage = reactive({
sender: "ai",
content: "",
isTyping: true,
});
chatStore.messages.push(aiMessage);
let index = 0;
const typingInterval = setInterval(() => {
if (index < processedContent.length) {
aiMessage.content += processedContent.charAt(index);
index++;
} else {
clearInterval(typingInterval);
aiMessage.isTyping = false;
// KaTeXDOM
nextTick(() => {
aiMessage.content = aiMessage.content.replace(
katexRegex,
(match, formula) => {
try {
return katex.renderToString(formula, {
throwOnError: false,
});
} catch (error) {
console.error("KaTeX 渲染错误:", error);
return match;
}
}
);
chatStore.setLoading(false);
});
}
}, 50); // 50ms/
// } else {
// chatStore.messages.pop();
// chatStore.messages.push({
// sender: "ai",
// content: status.msg
// });
// chatStore.setLoading(false);
// }
}
} catch (e) {
console.error("请求失败:", e);
hasValidData.value = false; //
// chatStore.messages.pop();
// chatStore.messages.push({
// sender: "ai",
// content: "AI... ",
// });
chatStore.setLoading(false);
} finally {
await chatStore.getUserCount();
} }
} catch (e) {
console.error("请求失败:", e);
hasValidData.value = false; //
// chatStore.messages.pop();
chatStore.messages.push({
sender: "ai",
content: "AI思考失败,请稍后再试... ",
});
chatStore.setLoading(false);
} finally {
await chatStore.getUserCount();
} }
} }
}, },
@ -5145,11 +5218,19 @@ function renderAllKlineCharts() {
// GIF // GIF
onMounted(() => { onMounted(() => {
// marked
marked.setOptions({
breaks: true, // <br>
gfm: true, // GitHub Flavored Markdown
sanitize: false, // HTML使
smartLists: true, //
smartypants: true, //
xhtml: false, // 使 XHTML
});
const random = Math.floor(Math.random() * 6) + 1; const random = Math.floor(Math.random() * 6) + 1;
currentGif.value = gifList[random]; currentGif.value = gifList[random];
getQuestionsList();
console.log("组件挂载完成"); console.log("组件挂载完成");
// DOM // DOM
@ -5195,22 +5276,6 @@ onUnmounted(() => {
<!-- GIF区域 --> <!-- GIF区域 -->
<div class="gif-area"> <div class="gif-area">
<img :src="currentGif" alt="AI动画" /> <img :src="currentGif" alt="AI动画" />
<!-- <div class="marquee-container">
<div id="top" class="marquee-row top" @mouseenter="floatingTopMouseEnter" @mouseleave="floatingTopMouseLeave">
<div v-for="(questions, index) in questionsList.slice(0, 5)" :key="'top' + index" class="marquee-item"
@click="showQuestions(questions)">
{{ questions.title }}
</div>
</div>
<div id="bottom" class="marquee-row bottom" @mouseenter="floatingBottomMouseEnter"
@mouseleave="floatingBottomMouseLeave">
<div v-for="(questions, index) in questionsList.slice(5, 10)" :key="'bottom' + index" class="marquee-item"
@click="showQuestions(questions)">
{{ questions.title }}
</div>
</div>
</div> -->
</div> </div>
<div <div
@ -5230,15 +5295,18 @@ onUnmounted(() => {
</div> </div>
</div> </div>
<div v-else-if="msg.type == 'ing'"> <div v-else-if="msg.type == 'ing'">
<span>{{ msg.content }}</span>
<span class="loading-dots">
<span class="dot">.</span>
<span class="dot">.</span>
<span class="dot">.</span>
<span class="dot">.</span>
<span class="dot">.</span>
<span class="dot">.</span>
</span>
<div v-if="msg.flag">
<span>{{ msg.content }}</span>
<span class="loading-dots">
<span class="dot">.</span>
<span class="dot">.</span>
<span class="dot">.</span>
<span class="dot">.</span>
<span class="dot">.</span>
<span class="dot">.</span>
</span>
</div>
<div v-else v-html="msg.content"></div>
</div> </div>
<div v-else-if="msg.type == 'title1'" style="display: flex; width: 100%"> <div v-else-if="msg.type == 'title1'" style="display: flex; width: 100%">
<div class="mainTitle"> <div class="mainTitle">

372
src/views/homePage.vue

@ -3,14 +3,14 @@
import { ref, computed, onMounted, watch, nextTick, onUnmounted } from "vue"; import { ref, computed, onMounted, watch, nextTick, onUnmounted } from "vue";
import { setHeight } from "../utils/setHeight"; import { setHeight } from "../utils/setHeight";
import { getUserCountAPI } from "../api/AIxiaocaishen"; import { getUserCountAPI } from "../api/AIxiaocaishen";
import { ElMessage } from 'element-plus'
import { ElMessage } from "element-plus";
import AIchat from "./AIchat.vue"; import AIchat from "./AIchat.vue";
import AIfind from "./AIfind.vue"; import AIfind from "./AIfind.vue";
import Feedback from "./Feedback.vue"; import Feedback from "./Feedback.vue";
import { useAppBridge } from '../assets/js/useAppBridge.js'
import { useDataStore } from '@/store/dataList.js'
import { useChatStore } from '../store/chat'
import { useAudioStore } from '../store/audio'
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 _ from "lodash";
import logo from "../assets/img/homePage/logo.png"; import logo from "../assets/img/homePage/logo.png";
@ -31,24 +31,23 @@ import msgBtn from "../assets/img/homePage/tail/msg.png";
import feedbackBtn from "../assets/img/Feedback/feedbackBtn.png"; import feedbackBtn from "../assets/img/Feedback/feedbackBtn.png";
import AiEmotion from "./AiEmotion.vue"; import AiEmotion from "./AiEmotion.vue";
// import VConsole from 'vconsole'; // import VConsole from 'vconsole';
// const vConsole = new VConsole(); // const vConsole = new VConsole();
// AiEmotion ref // AiEmotion ref
const aiEmotionRef = ref(null)
const aiEmotionRef = ref(null);
// import { useUserStore } from "../store/userPessionCode.js"; // import { useUserStore } from "../store/userPessionCode.js";
const { getQueryVariable, setActiveTabIndex } = useDataStore()
const dataStore = useDataStore()
const chatStore = useChatStore()
const { getQueryVariable, setActiveTabIndex } = useDataStore();
const dataStore = useDataStore();
const chatStore = useChatStore();
// //
// //
const audioStore = useAudioStore()
const isVoice = computed(() => audioStore.isVoiceEnabled)
const audioStore = useAudioStore();
const isVoice = computed(() => audioStore.isVoiceEnabled);
const toggleVoice = () => { const toggleVoice = () => {
audioStore.toggleVoice()
}
audioStore.toggleVoice();
};
// sessionStorage 使 'aifindCow'tab // sessionStorage 使 'aifindCow'tab
const activeTab = ref(sessionStorage.getItem("activeTabAI") || "AIchat"); const activeTab = ref(sessionStorage.getItem("activeTabAI") || "AIchat");
const activeIndex = ref( const activeIndex = ref(
@ -66,13 +65,13 @@ const tabs = computed(() => [
// }, // },
{ {
name: "AiEmotion", name: "AiEmotion",
label: "AI情绪大模型"
}
label: "AI情绪大模型",
},
]); ]);
// setActiveTab forceAIchat // setActiveTab forceAIchat
const setActiveTab = (tab, index, forceAIchat = false) => { const setActiveTab = (tab, index, forceAIchat = false) => {
isScrolling.value = false; //
isScrolling.value = false; //
isAnnouncementVisible.value = false; isAnnouncementVisible.value = false;
if (forceAIchat && activeTab.value !== "AIchat") { if (forceAIchat && activeTab.value !== "AIchat") {
activeTab.value = "AIchat"; activeTab.value = "AIchat";
@ -85,7 +84,7 @@ const setActiveTab = (tab, index, forceAIchat = false) => {
sessionStorage.setItem("activeTabAI", tab); sessionStorage.setItem("activeTabAI", tab);
sessionStorage.setItem("activeIndexAI", index.toString()); sessionStorage.setItem("activeIndexAI", index.toString());
} }
setActiveTabIndex(index)
setActiveTabIndex(index);
console.log(tab, index, "tab, index"); console.log(tab, index, "tab, index");
setHeight(document.getElementById("testId")); // setHeight(document.getElementById("testId")); //
}; };
@ -110,12 +109,11 @@ const ensureAIchat = () => {
}; };
// //
const UserCount = computed(() => chatStore.UserCount)
const UserCount = computed(() => chatStore.UserCount);
const getCount = () => { const getCount = () => {
console.log('点击了获取次数的按钮')
}
console.log("点击了获取次数的按钮");
};
// //
const isThinking = ref(true); const isThinking = ref(true);
@ -128,7 +126,9 @@ const message = ref("");
// //
const messages = ref([]); const messages = ref([]);
// //
const isLoading = computed(() => { chatStore.isLoading });
const isLoading = computed(() => {
chatStore.isLoading;
});
// //
const updateMessage = (title) => { const updateMessage = (title) => {
@ -136,14 +136,17 @@ const updateMessage = (title) => {
// console.log("updateMessage :", title); // console.log("updateMessage :", title);
}; };
const sendMessage = async () => { const sendMessage = async () => {
if (localStorage.getItem('localToken') == null || localStorage.getItem('localToken') == '') {
ElMessage.error('请先登录');
if (
localStorage.getItem("localToken") == null ||
localStorage.getItem("localToken") == ""
) {
ElMessage.error("请先登录");
return; return;
} }
isScrolling.value = false; isScrolling.value = false;
// AiEmotion // AiEmotion
if (activeTab.value === 'AiEmotion') {
if (activeTab.value === "AiEmotion") {
// AiEmotion handleSendMessage // AiEmotion handleSendMessage
aiEmotionRef.value?.handleSendMessage(message.value); aiEmotionRef.value?.handleSendMessage(message.value);
message.value = ""; // message.value = ""; //
@ -153,11 +156,11 @@ const sendMessage = async () => {
// ensureAIchat AIchat // ensureAIchat AIchat
ensureAIchat(); ensureAIchat();
console.log(chatStore.isLoading, 'isLoading.value1111');
console.log(chatStore.isLoading, "isLoading.value1111");
if (!message.value) return; if (!message.value) return;
if (chatStore.isLoading) return; if (chatStore.isLoading) return;
chatStore.setLoading(true); chatStore.setLoading(true);
console.log(chatStore.isLoading, 'isLoading.value2222');
console.log(chatStore.isLoading, "isLoading.value2222");
const messageContent = message.value; const messageContent = message.value;
// //
@ -172,12 +175,10 @@ const sendMessage = async () => {
sender: "user", sender: "user",
content: messageContent, content: messageContent,
timestamp: new Date().toISOString(), timestamp: new Date().toISOString(),
}
},
]; ];
console.log(messages.value, 'messages.value');
console.log(messages.value, "messages.value");
}, 200); }, 200);
}; };
// //
@ -190,8 +191,8 @@ const isAnnouncementVisible = ref(false);
const showAnnouncement = async () => { const showAnnouncement = async () => {
console.log("打开公告"); console.log("打开公告");
dataStore.isFeedback = false; // dataStore.isFeedback = false; //
isScrolling.value = false; //
setActiveTab('', -1); //
isScrolling.value = false; //
setActiveTab("", -1); //
isAnnouncementVisible.value = true; // isAnnouncementVisible.value = true; //
}; };
@ -200,7 +201,7 @@ const showAnnouncement = async () => {
const showFeedback = () => { const showFeedback = () => {
console.log("打开用户反馈"); console.log("打开用户反馈");
dataStore.isFeedback = true; // dataStore.isFeedback = true; //
}
};
// //
// ref // ref
@ -216,10 +217,10 @@ const showCount = () => {
// //
const tabContent = ref(null); const tabContent = ref(null);
const isScrolling = ref(false); //
const isScrolling = ref(false); //
const smoothScrollToBottom = async () => { const smoothScrollToBottom = async () => {
console.log('调用滚动到底部的方法')
console.log("调用滚动到底部的方法");
// await nextTick(); // await nextTick();
const container = tabContent.value; const container = tabContent.value;
// console.log(container, 'container') // console.log(container, 'container')
@ -235,10 +236,11 @@ const smoothScrollToBottom = async () => {
// container.scrollTop = container.scrollHeight + container.offsetHeight; // container.scrollTop = container.scrollHeight + container.offsetHeight;
// console.log(container.scrollHeight, container.offsetHeight, container.scrollHeight - container.offsetHeight, container.scrollTop, "", "", "") // console.log(container.scrollHeight, container.offsetHeight, container.scrollHeight - container.offsetHeight, container.scrollTop, "", "", "")
} }
};
}
const throttledSmoothScrollToBottom = _.throttle(smoothScrollToBottom, 500, { trailing: false });
const throttledSmoothScrollToBottom = _.throttle(smoothScrollToBottom, 500, {
trailing: false,
});
watch( watch(
() => chatStore.messages, () => chatStore.messages,
@ -250,16 +252,15 @@ watch(
{ deep: true, immediate: true } { deep: true, immediate: true }
); );
watch( watch(
activeTab, activeTab,
async () => { async () => {
console.log('activeTab变化了', activeTab.value)
if (activeTab.value === 'AIchat') {
isScrolling.value = false; //
console.log("activeTab变化了", activeTab.value);
if (activeTab.value === "AIchat") {
isScrolling.value = false; //
setTimeout(() => { setTimeout(() => {
throttledSmoothScrollToBottom(); throttledSmoothScrollToBottom();
}, 100)
}, 100);
} }
// setTimeout(throttledSmoothScrollToBottom, 100); // setTimeout(throttledSmoothScrollToBottom, 100);
}, },
@ -272,43 +273,46 @@ const fnGetToken = () => {
window.JWready = (ress) => { window.JWready = (ress) => {
// console.log('JWready') // console.log('JWready')
try { try {
ress = JSON.parse(ress)
ress = JSON.parse(ress);
// console.log(ress, 'ress') // console.log(ress, 'ress')
} catch (error) { } catch (error) {
console.log(error, 'fnGetToken error')
console.log(error, "fnGetToken error");
} //platform5app } //platform5app
// platform.value = ress.data.platform // platform.value = ress.data.platform
// //
console.log(ress.data.platform, 'ress.data.platform')
console.log(ress.data.platform, "ress.data.platform");
if (!ress.data.platform) { if (!ress.data.platform) {
// AppURL // AppURL
localStorage.setItem('localToken', decodeURIComponent(String(getQueryVariable('token'))))
localStorage.setItem(
"localToken",
decodeURIComponent(String(getQueryVariable("token")))
);
// localStorage.setItem('localToken', "+SsksARQgUHIbIG3rRnnbZi0+fEeMx8pywnIlrmTxo5EOPR/wjWDV7w7+ZUseiBtf9kFa/atmNx6QfSpv5w") // localStorage.setItem('localToken', "+SsksARQgUHIbIG3rRnnbZi0+fEeMx8pywnIlrmTxo5EOPR/wjWDV7w7+ZUseiBtf9kFa/atmNx6QfSpv5w")
} else { } else {
// App // App
useAppBridge().packageFun( useAppBridge().packageFun(
'JWgetStorage',
"JWgetStorage",
(response) => { (response) => {
const res = JSON.parse(response) //
localStorage.setItem('localToken', res.data)
const res = JSON.parse(response); //
localStorage.setItem("localToken", res.data);
// localStorage.setItem('localToken', "+SsksARQgUHIbIG3rRnnbZi0+fEeMx8pywnIlrmTxo5EOPR/wjWDV7w7+ZUseiBtf9kFa/atmNx6QfSpv5w") // localStorage.setItem('localToken', "+SsksARQgUHIbIG3rRnnbZi0+fEeMx8pywnIlrmTxo5EOPR/wjWDV7w7+ZUseiBtf9kFa/atmNx6QfSpv5w")
}, },
5, 5,
{ {
key: 'token'
key: "token",
} }
)
);
} }
}
};
// console.log('') // console.log('')
// App // App
useAppBridge().packageFun('JWwebReady', () => { }, 5, {})
}
useAppBridge().packageFun("JWwebReady", () => {}, 5, {});
};
// setTimeout // setTimeout
setTimeout(() => { setTimeout(() => {
fnGetToken()
}, 800)
fnGetToken();
}, 800);
const heightListener = () => { const heightListener = () => {
const tabContainer = tabContent.value; const tabContainer = tabContent.value;
@ -318,9 +322,10 @@ const heightListener = () => {
const aftertop = tabContainer.scrollTop; const aftertop = tabContainer.scrollTop;
// //
const isBottom = aftertop + tabContainer.offsetHeight + 50 >= tabContainer.scrollHeight;
const isBottom =
aftertop + tabContainer.offsetHeight + 50 >= tabContainer.scrollHeight;
if (activeTab.value === 'AIchat') {
if (activeTab.value === "AIchat") {
if (aftertop - befortop > 0) { if (aftertop - befortop > 0) {
// console.log(''); // console.log('');
isScrolling.value = true; isScrolling.value = true;
@ -340,42 +345,52 @@ const heightListener = () => {
// console.log(isScrolling.value, 'isScrolling.value') // console.log(isScrolling.value, 'isScrolling.value')
tabContainer.addEventListener('scroll', scrollHandler);
tabContainer.addEventListener("scroll", scrollHandler);
}; };
const throttledHeightListener = _.throttle(heightListener, 500, { trailing: false });
const throttledHeightListener = _.throttle(heightListener, 500, {
trailing: false,
});
const goToRecharge = () => { const goToRecharge = () => {
console.log('点击充值')
console.log("点击充值");
// http://39.101.133.168:8919/payment/recharge/index? // http://39.101.133.168:8919/payment/recharge/index?
// url=http%3A%2F%2Flocalhost%3A8080%2FLiveActivity%2Fpck // url=http%3A%2F%2Flocalhost%3A8080%2FLiveActivity%2Fpck
// &platform=1 // &platform=1
// &token=+S4h5QEE1hTIb4CxphrnbZi0+fEeMx8pywnIlrmTmo4QO6IolWnVWu5r+J4rKXMwK41UPfKqyIp+RvWmtM8 // &token=+S4h5QEE1hTIb4CxphrnbZi0+fEeMx8pywnIlrmTmo4QO6IolWnVWu5r+J4rKXMwK41UPfKqyIp+RvWmtM8
const userAgent = navigator.userAgent.toLowerCase(); const userAgent = navigator.userAgent.toLowerCase();
const mobileKeywords = ['mobile', 'android', 'iphone', 'ipad', 'ipod'];
const isMobile = mobileKeywords.some(keyword => userAgent.includes(keyword));
console.log(isMobile ? '手机' : '电脑')
const url = encodeURI("http://39.101.133.168:8857/aixiaocaishen/homePage")
console.log(url, 'url')
const platform = isMobile ? 2 : 1
const token = encodeURIComponent(localStorage.getItem('localToken'))
console.log(token, 'token')
const rechargeUrl = 'http://39.101.133.168:8919/payment/recharge/index?' + 'url=' + url + '&platform=' + platform + '&token=' + token
console.log(rechargeUrl, 'rechargeUrl')
window.location.href = rechargeUrl
const mobileKeywords = ["mobile", "android", "iphone", "ipad", "ipod"];
const isMobile = mobileKeywords.some((keyword) =>
userAgent.includes(keyword)
);
console.log(isMobile ? "手机" : "电脑");
const url = encodeURI("http://39.101.133.168:8857/aixiaocaishen/homePage");
console.log(url, "url");
const platform = isMobile ? 2 : 1;
const token = encodeURIComponent(localStorage.getItem("localToken"));
console.log(token, "token");
const rechargeUrl =
"http://39.101.133.168:8919/payment/recharge/index?" +
"url=" +
url +
"&platform=" +
platform +
"&token=" +
token;
console.log(rechargeUrl, "rechargeUrl");
window.location.href = rechargeUrl;
// window.open(rechargeUrl) // window.open(rechargeUrl)
}
};
const adjustFooterPosition = (height) => { const adjustFooterPosition = (height) => {
console.log('调整底部位置', height)
const footer = document.querySelector('.el-footer');
const main = document.querySelector('.el-main');
const homePage = document.querySelector('.homepage');
const app = document.getElementById('app');
console.log("调整底部位置", height);
const footer = document.querySelector(".el-footer");
const main = document.querySelector(".el-main");
const homePage = document.querySelector(".homepage");
const app = document.getElementById("app");
// Footer 60px // Footer // Footer 60px // Footer
// footer.style.bottom = `${keyboardHeight}px`; // footer.style.bottom = `${keyboardHeight}px`;
// Main Footer + // Main Footer +
@ -384,8 +399,8 @@ const adjustFooterPosition = (height) => {
void homePage.offsetHeight; void homePage.offsetHeight;
const html = document.querySelector('html');
const body = document.querySelector('body');
const html = document.querySelector("html");
const body = document.querySelector("body");
html.style.height = `${height}px`; html.style.height = `${height}px`;
body.style.height = `${height}px`; body.style.height = `${height}px`;
@ -394,9 +409,9 @@ const adjustFooterPosition = (height) => {
setTimeout(() => { setTimeout(() => {
// //
html.style.overflow = 'hidden';
body.style.overflow = 'hidden';
}, 200)
html.style.overflow = "hidden";
body.style.overflow = "hidden";
}, 200);
// console.log(html.offsetHeight, 'html') // console.log(html.offsetHeight, 'html')
// console.log(html.clientHeight, 'html') // console.log(html.clientHeight, 'html')
@ -411,68 +426,74 @@ const adjustFooterPosition = (height) => {
// console.log(main.offsetHeight, 'main') // console.log(main.offsetHeight, 'main')
// console.log(main.clientHeight, 'mainClientHeight') // console.log(main.clientHeight, 'mainClientHeight')
// console.log(main.scrollHeight, 'mainScrollHeight') // console.log(main.scrollHeight, 'mainScrollHeight')
}; };
const onFocus = function () { const onFocus = function () {
const visualViewport = window.visualViewport
const visualViewport = window.visualViewport;
// //
setTimeout(() => { setTimeout(() => {
console.log('输入框聚焦')
console.log("输入框聚焦");
console.log(visualViewport.height, 'visualViewport.height')
const keyboardHeight = window.innerHeight - visualViewport.height
console.log(window.innerHeight, 'window.innerHeight')
console.log(keyboardHeight, 'keyboardHeight')
console.log(visualViewport.height, "visualViewport.height");
const keyboardHeight = window.innerHeight - visualViewport.height;
console.log(window.innerHeight, "window.innerHeight");
console.log(keyboardHeight, "keyboardHeight");
adjustFooterPosition(visualViewport.height)
}, 200)
}
adjustFooterPosition(visualViewport.height);
}, 200);
};
const onBlur = function () { const onBlur = function () {
const visualViewport = window.visualViewport
const visualViewport = window.visualViewport;
setTimeout(() => { setTimeout(() => {
console.log('输入框失焦')
console.log("输入框失焦");
const keyboardHeight = window.innerHeight - visualViewport.height
console.log(window.innerHeight, 'window.innerHeight')
console.log(visualViewport.height, 'visualViewport.height')
console.log(keyboardHeight, 'keyboardHeight')
adjustFooterPosition(visualViewport.height)
}, 200)
}
const keyboardHeight = window.innerHeight - visualViewport.height;
console.log(window.innerHeight, "window.innerHeight");
console.log(visualViewport.height, "visualViewport.height");
console.log(keyboardHeight, "keyboardHeight");
adjustFooterPosition(visualViewport.height);
}, 200);
};
window.addEventListener('resize', () => {
window.addEventListener("resize", () => {
// iOS // iOS
const isIOS = /iPhone|iPad|iPod|ios/i.test(navigator.userAgent); const isIOS = /iPhone|iPad|iPod|ios/i.test(navigator.userAgent);
console.log('是否为iOS设备:', isIOS);
console.log("是否为iOS设备:", isIOS);
if (!isIOS) { if (!isIOS) {
console.log('窗口大小变化')
const homePage = document.querySelector('.homepage');
console.log("窗口大小变化");
const homePage = document.querySelector(".homepage");
homePage.style.height = `${window.innerHeight}px`; homePage.style.height = `${window.innerHeight}px`;
} }
}); });
// //
document.addEventListener('touchmove', (e) => {
if (!dataStore.isFeedback) {
//
const isScrollableArea = e.target.closest('.tab-content');
//
if (!isScrollableArea) {
e.preventDefault();
document.addEventListener(
"touchmove",
(e) => {
if (!dataStore.isFeedback) {
//
const isScrollableArea = e.target.closest(".tab-content");
//
if (!isScrollableArea) {
e.preventDefault();
}
} }
}
}, { passive: false });
},
{ passive: false }
);
onMounted(async () => { onMounted(async () => {
const isPhone = const isPhone =
/phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone/i.test( /phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone/i.test(
navigator.userAgent navigator.userAgent
)
);
!isPhone && !isPhone &&
localStorage.setItem('localToken', decodeURIComponent(String(getQueryVariable('token'))))
localStorage.setItem(
"localToken",
decodeURIComponent(String(getQueryVariable("token")))
);
setHeight(document.getElementById("testId")); // setHeight(document.getElementById("testId")); //
// //
await chatStore.getUserCount(); await chatStore.getUserCount();
@ -486,7 +507,7 @@ onMounted(async () => {
// //
// updateAppHeight(); // updateAppHeight();
})
});
</script> </script>
<template> <template>
@ -505,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>
@ -515,18 +544,30 @@ 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>
<!-- 尾部 问题输入框 深度思考 多语言 语音播报 --> <!-- 尾部 问题输入框 深度思考 多语言 语音播报 -->
<el-footer class="homepage-footer" id="input"> <el-footer class="homepage-footer" id="input">
@ -545,16 +586,33 @@ onMounted(async () => {
/> />
<!-- AI情绪大模型按钮 --> <!-- AI情绪大模型按钮 -->
<img <img
:src="activeTab === 'AiEmotion' ? emotionButton02 : emotionButton01"
:src="
activeTab === 'AiEmotion' ? emotionButton02 : emotionButton01
"
@click="setActiveTab('AiEmotion', 1)" @click="setActiveTab('AiEmotion', 1)"
class="action-btn model-btn" class="action-btn model-btn"
alt="AI情绪大模型" alt="AI情绪大模型"
/> />
<img v-if="isVoice" :src="voice" @click="toggleVoice" class="action-btn" />
<img v-else :src="voiceNoActive" @click="toggleVoice" class="action-btn" />
<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>
<img
v-if="!chatStore.isLoading"
:src="sendBtn"
@click="sendMessage"
class="action-btn send-btn"
/>
<div v-else @click="chatStore.setLoading(false)">
<el-icon class="is-loading"> <el-icon class="is-loading">
<Loading /> <Loading />
</el-icon> </el-icon>
@ -564,9 +622,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>
@ -584,8 +650,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>
@ -605,15 +679,9 @@ onMounted(async () => {
</template> </template>
<!-- 中间内容部分 --> <!-- 中间内容部分 -->
<div class="ruleContent"> <div class="ruleContent">
<p>
试运行期间AI小财神可以检索全市场数据
</p>
<p>
每个市场20支股票股票详情参见公告页面
</p>
<p>
弘历会员每人每日拥有10次检索机会
</p>
<p>试运行期间AI小财神可以检索全市场数据</p>
<p>每个市场20支股票股票详情参见公告页面</p>
<p>弘历会员每人每日拥有10次检索机会</p>
</div> </div>
<!-- <template #footer> --> <!-- <template #footer> -->
<!-- 添加一个div来包裹按钮并设置样式使其居中 --> <!-- 添加一个div来包裹按钮并设置样式使其居中 -->
@ -655,7 +723,7 @@ onMounted(async () => {
.tab-item.active { .tab-item.active {
/* color: #000; /* color: #000;
border-color: #000; */ border-color: #000; */
background: linear-gradient(0deg, #ffffff, #fec13e);
background: linear-gradient(0deg, #ffffff, #fec13e);
-webkit-background-clip: text; -webkit-background-clip: text;
background-clip: text; background-clip: text;
-webkit-text-fill-color: transparent; -webkit-text-fill-color: transparent;

Loading…
Cancel
Save