# Mobile Upgrade Admin - 开发指南

## 环境要求

| 工具 | 版本 | 说明 |
|------|------|------|
| Node.js | >= 18.x | 运行环境 |
| npm | >= 9.x | 包管理器 |
| Git | >= 2.x | 版本控制 |

## 快速开始

### 1. 克隆项目

```bash
git clone https://git.gdzx.xyz/hailin/rwadurian.git
cd rwadurian/frontend/mobile-upgrade
```

### 2. 安装依赖

```bash
npm install
```

### 3. 配置环境变量

```bash
# 复制环境变量模板
cp .env.local.example .env.local

# 编辑配置
# NEXT_PUBLIC_API_URL=http://localhost:3000
```

### 4. 启动开发服务器

```bash
npm run dev
```

访问 http://localhost:3000 查看应用。

## 项目脚本

```bash
# 开发模式
npm run dev

# 生产构建
npm run build

# 启动生产服务
npm run start

# 代码检查
npm run lint

# 类型检查
npm run type-check
```

## 开发规范

### 目录结构规范

```
src/
├── domain/           # 领域层：纯 TypeScript，无框架依赖
├── infrastructure/   # 基础设施层：外部服务交互
├── application/      # 应用层：业务逻辑和状态管理
├── presentation/     # 表示层：React 组件
└── app/              # Next.js 页面路由
```

### 命名规范

| 类型 | 规范 | 示例 |
|------|------|------|
| 文件名 | kebab-case | `version-card.tsx` |
| 组件名 | PascalCase | `VersionCard` |
| 函数名 | camelCase | `fetchVersions` |
| 常量 | UPPER_SNAKE_CASE | `API_BASE_URL` |
| 类型/接口 | PascalCase | `AppVersion` |

### 代码风格

项目使用 ESLint + Prettier 进行代码规范检查。

```json
// .eslintrc.json
{
  "extends": ["next/core-web-vitals"]
}
```

## 开发流程

### 1. 新增功能开发流程

```
1. 在 Domain 层定义实体和接口
2. 在 Infrastructure 层实现 API 调用
3. 在 Application 层添加状态管理逻辑
4. 在 Presentation 层创建 UI 组件
5. 编写测试用例
6. 提交代码
```

### 2. 示例：添加新的 API 功能

#### Step 1: Domain 层 - 定义类型

```typescript
// src/domain/entities/version.ts
export interface BatchDeleteInput {
  ids: string[]
}
```

#### Step 2: Domain 层 - 定义接口

```typescript
// src/domain/repositories/version-repository.ts
export interface IVersionRepository {
  // ... 现有方法
  batchDelete(input: BatchDeleteInput): Promise<void>
}
```

#### Step 3: Infrastructure 层 - 实现接口

```typescript
// src/infrastructure/repositories/version-repository-impl.ts
export class VersionRepositoryImpl implements IVersionRepository {
  // ... 现有方法

  async batchDelete(input: BatchDeleteInput): Promise<void> {
    await this.client.post('/api/v1/versions/batch-delete', input)
  }
}
```

#### Step 4: Application 层 - 添加状态管理

```typescript
// src/application/stores/version-store.ts
interface VersionState {
  // ... 现有状态
  batchDeleteVersions: (ids: string[]) => Promise<void>
}

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

  batchDeleteVersions: async (ids: string[]) => {
    set({ isLoading: true, error: null })
    try {
      await versionRepository.batchDelete({ ids })
      const { versions } = get()
      set({
        versions: versions.filter((v) => !ids.includes(v.id)),
        isLoading: false,
      })
    } catch (err) {
      set({
        error: err instanceof Error ? err.message : 'Failed to delete',
        isLoading: false,
      })
      throw err
    }
  },
}))
```

#### Step 5: Application 层 - 添加 Hook

```typescript
// src/application/hooks/use-versions.ts
export function useVersionActions() {
  const { batchDeleteVersions, ... } = useVersionStore()

  return {
    batchDelete: batchDeleteVersions,
    // ... 其他方法
  }
}
```

#### Step 6: Presentation 层 - 使用

```typescript
// src/presentation/components/batch-actions.tsx
export function BatchActions({ selectedIds }: { selectedIds: string[] }) {
  const { batchDelete } = useVersionActions()

  const handleBatchDelete = async () => {
    try {
      await batchDelete(selectedIds)
      toast.success('批量删除成功')
    } catch (err) {
      toast.error('批量删除失败')
    }
  }

  return (
    <button onClick={handleBatchDelete}>
      批量删除 ({selectedIds.length})
    </button>
  )
}
```

## 状态管理

### Zustand Store 设计

```typescript
// 状态结构
interface VersionState {
  // 数据状态
  versions: AppVersion[]
  selectedVersion: AppVersion | null

  // UI 状态
  isLoading: boolean
  error: string | null

  // 筛选状态
  filter: {
    platform?: Platform
    includeDisabled: boolean
  }

  // Actions
  fetchVersions: () => Promise<void>
  setFilter: (filter: Partial<VersionState['filter']>) => void
  clearError: () => void
}
```

### 使用 Hooks

```typescript
// 在组件中使用
function VersionList() {
  const { versions, isLoading, error, refetch, setFilter } = useVersions()
  const { deleteVersion, toggleVersion } = useVersionActions()

  // 筛选
  const handleFilterChange = (platform: Platform | 'all') => {
    setFilter({ platform: platform === 'all' ? undefined : platform })
  }

  // 删除
  const handleDelete = async (id: string) => {
    await deleteVersion(id)
    refetch()
  }

  return (/* JSX */)
}
```

## 组件开发

### 组件结构规范

```typescript
'use client'

import { useState, useEffect } from 'react'
import { useVersions } from '@/application'
import { AppVersion } from '@/domain'

// Props 接口定义
interface VersionCardProps {
  version: AppVersion
  onEdit: () => void
  onDelete: () => void
}

// 组件实现
export function VersionCard({ version, onEdit, onDelete }: VersionCardProps) {
  // Hooks
  const [isExpanded, setIsExpanded] = useState(false)

  // 事件处理
  const handleToggle = () => {
    setIsExpanded(!isExpanded)
  }

  // 渲染
  return (
    <div className="card">
      {/* 组件内容 */}
    </div>
  )
}
```

### 样式规范

使用 Tailwind CSS 原子类：

```tsx
// 推荐
<button className="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700">
  提交
</button>

// 复用样式定义在 globals.css
<button className="btn btn-primary">提交</button>
```

全局样式定义：

```css
/* src/app/globals.css */
@layer components {
  .btn {
    @apply px-4 py-2 rounded-lg font-medium transition-colors;
  }
  .btn-primary {
    @apply bg-blue-600 text-white hover:bg-blue-700;
  }
  .card {
    @apply bg-white rounded-lg shadow-sm border p-6;
  }
  .input {
    @apply w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500;
  }
}
```

## 调试技巧

### 1. React DevTools

安装浏览器扩展查看组件树和状态。

### 2. Zustand DevTools

```typescript
import { devtools } from 'zustand/middleware'

export const useVersionStore = create<VersionState>()(
  devtools(
    (set, get) => ({
      // store 实现
    }),
    { name: 'version-store' }
  )
)
```

### 3. API 请求调试

```typescript
// 在 api-client.ts 添加请求日志
apiClient.interceptors.request.use((config) => {
  console.log('API Request:', config.method?.toUpperCase(), config.url)
  return config
})

apiClient.interceptors.response.use(
  (response) => {
    console.log('API Response:', response.status, response.config.url)
    return response
  },
  (error) => {
    console.error('API Error:', error.response?.status, error.config.url)
    return Promise.reject(error)
  }
)
```

## 常见问题

### 1. 类型错误

确保导入路径使用别名：

```typescript
// 正确
import { AppVersion } from '@/domain'

// 错误
import { AppVersion } from '../../../domain/entities/version'
```

### 2. 环境变量不生效

Next.js 要求客户端环境变量以 `NEXT_PUBLIC_` 开头：

```bash
# 正确 - 客户端可访问
NEXT_PUBLIC_API_URL=http://localhost:3000

# 错误 - 仅服务端可访问
API_URL=http://localhost:3000
```

### 3. 热更新不工作

```bash
# 删除 .next 缓存目录
rm -rf .next
npm run dev
```

## 相关文档

- [架构文档](./ARCHITECTURE.md)
- [API 文档](./API.md)
- [测试指南](./TESTING.md)
- [部署指南](./DEPLOYMENT.md)
