feat:三个窗口接口联调版本

This commit is contained in:
liailing1026
2026-01-09 13:54:32 +08:00
parent 5847365eee
commit 920588b063
26 changed files with 4133 additions and 1856 deletions

View File

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

View File

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

View File

@@ -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: [],
},
}

View File

@@ -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: ['架构师', '后端工程师', '前端工程师', '测试工程师'],
}