# MeshRay Service 层架构详解

**文档版本**: v1.0  
**更新时间**: 2026-03-24  
**适用范围**: `internal/service/` 模块

---

## 📊 Service 层在整体架构中的位置

```
┌─────────────────────────────────────────────┐
│         Web UI（Vue 3 + Element Plus）        │
└────────────────┬────────────────────────────┘
                 │ REST API / WebSocket
┌────────────────▼────────────────────────────┐
│      API Handler（Gin 接入层）               │
│  - network_handler.go                       │
│  - device_handler.go                        │
│  - user_handler.go                          │
│  - service_handler.go                       │
└────────────────┬────────────────────────────┘
                 │ 函数调用
┌────────────────▼────────────────────────────┐
│     Service Layer（业务逻辑层）⭐核心        │
│  - NetworkService    ← 组网管理             │
│  - DeviceService     ← 设备管理             │
│  - PolicyService     ← 策略管理             │
│  - ExternalService   ← 外部服务管理         │
│  - UserService       ← 用户认证             │
│  - MonitorService    ← 监控告警             │
│  - DDNSService       ← DDNS 同步             │
│  - AuditService      ← 审计日志             │
└──────┬──────────────────────────────────────┘
       │
       ├──────────────────────────────────────┐
       │                                      │
┌──────▼──────┐                      ┌────────▼────────┐
│ Store Layer │                      │  Ctr Layer      │
│ (数据持久化) │                      │  (实时控制)     │
│             │                      │                 │
│ - networks  │                      │ - wgctrl        │
│ - devices   │                      │ - core gRPC     │
│ - policies  │                      │ - 实时调度      │
│ - users     │                      │                 │
│ - services  │                      │                 │
└─────────────┘                      └─────────────────┘
```

**关键点**：
- ✅ **Service 层是业务逻辑的核心**
- ✅ **Ctr 层只是 Service 层调用的一个执行器**
- ✅ **很多 Service 功能完全不依赖 Ctr**（如用户登录、策略校验）

---

## 🎯 Service 层模块划分

### **完整的服务模块清单**

```
internal/service/
├── service.go                  # Service 层总入口和依赖注入
│   type ServiceProvider struct {
│       network    *NetworkService
│       device     *DeviceService
│       policy     *PolicyService
│       external   *ExternalService
│       user       *UserService
│       monitor    *MonitorService
│       ddns       *DDNSService
│       audit      *AuditService
│   }
│
├── network.go                  # 组网管理服务
│   ├── ListNetworks()          []Network           # 获取网络列表
│   ├── CreateNetwork()         (*Network, error)   # 创建网络
│   ├── DeleteNetwork()         error               # 删除网络
│   ├── UpdateNetwork()         error               # 更新网络配置
│   ├── GenerateMeshSeed()      (*MeshSeed, error)  # 生成 MeshSeed
│   ├── ParseMeshSeed()         (*MeshSeed, error)  # 解析 MeshSeed
│   └── JoinNetwork()           error               # 加入网络
│
├── device.go                   # 设备管理服务
│   ├── ListDevices()           []Device            # 设备列表
│   ├── AddDevice()             (*Device, error)    # 添加设备
│   ├── RemoveDevice()          error               # 删除设备
│   ├── RegenerateKey()         error               # 重新生成密钥
│   ├── GetDeviceConfig()       (*WGConfig, error)  # 获取 WG 配置
│   └── ImportDevice()          error               # 导入现有设备
│
├── policy.go                   # 策略管理服务
│   ├── ListPolicies()          []Policy            # 策略列表
│   ├── SetPolicy()             error               # 设置传输策略
│   ├── GetPolicy()             (*Policy, error)    # 获取策略
│   ├── ValidatePolicy()        error               # 验证策略合法性
│   ├── GetEffectivePolicy()    (*Policy, error)    # 获取生效策略
│   └── ResetPolicy()           error               # 重置策略
│
├── external_service.go         # 外部服务管理服务
│   ├── ListServices()          []ExternalService   # 服务列表
│   ├── AddService()            error               # 添加服务
│   ├── UpdateService()         error               # 更新服务
│   ├── DeleteService()         error               # 删除服务
│   ├── TestConnectivity()      error               # 测试连通性
│   ├── GetServiceSchema()      (string, error)     # 获取 JSON Schema
│   └── ListByCategory()        []ExternalService   # 按分类筛选
│
├── user.go                     # 用户认证服务
│   ├── Login()                 (string, error)     # 登录 → JWT Token
│   ├── Register()              error               # 注册
│   ├── ChangePassword()        error               # 修改密码
│   ├── VerifyToken()           (*Claims, error)    # 验证 JWT
│   ├── RefreshToken()          (string, error)     # 刷新 Token
│   └── GetUserByID()           (*User, error)      # 根据 ID 获取用户
│
├── monitor.go                  # 监控告警服务
│   ├── GetSystemStats()        (*SystemStats, error) # 系统统计
│   ├── GetNetworkStatus()      (*NetworkStatus, error) # 网络状态
│   ├── CheckAlertRules()       ([]Alert, error)    # 检查告警规则
│   ├── SendAlert()             error               # 发送告警
│   ├── ListAlertRules()        []AlertRule         # 告警规则列表
│   └── AddAlertRule()          error               # 添加告警规则
│
├── ddns.go                     # DDNS 服务
│   ├── SyncDDNS()              error               # 同步 DDNS 记录
│   ├── GetDDNSStatus()         (*DDNSStatus, error) # 获取状态
│   ├── RefreshDDNS()           error               # 刷新记录
│   ├── TestDNSProvider()       error               # 测试 DNS 服务商
│   └── GetDDNSHistory()        []DDNSRecord        # 历史记录
│
└── audit.go                    # 审计日志服务
    ├── LogAction()             error               # 记录操作日志
    ├── ListAuditLogs()         []AuditLog          # 查询日志
    ├── ExportAuditLogs()       ([]byte, error)     # 导出日志
    ├── GetAuditStats()         (*AuditStats, error) # 统计数据
    └── CleanOldLogs()          error               # 清理旧日志
```

---

## 📋 每个 Service 的职责详解

### **1. NetworkService - 组网管理**

**职责**：
- ✅ 组网的创建、删除、更新
- ✅ MeshSeed 的生成和解析
- ✅ 网络配置的持久化
- ✅ 调用 Ctr 执行实际操作

**核心方法示例**：

```go
// CreateNetwork 创建网络
func (s *NetworkService) CreateNetwork(req CreateNetworkRequest) (*Network, error) {
    // ① 业务规则校验
    if req.Name == "" {
        return nil, errors.New("组网名称不能为空")
    }
    
    // 检查名称是否重复
    var existing Network
    err := s.store.DB().Where("name = ?", req.Name).First(&existing).Error
    if err == nil {
        return nil, errors.New("组网名称已存在")
    }
    
    // ② 数据生成
    networkID := snowflake.Generate()
    secret := generateSecureSecret() // 32 字节随机
    
    // ③ 保存到数据库
    network := &model.Network{
        ID:         networkID,
        Name:       req.Name,
        Secret:     secret,
        Subnet:     req.Subnet,
        STUNServers: []string{"stun.l.google.com:19302"},
        CreatedAt:  time.Now(),
    }
    
    err = s.store.DB().Create(network).Error
    if err != nil {
        return nil, err
    }
    
    // ④ 调用 ctr 执行（事务外，失败需回滚）
    err = s.ctrClient.CreateNetwork(networkID, network.ToConfig())
    if err != nil {
        // 回滚：删除刚创建的 network
        s.store.DB().Delete(network)
        return nil, fmt.Errorf("调用 ctr 失败：%w", err)
    }
    
    return network, nil
}

// GenerateMeshSeed 生成组网凭证
func (s *NetworkService) GenerateMeshSeed(networkID uint64) (*MeshSeed, error) {
    // ① 查询网络信息
    var network model.Network
    err := s.store.DB().First(&network, networkID).Error
    if err != nil {
        return nil, errors.New("网络不存在")
    }
    
    // ② 生成 SeedID（16 字节随机 Base64）
    seedID := generateRandomBase64(16)
    
    // ③ Ed25519 签名
    signature := ed25519.Sign(privateKey, []byte(network.Secret))
    
    // ④ AES-GCM 加密配置
    ciphertext := aesGCM.Encrypt(network.ToJSON())
    
    // ⑤ 构建 MeshSeed
    meshSeed := &MeshSeed{
        SeedID:      seedID,
        NetworkID:   networkID,
        Signature:   signature,
        Ciphertext:  ciphertext,
        IssuedAt:    time.Now(),
        ExpiresAt:   time.Now().Add(365 * 24 * time.Hour),
    }
    
    // ⑥ 保存到数据库
    s.store.DB().Create(&model.MeshSeed{
        NetworkID: networkID,
        Data:      meshSeed.ToJSON(),
    })
    
    return meshSeed, nil
    // ✅ 完全不需要调用 ctr！
}
```

---

### **2. DeviceService - 设备管理**

**职责**：
- ✅ WireGuard 密钥对生成
- ✅ 设备信息管理
- ✅ WG 配置文件生成
- ✅ 调用 Ctr 添加 Peer

**核心方法示例**：

```go
// AddDevice 添加设备
func (s *DeviceService) AddDevice(networkID uint64, name string) (*Device, error) {
    // ① 查询网络
    var network model.Network
    err := s.store.DB().First(&network, networkID).Error
    if err != nil {
        return nil, errors.New("网络不存在")
    }
    
    // ② 生成 WG 密钥对
    privateKey, publicKey, err := wgtypes.GenerateKey()
    if err != nil {
        return nil, err
    }
    
    // ③ 分配 IP（从子网中自动分配）
    ip := allocateIP(network.Subnet)
    
    // ④ 生成设备 ID
    deviceID := snowflake.Generate()
    
    // ⑤ 保存到数据库
    device := &model.Device{
        ID:         deviceID,
        NetworkID:  networkID,
        Name:       name,
        PublicKey:  publicKey.String(),
        PrivateKey: encryptPrivateKey(privateKey), // 加密存储
        IP:         ip,
        AllowedIPs: []string{ip + "/32"},
    }
    
    err = s.store.DB().Create(device).Error
    if err != nil {
        return nil, err
    }
    
    // ⑥ 调用 ctr 添加 Peer（可选，如果立即上线）
    if req.ImmediateConnect {
        err = s.ctrClient.AddPeer(networkID, device.PublicKey, device.AllowedIPs)
        if err != nil {
            s.store.DB().Delete(device)
            return nil, fmt.Errorf("调用 ctr 失败：%w", err)
        }
    }
    
    return device, nil
}

// GetDeviceConfig 获取设备配置（生成 WG 配置文件）
func (s *DeviceService) GetDeviceConfig(deviceID uint64) (string, error) {
    // ① 查询设备信息
    var device model.Device
    err := s.store.DB().Preload("Network").First(&device, deviceID).Error
    if err != nil {
        return "", errors.New("设备不存在")
    }
    
    // ② 解密私钥
    privateKey := decryptPrivateKey(device.PrivateKey)
    
    // ③ 生成 WG 配置
    config := fmt.Sprintf(`[Interface]
PrivateKey = %s
Address = %s
ListenPort = 51820

[Peer]
PublicKey = %s
AllowedIPs = %s
Endpoint = %s:51820
`, privateKey, device.IP, device.Network.PublicKey, device.AllowedIPs, device.Network.Endpoint)
    
    return config, nil
    // ✅ 纯业务逻辑，不需要调用 ctr！
}
```

---

### **3. UserService - 用户认证（完全不依赖 Ctr）**

**职责**：
- ✅ 用户注册、登录
- ✅ JWT Token 生成和验证
- ✅ 密码加密存储
- ✅ 审计日志记录

**核心方法示例**：

```go
// Login 用户登录
func (s *UserService) Login(username, password string) (string, error) {
    // ① 查询用户
    var user model.User
    err := s.store.DB().Where("username = ?", username).First(&user).Error
    if err != nil {
        return "", errors.New("用户名或密码错误")
    }
    
    // ② 验证密码（bcrypt）
    err = bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(password))
    if err != nil {
        return "", errors.New("用户名或密码错误")
    }
    
    // ③ 生成 JWT Token
    claims := jwt.Claims{
        UserID:   user.ID,
        Username: user.Username,
        Role:     user.Role,
    }
    token := jwt.GenerateToken(claims, jwtSecret, 24*time.Hour)
    
    // ④ 记录登录日志
    s.auditService.LogAction(user.ID, "login", "用户登录成功")
    
    return token, nil
    // ✅ 完全不需要调用 ctr！
}

// Register 用户注册
func (s *UserService) Register(username, password, email string) error {
    // ① 检查用户名是否已存在
    var existing model.User
    err := s.store.DB().Where("username = ?", username).First(&existing).Error
    if err == nil {
        return errors.New("用户名已存在")
    }
    
    // ② 密码加密（bcrypt）
    hash, err := bcrypt.GenerateFromPassword([]byte(password), 12)
    if err != nil {
        return err
    }
    
    // ③ 创建用户
    user := &model.User{
        Username:     username,
        Email:        email,
        PasswordHash: string(hash),
        Role:         "user",
    }
    
    err = s.store.DB().Create(user).Error
    if err != nil {
        return err
    }
    
    // ④ 记录注册日志
    s.auditService.LogAction(user.ID, "register", "用户注册成功")
    
    return nil
    // ✅ 完全不需要调用 ctr！
}
```

---

### **4. PolicyService - 策略管理（部分依赖 Ctr）**

**职责**：
- ✅ 9 层传输策略配置
- ✅ 策略合法性校验
- ✅ 策略持久化
- ✅ 调用 Ctr 应用策略

**核心方法示例**：

```go
// SetPolicy 设置传输策略
func (s *PolicyService) SetPolicy(networkID uint64, policy PolicyConfig) error {
    // ① 业务规则校验
    if err := s.validatePolicy(policy); err != nil {
        return fmt.Errorf("策略配置不合法：%w", err)
    }
    
    // ② 保存到数据库
    policyModel := &model.Policy{
        NetworkID: networkID,
        Config:    policy.ToJSON(),
        UpdatedAt: time.Now(),
    }
    
    err := s.store.DB().Save(policyModel).Error
    if err != nil {
        return err
    }
    
    // ③ 调用 ctr 应用策略（可选，如果网络正在运行）
    if network.IsActive {
        err = s.ctrClient.UpdatePolicy(networkID, policy)
        if err != nil {
            return fmt.Errorf("应用策略失败：%w", err)
        }
    }
    
    return nil
}

// validatePolicy 验证策略合法性（纯业务逻辑）
func (s *PolicyService) validatePolicy(policy PolicyConfig) error {
    // 检查至少启用了一层
    if !policy.AnyLayerEnabled() {
        return errors.New("至少需要启用一层传输")
    }
    
    // 检查优先级顺序
    if !policy.IsValidOrder() {
        return errors.New("传输层优先级顺序不合法")
    }
    
    // 检查 STUN/TURN 服务器配置
    if policy.EnableDirectUDP && len(policy.STUNServers) == 0 {
        return errors.New("启用 Direct-UDP 需要配置 STUN 服务器")
    }
    
    if policy.EnableTURN && len(policy.TURNServers) == 0 {
        return errors.New("启用 TURN 需要配置 TURN 服务器")
    }
    
    return nil
    // ✅ 纯业务逻辑校验，不需要调用 ctr！
}
```

---

## 🔄 Service 层的通用模式

### **标准操作流程**

```go
func (s *XXXService) DoSomething(params Params) (Result, error) {
    // ① 业务规则校验
    if err := s.validate(params); err != nil {
        return nil, err
    }
    
    // ② 数据生成/转换
    data := generateData(params)
    
    // ③ 保存到数据库
    err := s.store.DB().Create(&data).Error
    if err != nil {
        return nil, err
    }
    
    // ④ 调用 ctr 执行（可选，放在事务外）
    err = s.ctrClient.DoSomething(data.ID, data.Config)
    if err != nil {
        // 回滚：删除刚创建的数据
        s.store.DB().Delete(&data)
        return nil, fmt.Errorf("调用 ctr 失败：%w", err)
    }
    
    return data, nil
}
```

### **不调用 Ctr 的场景**

以下场景**完全不需要调用 Ctr**：

1. ✅ **用户认证**：Login/Register/VerifyToken
2. ✅ **数据查询**：ListXXX/GetXXX
3. ✅ **配置生成**：GenerateMeshSeed/GetDeviceConfig
4. ✅ **策略校验**：ValidatePolicy
5. ✅ **日志审计**：LogAction/ListAuditLogs
6. ✅ **统计分析**：GetAuditStats/GetSystemStats

---

## 📊 Service 与 Ctr 的职责对比

| 维度 | Service 层 | Ctr 层 |
|------|----------|--------|
| **定位** | 业务逻辑核心 | 实时控制执行器 |
| **职责** | 业务规则、数据生成、持久化 | 执行 WG/Core 操作 |
| **依赖数据库** | ✅ 是（直接操作） | ❌ 否（通过参数接收） |
| **依赖 Ctr** | ⚠️ 部分依赖 | ❌ 不依赖 Service |
| **主动性** | ✅ 主动发起调用 | ❌ 被动执行 |
| **可测试性** | ✅ 可 Mock Ctr | ✅ 可独立测试 |
| **示例方法** | CreateNetwork<br>Login<br>GenerateMeshSeed | CreateDevice<br>AddPeer<br>CreateEngine |

---

## ✅ 总结

### **Service 层的核心价值**

1. ✅ **业务逻辑的承载者**
   - 处理所有业务规则
   - 生成和转换数据
   - 持久化到数据库

2. ✅ **Ctr 层的调用者**
   - 决定何时调用 Ctr
   - 传递必要的参数
   - 处理 Ctr 的返回结果

3. ✅ **前后端的桥梁**
   - 接收 API Handler 的请求
   - 返回处理结果给 Handler
   - 对外暴露完整的业务能力

### **设计原则**

- ✅ **Service 层是核心**：所有业务逻辑都在这里
- ✅ **Ctr 层是工具**：只在需要实时控制时调用
- ✅ **保持解耦**：Service 层可以独立于 Ctr 测试
- ✅ **事务一致性**：Ctr 失败时需要回滚数据库

---

*文档版本：v1.0*  
*最后更新：2026-03-24*  
*维护者：MeshRay Team*
