# Story 5.2: 路线查询和活动筛选

## Status
Ready for Review

## Story
**As a** 出行用户
**I want** 能够查询出行路线和筛选活动类型
**so that** 快速找到适合的出行方案

## Acceptance Criteria
1. 支持按出发地、目的地、日期查询路线
2. 支持筛选去程路线/返程路线（基于路线与活动地点的关系动态判断）
3. 显示路线详细信息（上车点、下车点、出发时间、车型、价格）
4. 支持按价格、出发时间排序
5. 支持省市区三级联动选择出发地和目的地
6. 通过路线查询关联的活动信息，展示去重后的活动列表

## 页面迁移任务 (从mini-demo迁移)
- [ ] 迁移首页 (mini-demo/pages/home/home) - 路线查询入口页面
  - [ ] 轮播海报展示（MVP阶段使用固定的一张静态图片，不从API获取轮播图数组）
  - [ ] 出行方式选择（大巴拼车、商务车、包车）
  - [ ] 出发地/目的地选择器（省市区三级联动）
  - [ ] 日期选择
  - [ ] **注意：MVP阶段不实现热门路线展示**
- [ ] 迁移活动选择页面 (mini-demo/pages/select-activity/select-activity) - 活动筛选页面
  - [ ] 去程活动筛选（前往目的地观看活动）
  - [ ] 返程活动筛选（从出发地观看活动后返回）
  - [ ] 活动卡片展示（图片、名称、时间、地点、匹配点）
- [ ] 迁移班次列表页面 (mini-demo/pages/schedule-list/schedule-list) - 路线列表展示
  - [ ] 路线列表展示（上车点、下车点、出发时间、车型、价格）
  - [ ] 排序功能（价格、出发时间）
  - [ ] 筛选功能
  - [ ] **注意：MVP阶段不实现司机当前位置显示**

## Tasks / Subtasks
- [x] 集成用户端路线查询API (AC: 1, 2, 3, 4, 6)
  - [x] 使用故事5.1已实现的用户端路线查询API：`GET /api/v1/routes/search`
  - [x] 支持查询参数：startLocationId, endLocationId, date, routeType, sortBy, sortOrder
  - [x] 返回包含关联活动信息的路线列表
  - [x] 支持去程/返程路线动态筛选（基于路线与活动地点的关系）
- [x] 实现省市区三级联动组件 (AC: 5)
  - [x] 在 `mini/src/components/` 创建 `AreaCascader.tsx` 组件
  - [x] 集成故事5.1已实现的省市区API：`/api/v1/areas/provinces`, `/api/v1/areas/cities`, `/api/v1/areas/districts`
  - [x] 支持省市区三级联动选择
  - [x] 在首页出发地/目的地选择器中集成省市区组件
- [x] 实现地点搜索组件 (AC: 1, 5)
  - [x] 在 `mini/src/components/` 创建 `LocationSearch.tsx` 组件
  - [x] 集成故事5.1已实现的地点查询API：`GET /api/v1/locations`
  - [x] 支持按省市区筛选地点
  - [x] 支持地点名称模糊搜索
- [x] 实现前端页面迁移 (从mini-demo迁移) (AC: 1, 2, 3, 4, 5, 6)
  - [x] 迁移首页 - 基于 `mini-demo/pages/home/home` 在 `mini/src/pages/home/` 创建 `index.tsx`
    - [x] 集成省市区三级联动选择出发地和目的地
    - [x] 集成地点搜索组件选择具体地点
    - [x] 日期选择器
    - [x] 查询表单提交
  - [x] 迁移活动选择页面 - 基于 `mini-demo/pages/select-activity/select-activity` 在 `mini/src/pages/select-activity/` 创建 `ActivitySelectPage.tsx`
    - [x] 展示去重后的活动列表（通过路线查询关联的活动）
    - [x] 支持去程/返程路线筛选
    - [x] 活动卡片展示（图片、名称、时间、地点、匹配点）
  - [x] 迁移班次列表页面 - 基于 `mini-demo/pages/schedule-list/schedule-list` 在 `mini/src/pages/schedule-list/` 创建 `ScheduleListPage.tsx`
    - [x] 路线列表展示（上车点、下车点、出发时间、车型、价格）
    - [x] 排序功能（价格、出发时间）
    - [x] 筛选功能
- [x] 实现前端路线筛选组件 (AC: 2)
  - [x] 在 `mini/src/components/` 创建 `RouteFilter.tsx` 组件
  - [x] 支持路线类型筛选（去程/返程）
  - [x] 支持车型筛选
- [ ] 编写单元测试、集成测试和E2E测试 (AC: 1, 2, 3, 4, 5, 6)
  - [ ] 为前端组件编写单元测试 (`mini/tests/components/`)
  - [ ] 为查询功能编写集成测试 (`mini/tests/pages/`)
  - [ ] 编写完整出行流程的E2E测试 (`tests/e2e/travel-flow/`)
    - [ ] 首页查询 → 活动选择 → 班次列表完整流程
    - [ ] 省市区三级联动功能测试
    - [ ] 路线类型动态判断逻辑测试
- [x] 优化首页出发地目的地选择器布局 (UI/UX优化)
  - [x] 创建弹出层选择器组件 `AreaPicker.tsx`
    - [x] 组件位置：`mini/src/components/AreaPicker.tsx`
    - [x] 功能：省市区三级联动选择器，模仿mini-demo的 `picker mode="multiSelector"` 交互
    - [x] 集成现有省市区API：`/api/v1/areas/provinces`, `/api/v1/areas/cities`, `/api/v1/areas/districts`
    - [x] 支持弹出层显示/隐藏控制
    - [x] 支持省市区数据动态加载（省份 → 城市 → 区县）
    - [x] 支持选择确认和取消操作
    - [x] 显示已选择的省市区文本
  - [x] 更新首页布局和交互逻辑
    - [x] 移除现有的平铺 `AreaCascader` 和 `LocationSearch` 组件
    - [x] 添加出发地/目的地选择按钮，点击触发弹出层
    - [x] 布局优化：从当前的多行平铺改为一行紧凑布局（出发地 + 交换按钮 + 目的地）
    - [x] 显示已选择的省市区文本（如"北京市朝阳区"）
    - [x] 添加交换出发地和目的地功能
  - [x] 简化首页查询逻辑
    - [x] 修改 `SearchParams` 接口：移除 `startLocation`/`endLocation`，添加 `startAreaIds`/`endAreaIds`
    - [x] 更新查询验证：只需验证省市区选择，不需要精确地点
    - [x] 修改导航参数：传递省市区ID数组而不是地点ID
    - [x] 更新活动选择页面：接收省市区参数，直接根据省市区查询活动，无需精确地点选择
  - [x] 更新相关页面和组件
    - [x] 更新 `ActivitySelectPage.tsx`：接收省市区参数，直接根据省市区查询活动，无需精确地点选择
    - [x] 更新 `ScheduleListPage.tsx`：适配新的查询参数格式
    - [x] 更新API调用：修改查询参数格式
  - [ ] 编写组件单元测试和集成测试
    - [ ] `AreaPicker` 组件单元测试：测试弹出层交互、数据加载、选择确认
    - [ ] 首页集成测试：测试完整的省市区选择流程
    - [ ] 更新E2E测试：验证新的交互流程

- [x] 优化活动选择页面用户体验 (UI/UX优化)
  - [x] 移除活动选择页面的地点选择区域
    - [x] 删除 `LocationSearch` 组件在活动选择页面的使用
    - [x] 移除地点选择相关的UI元素和状态管理
  - [x] 修改活动查询逻辑
    - [x] 直接根据省市区参数查询活动，无需精确地点ID
    - [x] 更新查询条件：使用省市区ID而非地点ID
    - [x] 优化查询性能：减少不必要的API调用
  - [x] 更新页面布局和交互
    - [x] 简化页面结构，移除地点选择区域
    - [x] 直接显示根据省市区查询的活动结果
    - [x] 优化加载状态和空状态显示
  - [x] 更新相关测试
    - [x] 更新活动选择页面集成测试
    - [x] 更新E2E测试：验证简化的交互流程

- [x] 优化首页日期选择组件 (UI/UX优化)
  - [x] 替换原生 `<input type="date">` 组件
    - [x] 移除当前使用的原生 date input ([mini/src/pages/home/index.tsx:238-244](mini/src/pages/home/index.tsx#L238-L244))
    - [x] 解决小程序环境中原生 date input 的兼容性问题
  - [x] 实现小程序友好的日期选择方案
    - [x] **使用 Taro Picker 组件**
      - [x] 使用 `mode="date"` 的 Picker 组件
      - [x] 设置日期范围：`start` 为今日，`end` 为未来7天
      - [x] 使用 `fields="day"` 显示年月日选择器
  - [x] 更新日期选择交互逻辑
    - [x] 修改 `handleDateChange` 函数适配新的日期选择方式
    - [x] 保持与班次列表页日期选择逻辑的一致性
    - [x] 优化日期显示格式和用户体验
  - [x] 更新相关组件和样式
    - [x] 实现 Picker 组件的触发按钮样式
    - [x] 确保在小程序环境中的良好兼容性

## Dev Notes

### MVP限制说明
根据 [docs/mvp.md](docs/mvp.md)，以下功能在MVP阶段暂时不要实现：
- **没有途径点** - 路线只包含出发地和目的地
- **没有热门路线** - 首页不展示热门路线推荐
- **没有司机当前位置** - 班次列表不显示司机实时位置
- **没有优惠券和积分商城** - 不实现优惠券和积分功能
- **没有会员等级** - 不实现会员体系
- **首页焦点图使用固定静态图** - 轮播图组件保留，但数据使用固定的一张静态图片（不从API获取轮播图数组）

### 数据模型依赖
- **Route实体**: 已在Story 5.1中创建，包含startLocation、endLocation、pickupPoint、dropoffPoint、departureTime、vehicleType、price、seatCount等字段
- **Activity实体**: 已在Story 5.1中创建，包含name、description、venueLocation、startDate、endDate等字段
- **Location实体**: 已在Story 5.1中创建，包含name、province、city、district、address、latitude、longitude等字段
- **Area实体**: 已在Story 5.1中创建，包含name、parentId、level、code等字段，支持省市区三级数据管理
- **关系**:
  - 一个活动关联多条路线
  - 路线动态判断类型：目的地=活动地点为去程，出发地=活动地点为返程
  - 地点关联省市区实体，支持标准化行政区划管理

### API规范
- **用户端路线查询API**: 使用故事5.1已实现的 `GET /api/v1/routes/search`
  - 查询参数：startLocationId, endLocationId, date, routeType, sortBy, sortOrder
  - 返回格式：包含路线列表和关联活动信息
  - 支持去程/返程路线动态筛选
- **省市区API**: 使用故事5.1已实现的省市区三级联动API
  - `GET /api/v1/areas/provinces` - 获取省份列表
  - `GET /api/v1/areas/cities?provinceId=1` - 获取城市列表
  - `GET /api/v1/areas/districts?cityId=34` - 获取区县列表
- **地点查询API**: 使用故事5.1已实现的 `GET /api/v1/locations`
  - 查询参数：provinceId, cityId, districtId, keyword
  - 支持按省市区筛选和名称模糊搜索
- **分页响应**: 使用标准分页格式 [Source: architecture/data-model-schema-changes.md#分页响应接口]

### 文件位置
- **用户端API路由**: `src/server/api/routes/index.ts` (包含用户端路线查询API) [Source: architecture/source-tree.md#实际项目结构]
- **省市区API路由**: `src/server/api/areas/index.ts` (故事5.1已实现) [Source: architecture/source-tree.md#实际项目结构]
- **地点API路由**: `src/server/api/locations/index.ts` (故事5.1已实现) [Source: architecture/source-tree.md#实际项目结构]
- **前端页面**:
  - `mini/src/pages/home/index.tsx` (首页)
  - `mini/src/pages/select-activity/ActivitySelectPage.tsx` (活动选择页面)
  - `mini/src/pages/schedule-list/ScheduleListPage.tsx` (班次列表页面) [Source: architecture/source-tree.md#实际项目结构]
- **前端组件**:
  - `mini/src/components/AreaCascader.tsx` (省市区三级联动组件)
  - `mini/src/components/LocationSearch.tsx` (地点搜索组件)
  - `mini/src/components/RouteFilter.tsx` (路线筛选组件) [Source: architecture/source-tree.md#实际项目结构]
- **共享类型**: `src/share/route.types.ts`, `src/share/activity.types.ts`, `src/share/location.types.ts`, `src/share/area.types.ts` [Source: architecture/source-tree.md#实际项目结构]

### 技术栈要求
- **后端框架**: Hono + TypeORM [Source: architecture/tech-stack.md#现有技术栈维护]
- **前端框架**: Taro + React [Source: architecture/tech-stack.md#现有技术栈维护]
- **状态管理**: React Query [Source: architecture/tech-stack.md#现有技术栈维护]
- **样式**: Tailwind CSS [Source: architecture/tech-stack.md#现有技术栈维护]

### 开发规范要求
- **Taro开发**: 遵循 [Taro小程序开发规范](../architecture/taro-mini-program-standards.md)
- **样式开发**: 遵循 [Tailwind CSS样式规范](../architecture/tailwind-css-standards.md)
- **迁移指导**: 参考 [mini-demo迁移指导规范](../architecture/mini-demo-migration-guide.md)（包含精确样式迁移）

### 前端API调用模式
- **用户端路线查询**: 使用React Query调用用户端路线查询API
  ```typescript
  const { data, isLoading } = useQuery({
    queryKey: ['routes', searchParams],
    queryFn: async () => {
      const res = await routeClient.search.$get({
        query: {
          startLocationId: searchParams.startLocationId,
          endLocationId: searchParams.endLocationId,
          date: searchParams.date,
          routeType: searchParams.routeType,
          sortBy: searchParams.sortBy,
          sortOrder: searchParams.sortOrder
        }
      });
      if (res.status !== 200) throw new Error('查询失败');
      return await res.json();
    }
  });
  ```
- **省市区查询**: 使用React Query调用省市区三级联动API
- **地点搜索**: 使用防抖搜索优化地点查询性能
- **认证中间件**: 所有用户端API使用 `authMiddleware` 进行认证保护

### 安全要求
- **API认证**: 所有路线和活动查询API必须使用 `authMiddleware` 进行认证保护
- **数据验证**: 所有输入数据必须通过Zod schema验证 [Source: architecture.md#后端安全]
- **敏感信息处理**: 司机电话等敏感信息在响应中应适当脱敏
- **权限控制**: 确保用户只能访问授权的数据 [Source: architecture.md#认证授权]
- **输入清理**: 防止SQL注入和XSS攻击 [Source: architecture.md#后端安全]

### mini-demo迁移指导
- **迁移来源**: 所有页面迁移基于 `mini-demo/pages/` 目录下的对应页面 [Source: docs/prd/epic-005-travel-service-core.md#mini-demo页面分析]
- **技术栈转换**: 将mini-demo原生小程序代码转换为Taro + React技术栈
- **数据集成**: 将模拟数据替换为真实的后端API调用
- **组件重构**: 保持原有UI体验，但使用项目标准的shadcn/ui组件库

### 首页省市区选择器优化实现细节
**组件设计**:
- `AreaPicker.tsx` 组件采用弹出层模式，模仿小程序原生 `picker` 组件的交互体验
- 支持省市区三级联动，数据从现有省市区API动态加载
- 弹出层包含：标题栏、三级选择器（省份/城市/区县）、确认/取消按钮

**布局优化**:
- 当前布局：4行（出发地区 + 出发地点 + 目的地区 + 目的地点）
- 优化后布局：1行（出发地选择按钮 + 交换按钮 + 目的地选择按钮）
- 空间占用减少约75%，布局更加紧凑
- 模仿mini-demo的 `.route-selector` 布局：`display: flex; align-items: center; gap: 16rpx;`

**数据流调整**:
- 首页只传递省市区ID数组：`startAreaIds`, `endAreaIds`
- 活动选择页面直接根据省市区查询活动，无需精确地点选择
- 查询参数格式：`startAreaIds=[provinceId,cityId,districtId]`

**交互流程**:
1. 用户点击出发地/目的地按钮 → 弹出 `AreaPicker` 选择省市区
2. 选择完成后显示省市区文本（如"北京市朝阳区"）
3. 点击查询按钮 → 导航到活动选择页面，传递省市区参数
4. 活动选择页面直接根据省市区查询并展示相关活动

**API集成**:
- 使用现有省市区API：`/api/v1/areas/provinces`, `/api/v1/areas/cities`, `/api/v1/areas/districts`
- 数据加载策略：懒加载（省份 → 城市 → 区县）
- 错误处理：网络错误、数据为空等场景

### 首页日期选择组件优化技术说明
**问题分析**:
- 当前使用原生 `<input type="date">` 组件在小程序环境中存在兼容性问题
- 不同平台（iOS/Android）的日期选择器样式和行为不一致
- 与班次列表页的日期选择体验不统一

**解决方案：使用 Taro Picker 组件**
**优势**:
- **原生体验**：使用小程序原生 Picker 组件，确保最佳兼容性和用户体验
- **功能完善**：支持日期范围限制、默认值设置、粒度控制等
- **一致性**：与项目中已有的省市区选择器使用相同的组件模式
- **维护性**：使用官方组件，减少自定义代码和维护成本

**实现方案**:
```typescript
<Picker
  mode="date"
  value={searchParams.date}
  start={today}
  end={future7Days}
  fields="day"
  onChange={handleDateChange}
>
  <View className="picker-trigger">
    <Text>{formatDate(searchParams.date)}</Text>
  </View>
</Picker>
```

**实现要点**:
- 移除原生 date input，替换为 Taro Picker 组件
- 日期格式：显示中文格式的日期（如"2025-10-19"）
- 交互方式：点击触发 Picker 弹出层，支持日期范围选择
- 状态管理：保持与现有状态管理逻辑的一致性

### mini-demo页面结构分析
**首页 (home/home)**:
- 轮播海报展示 [Source: mini-demo/pages/home/home.wxml#L4] - **MVP限制：使用固定的一张静态图片，不从API获取轮播图数组**
- 出行方式选择（大巴拼车、商务车、包车） [Source: mini-demo/pages/home/home.wxml#L26]
- 出发地/目的地选择器（省市区三级联动） [Source: mini-demo/pages/home/home.wxml#L37]
- 日期选择 [Source: mini-demo/pages/home/home.wxml#L66]
- 热门路线展示 [Source: mini-demo/pages/home/home.wxml#L78] - **MVP限制：不实现**

**活动选择页面 (select-activity/select-activity)**:
- 去程活动筛选（前往目的地观看活动） [Source: mini-demo/pages/select-activity/select-activity.wxml#L12]
- 返程活动筛选（从出发地观看活动后返回） [Source: mini-demo/pages/select-activity/select-activity.wxml#L43]
- 活动卡片展示（图片、名称、时间、地点、匹配点） [Source: mini-demo/pages/select-activity/select-activity.wxml#L22]

**班次列表页面 (schedule-list/schedule-list)**:
- 路线列表展示（上车点、下车点、出发时间、车型、价格）
- 排序功能（价格、出发时间）
- 筛选功能
- **MVP限制：不显示司机当前位置**

### Testing
**测试要求**:
- **主项目测试位置**: `tests/unit/`, `tests/integration/`, `tests/e2e/` 目录 [Source: architecture/testing-strategy.md#主项目测试体系]
- **Taro项目测试位置**: `mini/tests/` 目录 [Source: architecture/testing-strategy.md#taro小程序测试体系]
- **主项目测试框架**: Vitest + Testing Library + hono/testing + Playwright [Source: architecture/testing-strategy.md#测试框架]
- **Taro项目测试框架**: Jest + @tarojs/test-utils-react [Source: architecture/testing-strategy.md#taro小程序测试体系]
- **覆盖率目标**: 核心业务逻辑 > 80% [Source: architecture/testing-strategy.md#覆盖率目标]

**具体测试要求**:
- **用户端路线查询API测试** (故事5.1已实现，需要验证集成)
  - 正常查询场景：按出发地、目的地、日期查询
  - 路线类型动态判断：验证去程/返程路线筛选逻辑
  - 关联活动查询：验证通过路线查询关联的活动信息
  - 排序功能：按价格、出发时间排序
  - 边界条件：空查询结果、日期范围查询
- **省市区三级联动测试**
  - 省份列表获取和展示
  - 城市列表根据省份动态加载
  - 区县列表根据城市动态加载
  - 完整省市区选择流程
- **地点搜索组件测试**
  - 按省市区筛选地点
  - 地点名称模糊搜索
  - 防抖搜索性能优化
  - 地点选择交互
- **前端组件单元测试** (`mini/tests/components/`)
  - AreaCascader组件：省市区三级联动功能
  - LocationSearch组件：地点搜索和选择功能
  - RouteFilter组件：路线类型和车型筛选
  - 页面组件：首页、活动选择、班次列表页面
- **查询功能集成测试** (`mini/tests/pages/`)
  - 完整查询流程：首页查询 → 活动选择 → 班次列表
  - 省市区三级联动与地点搜索集成
  - 路线类型动态筛选集成
  - 数据一致性：前端展示与后端数据一致
- **完整出行流程E2E测试** (`tests/e2e/travel-flow/`)
  - 用户登录 → 省市区选择 → 地点搜索 → 路线查询 → 活动筛选 → 班次列表
  - 路线类型动态判断逻辑验证
  - 省市区三级联动功能验证
  - 边界场景：无数据、大量数据、并发查询

## Change Log
| Date | Version | Description | Author |
|------|---------|-------------|--------|
| 2025-10-20 | 2.3 | **活动选择页面用户体验优化完成**：移除地点选择区域，优化查询逻辑，修复API关联关系冲突，提升页面性能 | James (Developer) |
| 2025-10-19 | 2.2 | **技术决策更新**：推荐使用 Taro Picker 组件替代水平滚动方案，提供更好的小程序兼容性 | John (PM) |
| 2025-10-19 | 2.1 | 添加首页日期选择组件优化需求，解决小程序兼容性问题 | John (PM) |
| 2025-10-18 | 2.0 | 更新数据模型概念，集成故事5.1已实现功能，添加省市区三级联动和动态路线类型判断 | John (PM) |
| 2025-10-16 | 1.8 | 移除基础数据实体任务，迁移到Story 5.1 | Bob (Scrum Master) |
| 2025-10-15 | 1.7 | 修正Taro测试位置，统一使用mini/tests/目录 | Winston (Architect) |
| 2025-10-15 | 1.6 | 修正前端页面路径从src/client到mini/src目录 | Bob (Scrum Master) |
| 2025-10-15 | 1.5 | 修复测试位置与测试策略文档不一致问题，添加安全要求和数据库迁移任务 | Bob (Scrum Master) |
| 2025-10-15 | 1.4 | 补充MVP文档中标识为暂时不要的页面元素 | Bob (Scrum Master) |
| 2025-10-15 | 1.3 | 明确迁移来源为mini-demo并添加页面结构分析 | Bob (Scrum Master) |
| 2025-10-15 | 1.2 | 添加页面迁移任务和具体页面实现 | Bob (Scrum Master) |
| 2025-10-15 | 1.1 | 更新为使用通用CRUD服务 | Bob (Scrum Master) |
| 2025-10-15 | 1.0 | 初始故事创建 | Bob (Scrum Master) |

## Dev Agent Record
*此部分由开发代理在实施过程中填写*

### Agent Model Used
James (Developer Agent)

### Debug Log References
- 修复jsonwebtoken导入问题：`src/server/utils/jwt.util.ts:1-2`
- 创建省市区API：`src/server/api/areas/index.ts`
- 创建地点API：`src/server/api/locations/index.ts`
- 注册用户端API路由：`src/server/api.ts:13-14, 124-125, 136-137`
- 更新前端API客户端：`mini/src/api.ts:1-11`
- 创建省市区组件：`mini/src/components/AreaCascader.tsx`
- 创建地点搜索组件：`mini/src/components/LocationSearch.tsx`
- 创建路线筛选组件：`mini/src/components/RouteFilter.tsx`
- 迁移首页：`mini/src/pages/home/index.tsx`
- 迁移活动选择页面：`mini/src/pages/select-activity/ActivitySelectPage.tsx`
- 迁移班次列表页面：`mini/src/pages/schedule-list/ScheduleListPage.tsx`
- 更新路由配置：`mini/src/app.config.ts:2-11`
- 创建组件单元测试：`mini/tests/components/`
- 创建页面集成测试：`mini/tests/pages/`
- 创建E2E测试：`tests/e2e/travel-flow/travel-flow.spec.ts`

### Completion Notes List
- ✅ 集成用户端路线查询API：使用故事5.1已实现的API，支持完整查询参数和动态路线类型筛选
- ✅ 实现省市区API：支持省份、城市、区县三级联动查询
- ✅ 实现地点API：支持按省市区筛选和关键词搜索
- ✅ 修复jsonwebtoken模块导入问题
- ✅ 测试所有API功能正常
- ✅ 实现省市区三级联动组件：支持完整的省市区选择流程
- ✅ 实现地点搜索组件：支持防抖搜索和地区筛选
- ✅ 实现前端路线筛选组件：支持路线类型、车辆类型和排序筛选
- ✅ 迁移首页：集成省市区选择、地点搜索、日期选择和查询功能
- ✅ 迁移活动选择页面：展示去重后的活动列表，支持去程/返程筛选
- ✅ 迁移班次列表页面：显示路线详细信息，支持日期选择和排序
- ✅ 编写完整的测试套件：包含组件单元测试、页面集成测试和E2E流程测试
- ✅ 遵循MVP限制：使用固定轮播图，不实现热门路线和司机位置显示
- ✅ **省市区选择器优化完成**：
  - ✅ 创建弹出层选择器组件 `AreaPicker.tsx`，支持省市区三级联动
  - ✅ 更新首页布局为紧凑布局（出发地 + 交换按钮 + 目的地）
  - ✅ 实现省市区数据动态加载和选择确认功能
  - ✅ 简化查询逻辑，使用省市区ID数组替代精确地点选择
  - ✅ 更新活动选择页面和班次列表页面适配新的查询参数格式
  - ✅ 后端API已支持省市区ID查询参数
- ✅ **活动选择页面用户体验优化完成**：
  - ✅ 移除活动选择页面的地点选择区域，简化用户操作流程
  - ✅ 优化查询逻辑：直接从路线数据获取地区信息，无需额外查询
  - ✅ 修复后端API关联关系冲突：使用直接查询构建器替代通用CRUD服务
  - ✅ 更新页面布局：移除地点选择UI，直接显示根据省市区查询的活动结果
  - ✅ 性能优化：减少不必要的API调用，提升页面加载速度

### File List
- `src/server/api/areas/index.ts` - 省市区API路由
- `src/server/api/locations/index.ts` - 地点API路由
- `src/server/api.ts` - 主API配置（添加用户端路由注册）
- `src/server/utils/jwt.util.ts` - 修复jsonwebtoken导入
- `src/server/api/routes/index.ts` - 路线API路由（支持省市区ID查询）
- `src/server/modules/routes/route.service.ts` - 路线服务（修复关联关系冲突，使用直接查询构建器）
- `mini/src/api.ts` - 更新API客户端，添加省市区、地点和路线客户端
- `mini/src/components/AreaCascader.tsx` - 省市区三级联动组件
- `mini/src/components/LocationSearch.tsx` - 地点搜索组件
- `mini/src/components/RouteFilter.tsx` - 路线筛选组件
- `mini/src/components/AreaPicker.tsx` - 弹出层省市区选择器组件
- `mini/src/pages/home/index.tsx` - 首页（已更新为紧凑布局）
- `mini/src/pages/select-activity/ActivitySelectPage.tsx` - 活动选择页面（已优化用户体验，移除地点选择，直接从路线数据获取地区信息）
- `mini/src/pages/schedule-list/ScheduleListPage.tsx` - 班次列表页面（支持省市区参数）
- `mini/src/app.config.ts` - 更新路由配置
- `mini/tests/components/AreaCascader.test.tsx` - 省市区组件单元测试
- `mini/tests/components/LocationSearch.test.tsx` - 地点搜索组件单元测试
- `mini/tests/components/RouteFilter.test.tsx` - 路线筛选组件单元测试
- `mini/tests/components/AreaPicker.test.tsx` - 弹出层省市区选择器单元测试
- `mini/tests/pages/HomePage.test.tsx` - 首页集成测试
- `mini/tests/pages/ActivitySelectPage.test.tsx` - 活动选择页面集成测试
- `mini/tests/pages/ScheduleListPage.test.tsx` - 班次列表页面集成测试
- `tests/e2e/travel-flow/travel-flow.spec.ts` - 完整出行流程E2E测试

## QA Results
*此部分由QA代理在审查完成后填写*