从这张飞书工作流图可以看出,这是一个产品评审到技术排期的需求流程,对应的需求分析可以拆解为以下核心内容:
一、需求流程的核心目标
这个流程是将产品需求从“发起评审”推进到“各技术端排期”,确保产品侧的设计方案(埋点、AB实验、UE/UI等)经过评审后,能明确各技术角色的开发排期。
二、需求参与角色
流程涉及的核心角色(图中顶部标签):
- 决策/评审方:DA(数据分析师)、PM(产品经理)、需求评审委员会
- 产品侧执行方:UE(用户体验)、UI&UX(交互视觉)、UX Writer(文案)
- 技术侧执行方:Android/FE/Server/Data开发、QA(测试)
三、需求流程的关键节点与核心动作
- 发起评审:需求从“开始”进入流程,由PM或相关角色发起产品评审
- 产品评审(当前节点):需完成5项核心产出(并行执行):
- 埋点设计:确定数据采集的埋点规则
- AB方案设计:制定AB实验的分组、变量、指标
- UE设计:输出用户体验流程(如交互逻辑)
- UI&UX设计:输出视觉设计稿(界面、组件)
- 翻译文案确认:完成多语言场景的文案翻译
- UI&UX设计:是产品评审到技术评审的衔接节点(可能是对设计稿的最终确认)
- 技术评审:各技术端(iOS/Android/Server等)基于产品方案,输出开发排期预估
四、需求的关键信息
- 流程类型:产品需求的“评审→排期”流程,属于需求落地前的准备阶段
- 依赖关系:产品评审的5项产出是技术评审的前置条件;技术评审的排期是后续开发的依据
- 风险点:若产品评审的某一项(如AB方案)延迟,会直接影响技术评审的排期
要基于Vue + Element UI + Spring Boot开发这张图对应的“需求评审工作流程可视化”功能,核心是实现流程模板展示、实例状态跟踪、节点进度可视化,以下是具体方案:
一、核心需求拆解
这个流程的可视化需要支持:
- 流程模板展示:固定展示“开始→发起评审→产品评审→UI&UX设计→技术评审”的节点与连线(即你图中的静态模板)。
- 实例状态跟踪:对某一个具体需求,标记当前所处节点(比如“产品评审中”)。
- 节点进度展示:产品评审下的子任务(埋点设计、AB方案等)的完成状态(未开始/进行中/已完成)。
二、技术实现方案
1. 后端(Spring Boot):提供流程数据接口
需要存储“流程模板”和“流程实例”的结构与状态:
- 数据库设计:
-- 流程模板表(存储节点、连线、子任务)CREATETABLEworkflow_template(idVARCHAR(64)PRIMARYKEY,nameVARCHAR(128)NOTNULLCOMMENT'流程名称(如需求评审流程)',nodes JSONNOTNULLCOMMENT'节点数据:[{"id":"node1","name":"发起评审","type":"start"}]',edges JSONNOTNULLCOMMENT'连线数据:[{"source":"node1","target":"node2"}]',subtasks JSONCOMMENT'子任务(如产品评审的埋点设计)');-- 流程实例表(存储某需求的当前状态)CREATETABLEworkflow_instance(idVARCHAR(64)PRIMARYKEY,template_idVARCHAR(64)NOTNULLCOMMENT'关联模板ID',demand_idVARCHAR(64)NOTNULLCOMMENT'关联需求ID',current_node_idVARCHAR(64)COMMENT'当前所处节点ID',subtask_status JSONCOMMENT'子任务完成状态:{"buried_point":"doing"}'); - 接口开发:
提供“获取流程模板”“获取实例状态”接口:// 获取流程模板(对应你图中的静态流程)@GetMapping("/template")publicResult<WorkflowTemplate>getTemplate(@RequestParamStringtemplateId){WorkflowTemplatetemplate=templateMapper.selectById(templateId);returnResult.success(template);}// 获取流程实例状态(某需求的当前进度)@GetMapping("/instance/status")publicResult<WorkflowInstance>getInstanceStatus(@RequestParamStringinstanceId){WorkflowInstanceinstance=instanceMapper.selectById(instanceId);returnResult.success(instance);}
2. 前端(Vue + Element UI):可视化渲染
用VueFlow(轻量级流程图组件)渲染模板,结合Element UI的组件展示状态:
- 流程模板渲染(静态结构):
<template> <div class="workflow-container"> <!-- VueFlow 渲染流程图 --> <VueFlow v-model="elements" :min-zoom="0.5" :max-zoom="2"> <Background /> </VueFlow> <!-- Element UI 展示当前节点和子任务 --> <el-card v-if="currentInstance"> <h3>当前节点:{{ currentNode.name }}</h3> <el-tag :type="currentNode.status === 'doing' ? 'warning' : 'success'"> {{ currentNode.status === 'doing' ? '进行中' : '已完成' }} </el-tag> <el-divider /> <h4>子任务进度:</h4> <el-checkbox-group v-model="finishedSubtasks"> <el-checkbox v-for="task in subtasks" :label="task.id"> {{ task.name }} </el-checkbox> </el-checkbox-group> </el-card> </div> </template> <script setup> import { ref, onMounted } from 'vue'; import { VueFlow, Background } from '@vue-flow/core'; import '@vue-flow/core/dist/style.css'; import axios from 'axios'; // 流程图元素(节点+连线) const elements = ref([]); // 当前流程实例 const currentInstance = ref(null); // 子任务列表 const subtasks = ref([]); // 已完成子任务 const finishedSubtasks = ref([]); onMounted(async () => { // 1. 获取流程模板(渲染静态结构) const templateRes = await axios.get('/api/workflow/template?templateId=demand-review'); const { nodes, edges, subtasks: taskList } = templateRes.data; elements.value = [...nodes, ...edges]; subtasks.value = taskList; // 2. 获取流程实例状态(标记当前节点和子任务) const instanceRes = await axios.get('/api/workflow/instance/status?instanceId=inst-123'); currentInstance.value = instanceRes.data; // 从实例中获取已完成的子任务 finishedSubtasks.value = Object.entries(instanceRes.data.subtask_status) .filter(([_, status]) => status === 'done') .map(([id]) => id); }); </script> - 样式自定义(匹配飞书风格):
给VueFlow的节点设置飞书样式(圆角、彩色标签):.vue-flow__node{border-radius:8px;padding:8px 12px;font-size:14px;}.vue-flow__node-start{background:#4cd964;color:white;}.vue-flow__node-doing{background:#ffcc00;color:black;}
3. 关键交互增强
- 节点点击详情:点击“产品评审”节点,弹窗展示子任务的详细进度(用Element UI的
el-dialog)。 - 状态实时更新:定时请求后端接口,刷新当前节点和子任务的状态(用
setInterval)。 - 导出流程图:用
html2canvas将VueFlow区域转为图片,支持下载(Element UI的el-button触发)。
三、效果示例
- 静态模板:渲染出和你图中一致的“开始→发起评审→产品评审”节点与连线。
- 实例状态:“产品评审”节点显示黄色(进行中),子任务“埋点设计”显示“已完成”(勾选状态)。
在Spring Boot + Vue + Element UI技术栈中,创建工作流程模板(对应你需求评审流程的“模板定义”)需要实现“模板可视化编辑 + 后端存储”的功能,以下是具体步骤:
一、核心功能目标
创建流程模板时,需要支持:
- 节点配置:添加/删除节点(如“发起评审”“产品评审”),设置节点名称、类型(开始/审批/并行任务)。
- 连线配置:拖拽连接节点,定义流程的流转顺序。
- 子任务配置:给节点(如“产品评审”)绑定子任务(如埋点设计、AB方案)。
- 模板保存:将配置好的模板存储到后端,供后续发起流程使用。
二、后端(Spring Boot):模板存储与接口
1. 数据库与实体类
复用之前的workflow_template表,实体类增加子任务配置:
@Data@TableName("workflow_template")publicclassWorkflowTemplate{privateStringid;// 模板ID(UUID生成)privateStringname;// 模板名称(如“需求评审流程”)privateStringnodes;// 节点JSON:[{"id":"n1","name":"发起评审","type":"start"}]privateStringedges;// 连线JSON:[{"source":"n1","target":"n2"}]privateStringsubtasks;// 子任务JSON:{"n2":[{"id":"t1","name":"埋点设计"}]}}2. 模板CRUD接口
提供“创建模板、查询模板、修改模板”接口:
@RestController@RequestMapping("/api/workflow/template")publicclassTemplateController{@AutowiredprivateWorkflowTemplateMappertemplateMapper;// 创建流程模板@PostMapping("/create")publicResult<String>createTemplate(@RequestBodyWorkflowTemplatetemplate){template.setId(UUID.randomUUID().toString().replace("-",""));templateMapper.insert(template);returnResult.success("模板创建成功,ID:"+template.getId());}// 查询所有模板@GetMapping("/list")publicResult<List<WorkflowTemplate>>listTemplates(){returnResult.success(templateMapper.selectList(null));}}三、前端(Vue + Element UI + VueFlow):模板可视化编辑器
用VueFlow(支持拖拽编辑)+ Element UI 做可视化编辑页面:
1. 编辑页面结构
<template> <el-container> <!-- 左侧:模板配置表单 --> <el-aside width="250px"> <el-form :model="templateForm" label-width="80px"> <el-form-item label="模板名称"> <el-input v-model="templateForm.name" placeholder="输入流程模板名称" /> </el-form-item> <el-form-item> <el-button type="primary" @click="saveTemplate">保存模板</el-button> </el-form-item> <el-divider /> <h4>节点库</h4> <!-- 拖拽节点到画布 --> <div class="node-item" draggable @dragstart="onDragStart('start', '开始')"> 开始节点 </div> <div class="node-item" draggable @dragstart="onDragStart('task', '审批节点')"> 审批节点 </div> </el-aside> <!-- 右侧:VueFlow编辑画布 --> <el-main> <VueFlow v-model="elements" @connect="onConnect" @node-remove="onNodeRemove" @edge-remove="onEdgeRemove" > <Background /> <Controls /> <MiniMap /> </VueFlow> </el-main> </el-container> </template>2. 核心逻辑(拖拽、保存)
<script setup> import { ref } from 'vue'; import { VueFlow, Background, Controls, MiniMap } from '@vue-flow/core'; import '@vue-flow/core/dist/style.css'; import axios from 'axios'; // 模板表单 const templateForm = ref({ name: '' }); // 流程图元素(节点+连线) const elements = ref([]); // 节点ID计数器 let nodeId = 1; // 拖拽节点到画布 const onDragStart = (type, name, e) => { e.dataTransfer.setData('node', JSON.stringify({ type, name })); }; // VueFlow画布监听拖拽放置 VueFlow.vueFlowInstance.value?.on('drop', (e) => { const nodeData = JSON.parse(e.dataTransfer.getData('node')); const { x, y } = VueFlow.vueFlowInstance.value.screenToFlowPosition({ x: e.clientX, y: e.clientY }); // 添加新节点到画布 elements.value.push({ id: `n${nodeId++}`, type: nodeData.type, position: { x, y }, data: { label: nodeData.name } }); }); // 连线创建时记录 const onConnect = (params) => { elements.value.push({ id: `e${Date.now()}`, source: params.source, target: params.target, type: 'default' }); }; // 保存模板到后端 const saveTemplate = async () => { // 整理节点、连线数据 const nodes = elements.value.filter(item => item.type !== 'edge'); const edges = elements.value.filter(item => item.type === 'edge'); // 调用后端接口 await axios.post('/api/workflow/template/create', { name: templateForm.value.name, nodes: JSON.stringify(nodes), edges: JSON.stringify(edges), subtasks: JSON.stringify({}) // 子任务可后续编辑 }); ElMessage.success('模板保存成功!'); }; </script> <style scoped> .node-item { padding: 8px; background: #f5f5f5; border-radius: 4px; margin: 8px 0; cursor: move; } </style>四、扩展:子任务配置
给节点(如“产品评审”)添加子任务,可在节点点击时弹出Element UI的弹窗,输入子任务列表,再关联到模板的subtasks字段中。
针对工作流程模板,需要设计至少2张核心数据库表(模板主表 + 子任务关联表),既支持存储流程的节点/连线结构,也能灵活管理节点下的子任务。以下是详细的表结构设计(以MySQL为例):
一、核心表1:流程模板主表(存储流程的整体结构)
记录流程模板的基本信息、节点和连线的完整结构。
CREATETABLE`workflow_template`(`template_id`VARCHAR(64)NOTNULLCOMMENT'模板唯一ID(UUID生成)',`template_name`VARCHAR(128)NOTNULLCOMMENT'模板名称(如“需求评审流程”)',`template_desc`VARCHAR(512)DEFAULT''COMMENT'模板描述',`nodes`JSONNOTNULLCOMMENT'节点列表:[{"node_id":"n1","node_name":"发起评审","node_type":"start","position":{"x":100,"y":100}}]',`edges`JSONNOTNULLCOMMENT'连线列表:[{"edge_id":"e1","source":"n1","target":"n2","line_type":"default"}]',`create_user`VARCHAR(64)NOTNULLCOMMENT'创建人ID',`create_time`DATETIMEDEFAULTCURRENT_TIMESTAMPCOMMENT'创建时间',`update_time`DATETIMEDEFAULTCURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMPCOMMENT'更新时间',PRIMARYKEY(`template_id`),KEY`idx_create_user`(`create_user`))ENGINE=InnoDBDEFAULTCHARSET=utf8mb4COMMENT='工作流程模板主表';二、核心表2:模板节点子任务表(关联节点与子任务)
单独存储节点下的子任务(避免主表JSON过于臃肿,也方便单独查询/修改子任务)。
CREATETABLE`workflow_template_subtask`(`subtask_id`BIGINTAUTO_INCREMENTPRIMARYKEYCOMMENT'子任务ID',`template_id`VARCHAR(64)NOTNULLCOMMENT'关联流程模板ID',`node_id`VARCHAR(64)NOTNULLCOMMENT'关联模板中的节点ID(如“n2”)',`subtask_name`VARCHAR(128)NOTNULLCOMMENT'子任务名称(如“埋点设计”)',`subtask_sort`INTDEFAULT0COMMENT'子任务排序(数字越小越靠前)',`is_required`TINYINTDEFAULT1COMMENT'是否必填:1=是,0=否',KEY`idx_template_node`(`template_id`,`node_id`)COMMENT'模板+节点的联合索引')ENGINE=InnoDBDEFAULTCHARSET=utf8mb4COMMENT='流程模板的节点子任务表';三、表结构说明
workflow_template的nodes字段示例:
存储节点的ID、名称、类型(开始/审批/并行)、画布位置(可视化编辑时的坐标):[{"node_id":"n1","node_name":"开始","node_type":"start","position":{"x":50,"y":100}},{"node_id":"n2","node_name":"产品评审","node_type":"task","position":{"x":200,"y":100}}]workflow_template的edges字段示例:
存储连线的ID、起点/终点节点ID、连线类型:[{"edge_id":"e1","source":"n1","target":"n2","line_type":"default"}]workflow_template_subtask的示例数据:subtask_id template_id node_id subtask_name subtask_sort is_required 1 temp-123 n2 埋点设计 1 1 2 temp-123 n2 AB方案设计 2 1
四、优势
- 主表用JSON存储节点/连线,适配可视化编辑的动态结构;
- 子任务单独建表,支持灵活增删改,也便于统计节点下的任务数量;
- 联合索引
idx_template_node确保查询某模板某节点的子任务时性能高效。
要不要我帮你整理一份这两张表的CRUD SQL语句示例(包含插入、查询模板+子任务的语句)?