AI绘制流程图

基于Vue3和通义千问的AI流程图绘制工具实践

前言

在软件开发过程中,流程图是一个非常重要的工具,它可以帮助我们更好地理解和设计系统。本文将介绍一个基于Vue3和通义千问AI的流程图自动绘制工具的实现过程。

项目概述

这是一个将自然语言转换为流程图的Web应用程序。用户只需输入文本描述,系统就能自动生成对应的流程图,大大提升了流程图创建的效率。

主要特性

  • 🚀 基于自然语言生成流程图
  • 📊 使用Mermaid.js作为图表渲染引擎
  • 🤖 集成通义千问大语言模型
  • 💡 支持实时预览和优化
  • 📥 支持导出配置文件和图片
  • 🎨 基于Tailwind CSS的现代UI设计

技术栈详解

1. 前端框架 - Vue 3

项目采用Vue 3作为前端框架,利用其组合式API(Composition API)提供更好的代码组织和复用能力。主要使用了以下特性:

  • 组合式API
  • 响应式系统
  • 组件化开发

2. UI框架 - Tailwind CSS

使用Tailwind CSS实现了响应式设计和现代化的UI界面:

javascript:e:\workspace\Git\ai-drawing-process-diagram-master\code\tailwind.config.js 复制代码
module.exports = {
  content: [
    "./index.html",
    "./src/**/*.{vue,js,ts,jsx,tsx}",
  ],
  darkMode: 'class',
  theme: {
    extend: {
      colors: {
        primary: '#4F46E5',
        secondary: '#6366F1'
      }
    }
  }
}

3. 消息通知系统

实现了一个优雅的消息通知组件,支持多种类型的消息提示:

  • 成功提示
  • 错误提示
  • 警告提示
  • 普通信息提示

4. Mermaid.js集成

使用Mermaid.js作为图表渲染引擎,支持多种图表类型:

  • 流程图
  • 时序图
  • 甘特图
  • 类图等

核心功能实现

1. AI文本解析

通过调用通义千问API,将用户输入的自然语言转换为结构化的图表描述。

2. 实时预览

实现了图表的实时预览功能,用户可以即时看到修改效果。

3. 导出功能

支持多种导出格式:

  • PNG图片
  • SVG矢量图
  • Mermaid源代码

项目亮点

  1. 优雅的代码组织

    • 采用模块化设计
    • 清晰的代码结构
    • 良好的代码复用
  2. 现代化的开发工具链

    • Vue CLI
    • PostCSS
    • Tailwind CSS
    • ESLint
  3. 用户体验优化

    • 响应式设计
    • 深色模式支持
    • 流畅的动画效果

未来展望

项目计划添加以下功能:

  • 支持更多图表类型
  • 添加历史记录功能
  • 优化生成质量
  • 支持模板系统
  • 增加协作功能

总结

这个项目展示了如何将现代前端技术与AI能力相结合,创造出实用的开发工具。通过Vue 3的组合式API和Tailwind CSS的原子化CSS,我们实现了一个既实用又美观的流程图绘制工具。

参考资料

核心源码

code/src/App.vue

html 复制代码
<script setup>
import {ref} from 'vue';
import FlowChart from './components/FlowChart.vue';
import {callGpt} from '@/utils/util';
import Message from '@/utils/message';

const description = ref('');
const isGenerating = ref(false);
const flowChartRef = ref();
const flowData = ref('');

// 处理流程图生成
const handleGenerate = async () => {
  if (!description.value.trim()) {
    Message.warning('请输入流程描述');
    return;
  }
  
  isGenerating.value = true;
  flowData.value = ''; // 清空现有流程图
  
  try {
    const prompt = `请根据以下描述生成一个 Mermaid 流程图:${description.value}
    要求:
    1. 使用 graph LR 方向
    2. 使用中文描述
    3. 只返回 Mermaid 格式的代码,不要其他解释
    4. 合理使用 subgraph 进行分组
    5. 使用合适的节点形状和连接线样式`;
    
    await callGpt(
      prompt,
      () => {},
      (text) => {
        // 处理返回的文本,提取 Mermaid 内容
        const matchText = "```mermaid";
        if (text.startsWith(matchText)) {
          let indexOf = text.indexOf("```", matchText.length + 1);
          if (indexOf > -1) {
            flowData.value = text.substring(matchText.length, indexOf);
          }
        }
        isGenerating.value = false;
        if (flowData.value) {
          Message.success('流程图生成完成');
        } else {
          Message.error('生成的内容格式不正确');
        }
      }
    );
  } catch (error) {
    console.error('生成流程图失败:', error);
    Message.error('生成流程图失败,请重试');
    isGenerating.value = false;
  }
};

// 导出配置文件
const exportConfig = () => {
  if (isGenerating.value || !flowData.value) return;
  flowChartRef.value?.exportConfig();
};

// 导出PNG图片
const exportToPNG = () => {
  if (isGenerating.value || !flowData.value) return;
  flowChartRef.value?.exportToPNG();
};
</script>

<template>
  <div class="min-h-screen bg-gray-50">
    <div class="max-w-7xl mx-auto">
      <nav class="h-16 bg-white shadow-sm flex items-center justify-between px-8">
        <div class="flex items-center space-x-2">
          <span class="text-2xl font-['Pacifico'] text-primary">logo</span>
          <span class="text-lg font-medium">AI绘制流程图</span>
        </div>
        <button class="w-10 h-10 rounded-button flex items-center justify-center hover:bg-gray-100 transition-colors">
          <i class="fas fa-sun text-gray-600"></i>
        </button>
      </nav>

      <main class="py-12">
        <div class="mx-auto">
          <div class="bg-white rounded-lg shadow-sm p-8">
            <div class="space-y-6">
              <div>
                <label for="description" class="block text-sm font-medium text-gray-700 mb-2">
                  流程描述
                </label>
                <textarea
                  id="description"
                  v-model="description"
                  rows="4"
                  class="block w-full rounded-md border-gray-300 shadow-sm focus:border-primary focus:ring-primary sm:text-sm resize-none p-4 my-2"
                  placeholder="请输入您想要绘制的流程描述,例如:'一个用户注册流程,包含填写信息、验证邮箱和完成注册三个步骤'"
                ></textarea>
              </div>
              
              <div class="flex justify-between items-center">
                <div class="space-x-3">
                  <button
                    v-if="!isGenerating && flowData"
                    class="inline-flex items-center px-4 py-2 rounded-md text-primary border border-primary text-sm font-medium hover:bg-primary/5"
                    @click="exportConfig"
                  >
                    <i class="fas fa-download mr-2"></i>
                    导出配置
                  </button>
                  <button
                    v-if="!isGenerating && flowData"
                    class="inline-flex items-center px-4 py-2 rounded-md text-primary border border-primary text-sm font-medium hover:bg-primary/5"
                    @click="exportToPNG"
                  >
                    <i class="fas fa-image mr-2"></i>
                    导出图片
                  </button>
                </div>
                <button
                  :class="[
                    'inline-flex items-center px-6 py-2.5 rounded-md text-white text-sm font-medium shadow-sm',
                    isGenerating ? 'bg-primary/70 cursor-not-allowed' : 'bg-primary hover:bg-primary/90'
                  ]"
                  :disabled="isGenerating"
                  @click="handleGenerate"
                >
                  <i class="fas fa-magic mr-2"></i>
                  {{ isGenerating ? '生成中...' : '开始生成' }}
                </button>
              </div>

              <div class="mt-6" v-if="!isGenerating && flowData">
                <h3 class="text-lg font-medium text-gray-900 mb-4">生成的流程图</h3>
                <FlowChart 
                  ref="flowChartRef"
                  :flow-data="flowData"
                />
              </div>
            </div>
          </div>

          <div class="mt-12 bg-white rounded-lg shadow-sm p-8">
            <h2 class="text-xl font-medium mb-6">使用说明 & 实现原理</h2>
            <div class="space-y-4 text-gray-600">
              <div class="flex items-start space-x-3">
                <div class="w-6 h-6 rounded-full bg-primary/10 flex items-center justify-center flex-shrink-0 mt-0.5">
                  <i class="fas fa-lightbulb text-sm text-primary"></i>
                </div>
                <p>输入您想要绘制的流程描述,系统会通过 AI 分析您的描述,自动生成符合 Mermaid 语法的流程图代码。支持复杂的业务流程、系统架构等多种场景。</p>
              </div>
              <div class="flex items-start space-x-3">
                <div class="w-6 h-6 rounded-full bg-primary/10 flex items-center justify-center flex-shrink-0 mt-0.5">
                  <i class="fas fa-code text-sm text-primary"></i>
                </div>
                <p>系统使用 Mermaid.js 作为流程图渲染引擎,通过 AI 生成标准的 Mermaid 图表代码,确保流程图的专业性和可维护性。支持导出配置文件和图片,方便进一步编辑和分享。</p>
              </div>
              <div class="flex items-start space-x-3">
                <div class="w-6 h-6 rounded-full bg-primary/10 flex items-center justify-center flex-shrink-0 mt-0.5">
                  <i class="fas fa-robot text-sm text-primary"></i>
                </div>
                <p>后端采用通义千问大语言模型,结合优化的 Prompt 策略,能够准确理解用户意图,生成结构清晰、层次分明的流程图,支持中文描述直接转换为专业流程图。</p>
              </div>
            </div>
          </div>
        </div>
      </main>
    </div>
  </div>
</template>

<style>
body {
  min-height: 100vh;
}

#app {
  min-height: 100vh;
}

body::-webkit-scrollbar {
  width: 15px;
}

body::-webkit-scrollbar-track {
  background: #f1f5f9;
  border-radius: 8px;
}

body::-webkit-scrollbar-thumb {
  background: #6366f1;
  border-radius: 8px;
  border: 2px solid #f1f5f9;
}

body::-webkit-scrollbar-thumb:hover {
  background: #4f46e5;
}

textarea {
  border: 1px solid #e5e7eb;
  padding: 1rem 1.25rem;
  margin: 0.75rem 0;
  line-height: 1.6;
  font-size: 0.975rem;
  transition: all 0.2s ease-in-out;
  background-color: #f9fafb;
}

textarea:focus {
  outline: none;
  border-color: #4F46E5;
  box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1);
  background-color: #ffffff;
}

textarea::placeholder {
  color: #9ca3af;
  font-size: 0.875rem;
}
</style>

code/src/components/FlowChart.vue

html 复制代码
<script setup>
import { onMounted, ref, defineProps, defineExpose } from 'vue'
import mermaid from 'mermaid'

const props = defineProps({
  flowData: {
    type: String,
    default: ''
  }
});

const flowChartRef = ref();

// 初始化 mermaid 配置
mermaid.initialize({
  startOnLoad: true,
  theme: 'neutral',
  securityLevel: 'loose',
  flowchart: {
    curve: 'basis',
    padding: 15,
    nodeSpacing: 50,
    rankSpacing: 50,
    htmlLabels: true,
    diagramPadding: 8,
  }
});

// 导出配置文件方法
const exportConfig = () => {
  if (!props.flowData) return;
  const blob = new Blob([props.flowData], { type: 'text/plain' });
  const url = URL.createObjectURL(blob);
  const link = document.createElement('a');
  link.href = url;
  link.download = 'flowchart.mmd';
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  URL.revokeObjectURL(url);
};

// 导出PNG图片方法
const exportToPNG = () => {
  const svg = flowChartRef.value.querySelector('svg')
  const svgData = new XMLSerializer().serializeToString(svg)
  const bbox = svg.getBBox()
  const width = bbox.width * 1.25
  const height = bbox.height * 1.25

  const newSvg = `
    <svg width="${width}" height="${height}" viewBox="${0} ${0} ${width} ${height}" xmlns="http://www.w3.org/2000/svg">
      <rect x="${0}" y="${0}" width="${width}" height="${height}" fill="white"/>
      ${svgData}
    </svg>
  `

  const canvas = document.createElement('canvas')
  const ctx = canvas.getContext('2d')
  const img = new Image()

  img.onload = () => {
    canvas.width = width * 2
    canvas.height = height * 2
    ctx.scale(2, 2)
    ctx.drawImage(img, 0, 0, width, height)

    const link = document.createElement('a')
    link.download = '流程图.png'
    link.href = canvas.toDataURL('image/png')
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
  }

  img.src = 'data:image/svg+xml;base64,' + btoa(unescape(encodeURIComponent(newSvg)))
}

onMounted(() => {
  mermaid.render('mermaid-diagram', `${props.flowData}`).then((result) => {
    if (flowChartRef.value) {
      flowChartRef.value.innerHTML = result.svg
    }
  })
})

// 暴露方法给父组件
defineExpose({
  exportConfig,
  exportToPNG,
});
</script>

<template>
  <div class="flow-chart-container">
    <div id="flow-chart" ref="flowChartRef"></div>
  </div>
</template>

<style scoped>
.flow-chart-container {
  background-color: white;
  padding: 1.5rem;
  border-radius: 0.75rem;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  overflow-x: auto;
}

:deep(.node rect) {
  fill: #fff;
  stroke: #333;
  stroke-width: 2px;
}

:deep(.edgeLabel) {
  background-color: #fff;
  padding: 4px;
  border-radius: 4px;
}

:deep(.cluster rect) {
  fill: #f5f5f5;
  stroke: #ddd;
  stroke-width: 1px;
  rx: 5px;
  ry: 5px;
}
</style>

效果展示

系统首页

绘制展示

源码下载

AI绘制流程图

相关推荐
huang_xiaoen1 分钟前
试一下阿里云新出的mcp服务
人工智能·阿里云·ai·云计算·mcp
Jamence28 分钟前
多模态大语言模型arxiv论文略读(二十一)
人工智能·语言模型·自然语言处理
小白学C++.29 分钟前
大模型论文:Language Models are Unsupervised Multitask Learners(GPT2)
人工智能·语言模型·自然语言处理
Steve lu34 分钟前
PyTorch逻辑回归总结
人工智能·pytorch·python·深度学习·逻辑回归·原力计划
Steve lu41 分钟前
pytorch实现逻辑回归
人工智能·pytorch·python·深度学习·机器学习·自然语言处理·逻辑回归
xcSpark1 小时前
Python基础入门(二)
开发语言·人工智能·python
驼驼学编程1 小时前
目标检测与分割:深度学习在视觉中的应用
人工智能·深度学习·目标检测·计算机视觉
行走的bug...1 小时前
sklearn估计器和变换器共有的一些方法 待更新
人工智能·算法·sklearn
LemonDu2 小时前
Cursor入门教程-JetBrains过度向
人工智能·后端
程序员小灰2 小时前
漫画:什么是MCP协议?
人工智能·aigc·mcp