Merge branch 'main' of http://18.167.251.121:10003/aidlab/FiDA_Front
This commit is contained in:
@@ -221,7 +221,8 @@
|
||||
}
|
||||
|
||||
buffer += decoder.decode(value, { stream: true })
|
||||
|
||||
console.log('收到chunk',new Date().getTime());
|
||||
|
||||
// 优先按空行拆分事件块(SSE标准)
|
||||
let events = buffer.split(/\n\n/)
|
||||
buffer = events.pop() // 保留不完整块
|
||||
@@ -261,7 +262,7 @@
|
||||
|
||||
try {
|
||||
const jsonData = JSON.parse(jsonText)
|
||||
console.log('jsonData', jsonData)
|
||||
// console.log('jsonData', jsonData)
|
||||
|
||||
// 赋值 project_id 和 version_id
|
||||
// if (jsonData.project_id) params.projectID = jsonData.project_id
|
||||
@@ -361,6 +362,67 @@
|
||||
)
|
||||
}
|
||||
|
||||
// 处理对话列表,将连续的 assistant 消息合并为一条
|
||||
const processDialogue = (dialogue, startIndex, existingImgList) => {
|
||||
if (!dialogue || dialogue.length === 0) return []
|
||||
|
||||
const result = []
|
||||
let i = startIndex
|
||||
|
||||
while (i < dialogue.length) {
|
||||
const item = dialogue[i]
|
||||
|
||||
if (item.image_url) {
|
||||
existingImgList.push(item.image_url)
|
||||
}
|
||||
|
||||
if (item.role === 'user') {
|
||||
// user 角色直接添加
|
||||
result.push({
|
||||
...item,
|
||||
text: item.content,
|
||||
isUser: true,
|
||||
id: result.length + 1
|
||||
})
|
||||
i++
|
||||
} else if (item.role === 'assistant') {
|
||||
// assistant 角色,拼接直到下一个 user
|
||||
let combinedContent = item.content || ''
|
||||
|
||||
// 继续往后找连续的 assistant 消息
|
||||
let j = i + 1
|
||||
while (j < dialogue.length && dialogue[j].role === 'assistant') {
|
||||
if (dialogue[j].image_url) {
|
||||
existingImgList.push(dialogue[j].image_url)
|
||||
}
|
||||
combinedContent += dialogue[j].content || ''
|
||||
j++
|
||||
}
|
||||
|
||||
result.push({
|
||||
...item,
|
||||
content: combinedContent,
|
||||
text: combinedContent,
|
||||
isUser: false,
|
||||
id: result.length + 1
|
||||
})
|
||||
|
||||
i = j
|
||||
} else {
|
||||
// 其他角色直接添加
|
||||
result.push({
|
||||
...item,
|
||||
text: item.content,
|
||||
isUser: item.role === 'user',
|
||||
id: result.length + 1
|
||||
})
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
const setChatInfo = (info) => {
|
||||
const initialData = agentStore.getInitialProjectData
|
||||
if (isGenerating.value || initialData) return
|
||||
@@ -389,35 +451,22 @@
|
||||
|
||||
const imgList = []
|
||||
const ancestorsList = []
|
||||
let ancestorsIdCounter = 1
|
||||
if (ancestors) {
|
||||
ancestors.forEach((item) => {
|
||||
const list =
|
||||
item.dialogue?.map((el, index) => {
|
||||
if (el.image_url) {
|
||||
imgList.push(el.image_url)
|
||||
}
|
||||
return {
|
||||
...el,
|
||||
text: el.content,
|
||||
isUser: el.role === 'user',
|
||||
id: index + 1
|
||||
}
|
||||
}) || []
|
||||
const list = processDialogue(item.dialogue, 0, imgList)
|
||||
// 重新设置 id
|
||||
list.forEach((el) => {
|
||||
el.id = ancestorsIdCounter++
|
||||
})
|
||||
ancestorsList.push(...list)
|
||||
})
|
||||
}
|
||||
const currentList =
|
||||
current?.dialogue?.map((item, index) => {
|
||||
if (item.image_url) {
|
||||
imgList.push(item.image_url)
|
||||
}
|
||||
return {
|
||||
...item,
|
||||
text: item.content,
|
||||
isUser: item.role === 'user',
|
||||
id: index + 1 + ancestorsList.length
|
||||
}
|
||||
}) || []
|
||||
const currentList = processDialogue(current?.dialogue, 0, imgList)
|
||||
// 重新设置 id
|
||||
currentList.forEach((el, index) => {
|
||||
el.id = index + 1 + ancestorsList.length
|
||||
})
|
||||
|
||||
// 延迟设置新数据,确保 UI 有时间响应清空操作
|
||||
nextTick(() => {
|
||||
|
||||
@@ -7,10 +7,7 @@
|
||||
<div class="thumb">
|
||||
<img :src="content.isUser ? userThumb : agentThumb" class="thumb-icon" />
|
||||
</div>
|
||||
<div
|
||||
class="message-context"
|
||||
v-show="!content.loading && !content.thinking && !content.streaming"
|
||||
>
|
||||
<div class="message-context" v-show="!content.loading">
|
||||
<div class="img-list flex" v-if="imageList.length > 0">
|
||||
<img
|
||||
v-for="(item, index) in imageList"
|
||||
@@ -22,7 +19,7 @@
|
||||
<div class="message-txt markdown-body">
|
||||
<div v-html="formatMessage"></div>
|
||||
</div>
|
||||
<div class="operate flex" v-show="isLast" :class="{ 'is-user': content.isUser }">
|
||||
<div class="operate flex" :class="{ 'is-user': content.isUser }">
|
||||
<template v-if="content.isUser">
|
||||
<SvgIcon name="copy" size="16" color="#000" @click.stop="handleCopyText" />
|
||||
</template>
|
||||
@@ -30,6 +27,7 @@
|
||||
<SvgIcon
|
||||
v-for="operate in operateList"
|
||||
:key="operate.name"
|
||||
v-show="isLast"
|
||||
:name="operate.name"
|
||||
:size="operate.name === 'refreshTransparent' ? '14' : '16'"
|
||||
color="#000000A6"
|
||||
@@ -196,7 +194,7 @@
|
||||
column-gap: 0.9rem;
|
||||
// align-items: flex-start;
|
||||
&.is-user {
|
||||
text-align: right;
|
||||
// text-align: right;
|
||||
flex-direction: row-reverse;
|
||||
column-gap: 1.3rem;
|
||||
}
|
||||
@@ -221,6 +219,7 @@
|
||||
.message-context {
|
||||
line-height: 2rem;
|
||||
font-size: 1.4rem;
|
||||
max-width: 82%;
|
||||
}
|
||||
}
|
||||
.operate {
|
||||
|
||||
@@ -165,12 +165,17 @@
|
||||
height: 100%;
|
||||
gap: 1.2rem;
|
||||
flex-wrap: wrap;
|
||||
overflow-y: auto;
|
||||
align-content: flex-start;
|
||||
.sketch-item {
|
||||
position: relative;
|
||||
&,
|
||||
width: calc((100% - 1.2rem * 3) / 4);
|
||||
//设置比例
|
||||
aspect-ratio: 1 / 1;
|
||||
border-radius: 1.6rem;
|
||||
img {
|
||||
width: 21.9rem;
|
||||
height: 21.9rem;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 1.6rem;
|
||||
}
|
||||
.menu-btn {
|
||||
|
||||
@@ -62,7 +62,7 @@ function traverseArray(items, callback) {
|
||||
const initialize = ()=>{
|
||||
isLoad.value = false
|
||||
treeList.value = []
|
||||
treeList.value.push({versionId: null,name:'index',})
|
||||
// treeList.value.push({versionId: null,name:'index',})
|
||||
traverseArray(props.versionsList, (item, index) => {
|
||||
treeList.value.push(item)
|
||||
})
|
||||
|
||||
@@ -60,7 +60,7 @@ const push = (item)=>{
|
||||
let className = `custom-node item${item.versionId.replace(/-/g, "_")}`
|
||||
let id = item.versionId
|
||||
let source = edges.value.length == 0?'0':item.versionId.slice(0, -2)
|
||||
nodes.value.push({id,type:'SecondaryNode',class:className,position,data:item})
|
||||
nodes.value.push({id,type:nodes.value.length == 0?'SecondaryNode':'SecondaryNode',class:className,position,data:item})
|
||||
edges.value.push({ id, target:id, source, type: 'smoothstep' })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ const props = defineProps<{
|
||||
<!-- source输入,target输出 -->
|
||||
<template>
|
||||
<div class="node" :class="{active:props.selectItem.id == props.data.id}">
|
||||
<Handle type="target" id="Top" :connectableStart="false" :connectableEnd="false" :position="Position.Top" />
|
||||
<Handle v-if="props.data?.versionId !== '1'" type="target" id="Top" :connectableStart="false" :connectableEnd="false" :position="Position.Top" />
|
||||
<Handle type="source" id="Bottom" :connectableStart="false" :connectableEnd="false" :position="Position.Bottom" />
|
||||
<!-- <Handle type="source" id="Right" :position="Position.Right" />
|
||||
<Handle type="target" id="Left" :position="Position.Left" /> -->
|
||||
|
||||
@@ -517,8 +517,8 @@
|
||||
const settingPopupVisible = ref(false)
|
||||
const settingOptions = ref([
|
||||
{ label: 'Input.settingOptions.creativity', value: 50 },
|
||||
{ label: 'Input.settingOptions.diversity', value: 75 },
|
||||
{ label: 'Input.settingOptions.relevance', value: 60 }
|
||||
{ label: 'Input.settingOptions.diversity', value: 50 },
|
||||
{ label: 'Input.settingOptions.relevance', value: 50 }
|
||||
])
|
||||
|
||||
const openStylePopup = () => {
|
||||
|
||||
@@ -48,7 +48,12 @@
|
||||
<el-popover
|
||||
placement="right"
|
||||
trigger="click"
|
||||
popper-style="padding: 1rem 0.5rem;"
|
||||
width="10rem"
|
||||
popper-style="
|
||||
padding: .6rem 0.7rem;
|
||||
border-radius: 1rem;
|
||||
min-width: 10rem;
|
||||
"
|
||||
v-model:visible="item.visible"
|
||||
>
|
||||
<template #reference>
|
||||
@@ -56,10 +61,20 @@
|
||||
</template>
|
||||
<div class="history-item-menu">
|
||||
<div class="rename" @click="onRenameHistoryItem(item)">
|
||||
{{ $t('Home.rename') }}
|
||||
<div class="icon">
|
||||
<svg-icon name="historyEdit" size="13" />
|
||||
</div>
|
||||
<span>
|
||||
{{ $t('Home.rename') }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="delete" @click="onDeleteHistoryItem(item)">
|
||||
{{ $t('Home.delete') }}
|
||||
<div class="icon">
|
||||
<svg-icon name="historyDelete" size="13" />
|
||||
</div>
|
||||
<span>
|
||||
{{ $t('Home.delete') }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-popover>
|
||||
@@ -338,18 +353,24 @@
|
||||
}
|
||||
.history-item-menu {
|
||||
user-select: none;
|
||||
|
||||
> div {
|
||||
cursor: pointer;
|
||||
padding: 0.5rem 1rem;
|
||||
padding: 0.6rem .7rem;
|
||||
display: flex;
|
||||
font-size: 1.3rem;
|
||||
> .icon{
|
||||
margin-right: .8rem;
|
||||
}
|
||||
&:hover {
|
||||
background-color: rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
}
|
||||
> .rename {
|
||||
color: #409eff;
|
||||
color: #000;
|
||||
}
|
||||
> .delete {
|
||||
color: #ff4d4f;
|
||||
color: #ff4747;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
if (isVisible.value) {
|
||||
isVisible.value = false
|
||||
} else {
|
||||
router.back()
|
||||
router.push({ name: 'index' })
|
||||
}
|
||||
}
|
||||
const onForgotPassword = () => {
|
||||
|
||||
Reference in New Issue
Block a user