tangning 4 月之前
父节点
当前提交
5095373c6b
共有 4 个文件被更改,包括 103 次插入11 次删除
  1. 1 0
      package.json
  2. 32 0
      src/util/ollama.js
  3. 58 11
      src/view/case/records/index.vue
  4. 12 0
      yarn.lock

+ 1 - 0
package.json

@@ -22,6 +22,7 @@
     "leaflet": "^1.9.4",
     "mime": "^3.0.0",
     "mitt": "^3.0.1",
+    "ollama": "^0.5.14",
     "province-city-china": "^8.5.8",
     "qs": "^6.11.2",
     "sass": "^1.64.2",

+ 32 - 0
src/util/ollama.js

@@ -0,0 +1,32 @@
+import { Ollama } from "ollama/browser";
+const ollama = new Ollama({ host: 'http://192.168.9.61:11434' })
+export function chatWithHistory(model, userMsg, history, systemMsg) {
+  return ollama.chat({
+    model,
+    messages: [
+      { role: "system", content: systemMsg },
+      ...history,
+      { role: "user", content: userMsg },
+    ],
+    stream: true,
+  });
+}
+
+export function chat(userMsg, systemMsg) {
+  return ollama.chat({
+    model: 'deepseek-r1:70b',
+    messages: [
+      { role: "system", content: systemMsg },
+      { role: "user", content: userMsg },
+    ],
+    stream: true,
+  });
+}
+
+export function listModels() {
+  return ollama.list();
+}
+
+export function abort() {
+  ollama.abort();
+}

+ 58 - 11
src/view/case/records/index.vue

@@ -236,7 +236,7 @@
       <div class="textarea">
         <div>
           <span>现场勘验情况 :</span>
-          <span @click="()=>{aiImgShow=true}" style="color:#26559B;cursor: pointer;float: right;font-weight: bold;">AI</span>
+          <span @click="handleShowAi" style="color:#26559B;cursor: pointer;float: right;font-weight: bold;">AI</span>
         </div>
         <el-input
           type="textarea"
@@ -550,6 +550,7 @@ import saveAs from "@/util/file-serve";
 import { CirclePlus, CircleClose, MagicStick } from "@element-plus/icons-vue";
 import { recorderInfoType, ChangeReasonType } from "./formData.ts";
 import { confirm } from "@/helper/message";
+import { chat, abort, listModels } from "@/util/ollama";
 import { copyTextToClipboard } from "@/util/index";
 const props = defineProps({ caseId: Number, title: String });
 console.log("router.currentRoute", router.currentRoute.value?.params);
@@ -641,17 +642,65 @@ const handleCopy = () => {
   copyTextToClipboard(aiImgData.value.result);
   ElMessage.success("复制成功!");
 }
+const handleShowAi = async () => {
+  const list = await getFloorList(caseId.value)
+  aiImgData.value.list = list.filter((i) => i.urls && i.urls.length);
+  aiImgData.value.src = list[0]?.urls[0];
+  aiImgShow.value = true;
+}
+//判断是否deepseek
+let isThink = ref(false);
+let testRegex = /deepseek/;
 const handleAI = async () => {
   aiImgData.value.loading = true;
   let orgin = window.location.origin;
   let imageUrl = orgin + aiImgData.value.src
   try {
-  const res = await getAiByImage({imageUrl: imageUrl})
-  console.log("handleAI", res)
-  aiImgData.value.result = res
-  aiImgData.value.loading = false
+  // const res = await getAiByImage({imageUrl: imageUrl})
+  chat('', '人为什么要吃饭').then(async stream => {
+    for await (const part of stream) {
+        // chatHistory.value.at(idx).text += part.message.content;
+        let tep_mesg = part.message.content;
+        console.log("isThinktep", tep_mesg);
+        //判断是否是deepseek模型
+        // if (testRegex.test(agentInfo.value.model)) {
+          if (tep_mesg == "\u003c/think\u003e") {
+            // isThink.value = true;
+            aiImgData.value.loading = false;
+          }
+          if (!aiImgData.value.loading) {
+            //清除think
+            if (
+              tep_mesg == "\u003cthink\u003e" ||
+              tep_mesg == "\u003c/think\u003e"
+            ) {
+              // chatHistory.value.at(idx).think += "";
+            } else {
+              console.log("isThinktep_mesg", tep_mesg);
+              aiImgData.value.result += tep_mesg;
+              // chatHistory.value.at(idx).think += tep_mesg;
+            }
+            //如果结尾标签则停止拼接
+            if (tep_mesg == "\u003c/think\u003e") {
+              // isThink.value = false;
+            }
+          } else {
+            // aiImgData.value.result += tep_mesg;
+            // chatHistory.value.at(idx).text += tep_mesg;
+          }
+        // } else {
+        //   // chatHistory.value.at(idx).text += tep_mesg;
+        //   aiImgData.value.result += tep_mesg;
+        // }
+        // autoScrollSwitch.value && scrollToBottom(true);
+      }
+  })
+  // console.log("handleAI", res)
+  // aiImgData.value.result = res
+  // aiImgData.value.loading = false
   } catch (error) {
-    aiImgData.value.loading = false;
+  console.log("handleAI", error)
+  aiImgData.value.loading = false;
   }
 
 };
@@ -678,12 +727,10 @@ const initSignatureAndWitInfo = () => {
 };
 
 onMounted(() => {
+  listModels().then(res => {
+    console.log("listModels", res)
+    })
   initInfo();
-  getFloorList(caseId.value).then((res) => {
-    aiImgData.value.list = res.filter((i) => i.urls && i.urls.length);
-    aiImgData.value.src = res[0]?.urls[0];
-    console.log("getFloorList", res);
-  });
 });
 
 const addRecorderInfo = () => {

+ 12 - 0
yarn.lock

@@ -1063,6 +1063,13 @@ object-inspect@^1.13.1:
   resolved "https://mirrors.cloud.tencent.com/npm/object-inspect/-/object-inspect-1.13.3.tgz#f14c183de51130243d6d18ae149375ff50ea488a"
   integrity sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==
 
+ollama@^0.5.14:
+  version "0.5.14"
+  resolved "https://registry.npmmirror.com/ollama/-/ollama-0.5.14.tgz#bf1b72998491636ee89766bb0e3163e3c50a6970"
+  integrity sha512-pvOuEYa2WkkAumxzJP0RdEYHkbZ64AYyyUszXVX7ruLvk5L+EiO2G71da2GqEQ4IAk4j6eLoUbGk5arzFT1wJA==
+  dependencies:
+    whatwg-fetch "^3.6.20"
+
 path-browserify@^1.0.1:
   version "1.0.1"
   resolved "https://mirrors.cloud.tencent.com/npm/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd"
@@ -1353,6 +1360,11 @@ webpack-virtual-modules@^0.6.2:
   resolved "https://mirrors.cloud.tencent.com/npm/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz#057faa9065c8acf48f24cb57ac0e77739ab9a7e8"
   integrity sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==
 
+whatwg-fetch@^3.6.20:
+  version "3.6.20"
+  resolved "https://registry.npmmirror.com/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz#580ce6d791facec91d37c72890995a0b48d31c70"
+  integrity sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==
+
 windicss@^3.5.6:
   version "3.5.6"
   resolved "https://mirrors.cloud.tencent.com/npm/windicss/-/windicss-3.5.6.tgz#30a34da76894d952a96c9a1921f2e91e13932183"