使用PlantUML绘制UML图

失去的东西,其实从来未曾真正地属于你,也不必惋惜,始终真心真意

Posted by yishuifengxiao on 2025-08-27

PlantUML 使用简单直观的文本语言来定义图表,然后将其渲染为图片。

如何渲染(使用)PlantUML

  1. 在线编辑器: 访问 PlantUML 官方网站PlantText,将代码粘贴到左侧,右侧会实时生成图表。
  2. VSCode 插件: 安装 PlantUML 插件,编写 .puml.wsd 文件,按 Alt+D 即可预览。
  3. 本地渲染: 下载 PlantUML 的 JAR 包,使用 Java 命令行进行渲染。
  4. 集成到代码/文档: 可以与 Markdown(通过插件)、Confluence、GitLab/GitHub 等工具集成。

活动图在 PlantUML 中通常以 @startuml@enduml 作为开始和结束的标记。

活动图-开始/停止/结束

起始/终止节点(Terminator):表示流程的开始或结束。

@startuml
start
:Hello World;
stop
@enduml

startstop 是关键字,会渲染成圆角矩形。:Hello World; 中的冒号 : 也会创建一个圆角矩形,常用于流程步骤。

image-20250826222826518

也可以使用end 关键字。

@startuml
start
:Hello world;
:This is defined on
several **lines**;
end
@enduml

image-20250826224059467

活动图-处理过程(Process)

处理过程(Process):表示一个操作或处理步骤。

@startuml
:处理步骤;
@enduml

同样使用冒号 : 定义,这是最常用的节点类型。

image-20250826222841709

指定颜色

@startuml

start
:开始处理;
#HotPink:读取配置文件
这些文件应该在此处编辑;
#AAAAAA:结束处理;

@enduml

image-20250826232113424

使用渐变色

@startuml
start
partition #red/white test分片 {
#blue\green:test活动;
}
@enduml

image-20250826232621234

活动图-判断(Conditional)

判断(Conditional):表示一个判断或决策,通常是 yes/no 或 true/false。

@startuml
if (今天是个好天气吗?) then (是)
:出去玩耍;
else (否)
:在家看书;
endif
@enduml

使用 ifthenelseendif 关键字。(是)(否) 是显示在连接线上的标签。

image-20250826222857294

if (...) then (...)

@startuml

start

if (Graphviz installed?) then (yes)
:process all\ndiagrams;
else (no)
:process only
__sequence__ and __activity__ diagrams;
endif

stop

@enduml

image-20250826224702849

if (...) is (...) then

@startuml
if (color?) is (<color:red>red) then
:print red;
else
:print not red;
@enduml

image-20250826224827591

注意该语法目前vscode插件可能不支持

if (...) equals (...) then

@startuml
if (counter?) equals (5) then
:print 5;
else
:print not 5;
@enduml

image-20250826224930598

注意该语法目前vscode插件可能不支持

活动图-输入/输出(Input/Output)

输入/输出(Input/Output):表示数据的输入或输出。

@startuml
start
-> 输入数据;
:处理数据;
-> 输出结果;
stop
@enduml

使用 -> 箭头符号加上文本定义,但更规范的做法是使用 : 或特定关键字。严格来说,IO常用平行四边形,但PlantUML中常用:代替。

image-20250826222927464

活动图-注释

文本格式可以使用克里奥尔维基语法

可以使用floating 关键字浮动注释。

floating 关键字浮动注释

@startuml

start
:foo1;
floating note left: This is a note
:foo2;
note right
This note is on several
//lines// and can
contain <b>HTML</b>
====
* Calling the method ""foo()"" is prohibited
end note
stop

@enduml

image-20250826230039815

后向活动添加注释

@startuml
start
repeat :Enter data;
:Submit;
backward :Warning;
note right: Note
repeat while (Valid?) is (No) not (Yes)
stop
@enduml

image-20250826230210223

活动图-连接元素:箭头和方向

无箭头连接线

可以使用 skinparam ArrowHeadColor none 参数来表示仅使用线条连接活动,而不带箭头

@startuml
skinparam ArrowHeadColor none
start
:Hello world;
:This is on defined on
several **lines**;
stop
@enduml

image-20250826225323520

@startuml
skinparam ArrowHeadColor none
start
repeat :Enter data;
:Submit;
backward :Warning;
repeat while (Valid?) is (No) not (Yes)
stop
@enduml

image-20250826225355032

带箭头连接线

使用->标记,你可以给箭头添加文字或者修改箭头颜色

同时,你也可以选择点状 (dotted),条状(dashed),加粗或者是隐式箭头

基本连接

@startuml
start
:步骤A;
:步骤B;
stop
@enduml

默认情况下,PlantUML 会按书写顺序自上而下连接节点。

image-20250826223047703

带标签的连接

@startuml
:用户点击按钮;
-> 请求发送;
:服务器处理;
-> 返回结果;
:显示信息;
@enduml

在箭头后面直接添加文本即可为箭头添加标签。

image-20250826223322848

其他类型箭头

@startuml
:foo1;
-> You can put text on arrows;
if (test) then
-[#blue]->
:foo2;
-[#green,dashed]-> The text can
also be on several lines
and **very** long...;
:foo3;
else
-[#black,dotted]->
:foo4;
endif
-[#gray,bold]->
:foo5;
@enduml

image-20250826225626437

活动图-控制流程:分支和循环

分支(if/else)

@startuml
start
if (决策点?) then (选项1)
:处理选项1;
else (选项2)
:处理选项2;
endif
:后续步骤;
stop
@enduml

image-20250826223337480

while循环

@startuml
start

while (数据未处理完?) is (是)
:处理一条数据;
:更新索引;
endwhile (否)

:完成;
stop
@enduml

image-20250826223359566

使用 whileendwhile 来创建 while 循环。is (是) 指定了循环条件成立时的出口标签。

重复循环

使用 repeatrepeat while 来创建 do-while 循环(先执行后判断)。

@startuml
start

repeat
:处理一条数据;
:更新索引;
repeat while (数据未处理完?) is (是) not (否)

:完成;
stop
@enduml

image-20250826223418342

同样可以使用一个全局行为作为repeat目标, 在返回循环开始时使用backward关键字插入一个全局行为

@startuml

start

repeat :foo作为开始标注;
:读取数据;
:生成图片;
backward:这是一个后撤行为;
repeat while (更多数据?)

stop

@enduml

image-20250826230828992

打断循环 [break]

可以使用 break 关键字跟在循环中的某个行为后面打断循环

@startuml
start
repeat
:测试某事;
if (发生错误?) then (没有)
#palegreen:好的;
break
endif
->not ok;
:弹窗 "文本过长错误";
repeat while (某事发生文本过长错误?) is (是的) not (不是)
->//合并步骤//;
:弹窗 "成功!";
stop
@enduml

image-20250826231045159

Switch判断 [switch, case, endswitch]

@startuml
start
switch (测试?)
case ( 条件 A )
:Text 1;
case ( 条件 B )
:Text 2;
case ( 条件 C )
:Text 3;
case ( 条件 D )
:Text 4;
case ( 条件 E )
:Text 5;
endswitch
stop
@enduml

image-20250826232917959

并行处理 [fork, fork again, end fork, end merge]

fork 示例

@startuml
start
fork
:行为 1;
fork again
:行为 2;
end fork
stop
@enduml

image-20250826233022992

fork 和合并示例

@startuml
start
fork
:行为 1;
fork again
:行为 2;
end merge
stop
@enduml

image-20250826233104353

@startuml
start
fork
:行为 1;
fork again
:行为 2;
fork again
:行为 3;
fork again
:行为 4;
end merge
stop
@enduml

image-20250826233142792

end fork 标注 (或 UML 连接规范)

@startuml
start
fork
:行为 A;
fork again
:行为 B;
end fork {或}
stop
@enduml

image-20250826233249681

复杂场景

@startuml

start

if (多进程处理?) then (是)
fork
:进程 1;
fork again
:进程 2;
end fork
else (否)
:逻辑 1;
:逻辑 2;
endif

@enduml

image-20250826233343761

活动图-使用分组(Grouping)

你可以使用 partitionpackagerectangle 等来将相关的节点分组,使其在视觉上更清晰。

@startuml
start

partition 初始化 {
:加载配置;
:建立连接;
}

partition 核心处理 {
:读取数据;
:处理数据;
if (成功?) then (是)
:写入结果;
else (否)
:记录错误;
endif
}

:清理资源;
stop
@enduml

image-20250826233935336

活动图-分区

通过定义分区(partition),你可以把多个活动组合(group)在一起:

@startuml
start
partition 初始化分区 {
:read config file;
:init internal variable;
}
partition 运行分区 {
:wait for user interaction;
:print information;
}

stop
@enduml

image-20250826234108945

可以改变分区颜色 color:

@startuml
start
partition #lightGreen "Input Interface" {
:read config file;
:init internal variable;
}
partition Running {
:wait for user interaction;
:print information;
}
stop
@enduml

image-20250826234150713

活动图综合示例

下面是一个模拟用户登录验证的完整活动图示例,融合了以上多种语法:

示例1

@startuml
start
:打开登录页面;
:输入用户名和密码;
:点击“登录”按钮;

' 验证过程分组
partition 验证 {
#LightBlue:验证输入是否合法;
-> 输入不合法;
note right: 用户名或密码为空

if (输入合法?) then (是)
:查询数据库验证用户;
else (否)
#Pink:显示“输入不合法”提示;
endif

if (用户存在且密码正确?) then (是)
-> 验证成功;
else (否)
-> 验证失败;
#Pink:显示“用户名或密码错误”提示;
endif
}

if (验证成功?) then (是)
#LightGreen:创建用户会话;
:跳转到首页;
stop
else (否)
:返回登录页面;
' 使用反向箭头指回之前的节点
-> 重新输入;
endif

@enduml

这个示例说明:

  1. 流程:清晰展示了从打开页面到最终登录成功或失败的完整路径。
  2. 分组:使用 partition 将所有的验证逻辑包在一起,结构清晰。
  3. 判断:使用了两个 if 判断,分别处理输入合法性和用户凭证有效性。
  4. 注释:使用 note right 为“输入不合法”的箭头添加了说明。
  5. 颜色:使用 #颜色代码 为特定节点添加了背景色(如 #LightBlue, #Pink, #LightGreen),使其更醒目。
  6. 箭头标签:使用 -> 标签; 为箭头添加了说明文字。

image-20250826234426249


示例2

@startuml
start
:打开登录页面;

repeat
:输入用户名和密码;
:点击"登录"按钮;

partition 验证 {
if (输入合法?) then (是)
:查询数据库验证用户;

if (用户存在且密码正确?) then (是)
:验证成功;
-> 跳出循环;
else (否)
:显示"用户名或密码错误"提示;
endif
else (否)
:显示"输入不合法"提示;
endif
}

-> 返回登录页面;
:清除输入;
' 这里不需要再次写"打开登录页面",因为已经在循环内
' 循环会自动返回到"输入用户名和密码"步骤
repeat while (验证成功?) is (否) not (是)

:创建用户会话;
:跳转到首页;
stop

@enduml
  1. 使用 @startuml@enduml 标记图表范围
  2. 使用 startstop 表示开始和结束
  3. 使用 :描述; 表示处理步骤
  4. 使用 if/else/endif 结构表示条件分支
  5. 使用 -> 连接各个元素,可添加标签
  6. 使用 repeat/repeat while 表示循环
  7. 使用 partition 创建分组
  8. 使用 note 添加注释
  9. 使用 #颜色 添加颜色

image-20250826234453834


时序图-核心概念

一个基本的时序图包含以下元素:参与者 (Participants)生命线 (Lifelines)消息 (Messages)激活条 (Activation Bars)

在 PlantUML 序列图中,-> 序列表示两个参与者之间发送的消息,它是自动识别的,不需要事先声明。

通过使用--> 序列,利用虚线箭头,在您的图中提供独特的可视化。

为了提高可读性而不影响可视化表示,可使用反向箭头,如<-<-- 。但要注意,这是专门针对序列图的,其他图类型的规则有所不同。

@startuml
Alice -> Bob: Authentication Request
Bob --> Alice: Authentication Response

Alice -> Bob: Another authentication Request
Alice <-- Bob: Another authentication Response
@enduml

image-20250826235034713

时序图-声明参与者 (participant, actor, etc.)

参与者是交互的实体。声明顺序决定了它们在图表中的默认排列顺序。

  • participant John: 普通参与者。可以用 as 来定义别名,例如 participant "A Client" as C
  • actor "User" as U: 表示角色(通常是用户),会显示一个小人图标。
  • boundary "UI" as B: 边界对象。
  • control "Controller" as C: 控制对象。
  • entity "Database" as D: 实体对象。
  • database "DB" as DB: 数据库图标。
  • collections "Cache" as Cache: 集合图标。
  • queue (队列)
  • 隐式声明: 你也可以不预先声明,直接在消息中使用名称,PlantUML 会自动按出现顺序创建参与者。

排序

使用 order 关键字可以自定义参与者的排列顺序。

@startuml
actor User
participant "First Component" as A
participant "Second Component" as B order 1
' B 会因为 order 1 而排在左边第一个
@enduml

image-20250826235238124

形状

@startuml
participant Participant as Foo
actor Actor as Foo1
boundary Boundary as Foo2
control Control as Foo3
entity Entity as Foo4
database Database as Foo5
collections Collections as Foo6
queue Queue as Foo7
Foo -> Foo1 : To actor
Foo -> Foo2 : To boundary
Foo -> Foo3 : To control
Foo -> Foo4 : To entity
Foo -> Foo5 : To database
Foo -> Foo6 : To collections
Foo -> Foo7: To queue
@enduml

image-20250826235317356

别名和颜色

使用as 关键字重命名参与者。

你也可以改变 演员或参与者的背景颜色

@startuml
actor Bob #red
' The only difference between actor
'and participant is the drawing
participant Alice
participant "I have a really\nlong name" as L #99FF99
/' You can also declare:
participant L as "I have a really\nlong name" #99FF99
'/

Alice->Bob: Authentication Request
Bob->Alice: Authentication Response
Bob->L: Log transaction
@enduml

image-20250826235423690

在参与者中使用非字母

@startuml
Alice -> "Bob()" : Hello
"Bob()" -> "This is very\nlong" as Long
' You can also declare:
' "Bob()" -> Long as "This is very\nlong"
Long --> "Bob()" : ok
@enduml

时序图-消息 (Messages)

消息是参与者之间的通信,用箭头表示。

同步消息

同步消息 (Synchronous): ->表示调用并等待返回。实心箭头。

A -> B: doSomething()

image-20250827000100638

异步消息

异步消息 (Asynchronous): -->表示发送后不等待返回。开放箭头。

A --> B: somethingHappened()

image-20250827000118338

返回消息

返回消息 (Return): <- or <--通常可省略,PlantUML 会自动推断。为了清晰,可以显式画出。

A -> B: compute()
B <- A: result // 显式地绘制返回消息

image-20250827000143881

给自己发消息

参与者可以给自己发信息,消息文字可以用\n来换行。

@startuml
Alice -> Alice: This is a signal to self.\nIt also demonstrates\nmultiline \ntext
@enduml

image-20250827000306572

@startuml
Alice <- Alice: This is a signal to self.\nIt also demonstrates\nmultiline \ntext
@enduml

image-20250827000332000

对消息序列编号

关键字 autonumber 用于自动对消息编号

@startuml
autonumber
Bob -> Alice : Authentication Request
Bob <- Alice : Authentication Response
@enduml

image-20250827000442074

语句 autonumber //start// 用于指定编号的初始值,而 autonumber //start// //increment// 可以同时指定编号的初始值和每次增加的值。

@startuml
autonumber
Bob -> Alice : Authentication Request
Bob <- Alice : Authentication Response

autonumber 15
Bob -> Alice : Another authentication Request
Bob <- Alice : Another authentication Response

autonumber 40 10
Bob -> Alice : Yet another authentication Request
Bob <- Alice : Yet another authentication Response

@enduml

image-20250827000534547

指定编号的格式

你可以在双引号内指定编号的格式。格式是由 Java 的DecimalFormat类实现的: (0 表示数字;# 也表示数字,但默认为0)。你也可以用 HTML 标签来制定格式。

@startuml
autonumber "<b>[000]"
Bob -> Alice : Authentication Request
Bob <- Alice : Authentication Response

autonumber 15 "<b>(<u>##</u>)"
Bob -> Alice : Another authentication Request
Bob <- Alice : Another authentication Response

autonumber 40 10 "<font color=red><b>Message 0 "
Bob -> Alice : Yet another authentication Request
Bob <- Alice : Yet another authentication Response

@enduml

image-20250827000702818

停止或继续使用自动编号

可以用语句 autonumber stopautonumber resume //increment// //format// 来表示暂停或继续使用自动编号

@startuml
autonumber 10 10 "<b>[000]"
Bob -> Alice : Authentication Request
Bob <- Alice : Authentication Response

autonumber stop
Bob -> Alice : dummy

autonumber resume "<font color=red><b>Message 0 "
Bob -> Alice : Yet another authentication Request
Bob <- Alice : Yet another authentication Response

autonumber stop
Bob -> Alice : dummy

autonumber resume 1 "<font color=blue><b>Message 0 "
Bob -> Alice : Yet another authentication Request
Bob <- Alice : Yet another authentication Response
@enduml

image-20250827000759049

使用2或3位的序列进行编号

你也可以使用一个2或3位的序列,中间采用一种或几种分隔符,如.,;,,,:。例如:1.1.11.1:1

最后一位数字会自动递增。

要增加第一个数字,请使用:autonumber inc A 。要增加第二位数字,请使用:autonumber inc B

@startuml
autonumber 1.1.1
Alice -> Bob: Authentication request
Bob --> Alice: Response

autonumber inc A
'Now we have 2.1.1
Alice -> Bob: Another authentication request
Bob --> Alice: Response

autonumber inc B
'Now we have 2.2.1
Alice -> Bob: Another authentication request
Bob --> Alice: Response

autonumber inc A
'Now we have 3.1.1
Alice -> Bob: Another authentication request
autonumber inc B
'Now we have 3.2.1
Bob --> Alice: Response
@enduml

image-20250827000912833

时序图-箭头

改变箭头样式

可以通过以下几种方式改变箭头样式:

  • 添加最后的x 表示丢失的信息
  • 使用\/ 而不是<> 只拥有箭头的底部或顶部部分
  • 重复箭头头(例如>>// )头,拥有一个薄的图纸
  • 使用-- 而不是- 拥有一个点状箭头
  • 在箭头头添加最后的 “o”
  • 使用双向的箭头<->
@startuml
Bob ->x Alice
Bob -> Alice
Bob ->> Alice
Bob -\ Alice
Bob \\- Alice
Bob //-- Alice

Bob ->o Alice
Bob o\\-- Alice

Bob <-> Alice
Bob <->o Alice
@enduml

image-20250827203047400

修改箭头颜色

@startuml
Bob -[#red]> Alice : hello
Alice -[#0000FF]->Bob : ok
@enduml

image-20250827203150001

时序图-激活与去激活 (Activation/Deactivation)

关键字activatedeactivate用来表示参与者的生命活动。一旦参与者被激活,它的生命线就会显示出来。activatedeactivate适用于以上情形。destroy表示一个参与者的生命线的终结。

激活条(生命线上的长方形)表示参与者正在执行操作。

激活

@startuml
participant User

User -> A: DoWork
activate A

A -> B: << createRequest >>
activate B

B -> C: DoWork
activate C
C --> B: WorkDone
destroy C

B --> A: RequestCreated
deactivate B

A -> User: Done
deactivate A

@enduml

image-20250827001332816

嵌套的生命线

@startuml
participant User

User -> A: DoWork
activate A #FFBBBB

A -> A: Internal call
activate A #DarkSalmon

A -> B: << createRequest >>
activate B

B --> A: RequestCreated
deactivate B
deactivate A
A -> User: Done
deactivate A

@enduml

image-20250827001458650

自动激活

需要与return关键字配合

@startuml
autoactivate on
alice -> bob : hello
bob -> bob : self call
bill -> bob #005500 : hello from thread 2
bob -> george ** : create
return done in thread 2
return rc
bob -> george !! : delete
return success

@enduml

image-20250827001556574

时序图-文本对齐

箭头上的文本对齐可以用skinparam sequenceMessageAlign,后接参数left,rightcenter

也可以使用directionreverseDirection来根据箭头的方向对齐文本。更多细节可参考skinparam

@startuml
skinparam sequenceMessageAlign right
Bob -> Alice : Request
Alice -> Bob : Response
@enduml

image-20250827202832713

时序图-让响应信息显示在箭头下面

可以使用skinparam responseMessageBelowArrow true命令,让响应信息显示在箭头下面。

@startuml
skinparam responseMessageBelowArrow true
Bob -> Alice : hello
Bob <- Alice : ok
@enduml

image-20250827202939642

时序图-注释信息

普通注释

可以使用note leftnote right 关键字在信息后面加上注释。可以使用end note 关键字有一个多行注释。

@startuml
Alice->Bob : hello
note left: this is a first note

Bob->Alice : ok
note right: this is another note

Bob->Bob : I am thinking
note left
a note
can also be defined
on several lines
end note
@enduml

image-20250827203906125

修改注释背景色

可以使用note left ofnote right ofnote over在节点(participant)的相对位置放置注释。还可以通过修改背景色来高亮显示注释。以及使用关键字end note来添加多行注释。

@startuml
participant Alice
participant Bob
note left of Alice #aqua
This is displayed
left of Alice.
end note

note right of Alice: This is displayed right of Alice.

note over Alice: This is displayed over Alice.

note over Alice, Bob #FFAAAA: This is displayed\n over Bob and Alice.

note over Bob, Alice
This is yet another
example of
a long note.
end note
@enduml

image-20250827204014732


时序图-组合消息

可以通过以下关键词来组合消息:

  • alt/else
  • opt
  • loop
  • par
  • break
  • critical
  • group, 后面紧跟着消息内容

可以在标头(header)添加需要显示的文字(对于group关键字,参看 ‘次级分组标签’)。关键词 end 用来结束分组。注意,分组可以嵌套使用。

@startuml
Alice -> Bob: 认证请求

alt 成功情况

Bob -> Alice: 认证接受

else 某种失败情况

Bob -> Alice: 认证失败
group 我自己的标签
Alice -> Log : 开始记录攻击日志
loop 1000次
Alice -> Bob: DNS 攻击
end
Alice -> Log : 结束记录攻击日志
end

else 另一种失败

Bob -> Alice: 请重复

end
@enduml

image-20250827203546131

时序图-次级分组标签

对于group而言,在标头处的[]之间可以显示次级文本或标签。

@startuml
Alice -> Bob: 认证请求
Bob -> Alice: 认证失败
group 我自己的标签 [我自己的标签2]
Alice -> Log : 开始记录攻击日志
loop 1000次
Alice -> Bob: DNS攻击
end
Alice -> Log : 结束记录攻击日志
end
@enduml

image-20250827203741581

时序图-生命线控制 (Lifeline Control)

  • 创建与销毁: createdestroy

    User -> A++: new()
    create B // 创建参与者 B
    A -> B: initialize()
    destroy A // 销毁参与者 A
  • 暂停生命线: |||... 表示时间流逝或等待。

    A -> B: request
    ...
    B --> A: response ' 中间有一段延迟
  • 给自己发消息: [Participant]->[Participant]

    A -> A: internalCall()

时序图-分隔线 (Dividers)

使用 == 来划分不同阶段。

User -> Server: Login
== Authentication ==
Server -> DB: Validate Credentials
...
== Data Access ==
User -> Server: Query Data

image-20250827001857636

时序图-脚注与标题 (Footer and Header)

  • title Diagram Title: 设置标题。
  • header: 页眉。
  • footer: 页脚。
  • legend / end legend: 添加图例。
title Example Sequence Diagram
header Some Header
footer Page %page% of %lastpage%
User -> System: Interaction
legend
This is a legend
end legend

image-20250827001837786


时序图完整综合示例

示例1

下面是一个综合了以上多种语法的示例,模拟一个用户登录流程。

@startuml 用户登录时序图示例
' 1. 定义参与者
actor "User" as User
participant "Web Browser" as Browser
participant "Auth Controller" as Auth
participant "Database" as DB
database "Redis Cache" as Cache

' 2. 设置标题
title 用户登录流程时序图

' 3. 开始交互
User -> Browser++: 输入用户名/密码,点击登录
Browser -> Auth++: POST /login (credentials)

' 4. 分组:输入验证
group 输入验证 [客户端验证]
alt 格式有效
note over Browser, Auth: 用户名密码不为空
Auth -> Cache++: get(captcha_id)
return captcha_code
Auth -> Auth: validateCaptcha(input, captcha_code)
else 格式无效
Auth --> Browser--: 错误:输入格式无效
Browser --> User--: 显示错误消息
return
end

' 5. 分组:认证逻辑
== 核心认证 ==
opt 验证码正确
Auth -> DB++: queryUser(username, password_hash)
alt 用户存在且密码正确
DB --> Auth: User object
Auth -> Auth: generateSessionToken()
Auth -> DB: storeSession(token, user_id)
DB --> Auth: OK
Auth -> Cache: storeUserProfile(user_id)
Cache --> Auth: OK
Auth --> Browser--: HTTP 302 (Redirect to home)
Browser -> Browser: storeCookie(session_token)
Browser --> User--: 重定向到首页
else 认证失败
DB --> Auth: null
Auth --> Browser--: 错误:用户名或密码错误
Browser --> User--: 显示错误消息
end
else 验证码错误
Auth --> Browser--: 错误:验证码错误
Browser --> User--: 显示错误消息
end

@enduml

PlantUML 的时序图语法直观且强大:

  • ->, --> 定义消息。
  • ++, -- 管理激活状态。
  • alt/opt/loop/par 等关键字处理控制流和分组。
  • note 添加注释。
  • 通过声明参与者和使用 title, header 等使图表更清晰。

image-20250827001738239

示例2

@startuml
hide footbox
skinparam sequenceMessageAlign center
skinparam sequenceArrowFontSize 11
skinparam noteFontSize 11
skinparam monochrome true
skinparam lifelinestrategy solid

participant "<b>Operator" as OP
participant "<b>SM-DP+" as DP
participant "<b>LPAd" as LPA
participant "<b>eUICC" as E

LPA -> E : [1] ES10b.LoadBoundProfilePackage x N\n(ES8+.InitialiseSecureChannel)

rnote over E #FFFFFF
[2]
- Verify InitialiseSecureChannel data
- Generate Session Keys
endnote
E --> LPA : Response APDU x N
LPA -> E : [3] ES10b.LoadBoundProfilePackage x N\n(ES8+.ConfigureISDP)
E --> LPA : Response APDU x N
LPA -> E : [4] ES10b.LoadBoundProfilePackage x N\n(ES8+.StoreMetadata)
E --> LPA : Response APDU x N

rnote over E #FFFFFF
[4a] Verify PPR(s) against RAT
[4b] [Verify Enterprise Configuration]
endrnote

LPA -> E : [5] [ES10b.LoadBoundProfilePackage x N]\n(ES8+.ReplaceSessionKeys)
E --> LPA : [Response APDU x N]
LPA -> E : [6] ES10b.LoadBoundProfilePackage x N\n(ES8+.LoadProfileElements)
E --> LPA : Response APDU x N \n(ProfileInstallationResult)

LPA -> DP : [7] ES9+.HandleNotification(ProfileInstallationResult)
DP --> LPA : OK

rnote over DP #FFFFFF
[8] [Terminate Download order]
endrnote

DP -> OP : [9] [ES2+.HandleNotification]
OP --> DP : OK

rnote over DP #FFFFFF
[10] [Delete Event, Refer to Event Deletion section 3.6.3]
endrnote

LPA -> E : [11] ES10b.RemoveNotificationFromList

rnote over E #FFFFFF
[12] Delete Notification
endrnote

E --> LPA : OK

rnote over DP, E #FFFFFF
[13] [Next RSP Session follows]
endrnote

@enduml

image-20250827204601819


参考文档

https://plantuml.com/zh/sequence-diagram#77852febc7dde952

https://plantuml.com/zh/activity-diagram-beta

https://www.plantuml.com/plantuml/uml/SyfFKj2rKt3CoKnELR1Io4ZDoSa700001