feat:额外产物添加

This commit is contained in:
liailing1026
2025-12-21 15:28:59 +08:00
parent b42ab5aedd
commit b987fe70ad
11 changed files with 281 additions and 587 deletions

View File

@@ -1,8 +1,8 @@
<script setup lang="ts">
import { computed, onUnmounted, ref } from 'vue'
import { computed, onUnmounted, ref, reactive, nextTick } from 'vue'
import { throttle } from 'lodash'
import { AnchorLocations, BezierConnector } from '@jsplumb/browser-ui'
import AdditionalOutputCard from './AdditionalOutputCard.vue'
import SvgIcon from '@/components/SvgIcon/index.vue'
import { getActionTypeDisplay, getAgentMapIcon } from '@/layout/components/config.ts'
import { type ConnectArg, Jsplumb } from '@/layout/components/Main/TaskTemplate/utils.ts'
@@ -23,11 +23,24 @@ const collaborationProcess = computed(() => {
return agentsStore.agentRawPlan.data?.['Collaboration Process'] ?? []
})
// 监听额外产物变化
watch(
() => agentsStore.additionalOutputs,
() => {
nextTick(() => {
setTimeout(() => {
jsplumb.repaintEverything()
}, 0)
})
},
{ deep: true }
)
// 编辑逻辑
const editMode = ref(false) //全局编辑开关
const editMap = reactive<Record<string, boolean>>({}) //行级编辑状态
const editBuffer = reactive<Record<string, string | undefined>>({}) //临时输入
const showPopover = ref(false)
function getProcessDescription(stepId: string, processId: string) {
const step = collaborationProcess.value.find(s => s.Id === stepId)
if (step) {
@@ -37,21 +50,6 @@ function getProcessDescription(stepId: string, processId: string) {
return ''
}
function save() {
Object.keys(editMap).forEach(key => {
if (editMap[key]) {
const [stepId, processId] = key.split('-')
const value = editBuffer[key]
// 确保 value 是字符串类型
if (value !== undefined && value !== null) {
// @ts-ignore - TypeScript 无法正确推断类型,但运行时是安全的
handleSaveEdit(stepId, processId, value)
}
}
})
editMode.value = false
}
function handleOpenEdit(stepId: string, processId: string) {
if (!editMode.value) return
const key = `${stepId}-${processId}`
@@ -69,7 +67,6 @@ function handleSaveEdit(stepId: string, processId: string, value: string) {
}
}
editMap[key] = false
ElMessage.success('已保存(前端内存)')
}
const jsplumb = new Jsplumb('task-results-main', {
connector: {
@@ -185,13 +182,6 @@ function createInternalLine(id?: string) {
const loading = ref(false)
// 额外产物编辑状态
const editingOutputId = ref<string | null>(null)
const editingOutputContent = ref('')
// 额外产物内容存储
const additionalOutputContents = ref<Record<string, string>>({})
async function handleRun() {
try {
loading.value = true
@@ -207,43 +197,6 @@ async function handleTaskProcess() {
drawerVisible.value = true
}
// 开始编辑额外产物内容
function startOutputEditing(output: string) {
editingOutputId.value = output
editingOutputContent.value = getAdditionalOutputContent(output) || ''
}
// 保存额外产物内容
function saveOutputEditing() {
if (editingOutputId.value && editingOutputContent.value.trim()) {
additionalOutputContents.value[editingOutputId.value] = editingOutputContent.value.trim()
}
editingOutputId.value = null
editingOutputContent.value = ''
}
// 取消编辑额外产物内容
function cancelOutputEditing() {
editingOutputId.value = null
editingOutputContent.value = ''
}
// 获取额外产物内容
function getAdditionalOutputContent(output: string) {
return additionalOutputContents.value[output] || ''
}
// 处理额外产物的键盘事件
function handleOutputKeydown(event: KeyboardEvent) {
if (event.key === 'Enter') {
event.preventDefault()
saveOutputEditing()
} else if (event.key === 'Escape') {
editingOutputId.value = null
editingOutputContent.value = ''
}
}
// 添加滚动状态标识
const isScrolling = ref(false)
let scrollTimer: ReturnType<typeof setTimeout> | null = null
@@ -281,7 +234,7 @@ function clear() {
jsplumb.reset()
}
// ========== 按钮交互状态管理 ==========
//按钮交互状态管理
const buttonHoverState = ref<'process' | 'execute' | null>(null)
let buttonHoverTimer: ReturnType<typeof setTimeout> | null = null
const handleProcessMouseEnter = () => {
@@ -328,7 +281,7 @@ const executeBtnClass = computed(() => {
if (buttonHoverState.value === 'process') {
return 'circle'
}
// 其他情况:如果有任务数据就显示椭圆形,否则显示圆形
//如果有任务数据就显示椭圆形,否则显示圆形
return agentsStore.agentRawPlan.data ? 'ellipse' : 'circle'
})
@@ -444,6 +397,20 @@ defineExpose({
@scroll="handleScroll"
>
<div id="task-results-main" class="px-[40px] relative">
<!-- 额外产物卡片 -->
<div
v-if="agentsStore.additionalOutputs && agentsStore.additionalOutputs.length > 0"
class="mt-6"
:key="`additional-outputs-${agentsStore.additionalOutputs.length}`"
>
<div class="space-y-4 mb-4">
<AdditionalOutputCard
v-for="(_, index) in agentsStore.additionalOutputs"
:key="`additional-${index}-${agentsStore.additionalOutputs[index]}`"
:index="index"
/>
</div>
</div>
<!-- 原有的流程和产物 -->
<div v-for="item in collaborationProcess" :key="item.Id" class="card-item">
<el-card
@@ -556,76 +523,6 @@ defineExpose({
</el-collapse>
</el-card>
</div>
<!-- 额外产物的编辑卡片 -->
<div
v-for="(output, index) in agentsStore.additionalOutputs"
:key="`additional-output-${index}`"
class="card-item"
>
<!-- 空的流程卡片位置 -->
<div class="w-full"></div>
<!-- 额外产物的编辑卡片 -->
<el-card
class="card-item w-full relative output-object-card additional-output-card"
:shadow="false"
:id="`additional-output-results-${index}`"
>
<!-- 产物名称行 -->
<div class="text-[18px] mb-3">
{{ output }}
</div>
<!-- 编辑区域行 -->
<div class="additional-output-editor">
<div v-if="editingOutputId === output" class="w-full">
<!-- 编辑状态输入框 + 按钮 -->
<div class="flex flex-col gap-3">
<el-input
v-model="editingOutputContent"
type="textarea"
:autosize="{ minRows: 3, maxRows: 6 }"
placeholder="请输入产物内容"
@keydown="handleOutputKeydown"
class="output-editor"
size="small"
/>
<div class="flex justify-end gap-2">
<el-button @click="saveOutputEditing" type="primary" size="small" class="px-3">
</el-button>
<el-button @click="cancelOutputEditing" size="small" class="px-3">
×
</el-button>
</div>
</div>
</div>
<div v-else class="w-full">
<!-- 非编辑状态折叠区域 + 编辑按钮 -->
<div
class="flex items-center justify-between p-3 bg-[var(--color-bg-quinary)] rounded-[8px]"
>
<div
class="text-[14px] text-[var(--color-text-secondary)] output-content-display"
>
{{ getAdditionalOutputContent(output) || '暂无内容,点击编辑' }}
</div>
<el-button
@click="startOutputEditing(output)"
size="small"
type="primary"
plain
class="flex items-center gap-1"
>
<svg-icon icon-class="action" size="12px" />
<span>编辑</span>
</el-button>
</div>
</div>
</div>
</el-card>
</div>
</div>
</div>
</div>
@@ -771,45 +668,6 @@ defineExpose({
}
}
// 额外产物编辑区域样式
.additional-output-editor {
.output-editor {
:deep(.el-textarea__inner) {
font-size: 14px;
color: var(--color-text-primary);
background: var(--color-bg-detail);
border: 1px solid #dcdfe6;
resize: none;
padding: 12px;
}
}
.output-content-display {
word-break: break-word;
white-space: pre-wrap;
transition: all 0.2s ease;
line-height: 1.5;
min-height: 20px;
&:hover {
background-color: rgba(0, 0, 0, 0.05);
border-color: #409eff;
opacity: 1;
}
}
// 编辑按钮样式
.el-button {
font-weight: bold;
font-size: 16px;
border-radius: 4px;
&.el-button--small {
padding: 4px 12px;
}
}
}
// ========== 新增:按钮交互样式 ==========
.task-button-group {
.el-button {