2 Revīzijas 6d6706606c ... 6d29b4c207

Autors SHA1 Ziņojums Datums
  miaofuhao 6d29b4c207 fix 2 nedēļas atpakaļ
  miaofuhao eeee513a30 fix 2 nedēļas atpakaļ

+ 1 - 1
.env.development

@@ -5,9 +5,9 @@ VITE_APP_TITLE = 蓝天燃气智慧话务系统
5 5
 VITE_APP_ENV = 'development'
6 6
 
7 7
 # VITE_APP_BASE_API = 'http://192.168.1.15:8160/'  # 接口地址
8
+#  VITE_APP_BASE_API = 'http://39.164.159.226:8160/'  # 接口地址
8 9
  VITE_APP_BASE_API = 'http://192.168.1.170:8160/'  # 接口地址
9 10
 
10
-# VITE_APP_BASE_API = 'http://192.168.1.170:8160/'  # 接口地址
11 11
 # VITE_APP_BASE_API = 'http://412ym2dg6665.vicp.fun/'  # 接口地址
12 12
 
13 13
 VITE_APP_BASE_WS = 'ws://192.168.1.19:9000/ws'

BIN
node_modules (2).zip


+ 195 - 2
src/views/main/chat/online/cpns/borderRight/borderRight.vue

@@ -127,18 +127,25 @@
127 127
           
128 128
           <!-- 其他标签页 - 保留标签结构但移除未使用的组件 -->
129 129
           <template v-else-if="tab.name === 'subscribe'">
130
+            <subscribe :userNo="customerInfo.customerNo" />
130 131
           </template>
131 132
           <template v-else-if="tab.name === 'payment'">
133
+            <PayRecord :userNo="customerInfo.customerNo" />
132 134
           </template>
133 135
           <template v-else-if="tab.name === 'meterReading'">
136
+            <MeterReading :userNo="customerInfo.customerNo" />
134 137
           </template>
135 138
           <template v-else-if="tab.name === 'overdue'">
139
+            <OweFee :userNo="customerInfo.customerNo" />
136 140
           </template>
137 141
           <template v-else-if="tab.name === 'meterInfo'">
142
+            <MeterBasicInfo :userNo="customerInfo.customerNo" />
138 143
           </template>
139 144
           <template v-else-if="tab.name === 'security'">
145
+            <seOrder :userNo="customerInfo.customerNo" />
140 146
           </template>
141 147
           <template v-else-if="tab.name === 'ticket'">
148
+            <woOrder :userNo="customerInfo.customerNo" />
142 149
           </template>
143 150
         </el-tab-pane>
144 151
       </el-tabs>
@@ -244,11 +251,19 @@ import { getPageListData ,deletePageData } from '@/api/main/system/system';
244 251
 import request from '@/utils/request';
245 252
 import { userToAsterisk } from '@/utils/aes';
246 253
 import useSelectStore from '@/store/commonSelect/common';
254
+import { getToken } from '@/utils/auth'
247 255
 
256
+import subscribe from '@/components/conInfor/subscribe/index.vue' // 预约记录
257
+import PayRecord from '@/components/conInfor/payrecord/index.vue' // 缴费明细
258
+import MeterReading from '@/components/conInfor/meterReading/index.vue' // 抄表记录
259
+import OweFee from '@/components/conInfor/owefee/index.vue'  // 欠费记录
260
+import MeterBasicInfo from '@/components/conInfor/meterBasicInfo/index.vue' // 表具信息
261
+import seOrder from '@/components/conInfor/seOrder/index.vue' // 安检工单
262
+import woOrder from '@/components/conInfor/woOrder/index.vue' // 工单信息
248 263
 // 标签页状态
249 264
 const activeName = ref('first');
250 265
 const isIntelligentFlag = ref(useSelectStore().isIntelligentFlag)
251
-
266
+const getOpenId = ref('')
252 267
 // 客户信息数据
253 268
 const customerInfo = ref({
254 269
   customerNo: '',
@@ -349,7 +364,24 @@ const userSearchLoading = ref(false);
349 364
 // 关联患者
350 365
 const associatedPatient = async () => {
351 366
   try {
352
-    ElMessage.warning('请先选择客户');
367
+    if (!AssociaPatientId.value) {
368
+      ElMessage.warning('请先选择客户');
369
+      return;
370
+    }
371
+    if (!getOpenId.value) {
372
+      ElMessage.warning('请先选择聊天对象');
373
+      return;
374
+    }
375
+    const params = {
376
+      patientId: AssociaPatientId.value,
377
+      openId: getOpenId.value
378
+    };
379
+    const res = await getPageListData('/patient/patient/associated', params);
380
+    if (res.state === 'success') {
381
+      ElMessage.success('关联成功');
382
+    } else {
383
+      ElMessage.error(res.message || '关联失败');
384
+    }
353 385
   } catch (error) {
354 386
     console.error('关联患者失败:', error);
355 387
     ElMessage.error('关联失败,请重试');
@@ -497,7 +529,168 @@ function delQuickMsg(rowData) {
497 529
     console.log('取消删除');
498 530
   });
499 531
 }
532
+// 搜索关键词
533
+const searchKeyword = ref('');
534
+const recommendations = ref([]);
535
+
536
+function searchRecommendations() {
537
+    knowledgeLoading.value = true;
538
+    if (searchKeyword.value) {
539
+        aiKnowledge(searchKeyword.value).then(res => {}).finally(() => {
540
+            knowledgeLoading.value = false;
541
+        })
542
+    } else {
543
+        ElMessage({
544
+        message: '请输入关键词',
545
+        type: 'warning'
546
+        });
547
+    }
548
+}
549
+const knowledgeLoading = ref(false)
550
+const aiKnowledge = async (text) => {
551
+    
552
+    // 构建对话文本
553
+    // let text = '热点问题请注意'
554
+    knowledgeObj.value = ''
555
+    if (text) {
556
+        // 获取AI分析结果
557
+        let res = await getKnowledgeDocs(text);
558
+        // 移除思考过程
559
+        if (knowledgeObj.value) {
560
+            const obj = {
561
+                content: knowledgeObj.value,
562
+                // type: knowledgeObj.value.intention,
563
+                source: "AI 推荐",
564
+                time: moment().format('HH:mm:ss'), // 当前时间时分秒
565
+            }
566
+            recommendations.value.splice(0,0,obj)
567
+        }
568
+        
569
+    }
570
+}
571
+const knowledgeObj = ref('')
572
+const workflow_run_id = ref('')
573
+const getKnowledgeDocs = async (text) => {
574
+    
575
+    // const params = {
576
+    //     "id": 6,
577
+    //     "inputs": {"type": "zsk","text":text}
578
+    // };
579
+   
580
+    // if (workflow_run_id.value) {
581
+    //     params.inputs.workflowrunid = workflow_run_id.value
582
+    // }
583
+    const params = {
584
+        "auto_generate_name": false,
585
+        "conversation_id": "",
586
+        "files": [],
587
+        "id": 8,
588
+        "inputs": {},
589
+        "query": text
590
+    };
591
+    if (workflow_run_id.value) {
592
+        params.conversation_id = workflow_run_id.value
593
+    }
594
+    try {
595
+        // 发送请求
596
+        // const url = import.meta.env.VITE_APP_AI_API || 'https://open.bigmodel.cn/api/paas/v4/chat/completions'
597
+        // const url = import.meta.env.VITE_APP_BASE_API+'/dify/difyassistant/workflows'  
598
+        const url = import.meta.env.VITE_APP_BASE_API+ '/dify/difyassistant/chatMessages'
599
+        console.log(url,params)
600
+        let response = await fetch(url,
601
+            {
602
+                method: "post",
603
+                responseType: "stream",
604
+                headers: {
605
+                    "Content-Type": "application/json",
606
+                    "Authorization": "Bearer "+getToken(),
607
+                },
608
+                body: JSON.stringify(params),
609
+            }
610
+        );
611
+
612
+        let resultStr = '';
613
+
614
+        // ok字段判断是否成功获取到数据流
615
+        if (!response.ok) {
616
+            throw new Error("Network response was not ok");
617
+        }
618
+        // 用来获取一个可读的流的读取器(Reader)以流的方式处理响应体数据
619
+        const reader = response.body.getReader();
620
+        // 将流中的字节数据解码为文本字符串
621
+        const textDecoder = new TextDecoder();
622
+        let result = true;
623
+        let sqlValue = ''
624
+
625
+        while (result) {
626
+            // done表示流是否已经完成读取  value包含读取到的数据块
627
+            const { done, value } = await reader.read();
628
+            if (done) {
629
+                result = false;
630
+                return resultStr;
631
+                break;
632
+            }
633
+            // 拿到的value就是后端分段返回的数据,大多是以data:开头的字符串
634
+            // 需要通过decode方法处理数据块,例如转换为文本或进行其他操作
635
+            const chunkText = textDecoder.decode(value).split("\n").forEach((val) => {
636
+                if (!val) return;
637
+                try {
638
+                    // 后端返回的流式数据一般都是以data:开头的字符,排除掉data:后就是需要的数据
639
+                    // 具体返回结构可以跟后端约定
640
+                    let text = val?.replace("data:", "") || ""
641
+                    const resultData = JSON.parse(text)
642
+                    let resultText = resultData.answer || ''
643
+                    workflow_run_id.value = resultData.conversation_id
644
+                    knowledgeObj.value += resultText
645
+                    console.log(knowledgeObj.value)
646
+                } catch (err) { }
647
+            });
648
+        }
649
+
650
+    } catch (err) {
651
+        console.error('获取客户信息异常:', err);
652
+        return err;
653
+    }
654
+}
655
+const dealChatMessage = (msg) => {
656
+    if (msg.detail && msg.detail.content && isIntelligentFlag.value ==='true') {
657
+      aiKnowledge(msg.detail.content)
658
+    }
659
+   
660
+}
661
+// 获取客户信息详情
662
+async function getchatDetail(openId) {
663
+  getOpenId.value = openId
664
+  console.log(getOpenId.value)
665
+  // if (getOpenId.value) window.addEventListener(`ChatMessageEvent-${getOpenId.value}`, dealChatMessage)
666
+  if (!getOpenId.value) {
667
+    ElMessage.warning('请提供有效的openId');
668
+    return;
669
+  }
670
+  
671
+  try {
672
+    const res = await request.get('/patient/patient', {
673
+      params: { openId }
674
+    });
675
+    
676
+    if (res.state === 'success' && res.data) {
677
+      // 更新客户信息
678
+      customerInfo.value = res.data[0];
679
+      // 对手机号和身份证号进行掩码处理
680
+      customerInfo.value.phoneNumber =   customerInfo.value.phoneNumber ? userToAsterisk(customerInfo.value.phoneNumber) : '';
681
+      customerInfo.value.idcard =   customerInfo.value.idcard ? userToAsterisk(customerInfo.value.idcard) : '';
682
+      customerInfo.value.tel =   customerInfo.value.tel ? userToAsterisk(customerInfo.value.tel) : '';
683
+    } else {
684
+      ElMessage.error('获取客户信息失败');
685
+      console.error('获取客户信息失败:', res.message);
686
+    }
687
+  } catch (error) {
688
+    ElMessage.error('获取客户信息异常');
689
+    console.error('获取客户信息异常:', error);
690
+  }
691
+}
500 692
 defineExpose({
693
+  getchatDetail,
501 694
   getQuickMsgList
502 695
 })
503 696
 </script>