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