From 422fbc5e9546674ac1ce13360222ccd76acbe88b Mon Sep 17 00:00:00 2001 From: no99 <17663930442@163.com> Date: Wed, 18 Jun 2025 19:56:31 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=BA=E5=AE=9D=E5=A4=A7=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.development | 4 +- package-lock.json | 8 +- package.json | 2 +- src/api/AIxiaocaishen.js | 59 +++- src/utils/request.js | 1 + src/views/AIchat.vue | 818 +++++++++++++++++++++++++---------------------- src/views/homePage.vue | 396 +++++++++++++---------- 7 files changed, 733 insertions(+), 555 deletions(-) diff --git a/.env.development b/.env.development index 007e426..32dcc78 100644 --- a/.env.development +++ b/.env.development @@ -5,8 +5,8 @@ VITE_OUTPUT_DIR = 'dev' 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" #MJ API diff --git a/package-lock.json b/package-lock.json index e04a679..7bf2b91 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,7 +21,7 @@ "html-to-text": "^9.0.5", "katex": "^0.16.21", "lodash": "^4.17.21", - "marked": "^15.0.7", + "marked": "^15.0.12", "mitt": "^3.0.1", "moment": "^2.30.1", "pinia": "^2.3.1", @@ -5117,9 +5117,9 @@ } }, "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", "bin": { "marked": "bin/marked.js" diff --git a/package.json b/package.json index 70957f2..14651ed 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "html-to-text": "^9.0.5", "katex": "^0.16.21", "lodash": "^4.17.21", - "marked": "^15.0.7", + "marked": "^15.0.12", "mitt": "^3.0.1", "moment": "^2.30.1", "pinia": "^2.3.1", diff --git a/src/api/AIxiaocaishen.js b/src/api/AIxiaocaishen.js index b3394ad..0cbce31 100644 --- a/src/api/AIxiaocaishen.js +++ b/src/api/AIxiaocaishen.js @@ -213,12 +213,53 @@ export const getMarketAndCodeAPI = 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", - }, - }); - }; \ No newline at end of file + 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, + }); +}; diff --git a/src/utils/request.js b/src/utils/request.js index 80b4877..e4f8432 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -115,6 +115,7 @@ service.interceptors.response.use( const errorMsg = res.msg || 'Unkonw error' // ElMessage.error(errorMsg) // return Promise.reject(new Error(res.msg || 'Error')) + return response.data } else { return response.data } diff --git a/src/views/AIchat.vue b/src/views/AIchat.vue index 03cc174..44a9343 100644 --- a/src/views/AIchat.vue +++ b/src/views/AIchat.vue @@ -5,8 +5,12 @@ import { getReplyStreamAPI, getReplyAPI, TTSAPI, - getQuestionAPI, qsArpAamClickAPI, + dbqbFirstAPI, + dbqbSecondOneAPI, + dbqbSecondTwoAPI, + dbqbSecondThreeAPI, + dbqbSecondFourAPI, } from "../api/AIxiaocaishen"; import { useUserStore } from "../store/userPessionCode"; import { useChatStore } from "../store/chat"; @@ -17,6 +21,7 @@ import katex from "katex"; // 引入 KaTeX 库 import { htmlToText } from "html-to-text"; import { Howl, Howler } from "howler"; import * as echarts from "echarts"; +import moment from "moment"; import AIgif1 from "@/assets/img/AIchat/AIgif1.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"; const gifList = [AIgif1, AIgif2, AIgif3, AIgif4, AIgif5, AIgif6, AIgif7]; - const chatStore = useChatStore(); const audioStore = useAudioStore(); const dataStore = useDataStore(); // 随机GIF const currentGif = ref(""); -// 推荐问题飘屏数据 -const questionsList = ref([]); -const getQuestionsList = async () => { - const result = await getQuestionAPI(); - questionsList.value = result.data; -}; - // 定义自定义事件 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) => { // 添加空值校验 @@ -276,123 +204,45 @@ watch( // 获取权限 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 { - 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("执行回绝话术"); - AIcontent.value = ans.value.resp; - + const AIcontent = ref(result.msg); // 修改后的消息处理逻辑 + const processedContent = marked(AIcontent.value); const katexRegex = /\$\$(.*?)\$\$/g; - // const plainTextContent = htmlToText(processedContent); - const aiContent = processedContent.replace( katexRegex, (match, formula) => { @@ -404,193 +254,416 @@ watch( } } ); - console.log(aiContent, "aiContent"); - // chatStore.messages.pop(); - chatStore.messages.push({ - sender: "ai", + class: "ing", + type: "ing", + flag: flag, content: aiContent, }); 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 = `

【主力行为】

${result23.data.zhuli1}

${result23.data.zhuli2}

${result23.data.zhuli3}

`; + 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 = `

【空间维度】

${arr[0]},${arr[1]}

${arr[2]},${arr[3]}

`; + const shijian = `

【时间维度】

${result23.data.shijian}

`; + const nengliang = `

【能量维度】

${result23.data.nengliang}

`; + 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 = `

【触发条件】

${result24.data.cftl}

`; + const gfzl = `

【攻防指令】

${result24.data.gfzl}

`; + 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; + } - // 延迟处理KaTeX确保DOM已更新 + if (ttsUrl.value) { 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; + + // 延迟处理KaTeX确保DOM已更新 + 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 onMounted(() => { + // 初始化marked组件 + marked.setOptions({ + breaks: true, // 支持换行符转换为
+ gfm: true, // 启用 GitHub Flavored Markdown + sanitize: false, // 不清理 HTML(谨慎使用) + smartLists: true, // 智能列表 + smartypants: true, // 智能标点符号 + xhtml: false, // 不使用 XHTML 输出 + }); + const random = Math.floor(Math.random() * 6) + 1; currentGif.value = gifList[random]; - getQuestionsList(); - console.log("组件挂载完成"); // 添加DOM变化监听器 @@ -5195,22 +5276,6 @@ onUnmounted(() => {
AI动画 - -
{
- {{ msg.content }} - - . - . - . - . - . - . - +
+ {{ msg.content }} + + . + . + . + . + . + . + +
+
diff --git a/src/views/homePage.vue b/src/views/homePage.vue index be29860..472eab9 100644 --- a/src/views/homePage.vue +++ b/src/views/homePage.vue @@ -3,14 +3,14 @@ import { ref, computed, onMounted, watch, nextTick, onUnmounted } from "vue"; import { setHeight } from "../utils/setHeight"; import { getUserCountAPI } from "../api/AIxiaocaishen"; -import { ElMessage } from 'element-plus' +import { ElMessage } from "element-plus"; import AIchat from "./AIchat.vue"; import AIfind from "./AIfind.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 logo from "../assets/img/homePage/logo.png"; @@ -23,7 +23,7 @@ import languageBtn from "../assets/img/homePage/tail/language.png"; import dbqbButton01 from "../assets/img/AiEmotion/dbqb-button01.png"; import dbqbButton02 from "../assets/img/AiEmotion/dbqb-button02.png"; import emotionButton01 from "../assets/img/AiEmotion/emotion-button01.png"; -import emotionButton02 from "../assets/img/AiEmotion/emotion-button02.png"; +import emotionButton02 from "../assets/img/AiEmotion/emotion-button02.png"; import voice from "../assets/img/homePage/tail/voice.png"; import voiceNoActive from "../assets/img/homePage/tail/voice-no-active.png"; import sendBtn from "../assets/img/homePage/tail/send.png"; @@ -31,24 +31,23 @@ import msgBtn from "../assets/img/homePage/tail/msg.png"; import feedbackBtn from "../assets/img/Feedback/feedbackBtn.png"; import AiEmotion from "./AiEmotion.vue"; - // import VConsole from 'vconsole'; // const vConsole = new VConsole(); // 获取 AiEmotion 组件的 ref -const aiEmotionRef = ref(null) +const aiEmotionRef = ref(null); // 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 = () => { - audioStore.toggleVoice() -} + audioStore.toggleVoice(); +}; // 将默认值改为从 sessionStorage 中获取,如果没有则使用默认值 'aifindCow'为第一个默认tab const activeTab = ref(sessionStorage.getItem("activeTabAI") || "AIchat"); const activeIndex = ref( @@ -66,13 +65,13 @@ const tabs = computed(() => [ // }, { name: "AiEmotion", - label: "AI情绪大模型" - } + label: "AI情绪大模型", + }, ]); // 修改 setActiveTab 方法,添加一个可选参数 forceAIchat const setActiveTab = (tab, index, forceAIchat = false) => { - isScrolling.value = false; //回复滚动到底部方法 + isScrolling.value = false; //回复滚动到底部方法 isAnnouncementVisible.value = false; if (forceAIchat && activeTab.value !== "AIchat") { activeTab.value = "AIchat"; @@ -85,7 +84,7 @@ const setActiveTab = (tab, index, forceAIchat = false) => { sessionStorage.setItem("activeTabAI", tab); sessionStorage.setItem("activeIndexAI", index.toString()); } - setActiveTabIndex(index) + setActiveTabIndex(index); console.log(tab, index, "tab, index"); setHeight(document.getElementById("testId")); // 给父组件发送窗口高度 }; @@ -110,12 +109,11 @@ const ensureAIchat = () => { }; // 获取次数 -const UserCount = computed(() => chatStore.UserCount) - +const UserCount = computed(() => chatStore.UserCount); const getCount = () => { - console.log('点击了获取次数的按钮') -} + console.log("点击了获取次数的按钮"); +}; // 深度思考 const isThinking = ref(true); @@ -128,7 +126,9 @@ const message = ref(""); // 传输对象 const messages = ref([]); // 信息加载状态 -const isLoading = computed(() => { chatStore.isLoading }); +const isLoading = computed(() => { + chatStore.isLoading; +}); // 添加用户消息 const updateMessage = (title) => { @@ -136,14 +136,17 @@ const updateMessage = (title) => { // console.log("updateMessage 的值:", title); }; const sendMessage = async () => { - if (localStorage.getItem('localToken') == null || localStorage.getItem('localToken') == '') { - ElMessage.error('请先登录'); + if ( + localStorage.getItem("localToken") == null || + localStorage.getItem("localToken") == "" + ) { + ElMessage.error("请先登录"); return; } isScrolling.value = false; - + // 判断当前是否为 AiEmotion 组件 - if (activeTab.value === 'AiEmotion') { + if (activeTab.value === "AiEmotion") { // 调用 AiEmotion 组件的 handleSendMessage 方法 aiEmotionRef.value?.handleSendMessage(message.value); message.value = ""; // 清空输入框 @@ -153,11 +156,11 @@ const sendMessage = async () => { // 调用 ensureAIchat 确保跳转到 AIchat 页面 ensureAIchat(); - console.log(chatStore.isLoading, 'isLoading.value1111'); + console.log(chatStore.isLoading, "isLoading.value1111"); if (!message.value) return; if (chatStore.isLoading) return; chatStore.setLoading(true); - console.log(chatStore.isLoading, 'isLoading.value2222'); + console.log(chatStore.isLoading, "isLoading.value2222"); const messageContent = message.value; // 重置消息输入框 @@ -172,12 +175,10 @@ const sendMessage = async () => { sender: "user", content: messageContent, timestamp: new Date().toISOString(), - } + }, ]; - console.log(messages.value, 'messages.value'); + console.log(messages.value, "messages.value"); }, 200); - - }; // 公告 @@ -190,8 +191,8 @@ const isAnnouncementVisible = ref(false); const showAnnouncement = async () => { console.log("打开公告"); dataStore.isFeedback = false; // 显示用户反馈页面 - isScrolling.value = false; //回复滚动到底部方法 - setActiveTab('', -1); // 清空当前选中状态 + isScrolling.value = false; //回复滚动到底部方法 + setActiveTab("", -1); // 清空当前选中状态 isAnnouncementVisible.value = true; // 显示公告页面 }; @@ -200,7 +201,7 @@ const showAnnouncement = async () => { const showFeedback = () => { console.log("打开用户反馈"); dataStore.isFeedback = true; // 显示用户反馈页面 -} +}; // 点击剩余次数会弹出的弹窗 // 新增一个 ref 来控制弹窗的显示与隐藏 @@ -216,10 +217,10 @@ const showCount = () => { // 保证发送消息时,滚动屏在底部 const tabContent = ref(null); -const isScrolling = ref(false); //判断用户是否在滚动 +const isScrolling = ref(false); //判断用户是否在滚动 const smoothScrollToBottom = async () => { - console.log('调用滚动到底部的方法') + console.log("调用滚动到底部的方法"); // await nextTick(); const container = tabContent.value; // console.log(container, 'container') @@ -235,10 +236,11 @@ const smoothScrollToBottom = async () => { // container.scrollTop = container.scrollHeight + container.offsetHeight; // 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( () => chatStore.messages, @@ -250,16 +252,15 @@ watch( { deep: true, immediate: true } ); - watch( activeTab, 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(() => { throttledSmoothScrollToBottom(); - }, 100) + }, 100); } // setTimeout(throttledSmoothScrollToBottom, 100); }, @@ -272,43 +273,46 @@ const fnGetToken = () => { window.JWready = (ress) => { // console.log('进入JWready') try { - ress = JSON.parse(ress) + ress = JSON.parse(ress); // console.log(ress, 'ress') } catch (error) { - console.log(error, 'fnGetToken error') + console.log(error, "fnGetToken error"); } //platform为5是app端 // 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) { // 非App环境通过URL参数获取 - localStorage.setItem('localToken', decodeURIComponent(String(getQueryVariable('token')))) + localStorage.setItem( + "localToken", + decodeURIComponent(String(getQueryVariable("token"))) + ); // localStorage.setItem('localToken', "+SsksARQgUHIbIG3rRnnbZi0+fEeMx8pywnIlrmTxo5EOPR/wjWDV7w7+ZUseiBtf9kFa/atmNx6QfSpv5w") } else { // App环境通过桥接获取 useAppBridge().packageFun( - 'JWgetStorage', + "JWgetStorage", (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") }, 5, { - key: 'token' + key: "token", } - ) + ); } - } + }; // console.log('出来了') // 触发App桥接 - useAppBridge().packageFun('JWwebReady', () => { }, 5, {}) -} + useAppBridge().packageFun("JWwebReady", () => {}, 5, {}); +}; // 在setTimeout中延迟执行 setTimeout(() => { - fnGetToken() -}, 800) + fnGetToken(); +}, 800); const heightListener = () => { const tabContainer = tabContent.value; @@ -318,9 +322,10 @@ const heightListener = () => { 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) { // console.log('向下滚动'); isScrolling.value = true; @@ -340,52 +345,62 @@ const heightListener = () => { // 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 = () => { - console.log('点击充值') + console.log("点击充值"); // http://39.101.133.168:8919/payment/recharge/index? // url=http%3A%2F%2Flocalhost%3A8080%2FLiveActivity%2Fpck // &platform=1 // &token=+S4h5QEE1hTIb4CxphrnbZi0+fEeMx8pywnIlrmTmo4QO6IolWnVWu5r+J4rKXMwK41UPfKqyIp+RvWmtM8 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) -} - +}; 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.style.bottom = `${keyboardHeight}px`; + // footer.style.bottom = `${keyboardHeight}px`; // 给 Main 区域留出 Footer + 键盘的空间 homePage.style.height = `${height}px`; // app.style.height = `${height}px`; 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`; body.style.height = `${height}px`; @@ -394,9 +409,9 @@ const adjustFooterPosition = (height) => { 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.clientHeight, 'html') @@ -411,68 +426,74 @@ const adjustFooterPosition = (height) => { // console.log(main.offsetHeight, 'main') // console.log(main.clientHeight, 'mainClientHeight') // console.log(main.scrollHeight, 'mainScrollHeight') - }; const onFocus = function () { - const visualViewport = window.visualViewport + const visualViewport = window.visualViewport; // 获取可视区域高度 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 visualViewport = window.visualViewport + const visualViewport = window.visualViewport; 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设备 const isIOS = /iPhone|iPad|iPod|ios/i.test(navigator.userAgent); - console.log('是否为iOS设备:', isIOS); + console.log("是否为iOS设备:", isIOS); if (!isIOS) { - console.log('窗口大小变化') - const homePage = document.querySelector('.homepage'); + console.log("窗口大小变化"); + const homePage = document.querySelector(".homepage"); 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 () => { const isPhone = /phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone/i.test( navigator.userAgent - ) + ); !isPhone && - localStorage.setItem('localToken', decodeURIComponent(String(getQueryVariable('token')))) + localStorage.setItem( + "localToken", + decodeURIComponent(String(getQueryVariable("token"))) + ); setHeight(document.getElementById("testId")); // 给父组件发送窗口高度 // 获取次数 await chatStore.getUserCount(); @@ -486,7 +507,7 @@ onMounted(async () => { // 初始化视口高度变量 // updateAppHeight(); -}) +});
-

- 试运行期间,AI小财神可以检索全市场数据 -

-

- (每个市场20支股票,股票详情参见【公告】页面), -

-

- 弘历会员每人每日拥有10次检索机会! -

+

试运行期间,AI小财神可以检索全市场数据

+

(每个市场20支股票,股票详情参见【公告】页面),

+

弘历会员每人每日拥有10次检索机会!

@@ -655,7 +723,7 @@ onMounted(async () => { .tab-item.active { /* color: #000; border-color: #000; */ - background: linear-gradient(0deg, #ffffff, #fec13e); + background: linear-gradient(0deg, #ffffff, #fec13e); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;