fix(eslint): reduce warnings in GitHub Actions deployment
- Disable formatting rules (handled by Prettier) - Relaxed strict Vue/JS rules for demo code compatibility - Fix syntax errors in ApiPlayground and VoiceCloningDemo - Fix duplicate else-if condition in ApiPlayground - Fix Promise executor async pattern in AutoregressiveAudioDemo - Add TypeScript file support to ESLint config Warnings reduced from 295 to 251 problems. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
+82
-27
@@ -2,7 +2,9 @@
|
||||
<div class="clean-architecture-demo">
|
||||
<div class="demo-header">
|
||||
<h4>🏗️ 整洁架构(Clean Architecture)与分层架构</h4>
|
||||
<p class="subtitle">分层架构是整洁架构的基础,理解两者的关系有助于构建更灵活的系统</p>
|
||||
<p class="subtitle">
|
||||
分层架构是整洁架构的基础,理解两者的关系有助于构建更灵活的系统
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- 架构对比 -->
|
||||
@@ -20,26 +22,51 @@
|
||||
|
||||
<div class="comparison-content">
|
||||
<!-- 传统分层架构 -->
|
||||
<div v-if="currentTab === 'layered'" class="tab-panel">
|
||||
<div
|
||||
v-if="currentTab === 'layered'"
|
||||
class="tab-panel"
|
||||
>
|
||||
<div class="arch-diagram layered">
|
||||
<div class="layer-box controller">
|
||||
<div class="layer-title">Controller 层</div>
|
||||
<div class="layer-desc">接收请求、参数校验</div>
|
||||
<div class="layer-title">
|
||||
Controller 层
|
||||
</div>
|
||||
<div class="layer-desc">
|
||||
接收请求、参数校验
|
||||
</div>
|
||||
</div>
|
||||
<div class="arrow down">
|
||||
⬇️ 依赖
|
||||
</div>
|
||||
<div class="arrow down">⬇️ 依赖</div>
|
||||
<div class="layer-box service">
|
||||
<div class="layer-title">Service 层</div>
|
||||
<div class="layer-desc">业务逻辑、事务管理</div>
|
||||
<div class="layer-title">
|
||||
Service 层
|
||||
</div>
|
||||
<div class="layer-desc">
|
||||
业务逻辑、事务管理
|
||||
</div>
|
||||
</div>
|
||||
<div class="arrow down">
|
||||
⬇️ 依赖
|
||||
</div>
|
||||
<div class="arrow down">⬇️ 依赖</div>
|
||||
<div class="layer-box repository">
|
||||
<div class="layer-title">Repository 层</div>
|
||||
<div class="layer-desc">数据访问、ORM 映射</div>
|
||||
<div class="layer-title">
|
||||
Repository 层
|
||||
</div>
|
||||
<div class="layer-desc">
|
||||
数据访问、ORM 映射
|
||||
</div>
|
||||
</div>
|
||||
<div class="arrow down">
|
||||
⬇️ 依赖
|
||||
</div>
|
||||
<div class="arrow down">⬇️ 依赖</div>
|
||||
<div class="layer-box domain">
|
||||
<div class="layer-title">Domain 层</div>
|
||||
<div class="layer-desc">实体定义、业务规则</div>
|
||||
<div class="layer-title">
|
||||
Domain 层
|
||||
</div>
|
||||
<div class="layer-desc">
|
||||
实体定义、业务规则
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -55,30 +82,49 @@
|
||||
</div>
|
||||
|
||||
<!-- 整洁架构 -->
|
||||
<div v-else-if="currentTab === 'clean'" class="tab-panel">
|
||||
<div
|
||||
v-else-if="currentTab === 'clean'"
|
||||
class="tab-panel"
|
||||
>
|
||||
<div class="arch-diagram clean">
|
||||
<div class="clean-layers">
|
||||
<div class="clean-layer framework">
|
||||
<div class="layer-name">框架与驱动层</div>
|
||||
<div class="layer-items">Web / DB / UI / 外部接口</div>
|
||||
<div class="layer-name">
|
||||
框架与驱动层
|
||||
</div>
|
||||
<div class="layer-items">
|
||||
Web / DB / UI / 外部接口
|
||||
</div>
|
||||
</div>
|
||||
<div class="clean-layer interface">
|
||||
<div class="layer-name">接口适配层</div>
|
||||
<div class="layer-items">Controller / Gateway / Presenter</div>
|
||||
<div class="layer-name">
|
||||
接口适配层
|
||||
</div>
|
||||
<div class="layer-items">
|
||||
Controller / Gateway / Presenter
|
||||
</div>
|
||||
</div>
|
||||
<div class="clean-layer application">
|
||||
<div class="layer-name">应用层</div>
|
||||
<div class="layer-items">Service / UseCase / DTO</div>
|
||||
<div class="layer-name">
|
||||
应用层
|
||||
</div>
|
||||
<div class="layer-items">
|
||||
Service / UseCase / DTO
|
||||
</div>
|
||||
</div>
|
||||
<div class="clean-layer domain">
|
||||
<div class="layer-name">领域层(核心)</div>
|
||||
<div class="layer-items">Entity / ValueObject / DomainService</div>
|
||||
<div class="layer-name">
|
||||
领域层(核心)
|
||||
</div>
|
||||
<div class="layer-items">
|
||||
Entity / ValueObject / DomainService
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dependency-rule">
|
||||
<div class="rule-arrow">
|
||||
<span class="arrow-line"></span>
|
||||
<span class="arrow-line" />
|
||||
<span class="arrow-head">◀ 依赖方向</span>
|
||||
</div>
|
||||
<div class="rule-text">
|
||||
@@ -99,7 +145,10 @@
|
||||
</div>
|
||||
|
||||
<!-- 对比总结 -->
|
||||
<div v-else class="tab-panel">
|
||||
<div
|
||||
v-else
|
||||
class="tab-panel"
|
||||
>
|
||||
<div class="comparison-table">
|
||||
<table>
|
||||
<thead>
|
||||
@@ -148,7 +197,9 @@
|
||||
<h5>💡 选型建议</h5>
|
||||
<div class="rec-grid">
|
||||
<div class="rec-card">
|
||||
<div class="rec-title">选择传统分层架构当...</div>
|
||||
<div class="rec-title">
|
||||
选择传统分层架构当...
|
||||
</div>
|
||||
<ul>
|
||||
<li>项目规模较小,业务相对简单</li>
|
||||
<li>团队对 DDD 不熟悉</li>
|
||||
@@ -157,14 +208,18 @@
|
||||
</ul>
|
||||
</div>
|
||||
<div class="rec-card recommended">
|
||||
<div class="rec-title">选择整洁架构当...</div>
|
||||
<div class="rec-title">
|
||||
选择整洁架构当...
|
||||
</div>
|
||||
<ul>
|
||||
<li>业务复杂,领域模型丰富</li>
|
||||
<li>需要长期维护和演进</li>
|
||||
<li>需要频繁切换技术栈</li>
|
||||
<li>团队有较强的设计能力</li>
|
||||
</ul>
|
||||
<div class="rec-badge">推荐</div>
|
||||
<div class="rec-badge">
|
||||
推荐
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+102
-51
@@ -2,28 +2,36 @@
|
||||
<div class="controller-layer-demo">
|
||||
<div class="demo-header">
|
||||
<h4>🎮 Controller 层:请求的"接待员"</h4>
|
||||
<p class="subtitle">点击流程节点查看 Controller 如何接收和处理请求</p>
|
||||
<p class="subtitle">
|
||||
点击流程节点查看 Controller 如何接收和处理请求
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flow-container">
|
||||
<!-- 请求发起 -->
|
||||
<div class="flow-step">
|
||||
<div class="step-icon">🌐</div>
|
||||
<div class="step-icon">
|
||||
🌐
|
||||
</div>
|
||||
<div class="step-content">
|
||||
<div class="step-title">客户端发起请求</div>
|
||||
<div class="step-title">
|
||||
客户端发起请求
|
||||
</div>
|
||||
<div class="step-code">
|
||||
POST /api/users/register
|
||||
Content-Type: application/json
|
||||
{
|
||||
"username": "张三",
|
||||
"email": "zhangsan@example.com",
|
||||
"password": "123456"
|
||||
"username": "张三",
|
||||
"email": "zhangsan@example.com",
|
||||
"password": "123456"
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="arrow-connector">⬇️ 请求到达</div>
|
||||
<div class="arrow-connector">
|
||||
⬇️ 请求到达
|
||||
</div>
|
||||
|
||||
<!-- Controller 接收 -->
|
||||
<div
|
||||
@@ -31,28 +39,34 @@
|
||||
:class="{ active: showDetails === 'controller' }"
|
||||
@click="toggleDetails('controller')"
|
||||
>
|
||||
<div class="step-icon">🎮</div>
|
||||
<div class="step-icon">
|
||||
🎮
|
||||
</div>
|
||||
<div class="step-content">
|
||||
<div class="step-title">Controller 接收并解析请求</div>
|
||||
<div class="step-title">
|
||||
Controller 接收并解析请求
|
||||
</div>
|
||||
<div class="step-code">
|
||||
@RestController
|
||||
@RequestMapping("/api/users")
|
||||
public class UserController {
|
||||
|
||||
@PostMapping("/register")
|
||||
public ResponseEntity<UserDTO> register(
|
||||
@RequestBody @Valid UserRegisterRequest request
|
||||
) {
|
||||
// 调用 Service 处理业务
|
||||
UserDTO user = userService.register(request);
|
||||
return ResponseEntity.ok(user);
|
||||
}
|
||||
@PostMapping("/register")
|
||||
public ResponseEntity<UserDTO> register(
|
||||
@RequestBody @Valid UserRegisterRequest request
|
||||
) {
|
||||
// 调用 Service 处理业务
|
||||
UserDTO user = userService.register(request);
|
||||
return ResponseEntity.ok(user);
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="arrow-connector">⬇️ 参数校验 + 调用</div>
|
||||
<div class="arrow-connector">
|
||||
⬇️ 参数校验 + 调用
|
||||
</div>
|
||||
|
||||
<!-- 校验逻辑 -->
|
||||
<div
|
||||
@@ -60,23 +74,30 @@
|
||||
:class="{ active: showDetails === 'validation' }"
|
||||
@click="toggleDetails('validation')"
|
||||
>
|
||||
<div class="step-icon">✅</div>
|
||||
<div class="step-icon">
|
||||
✅
|
||||
</div>
|
||||
<div class="step-content">
|
||||
<div class="step-title">参数校验(Controller 的职责之一)</div>
|
||||
<div class="step-title">
|
||||
参数校验(Controller 的职责之一)
|
||||
</div>
|
||||
<div class="step-code">
|
||||
public class UserRegisterRequest {
|
||||
@NotBlank(message = "用户名不能为空")
|
||||
@Size(min = 2, max = 20, message = "用户名长度2-20")
|
||||
private String username;
|
||||
@NotBlank(message = "用户名不能为空")
|
||||
@Size(min = 2, max = 20, message = "用户名长度2-20")
|
||||
private String username;
|
||||
|
||||
@Email(message = "邮箱格式不正确")
|
||||
private String email;
|
||||
@Email(message = "邮箱格式不正确")
|
||||
private String email;
|
||||
|
||||
@Size(min = 6, message = "密码至少6位")
|
||||
private String password;
|
||||
@Size(min = 6, message = "密码至少6位")
|
||||
private String password;
|
||||
}
|
||||
</div>
|
||||
<div v-if="showDetails === 'validation'" class="detail-panel">
|
||||
<div
|
||||
v-if="showDetails === 'validation'"
|
||||
class="detail-panel"
|
||||
>
|
||||
<h5>为什么校验要放在 Controller?</h5>
|
||||
<ul>
|
||||
<li>🛡️ 第一道防线:尽早拦截非法请求</li>
|
||||
@@ -87,26 +108,32 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="arrow-connector">⬇️ 返回结果</div>
|
||||
<div class="arrow-connector">
|
||||
⬇️ 返回结果
|
||||
</div>
|
||||
|
||||
<!-- 响应返回 -->
|
||||
<div class="flow-step">
|
||||
<div class="step-icon">📤</div>
|
||||
<div class="step-icon">
|
||||
📤
|
||||
</div>
|
||||
<div class="step-content">
|
||||
<div class="step-title">Controller 封装响应返回给客户端</div>
|
||||
<div class="step-title">
|
||||
Controller 封装响应返回给客户端
|
||||
</div>
|
||||
<div class="step-code">
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"code": 200,
|
||||
"message": "注册成功",
|
||||
"data": {
|
||||
"id": 10001,
|
||||
"username": "张三",
|
||||
"email": "zhangsan@example.com",
|
||||
"createdAt": "2024-01-15T10:30:00Z"
|
||||
}
|
||||
"code": 200,
|
||||
"message": "注册成功",
|
||||
"data": {
|
||||
"id": 10001,
|
||||
"username": "张三",
|
||||
"email": "zhangsan@example.com",
|
||||
"createdAt": "2024-01-15T10:30:00Z"
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@@ -118,24 +145,48 @@
|
||||
<h5>🎯 Controller 的核心职责</h5>
|
||||
<div class="duty-grid">
|
||||
<div class="duty-item">
|
||||
<div class="duty-icon">📡</div>
|
||||
<div class="duty-title">接收请求</div>
|
||||
<div class="duty-desc">映射 HTTP 请求到方法</div>
|
||||
<div class="duty-icon">
|
||||
📡
|
||||
</div>
|
||||
<div class="duty-title">
|
||||
接收请求
|
||||
</div>
|
||||
<div class="duty-desc">
|
||||
映射 HTTP 请求到方法
|
||||
</div>
|
||||
</div>
|
||||
<div class="duty-item">
|
||||
<div class="duty-icon">✅</div>
|
||||
<div class="duty-title">参数校验</div>
|
||||
<div class="duty-desc">基础格式和必填校验</div>
|
||||
<div class="duty-icon">
|
||||
✅
|
||||
</div>
|
||||
<div class="duty-title">
|
||||
参数校验
|
||||
</div>
|
||||
<div class="duty-desc">
|
||||
基础格式和必填校验
|
||||
</div>
|
||||
</div>
|
||||
<div class="duty-item">
|
||||
<div class="duty-icon">🔄</div>
|
||||
<div class="duty-title">调用 Service</div>
|
||||
<div class="duty-desc">将请求转发给业务层</div>
|
||||
<div class="duty-icon">
|
||||
🔄
|
||||
</div>
|
||||
<div class="duty-title">
|
||||
调用 Service
|
||||
</div>
|
||||
<div class="duty-desc">
|
||||
将请求转发给业务层
|
||||
</div>
|
||||
</div>
|
||||
<div class="duty-item">
|
||||
<div class="duty-icon">📦</div>
|
||||
<div class="duty-title">封装响应</div>
|
||||
<div class="duty-desc">统一响应格式返回</div>
|
||||
<div class="duty-icon">
|
||||
📦
|
||||
</div>
|
||||
<div class="duty-title">
|
||||
封装响应
|
||||
</div>
|
||||
<div class="duty-desc">
|
||||
统一响应格式返回
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+35
-13
@@ -2,7 +2,9 @@
|
||||
<div class="dependency-direction-demo">
|
||||
<div class="demo-header">
|
||||
<h4>🔄 依赖方向:分层架构的核心规则</h4>
|
||||
<p class="subtitle">理解依赖方向,才能真正掌握分层架构</p>
|
||||
<p class="subtitle">
|
||||
理解依赖方向,才能真正掌握分层架构
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- 依赖方向可视化 -->
|
||||
@@ -10,38 +12,52 @@
|
||||
<div class="arch-diagram">
|
||||
<!-- 外层 -->
|
||||
<div class="layer outer">
|
||||
<div class="layer-label">外层(UI / 外部系统)</div>
|
||||
<div class="layer-box">Controller</div>
|
||||
<div class="layer-label">
|
||||
外层(UI / 外部系统)
|
||||
</div>
|
||||
<div class="layer-box">
|
||||
Controller
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 依赖箭头 -->
|
||||
<div class="dependency-arrow down">
|
||||
<span class="arrow-line"></span>
|
||||
<span class="arrow-line" />
|
||||
<span class="arrow-head">▶️ 依赖</span>
|
||||
</div>
|
||||
|
||||
<!-- 中层 -->
|
||||
<div class="layer middle">
|
||||
<div class="layer-label">中层(应用层)</div>
|
||||
<div class="layer-box">Service</div>
|
||||
<div class="layer-label">
|
||||
中层(应用层)
|
||||
</div>
|
||||
<div class="layer-box">
|
||||
Service
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 依赖箭头 -->
|
||||
<div class="dependency-arrow down">
|
||||
<span class="arrow-line"></span>
|
||||
<span class="arrow-line" />
|
||||
<span class="arrow-head">▶️ 依赖</span>
|
||||
</div>
|
||||
|
||||
<!-- 内层 -->
|
||||
<div class="layer inner">
|
||||
<div class="layer-label">内层(领域层)</div>
|
||||
<div class="layer-box">Domain / Repository</div>
|
||||
<div class="layer-label">
|
||||
内层(领域层)
|
||||
</div>
|
||||
<div class="layer-box">
|
||||
Domain / Repository
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 核心原则说明 -->
|
||||
<div class="principle-box">
|
||||
<div class="principle-title">🎯 核心原则:依赖倒置(DIP)</div>
|
||||
<div class="principle-title">
|
||||
🎯 核心原则:依赖倒置(DIP)
|
||||
</div>
|
||||
<div class="principle-content">
|
||||
<p><strong>上层模块不应该依赖下层模块的具体实现,而应该依赖于抽象。</strong></p>
|
||||
<div class="rule-list">
|
||||
@@ -49,21 +65,27 @@
|
||||
<span class="rule-icon">✅</span>
|
||||
<div class="rule-text">
|
||||
<strong>Controller → Service 接口</strong>
|
||||
<div class="rule-desc">Controller 只依赖 Service 的接口,不依赖实现类</div>
|
||||
<div class="rule-desc">
|
||||
Controller 只依赖 Service 的接口,不依赖实现类
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="rule-item">
|
||||
<span class="rule-icon">✅</span>
|
||||
<div class="rule-text">
|
||||
<strong>Service → Repository 接口</strong>
|
||||
<div class="rule-desc">Service 只依赖 Repository 接口,不关心数据怎么存</div>
|
||||
<div class="rule-desc">
|
||||
Service 只依赖 Repository 接口,不关心数据怎么存
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="rule-item">
|
||||
<span class="rule-icon">✅</span>
|
||||
<div class="rule-text">
|
||||
<strong>所有层依赖 Domain</strong>
|
||||
<div class="rule-desc">Domain 是核心,被所有上层依赖,但 Domain 不依赖任何层</div>
|
||||
<div class="rule-desc">
|
||||
Domain 是核心,被所有上层依赖,但 Domain 不依赖任何层
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+35
-11
@@ -2,7 +2,9 @@
|
||||
<div class="domain-model-demo">
|
||||
<div class="demo-header">
|
||||
<h4>📦 Domain 层:领域模型设计</h4>
|
||||
<p class="subtitle">Domain 是业务概念的载体,所有层的依赖基础</p>
|
||||
<p class="subtitle">
|
||||
Domain 是业务概念的载体,所有层的依赖基础
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- 领域模型对比 -->
|
||||
@@ -20,7 +22,10 @@
|
||||
|
||||
<div class="comparison-content">
|
||||
<!-- 贫血模型 vs 充血模型 -->
|
||||
<div v-if="currentTab === 'comparison'" class="tab-panel">
|
||||
<div
|
||||
v-if="currentTab === 'comparison'"
|
||||
class="tab-panel"
|
||||
>
|
||||
<div class="model-cards">
|
||||
<div class="model-card anemic">
|
||||
<div class="card-header">
|
||||
@@ -30,7 +35,9 @@
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<div class="code-section">
|
||||
<div class="code-label">Entity(只有 getter/setter)</div>
|
||||
<div class="code-label">
|
||||
Entity(只有 getter/setter)
|
||||
</div>
|
||||
<pre><code>@Entity
|
||||
public class Order {
|
||||
@Id
|
||||
@@ -48,7 +55,9 @@ public class Order {
|
||||
</div>
|
||||
|
||||
<div class="code-section">
|
||||
<div class="code-label">Service(所有业务逻辑都在这里)</div>
|
||||
<div class="code-label">
|
||||
Service(所有业务逻辑都在这里)
|
||||
</div>
|
||||
<pre><code>@Service
|
||||
public class OrderService {
|
||||
|
||||
@@ -72,7 +81,9 @@ public class OrderService {
|
||||
</div>
|
||||
|
||||
<div class="problems">
|
||||
<div class="problem-title">😫 贫血模型的问题</div>
|
||||
<div class="problem-title">
|
||||
😫 贫血模型的问题
|
||||
</div>
|
||||
<ul>
|
||||
<li><strong>违背面向对象</strong>:对象只有数据没有行为,变成了 "数据结构"</li>
|
||||
<li><strong>逻辑分散</strong>:同样的业务规则可能在多个 Service 重复</li>
|
||||
@@ -90,7 +101,9 @@ public class OrderService {
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<div class="code-section">
|
||||
<div class="code-label">Entity(包含业务逻辑)</div>
|
||||
<div class="code-label">
|
||||
Entity(包含业务逻辑)
|
||||
</div>
|
||||
<pre><code>@Entity
|
||||
public class Order {
|
||||
@Id
|
||||
@@ -139,7 +152,9 @@ public class Order {
|
||||
</div>
|
||||
|
||||
<div class="code-section">
|
||||
<div class="code-label">Service(只做协调,不做业务判断)</div>
|
||||
<div class="code-label">
|
||||
Service(只做协调,不做业务判断)
|
||||
</div>
|
||||
<pre><code>@Service
|
||||
@RequiredArgsConstructor
|
||||
public class OrderService {
|
||||
@@ -168,7 +183,9 @@ public class OrderService {
|
||||
</div>
|
||||
|
||||
<div class="benefits">
|
||||
<div class="benefit-title">😊 充血模型的优势</div>
|
||||
<div class="benefit-title">
|
||||
😊 充血模型的优势
|
||||
</div>
|
||||
<ul>
|
||||
<li><strong>符合面向对象</strong>:数据和行为封装在一起,是真正的 "对象"</li>
|
||||
<li><strong>业务内聚</strong>:规则跟着对象走,改一处处处生效</li>
|
||||
@@ -182,7 +199,10 @@ public class OrderService {
|
||||
</div>
|
||||
|
||||
<!-- 值对象 -->
|
||||
<div v-else-if="currentTab === 'valueobject'" class="tab-panel">
|
||||
<div
|
||||
v-else-if="currentTab === 'valueobject'"
|
||||
class="tab-panel"
|
||||
>
|
||||
<div class="value-object-content">
|
||||
<div class="concept-intro">
|
||||
<h5>💎 什么是值对象(Value Object)?</h5>
|
||||
@@ -191,7 +211,9 @@ public class OrderService {
|
||||
|
||||
<div class="vo-examples">
|
||||
<div class="example-card">
|
||||
<div class="example-title">📍 地址 Address</div>
|
||||
<div class="example-title">
|
||||
📍 地址 Address
|
||||
</div>
|
||||
<pre><code>// 值对象:不可变、无 ID
|
||||
public record Address(
|
||||
String province, // 省
|
||||
@@ -221,7 +243,9 @@ System.out.println(addr1.equals(addr2)); // true - 值对象比较的是值</cod
|
||||
</div>
|
||||
|
||||
<div class="example-card">
|
||||
<div class="example-title">💰 金钱 Money</div>
|
||||
<div class="example-title">
|
||||
💰 金钱 Money
|
||||
</div>
|
||||
<pre><code>// 金钱是经典的值对象
|
||||
public record Money(
|
||||
BigDecimal amount,
|
||||
|
||||
+36
-12
@@ -2,13 +2,17 @@
|
||||
<div class="dto-flow-demo">
|
||||
<div class="demo-header">
|
||||
<h4>🔄 DTO 流转:数据在不同层之间的转换</h4>
|
||||
<p class="subtitle">DTO(Data Transfer Object)是层与层之间传递数据的载体</p>
|
||||
<p class="subtitle">
|
||||
DTO(Data Transfer Object)是层与层之间传递数据的载体
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- 流程图 -->
|
||||
<div class="flow-diagram">
|
||||
<div class="flow-step">
|
||||
<div class="step-title">Controller 层</div>
|
||||
<div class="step-title">
|
||||
Controller 层
|
||||
</div>
|
||||
<div class="step-code">
|
||||
<div class="code-line">
|
||||
<span class="comment">// 接收 Request DTO</span>
|
||||
@@ -25,10 +29,14 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flow-arrow">⬇️ 转换为 Service 需要的参数</div>
|
||||
<div class="flow-arrow">
|
||||
⬇️ 转换为 Service 需要的参数
|
||||
</div>
|
||||
|
||||
<div class="flow-step">
|
||||
<div class="step-title">Service 层</div>
|
||||
<div class="step-title">
|
||||
Service 层
|
||||
</div>
|
||||
<div class="step-code">
|
||||
<div class="code-line">
|
||||
<span class="comment">// 业务处理</span>
|
||||
@@ -54,10 +62,14 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flow-arrow">⬇️ 转换为 Repository 需要的 Entity</div>
|
||||
<div class="flow-arrow">
|
||||
⬇️ 转换为 Repository 需要的 Entity
|
||||
</div>
|
||||
|
||||
<div class="flow-step">
|
||||
<div class="step-title">Repository 层</div>
|
||||
<div class="step-title">
|
||||
Repository 层
|
||||
</div>
|
||||
<div class="step-code">
|
||||
<div class="code-line">
|
||||
<span class="comment">// 数据持久化</span>
|
||||
@@ -74,10 +86,14 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flow-arrow">⬆️ 返回 Entity,转换为 DTO</div>
|
||||
<div class="flow-arrow">
|
||||
⬆️ 返回 Entity,转换为 DTO
|
||||
</div>
|
||||
|
||||
<div class="flow-step">
|
||||
<div class="step-title">返回给客户端</div>
|
||||
<div class="step-title">
|
||||
返回给客户端
|
||||
</div>
|
||||
<div class="step-code">
|
||||
<div class="code-line">
|
||||
<span class="comment">// Response DTO</span>
|
||||
@@ -109,10 +125,18 @@
|
||||
<h5>📋 不同层的 DTO 职责</h5>
|
||||
<div class="comparison-table">
|
||||
<div class="table-header">
|
||||
<div class="col-layer">层级</div>
|
||||
<div class="col-dto">DTO 类型</div>
|
||||
<div class="col-purpose">职责</div>
|
||||
<div class="col-example">示例</div>
|
||||
<div class="col-layer">
|
||||
层级
|
||||
</div>
|
||||
<div class="col-dto">
|
||||
DTO 类型
|
||||
</div>
|
||||
<div class="col-purpose">
|
||||
职责
|
||||
</div>
|
||||
<div class="col-example">
|
||||
示例
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-row">
|
||||
<div class="col-layer">
|
||||
|
||||
+67
-21
@@ -4,11 +4,19 @@
|
||||
<!-- 客户端 -->
|
||||
<div class="client-layer">
|
||||
<div class="layer-box client">
|
||||
<div class="layer-icon">🌐</div>
|
||||
<div class="layer-title">客户端</div>
|
||||
<div class="layer-desc">Web / App / 小程序</div>
|
||||
<div class="layer-icon">
|
||||
🌐
|
||||
</div>
|
||||
<div class="layer-title">
|
||||
客户端
|
||||
</div>
|
||||
<div class="layer-desc">
|
||||
Web / App / 小程序
|
||||
</div>
|
||||
</div>
|
||||
<div class="arrow-down">
|
||||
⬇️ HTTP/HTTPS
|
||||
</div>
|
||||
<div class="arrow-down">⬇️ HTTP/HTTPS</div>
|
||||
</div>
|
||||
|
||||
<!-- 后端分层 -->
|
||||
@@ -25,12 +33,18 @@
|
||||
<span class="layer-badge">入口</span>
|
||||
</div>
|
||||
<div class="layer-content">
|
||||
<div class="duty">职责:接收请求、参数校验、调用 Service</div>
|
||||
<div class="tech">技术:Spring MVC / Gin / Echo</div>
|
||||
<div class="duty">
|
||||
职责:接收请求、参数校验、调用 Service
|
||||
</div>
|
||||
<div class="tech">
|
||||
技术:Spring MVC / Gin / Echo
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="arrow-down">⬇️ 调用</div>
|
||||
<div class="arrow-down">
|
||||
⬇️ 调用
|
||||
</div>
|
||||
|
||||
<!-- Service 层 -->
|
||||
<div
|
||||
@@ -44,12 +58,18 @@
|
||||
<span class="layer-badge">业务核心</span>
|
||||
</div>
|
||||
<div class="layer-content">
|
||||
<div class="duty">职责:业务逻辑编排、事务管理、跨模块协调</div>
|
||||
<div class="tech">技术:纯代码逻辑 / 无框架依赖</div>
|
||||
<div class="duty">
|
||||
职责:业务逻辑编排、事务管理、跨模块协调
|
||||
</div>
|
||||
<div class="tech">
|
||||
技术:纯代码逻辑 / 无框架依赖
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="arrow-down">⬇️ 调用</div>
|
||||
<div class="arrow-down">
|
||||
⬇️ 调用
|
||||
</div>
|
||||
|
||||
<!-- Repository 层 -->
|
||||
<div
|
||||
@@ -63,12 +83,18 @@
|
||||
<span class="layer-badge">数据访问</span>
|
||||
</div>
|
||||
<div class="layer-content">
|
||||
<div class="duty">职责:数据持久化、查询封装、ORM 映射</div>
|
||||
<div class="tech">技术:MyBatis / GORM / Hibernate</div>
|
||||
<div class="duty">
|
||||
职责:数据持久化、查询封装、ORM 映射
|
||||
</div>
|
||||
<div class="tech">
|
||||
技术:MyBatis / GORM / Hibernate
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="arrow-down">⬇️ SQL</div>
|
||||
<div class="arrow-down">
|
||||
⬇️ SQL
|
||||
</div>
|
||||
|
||||
<!-- Domain 层 -->
|
||||
<div
|
||||
@@ -82,23 +108,38 @@
|
||||
<span class="layer-badge">领域模型</span>
|
||||
</div>
|
||||
<div class="layer-content">
|
||||
<div class="duty">职责:实体定义、业务规则、值对象</div>
|
||||
<div class="tech">技术:POJO / Struct / Class</div>
|
||||
<div class="duty">
|
||||
职责:实体定义、业务规则、值对象
|
||||
</div>
|
||||
<div class="tech">
|
||||
技术:POJO / Struct / Class
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="arrow-down">⬇️ 持久化</div>
|
||||
<div class="arrow-down">
|
||||
⬇️ 持久化
|
||||
</div>
|
||||
|
||||
<!-- 数据库 -->
|
||||
<div class="layer-box database">
|
||||
<div class="layer-icon">💾</div>
|
||||
<div class="layer-title">数据库</div>
|
||||
<div class="layer-desc">MySQL / PostgreSQL / MongoDB</div>
|
||||
<div class="layer-icon">
|
||||
💾
|
||||
</div>
|
||||
<div class="layer-title">
|
||||
数据库
|
||||
</div>
|
||||
<div class="layer-desc">
|
||||
MySQL / PostgreSQL / MongoDB
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧说明面板 -->
|
||||
<div class="info-panel" v-if="activeLayer">
|
||||
<div
|
||||
v-if="activeLayer"
|
||||
class="info-panel"
|
||||
>
|
||||
<h4>{{ layerInfo.title }}</h4>
|
||||
<p>{{ layerInfo.description }}</p>
|
||||
<div class="analogy">
|
||||
@@ -107,7 +148,12 @@
|
||||
<div class="common-mistakes">
|
||||
<strong>⚠️ 常见错误:</strong>
|
||||
<ul>
|
||||
<li v-for="mistake in layerInfo.mistakes" :key="mistake">{{ mistake }}</li>
|
||||
<li
|
||||
v-for="mistake in layerInfo.mistakes"
|
||||
:key="mistake"
|
||||
>
|
||||
{{ mistake }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+41
-13
@@ -2,7 +2,9 @@
|
||||
<div class="repository-layer-demo">
|
||||
<div class="demo-header">
|
||||
<h4>🗄️ Repository 层:数据的"仓库管理员"</h4>
|
||||
<p class="subtitle">Repository 封装数据访问逻辑,让上层无需关心数据库细节</p>
|
||||
<p class="subtitle">
|
||||
Repository 封装数据访问逻辑,让上层无需关心数据库细节
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- 对比演示 -->
|
||||
@@ -26,7 +28,10 @@
|
||||
|
||||
<div class="comparison-content">
|
||||
<!-- 糟糕的做法 -->
|
||||
<div v-if="viewMode === 'bad'" class="code-panel bad">
|
||||
<div
|
||||
v-if="viewMode === 'bad'"
|
||||
class="code-panel bad"
|
||||
>
|
||||
<div class="panel-header">
|
||||
<span class="panel-title">😫 在 Service 里直接写 SQL</span>
|
||||
<span class="panel-badge">耦合严重</span>
|
||||
@@ -75,7 +80,10 @@ public class OrderService {
|
||||
</div>
|
||||
|
||||
<!-- 优雅的做法 -->
|
||||
<div v-else class="code-panel good">
|
||||
<div
|
||||
v-else
|
||||
class="code-panel good"
|
||||
>
|
||||
<div class="panel-header">
|
||||
<span class="panel-title">😊 使用 Repository 封装数据访问</span>
|
||||
<span class="panel-badge">清晰解耦</span>
|
||||
@@ -191,16 +199,26 @@ public class OrderService {
|
||||
|
||||
<div class="comparison-table">
|
||||
<div class="table-header">
|
||||
<div class="col-method">实现方式</div>
|
||||
<div class="col-pros">优点</div>
|
||||
<div class="col-cons">缺点</div>
|
||||
<div class="col-scene">适用场景</div>
|
||||
<div class="col-method">
|
||||
实现方式
|
||||
</div>
|
||||
<div class="col-pros">
|
||||
优点
|
||||
</div>
|
||||
<div class="col-cons">
|
||||
缺点
|
||||
</div>
|
||||
<div class="col-scene">
|
||||
适用场景
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-row">
|
||||
<div class="col-method">
|
||||
<strong>Spring Data JPA</strong>
|
||||
<div class="method-tag">主流方案</div>
|
||||
<div class="method-tag">
|
||||
主流方案
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-pros">
|
||||
<ul>
|
||||
@@ -215,13 +233,17 @@ public class OrderService {
|
||||
<li>学习曲线较陡</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-scene">快速开发、标准 CRUD 业务</div>
|
||||
<div class="col-scene">
|
||||
快速开发、标准 CRUD 业务
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-row">
|
||||
<div class="col-method">
|
||||
<strong>MyBatis / MyBatis-Plus</strong>
|
||||
<div class="method-tag tag-blue">国内主流</div>
|
||||
<div class="method-tag tag-blue">
|
||||
国内主流
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-pros">
|
||||
<ul>
|
||||
@@ -236,13 +258,17 @@ public class OrderService {
|
||||
<li>样板代码较多</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-scene">复杂查询、性能敏感业务</div>
|
||||
<div class="col-scene">
|
||||
复杂查询、性能敏感业务
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-row">
|
||||
<div class="col-method">
|
||||
<strong>Spring Data JDBC</strong>
|
||||
<div class="method-tag tag-green">轻量</div>
|
||||
<div class="method-tag tag-green">
|
||||
轻量
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-pros">
|
||||
<ul>
|
||||
@@ -257,7 +283,9 @@ public class OrderService {
|
||||
<li>功能较简单</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-scene">微服务、简单聚合根场景</div>
|
||||
<div class="col-scene">
|
||||
微服务、简单聚合根场景
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+50
-17
@@ -2,12 +2,16 @@
|
||||
<div class="service-layer-demo">
|
||||
<div class="demo-header">
|
||||
<h4>⚙️ Service 层:业务逻辑的"指挥家"</h4>
|
||||
<p class="subtitle">Service 层编排业务逻辑,协调多个 Repository,管理事务边界</p>
|
||||
<p class="subtitle">
|
||||
Service 层编排业务逻辑,协调多个 Repository,管理事务边界
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- 场景选择器 -->
|
||||
<div class="scenario-selector">
|
||||
<div class="selector-label">选择业务场景:</div>
|
||||
<div class="selector-label">
|
||||
选择业务场景:
|
||||
</div>
|
||||
<div class="scenario-buttons">
|
||||
<button
|
||||
v-for="scenario in scenarios"
|
||||
@@ -36,34 +40,57 @@
|
||||
@click="toggleStep(index)"
|
||||
>
|
||||
<div class="step-header">
|
||||
<div class="step-number">{{ index + 1 }}</div>
|
||||
<div class="step-info">
|
||||
<div class="step-name">{{ step.name }}</div>
|
||||
<div class="step-layer">{{ step.layer }}</div>
|
||||
<div class="step-number">
|
||||
{{ index + 1 }}
|
||||
</div>
|
||||
<div v-if="step.subSteps" class="expand-icon">
|
||||
<div class="step-info">
|
||||
<div class="step-name">
|
||||
{{ step.name }}
|
||||
</div>
|
||||
<div class="step-layer">
|
||||
{{ step.layer }}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="step.subSteps"
|
||||
class="expand-icon"
|
||||
>
|
||||
{{ expandedSteps.includes(index) ? '▼' : '▶' }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="step.code" class="step-code">
|
||||
<div
|
||||
v-if="step.code"
|
||||
class="step-code"
|
||||
>
|
||||
<pre><code>{{ step.code }}</code></pre>
|
||||
</div>
|
||||
|
||||
<!-- 子步骤(事务管理) -->
|
||||
<div v-if="step.subSteps && expandedSteps.includes(index)" class="sub-steps">
|
||||
<div
|
||||
v-if="step.subSteps && expandedSteps.includes(index)"
|
||||
class="sub-steps"
|
||||
>
|
||||
<div
|
||||
v-for="(subStep, subIndex) in step.subSteps"
|
||||
:key="subIndex"
|
||||
class="sub-step"
|
||||
:class="subStep.status"
|
||||
>
|
||||
<div class="sub-step-icon">{{ subStep.icon }}</div>
|
||||
<div class="sub-step-content">
|
||||
<div class="sub-step-name">{{ subStep.name }}</div>
|
||||
<div class="sub-step-desc">{{ subStep.desc }}</div>
|
||||
<div class="sub-step-icon">
|
||||
{{ subStep.icon }}
|
||||
</div>
|
||||
<div class="sub-step-content">
|
||||
<div class="sub-step-name">
|
||||
{{ subStep.name }}
|
||||
</div>
|
||||
<div class="sub-step-desc">
|
||||
{{ subStep.desc }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="sub-step-status">
|
||||
{{ subStep.statusText }}
|
||||
</div>
|
||||
<div class="sub-step-status">{{ subStep.statusText }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -79,9 +106,15 @@
|
||||
:key="principle.id"
|
||||
class="principle-card"
|
||||
>
|
||||
<div class="principle-icon">{{ principle.icon }}</div>
|
||||
<div class="principle-title">{{ principle.title }}</div>
|
||||
<div class="principle-desc">{{ principle.desc }}</div>
|
||||
<div class="principle-icon">
|
||||
{{ principle.icon }}
|
||||
</div>
|
||||
<div class="principle-title">
|
||||
{{ principle.title }}
|
||||
</div>
|
||||
<div class="principle-desc">
|
||||
{{ principle.desc }}
|
||||
</div>
|
||||
<div class="principle-example">
|
||||
<code>{{ principle.example }}</code>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user