feat:额外产物添加
This commit is contained in:
@@ -3,7 +3,7 @@ import SvgIcon from '@/components/SvgIcon/index.vue'
|
||||
import { getAgentMapIcon } from '@/layout/components/config.ts'
|
||||
import { type ConnectArg, Jsplumb } from '@/layout/components/Main/TaskTemplate/utils.ts'
|
||||
import { type IRawStepTask, useAgentsStore } from '@/stores'
|
||||
import { computed, ref } from 'vue'
|
||||
import { computed, ref, nextTick } from 'vue'
|
||||
import { AnchorLocations } from '@jsplumb/browser-ui'
|
||||
import MultiLineTooltip from '@/components/MultiLineTooltip/index.vue'
|
||||
import Bg from './Bg.vue'
|
||||
@@ -11,8 +11,12 @@ import Bg from './Bg.vue'
|
||||
const emit = defineEmits<{
|
||||
(el: 'resetAgentRepoLine'): void
|
||||
(el: 'setCurrentTask', task: IRawStepTask): void
|
||||
(el: 'add-output', outputName: string): void
|
||||
(el: 'click-branch'): void
|
||||
}>()
|
||||
|
||||
// 分支数量
|
||||
|
||||
const jsplumb = new Jsplumb('task-syllabus')
|
||||
|
||||
const handleScroll = () => {
|
||||
@@ -30,9 +34,79 @@ const editingTaskId = ref<string | null>(null)
|
||||
const editingContent = ref('')
|
||||
|
||||
// 添加新产物状态管理
|
||||
const showAddOutputForm = ref(false)
|
||||
const isAddingOutput = ref(false)
|
||||
const newOutputInputRef = ref<HTMLElement>()
|
||||
const newOutputName = ref('')
|
||||
|
||||
// 处理加号点击
|
||||
const handleAddOutputClick = () => {
|
||||
isAddingOutput.value = true
|
||||
newOutputName.value = ''
|
||||
|
||||
nextTick(() => {
|
||||
setTimeout(() => {
|
||||
if (newOutputInputRef.value) {
|
||||
newOutputInputRef.value?.focus()
|
||||
}
|
||||
jsplumb.instance.repaintEverything()
|
||||
}, 50)
|
||||
})
|
||||
}
|
||||
|
||||
// 保存新产物
|
||||
const saveNewOutput = () => {
|
||||
if (newOutputName.value.trim()) {
|
||||
const outputName = newOutputName.value.trim()
|
||||
const success = agentsStore.addNewOutput(outputName)
|
||||
if (success) {
|
||||
emit('add-output', outputName)
|
||||
isAddingOutput.value = false
|
||||
newOutputName.value = ''
|
||||
nextTick(() => {
|
||||
setTimeout(() => {
|
||||
jsplumb.instance.repaintEverything()
|
||||
}, 50)
|
||||
})
|
||||
console.log('添加新产物成功', outputName)
|
||||
} else {
|
||||
// 退出编辑状态
|
||||
isAddingOutput.value = false
|
||||
newOutputName.value = ''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 取消添加产物
|
||||
const cancelAddOutput = () => {
|
||||
isAddingOutput.value = false
|
||||
newOutputName.value = ''
|
||||
|
||||
nextTick(() => {
|
||||
setTimeout(() => {
|
||||
jsplumb.instance.repaintEverything()
|
||||
}, 50)
|
||||
})
|
||||
}
|
||||
|
||||
// 处理新产物的键盘事件
|
||||
const handleNewOutputKeydown = (event: KeyboardEvent) => {
|
||||
if (event.key === 'Enter') {
|
||||
event.preventDefault()
|
||||
saveNewOutput()
|
||||
} else if (event.key === 'Escape') {
|
||||
cancelAddOutput()
|
||||
}
|
||||
}
|
||||
|
||||
// 新产物输入框失去焦点处理
|
||||
const handleNewOutputBlur = () => {
|
||||
setTimeout(() => {
|
||||
if (newOutputName.value.trim() === '') {
|
||||
cancelAddOutput()
|
||||
}
|
||||
}, 100)
|
||||
}
|
||||
|
||||
// 开始编辑
|
||||
const startEditing = (task: IRawStepTask) => {
|
||||
if (!task.Id) {
|
||||
@@ -71,44 +145,6 @@ const handleKeydown = (event: KeyboardEvent) => {
|
||||
}
|
||||
}
|
||||
|
||||
// 显示添加产物表单
|
||||
const showAddOutputDialog = () => {
|
||||
showAddOutputForm.value = true
|
||||
newOutputName.value = ''
|
||||
}
|
||||
|
||||
// 添加新产物
|
||||
const addNewOutput = () => {
|
||||
if (newOutputName.value.trim()) {
|
||||
const success = agentsStore.addNewOutput(newOutputName.value.trim())
|
||||
if (success) {
|
||||
showAddOutputForm.value = false
|
||||
newOutputName.value = ''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 取消添加产物
|
||||
const cancelAddOutput = () => {
|
||||
showAddOutputForm.value = false
|
||||
newOutputName.value = ''
|
||||
}
|
||||
|
||||
// 处理添加产物的键盘事件
|
||||
const handleAddOutputKeydown = (event: KeyboardEvent) => {
|
||||
if (event.key === 'Enter') {
|
||||
event.preventDefault()
|
||||
addNewOutput()
|
||||
} else if (event.key === 'Escape') {
|
||||
cancelAddOutput()
|
||||
}
|
||||
}
|
||||
|
||||
// 删除额外产物
|
||||
const removeAdditionalOutput = (output: string) => {
|
||||
agentsStore.removeAdditionalOutput(output)
|
||||
}
|
||||
|
||||
function handleCurrentTask(task: IRawStepTask, transparent: boolean): ConnectArg[] {
|
||||
// 创建当前流程与产出的连线
|
||||
const arr: ConnectArg[] = [
|
||||
@@ -179,7 +215,7 @@ defineExpose({
|
||||
class="w-full relative min-h-full"
|
||||
id="task-syllabus"
|
||||
>
|
||||
<Bg />
|
||||
<Bg :is-adding="isAddingOutput" @start-add-output="handleAddOutputClick" />
|
||||
|
||||
<div class="w-full flex items-center gap-[14%] mb-[35px]">
|
||||
<div class="flex-1 flex justify-center">
|
||||
@@ -198,7 +234,47 @@ defineExpose({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 添加新产物卡片 -->
|
||||
<div
|
||||
v-if="isAddingOutput"
|
||||
class="card-it w-full flex items-center gap-[14%] bg-[var(--color-card-bg)] add-output-form mb-[100px]"
|
||||
>
|
||||
<!-- 左侧空白的流程卡片占位 -->
|
||||
<div class="w-[43%] relative z-99" style="height: 20px"></div>
|
||||
|
||||
<!-- 右侧可编辑的产物卡片 -->
|
||||
<el-card
|
||||
class="w-[43%] relative task-syllabus-output-object-card border-dashed border-2 border-[var(--color-primary)]"
|
||||
>
|
||||
<div class="h-full flex items-center justify-center">
|
||||
<!-- 输入框 -->
|
||||
<el-input
|
||||
ref="newOutputInputRef"
|
||||
v-model="newOutputName"
|
||||
placeholder="Enter保存,ESC取消"
|
||||
@keydown="handleNewOutputKeydown"
|
||||
@blur="handleNewOutputBlur"
|
||||
size="large"
|
||||
class="w-full"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
<!-- 显示临时产物卡片 -->
|
||||
<div
|
||||
v-for="output in agentsStore.additionalOutputs"
|
||||
:key="output"
|
||||
class="card-it w-full flex items-center gap-[14%] bg-[var(--color-card-bg)] mb-[100px]"
|
||||
>
|
||||
<!-- 左侧空白的流程卡片占位 -->
|
||||
<div class="w-[43%] relative z-99" style="height: 100px"></div>
|
||||
|
||||
<!-- 右侧产物卡片 -->
|
||||
<el-card class="w-[43%] relative task-syllabus-output-object-card" :shadow="true">
|
||||
<div class="text-[18px] font-bold text-center">{{ output }}</div>
|
||||
</el-card>
|
||||
</div>
|
||||
<div
|
||||
v-for="item in collaborationProcess"
|
||||
:key="item.Id"
|
||||
@@ -292,72 +368,12 @@ defineExpose({
|
||||
<div class="text-[18px] font-bold text-center">{{ item.OutputObject }}</div>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
<!-- 额外的产物列表 -->
|
||||
<!-- <div
|
||||
v-for="(output, index) in agentsStore.additionalOutputs"
|
||||
:key="`additional-${index}`"
|
||||
class="card-item w-full flex items-center gap-[14%]"
|
||||
> -->
|
||||
<!-- 空的流程卡片位置 -->
|
||||
<!-- <div class="w-[43%]"></div> -->
|
||||
<!-- 额外产物卡片 -->
|
||||
<!-- <el-card class="w-[43%] relative additional-output-card group" :shadow="false">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="text-[18px] font-bold text-center flex-1">{{ output }}</div>
|
||||
<button
|
||||
@click="removeAdditionalOutput(output)"
|
||||
class="opacity-0 group-hover:opacity-100 text-red-500 hover:text-red-700 transition-all duration-200 ml-2 text-lg font-bold w-5 h-5 flex items-center justify-center rounded hover:bg-red-50"
|
||||
>
|
||||
×
|
||||
</button>
|
||||
</div>
|
||||
</el-card>
|
||||
</div> -->
|
||||
<!-- 添加新产物按钮 -->
|
||||
<!-- <div class="card-item w-full flex items-center gap-[14%] mt-[20px]"> -->
|
||||
<!-- 空的流程卡片位置 -->
|
||||
<!-- <div class="w-[43%]"></div> -->
|
||||
<!-- 添加新产物按钮 -->
|
||||
<!-- <div class="w-[43%] relative"> -->
|
||||
<!-- <div v-if="!showAddOutputForm" class="add-output-btn">
|
||||
<button
|
||||
@click="showAddOutputDialog"
|
||||
class="w-full h-[50px] border-2 border-dashed border-gray-300 rounded-lg flex items-center justify-center text-gray-500 hover:border-blue-500 hover:text-blue-500 transition-all duration-200 group"
|
||||
>
|
||||
<svg-icon icon-class="plus" size="20px" class="mr-2" />
|
||||
<span class="text-sm font-medium"></span>
|
||||
</button>
|
||||
</div> -->
|
||||
|
||||
<!-- 添加产物表单 -->
|
||||
<!-- <div v-else class="add-output-form">
|
||||
<el-card class="w-full" shadow="hover">
|
||||
<div class="p-3">
|
||||
<el-input
|
||||
v-model="newOutputName"
|
||||
placeholder="输入产物名称"
|
||||
size="small"
|
||||
@keydown="handleAddOutputKeydown"
|
||||
@blur="addNewOutput"
|
||||
class="w-full mb-3"
|
||||
/>
|
||||
<div class="flex gap-2">
|
||||
<el-button @click="addNewOutput" type="primary" size="small" class="flex-1">
|
||||
确定
|
||||
</el-button>
|
||||
<el-button @click="cancelAddOutput" size="small" class="flex-1">
|
||||
取消
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div> -->
|
||||
<!-- </div> -->
|
||||
<!-- </div> -->
|
||||
<!-- <div>
|
||||
<el-button type="info" size="medium" class="flex-1"> branch </el-button>
|
||||
</div> -->
|
||||
</div>
|
||||
<div class="branch-button" @click="handleBranchClick">
|
||||
<div class="branch-icon">
|
||||
<svg-icon icon-class="branch" color="#000" size="24px" />
|
||||
</div>
|
||||
<span>{{ branchCount }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -368,7 +384,6 @@ defineExpose({
|
||||
border: 1px solid var(--color-card-border-task);
|
||||
box-sizing: border-box;
|
||||
transition: border-color 0.2s ease;
|
||||
// box-shadow: var(--color-card-shadow);
|
||||
margin-bottom: 100px;
|
||||
&:hover {
|
||||
background-color: var(--color-card-bg-task-hover);
|
||||
@@ -390,7 +405,6 @@ defineExpose({
|
||||
border: 1px solid var(--color-card-border-task);
|
||||
box-sizing: border-box;
|
||||
transition: border-color 0.2s ease;
|
||||
// box-shadow: var(--color-card-shadow-hover);
|
||||
&:hover {
|
||||
background-color: var(--color-card-bg-task-hover);
|
||||
border-color: var(--color-card-border-hover);
|
||||
@@ -449,6 +463,27 @@ defineExpose({
|
||||
|
||||
.add-output-form {
|
||||
animation: slideDown 0.3s ease-out;
|
||||
:deep(.el-card__body) {
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
:deep(.el-input__wrapper) {
|
||||
border: 1px solid var(--color-text);
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
|
||||
&.is-focus {
|
||||
border-color: var(--color-text);
|
||||
box-shadow: 0 0 0 1px var(--color-primary-light);
|
||||
}
|
||||
:deep(.el-input__inner) {
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideDown {
|
||||
@@ -462,11 +497,6 @@ defineExpose({
|
||||
}
|
||||
}
|
||||
|
||||
// 添加产物表单样式
|
||||
:deep(.el-card__body) {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
// 输入框样式
|
||||
:deep(.el-input__wrapper) {
|
||||
background: transparent;
|
||||
|
||||
Reference in New Issue
Block a user