职场新人工作流程可视化图表,快速上手岗位。

1 阅读10分钟

职场新人工作流程可视化系统

一、实际应用场景描述

场景:某数字文化公司新入职的运营专员小王,每天需要处理:

  • 内容选题 → 素材收集 → 设计制作 → 审核发布 → 数据复盘
  • 跨部门沟通(设计部/市场部/技术部)
  • 任务进度跟踪与汇报

当前痛点:

  1. 流程不透明,不知道下一步该找谁
  2. 任务卡在哪个环节不清楚
  3. 新人学习成本高,试错成本大
  4. 无法量化工作效率和瓶颈

二、引入痛点

graph TD A[新人入职] --> B{遇到问题} B --> C[问同事: 流程是什么?] B --> D[自己摸索: 看文档/试错] C --> E[同事忙, 解释不清] D --> F[走弯路, 效率低] E --> G[新人焦虑, 成长慢] F --> G G --> H[团队整体效率下降]

痛点分析表:

痛点 影响 解决思路 流程黑盒 新人不知从何下手 可视化流程图 责任模糊 推诿扯皮, 效率低下 明确节点负责人 进度不透明 无法预估完成时间 实时状态追踪 知识断层 依赖口口相传 结构化知识沉淀

三、核心逻辑讲解

3.1 系统架构

┌─────────────────────────────────────────────────────┐ │ 表现层 (View) │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ 流程图 │ │ 看板 │ │ 统计 │ │ 帮助 │ │ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ ├─────────────────────────────────────────────────────┤ │ 业务层 (Service) │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ 流程 │ │ 任务 │ │ 用户 │ │ 报告 │ │ │ │ 引擎 │ │ 管理 │ │ 权限 │ │ 生成 │ │ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ ├─────────────────────────────────────────────────────┤ │ 数据层 (Data) │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ 流程 │ │ 任务 │ │ 操作 │ │ │ │ 定义 │ │ 记录 │ │ 日志 │ │ │ └─────────┘ └─────────┘ └─────────┘ │ └─────────────────────────────────────────────────────┘

3.2 核心概念

  1. 工作流(Workflow):由多个任务节点组成的有向无环图(DAG)
  2. 任务节点(TaskNode):流程中的最小执行单元,包含负责人、时限、状态
  3. 流程实例(ProcessInstance):工作流的一次具体执行
  4. 状态机(StateMachine):管理任务在"待办→进行中→已完成→已归档"间的转换

四、代码模块化实现

4.1 项目结构

workflow_visualizer/ ├── main.py # 程序入口 ├── config/ │ └── settings.py # 配置文件 ├── models/ │ ├── init.py │ ├── task_node.py # 任务节点模型 │ ├── workflow.py # 工作流模型 │ └── process_instance.py # 流程实例模型 ├── services/ │ ├── init.py │ ├── workflow_engine.py # 工作流引擎 │ ├── task_service.py # 任务服务 │ └── report_service.py # 报告服务 ├── utils/ │ ├── init.py │ ├── visualizer.py # 可视化工具 │ └── helpers.py # 辅助函数 ├── data/ │ └── sample_data.py # 示例数据 ├── static/ # 静态资源(HTML模板) └── README.md # 项目说明

4.2 核心代码实现

"models/task_node.py" - 任务节点模型

""" 任务节点模型模块 功能:定义工作流中的基本执行单元 核心概念:每个节点代表一个具体的工作任务 """

from dataclasses import dataclass, field from enum import Enum, auto from typing import Optional, List import uuid from datetime import datetime

class NodeStatus(Enum): """任务节点状态枚举""" PENDING = auto() # 待办 IN_PROGRESS = auto() # 进行中 COMPLETED = auto() # 已完成 BLOCKED = auto() # 阻塞 ARCHIVED = auto() # 已归档

class NodeType(Enum): """任务类型枚举""" CONTENT = "内容创作" # 内容相关任务 DESIGN = "视觉设计" # 设计相关任务 REVIEW = "审核确认" # 审核类任务 COMMUNICATION = "跨部门沟通" # 沟通协调 DATA = "数据分析" # 数据复盘

@dataclass class TaskNode: """ 任务节点类

属性:
    node_id: 唯一标识符
    name: 任务名称
    description: 任务描述
    node_type: 任务类型
    assignee: 负责人(部门/角色)
    deadline: 截止时间
    status: 当前状态
    dependencies: 前置依赖节点ID列表
    output: 任务产出物描述
    created_at: 创建时间
    completed_at: 完成时间

方法:
    can_start: 检查任务是否可开始(所有依赖已完成)
    complete: 完成任务并更新状态
"""

# 基础信息
node_id: str = field(default_factory=lambda: str(uuid.uuid4())[:8])
name: str = ""
description: str = ""
node_type: NodeType = NodeType.CONTENT

# 人员与时间
assignee: str = ""  # 如: "运营部-小王", "设计部"
deadline: Optional[datetime] = None

# 状态管理
status: NodeStatus = NodeStatus.PENDING
dependencies: List[str] = field(default_factory=list)  # 依赖的node_id列表

# 产出与追踪
output: str = ""  # 任务完成后产出的内容/文件
created_at: datetime = field(default_factory=datetime.now)
completed_at: Optional[datetime] = None

def can_start(self, completed_nodes: set) -> bool:
    """
    判断任务是否可以开始
    
    参数:
        completed_nodes: 已完成节点的ID集合
        
    返回:
        bool: True表示所有依赖已完成,可以开始
        
    业务逻辑:
        只有当任务的所有前置依赖节点都已完成时,
        该任务才能进入"进行中"状态
    """
    if not self.dependencies:
        return True  # 无依赖任务可直接开始
    return all(dep_id in completed_nodes for dep_id in self.dependencies)

def complete(self, output_content: str = "") -> None:
    """
    完成任务
    
    参数:
        output_content: 任务产出内容
        
    业务逻辑:
        1. 验证当前状态是否为"进行中"
        2. 更新状态为"已完成"
        3. 记录完成时间和产出物
    """
    if self.status != NodeStatus.IN_PROGRESS:
        raise ValueError(f"任务 {self.name} 当前状态为 {self.status.name},无法直接完成")
    
    self.status = NodeStatus.COMPLETED
    self.completed_at = datetime.now()
    if output_content:
        self.output = output_content

def to_dict(self) -> dict:
    """转换为字典,用于JSON序列化"""
    return {
        "node_id": self.node_id,
        "name": self.name,
        "description": self.description,
        "type": self.node_type.value,
        "assignee": self.assignee,
        "deadline": self.deadline.isoformat() if self.deadline else None,
        "status": self.status.name,
        "dependencies": self.dependencies,
        "output": self.output,
        "created_at": self.created_at.isoformat(),
        "completed_at": self.completed_at.isoformat() if self.completed_at else None
    }

"models/workflow.py" - 工作流模型

""" 工作流模型模块 功能:定义完整的工作流程结构和元数据 核心概念:工作流是任务节点的有向无环图(DAG) """

from dataclasses import dataclass, field from typing import Dict, List, Optional from datetime import datetime import uuid

from models.task_node import TaskNode, NodeStatus

@dataclass class Workflow: """ 工作流类

属性:
    workflow_id: 工作流唯一标识
    name: 工作流名称
    description: 工作流描述
    nodes: 任务节点字典 {node_id: TaskNode}
    edges: 边列表 [(from_node_id, to_node_id), ...]
    version: 版本号
    created_by: 创建者
    created_at: 创建时间
    tags: 标签列表(用于分类检索)

方法:
    add_node: 添加任务节点
    add_edge: 添加依赖关系
    get_start_nodes: 获取起始节点(无依赖的任务)
    validate: 验证工作流是否有效(DAG检查)
    visualize_mermaid: 生成Mermaid流程图代码
"""

workflow_id: str = field(default_factory=lambda: f"WF-{uuid.uuid4().hex[:6].upper()}")
name: str = ""
description: str = ""
nodes: Dict[str, TaskNode] = field(default_factory=dict)
edges: List[tuple] = field(default_factory=list)
version: str = "1.0"
created_by: str = ""
created_at: datetime = field(default_factory=datetime.now)
tags: List[str] = field(default_factory=list)

def add_node(self, node: TaskNode) -> None:
    """
    添加任务节点到工作流
    
    参数:
        node: TaskNode实例
        
    异常:
        ValueError: 节点ID已存在时抛出
    """
    if node.node_id in self.nodes:
        raise ValueError(f"节点ID {node.node_id} 已存在")
    self.nodes[node.node_id] = node

def add_edge(self, from_node_id: str, to_node_id: str) -> None:
    """
    添加节点间的依赖关系(边)
    
    参数:
        from_node_id: 前置节点ID
        to_node_id: 后置节点ID
        
    业务逻辑:
        1. 验证两个节点都存在
        2. 防止循环依赖
        3. 添加到edges列表,并更新后置节点的dependencies
    """
    if from_node_id not in self.nodes:
        raise ValueError(f"前置节点 {from_node_id} 不存在")
    if to_node_id not in self.nodes:
        raise ValueError(f"后置节点 {to_node_id} 不存在")
    
    # 防止重复添加
    if (from_node_id, to_node_id) not in self.edges:
        self.edges.append((from_node_id, to_node_id))
        self.nodes[to_node_id].dependencies.append(from_node_id)

def get_start_nodes(self) -> List[TaskNode]:
    """
    获取起始节点(没有任何依赖的任务)
    
    返回:
        List[TaskNode]: 起始节点列表
        
    应用场景:
        用于确定工作流的入口点,新人可以从这里开始执行
    """
    start_nodes = []
    for node in self.nodes.values():
        if not node.dependencies:
            start_nodes.append(node)
    return start_nodes

def validate(self) -> tuple:
    """
    验证工作流的有效性
    
    返回:
        tuple: (is_valid: bool, errors: List[str])
        
    验证逻辑:
        1. 至少有一个节点
        2. 无循环依赖
        3. 所有边的节点都存在
    """
    errors = []
    
    # 检查是否有节点
    if not self.nodes:
        errors.append("工作流必须至少包含一个任务节点")
        return False, errors
    
    # 检查循环依赖(DFS检测)
    visited = set()
    rec_stack = set()
    
    def has_cycle(node_id: str) -> bool:
        visited.add(node_id)
        rec_stack.add(node_id)
        
        for _, to_id in self.edges:
            if to_id == node_id:
                continue
            if to_id not in self.nodes:
                errors.append(f"边引用了不存在的节点: {to_id}")
                return True
            if to_id in rec_stack:
                errors.append(f"检测到循环依赖: 包含节点 {node_id} 和 {to_id}")
                return True
            if to_id not in visited and has_cycle(to_id):
                return True
        
        rec_stack.remove(node_id)
        return False
    
    for node_id in self.nodes:
        if node_id not in visited:
            if has_cycle(node_id):
                break
    
    is_valid = len(errors) == 0
    return is_valid, errors

def visualize_mermaid(self) -> str:
    """
    生成Mermaid格式的流程图代码
    
    返回:
        str: Mermaid流程图代码
        
    应用场景:
        可直接粘贴到支持Mermaid的工具(Markdown编辑器、Notion等)
        生成可视化流程图
    """
    lines = ["graph TD"]
    
    # 状态颜色映射
    color_map = {
        NodeStatus.PENDING: "#FFE4B5",    # 待办-浅橙
        NodeStatus.IN_PROGRESS: "#87CEEB", # 进行中-天蓝
        NodeStatus.COMPLETED: "#90EE90",   # 已完成-浅绿
        NodeStatus.BLOCKED: "#FFA07A",     # 阻塞-浅红
        NodeStatus.ARCHIVED: "#D3D3D3"     # 已归档-灰色
    }
    
    # 添加节点定义
    for node in self.nodes.values():
        # 转义特殊字符
        safe_name = node.name.replace('"', '\\"')
        safe_desc = node.description.replace('"', '\\"')[:30] + "..." if len(node.description) > 30 else node.description.replace('"', '\\"')
        
        # 节点样式
        color = color_map.get(node.status, "#FFFFFF")
        node_label = f'{node.node_id}["<b>{safe_name}</b><br/>{node.node_type.value}<br/>{safe_desc}"]'
        node_style = f'style {node.node_id} fill:{color},stroke:#333,stroke-width:2px'
        
        lines.append(f"    {node_label}")
        lines.append(f"    {node_style}")
    
    # 添加边定义
    for from_id, to_id in self.edges:
        lines.append(f"    {from_id} --> {to_id}")
    
    return "\n".join(lines)

def to_dict(self) -> dict:
    """转换为字典,用于JSON序列化"""
    return {
        "workflow_id": self.workflow_id,
        "name": self.name,
        "description": self.description,
        "version": self.version,
        "created_by": self.created_by,
        "created_at": self.created_at.isoformat(),
        "tags": self.tags,
        "nodes": {k: v.to_dict() for k, v in self.nodes.items()},
        "edges": self.edges,
        "mermaid_code": self.visualize_mermaid()
    }

"services/workflow_engine.py" - 工作流引擎

""" 工作流引擎模块 功能:驱动工作流实例的执行和管理 核心概念:引擎负责状态流转、任务调度、事件处理 """

from dataclasses import dataclass, field from typing import Dict, List, Optional, Callable from datetime import datetime import uuid import copy

from models.task_node import TaskNode, NodeStatus, NodeType from models.workflow import Workflow from models.process_instance import ProcessInstance

class WorkflowEngine: """ 工作流引擎类

职责:
    1. 创建工作流实例
    2. 推进工作流执行
    3. 处理任务状态变更
    4. 触发事件回调
    5. 生成执行报告

设计模式:
    - 观察者模式: 通过回调函数通知状态变化
    - 命令模式: 将操作封装为可撤销的命令
"""

def __init__(self):
    self._workflows: Dict[str, Workflow] = {}  # 注册的工作流模板
    self._instances: Dict[str, ProcessInstance] = {}  # 运行中的实例
    self._event_handlers: Dict[str, List[Callable]] = {
        "task_started": [],
        "task_completed": [],
        "workflow_completed": []
    }

def register_workflow(self, workflow: Workflow) -> None:
    """
    注册工作流模板
    
    参数:
        workflow: 要注册的工作流
    """
    is_valid, errors = workflow.validate()
    if not is_valid:
        raise ValueError(f"工作流验证失败: {'; '.join(errors)}")
    
    self._workflows[workflow.workflow_id] = workflow
    print(f"✅ 工作流 '{workflow.name}' 已注册 (ID: {workflow.workflow_id})")

def create_instance(self, workflow_id: str, instance_name: str = "", 
                    creator: str = "系统") -> ProcessInstance:
    """
    根据工作流模板创建实例
    
    参数:
        workflow_id: 工作流模板ID
        instance_name: 实例名称(可选)
        creator: 创建者
        
    返回:
        ProcessInstance: 新创建的流程实例
    """
    if workflow_id not in self._workflows:
        raise ValueError(f"工作流模板 {workflow_id} 未找到")
    
    template = self._workflows[workflow_id]
    
    # 深拷贝节点,避免修改模板
    instance_nodes = {}
    for node_id, node in template.nodes.items():
        new_node = copy.deepcopy(node)
        new_node.status = NodeStatus.PENDING
        new_node.output = ""
        new_node.completed_at = None
        instance_nodes[node_id] = new_node
    
    # 创建实例
    instance = ProcessInstance(
        instance_id=f"PI-{uuid.uuid4().hex[:8].upper()}",
        workflow_id=workflow_id,
        workflow_name=template.name,
        name=instance_name or f"{template.name} - 实例",
        nodes=instance_nodes,
        creator=creator
    )
    
    self._instances[instance.instance_id] = instance
    print(f"🚀 流程实例已创建: {instance.instance_id}")
    
    return instance

def get_available_tasks(self, instance_id: str) -> List[TaskNode]:
    """
    获取当前可执行的任务列表
    
    参数:
        instance_id: 流程实例ID
        
    返回:
        List[TaskNode]: 可开始执行的任务列表
        
    业务逻辑:
        1. 获取所有已完成的任务
        2. 遍历所有待办任务
        3. 检查其所有依赖是否已完成
    """
    if instance_id not in self._instances:
        raise ValueError(f"流程实例 {instance_id} 未找到")
    
    instance = self._instances[instance_id]
    completed_ids = instance.get_completed_node_ids()
    
    available = []
    for node in instance.nodes.values():
        if node.status == NodeStatus.PENDING and node.can_start(completed_ids):
            available.append(node)
    
    return available

def start_task(self, instance_id: str, node_id: str, 
               executor: str = "") -> TaskNode:
    """
    开始执行任务
    
    参数:
        instance_id: 流程实例ID
        node_id: 要开始的节点ID
        executor: 执行人
        
    返回:
        TaskNode: 更新后的任务节点
    """
    if instance_id not in self._instances:
        raise ValueError(f"流程实例 {instance_id} 未找到")
    
    instance = self._instances[instance_id]
    
    if node_id not in instance.nodes:
        raise ValueError(f"节点 {node_id} 不在流程实例中")
    
    node = instance.nodes[node_id]
    
    if node.status != NodeStatus.PENDING:
        raise ValueError(f"任务 {node.name} 当前状态为 {node.status.name},无法开始")
    
    # 检查依赖
    completed_ids = instance.get_completed_node_ids()
    if not node.can_start(completed_ids):
        missing = [d for d in node.dependencies if d not in completed_ids]
        raise ValueError(f"任务 {node.name} 的依赖未完成: {missing}")
    
    # 更新状态
    node.status = NodeStatus.IN_PROGRESS
    if executor:
        node.assignee = executor
    
    # 触发事件
    self._trigger_event("task_started", instance, node)
    
    print(f"▶️ 任务已开始: {node.name} (执行人: {node.assignee})")
    return node

def complete_task(self, instance_id: str, node_id: str, 
                  output: str = "") -> TaskNode:
    """
    完成任务
    
    参数:
        instance_id: 流程实例ID
        node_id: 要完成的节点ID
        output: 任务产出内容
        
    返回:
        TaskNode: 更新后的任务节点
    """
    if instance_id not in self._instances:
        raise ValueError(f"流程实例 {instance_id} 未找到")
    
    instance = self._instances[instance_id]
    
    if node_id not in instance.nodes:
        raise ValueError(f"节点 {node_id} 不在流程实例中")
    
    node = instance.nodes[node_id]
    node.complete(output)
    
    # 触发事件
    self._trigger_event("task_completed", instance, node)
    
    # 检查工作流是否完成
    if instance.is_completed():
        self._trigger_event("workflow_completed", instance, None)
        print(f"🎉 工作流已完成: {instance.name}")
    
    print(f"✅ 任务已完成: {node.name}")
    return node

def get_instance_status(self, instance_id: str) -> dict:
    """
    获取流程实例状态概览
    
    参数:
        instance_id: 流程实例ID
        
    返回:
        dict: 状态概览
    """
    if instance_id not in self._instances:
        raise ValueError(f"流程实例 {instance_id} 未找到")
    
    instance = self._instances[instance_id]
    return instance.get_status_summary()

def register_event_handler(self, event_type: str, handler: Callable) -> None:
    """
    注册事件处理器
    
    参数:
        event_type: 事件类型 ("task_started", "task_completed", "workflow_completed")
        handler: 处理函数
    """
    if event_type in self._event_handlers:
        self._event_handlers[event_type].append(handler)

def _trigger_event(self, event_type: str, instance: ProcessInstance, 
                   node: Optional[TaskNode]) -> None:
    """触发事件,调用所有注册的handler"""
    for handler in self._event_handlers.get(event_type, []):
        try:
            handler(instance, node)
        except Exception as e:
            print(f"⚠️ 事件处理器出错: {e}")

def list_instances(self) -> List[dict]:
    """列出所有流程实例"""
    return [
        {
            "instance_id": inst.instance_id,
            "name": inst.name,
            "workflow_name": inst.workflow_name,
            "status": inst.status.name,
            "progress": inst.progress_percentage,
            "creator": inst.creator
        }
        for inst in self._instances.values()
    ]

"services/report_service.py" - 报告服务

""" 报告服务模块 功能:生成各类分析报告,帮助新人学习和管理者决策 """

from typing import Dict, List from collections import defaultdict from datetime import datetime, timedelta

from models.process_instance import ProcessInstance

class ReportService: """ 报告服务类

提供以下报告:
    1. 新人上手报告 - 展示标准流程和关键节点
    2. 工作效率报告 - 统计任务耗时和瓶颈
    3. 团队协作报告 - 展示跨部门协作情况
"""

def __init__(self, engine):
    self.engine = engine

def generate_onboarding_report(self, workflow_id: str) -> str:
    """
    生成新人上手指南报告
    
    参数:
        workflow_id: 工作流模板ID
        
    返回:
        str: Markdown格式的报告
    """
    workflow = self.engine._workflows.get(workflow_id)
    if not workflow:
        return "工作流未找到"
    
    lines = [
        f"# 📚 {workflow.name} - 新人上手指南",
        "",
    利用AI解决实际问题,如果你觉得这个工具好用,欢迎关注长安牧笛!