文章

Cursor 结合 PlantUML 绘制架构图实践

见字如面,与大家分享实践中的经验与思考。

在软件开发过程中,图表是表达系统架构、流程和关系的强大工具。传统上,我们绘制这些图表需要专门的工具和相当的时间投入。然而,随着 AIGC 的发展,我们现在可以通过 AI 结合PlantUML 快速生成高质量的技术图表。

作为技术Leader或架构师,我们经常需要:

  • 向团队和业务方清晰地传达系统设计

  • 快速迭代架构方案

  • 在不同抽象层次上展示系统

  • 确保文档与代码保持一致

Cursor 作为一个集成了强大 AI 能力的 IDE,可以通过与 PlantUML 的结合,帮助我们实现这些需求。只需简单描述需求,AI 就能生成对应的 PlantUML 代码,极大地提升了文档创建的效率和质量。这种方式不仅节省时间,还能让我们专注于思考设计本身,而非绘图工具的使用细节。

对于想深入了解如何通过 PlantUML 类图生成企业级 SQL 的话,可以阅读《Cursor + PlantUML:告别手写 SQL 的高效工作流》。

实操演示

本节将展示如何使用 Cursor 结合 AI 能力生成各种常见的技术图表,大部分示例都包括:

  • 向AI提供的提示词

  • 生成的PlantUML代码

  • 最终的图表效果

image-20250420下午72803936

01 认证鉴权模型概念图

提示词:

我需要绘制一个基于RBAC(基于角色的访问控制)的认证鉴权模型概念图,使用PlantUML的类图语法,要求布局清晰、层次分明。
​
系统包含以下核心实体:
1. 用户(User):包含用户ID、用户名、密码(加密存储)、邮箱、手机号、状态(启用/禁用)、创建时间
2. 角色(Role):包含角色ID、角色名称、角色描述、创建时间
3. 权限(Permission):包含权限ID、权限代码、权限名称、资源类型、资源路径、操作类型(如GET、POST等)
4. 用户组(UserGroup):包含组ID、组名称、组描述
5. 租户(Tenant):包含租户ID、租户名称、租户状态
​
实体间关系:
- 用户与角色是多对多关系,使用实体 UserRole
- 角色与权限是多对多关系,使用实体 UserPermission
- 用户与用户组是多对多关系,使用实体 UserGroupUser
- 用户组与角色是多对多关系,使用使用 UserGroupRole
- 用户、角色、权限、用户组都属于某个租户(多租户系统)
​
输出要求:
1. 严格遵循单向关系原则:每对实体间只使用一个方向的关系箭头,避免双向关系造成的混乱,同时避免实体间关系的重复
  - `--` 基本关联关系
  - `<--` 或 `-->` 带方向的关联
  - `--o` 或 `o--` 聚合关系(空心菱形)
  - `--*` 或 `*--` 组合关系(实心菱形)
  - `--|>` 继承关系
  - `..|>` 实现关系
2. 明确标注实体间的数量关系(如:`"1" -- "n"`,`"0..1" -- "*"`,`"1" -- "0..*"` )
3. 使用简洁的自定义颜色方案(使用!define和skinparam),实体使用蓝色#3498DB、边框使用黑色#2C3E50、关系连线使用红色#E74C3C
4. 保证 PlanUML代码简洁,可阅读性好

AI会生成类似的结果:

@startuml RBAC认证鉴权模型
​
!define TABLE_BORDER_COLOR #2C3E50
!define ENTITY_COLOR #3498DB
!define RELATIONSHIP_COLOR #E74C3C
​
skinparam class {
  BackgroundColor ENTITY_COLOR
  BorderColor TABLE_BORDER_COLOR
  ArrowColor RELATIONSHIP_COLOR
}
​
class User {
  +userId: String
  +username: String
  +password: String (encrypted)
  +email: String
  +phoneNumber: String
  +status: Enum (ENABLED/DISABLED)
  +createdTime: DateTime
}
​
class Role {
  +roleId: String
  +roleName: String
  +description: String
  +createdTime: DateTime
}
​
class Permission {
  +permissionId: String
  +permissionCode: String
  +permissionName: String
  +resourceType: String
  +resourcePath: String
  +operationType: String (GET/POST/etc)
}
​
class UserGroup {
  +groupId: String
  +groupName: String
  +description: String
}
​
class Tenant {
  +tenantId: String
  +tenantName: String
  +status: Enum (ACTIVE/INACTIVE)
}
​
class UserRole {
  +userId: String
  +roleId: String
}
​
class RolePermission {
  +roleId: String
  +permissionId: String
}
​
class UserGroupUser {
  +groupId: String
  +userId: String
}
​
class UserGroupRole {
  +groupId: String
  +roleId: String
}
​
User "1" -- "0..*" UserRole
Role "1" -- "0..*" UserRole
Role "1" -- "0..*" RolePermission
Permission "1" -- "0..*" RolePermission
User "1" -- "0..*" UserGroupUser
UserGroup "1" -- "0..*" UserGroupUser
UserGroup "1" -- "0..*" UserGroupRole
Role "1" -- "0..*" UserGroupRole
​
Tenant "1" -- "0..*" User
Tenant "1" -- "0..*" Role
Tenant "1" -- "0..*" Permission
Tenant "1" -- "0..*" UserGroup
​
note bottom of User
  用户实体是系统中的账号,
  可以拥有多个角色和所属多个用户组
end note
​
note bottom of Role
  角色是权限的集合,
  用户通过角色获得相应的权限
end note
​
note right of Tenant
  多租户设计,所有实体都属于某个租户,
  实现租户间的数据隔离
end note
​
@enduml

image-20250420下午90602052

02 用户登录注册活动图

提示词:

请使用PlantUML 活动图(Activity Diagram)语法绘制一个完整的用户登录注册流程图,包含以下要素:
​
1. 用户可以通过两种方式注册:
   - 邮箱注册:需要邮箱验证
   - 手机号注册:需要短信验证码
​
2. 用户登录支持以下方式:
   - 账号密码登录(账号可以是用户名、邮箱或手机号)
   - 手机验证码登录
   - 第三方OAuth登录(微信、支付宝)
   - 支持双因素认证
​
3. 密码错误次数限制与账号锁定机制
4. 登录成功后的JWT签发流程
5. 密码找回流程
​
输出要求:
1. 不同的流程使用partition进行区分
2. 展示完整的流程,包括分支、判断和出错处理路径
3. 保证PlantUML最新语法的正确。

AI 生成类似的结果:

@startuml 用户认证系统流程图
​
skinparam backgroundColor white
skinparam ActivityBackgroundColor #FEFECE
skinparam ActivityBorderColor #D3D3D3
skinparam ArrowColor #666666
skinparam ActivityDiamondBackgroundColor #FEFECE
skinparam ActivityDiamondBorderColor #666666
​
title 用户认证系统 - 登录注册流程图
​
|用户|
start
​
:用户访问系统;
​
|系统|
if (用户是否已有账号?) then (是)
  #LightBlue:进入登录流程;
else (否)
  #LightGreen:进入注册流程;
endif
​
partition "注册流程" {
  #LightGreen:选择注册方式;
​
  if (注册方式?) then (邮箱注册)
    :填写邮箱和密码;
    :系统生成验证链接;
    :发送验证邮件;
    :用户点击邮件验证链接;
    if (验证链接有效?) then (是)
      :激活账号;
    else (否)
      :提示验证失败;
      :重新发送验证邮件;
      note right: 可重试3次
    endif
  else (手机号注册)
    :填写手机号和密码;
    :生成短信验证码;
    :发送短信验证码;
    :用户输入收到的验证码;
    if (验证码正确?) then (是)
      :激活账号;
    else (否)
      :提示验证码错误;
      :允许重新获取验证码;
      note right: 每日限制5次
    endif
  endif
​
  :创建用户账号;
  :存储加密后的密码;
  :完成注册流程;
}
​
partition "登录流程" {
  #LightBlue:选择登录方式;
​
  if (登录方式?) then (账号密码登录)
    :输入账号(用户名/邮箱/手机号);
    :输入密码;
    :验证账号密码;
    if (账号是否锁定?) then (是)
      :显示账号锁定提示;
      :提供解锁选项;
      stop
    else (否)
      if (密码是否正确?) then (是)
        :密码错误计数清零;
      else (否)
        :密码错误计数+1;
        if (错误次数>5?) then (是)
          :锁定账号30分钟;
          :发送账号异常通知;
          stop
        else (否)
          :显示密码错误;
          :允许重试;
          note right: 剩余尝试次数显示
        endif
      endif
    endif
​
  elseif (登录方式?) then (手机验证码登录)
    :输入手机号;
    :发送短信验证码;
    :用户输入验证码;
    if (验证码正确?) then (是)
      :验证通过;
    else (否)
      :提示验证码错误;
      :允许重新获取;
      note right: 每日限制5次
    endif
​
  else (第三方OAuth登录)
    :选择第三方平台(微信/支付宝);
    :跳转到第三方认证页面;
    :用户在第三方平台授权;
    :接收第三方平台回调;
    if (授权成功?) then (是)
      :获取第三方用户信息;
      if (是否首次使用第三方登录?) then (是)
        :创建关联账号;
      else (否)
        :找到关联账号;
      endif
    else (否)
      :提示授权失败;
      :返回登录选择页;
    endif
  endif
​
  if (用户是否开启双因素认证?) then (是)
    :提示输入双因素验证码;
    :用户从认证器App获取验证码;
    :输入双因素验证码;
    if (验证码正确?) then (是)
      :验证通过;
    else (否)
      :提示验证码错误;
      :允许重试;
      note right: 错误3次后锁定账号
    endif
  else (否)
    :跳过双因素认证;
  endif
​
  #palegreen:登录成功;
}
​
partition "JWT签发流程" {
  :生成用户会话;
  :创建JWT负载(Payload);
  note right
    包含:
    - 用户ID
    - 角色权限
    - 过期时间
    - 设备信息
  end note
  :使用密钥签名JWT;
  :返回JWT令牌给客户端;
  :客户端存储JWT;
}
​
partition "密码找回流程" {
  #orange:用户请求找回密码;
​
  if (找回方式?) then (邮箱找回)
    :输入注册邮箱;
    :验证邮箱是否存在;
    if (邮箱存在?) then (是)
      :生成密码重置链接;
      :发送重置链接到邮箱;
      :用户点击邮件中的重置链接;
      if (链接是否有效?) then (是)
        :显示重置密码页面;
      else (否)
        :提示链接已过期;
        :允许重新申请;
      endif
    else (否)
      :提示邮箱不存在;
    endif
​
  else (手机找回)
    :输入注册手机号;
    :验证手机号是否存在;
    if (手机号存在?) then (是)
      :发送验证码到手机;
      :用户输入验证码;
      if (验证码正确?) then (是)
        :显示重置密码页面;
      else (否)
        :提示验证码错误;
        :允许重新获取;
      endif
    else (否)
      :提示手机号不存在;
    endif
  endif
​
  :用户输入新密码;
  :验证密码强度;
  if (密码强度达标?) then (是)
    :更新密码;
    :清除原有会话;
    :提示密码重置成功;
  else (否)
    :提示密码强度不足;
    :显示密码规则;
  endif
}
​
|用户|
:用户成功进入系统;
stop
​
@enduml

user_login_activity

03 用户支付流程图

提示词:

请使用PlantUML的序列图(Sequence Diagram)语法创建一个电商系统的用户支付流程图,涵盖以下要素:
​
1. 参与者包括:
   - 用户
   - 电商前端系统
   - 订单服务
   - 支付服务
   - 库存服务
   - 第三方支付平台(如支付宝/微信支付)
   - 消息队列
   - 用户通知服务
​
2. 流程应包含:
   - 用户下单并选择支付方式
   - 订单服务创建订单并锁定库存
   - 生成支付单并跳转到支付平台
   - 用户在支付平台完成支付
   - 支付平台异步通知支付结果
   - 支付服务更新支付状态
   - 订单服务确认订单并释放库存
   - 消息通知用户支付结果
​
3. 包含异常处理路径:
   - 支付超时处理
   - 库存不足处理
   - 支付失败处理
​
4. 使用注释说明关键步骤
5. 合理分组相关操作(使用alt, loop, opt等元素)

AI 会生成类似的结果:

@startuml 电商系统用户支付流程
​
' 定义参与者
actor 用户
participant "电商前端系统" as Frontend
participant "订单服务" as OrderService
participant "支付服务" as PaymentService
participant "库存服务" as InventoryService
participant "第三方支付平台" as ThirdPartyPayment
queue "消息队列" as MessageQueue
participant "用户通知服务" as NotificationService
​
' 设置样式
skinparam sequenceArrowThickness 2
skinparam roundcorner 10
skinparam maxmessagesize 160
skinparam sequenceParticipant underline
​
' 开始流程
title 电商系统用户支付流程
​
' 用户下单
group 下单流程
    用户 -> Frontend : 浏览商品并添加到购物车
    用户 -> Frontend : 提交订单并选择支付方式
    Frontend -> OrderService : 创建订单请求
​
    ' 库存检查
    OrderService -> InventoryService : 检查库存
​
    alt 库存充足
        InventoryService -> OrderService : 返回库存充足
        OrderService -> InventoryService : 锁定库存
        InventoryService --> OrderService : 库存锁定成功
        OrderService --> Frontend : 返回订单创建成功
    else 库存不足
        InventoryService --> OrderService : 返回库存不足
        OrderService --> Frontend : 返回库存不足错误
        Frontend --> 用户 : 显示"库存不足"提示
        note right of 用户: 订单创建失败,流程终止
    end
end
​
' 支付流程
group 支付流程
    Frontend -> PaymentService : 创建支付单
    PaymentService -> PaymentService : 生成支付单号
    PaymentService --> Frontend : 返回支付链接/二维码
    Frontend --> 用户 : 展示支付界面(链接/二维码)
​
    用户 -> ThirdPartyPayment : 跳转到支付平台
    ThirdPartyPayment -> 用户 : 请求付款确认
    用户 -> ThirdPartyPayment : 确认付款
​
    alt 支付成功
        ThirdPartyPayment -> PaymentService : 异步通知支付结果(成功)
        PaymentService -> PaymentService : 更新支付状态为"成功"
        PaymentService -> OrderService : 通知订单支付成功
        OrderService -> OrderService : 更新订单状态为"已支付"
​
        ' 消息通知
        OrderService -> MessageQueue : 发送订单状态变更消息
        MessageQueue -> NotificationService : 消费订单状态消息
        NotificationService -> 用户 : 发送支付成功通知
​
        ' 确认库存
        OrderService -> InventoryService : 确认库存扣减
    else 支付失败
        ThirdPartyPayment -> PaymentService : 异步通知支付结果(失败)
        PaymentService -> PaymentService : 更新支付状态为"失败"
        PaymentService -> OrderService : 通知订单支付失败
        OrderService -> OrderService : 更新订单状态为"支付失败"
​
        ' 解锁库存
        OrderService -> InventoryService : 解锁库存
        InventoryService --> OrderService : 库存解锁成功
​
        ' 消息通知
        OrderService -> MessageQueue : 发送订单状态变更消息
        MessageQueue -> NotificationService : 消费订单状态消息
        NotificationService -> 用户 : 发送支付失败通知
    end
end
​
' 支付超时处理
group 支付超时处理
    note over PaymentService: 定时任务检查超时支付单
​
    opt 支付单超过限定时间未完成
        PaymentService -> PaymentService : 标记支付单为"超时"
        PaymentService -> OrderService : 通知订单支付超时
        OrderService -> OrderService : 更新订单状态为"已取消"
​
        ' 解锁库存
        OrderService -> InventoryService : 解锁库存
        InventoryService --> OrderService : 库存解锁成功
​
        ' 消息通知
        OrderService -> MessageQueue : 发送订单取消消息
        MessageQueue -> NotificationService : 消费订单取消消息
        NotificationService -> 用户 : 发送订单取消通知
    end
end
​
' 支付平台主动查询
group 支付结果主动查询
    note over PaymentService: 对于未收到异步通知的订单,主动查询支付状态
​
    loop 未收到支付结果的订单
        PaymentService -> ThirdPartyPayment : 查询支付状态
        ThirdPartyPayment --> PaymentService : 返回最新支付状态
​
        alt 支付已成功
            PaymentService -> OrderService : 通知订单支付成功
            OrderService -> OrderService : 更新订单状态为"已支付"
            OrderService -> InventoryService : 确认库存扣减
            OrderService -> MessageQueue : 发送订单状态变更消息
            MessageQueue -> NotificationService : 消费订单状态消息
            NotificationService -> 用户 : 发送支付成功通知
        else 支付已失败
            PaymentService -> OrderService : 通知订单支付失败
            OrderService -> OrderService : 更新订单状态为"支付失败"
            OrderService -> InventoryService : 解锁库存
            OrderService -> MessageQueue : 发送订单状态变更消息
            MessageQueue -> NotificationService : 消费订单状态消息
            NotificationService -> 用户 : 发送支付失败通知
        end
    end
end
​
@enduml
​

payment

因代码太长,影响阅读,后续以最终生成的预览图进行展示。

04 DDD 分层架构图

一个基于领域驱动设计(DDD)的订单系统创建内部的代码分层架构图,展示完整的分层结构。

order_ddd

05 集成架构图(C4 模型)

一个企业集成平台创建C4模型图。该平台需要集成多个内部系统和外部服务,实现数据同步和业务流程自动化。

系统上下文图:

image-20250420下午102455028

容器图:

image-20250420下午102732397

ESB 组件图:

image-20250420下午103014540

数据处理引擎图:

image-20250420下午103033265

总结

通过 Cursor 结合 AI 能力,我们可以快速生成各种复杂的 PlantUML 图表,大大提高了技术文档创建的效率。不管是系统架构图、流程图还是领域模型图,只需要通过文字描述我们的需求,AI 便能理解并生成对应的 PlantUML 代码。

使用这种方式的主要优势包括:

  1. 效率提升:从几小时的手动绘图工作缩减到几分钟的文字提示

  2. 专注设计:将精力集中在业务逻辑和系统设计上,而非绘图工具的使用

  3. 易于迭代:只需修改提示词即可快速调整图表内容

  4. 一致性:通过模板化提示词可确保不同图表风格的一致性

  5. 无需记忆语法:不需要精通PlantUML的复杂语法也能生成专业图表

作为架构师或技术Leader,我们可以将这些提示词模板化,根据不同项目和场景进行小幅调整,从而快速生成高质量的技术文档图表。同时,PlantUML的文本特性也使得这些图表易于版本控制和团队协作。

最后,随着AI技术的不断发展,这种结合方式的效果会越来越好,我们可以期待在未来通过更自然的交互方式,创建更加复杂和精确的技术图表。

Cursor 系列精选阅读

如果你对 Cursor 感兴趣,可以按学习路径浏览我的更多专题文章:

入门篇

进阶篇

设计与开发实战

工作流整合


欢迎关注我的公众号"Eric技术圈",原创技术文章第一时间推送。

License:  CC BY 4.0