copilot处理完成
This commit is contained in:
		| @@ -322,6 +322,10 @@ div[flex], .flex { | |||||||
|   &.normal { |   &.normal { | ||||||
|     align-items: unset; |     align-items: unset; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   &.end { | ||||||
|  |     align-items: flex-end; | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| .fill { | .fill { | ||||||
|   | |||||||
| @@ -16,16 +16,11 @@ export default { | |||||||
|       loading: false, |       loading: false, | ||||||
|       prompt: "", |       prompt: "", | ||||||
|       history: [], |       history: [], | ||||||
|       apps: [ |       apps: [], | ||||||
|         {label: "日常助理", icon: "https://cdn.sinoecare.com/i/2024/07/04/66864da37fc2b.png"}, |  | ||||||
|         {label: "文本助理", icon: "https://cdn.sinoecare.com/i/2024/07/04/66864da1684ad.png"}, |  | ||||||
|       ], |  | ||||||
|       filter: "", |       filter: "", | ||||||
|       conversations: [ |       conversations: [], | ||||||
|         {content: "请对“city不city”一词进行深入分析"}, |       currentConversation: null, | ||||||
|         {content: "请对“city不city”一词进行深入分析"}, |       app: {} | ||||||
|         {content: "请对“city不city”一词进行深入分析"}, |  | ||||||
|       ] |  | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   computed: { |   computed: { | ||||||
| @@ -38,19 +33,38 @@ export default { | |||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     ], |     ], | ||||||
|     rowBtns: () => [ |     rowBtns: v => [ | ||||||
|       {icon: "https://cdn.sinoecare.com/i/2024/07/04/66866edc2910a.png", click: row => 0}, |       {icon: "https://cdn.sinoecare.com/i/2024/07/04/66866edc2910a.png", label: "置顶", click: row => 0}, | ||||||
|       {icon: "https://cdn.sinoecare.com/i/2024/07/04/66866ed734540.png", click: row => 0}, |       {icon: "https://cdn.sinoecare.com/i/2024/07/04/66866ed734540.png", label: "编辑", click: row => 0}, | ||||||
|       {icon: "https://cdn.sinoecare.com/i/2024/07/04/66866eda99e4d.png", click: row => 0}, |       {icon: "https://cdn.sinoecare.com/i/2024/07/04/66866eda99e4d.png", label: "删除", click: row => v.handleDeleteConversation(row.id)}, | ||||||
|     ] |     ] | ||||||
|   }, |   }, | ||||||
|   components: {ThinkingBar, ChatContent}, |   components: {ThinkingBar, ChatContent}, | ||||||
|   methods: { |   methods: { | ||||||
|     getHistory(cb) { |     getHistory(params) { | ||||||
|       this.http.post("/app/appaicopilotinfo/list").then(res => { |       this.http.post("/app/appaicopilotinfo/list", null, {params}).then(res => { | ||||||
|         if (res?.data) { |         if (res?.data) { | ||||||
|           if (cb) cb(res.data.records) |           this.history = res.data.records | ||||||
|           else this.history = res.data.records |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     getApps() { | ||||||
|  |       return this.http.post("/app/appaiconfiginfo/list", null, { | ||||||
|  |         params: { | ||||||
|  |           status: 1, size: 999 | ||||||
|  |         } | ||||||
|  |       }).then(res => { | ||||||
|  |         if (res?.data) { | ||||||
|  |           return this.apps = res.data.records | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     getConversations() { | ||||||
|  |       return this.http.post("/app/appaicopilotinfo/listHistory", null, { | ||||||
|  |         params: {content: this.filter} | ||||||
|  |       }).then(res => { | ||||||
|  |         if (res?.data) { | ||||||
|  |           return this.conversations = res.data.records || [] | ||||||
|         } |         } | ||||||
|       }) |       }) | ||||||
|     }, |     }, | ||||||
| @@ -66,7 +80,8 @@ export default { | |||||||
|         if (++i < content.length) setTimeout(() => concatenateStr(content, i), 50) |         if (++i < content.length) setTimeout(() => concatenateStr(content, i), 50) | ||||||
|       } |       } | ||||||
|       this.$debounce(() => { |       this.$debounce(() => { | ||||||
|         const message = {appType: "2", userType: 0, content: this.prompt} |         const {currentConversation: conversationId, app, prompt: content} = this.$data | ||||||
|  |         const message = {appType: "2", userType: 0, content, conversationId, ...app} | ||||||
|         this.history.push(message) |         this.history.push(message) | ||||||
|         this.loading = true |         this.loading = true | ||||||
|         this.prompt = "" |         this.prompt = "" | ||||||
| @@ -80,11 +95,45 @@ export default { | |||||||
|           this.loading = false |           this.loading = false | ||||||
|         }) |         }) | ||||||
|       }, 100) |       }, 100) | ||||||
|  |     }, | ||||||
|  |     handleDeleteConversation(conversationId) { | ||||||
|  |       this.$confirm("是否要删除该会话历史?").then(() => { | ||||||
|  |         this.http.post("/app/appaicopilotinfo/deleteConversation", null, {params: {conversationId}}).then(res => { | ||||||
|  |           if (res?.code == '0') { | ||||||
|  |             this.$message.success("删除成功!") | ||||||
|  |             this.getConversations() | ||||||
|  |           } | ||||||
|  |         }) | ||||||
|  |       }).catch(() => 0) | ||||||
|  |     }, | ||||||
|  |     handleChangeApp(item) { | ||||||
|  |       const {appId, id: aiConfigId} = item | ||||||
|  |       this.handleChangeConversation({appId, aiConfigId}) | ||||||
|  |       this.history = [{userType: 2, content: `当前应用已切换至【${item.appName}】`}] | ||||||
|  |     }, | ||||||
|  |     handleChangeConversation({conversationId, appId, aiConfigId} = {}) { | ||||||
|  |       this.currentConversation = conversationId | ||||||
|  |       this.app = {appId, aiConfigId} | ||||||
|  |     }, | ||||||
|  |     getIcon(item = {}) { | ||||||
|  |       const icon = item.appIconUrl || "https://cdn.sinoecare.com/i/2024/07/04/66864da1684ad.png" | ||||||
|  |       return { | ||||||
|  |         backgroundImage: `url(${icon})` | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   watch: { | ||||||
|  |     currentConversation(v) { | ||||||
|  |       v && this.getHistory({conversationId: v}) | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   created() { |   created() { | ||||||
|     this.getHistory() |     Promise.all([this.getApps(), this.getConversations()]).then(() => { | ||||||
|  |       const {appId, id: aiConfigId} = this.apps.at(0) | ||||||
|  |       this.handleChangeConversation(this.conversations.at(0) || {appId, aiConfigId}) | ||||||
|  |     }) | ||||||
|   } |   } | ||||||
|  |  | ||||||
| } | } | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
| @@ -104,14 +153,14 @@ export default { | |||||||
|             <span v-text="profile.girdName"/> |             <span v-text="profile.girdName"/> | ||||||
|           </div> |           </div> | ||||||
|           <div class="apps flex"> |           <div class="apps flex"> | ||||||
|             <div v-for="(item,i) in apps" :key="i" class="app pointer" :style="{backgroundImage: `url(${item.icon})`}" v-text="item.label"/> |             <div v-for="(item,i) in apps" :key="i" class="app pointer" :style="getIcon(item)" v-text="item.appName" @click="handleChangeApp(item)"/> | ||||||
|           </div> |           </div> | ||||||
|           <div class="conversation"> |           <div class="conversation"> | ||||||
|             <el-input class="search" v-model="filter" placeholder="搜索历史对话记录" size="small" suffix-icon="el-icon-search" clearable/> |             <el-input class="search" v-model="filter" placeholder="搜索历史对话记录" size="small" suffix-icon="el-icon-search" clearable @change="getConversations"/> | ||||||
|             <div class="item pointer" v-for="item in conversations" :key="item.id"> |             <div class="item pointer" v-for="item in conversations" :key="item.id" @click="currentConversation=item.id" :class="{current:item.conversationId==currentConversation}"> | ||||||
|               {{ item.content }} |               {{ item.content }} | ||||||
|               <div class="operation flex"> |               <div class="operation flex"> | ||||||
|                 <div v-for="(btn,i) in rowBtns" :key="i" class="pointer" :style="{backgroundImage: `url(${btn.icon})`}"/> |                 <div v-for="(btn,i) in rowBtns" :key="i" class="pointer" :style="{backgroundImage: `url(${btn.icon})`}" @click.stop="btn.click(item)"/> | ||||||
|               </div> |               </div> | ||||||
|             </div> |             </div> | ||||||
|           </div> |           </div> | ||||||
| @@ -123,7 +172,7 @@ export default { | |||||||
|               <div v-for="(btn,i) in btns" :key="i" class="btn pointer" :style="{backgroundImage: `url(${btn.icon})`}" v-text="btn.label" @click="btn.click"/> |               <div v-for="(btn,i) in btns" :key="i" class="btn pointer" :style="{backgroundImage: `url(${btn.icon})`}" v-text="btn.label" @click="btn.click"/> | ||||||
|             </div> |             </div> | ||||||
|             <div class="flex end"> |             <div class="flex end"> | ||||||
|               <el-input type="textarea" class="fill input" autosize resize="none" v-model="prompt" placeholder="请输入..." :rows="2" |               <el-input type="textarea" class="fill input" autosize resize="none" v-model="prompt" placeholder="请输入..." :rows="5" | ||||||
|                         @keydown.native="handleHotkey" :disabled="loading" :placeholder="loading?'正在思考中...':'请输入'"/> |                         @keydown.native="handleHotkey" :disabled="loading" :placeholder="loading?'正在思考中...':'请输入'"/> | ||||||
|               <div class="sendBtn" @click="handleSend"/> |               <div class="sendBtn" @click="handleSend"/> | ||||||
|             </div> |             </div> | ||||||
| @@ -199,10 +248,11 @@ export default { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         &.expand { |         &.expand { | ||||||
|           width: 260px; |           width: 306px; | ||||||
|  |  | ||||||
|           & + .right { |           & + .right { | ||||||
|             border-left-color: #ddd; |             border-left-color: #ddd; | ||||||
|  |             width: 660px; | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -210,7 +260,7 @@ export default { | |||||||
|           padding: 18px 14px; |           padding: 18px 14px; | ||||||
|           height: 88px; |           height: 88px; | ||||||
|           background: url("https://cdn.sinoecare.com/i/2024/06/04/665ed2bc580fa.png") no-repeat; |           background: url("https://cdn.sinoecare.com/i/2024/06/04/665ed2bc580fa.png") no-repeat; | ||||||
|           background-size: 100%; |           background-size: 100% 100%; | ||||||
|           font-size: 14px; |           font-size: 14px; | ||||||
|           color: #222222; |           color: #222222; | ||||||
|           letter-spacing: 0; |           letter-spacing: 0; | ||||||
| @@ -304,7 +354,7 @@ export default { | |||||||
|               } |               } | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             &:hover { |             &:hover, &.current { | ||||||
|               background: #2b71fd24; |               background: #2b71fd24; | ||||||
|  |  | ||||||
|               .operation { |               .operation { | ||||||
| @@ -316,11 +366,12 @@ export default { | |||||||
|       } |       } | ||||||
|  |  | ||||||
|       .right { |       .right { | ||||||
|         width: 420px; |         width: 468px; | ||||||
|         height: 100%; |         height: 100%; | ||||||
|         padding: 14px 0 14px 14px; |         padding: 14px 0 14px 14px; | ||||||
|         align-items: stretch; |         align-items: stretch; | ||||||
|         border-left: 1px solid transparent; |         border-left: 1px solid transparent; | ||||||
|  |         transition: width 1s; | ||||||
|  |  | ||||||
|         .sendBtn { |         .sendBtn { | ||||||
|           width: 36px; |           width: 36px; | ||||||
| @@ -346,9 +397,10 @@ export default { | |||||||
|  |  | ||||||
|         .topBar { |         .topBar { | ||||||
|           width: 100%; |           width: 100%; | ||||||
|           height: 25px; |           height: 28px; | ||||||
|           border-bottom: 1px solid #E0E0E0; |           border-bottom: 1px solid #E0E0E0; | ||||||
|           margin-bottom: 10px; |           margin-bottom: 10px; | ||||||
|  |           align-items: flex-start; | ||||||
|  |  | ||||||
|           .btn { |           .btn { | ||||||
|             font-size: 12px; |             font-size: 12px; | ||||||
| @@ -371,6 +423,7 @@ export default { | |||||||
|           border: none; |           border: none; | ||||||
|           box-sizing: border-box; |           box-sizing: border-box; | ||||||
|           background: transparent; |           background: transparent; | ||||||
|  |           min-height: 73px !important; | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| <template> | <template> | ||||||
|   <el-scrollbar class="chatContent"> |   <el-scrollbar class="chatContent"> | ||||||
|     <div class="chat-wrapper" v-for="item in list" :key="item.id"> |     <div class="chat-wrapper" v-for="item in list" :key="item.id"> | ||||||
|       <div class="chat-text" :class="{right:item.userType == '0'}"> |       <div class="chat-text" :class="{right:item.userType == '0',system:item.userType == '2'}"> | ||||||
|         <img class="avatar" :src="avatar(item)" alt=""/> |         <img v-if="item.userType!=2" class="avatar" :src="avatar(item)" alt=""/> | ||||||
|         <div class="content" v-text="item.content"/> |         <div class="content" v-text="item.content"/> | ||||||
|       </div> |       </div> | ||||||
|     </div> |     </div> | ||||||
| @@ -11,6 +11,9 @@ | |||||||
|  |  | ||||||
| <script> | <script> | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * userType: 0-用户 1-机器人 2-系统 | ||||||
|  |  */ | ||||||
| export default { | export default { | ||||||
|   name: "chatContent", |   name: "chatContent", | ||||||
|   props: { |   props: { | ||||||
| @@ -58,7 +61,7 @@ export default { | |||||||
|  |  | ||||||
|     .content { |     .content { | ||||||
|       position: relative; |       position: relative; | ||||||
|       max-width: 220px; |       max-width: max(calc(100% - 140px), 220px); | ||||||
|       padding: 8px; |       padding: 8px; | ||||||
|       border-radius: 4px; |       border-radius: 4px; | ||||||
|       background: #F3F5F7; |       background: #F3F5F7; | ||||||
| @@ -91,6 +94,24 @@ export default { | |||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     &.system { | ||||||
|  |       padding-right: 0; | ||||||
|  |       justify-content: center; | ||||||
|  |  | ||||||
|  |       .content { | ||||||
|  |         font-size: 12px; | ||||||
|  |         background: #F0F0F0; | ||||||
|  |         border-radius: 4px; | ||||||
|  |         color: #888; | ||||||
|  |         padding: 3px 6px; | ||||||
|  |         width: fit-content; | ||||||
|  |  | ||||||
|  |         &:before { | ||||||
|  |           display: none; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   .avatar { |   .avatar { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user