zhangkai 1 سال پیش
والد
کامیت
e8279a2deb

+ 28 - 0
package-lock.json

@@ -51,6 +51,7 @@
         "cmdk": "^0.2.0",
         "daisyui": "^3.6.3",
         "dompurify": "^3.0.5",
+        "echarts": "^5.5.1",
         "esbuild": "^0.17.19",
         "i18next": "^23.6.0",
         "i18next-http-backend": "^2.2.2",
@@ -6778,6 +6779,20 @@
       "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
       "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="
     },
+    "node_modules/echarts": {
+      "version": "5.5.1",
+      "resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.5.1.tgz",
+      "integrity": "sha512-Fce8upazaAXUVUVsjgV6mBnGuqgO+JNDlcgF79Dksy4+wgGpQB2lmYoO4TSweFg/mZITdpGHomw/cNBJZj1icA==",
+      "dependencies": {
+        "tslib": "2.3.0",
+        "zrender": "5.6.0"
+      }
+    },
+    "node_modules/echarts/node_modules/tslib": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz",
+      "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
+    },
     "node_modules/electron-to-chromium": {
       "version": "1.4.750",
       "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.750.tgz",
@@ -17240,6 +17255,19 @@
         "url": "https://github.com/sponsors/colinhacks"
       }
     },
+    "node_modules/zrender": {
+      "version": "5.6.0",
+      "resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.6.0.tgz",
+      "integrity": "sha512-uzgraf4njmmHAbEUxMJ8Oxg+P3fT04O+9p7gY+wJRVxo8Ge+KmYv0WJev945EH4wFuc4OY2NLXz46FZrWS9xJg==",
+      "dependencies": {
+        "tslib": "2.3.0"
+      }
+    },
+    "node_modules/zrender/node_modules/tslib": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz",
+      "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
+    },
     "node_modules/zustand": {
       "version": "4.5.2",
       "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.2.tgz",

+ 1 - 0
package.json

@@ -46,6 +46,7 @@
     "cmdk": "^0.2.0",
     "daisyui": "^3.6.3",
     "dompurify": "^3.0.5",
+    "echarts": "^5.5.1",
     "esbuild": "^0.17.19",
     "i18next": "^23.6.0",
     "i18next-http-backend": "^2.2.2",

+ 74 - 0
src/components/Chart/index.tsx

@@ -0,0 +1,74 @@
+import { useEffect, useRef } from "react";
+import * as echarts from "echarts";
+
+function Chart({ options }) {
+  const chartRef = useRef(null);
+  let chartInstance = null;
+
+  options = eval('('+options.substring(8)+')');
+  console.log(options)
+
+  const options1 = {
+    tooltip: {},
+    legend: {
+      data: [""],
+    },
+    xAxis: {
+      data: options.data.map(obj => {return obj.name}),
+    },
+    yAxis: {},
+    series: [
+      {
+        name: "",
+        type: options.chartType,
+        data: options.data.map(obj => {return obj.value}),
+      },
+    ],
+};
+  // 定义渲染函数
+  function renderChart() {
+    try {
+      // `echarts.getInstanceByDom` 可以从已经渲染成功的图表中获取实例,其目的就是在 options 发生改变的时候,不需要
+      // 重新创建图表,而是复用该图表实例,提升性能
+      const renderedInstance = echarts.getInstanceByDom(chartRef.current);
+      if (renderedInstance) {
+        chartInstance = renderedInstance;
+      } else {
+        chartInstance = echarts.init(chartRef.current);
+      }
+      chartInstance.setOption(options1);
+    } catch (error) {
+      console.error("error", error.message);
+      chartInstance && chartInstance.dispose();
+    }
+  }
+
+  // 定义窗口大小发生改变执行的回调函数
+  function resizeHandler() {
+    chartInstance.resize();
+  }
+
+  // 页面初始化时,开始渲染图表
+  useEffect(() => {
+    renderChart();
+
+    return () => {
+      // 销毁图表实例,释放内存
+      chartInstance && chartInstance.dispose();
+    };
+  }, []);
+
+  // 监听窗口大小改变
+  useEffect(() => {
+    window.addEventListener("resize", resizeHandler);
+    return () => window.removeEventListener("resize", resizeHandler);
+  }, []);
+
+  return (
+    <div>
+      <div style={{ width: "800px", height: "400px" }} ref={chartRef} />
+    </div>
+  );
+}
+
+export default Chart;

+ 14 - 4
src/components/bs-comp/chatComponent/MessageBs.tsx

@@ -22,7 +22,7 @@ import npcIcon from "../../../assets/npc/npcIcon.png";
 import nengliIcon from "../../../assets/npc/nengliIcon.png";
 import { TitleIconBg } from "../cardComponent";
 import Thumbs from "@/pages/ChatAppPage/components/Thumbs";
-
+import Chart from "@/components/Chart"
 // 颜色列表
 const colorList = [
     "#111",
@@ -104,16 +104,26 @@ export default function MessageBs({ data, onUnlike = () => { }, flow_type, onSou
                         {/* 光标 */}
                         {/* {data.message.toString() && !data.end && <div className="animate-cursor absolute w-2 h-5 ml-1 bg-gray-600" style={{ left: cursor.x, top: cursor.y }}></div>} */}
                     {/* </div> */}
+                    {/* <div className="App">
+      <Chart options={data.message} />
+    </div>
                     {data.message.toString() ?
                         <div className="chat-start-zk relative">
                             {mkdown}
+                            {data.receiver && <p className="text-blue-500 text-sm">@ {data.receiver.user_name}</p>}
+                        
+                        </div>
+                        : <div><LoadIcon className="text-gray-400" /></div>
+                    } */}
+                    {data.message.toString() && data.message.toString().includes('```chart') && <Chart options={data.message} />}
+                    {data.message.toString() && !data.message.toString().includes('```chart') && <div className="chat-start-zk relative">
+                            {mkdown}
                             {/* @user */}
                             {data.receiver && <p className="text-blue-500 text-sm">@ {data.receiver.user_name}</p>}
                             {/* 光标 */}
                             {/* {data.message.toString() && !data.end && <div className="animate-cursor absolute w-2 h-5 ml-1 bg-gray-600" style={{ left: cursor.x, top: cursor.y }}></div>} */}
-                        </div>
-                        : <div><LoadIcon className="text-gray-400" /></div>
-                    }
+                        </div>}
+                    {!data.message.toString() && <div><LoadIcon className="text-gray-400" /></div>}
                     
                     {/* 赞 踩 */}
                     {!!data.id && data.end && <Thumbs

+ 1 - 1
src/components/bs-comp/chatComponent/MessagePanne.tsx

@@ -75,7 +75,7 @@ export default function MessagePanne({ useName, guideWord, loadMore, flow_type }
                 } else if (msg.thought) {
                     type = 'system'
                 }
-                // console.log(type)
+                console.log(type)
                 switch (type) {
                     case 'user':
                         return <MessageUser key={msg.id} useName={useName} data={msg} />;

+ 9 - 1
src/modals/formModal/chatMessage/index.tsx

@@ -13,6 +13,7 @@ import { ChatMessageType } from "../../../types/chat";
 import { classNames } from "../../../utils";
 import FileCard from "../fileComponent";
 import { CodeBlock } from "./codeBlock";
+import Chart from "@/components/Chart";
 export default function ChatMessage({
   chat,
   lockChat,
@@ -26,6 +27,8 @@ export default function ChatMessage({
   const [hidden, setHidden] = useState(true);
   const template = chat.template;
   const [promptOpen, setPromptOpen] = useState(false);
+
+  console.log(chat.message)
   return (
     <div
       className={classNames("form-modal-chat-position", chat.isSend ? "human-word" : "robert-word")}
@@ -76,6 +79,9 @@ export default function ChatMessage({
             <div className="w-full">
               <div className="w-full dark:text-white">
                 <div className="w-full">
+                  
+                  {chat.message.toString() && chat.message.toString().includes('```chart') && <Chart options={chat.message} />}
+                  
                   {useMemo(
                     () => (
                       <ReactMarkdown
@@ -125,7 +131,9 @@ export default function ChatMessage({
                           },
                         }}
                       >
-                        {chat.message.toString()}
+                      {chat.message.toString() && !chat.message.toString().includes('```chart') && chat.message.toString()}
+
+                        {/* {chat.message.toString()} */}
                       </ReactMarkdown>
                     ),
                     [chat.message, chat.message.toString()]

+ 1 - 1
vite.config.ts

@@ -8,7 +8,7 @@ import path from "path";
 // Use environment variable to determine the target.
 // const target = process.env.VITE_PROXY_TARGET || "http://localhost:7860";
  const target = process.env.VITE_PROXY_TARGET || "http://npcall.ai:3003";
-//  const target = process.env.VITE_PROXY_TARGET || "http://172.30.40.241:7866";
+//  const target = process.env.VITE_PROXY_TARGET || "http://172.30.96.205:7880";
 
 const proxyTargets = apiRoutes.reduce((proxyObj, route) => {
   proxyObj[route] = {