Просмотр исходного кода

fix: 修复AI助手描述及优化代码结构

闪电 1 год назад
Родитель
Сommit
27b9be8d0d

+ 1 - 1
package.json

5
   "author": "加一",
5
   "author": "加一",
6
   "license": "MIT",
6
   "license": "MIT",
7
   "scripts": {
7
   "scripts": {
8
-    "dev": "vite --mode zzprod",
8
+    "dev": "vite",
9
     "css": "npx tailwindcss -i ./src/style.css -o ./src/assets/style.css --watch",
9
     "css": "npx tailwindcss -i ./src/style.css -o ./src/assets/style.css --watch",
10
     "build:prod": "vite build",
10
     "build:prod": "vite build",
11
     "build:bayuan": "vite build --mode zzprod",
11
     "build:bayuan": "vite build --mode zzprod",

+ 43 - 21
src/components/main/Navbar/cpns/aiDialog/aiDialog.vue

8
                 :style="{ 'background': 'url(' + base64data.aiBG3 + ')  -16px -36px/400px 300px no-repeat'}">
8
                 :style="{ 'background': 'url(' + base64data.aiBG3 + ')  -16px -36px/400px 300px no-repeat'}">
9
                 <div class="ai_content">
9
                 <div class="ai_content">
10
                     <div class="ai_des">
10
                     <div class="ai_des">
11
-                        我是你的智能助手,可以帮你撰写营销文案、查询数据和功能,助力你更高效的完成工作
11
+                        我是你的智能助手, 请问有什么可以帮您
12
                     </div>
12
                     </div>
13
                     <div class="ai_tips">
13
                     <div class="ai_tips">
14
                         💡你可能想知道
14
                         💡你可能想知道
15
                     </div>
15
                     </div>
16
                     <div class="ai_text">
16
                     <div class="ai_text">
17
-                        <div class="ai_item" @click="chatModalHandle(item.content)" v-for="(item,index) in conModelData" :key="index">
17
+                        <div class="ai_item" @click="chatModalHandle(item)" v-for="(item,index) in conModelData" :key="index">
18
                             <span class="ai_label">{{item.icon}}{{item.title}}</span>
18
                             <span class="ai_label">{{item.icon}}{{item.title}}</span>
19
                             <span class="ai_value">{{item.content}}</span>
19
                             <span class="ai_value">{{item.content}}</span>
20
                         </div>
20
                         </div>
230
     import aiIcon from '@/assets/images/aiIcon.png' // 默认头像
230
     import aiIcon from '@/assets/images/aiIcon.png' // 默认头像
231
     import { getToken } from '@/utils/auth'
231
     import { getToken } from '@/utils/auth'
232
     import { base64data } from '@/utils/baseUrlData'
232
     import { base64data } from '@/utils/baseUrlData'
233
+    import { createPageData } from '@/api/main/system/system';
233
     const { proxy } = getCurrentInstance();
234
     const { proxy } = getCurrentInstance();
234
     const drawer = ref(false)
235
     const drawer = ref(false)
235
     const props = defineProps({
236
     const props = defineProps({
260
         }
261
         }
261
     })
262
     })
262
 
263
 
264
+    const currentSession = ref({});
263
     const dialogState = ref('新建会话')
265
     const dialogState = ref('新建会话')
264
     const tipFlag = ref(false)
266
     const tipFlag = ref(false)
265
 
267
 
283
         }
285
         }
284
     }
286
     }
285
 
287
 
286
-    function chatModalHandle(value) {
288
+    
289
+
290
+    function chatModalHandle(item) {
287
         console.log('chatModalHandle')
291
         console.log('chatModalHandle')
288
-        // dialogState.value = '会话中'
289
-        postChatText.value = value
292
+        currentSession.value = item
293
+        dialogState.value = '会话中'
294
+        // postChatText.value = value
290
     }
295
     }
291
     function tipBgHandle() {
296
     function tipBgHandle() {
292
         tipFlag.value = false
297
         tipFlag.value = false
325
         
330
         
326
     }
331
     }
327
 
332
 
333
+    const createLog = (content) => {
334
+        createPageData('/ai/aioperation', {
335
+            operateType: 'DeepSeek',
336
+            operationContent: content,
337
+        }).then(() => {
338
+
339
+        }).catch(() => {
340
+            
341
+        })
342
+    }
343
+
328
     const hisItemFlag = ref(false)
344
     const hisItemFlag = ref(false)
329
     function hisItemOver() {
345
     function hisItemOver() {
330
         hisItemFlag.value = true
346
         hisItemFlag.value = true
412
             roll();
428
             roll();
413
         }, 200);
429
         }, 200);
414
         try {
430
         try {
431
+            let content = currentSession.value.content
432
+            if (!content) {
433
+                content = `你是一个专业的心理专家,能帮坐席解决所有心理上的问题,回答问题需要精简,尽量全面,回答的字数不要过长`
434
+            }
415
             params = {
435
             params = {
416
                 model: 'deepseek-r1:32b',
436
                 model: 'deepseek-r1:32b',
417
 				messages: [{
437
 				messages: [{
418
 					role: 'system',
438
 					role: 'system',
419
-					content: `你是一位专业的心理咨询师,擅长帮助来访者探索情绪、压力、人际关系等问题。请根据以下用户输入,提供专业、温暖且有针对性的心理咨询建议。如果用户的问题涉及具体心理困扰,请尝试引导用户深入思考,并提供适当的应对策略或情绪调节方法。
420
-
421
-用户输入:{用户输入信息}
422
-
423
-请根据以下步骤进行回复:
424
-1. **共情与理解**:首先对用户的情绪或困扰表示理解,建立信任感。
425
-2. **问题分析**:分析用户问题的可能根源或核心矛盾。
426
-3. **建议与引导**:提供具体的建议或引导用户思考解决方案。
427
-4. **总结与支持**:总结关键点,并鼓励用户尝试行动或进一步探索。
428
-
429
-注意:保持语气温和、专业,避免使用过于绝对的判断或建议,内容尽量言简意赅。`
439
+					content,
430
 				}, {
440
 				}, {
431
 					role: 'user',
441
 					role: 'user',
432
 					content: postChatText.value,
442
 					content: postChatText.value,
434
 				stop: ['stop'],
444
 				stop: ['stop'],
435
 				stream: true,
445
 				stream: true,
436
             }
446
             }
447
+
448
+            createLog(postChatText.value);
437
             // 发送请求
449
             // 发送请求
438
             // let response = await fetch("http://192.168.1.89:7861/chat/kb_chat",
450
             // let response = await fetch("http://192.168.1.89:7861/chat/kb_chat",
439
             const url = import.meta.env.VITE_APP_AI_API || 'https://open.bigmodel.cn/api/paas/v4/chat/completions'
451
             const url = import.meta.env.VITE_APP_AI_API || 'https://open.bigmodel.cn/api/paas/v4/chat/completions'
515
         //     title:'标题大师',
527
         //     title:'标题大师',
516
         //     content:'请帮我拟定几个合适的标题,我的主题或内容是:'
528
         //     content:'请帮我拟定几个合适的标题,我的主题或内容是:'
517
         // },
529
         // },
518
-        // {
519
-        //     icon:'💬 ',
520
-        //     title:'疾病咨询',
521
-        //     content:'请帮我查询一下,心脏病'
522
-        // },
530
+        {
531
+            icon:'💬 ',
532
+            title:'心理咨询建议',
533
+            content:`你是一位专业的心理咨询师,擅长帮助来访者探索情绪、压力、人际关系等问题。请根据以下用户输入,提供专业、温暖且有针对性的心理咨询建议。如果用户的问题涉及具体心理困扰,请尝试引导用户深入思考,并提供适当的应对策略或情绪调节方法。
534
+
535
+用户输入:{用户输入信息}
536
+
537
+请根据以下步骤进行回复:
538
+1. **共情与理解**:首先对用户的情绪或困扰表示理解,建立信任感。
539
+2. **问题分析**:分析用户问题的可能根源或核心矛盾。
540
+3. **建议与引导**:提供具体的建议或引导用户思考解决方案。
541
+4. **总结与支持**:总结关键点,并鼓励用户尝试行动或进一步探索。
542
+
543
+注意:保持语气温和、专业,避免使用过于绝对的判断或建议,内容尽量言简意赅。`
544
+        },
523
         
545
         
524
         // {
546
         // {
525
         //     icon:'🔍',
547
         //     icon:'🔍',

+ 25 - 0
src/components/main/drawer-phone/index.vue

185
     Notebook,
185
     Notebook,
186
     Mute
186
     Mute
187
 } from '@element-plus/icons-vue';
187
 } from '@element-plus/icons-vue';
188
+import { createPageData } from '@/api/main/system/system';
188
 const router = useRouter()
189
 const router = useRouter()
189
 const showCallPanel = ref(false);
190
 const showCallPanel = ref(false);
190
 const searchQuery = ref('');
191
 const searchQuery = ref('');
244
 };
245
 };
245
 
246
 
246
 const lineState = ref(7);
247
 const lineState = ref(7);
248
+const msgs: any = ref([])
247
 
249
 
248
 const callPhoneFlag = ref(false)
250
 const callPhoneFlag = ref(false)
249
 
251
 
308
         if (!timer) timer = window.setInterval(updateCallDuration, 1000);
310
         if (!timer) timer = window.setInterval(updateCallDuration, 1000);
309
     } else if (state === 4) {
311
     } else if (state === 4) {
310
         callState.value = 0
312
         callState.value = 0
313
+        console.log('timer',timer)
314
+        saveTranslate(currentCall.value.callid, msgs.value)
311
         initCall(true)
315
         initCall(true)
312
     }
316
     }
313
 }
317
 }
321
     6: '振铃',
325
     6: '振铃',
322
     7: '注销',
326
     7: '注销',
323
 }
327
 }
328
+
329
+const saveTranslate = (callid, translate) => {
330
+    console.log(callid, translate, 'adsfasdf')
331
+    if (!translate || !translate.length || !callid) return;
332
+    createPageData('/call/translate', {
333
+        callid,
334
+        translate: JSON.stringify(translate),
335
+    }).then(() => {
336
+
337
+    }).catch(() => {
338
+
339
+    })
340
+}
341
+
342
+
324
 const initWs = () => {
343
 const initWs = () => {
325
     ws.addEventListener('message', function (evt) {
344
     ws.addEventListener('message', function (evt) {
326
         const telWSData = JSON.parse(evt.data)
345
         const telWSData = JSON.parse(evt.data)
337
                     break
356
                     break
338
                 case 'incoming': // 来电
357
                 case 'incoming': // 来电
339
                     {
358
                     {
359
+                        msgs.value = []
340
                         currentCall.value.phone = getUnprefixNuber(telWSData.Number) 
360
                         currentCall.value.phone = getUnprefixNuber(telWSData.Number) 
341
                         currentCall.value.truePhone = hidePhone(telWSData.Number)
361
                         currentCall.value.truePhone = hidePhone(telWSData.Number)
362
+                        currentCall.value.callid = telWSData.CallID
363
+                        console.log(currentCall.value, 'currentCall.value')
342
                         getUserInfo(currentCall.value.phone)
364
                         getUserInfo(currentCall.value.phone)
343
                         router.push({
365
                         router.push({
344
                             path: '/inComming/callScreen/'+telWSData.Number,
366
                             path: '/inComming/callScreen/'+telWSData.Number,
360
     })
382
     })
361
 }
383
 }
362
 
384
 
385
+
386
+
363
 const asrMessageEvent = (msg) => {
387
 const asrMessageEvent = (msg) => {
364
   console.log('asrMessageEvent', msg)
388
   console.log('asrMessageEvent', msg)
389
+  msgs.value.push(msg)
365
   const event = new CustomEvent("AsrMessageEvent", { detail: msg });
390
   const event = new CustomEvent("AsrMessageEvent", { detail: msg });
366
   window.dispatchEvent(event);
391
   window.dispatchEvent(event);
367
 }
392
 }

+ 30 - 188
src/views/main/phone/index.vue

450
 const searchQuery = ref('');
450
 const searchQuery = ref('');
451
 const aiLoading = ref(false);
451
 const aiLoading = ref(false);
452
 const isCanAutoScroll = ref(1); 
452
 const isCanAutoScroll = ref(1); 
453
-console.log('proxy', proxy.$route);
454
 
453
 
455
 const showAsr = ref(import.meta.env.VITE_APP_AI_ASR === 'true');
454
 const showAsr = ref(import.meta.env.VITE_APP_AI_ASR === 'true');
456
 const showAI = ref(import.meta.env.VITE_APP_AI_SEARCH === 'true');
455
 const showAI = ref(import.meta.env.VITE_APP_AI_SEARCH === 'true');
459
 console.log(telNumber.value)
458
 console.log(telNumber.value)
460
 proxy.$route.meta.title = telNumber.value || '来电弹屏';
459
 proxy.$route.meta.title = telNumber.value || '来电弹屏';
461
 const callid = ref(proxy.$route.query.callid || 0);
460
 const callid = ref(proxy.$route.query.callid || 0);
462
-onMounted(() => {
463
-    getUserInfo();
464
-});
465
-onUnmounted(() => {
466
 
461
 
467
-});
462
+const createLog = (content = '') => {
463
+    createPageData('/ai/aioperation', {
464
+        operateType: 'ASR',
465
+        operationContent: content,
466
+    }).then(() => {
467
+
468
+    }).catch(() => {
469
+
470
+    })
471
+}
472
+
473
+
474
+if (callid) createLog('callid');
475
+
468
 const showDialpad = ref(false);
476
 const showDialpad = ref(false);
469
 
477
 
470
 const showContacts = ref(false);
478
 const showContacts = ref(false);
637
     ],
645
     ],
638
     description: [
646
     description: [
639
         { required: true, message: '请输入问题描述', trigger: 'blur' },
647
         { required: true, message: '请输入问题描述', trigger: 'blur' },
640
-        { min: 5, max: 100, message: '问题描述5-100个字符', trigger: 'blur' },
648
+        { min: 5, max: 2000, message: '问题描述5-2000个字符', trigger: 'blur' },
641
     ],
649
     ],
642
     handleMethod: [
650
     handleMethod: [
643
         { required: true, message: '请选择处理方式', trigger: 'change' }
651
         { required: true, message: '请选择处理方式', trigger: 'change' }
728
                 console.log(data, 'submit');
736
                 console.log(data, 'submit');
729
                 if (data.state === 'success') {
737
                 if (data.state === 'success') {
730
                     ElMessage.success('提交成功');
738
                     ElMessage.success('提交成功');
739
+                    transcripts.value = []
740
+                    
731
                     resetForm()
741
                     resetForm()
732
                     close()
742
                     close()
733
                 } else {
743
                 } else {
815
     //     direction: 1,
825
     //     direction: 1,
816
     //     timestamp: '14:30:24',
826
     //     timestamp: '14:30:24',
817
     //     page_content: '你好,中国热线请假。',
827
     //     page_content: '你好,中国热线请假。',
818
-    // }, {
819
-    //     direction: 2,
820
-    //     timestamp: '14:30:24',
821
-    //     page_content: '喂,你好,嗯,听这样哦,我是林州这个横岛岳湖人呃',
822
-    // }, {
823
-    //     direction: 1,
824
-    //     timestamp: '14:30:24',
825
-    //     page_content: '什么问题啊?你确实是无法统一工作呃,按照说实体上头到现在都没有工作了',
826
-    // }, {
827
-    //     direction: 2,
828
-    //     timestamp: '14:30:24',
829
-    //     page_content: '我来问违约金怎么事儿?嗯,他说他他说是月底工资,',
830
-    // }, {
831
-    //     direction: 1,
832
-    //     timestamp: '14:30:24',
833
-    //     page_content: '这个麻问您一下,我这边给您登记反映,您是林州市哪里的?',
834
-    // }, {
835
-    //     direction: 2,
836
-    //     timestamp: '14:30:24',
837
-    //     page_content: '林州恒大悦府,恒大悦府',
838
-    // }, {
839
-    //     direction: 1,
840
-    //     timestamp: '14:30:24',
841
-    //     page_content: '嗯,乐府乐是那个舒心一个舒心,一个对那个乐是吧?',
842
-    // }, {
843
-    //     direction: 2,
844
-    //     timestamp: '14:30:24',
845
-    //     page_content: '嗯,对嗯',
846
-    // }, {
847
-    //     direction: 1,
848
-    //     timestamp: '14:30:24',
849
-    //     page_content: '恒大乐府分几七部分啊,',
850
-    // }, {
851
-    //     direction: 2,
852
-    //     timestamp: '14:30:24',
853
-    //     page_content: '分级,你们一期二期分不分呃,一期同大月付一期几号楼几单元,十七号楼一单元幺九零一十七号楼一单元幺九零一',
854
-    // }, {
855
-    //     direction: 1,
856
-    //     timestamp: '14:30:24',
857
-    //     page_content: '嗯,您怎么称呼先生啊?',
858
-    // }, {
859
-    //     direction: 2,
860
-    //     timestamp: '14:30:24',
861
-    //     page_content: '免贵?我就我我姓李李松,你让李先生吧',
862
-    // }, {
863
-    //     direction: 1,
864
-    //     timestamp: '14:30:24',
865
-    //     page_content: '给您单心恒大悦府在林州市的哪个路段。您说一下',
866
-    // }, {
867
-    //     direction: 2,
868
-    //     timestamp: '14:30:24',
869
-    //     page_content: '在这个这个是河南一个湖,也就他就一个湖,河南一个湖,我也不知道这个是什么路段',
870
-    // }, {
871
-    //     direction: 1,
872
-    //     timestamp: '14:30:24',
873
-    //     page_content: '那您没有路段的话,这个位置不明确,我这边就暂不给您反映啊',
874
-    // }, {
875
-    //     direction: 2,
876
-    //     timestamp: '14:30:24',
877
-    //     page_content: '嗯,那个是可能是那个呃华城相府,',
878
-    // }, {
879
-    //     direction: 1,
880
-    //     timestamp: '14:30:24',
881
-    //     page_content: '哪个路段?',
882
-    // }, {
883
-    //     direction: 2,
884
-    //     timestamp: '14:30:24',
885
-    //     page_content: '不是那个那个是呃鲁八大道,',
886
-    // }, {
887
-    //     direction: 1,
888
-    //     timestamp: '14:30:24',
889
-    //     page_content: '鲁八大道中段什么大道,',
890
-    // }, {
891
-    //     direction: 2,
892
-    //     timestamp: '14:30:24',
893
-    //     page_content: '鲁班哪两个字卢班鲁班嗯,',
894
-    // }, {
895
-    //     direction: 1,
896
-    //     timestamp: '14:30:24',
897
-    //     page_content: '鲁班大道与什么路交叉口?',
898
-    // }, {
899
-    //     direction: 2,
900
-    //     timestamp: '14:30:24',
901
-    //     page_content: '嗯,鲁班大道一零米,',
902
-    // }, 
903
-    // {
904
-    //     direction: 1,
905
-    //     timestamp: '14:30:24',
906
-    //     page_content: '你们是是什么路来的,',
907
-    // }, {
908
-    //     direction: 2,
909
-    //     timestamp: '14:30:24',
910
-    //     page_content: '你就说恒大悦府就行了。',
911
-    // }, {
912
-    //     direction: 1,
913
-    //     timestamp: '14:30:24',
914
-    //     page_content: '那个那个零六就你一个恒大悦府必须哪个路段,',
915
-    // }, {
916
-    //     direction: 2,
917
-    //     timestamp: '14:30:24',
918
-    //     page_content: '我们这边也得清楚,鲁班大鲁班大道开元街道,',
919
-    // }, {
920
-    //     direction: 1,
921
-    //     timestamp: '14:30:24',
922
-    //     page_content: '恒大悦府是吗?',
923
-    // }, {
924
-    //     direction: 2,
925
-    //     timestamp: '14:30:24',
926
-    //     page_content: '哦,对,康阳街道的嗯,',
927
-    // }, {
928
-    //     direction: 1,
929
-    //     timestamp: '14:30:24',
930
-    //     page_content: '行好的,这边给您登记一下啊。',
931
-    // }, {
932
-    //     direction: 2,
933
-    //     timestamp: '14:30:24',
934
-    //     page_content: '嗯,好了,不歉。',
935
-    // }, {
936
-    //     direction: 1,
937
-    //     timestamp: '14:30:24',
938
-    //     page_content: '喂,哎,可以了。',
939
-    // }, {
940
-    //     direction: 2,
941
-    //     timestamp: '14:30:24',
942
-    //     page_content: '呃',
943
-    // }, {
944
-    //     direction: 1,
945
-    //     timestamp: '14:30:24',
946
-    //     page_content: '刚才我给你他们啊嗯已经给您登记了,稍后反应呃。',
947
-    // }, {
948
-    //     direction: 2,
949
-    //     timestamp: '14:30:24',
950
-    //     page_content: '登登记了,你登记的,我是你知道我反映的什么吗?',
951
-    // }, {
952
-    //     direction: 1,
953
-    //     timestamp: '14:30:24',
954
-    //     page_content: '你不是家中暖气没热吗?不热吗?',
955
-    // }, {
956
-    //     direction: 2,
957
-    //     timestamp: '14:30:24',
958
-    //     page_content: '这不是不热,是没充暖,我给物业,我给物业联系了,物业,说是呃,他们这里公司就两个人,一共十七栋楼,他问他说这个还能等待几天一栋一栋的开呢,我们的我我们的供暖费都交了。',
959
-    // }, {
960
-    //     direction: 2,
961
-    //     page_content: '看他几天,你看他几天',
962
-    // }, {
963
-    //     direction: 1,
964
-    //     page_content: '你给我说个定是不是嗯就是人员少,担心无法正常供暖,是不是啊?',
965
-    // }, {
966
-    //     direction: 2,
967
-    //     page_content: '他说还得几天,你现在十五号都是显示统一功能。你到现在就你你说排了几天,还得几天的。',
968
-    // }, {
969
-    //     direction: 1,
970
-    //     page_content: '嗯,好的,这边已经有您同小弟业主反映过了,跟您跟他同甘办理啊。',
971
-    // }, {
972
-    //     direction: 2,
973
-    //     page_content: '嗯嗯,行好的。',
974
-    // }
975
 ])
828
 ])
976
 // 关键词提示
829
 // 关键词提示
977
 const keywords = ref([
830
 const keywords = ref([
1071
         aiLoading.value = false;
924
         aiLoading.value = false;
1072
     }
925
     }
1073
 }
926
 }
927
+
928
+onMounted(() => {
929
+    transcripts.value = [];
930
+    getUserInfo();
931
+});
932
+onUnmounted(() => {
933
+
934
+});
1074
 async function getSearchDocs (text) {
935
 async function getSearchDocs (text) {
1075
-    // const params = {
1076
-    //     query: text,
1077
-    //     mode: "local_kb",
1078
-    //     kb_name: "mszsk",
1079
-    //     top_k: 1,
1080
-    //     score_threshold: 0.5,
1081
-    //     stream: true,
1082
-    //     model: "glm-4",
1083
-    //     temperature: 0.7,
1084
-    //     max_tokens: 0,
1085
-    //     prompt_name: "default",
1086
-    //     return_direct: false
1087
-    // }
1088
     const params = {
936
     const params = {
1089
         "model": "deepseek-r1:32b",
937
         "model": "deepseek-r1:32b",
1090
       "messages": [
938
       "messages": [
1095
 格式:[省/市/区/街道/楼栋号/房间号](如未提及则标记"未知")
943
 格式:[省/市/区/街道/楼栋号/房间号](如未提及则标记"未知")
1096
 注意模糊表述(如"北方城市""江浙地区"等需保留原话)
944
 注意模糊表述(如"北方城市""江浙地区"等需保留原话)
1097
 通话内容总结:
945
 通话内容总结:
1098
-用第三人称概括核心问题(100字
946
+用第三人称概括核心问题(100字到2000字之间
1099
 保留以下关键要素:
947
 保留以下关键要素:
1100
 • 主要症状描述(情绪/躯体/行为表现)
948
 • 主要症状描述(情绪/躯体/行为表现)
1101
 • 持续时间(使用"约X周/月/年"格式)
949
 • 持续时间(使用"约X周/月/年"格式)
1127
     };
975
     };
1128
     try {
976
     try {
1129
         // 发送请求
977
         // 发送请求
1130
-        // let response = await fetch("http://192.168.1.89:7861/chat/chat",
1131
-        //     {
1132
-        //         method: "post",
1133
-        //         // responseType: "stream",
1134
-        //         headers: {
1135
-        //             "Content-Type": "application/json",
1136
-        //         },
1137
-        //         body: JSON.stringify(params),
1138
-        //     }
1139
-        // );
1140
 
978
 
1141
         const url = import.meta.env.VITE_APP_AI_API || 'https://open.bigmodel.cn/api/paas/v4/chat/completions'
979
         const url = import.meta.env.VITE_APP_AI_API || 'https://open.bigmodel.cn/api/paas/v4/chat/completions'
1142
             let response = await fetch(url,
980
             let response = await fetch(url,
1198
         return err;
1036
         return err;
1199
     }
1037
     }
1200
 
1038
 
1039
+
1040
+
1201
 }
1041
 }
1202
 
1042
 
1043
+
1044
+
1203
 </script>
1045
 </script>
1204
 <style scoped>
1046
 <style scoped>
1205
 * {
1047
 * {