# Design Document

## Overview

本设计文档描述将 supermart-mini 微信小程序迁移到 React Native/Expo iOS 应用的技术方案。迁移遵循以下原则：
1. 保持与小程序一致的视觉样式和交互体验
2. 复用小程序的 CDN 图片资源（通过 Images 常量配置）
3. 对接相同的后端 API 接口
4. 使用 React Native 的 ImageBackground 组件实现背景图效果

## Architecture

```mermaid
graph TB
    subgraph "React Native App"
        subgraph "Pages (app/)"
            Tabs["Tab Pages<br/>(tabs)"]
            Login["Login Page"]
            Address["Address Pages"]
            Orders["Order Pages"]
            Product["Product Pages"]
        end
        
        subgraph "Components"
            Home["Home Components"]
            ProductComp["Product Components"]
            Common["Common Components"]
        end
        
        subgraph "Services"
            UserService["user.ts"]
            MallService["mall.ts"]
            AwardService["award.ts"]
            AddressService["address.ts"]
            BaseService["base.ts"]
        end
        
        subgraph "Constants"
            Images["images.ts"]
            Theme["theme.ts"]
        end
        
        subgraph "Contexts"
            AuthContext["AuthContext"]
        end
    end
    
    subgraph "Backend API"
        API["REST API Server"]
    end
    
    Tabs --> Services
    Login --> UserService
    Address --> AddressService
    Orders --> MallService
    Product --> MallService
    Services --> API
    Pages --> Images
    Pages --> Components
```

## Components and Interfaces

### 1. 页面组件结构

#### Login Page (`app/login.tsx`)
```typescript
interface LoginScreenProps {}

// 状态
- phone: string           // 手机号
- verifyCode: string      // 验证码
- agreeFlag: boolean      // 协议同意状态
- loading: boolean        // 登录加载状态
- countdown: number       // 验证码倒计时

// 方法
- handleGetVerifyCode()   // 获取验证码
- handleLogin()           // 登录
- goBack()               // 返回
```

#### Mine Page (`app/(tabs)/mine.tsx`)
```typescript
interface MineScreenProps {}

interface IndexData {
  couponCount?: number;
  inventoryCount?: number;
  magicBalance?: number;
  treasureBoxCount?: number;
}

// 状态
- userInfo: UserInfo | null
- indexData: IndexData | null

// 方法
- loadData()              // 加载用户数据
- handleLogin()           // 跳转登录
- handleCopy(text)        // 复制文本
- handleMenuPress(route)  // 菜单点击
- showNumber(key)         // 格式化数字显示
```

#### Address List Page (`app/address/index.tsx`)
```typescript
interface Address {
  id: string;
  contactName: string;
  contactNo: string;
  province: string;
  city: string;
  district: string;
  address: string;
  defaultFlag: number;
}

// 方法
- loadData()              // 加载地址列表
- selectAddress(item)     // 选择地址
- setDefault(item)        // 设为默认
- handleDelete(item)      // 删除地址
- editAddress(item)       // 编辑地址
- addNewAddress()         // 新增地址
```

#### Orders Page (`app/orders/index.tsx`)
```typescript
interface OrderItem {
  tradeNo: string;
  status: number;
  statusText: string;
  goodsName: string;
  goodsCover: string;
  quantity: number;
  paymentAmount: number;
  createTime: string;
}

// Tab 配置
const tabs = [
  { label: '全部', value: undefined },
  { label: '待付款', value: 1 },
  { label: '待发货', value: 2 },
  { label: '待收货', value: 3 },
  { label: '已完成', value: 4 },
];
```

### 2. 服务层接口

#### Address Service (`services/address.ts`)
```typescript
// API 端点
const apis = {
  LIST: '/api/addressBook',
  ADD: '/api/addressBook/add',
  DELETE: '/api/addressBook/delete/{id}',
  DEFAULT: '/api/addressBook/getDefault',
  UPDATE: '/api/addressBook/update',
  GET_AREA: '/api/area',
};

// 方法
export const getAddressList: () => Promise<Address[]>
export const getDefaultAddress: () => Promise<Address | null>
export const addAddress: (params) => Promise<boolean>
export const updateAddress: (params) => Promise<boolean>
export const deleteAddress: (id) => Promise<boolean>
export const getArea: (pid) => Promise<AreaItem[]>
```

#### Award Service (`services/award.ts`)
```typescript
// 新增方法
export const getMagicIndex: () => Promise<IndexData>
export const getPoolList: (params) => Promise<PoolListResponse>
export const getPoolDetail: (poolId) => Promise<PoolDetail>
export const getIPList: () => Promise<IPItem[]>
```

## Data Models

### User Info
```typescript
interface UserInfo {
  id: string;
  nickname: string;
  avatar: string;
  phone?: string;
  realName?: string;
  idNum?: string;
  balance?: number;
}
```

### Address
```typescript
interface Address {
  id: string;
  contactName: string;
  contactNo: string;
  location?: string;
  province: string;
  city: string;
  district: string;
  address: string;
  defaultFlag: number;  // 0: 非默认, 1: 默认
}
```

### Order
```typescript
interface OrderItem {
  tradeNo: string;
  status: number;
  statusText: string;
  goodsName: string;
  goodsCover: string;
  quantity: number;
  paymentAmount: number;
  createTime: string;
}

interface OrderDetail extends OrderItem {
  address?: {
    contactName: string;
    contactNo: string;
    province: string;
    city: string;
    district: string;
    address: string;
  };
  expressInfo?: ExpressInfo[];
}
```

### Pool (奖池)
```typescript
interface PoolItem {
  id: string;
  name: string;
  cover: string;
  price: number;
  mode: string;
}

interface PoolDetail extends PoolItem {
  description?: string;
  prizes?: PrizeItem[];
  boxCount?: number;
}
```

## Correctness Properties

*A property is a characteristic or behavior that should hold true across all valid executions of a system-essentially, a formal statement about what the system should do. Properties serve as the bridge between human-readable specifications and machine-verifiable correctness guarantees.*

Property 1: Login API call with correct parameters
*For any* valid phone number and verify code combination, when the login function is called, it SHALL send a request with loginWay, mobile, and verifycode parameters to the login API endpoint.
**Validates: Requirements 1.3**

Property 2: Navigation after login success
*For any* successful login response, the system SHALL navigate back if needInfo is false, or navigate to user-info page if needInfo is true.
**Validates: Requirements 1.4**

Property 3: User profile data display
*For any* user info object with avatar, nickname, id, and phone fields, the mine page SHALL render all these fields in the appropriate UI elements.
**Validates: Requirements 2.2**

Property 4: Statistics data display
*For any* index data object, the mine page SHALL display couponCount, inventoryCount, magicBalance, and treasureBoxCount values.
**Validates: Requirements 2.3**

Property 5: Function entry navigation
*For any* function entry tap with a valid route, the system SHALL trigger navigation to that route.
**Validates: Requirements 2.4, 2.5**

Property 6: Address list rendering
*For any* list of addresses, the address list page SHALL render each address with contactName, contactNo, and full address (province + city + district + address).
**Validates: Requirements 3.2**

Property 7: Address save API call
*For any* valid address form submission, the system SHALL call the add or update API and navigate back on success.
**Validates: Requirements 3.5**

Property 8: Order item rendering
*For any* order item, the orders page SHALL display tradeNo, statusText, goodsCover, goodsName, paymentAmount, quantity, and createTime.
**Validates: Requirements 4.2**

Property 9: Order navigation
*For any* order item tap, the system SHALL navigate to the order detail page with the correct tradeNo.
**Validates: Requirements 4.3**

Property 10: Order action handling
*For any* order with status 1 (待付款), the pay action SHALL be available; for status 3 (待收货), the confirm receipt action SHALL be available.
**Validates: Requirements 4.4**

Property 11: Welfare room navigation
*For any* room entry tap with type 0, 1, or 2, the system SHALL navigate to the corresponding welfare page (room, catchDoll, or wish).
**Validates: Requirements 6.3**

Property 12: Image constants consistency
*For any* image key used in the app, the Images constant SHALL provide a valid CDN URL matching the ossurl configuration.
**Validates: Requirements 8.1, 8.2**

Property 13: API service function mapping
*For any* service function call, the request SHALL be sent to the correct API endpoint matching the mini-program service configuration.
**Validates: Requirements 9.1**

Property 14: API error handling
*For any* failed API call, the system SHALL catch the error and not crash, optionally displaying an error message.
**Validates: Requirements 9.2**

Property 15: Authentication token inclusion
*For any* authenticated API request, the HTTP headers SHALL include the authorization token.
**Validates: Requirements 9.3**

## Error Handling

### API 错误处理
```typescript
// HTTP 请求封装中的错误处理
try {
  const response = await fetch(url, options);
  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`);
  }
  const data = await response.json();
  if (data.code === '401') {
    // Token 过期，跳转登录
    router.push('/login');
    return { success: false, code: '401' };
  }
  return data;
} catch (error) {
  console.error('API Error:', error);
  return { success: false, error };
}
```

### 页面错误处理
- 加载失败时显示重试按钮
- 网络错误时显示提示信息
- 表单验证失败时显示具体错误

## Testing Strategy

### 单元测试
- 使用 Jest 进行单元测试
- 测试服务层函数的参数处理和返回值
- 测试工具函数（如数字格式化）

### 属性测试
- 使用 fast-check 进行属性测试
- 每个属性测试运行至少 100 次迭代
- 测试标注格式：`**Feature: miniapp-to-rn-migration, Property {number}: {property_text}**`

### 测试覆盖范围
1. 服务层 API 调用测试
2. 页面组件渲染测试
3. 导航逻辑测试
4. 表单验证测试
5. 错误处理测试
