rwadurian/frontend/mobile-upgrade/docs/ARCHITECTURE.md

11 KiB
Raw Blame History

Mobile Upgrade Admin - 架构文档

概述

Mobile Upgrade Admin 是一个用于管理移动应用版本升级的 Web 管理后台。本项目采用 Clean Architecture整洁架构 设计模式,实现了关注点分离、可测试性和可维护性。

技术栈

分类 技术 版本 说明
框架 Next.js 14.x React 全栈框架App Router
语言 TypeScript 5.x 类型安全
状态管理 Zustand 4.x 轻量级状态管理
HTTP 客户端 Axios 1.x API 请求
样式 Tailwind CSS 3.x 原子化 CSS
通知 react-hot-toast 2.x Toast 通知

架构设计

Clean Architecture 分层

┌─────────────────────────────────────────────────────────────┐
│                    Presentation Layer                        │
│                   (UI Components, Pages)                     │
├─────────────────────────────────────────────────────────────┤
│                    Application Layer                         │
│               (Stores, Hooks, Use Cases)                     │
├─────────────────────────────────────────────────────────────┤
│                      Domain Layer                            │
│            (Entities, Repository Interfaces)                 │
├─────────────────────────────────────────────────────────────┤
│                   Infrastructure Layer                       │
│           (API Client, Repository Implementations)           │
└─────────────────────────────────────────────────────────────┘

目录结构

src/
├── domain/                          # 领域层 - 业务核心
│   ├── entities/
│   │   └── version.ts               # 版本实体和类型定义
│   ├── repositories/
│   │   └── version-repository.ts    # Repository 接口定义
│   └── index.ts                     # 统一导出
│
├── infrastructure/                  # 基础设施层 - 外部依赖
│   ├── http/
│   │   └── api-client.ts            # Axios 客户端配置
│   ├── repositories/
│   │   └── version-repository-impl.ts # Repository 实现
│   └── index.ts                     # 统一导出
│
├── application/                     # 应用层 - 业务逻辑
│   ├── stores/
│   │   └── version-store.ts         # Zustand 状态管理
│   ├── hooks/
│   │   └── use-versions.ts          # React Hooks
│   └── index.ts                     # 统一导出
│
├── presentation/                    # 表示层 - UI 组件
│   ├── components/
│   │   ├── version-card.tsx         # 版本卡片组件
│   │   ├── upload-modal.tsx         # 上传弹窗组件
│   │   └── edit-modal.tsx           # 编辑弹窗组件
│   └── index.ts                     # 统一导出
│
└── app/                             # Next.js App Router
    ├── layout.tsx                   # 根布局
    ├── page.tsx                     # 首页
    └── globals.css                  # 全局样式

各层职责详解

1. Domain Layer领域层

职责:定义业务实体和接口,不依赖任何外部框架。

实体定义 (entities/version.ts)

// 平台类型
export type Platform = 'android' | 'ios'

// 应用版本实体
export interface AppVersion {
  id: string
  platform: Platform
  versionCode: number
  versionName: string
  buildNumber: string
  downloadUrl: string
  fileSize: string
  fileSha256: string
  changelog: string
  isForceUpdate: boolean
  isEnabled: boolean
  minOsVersion: string | null
  releaseDate: string | null
  createdAt: string
  updatedAt: string
}

// 输入/输出 DTO
export interface CreateVersionInput { ... }
export interface UpdateVersionInput { ... }
export interface UploadVersionInput { ... }
export interface VersionListFilter { ... }

Repository 接口 (repositories/version-repository.ts)

export interface IVersionRepository {
  list(filter?: VersionListFilter): Promise<AppVersion[]>
  getById(id: string): Promise<AppVersion>
  create(input: CreateVersionInput): Promise<AppVersion>
  update(id: string, input: UpdateVersionInput): Promise<AppVersion>
  delete(id: string): Promise<void>
  toggle(id: string, isEnabled: boolean): Promise<void>
  upload(input: UploadVersionInput): Promise<AppVersion>
}

2. Infrastructure Layer基础设施层

职责实现与外部系统的交互API、数据库等

API 客户端 (http/api-client.ts)

import axios from 'axios'

export const apiClient = axios.create({
  baseURL: process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3000',
  timeout: 30000,
  headers: {
    'Content-Type': 'application/json',
  },
})

// 响应拦截器处理错误
apiClient.interceptors.response.use(
  (response) => response,
  (error) => {
    const message = error.response?.data?.message || '请求失败'
    return Promise.reject(new Error(message))
  }
)

Repository 实现 (repositories/version-repository-impl.ts)

export class VersionRepositoryImpl implements IVersionRepository {
  private client: AxiosInstance

  constructor(client?: AxiosInstance) {
    this.client = client || apiClient
  }

  async list(filter?: VersionListFilter): Promise<AppVersion[]> {
    const response = await this.client.get<AppVersion[]>('/api/v1/versions', { params: filter })
    return response.data
  }

  async upload(input: UploadVersionInput): Promise<AppVersion> {
    const formData = new FormData()
    formData.append('file', input.file)
    // ... 其他字段
    const response = await this.client.post<AppVersion>('/api/v1/versions/upload', formData)
    return response.data
  }
  // ... 其他方法
}

3. Application Layer应用层

职责:协调业务逻辑,管理应用状态。

Zustand Store (stores/version-store.ts)

import { create } from 'zustand'

interface VersionState {
  // 状态
  versions: AppVersion[]
  selectedVersion: AppVersion | null
  isLoading: boolean
  error: string | null
  filter: { platform?: Platform; includeDisabled: boolean }

  // Actions
  fetchVersions: () => Promise<void>
  createVersion: (input: CreateVersionInput) => Promise<AppVersion>
  updateVersion: (id: string, input: UpdateVersionInput) => Promise<AppVersion>
  deleteVersion: (id: string) => Promise<void>
  toggleVersion: (id: string, isEnabled: boolean) => Promise<void>
  uploadVersion: (input: UploadVersionInput) => Promise<AppVersion>
}

export const useVersionStore = create<VersionState>((set, get) => ({
  // 实现...
}))

React Hooks (hooks/use-versions.ts)

// 获取版本列表
export function useVersions() {
  const { versions, isLoading, error, fetchVersions, setFilter } = useVersionStore()

  useEffect(() => {
    fetchVersions()
  }, [filter.platform])

  return { versions, isLoading, error, refetch: fetchVersions, setFilter }
}

// 获取单个版本
export function useVersion(id: string | null) { ... }

// 版本操作
export function useVersionActions() { ... }

4. Presentation Layer表示层

职责UI 渲染和用户交互。

组件结构

presentation/
├── components/
│   ├── version-card.tsx      # 版本信息卡片
│   ├── upload-modal.tsx      # 上传新版本弹窗
│   └── edit-modal.tsx        # 编辑版本弹窗

数据流

┌─────────────┐    ┌─────────────┐    ┌─────────────┐    ┌─────────────┐
│   User      │───▶│ Presentation│───▶│ Application │───▶│Infrastructure│
│  Action     │    │  Component  │    │   Store     │    │  Repository │
└─────────────┘    └─────────────┘    └─────────────┘    └─────────────┘
                          │                   │                   │
                          │                   │                   ▼
                          │                   │           ┌─────────────┐
                          │                   │           │  Admin API  │
                          │                   │           └─────────────┘
                          │                   │                   │
                          │                   ◀───────────────────┘
                          │                   │
                          ◀───────────────────┘
                          │
                   ┌─────────────┐
                   │   UI Update │
                   └─────────────┘

依赖关系

Presentation ──▶ Application ──▶ Domain ◀── Infrastructure
     │                │              │              │
     │                │              │              │
     ▼                ▼              ▼              ▼
  React           Zustand        纯TS接口        Axios
 Next.js          Hooks                         API实现

关键原则

  • Domain 层不依赖任何外部层
  • Infrastructure 依赖 Domain实现接口
  • Application 依赖 Domain使用接口
  • Presentation 依赖 Application使用 Hooks/Store

设计优势

  1. 可测试性每层都可以独立测试Infrastructure 可以被 Mock
  2. 可维护性:关注点分离,修改一层不影响其他层
  3. 可扩展性:新增功能只需在相应层添加代码
  4. 可替换性:可以轻松替换技术实现(如 Axios → Fetch

相关文档