copilot处理完成
This commit is contained in:
		| @@ -322,6 +322,10 @@ div[flex], .flex { | ||||
|   &.normal { | ||||
|     align-items: unset; | ||||
|   } | ||||
|  | ||||
|   &.end { | ||||
|     align-items: flex-end; | ||||
|   } | ||||
| } | ||||
|  | ||||
| .fill { | ||||
|   | ||||
| @@ -16,16 +16,11 @@ export default { | ||||
|       loading: false, | ||||
|       prompt: "", | ||||
|       history: [], | ||||
|       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"}, | ||||
|       ], | ||||
|       apps: [], | ||||
|       filter: "", | ||||
|       conversations: [ | ||||
|         {content: "请对“city不city”一词进行深入分析"}, | ||||
|         {content: "请对“city不city”一词进行深入分析"}, | ||||
|         {content: "请对“city不city”一词进行深入分析"}, | ||||
|       ] | ||||
|       conversations: [], | ||||
|       currentConversation: null, | ||||
|       app: {} | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
| @@ -38,19 +33,38 @@ export default { | ||||
|         } | ||||
|       } | ||||
|     ], | ||||
|     rowBtns: () => [ | ||||
|       {icon: "https://cdn.sinoecare.com/i/2024/07/04/66866edc2910a.png", 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/66866eda99e4d.png", click: row => 0}, | ||||
|     rowBtns: v => [ | ||||
|       {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", label: "编辑", click: row => 0}, | ||||
|       {icon: "https://cdn.sinoecare.com/i/2024/07/04/66866eda99e4d.png", label: "删除", click: row => v.handleDeleteConversation(row.id)}, | ||||
|     ] | ||||
|   }, | ||||
|   components: {ThinkingBar, ChatContent}, | ||||
|   methods: { | ||||
|     getHistory(cb) { | ||||
|       this.http.post("/app/appaicopilotinfo/list").then(res => { | ||||
|     getHistory(params) { | ||||
|       this.http.post("/app/appaicopilotinfo/list", null, {params}).then(res => { | ||||
|         if (res?.data) { | ||||
|           if (cb) cb(res.data.records) | ||||
|           else this.history = res.data.records | ||||
|           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) | ||||
|       } | ||||
|       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.loading = true | ||||
|         this.prompt = "" | ||||
| @@ -80,11 +95,45 @@ export default { | ||||
|           this.loading = false | ||||
|         }) | ||||
|       }, 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() { | ||||
|     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> | ||||
|  | ||||
| @@ -104,14 +153,14 @@ export default { | ||||
|             <span v-text="profile.girdName"/> | ||||
|           </div> | ||||
|           <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 class="conversation"> | ||||
|             <el-input class="search" v-model="filter" placeholder="搜索历史对话记录" size="small" suffix-icon="el-icon-search" clearable/> | ||||
|             <div class="item pointer" v-for="item in conversations" :key="item.id"> | ||||
|             <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" @click="currentConversation=item.id" :class="{current:item.conversationId==currentConversation}"> | ||||
|               {{ item.content }} | ||||
|               <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> | ||||
| @@ -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> | ||||
|             <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?'正在思考中...':'请输入'"/> | ||||
|               <div class="sendBtn" @click="handleSend"/> | ||||
|             </div> | ||||
| @@ -199,10 +248,11 @@ export default { | ||||
|         } | ||||
|  | ||||
|         &.expand { | ||||
|           width: 260px; | ||||
|           width: 306px; | ||||
|  | ||||
|           & + .right { | ||||
|             border-left-color: #ddd; | ||||
|             width: 660px; | ||||
|           } | ||||
|         } | ||||
|  | ||||
| @@ -210,7 +260,7 @@ export default { | ||||
|           padding: 18px 14px; | ||||
|           height: 88px; | ||||
|           background: url("https://cdn.sinoecare.com/i/2024/06/04/665ed2bc580fa.png") no-repeat; | ||||
|           background-size: 100%; | ||||
|           background-size: 100% 100%; | ||||
|           font-size: 14px; | ||||
|           color: #222222; | ||||
|           letter-spacing: 0; | ||||
| @@ -304,7 +354,7 @@ export default { | ||||
|               } | ||||
|             } | ||||
|  | ||||
|             &:hover { | ||||
|             &:hover, &.current { | ||||
|               background: #2b71fd24; | ||||
|  | ||||
|               .operation { | ||||
| @@ -316,11 +366,12 @@ export default { | ||||
|       } | ||||
|  | ||||
|       .right { | ||||
|         width: 420px; | ||||
|         width: 468px; | ||||
|         height: 100%; | ||||
|         padding: 14px 0 14px 14px; | ||||
|         align-items: stretch; | ||||
|         border-left: 1px solid transparent; | ||||
|         transition: width 1s; | ||||
|  | ||||
|         .sendBtn { | ||||
|           width: 36px; | ||||
| @@ -346,9 +397,10 @@ export default { | ||||
|  | ||||
|         .topBar { | ||||
|           width: 100%; | ||||
|           height: 25px; | ||||
|           height: 28px; | ||||
|           border-bottom: 1px solid #E0E0E0; | ||||
|           margin-bottom: 10px; | ||||
|           align-items: flex-start; | ||||
|  | ||||
|           .btn { | ||||
|             font-size: 12px; | ||||
| @@ -371,6 +423,7 @@ export default { | ||||
|           border: none; | ||||
|           box-sizing: border-box; | ||||
|           background: transparent; | ||||
|           min-height: 73px !important; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| <template> | ||||
|   <el-scrollbar class="chatContent"> | ||||
|     <div class="chat-wrapper" v-for="item in list" :key="item.id"> | ||||
|       <div class="chat-text" :class="{right:item.userType == '0'}"> | ||||
|         <img class="avatar" :src="avatar(item)" alt=""/> | ||||
|       <div class="chat-text" :class="{right:item.userType == '0',system:item.userType == '2'}"> | ||||
|         <img v-if="item.userType!=2" class="avatar" :src="avatar(item)" alt=""/> | ||||
|         <div class="content" v-text="item.content"/> | ||||
|       </div> | ||||
|     </div> | ||||
| @@ -11,6 +11,9 @@ | ||||
|  | ||||
| <script> | ||||
|  | ||||
| /** | ||||
|  * userType: 0-用户 1-机器人 2-系统 | ||||
|  */ | ||||
| export default { | ||||
|   name: "chatContent", | ||||
|   props: { | ||||
| @@ -58,7 +61,7 @@ export default { | ||||
|  | ||||
|     .content { | ||||
|       position: relative; | ||||
|       max-width: 220px; | ||||
|       max-width: max(calc(100% - 140px), 220px); | ||||
|       padding: 8px; | ||||
|       border-radius: 4px; | ||||
|       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 { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user