# 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`) ```typescript // 平台类型 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`) ```typescript export interface IVersionRepository { list(filter?: VersionListFilter): Promise getById(id: string): Promise create(input: CreateVersionInput): Promise update(id: string, input: UpdateVersionInput): Promise delete(id: string): Promise toggle(id: string, isEnabled: boolean): Promise upload(input: UploadVersionInput): Promise } ``` ### 2. Infrastructure Layer(基础设施层) **职责**:实现与外部系统的交互(API、数据库等)。 #### API 客户端 (`http/api-client.ts`) ```typescript 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`) ```typescript export class VersionRepositoryImpl implements IVersionRepository { private client: AxiosInstance constructor(client?: AxiosInstance) { this.client = client || apiClient } async list(filter?: VersionListFilter): Promise { const response = await this.client.get('/api/v1/versions', { params: filter }) return response.data } async upload(input: UploadVersionInput): Promise { const formData = new FormData() formData.append('file', input.file) // ... 其他字段 const response = await this.client.post('/api/v1/versions/upload', formData) return response.data } // ... 其他方法 } ``` ### 3. Application Layer(应用层) **职责**:协调业务逻辑,管理应用状态。 #### Zustand Store (`stores/version-store.ts`) ```typescript import { create } from 'zustand' interface VersionState { // 状态 versions: AppVersion[] selectedVersion: AppVersion | null isLoading: boolean error: string | null filter: { platform?: Platform; includeDisabled: boolean } // Actions fetchVersions: () => Promise createVersion: (input: CreateVersionInput) => Promise updateVersion: (id: string, input: UpdateVersionInput) => Promise deleteVersion: (id: string) => Promise toggleVersion: (id: string, isEnabled: boolean) => Promise uploadVersion: (input: UploadVersionInput) => Promise } export const useVersionStore = create((set, get) => ({ // 实现... })) ``` #### React Hooks (`hooks/use-versions.ts`) ```typescript // 获取版本列表 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) ## 相关文档 - [API 文档](./API.md) - [开发指南](./DEVELOPMENT.md) - [测试指南](./TESTING.md) - [部署指南](./DEPLOYMENT.md)