|
@@ -0,0 +1,219 @@
|
|
|
|
+
|
|
|
|
+export default {
|
|
|
|
+ data() {
|
|
|
|
+ return {
|
|
|
|
+ controller:null
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ computed:{
|
|
|
|
+ userinfo(){
|
|
|
|
+ return this.$s.getObj('userinfo')
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ methods: {
|
|
|
|
+ async getResult(){
|
|
|
|
+ if(!this.confession.guid){
|
|
|
|
+ this.$message.warning('请先上传审查意见书')
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ if(this.loading){
|
|
|
|
+ this.$message.warning('请等当前执行完成')
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ this.loading = true
|
|
|
|
+ this.result = null
|
|
|
|
+ this.controller = new AbortController();
|
|
|
|
+ const response = await fetch('/api/xiaoshi/dify/sendOADefense?confessionSessionId='+this.currentConversation.id, {
|
|
|
|
+ method: 'GET',
|
|
|
|
+ headers: {
|
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
|
+ 'Accept': 'text/event-stream',
|
|
|
|
+ },
|
|
|
|
+ signal: this.controller.signal
|
|
|
|
+ });
|
|
|
|
+ if (!response.ok) throw new Error('AI API 调用失败');
|
|
|
|
+ this.finish = false
|
|
|
|
+ const reader = response.body.getReader();
|
|
|
|
+ const decoder = new TextDecoder('utf-8');
|
|
|
|
+ let noFinishMessage = ''
|
|
|
|
+ while (true) {
|
|
|
|
+ const { done, value } = await reader.read();
|
|
|
|
+ if (done){
|
|
|
|
+ this.finish = true
|
|
|
|
+ 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 == 'message'){
|
|
|
|
+ this.result += json.answer;
|
|
|
|
+ }else if(json.event == 'message_replace'){
|
|
|
|
+ this.result = json.answer
|
|
|
|
+ }else if(json.event == 'text_chunk'){
|
|
|
|
+ if(json.data){
|
|
|
|
+ this.result += json.data.text;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ } 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 == 'message'){
|
|
|
|
+ this.result += json.answer;
|
|
|
|
+ }else if(json.event == 'message_replace'){
|
|
|
|
+ this.result = json.answer
|
|
|
|
+ }else if(json.event == 'text_chunk'){
|
|
|
|
+ if(json.data){
|
|
|
|
+ this.result += json.data.text;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ catch(e){
|
|
|
|
+ console.error('解析响应数据出错:', e);
|
|
|
|
+ }finally{
|
|
|
|
+ noFinishMessage = ''
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ cancelRun(){
|
|
|
|
+ if (this.controller) {
|
|
|
|
+ this.controller.abort();
|
|
|
|
+ }
|
|
|
|
+ this.loading = false
|
|
|
|
+ },
|
|
|
|
+ //格式化AI答复
|
|
|
|
+ formateAIAnswer(chat){
|
|
|
|
+ let answer = chat
|
|
|
|
+ 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);
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+}
|