From 4d421ddfed1b725eabbed81eab113b4e440517c1 Mon Sep 17 00:00:00 2001
From: jialh <1972868360@qq.com>
Date: 星期二, 10 六月 2025 14:49:14 +0800
Subject: [PATCH] 备份

---
 src/components/AiProChat/AiProChat.tsx |  270 ++++++++++++++++++++++++------------------------------
 1 files changed, 120 insertions(+), 150 deletions(-)

diff --git a/src/components/AiProChat/AiProChat.tsx b/src/components/AiProChat/AiProChat.tsx
index 66caa01..f0c156f 100644
--- a/src/components/AiProChat/AiProChat.tsx
+++ b/src/components/AiProChat/AiProChat.tsx
@@ -15,17 +15,8 @@
 import remarkBreaks from "remark-breaks";
 import rehypeRaw from "rehype-raw";
 import rehypeSanitize from "rehype-sanitize";
-import rehypeHighlight from "rehype-highlight";
-import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
-import { ghcolors } from "react-syntax-highlighter/dist/esm/styles/prism";
 import logo from "/favicon.png";
 import "./markdown-styles.css";
-
-const codeStyle: Record<string, React.CSSProperties> = {
-  ...(Object.fromEntries(
-    Object.entries(ghcolors).filter(([key]) => typeof key === "string")
-  ) as Record<string, React.CSSProperties>),
-};
 
 const loadMermaid = () => {
   if (typeof window !== "undefined" && !(window as any).mermaid) {
@@ -63,10 +54,10 @@
   botAvatar?: string;
   request: (messages: ChatMessage[]) => Promise<Response>;
   clearMessage?: () => void;
-  botId?: string; // 鏂板 botId 鍙傛暟
+  botId?: string;
   botTypeId?: number;
-  onFileUploaded?: (fileId: string) => void; // 鏂板鏂囦欢涓婁紶鍥炶皟
-  onFileRemoved?: (removedFileId?: string) => void; // 鏂板鏂囦欢鍒犻櫎鍥炶皟
+  onFileUploaded?: (fileId: string) => void;
+  onFileRemoved?: (removedFileId?: string) => void;
 };
 
 export const AiProChat = ({
@@ -79,10 +70,10 @@
   botAvatar = `${logo}`,
   request,
   clearMessage,
-  botId, // 鏂板
+  botId,
   botTypeId,
-  onFileUploaded, // 鏂板
-  onFileRemoved, // 鏂板
+  onFileUploaded,
+  onFileRemoved,
 }: AiProChatProps) => {
   const isControlled =
     parentChats !== undefined && parentOnChatsChange !== undefined;
@@ -110,38 +101,34 @@
     }
   }, [chats]);
 
-
   const handleRemoveFile = (name: string) => {
-    const fileToRemove = fileList.find(f => f.name === name);
+    const fileToRemove = fileList.find((f) => f.name === name);
     console.log("handleRemoveFile", fileToRemove);
-    
+
     if (!fileToRemove) return;
-  
-    const newUploadedFiles = uploadedFiles.filter(f => f !== name);
-    const newFileList = fileList.filter(f => f.name !== name);
-    
+
+    const newUploadedFiles = uploadedFiles.filter((f) => f !== name);
+    const newFileList = fileList.filter((f) => f.name !== name);
+
     setUploadedFiles(newUploadedFiles);
     setFileList(newFileList);
-    
-    // 纭繚浼犻�掔殑鏄枃浠剁殑 url (鍗虫枃浠禝D)
+
     if (fileToRemove.url) {
       onFileRemoved?.(fileToRemove.url);
     }
   };
-  
 
   const handleUpload = async (file: File) => {
     if (botTypeId === 2 && uploadedFiles.length >= 1) {
       messageApi.warning("鍙兘涓婁紶涓�涓枃浠讹紝璇峰垹闄ゅ凡涓婁紶鏂囦欢");
       return false;
     }
-    // 澶氭枃浠舵ā寮忔鏌ワ紙鍋囪闄愬埗鏈�澶�5涓枃浠讹級
     if (botTypeId === 3 && uploadedFiles.length >= 5) {
       messageApi.warning("鏈�澶氬彧鑳戒笂浼�5涓枃浠�");
       return false;
     }
 
-    setFileList(prev => [
+    setFileList((prev) => [
       ...prev,
       {
         uid: file.name,
@@ -149,7 +136,7 @@
         status: "uploading",
       },
     ]);
-  
+
     const formData = new FormData();
     const tokenKey = `${import.meta.env.VITE_APP_TOKEN_KEY}`;
     formData.append("file", file);
@@ -167,9 +154,9 @@
       const result = await res.json();
       const fileData = JSON.parse(result.data.trim());
 
-      setFileList(prev => 
-        prev.map(f => 
-          f.name === file.name 
+      setFileList((prev) =>
+        prev.map((f) =>
+          f.name === file.name
             ? { ...f, uid: fileData.name, status: "done", url: fileData.id }
             : f
         )
@@ -177,17 +164,12 @@
 
       setUploadedFiles((prev) => [...prev, fileData.name]);
       messageApi.success(`${fileData.name} 涓婁紶鎴愬姛`);
-      // 璋冪敤鍥炶皟鍑芥暟浼犻�掓枃浠禝D
       onFileUploaded?.(fileData.id);
 
       return fileData;
     } catch (error) {
-      setFileList(prev => 
-        prev.map(f => 
-          f.name === file.name 
-            ? { ...f, status: "error" }
-            : f
-        )
+      setFileList((prev) =>
+        prev.map((f) => (f.name === file.name ? { ...f, status: "error" } : f))
       );
       messageApi.error((error as Error).message || "涓婁紶澶辫触");
       throw error;
@@ -368,122 +350,113 @@
     }
   };
 
-  const renderMessages = () => {
-    if (!chats?.length) {
-      return (
-        <Welcome
-          variant="borderless"
-          icon={
+ // 淇敼 renderMessages 鍑芥暟涓殑 ReactMarkdown 閮ㄥ垎
+const renderMessages = () => {
+  if (!chats?.length) {
+    return (
+      <Welcome
+        variant="borderless"
+        icon={
+          <img
+            src={botAvatar}
+            style={{ width: 32, height: 32, borderRadius: "50%" }}
+            alt="AI Avatar"
+          />
+        }
+        description={helloMessage}
+        styles={{ icon: { width: 40, height: 40 } }}
+      />
+    );
+  }
+  return (
+    <Bubble.List
+      autoScroll={true}
+      items={chats.map((chat, index) => ({
+        key: chat.id + Math.random().toString(),
+        typing: { suffix: <>馃挆</> },
+        header: <Space>{new Date(chat.created).toLocaleString()}</Space>,
+        loading: chat.loading,
+        loadingRender: () => (
+          <Space>
+            <Spin size="small" />
+            AI姝e湪鎬濊�冧腑...
+          </Space>
+        ),
+        footer: (
+          <Space>
+            {chat.role === "assistant" && (
+              <Button
+                color="default"
+                variant="text"
+                size="small"
+                icon={<SyncOutlined />}
+                onClick={() => handleRegenerate(index)}
+              />
+            )}
+            <Button
+              color="default"
+              variant="text"
+              size="small"
+              icon={<CopyOutlined />}
+              onClick={async () => {
+                try {
+                  await navigator.clipboard.writeText(chat.content);
+                  message.success("澶嶅埗鎴愬姛");
+                } catch (error) {
+                  message.error("澶嶅埗澶辫触");
+                }
+              }}
+            />
+          </Space>
+        ),
+        role: chat.role === "user" ? "local" : "ai",
+        content: (
+          <div className="markdown-body">
+            {chat.role === "assistant" ? (
+              <ReactMarkdown
+                remarkPlugins={[remarkGfm, remarkBreaks]}
+                rehypePlugins={[rehypeRaw, rehypeSanitize]}
+                components={{
+                  code({ node, className, children, ...props }) {
+                    const match = /language-(\w+)/.exec(className || "");
+                    return match ? (
+                      <pre className={className} {...props as React.HTMLAttributes<HTMLPreElement>}>
+                        <code>{children}</code>
+                      </pre>
+                    ) : (
+                      <code className={className} {...props as React.HTMLAttributes<HTMLElement>}>
+                        {children}
+                      </code>
+                    );
+                  },
+                }}
+              >
+                {chat.content}
+              </ReactMarkdown>
+            ) : (
+              chat.content
+            )}
+          </div>
+        ),
+        avatar:
+          chat.role === "assistant" ? (
             <img
               src={botAvatar}
               style={{ width: 32, height: 32, borderRadius: "50%" }}
               alt="AI Avatar"
             />
-          }
-          description={helloMessage}
-          styles={{ icon: { width: 40, height: 40 } }}
-        />
-      );
-    }
-    return (
-      <Bubble.List
-        autoScroll={true}
-        items={chats.map((chat, index) => ({
-          key: chat.id + Math.random().toString(),
-          typing: { suffix: <>馃挆</> },
-          header: <Space>{new Date(chat.created).toLocaleString()}</Space>,
-          loading: chat.loading,
-          loadingRender: () => (
-            <Space>
-              <Spin size="small" />
-              AI姝e湪鎬濊�冧腑...
-            </Space>
+          ) : (
+            {
+              icon: <UserOutlined />,
+              style: { color: "#fff", backgroundColor: "#87d068" },
+            }
           ),
-          footer: (
-            <Space>
-              {chat.role === "assistant" && (
-                <Button
-                  color="default"
-                  variant="text"
-                  size="small"
-                  icon={<SyncOutlined />}
-                  onClick={() => handleRegenerate(index)}
-                />
-              )}
-              <Button
-                color="default"
-                variant="text"
-                size="small"
-                icon={<CopyOutlined />}
-                onClick={async () => {
-                  try {
-                    await navigator.clipboard.writeText(chat.content);
-                    message.success("澶嶅埗鎴愬姛");
-                  } catch (error) {
-                    message.error("澶嶅埗澶辫触");
-                  }
-                }}
-              />
-            </Space>
-          ),
-          role: chat.role === "user" ? "local" : "ai",
-          content: (
-            <div className="markdown-body">
-              {chat.role === "assistant" ? (
-                <ReactMarkdown
-                  remarkPlugins={[remarkGfm, remarkBreaks]}
-                  rehypePlugins={[rehypeRaw, rehypeSanitize, rehypeHighlight]}
-                  components={{
-                    code({ node, className, children, ...props }) {
-                      const match = /language-(\w+)/.exec(className || "");
-                      const isInline = !!(
-                        node?.position?.start &&
-                        node.position.end &&
-                        node.position.start.line === node.position.end.line
-                      );
+      }))}
+      roles={{ ai: { placement: "start" }, local: { placement: "end" } }}
+    />
+  );
+};
 
-                      return !isInline ? (
-                        <SyntaxHighlighter
-                          language={match?.[1] || "text"}
-                          style={codeStyle as { [key: string]: React.CSSProperties }}
-                          PreTag="div"
-                          {...props}
-                        >
-                          {String(children).replace(/\n$/, "")}
-                        </SyntaxHighlighter>
-                      ) : (
-                        <code className={className} {...props}>
-                          {children}
-                        </code>
-                      );
-                    },
-                  }}
-                >
-                  {chat.content}
-                </ReactMarkdown>
-              ) : (
-                chat.content
-              )}
-            </div>
-          ),
-          avatar:
-            chat.role === "assistant" ? (
-              <img
-                src={botAvatar}
-                style={{ width: 32, height: 32, borderRadius: "50%" }}
-                alt="AI Avatar"
-              />
-            ) : (
-              {
-                icon: <UserOutlined />,
-                style: { color: "#fff", backgroundColor: "#87d068" },
-              }
-            ),
-        }))}
-        roles={{ ai: { placement: "start" }, local: { placement: "end" } }}
-      />
-    );
-  };
 
   return (
     <div
@@ -552,15 +525,12 @@
                 >
                   {name}
                 </span>
-                {/* 娣诲姞鍒犻櫎鎸夐挳 */}
                 <Button
                   type="text"
                   size="small"
                   icon={<DeleteOutlined />}
                   onClick={() => {
                     handleRemoveFile(name);
-                    // setUploadedFiles(uploadedFiles.filter((f) => f !== name));
-                    // setFileList(fileList.filter((f) => f.name !== name));
                   }}
                 />
               </div>

--
Gitblit v1.8.0