zhuliu 4 ماه پیش
والد
کامیت
179aaa7c51

+ 19 - 0
src/assets/css/main.scss

@@ -253,4 +253,23 @@
     content: "无数据";
     color:#c2c5c9;
   }
+}
+
+
+.cursor {
+  position: absolute;
+  pointer-events: none;
+  transform: translate(-50%, -50%);
+  animation: blink 1s infinite alternate;
+}
+
+@keyframes blink {
+  0% {
+      opacity: 0.3;
+      transform: translate(-50%, -50%) scale(0.8);
+  }
+  100% {
+      opacity: 1;
+      transform: translate(-50%, -50%) scale(1.2);
+  }
 }

+ 8 - 0
src/views/AITools/OADefense/mixins/index.js

@@ -62,6 +62,10 @@ export default {
                                this.result += json.data.text; 
                             }
                             
+                        }else if(json.event == 'workflow_finished'){
+                            if(json.data){
+                                this.result = json.data.outputs.output; 
+                             }
                         }
                         
                     } catch (e) {
@@ -80,6 +84,10 @@ export default {
                                         if(json.data){
                                             this.result += json.data.text; 
                                          }
+                                    }else if(json.event == 'workflow_finished'){
+                                        if(json.data){
+                                            this.result = json.data.outputs.output; 
+                                         }
                                     }
                                 }
                                 catch(e){

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1 - 1
src/views/AITools/assistWritingInstruction/assistWritingInstruction.vue


+ 329 - 0
src/views/AITools/assistWritingInstruction/mixins/index-print.js

@@ -0,0 +1,329 @@
+const cursor_svg = '<svg t="1749101929606" class="icon cursor" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6995" width="200" height="200"><path d="M512 0a51.2 51.2 0 0 0-51.2 51.2v921.6a51.2 51.2 0 0 0 51.2 51.2 51.2 51.2 0 0 0 51.2-51.2V51.2a51.2 51.2 0 0 0-51.2-51.2z" fill="#231815" p-id="6996"></path></svg>'
+export default {
+    data() {
+        return {
+            controller:null,
+            current_result_sort:[],
+            current_result_obj:{}
+        }
+    },
+    computed:{
+        userinfo(){
+            return this.$s.getObj('userinfo')
+        }
+    },
+    methods: {
+        async getResult(){
+            if(this.loading){
+                this.$message.warning('请等当前执行完成')
+                return
+            }
+            if(!this.inputs.claim){
+                this.$message.warning('请输入权利要求')
+                return
+            }
+            if(!this.inputs.background){
+                this.$message.warning('请输入背景技术')
+                return
+            }
+            this.loading = true
+            this.show = false
+            this.result = []
+            this.confession = {}
+            this.controller = new AbortController();
+            var params = this.inputs
+            const response = await fetch('/api/xiaoshi/dify/generateInstruction', {
+              method: 'POST',
+              headers: {
+                'Content-Type': 'application/json',
+                'Accept': 'text/event-stream',
+              },
+              body:JSON.stringify(params),
+              signal: this.controller.signal
+            });
+            if (!response.ok) throw new Error('AI API 调用失败');
+            const reader = response.body.getReader();
+            const decoder = new TextDecoder('utf-8');
+            let noFinishMessage = ''
+            this.timed_acquisition()
+            while (true) {
+                const { done, value } = await reader.read();
+                if (done){
+                    this.loading = false
+                    break;
+                } 
+                const chunk = decoder.decode(value);
+                const lines2 = chunk.split('\n\n').filter(line => line.trim() !== '' && line.trim() !== 'data:event: ping')
+                for(const line of lines2){
+                    const jsonStr1 = line.replace(/^data:\s{0,}/, '');
+                    const jsonStr = jsonStr1.trim()
+                    if(jsonStr == 'event: ping' || jsonStr ==''){
+                        continue;
+                    }
+                    try {
+                        const json = JSON.parse(jsonStr);
+                        if(json.event == 'all_start'){
+                        }else if(json.event == 'start'){
+                            this.result.push(
+                                {
+                                    field:json.field,
+                                    content:json.content,
+                                    title:this.title_obj[json.field],
+                                    state:'start'
+                                }
+                            )
+                            this.current_result_sort.push(json.field)
+                            this.current_result_obj[json.field] = {
+                                content:'',
+                                current_content:'',
+                                state:'start'
+                            }
+                        }else if(json.event == 'message'){
+                            this.current_result_obj[json.field].content += json.content.replace(/\\{1,10}n/g,'<br>')
+                        }else if(json.event == 'end'){
+                            // let obj = this.result.find(item=>{
+                            //     return item.field == json.field
+                            // })
+                            // if(obj){
+                            //     obj.state = 'end'
+                            // }
+                            this.current_result_obj[json.field].state = 'end'
+                            if(json.field == 'title'){
+                                this.currentConversation.id = json.id
+                                this.queryConfessionSession(1)
+                            }
+                        }else if(json.event == 'all_end'){
+                            this.queryConfessionSession(false,true)  
+                            this.loading = false
+                            break;
+                        }
+                        
+                    } catch (e) {
+                        if(jsonStr.indexOf('{') == 0){
+                            noFinishMessage = jsonStr
+                        }else{
+                            noFinishMessage += jsonStr
+                            if(jsonStr.lastIndexOf('}') == jsonStr.length - 1){
+                                try{
+                                    const json = JSON.parse(noFinishMessage);
+                                    if(json.event == 'all_start'){
+                                    }else if(json.event == 'start'){
+                                        this.result.push(
+                                            {
+                                                field:json.field,
+                                                content:json.content,
+                                                title:this.title_obj[json.field],
+                                                state:'start'
+                                            }
+                                        )
+                                        this.current_result_sort.push(json.field)
+                                        this.current_result_obj[json.field] = {
+                                            content:'',
+                                            state:'start'
+                                        }
+                                    }else if(json.event == 'message'){
+                                        this.current_result_obj[json.field].content += json.content.replace(/\\{1,10}n/g,'<br>')
+                                    }else if(json.event == 'end'){
+                                        // let obj = this.result.find(item=>{
+                                        //     return item.field == json.field
+                                        // })
+                                        // if(obj){
+                                        //     obj.state = 'end'
+                                        // }
+                                        this.current_result_obj[json.field].state = 'end'
+                                        if(json.field == 'title'){
+                                            this.currentConversation.id = json.id
+                                            this.queryConfessionSession(1)
+                                        }
+                                    }else if(json.event == 'all_end'){
+                                        this.queryConfessionSession(false,true)  
+                                        this.loading = false
+                                        break;
+                                    }
+                                }
+                                catch(e){
+                                    console.error('解析响应数据出错:', e);
+                                }finally{
+                                    noFinishMessage = ''
+                                }
+                            }
+                        }
+                    }
+                    
+                }
+            }
+        },
+
+        timed_acquisition(){
+            var that = this
+            var timer = setInterval(() => {
+                if(!that.loading){
+                    clearInterval(timer);
+                    return
+                }
+                that.getResultContent()
+            }, 100);
+        },
+
+        getResultContent(){
+            if(this.current_result_sort.length == 0){
+                return
+            }
+            let field = this.current_result_sort[0]
+            let obj = this.result.find(item=>{
+                return item.field == field
+            })
+            if(!obj){
+                return
+            }
+            let state = this.current_result_obj[field].state
+            let content = this.current_result_obj[field].content
+            if(!content && state == 'end'){
+                this.current_result_sort.shift()
+                obj.state = 'end'
+                return
+            }
+            if(!content){
+                return
+            }
+            let content_after = ''
+            if(content.startsWith("<br>")){
+                content_after = content.substring(4,content.length)
+                this.current_result_obj[field].current_content += '<p>'
+            }else{
+                let sub_str = content.substring(0,1)
+                content_after = content.substring(1,content.length)
+                this.current_result_obj[field].current_content += sub_str
+            }
+            obj.content = this.current_result_obj[field].current_content
+            this.current_result_obj[field].content = content_after
+        },
+
+        formattedText(text) {
+            // 将<br>替换为<p>标签
+            let html = text.replace(/<br>/gi, '</p><p>').replace(/^<p>|<\/p>$/gi, '')
+            return html;
+        },
+        cancelRun(){
+            if (this.controller) {
+                this.controller.abort();
+            }
+            this.loading = false
+        },
+        //格式化AI答复
+        formateAIAnswer(chat){
+            let answer = chat.replace('null','')
+            let len = answer.length
+
+            let signs = [
+                {
+                    start:'<think>',
+                    end:'</think>'
+                },
+                {
+                    start:'<details style="color:gray;background-color: #f8f8f8;padding: 8px;border-radius: 4px;" open> <summary> Thinking... </summary>',
+                    end:'</details>'
+                },
+            ]
+            let sign_obj = {}
+            let start_index = -1
+            let end_index = -1
+
+            for(let i = 0;i<signs.length;i++){
+                let item = signs[i]
+                let index = answer.indexOf(item.start)
+                if(index!=-1){
+                    sign_obj = item
+                    start_index = index
+                    end_index = answer.indexOf(item.end)
+                    break;
+                }
+            }
+
+            var arr = []
+            if(start_index == -1){
+                let obj = {
+                    type:'text',
+                    content:answer.trim()
+                }
+                arr.push(obj)
+                return arr
+            }
+            if(end_index == -1){
+                let obj = {
+                    type:'text',
+                    content:answer.substring(0, start_index).trim()
+                }
+                arr.push(obj)
+                obj = {
+                    type:'think',
+                    content:answer.substring(start_index + sign_obj.start.length,len).trim(),
+                    show:false
+                }
+                if(chat.id == this.currentMessage.id){
+                    obj.show = true
+                }
+                arr.push(obj)
+                return arr
+            }
+            let obj = {
+                type:'text',
+                content:answer.substring(0, start_index).trim()
+            }
+            arr.push(obj)
+            obj = {
+                type:'think',
+                show:false,
+                content:answer.substring(start_index + sign_obj.start.length, end_index).trim()
+            }
+            arr.push(obj)
+            obj = {
+                type:'text',
+                content:answer.substring(end_index + sign_obj.end.length,len).trim()
+            }
+            arr.push(obj)
+            return arr
+
+        },
+        async copy(chat){
+            let answerDomList = document.querySelectorAll('#answer')
+    
+            if(answerDomList.length == 0){
+                return
+            }
+            let answerDom = answerDomList[answerDomList.length - 1]
+            let answerHtml = answerDom.innerHTML
+            let answer_text = answerDom.textContent || answerDom.innerText;
+            if(navigator.clipboard && navigator.clipboard.write){
+                // 复制复杂内容(纯文本 + HTML)
+                navigator.clipboard.write([
+                    new ClipboardItem({
+                        'text/html': new Blob([answerHtml], { type: 'text/html' }),
+                        'text/plain': new Blob([answer_text], { type: 'text/plain' })
+                    })
+                ]).then(() => {
+                    console.log('内容已复制到剪贴板');
+                    this.$message.success('复制成功');
+                });
+                return
+            }
+            
+            let textArea = document.createElement("textarea");
+            textArea.value = answer_text;
+            // 防止滚动到页面底部
+            textArea.style.top = "0";
+            textArea.style.left = "0";
+            textArea.style.position = "fixed";
+            textArea.style.opacity = "0";
+            document.body.appendChild(textArea);
+            textArea.select();
+            try {
+                document.execCommand('copy');
+                this.$message.success('复制成功');
+            } catch (err) {
+                this.$message.error('复制失败');
+            }
+            document.body.removeChild(textArea);
+        },
+    },
+}

+ 4 - 4
src/views/AITools/assistWritingInstruction/mixins/index.js

@@ -1,4 +1,3 @@
-
 export default {
     data() {
         return {
@@ -74,7 +73,7 @@ export default {
                                 return item.field == json.field
                             })
                             if(obj){
-                                obj.content += json.content.replace(/\n/g,'<br>')
+                                obj.content += json.content.replace(/\\{1,10}n/g,'<br>')
                             }
                         }else if(json.event == 'end'){
                             let obj = this.result.find(item=>{
@@ -116,7 +115,7 @@ export default {
                                             return item.field == json.field
                                         })
                                         if(obj){
-                                            obj.content += json.content.replace(/\n/g,'<br>')
+                                            obj.content += json.content.replace(/\\{1,10}n/g,'<br>')
                                         }
                                     }else if(json.event == 'end'){
                                         let obj = this.result.find(item=>{
@@ -149,7 +148,8 @@ export default {
         },
         formattedText(text) {
             // 将<br>替换为<p>标签
-            return text.replace(/<br>/gi, '</p><p>').replace(/^<p>|<\/p>$/gi, '');
+            let html = text.replace(/<br>/gi, '</p><p>').replace(/^<p>|<\/p>$/gi, '')
+            return html;
         },
         cancelRun(){
             if (this.controller) {