This commit is contained in:
lzp
2026-03-04 15:06:24 +08:00
11 changed files with 127 additions and 47 deletions

View File

@@ -0,0 +1,3 @@
<svg width="12" height="13" viewBox="0 0 12 13" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.4781 2H8.9829V1.5C8.9829 1.1 8.82277 0.72043 8.5433 0.44043C8.26384 0.16043 7.88499 0 7.48575 0H4.49145C4.09221 0 3.71336 0.16043 3.43389 0.44043C3.15442 0.72043 2.9943 1.1 2.9943 1.5V2H0.49905C0.369297 2 0.239934 2.05039 0.150105 2.15039C0.0502949 2.24039 0 2.37 0 2.5C0 2.63 0.0502949 2.75961 0.150105 2.84961C0.239934 2.94961 0.369297 3 0.49905 3H0.9981V12C0.9981 12.27 1.10793 12.52 1.28759 12.71C1.47723 12.89 1.72671 13 1.9962 13H9.981C10.2505 13 10.5 12.89 10.6896 12.71C10.8693 12.52 10.9791 12.27 10.9791 12V3H11.4781C11.6079 3 11.7373 2.94961 11.8271 2.84961C11.9269 2.75961 11.9772 2.63 11.9772 2.5C11.9772 2.37 11.9269 2.24039 11.8271 2.15039C11.7373 2.05039 11.6079 2 11.4781 2ZM3.9924 1.5C3.9924 1.37 4.04269 1.24039 4.1425 1.15039C4.23233 1.05039 4.3617 1 4.49145 1H7.48575C7.6155 1 7.74486 1.05039 7.83469 1.15039C7.9345 1.24039 7.9848 1.37 7.9848 1.5V2H3.9924V1.5ZM9.981 12H1.9962V3H9.981V12ZM4.9905 5.5V9.5C4.9905 9.63 4.9402 9.75961 4.84039 9.84961C4.75056 9.94961 4.6212 10 4.49145 10C4.3617 10 4.23233 9.94961 4.1425 9.84961C4.04269 9.75961 3.9924 9.63 3.9924 9.5V5.5C3.9924 5.37 4.04269 5.24039 4.1425 5.15039C4.23233 5.05039 4.3617 5 4.49145 5C4.6212 5 4.75056 5.05039 4.84039 5.15039C4.9402 5.24039 4.9905 5.37 4.9905 5.5ZM7.9848 5.5V9.5C7.9848 9.63 7.9345 9.75961 7.83469 9.84961C7.74486 9.94961 7.6155 10 7.48575 10C7.35599 10 7.22663 9.94961 7.1368 9.84961C7.03699 9.75961 6.9867 9.63 6.9867 9.5V5.5C6.9867 5.37 7.03699 5.24039 7.1368 5.15039C7.22663 5.05039 7.35599 5 7.48575 5C7.6155 5 7.74486 5.05039 7.83469 5.15039C7.9345 5.24039 7.9848 5.37 7.9848 5.5Z" fill="#FF4747"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,3 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.44798 0.609431C9.26055 -0.203144 10.578 -0.203144 11.3906 0.609431C12.2031 1.42201 12.2031 2.73945 11.3906 3.55203L7.43273 7.50987C6.92278 8.01982 6.26118 8.35062 5.54725 8.45261L4.09398 8.66022C3.88627 8.68989 3.6767 8.62004 3.52834 8.47167C3.37997 8.3233 3.31012 8.11374 3.33979 7.90603L3.5474 6.45275C3.64939 5.73882 3.98019 5.07722 4.49014 4.56727L8.44798 0.609431ZM10.4478 1.55217C10.1559 1.26026 9.68263 1.26026 9.39072 1.55217L5.43288 5.51001C5.12691 5.81598 4.92843 6.21294 4.86723 6.6413L4.78532 7.21468L5.3587 7.13277C5.78706 7.07158 6.18402 6.8731 6.48999 6.56713L10.4478 2.60929C10.7397 2.31737 10.7397 1.84409 10.4478 1.55217ZM5.33294 0.667037C5.33323 1.0352 5.03501 1.33389 4.66684 1.33418C4.00122 1.33469 3.53154 1.33965 3.16411 1.37456C2.80436 1.40873 2.58973 1.46823 2.42517 1.55208C2.04888 1.74381 1.74294 2.04975 1.55121 2.42605C1.46176 2.60161 1.40031 2.83338 1.36735 3.2368C1.33375 3.64799 1.33324 4.17616 1.33324 4.93385V7.06703C1.33324 7.82471 1.33375 8.35288 1.36735 8.76408C1.40031 9.16749 1.46176 9.39927 1.55121 9.57482C1.74294 9.95112 2.04888 10.2571 2.42517 10.4488C2.60073 10.5382 2.83251 10.5997 3.23592 10.6326C3.64712 10.6662 4.17529 10.6668 4.93297 10.6668H7.06615C7.82383 10.6668 8.352 10.6662 8.7632 10.6326C9.16661 10.5997 9.39839 10.5382 9.57395 10.4488C9.95024 10.2571 10.2562 9.95112 10.4479 9.57482C10.5318 9.41027 10.5913 9.19564 10.6254 8.83589C10.6603 8.46846 10.6653 7.99878 10.6658 7.33315C10.6661 6.96499 10.9648 6.66677 11.333 6.66705C11.7011 6.66734 11.9993 6.96603 11.9991 7.33419C11.9985 7.98627 11.9946 8.52079 11.9527 8.96199C11.91 9.41086 11.8248 9.80928 11.6358 10.1801C11.3163 10.8073 10.8064 11.3172 10.1792 11.6367C9.78439 11.8379 9.35763 11.9218 8.87176 11.9615C8.39988 12 7.81716 12 7.0947 12H4.90442C4.18196 12 3.59924 12 3.12735 11.9615C2.64149 11.9218 2.21473 11.8379 1.8199 11.6367C1.19274 11.3172 0.68284 10.8073 0.363285 10.1801C0.162108 9.78527 0.0782394 9.35851 0.0385427 8.87264C-1.18257e-05 8.40076 -6.50027e-06 7.81803 1.74959e-07 7.09556V4.90531C-6.50027e-06 4.18284 -1.18257e-05 3.60011 0.0385427 3.12823C0.0782394 2.64236 0.162108 2.2156 0.363285 1.82077C0.68284 1.19361 1.19274 0.683712 1.8199 0.364157C2.19072 0.175211 2.58914 0.0899426 3.03801 0.047296C3.47921 0.00537885 4.01373 0.00144737 4.6658 0.000938901C5.03397 0.000651826 5.33265 0.298874 5.33294 0.667037Z" fill="#0D0D0D"/>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -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(() => {

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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)
})

View File

@@ -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' })
}
}

View File

@@ -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" /> -->

View File

@@ -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 = () => {

View File

@@ -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>

View File

@@ -89,7 +89,7 @@
if (isVisible.value) {
isVisible.value = false
} else {
router.back()
router.push({ name: 'index' })
}
}
const onForgotPassword = () => {