feat:三个窗口接口联调版本
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { ref, computed } from 'vue'
|
||||
import { getActionTypeDisplay } from '@/layout/components/config.ts'
|
||||
import { useAgentsStore } from '@/stores'
|
||||
import BranchButton from './components/TaskButton.vue'
|
||||
@@ -23,6 +23,20 @@ const emit = defineEmits<{
|
||||
(e: 'save-edit', stepId: string, processId: string, value: string): void
|
||||
}>()
|
||||
|
||||
// 🔄 从 currentTask 中获取数据(与分支切换联动)
|
||||
const currentTaskProcess = computed(() => {
|
||||
// ✅ 优先使用 currentTask(包含分支切换后的数据)
|
||||
const currentTask = agentsStore.currentTask
|
||||
if (currentTask && currentTask.Id === props.step.Id && currentTask.TaskProcess) {
|
||||
return currentTask.TaskProcess
|
||||
}
|
||||
|
||||
// ⚠️ 降级:从 agentRawPlan 中获取原始数据(不受分支切换影响)
|
||||
const collaborationProcess = agentsStore.agentRawPlan.data?.['Collaboration Process'] || []
|
||||
const rawData = collaborationProcess.find((task: any) => task.Id === props.step.Id)
|
||||
return rawData?.TaskProcess || []
|
||||
})
|
||||
|
||||
// 当前正在编辑的process ID
|
||||
const editingProcessId = ref<string | null>(null)
|
||||
// 编辑框的值
|
||||
@@ -30,6 +44,17 @@ const editValue = ref('')
|
||||
// 鼠标悬停的process ID
|
||||
const hoverProcessId = ref<string | null>(null)
|
||||
|
||||
// 🆕 处理卡片点击事件(非编辑模式下)
|
||||
function handleCardClick() {
|
||||
// 如果正在编辑,不处理点击
|
||||
if (editingProcessId.value) return
|
||||
|
||||
// 设置当前任务,与任务大纲联动
|
||||
if (props.step.Id) {
|
||||
agentsStore.setCurrentTask(props.step)
|
||||
}
|
||||
}
|
||||
|
||||
// 检测当前是否是深色模式
|
||||
function isDarkMode(): boolean {
|
||||
return document.documentElement.classList.contains('dark')
|
||||
@@ -116,12 +141,12 @@ function handleCancel() {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="process-card">
|
||||
<div class="process-card" @click="handleCardClick">
|
||||
<div class="process-content">
|
||||
<!-- 显示模式 -->
|
||||
<div class="display-content">
|
||||
<span
|
||||
v-for="process in step.TaskProcess"
|
||||
v-for="process in currentTaskProcess"
|
||||
:key="process.ID"
|
||||
class="process-segment"
|
||||
@mouseenter="handleMouseEnter(process.ID)"
|
||||
@@ -190,10 +215,13 @@ function handleCancel() {
|
||||
{{ process.Description }}
|
||||
</span>
|
||||
|
||||
<span class="separator" v-if="!process.Description.endsWith('。')">。</span>
|
||||
<span class="separator" v-if="process.Description && !process.Description.endsWith('。')"
|
||||
>。</span
|
||||
>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 按钮点击不会冒泡到卡片 -->
|
||||
<BranchButton :step="step" />
|
||||
</div>
|
||||
</template>
|
||||
@@ -207,6 +235,8 @@ function handleCancel() {
|
||||
background: var(--color-bg-list);
|
||||
border: 1px solid var(--color-border-default);
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
|
||||
.process-content {
|
||||
min-height: 20px;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -21,11 +21,28 @@ const branchCount = computed(() => {
|
||||
const branches = selectionStore.getTaskProcessBranches(taskStepId)
|
||||
|
||||
// 主分支(1) + 额外分支数量
|
||||
return 1 + branches.length
|
||||
return branches.length || 1
|
||||
})
|
||||
|
||||
const handleClick = (event: MouseEvent) => {
|
||||
event.stopPropagation() // 阻止冒泡,避免触发卡片点击
|
||||
// 🆕 判断按钮是否可点击(只有当前按钮对应的任务是任务大纲中选中的任务时才可点击)
|
||||
const isClickable = computed(() => {
|
||||
if (!props.step?.Id || !agentsStore.currentTask?.Id) {
|
||||
return false
|
||||
}
|
||||
return props.step.Id === agentsStore.currentTask.Id
|
||||
})
|
||||
|
||||
const handleClick = (event?: MouseEvent) => {
|
||||
// 🆕 只有可点击时才执行操作
|
||||
if (!isClickable.value) {
|
||||
return
|
||||
}
|
||||
|
||||
// 阻止冒泡,避免触发卡片点击
|
||||
if (event) {
|
||||
event.stopPropagation()
|
||||
}
|
||||
|
||||
emit('click')
|
||||
// 设置当前任务
|
||||
if (props.step) {
|
||||
@@ -39,9 +56,9 @@ const handleClick = (event: MouseEvent) => {
|
||||
<template>
|
||||
<div
|
||||
class="task-button"
|
||||
:class="{ 'has-branches': branchCount > 1 }"
|
||||
:class="{ 'has-branches': branchCount > 0, 'is-disabled': !isClickable }"
|
||||
@click="handleClick"
|
||||
:title="`${branchCount} 个分支`"
|
||||
:title="isClickable ? `${branchCount} 个分支` : '请先在任务大纲中选中此任务'"
|
||||
>
|
||||
<!-- 流程图标 -->
|
||||
<svg-icon icon-class="branch" size="20px" class="task-icon" />
|
||||
@@ -83,6 +100,17 @@ const handleClick = (event: MouseEvent) => {
|
||||
filter: brightness(0.9);
|
||||
}
|
||||
|
||||
// 🆕 禁用状态
|
||||
&.is-disabled {
|
||||
background-color: #bdc3c7;
|
||||
cursor: not-allowed;
|
||||
opacity: 0.6;
|
||||
|
||||
&:hover {
|
||||
filter: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.has-branches::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
// /api/fill_stepTask 接口的Vue适用mock数据
|
||||
import type { IApiStepTask, IRawStepTask } from '@/stores/modules/agents'
|
||||
|
||||
// 模拟接口响应数据
|
||||
export const mockFillStepTaskResponse: IApiStepTask = {
|
||||
name: '需求分析与原型设计',
|
||||
content: '分析用户需求并创建产品原型',
|
||||
inputs: ['用户调研报告', '竞品分析文档'],
|
||||
output: '产品原型设计稿',
|
||||
agents: ['实验材料学家', '腐蚀机理研究员', '防护工程专家'],
|
||||
brief: {
|
||||
template: '基于!<0>!和!<1>!,!<2>!、!<3>!和!<4>!执行!<5>!任务,以获得!<6>!。',
|
||||
data: {
|
||||
'0': {
|
||||
text: '用户调研报告',
|
||||
style: {
|
||||
background: 'hsl(120, 60%, 70%)',
|
||||
},
|
||||
},
|
||||
'1': {
|
||||
text: '竞品分析文档',
|
||||
style: {
|
||||
background: 'hsl(120, 60%, 70%)',
|
||||
},
|
||||
},
|
||||
'2': {
|
||||
text: '实验材料学家',
|
||||
style: {
|
||||
background: 'hsl(0, 0%, 90%)',
|
||||
boxShadow: '1px 1px 4px 1px rgba(0,0,0,0.2)',
|
||||
},
|
||||
},
|
||||
'3': {
|
||||
text: '腐蚀机理研究员',
|
||||
style: {
|
||||
background: 'hsl(0, 0%, 90%)',
|
||||
boxShadow: '1px 1px 4px 1px rgba(0,0,0,0.2)',
|
||||
},
|
||||
},
|
||||
'4': {
|
||||
text: '防护工程专家',
|
||||
style: {
|
||||
background: 'hsl(0, 0%, 90%)',
|
||||
boxShadow: '1px 1px 4px 1px rgba(0,0,0,0.2)',
|
||||
},
|
||||
},
|
||||
'5': {
|
||||
text: '分析用户需求并创建产品原型',
|
||||
style: {
|
||||
background: 'hsl(0, 0%, 87%)',
|
||||
border: '1.5px solid #ddd',
|
||||
},
|
||||
},
|
||||
'6': {
|
||||
text: '产品原型设计稿',
|
||||
style: {
|
||||
background: 'hsl(30, 100%, 80%)',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
process: [
|
||||
{
|
||||
id: 'action_001',
|
||||
type: '需求分析',
|
||||
agent: '实验材料学家',
|
||||
description: '分析用户调研报告,识别核心需求点',
|
||||
inputs: ['用户调研报告'],
|
||||
},
|
||||
{
|
||||
id: 'action_002',
|
||||
type: '竞品分析',
|
||||
agent: '实验材料学家',
|
||||
description: '对比竞品功能,确定产品差异化优势',
|
||||
inputs: ['竞品分析文档'],
|
||||
},
|
||||
{
|
||||
id: 'action_003',
|
||||
type: '信息架构设计',
|
||||
agent: '防护工程专家',
|
||||
description: '设计产品信息结构和用户流程',
|
||||
inputs: ['需求分析结果'],
|
||||
},
|
||||
{
|
||||
id: 'action_004',
|
||||
type: '界面原型设计',
|
||||
agent: '腐蚀机理研究员',
|
||||
description: '创建高保真界面原型',
|
||||
inputs: ['信息架构设计'],
|
||||
},
|
||||
{
|
||||
id: 'action_005',
|
||||
type: '原型评审',
|
||||
agent: '实验材料学家',
|
||||
description: '组织团队评审原型设计',
|
||||
inputs: ['界面原型设计'],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
// 请求参数类型
|
||||
export interface IFillStepTaskRequest {
|
||||
goal: string
|
||||
stepTask: IApiStepTask
|
||||
}
|
||||
|
||||
// Vue composable
|
||||
export const useFillStepTaskMock = () => {
|
||||
const fillStepTask = async (
|
||||
goal: string,
|
||||
stepTask: IApiStepTask,
|
||||
): Promise<{ data: IApiStepTask }> => {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve({
|
||||
data: mockFillStepTaskResponse,
|
||||
})
|
||||
}, 500)
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
fillStepTask,
|
||||
}
|
||||
}
|
||||
|
||||
// Vue组件使用示例
|
||||
export const fillStepTaskExampleRequest: IFillStepTaskRequest = {
|
||||
goal: '开发一个智能协作平台',
|
||||
stepTask: {
|
||||
name: '需求分析与原型设计',
|
||||
content: '分析用户需求并创建产品原型',
|
||||
inputs: ['用户调研报告', '竞品分析文档'],
|
||||
output: '产品原型设计稿',
|
||||
agents: [],
|
||||
brief: {
|
||||
template: '',
|
||||
data: {},
|
||||
},
|
||||
process: [],
|
||||
},
|
||||
}
|
||||
@@ -1,159 +0,0 @@
|
||||
// /api/fill_stepTask_TaskProcess 接口的Vue适用mock数据
|
||||
import type { IApiStepTask } from '@/stores'
|
||||
|
||||
// 模拟接口响应数据
|
||||
export const mockFillAgentSelectionResponse: IApiStepTask = {
|
||||
name: '技术方案设计与开发',
|
||||
content: '设计技术架构并完成核心功能开发',
|
||||
inputs: ['产品需求文档', '技术选型指南'],
|
||||
output: '可运行的产品版本',
|
||||
agents: ['架构师', '后端工程师', '前端工程师', '测试工程师'],
|
||||
brief: {
|
||||
template: '基于!<0>!和!<1>!,!<2>!、!<3>!、!<4>!和!<5>!执行!<6>!任务,以获得!<7>!。',
|
||||
data: {
|
||||
'0': {
|
||||
text: '产品需求文档',
|
||||
style: {
|
||||
background: 'hsl(120, 60%, 70%)',
|
||||
},
|
||||
},
|
||||
'1': {
|
||||
text: '技术选型指南',
|
||||
style: {
|
||||
background: 'hsl(120, 60%, 70%)',
|
||||
},
|
||||
},
|
||||
'2': {
|
||||
text: '架构师',
|
||||
style: {
|
||||
background: 'hsl(0, 0%, 90%)',
|
||||
boxShadow: '1px 1px 4px 1px rgba(0,0,0,0.2)',
|
||||
},
|
||||
},
|
||||
'3': {
|
||||
text: '后端工程师',
|
||||
style: {
|
||||
background: 'hsl(0, 0%, 90%)',
|
||||
boxShadow: '1px 1px 4px 1px rgba(0,0,0,0.2)',
|
||||
},
|
||||
},
|
||||
'4': {
|
||||
text: '前端工程师',
|
||||
style: {
|
||||
background: 'hsl(0, 0%, 90%)',
|
||||
boxShadow: '1px 1px 4px 1px rgba(0,0,0,0.2)',
|
||||
},
|
||||
},
|
||||
'5': {
|
||||
text: '测试工程师',
|
||||
style: {
|
||||
background: 'hsl(0, 0%, 90%)',
|
||||
boxShadow: '1px 1px 4px 1px rgba(0,0,0,0.2)',
|
||||
},
|
||||
},
|
||||
'6': {
|
||||
text: '设计技术架构并完成核心功能开发',
|
||||
style: {
|
||||
background: 'hsl(0, 0%, 87%)',
|
||||
border: '1.5px solid #ddd',
|
||||
},
|
||||
},
|
||||
'7': {
|
||||
text: '可运行的产品版本',
|
||||
style: {
|
||||
background: 'hsl(30, 100%, 80%)',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
process: [
|
||||
{
|
||||
id: 'action_101',
|
||||
type: '技术架构设计',
|
||||
agent: '架构师',
|
||||
description: '设计系统架构和技术栈选型',
|
||||
inputs: ['产品需求文档', '技术选型指南'],
|
||||
},
|
||||
{
|
||||
id: 'action_102',
|
||||
type: '数据库设计',
|
||||
agent: '后端工程师',
|
||||
description: '设计数据库表结构和关系',
|
||||
inputs: ['技术架构设计'],
|
||||
},
|
||||
{
|
||||
id: 'action_103',
|
||||
type: '后端API开发',
|
||||
agent: '后端工程师',
|
||||
description: '实现RESTful API接口',
|
||||
inputs: ['数据库设计'],
|
||||
},
|
||||
{
|
||||
id: 'action_104',
|
||||
type: '前端界面开发',
|
||||
agent: '前端工程师',
|
||||
description: '开发用户界面和交互功能',
|
||||
inputs: ['后端API开发'],
|
||||
},
|
||||
{
|
||||
id: 'action_105',
|
||||
type: '单元测试',
|
||||
agent: '测试工程师',
|
||||
description: '编写和执行单元测试用例',
|
||||
inputs: ['前端界面开发'],
|
||||
},
|
||||
{
|
||||
id: 'action_106',
|
||||
type: '集成测试',
|
||||
agent: '测试工程师',
|
||||
description: '进行系统集成测试',
|
||||
inputs: ['单元测试'],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
// 请求参数类型
|
||||
export interface IFillAgentSelectionRequest {
|
||||
goal: string
|
||||
stepTask: IApiStepTask
|
||||
agents: string[]
|
||||
}
|
||||
|
||||
// Vue composable
|
||||
export const useFillAgentSelectionMock = () => {
|
||||
const fillAgentSelection = async (
|
||||
goal: string,
|
||||
stepTask: IApiStepTask,
|
||||
agents: string[],
|
||||
): Promise<{ data: IApiStepTask }> => {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve({
|
||||
data: mockFillAgentSelectionResponse,
|
||||
})
|
||||
}, 500)
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
fillAgentSelection,
|
||||
}
|
||||
}
|
||||
|
||||
// Vue组件使用示例
|
||||
export const fillAgentSelectionExampleRequest: IFillAgentSelectionRequest = {
|
||||
goal: '开发一个智能协作平台',
|
||||
stepTask: {
|
||||
name: '技术方案设计与开发',
|
||||
content: '设计技术架构并完成核心功能开发',
|
||||
inputs: ['产品需求文档', '技术选型指南'],
|
||||
output: '可运行的产品版本',
|
||||
agents: [],
|
||||
brief: {
|
||||
template: '',
|
||||
data: {},
|
||||
},
|
||||
process: [],
|
||||
},
|
||||
agents: ['架构师', '后端工程师', '前端工程师', '测试工程师'],
|
||||
}
|
||||
Reference in New Issue
Block a user