|
@@ -55,14 +55,14 @@ const handleChatDetail = async ({ sessionId }) => {
|
|
|
isLoading.value = false;
|
|
|
|
|
|
recordActive.value = sessionId;
|
|
|
-
|
|
|
+
|
|
|
inputRef.value.clearInpVal();
|
|
|
|
|
|
controller.abort();
|
|
|
|
|
|
const { data } = await chatApi.getAnswerHistoryDetail({ sessionId });
|
|
|
|
|
|
- chatDataSource.value = data.map(item => ({ ...item, loading: false, }));
|
|
|
+ chatDataSource.value = data.map(item => ({ ...item, loading: false, }));
|
|
|
currenSessionId.value = sessionId;
|
|
|
|
|
|
|
|
@@ -86,7 +86,7 @@ const onRegenerate = async ({ question, realQuestion }) => {
|
|
|
onDownloadProgress: ({ event }) => {
|
|
|
const xhr = event.target;
|
|
|
const { responseText } = xhr;
|
|
|
- const [ answer ] = responseText.split(ANSWER_ID_KEY);
|
|
|
+ const [answer] = responseText.split(ANSWER_ID_KEY);
|
|
|
|
|
|
updateChat({
|
|
|
sessionId,
|
|
@@ -101,9 +101,9 @@ const onRegenerate = async ({ question, realQuestion }) => {
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
- const { data } = await chatApi.getChatStream(params);
|
|
|
-
|
|
|
- const [ answer, id ] = data.split(ANSWER_ID_KEY);
|
|
|
+ const { data } = await chatApi.getChatStream(params);
|
|
|
+
|
|
|
+ const [answer, id] = data.split(ANSWER_ID_KEY);
|
|
|
|
|
|
updateChat({
|
|
|
id,
|
|
@@ -113,10 +113,10 @@ const onRegenerate = async ({ question, realQuestion }) => {
|
|
|
loading: false,
|
|
|
delayLoading: false
|
|
|
})
|
|
|
-
|
|
|
+
|
|
|
scrollToBottomIfAtBottom();
|
|
|
}
|
|
|
- catch (error){
|
|
|
+ catch (error) {
|
|
|
console.log("取消了请求 - catch", error);
|
|
|
}
|
|
|
finally {
|
|
@@ -127,12 +127,12 @@ const onRegenerate = async ({ question, realQuestion }) => {
|
|
|
// 提交问题
|
|
|
const handleSubmit = async (question, realQuestion = '') => {
|
|
|
// 用于模拟 - 内容生成前置等待状态
|
|
|
-
|
|
|
+
|
|
|
if (unref(isExistInHistory)) {
|
|
|
const { data: sessionId } = await chatApi.getChatSessionTag();
|
|
|
currenSessionId.value = sessionId;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
isLoading.value = true;
|
|
|
|
|
|
addChat({
|
|
@@ -151,7 +151,7 @@ const handleSubmit = async (question, realQuestion = '') => {
|
|
|
|
|
|
// 处理推荐问题
|
|
|
const handleWelcomeRecommend = ({ content }) => {
|
|
|
- console.log( inputRef.value )
|
|
|
+ console.log(inputRef.value)
|
|
|
inputRef.value.inpVal = content;
|
|
|
inputRef.value.handleInpFocus();
|
|
|
}
|
|
@@ -183,39 +183,26 @@ onUnmounted(() => {
|
|
|
</template>
|
|
|
|
|
|
<div class="pr-[4px] text-[#5e5e5e]">
|
|
|
- <RecodeCardItem
|
|
|
- v-for="item, index in recordList"
|
|
|
- :key="item.sessionId + index"
|
|
|
- :title="item.showVal"
|
|
|
- :time="item.createTime"
|
|
|
- :data-item="item"
|
|
|
- :class="{'recode-card-item_active': recordActive === item.sessionId}"
|
|
|
- @on-click="handleChatDetail"
|
|
|
- @on-delete="handeChatDelete"
|
|
|
- />
|
|
|
+ <RecodeCardItem v-for="item, index in recordList" :key="item.sessionId + index" :title="item.showVal"
|
|
|
+ :time="item.createTime" :data-item="item"
|
|
|
+ :class="{ 'recode-card-item_active': recordActive === item.sessionId }" @on-click="handleChatDetail"
|
|
|
+ @on-delete="handeChatDelete" />
|
|
|
</div>
|
|
|
</TheSubMenu>
|
|
|
|
|
|
<TheChatView ref="scrollRef">
|
|
|
<div v-if="!chatDataSource.length">
|
|
|
- <ChatWelcome title="您好,我是LibraAI专家问答"
|
|
|
- :sub-title="[
|
|
|
+ <ChatWelcome title="您好,我是LibraAI智能助手" :sub-title="[
|
|
|
'LibarAI智能助手模块提供撰写文章、生成报告等服务',
|
|
|
'请替换问题中##的内容'
|
|
|
- ]"
|
|
|
- />
|
|
|
+ ]" />
|
|
|
<div class="grid-container">
|
|
|
<div class="grid-content">
|
|
|
- <div
|
|
|
- class="grid-item"
|
|
|
- v-for="item in helperList"
|
|
|
- :key="item.id"
|
|
|
- @click="handleWelcomeRecommend(item)"
|
|
|
- >
|
|
|
+ <div class="grid-item" v-for="item in helperList" :key="item.id" @click="handleWelcomeRecommend(item)">
|
|
|
<div class="grid-item-icon space-x-[8px]">
|
|
|
<img :src="item.banner" alt="" class="w-[24px]">
|
|
|
<!-- <SvgIcon name="tool-report" size="24"></SvgIcon> -->
|
|
|
- <h3 class="grid-item-title">{{item.title}}</h3>
|
|
|
+ <h3 class="grid-item-title">{{ item.title }}</h3>
|
|
|
</div>
|
|
|
<div class="text-[#5E5E5E] mt-[8px] text-justify">
|
|
|
<template v-if="item.content.indexOf('#') !== -1">
|
|
@@ -224,90 +211,78 @@ onUnmounted(() => {
|
|
|
</span>
|
|
|
</template>
|
|
|
<template v-else>
|
|
|
- <p>{{item.content}}</p>
|
|
|
+ <p>{{ item.content }}</p>
|
|
|
</template>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
-
|
|
|
+
|
|
|
<div class="conversation-item" v-if="chatDataSource.length">
|
|
|
<template v-for="item in chatDataSource" :key="item.id">
|
|
|
<ChatAsk :content="item.question" :sessionId="item.sessionId"></ChatAsk>
|
|
|
- <ChatAnswer
|
|
|
- :id="item.id"
|
|
|
- :content="item.answer"
|
|
|
- :loading="item.loading"
|
|
|
- :delay-loading="item.delayLoading"
|
|
|
- :isSatisfied="item.isSatisfied"
|
|
|
- @on-click-icon=" params => updateById(params)"
|
|
|
- ></ChatAnswer>
|
|
|
+ <ChatAnswer :id="item.id" :content="item.answer" :loading="item.loading" :delay-loading="item.delayLoading"
|
|
|
+ :isSatisfied="item.isSatisfied" @on-click-icon="params => updateById(params)"></ChatAnswer>
|
|
|
</template>
|
|
|
</div>
|
|
|
|
|
|
<template #footer>
|
|
|
- <ChatInput
|
|
|
- ref="inputRef"
|
|
|
- v-model:loading="isLoading"
|
|
|
- v-model:switch="switchActive"
|
|
|
- @on-click="handleSubmit"
|
|
|
- @on-enter="handleSubmit"
|
|
|
- ></ChatInput>
|
|
|
+ <ChatInput ref="inputRef" v-model:loading="isLoading" v-model:switch="switchActive" @on-click="handleSubmit"
|
|
|
+ @on-enter="handleSubmit"></ChatInput>
|
|
|
</template>
|
|
|
</TheChatView>
|
|
|
- </section>
|
|
|
+ </section>
|
|
|
</template>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
-.grid-container{
|
|
|
- position: relative;
|
|
|
+.grid-container {
|
|
|
+ position: relative;
|
|
|
padding-bottom: 20px;
|
|
|
margin-top: 36px;
|
|
|
- overflow: hidden;
|
|
|
- overflow-y: scroll;
|
|
|
-
|
|
|
+ overflow: hidden;
|
|
|
+ overflow-y: scroll;
|
|
|
+
|
|
|
&::-webkit-scrollbar {
|
|
|
width: 0px;
|
|
|
}
|
|
|
|
|
|
- .grid-content{
|
|
|
- column-count: 3;
|
|
|
- column-gap: 16px;
|
|
|
- -moz-column-count: 3;
|
|
|
- -webkit-column-count: 3;
|
|
|
- -moz-column-gap: 16px;
|
|
|
- -webkit-column-gap: 16px;
|
|
|
-
|
|
|
- .grid-item{
|
|
|
- height: auto;
|
|
|
- padding: 16px;
|
|
|
- margin-bottom: 16px;
|
|
|
- border-radius: 10px;
|
|
|
- background-color: #fff;
|
|
|
- -webkit-column-break-inside: avoid;
|
|
|
- break-inside: avoid;
|
|
|
- border:1px solid #fff;
|
|
|
+ .grid-content {
|
|
|
+ column-count: 3;
|
|
|
+ column-gap: 16px;
|
|
|
+ -moz-column-count: 3;
|
|
|
+ -webkit-column-count: 3;
|
|
|
+ -moz-column-gap: 16px;
|
|
|
+ -webkit-column-gap: 16px;
|
|
|
+
|
|
|
+ .grid-item {
|
|
|
+ height: auto;
|
|
|
+ padding: 16px;
|
|
|
+ margin-bottom: 16px;
|
|
|
+ border-radius: 10px;
|
|
|
+ background-color: #fff;
|
|
|
+ -webkit-column-break-inside: avoid;
|
|
|
+ break-inside: avoid;
|
|
|
+ border: 1px solid #fff;
|
|
|
cursor: pointer;
|
|
|
|
|
|
&:hover {
|
|
|
- border:1px solid #2454FF;
|
|
|
- box-shadow: 0 2px 4px rgba(0,0,0,0.08);
|
|
|
+ border: 1px solid #2454FF;
|
|
|
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
|
|
|
}
|
|
|
|
|
|
- .grid-item-icon{
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: start;
|
|
|
-
|
|
|
- .grid-item-title{
|
|
|
- font-size: 14px;
|
|
|
- font-weight: 600;
|
|
|
- color: #1A2029;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
+ .grid-item-icon {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: start;
|
|
|
|
|
|
+ .grid-item-title {
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #1A2029;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
</style>
|