|
|
@@ -10,9 +10,11 @@ Draft
|
|
|
|
|
|
## Acceptance Criteria
|
|
|
1. 支持按出发地、目的地、日期查询路线
|
|
|
-2. 支持筛选去程活动/返程活动
|
|
|
+2. 支持筛选去程路线/返程路线(基于路线与活动地点的关系动态判断)
|
|
|
3. 显示路线详细信息(上车点、下车点、出发时间、车型、价格)
|
|
|
4. 支持按价格、出发时间排序
|
|
|
+5. 支持省市区三级联动选择出发地和目的地
|
|
|
+6. 通过路线查询关联的活动信息,展示去重后的活动列表
|
|
|
|
|
|
## 页面迁移任务 (从mini-demo迁移)
|
|
|
- [ ] 迁移首页 (mini-demo/pages/home/home) - 路线查询入口页面
|
|
|
@@ -32,29 +34,46 @@ Draft
|
|
|
- [ ] **注意:MVP阶段不实现司机当前位置显示**
|
|
|
|
|
|
## Tasks / Subtasks
|
|
|
-- [ ] 实现路线查询API使用通用CRUD (AC: 1, 3, 4)
|
|
|
- - [ ] 在 `src/server/api/routes/index.ts` 使用 `createCrudRoutes` 创建通用CRUD路由
|
|
|
- - [ ] 配置搜索字段:startPoint, endPoint, vehicleType
|
|
|
- - [ ] 配置排序字段:price, departureTime
|
|
|
- - [ ] 使用filters参数支持日期范围查询
|
|
|
-- [ ] 实现活动查询API使用通用CRUD (AC: 2)
|
|
|
- - [ ] 在 `src/server/api/activities/index.ts` 使用 `createCrudRoutes` 创建通用CRUD路由
|
|
|
- - [ ] 配置搜索字段:name, description
|
|
|
- - [ ] 配置筛选字段:type (去程活动/返程活动)
|
|
|
-- [ ] 实现前端页面迁移 (从mini-demo迁移) (AC: 1, 2, 3, 4)
|
|
|
+- [ ] 集成用户端路线查询API (AC: 1, 2, 3, 4, 6)
|
|
|
+ - [ ] 使用故事5.1已实现的用户端路线查询API:`GET /api/v1/routes/search`
|
|
|
+ - [ ] 支持查询参数:startLocationId, endLocationId, date, routeType, sortBy, sortOrder
|
|
|
+ - [ ] 返回包含关联活动信息的路线列表
|
|
|
+ - [ ] 支持去程/返程路线动态筛选(基于路线与活动地点的关系)
|
|
|
+- [ ] 实现省市区三级联动组件 (AC: 5)
|
|
|
+ - [ ] 在 `mini/src/components/` 创建 `AreaCascader.tsx` 组件
|
|
|
+ - [ ] 集成故事5.1已实现的省市区API:`/api/v1/areas/provinces`, `/api/v1/areas/cities`, `/api/v1/areas/districts`
|
|
|
+ - [ ] 支持省市区三级联动选择
|
|
|
+ - [ ] 在首页出发地/目的地选择器中集成省市区组件
|
|
|
+- [ ] 实现地点搜索组件 (AC: 1, 5)
|
|
|
+ - [ ] 在 `mini/src/components/` 创建 `LocationSearch.tsx` 组件
|
|
|
+ - [ ] 集成故事5.1已实现的地点查询API:`GET /api/v1/locations`
|
|
|
+ - [ ] 支持按省市区筛选地点
|
|
|
+ - [ ] 支持地点名称模糊搜索
|
|
|
+- [ ] 实现前端页面迁移 (从mini-demo迁移) (AC: 1, 2, 3, 4, 5, 6)
|
|
|
- [ ] 迁移首页 - 基于 `mini-demo/pages/home/home` 在 `mini/src/pages/home/` 创建 `HomePage.tsx`
|
|
|
+ - [ ] 集成省市区三级联动选择出发地和目的地
|
|
|
+ - [ ] 集成地点搜索组件选择具体地点
|
|
|
+ - [ ] 日期选择器
|
|
|
+ - [ ] 查询表单提交
|
|
|
- [ ] 迁移活动选择页面 - 基于 `mini-demo/pages/select-activity/select-activity` 在 `mini/src/pages/select-activity/` 创建 `ActivitySelectPage.tsx`
|
|
|
+ - [ ] 展示去重后的活动列表(通过路线查询关联的活动)
|
|
|
+ - [ ] 支持去程/返程路线筛选
|
|
|
+ - [ ] 活动卡片展示(图片、名称、时间、地点、匹配点)
|
|
|
- [ ] 迁移班次列表页面 - 基于 `mini-demo/pages/schedule-list/schedule-list` 在 `mini/src/pages/schedule-list/` 创建 `ScheduleListPage.tsx`
|
|
|
- - [ ] 集成查询表单和结果展示
|
|
|
- - [ ] 使用React Query调用通用CRUD API
|
|
|
-- [ ] 实现前端活动筛选组件 (AC: 2)
|
|
|
- - [ ] 在 `mini/src/components/` 创建 `ActivityFilter.tsx` 组件
|
|
|
- - [ ] 支持活动类型筛选
|
|
|
-- [ ] 编写单元测试、集成测试和E2E测试 (AC: 1, 2, 3, 4)
|
|
|
- - [ ] 为通用CRUD路由编写集成测试 (`tests/integration/server/`)
|
|
|
- - [ ] 为前端组件编写单元测试 (`tests/unit/client/`)
|
|
|
- - [ ] 为查询功能编写集成测试 (`tests/integration/client/`)
|
|
|
+ - [ ] 路线列表展示(上车点、下车点、出发时间、车型、价格)
|
|
|
+ - [ ] 排序功能(价格、出发时间)
|
|
|
+ - [ ] 筛选功能
|
|
|
+- [ ] 实现前端路线筛选组件 (AC: 2)
|
|
|
+ - [ ] 在 `mini/src/components/` 创建 `RouteFilter.tsx` 组件
|
|
|
+ - [ ] 支持路线类型筛选(去程/返程)
|
|
|
+ - [ ] 支持车型筛选
|
|
|
+- [ ] 编写单元测试、集成测试和E2E测试 (AC: 1, 2, 3, 4, 5, 6)
|
|
|
+ - [ ] 为前端组件编写单元测试 (`mini/tests/components/`)
|
|
|
+ - [ ] 为查询功能编写集成测试 (`mini/tests/pages/`)
|
|
|
- [ ] 编写完整出行流程的E2E测试 (`tests/e2e/travel-flow/`)
|
|
|
+ - [ ] 首页查询 → 活动选择 → 班次列表完整流程
|
|
|
+ - [ ] 省市区三级联动功能测试
|
|
|
+ - [ ] 路线类型动态判断逻辑测试
|
|
|
|
|
|
## Dev Notes
|
|
|
|
|
|
@@ -68,25 +87,42 @@ Draft
|
|
|
- **首页焦点图使用固定静态图** - 轮播图组件保留,但数据使用固定的一张静态图片(不从API获取轮播图数组)
|
|
|
|
|
|
### 数据模型依赖
|
|
|
-- **Route实体**: 已在Story 5.1中创建,包含上车点、下车点、出发时间、车型、价格等字段
|
|
|
-- **Activity实体**: 已在Story 5.1中创建,包含活动名称、描述、类型(去程/返程)、开始日期、结束日期等字段
|
|
|
-- **关系**: 一个活动关联多条路线 [Source: architecture/data-model-schema-changes.md#数据关系]
|
|
|
+- **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规范
|
|
|
-- **通用CRUD路由**: 使用 `createCrudRoutes` 创建标准CRUD API [Source: src/server/utils/generic-crud.routes.ts]
|
|
|
-- **路线查询端点**: `GET /api/v1/routes` 支持查询参数:page, pageSize, keyword, sortBy, sortOrder, filters [Source: src/server/utils/generic-crud.routes.ts#L23]
|
|
|
-- **活动查询端点**: `GET /api/v1/activities` 支持查询参数:page, pageSize, keyword, sortBy, sortOrder, filters [Source: src/server/utils/generic-crud.routes.ts#L23]
|
|
|
+- **用户端路线查询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#分页响应接口]
|
|
|
-- **通用CRUD服务**: 使用 `ConcreteCrudService` 作为基础服务类 [Source: src/server/utils/concrete-crud.service.ts]
|
|
|
|
|
|
### 文件位置
|
|
|
-- **API路由**: `src/server/api/routes/index.ts`, `src/server/api/activities/index.ts` [Source: architecture/source-tree.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/HomePage.tsx` (首页)
|
|
|
- `mini/src/pages/select-activity/ActivitySelectPage.tsx` (活动选择页面)
|
|
|
- `mini/src/pages/schedule-list/ScheduleListPage.tsx` (班次列表页面) [Source: architecture/source-tree.md#实际项目结构]
|
|
|
-- **前端组件**: `mini/src/components/ActivityFilter.tsx` [Source: architecture/source-tree.md#实际项目结构]
|
|
|
-- **共享类型**: `src/share/route.types.ts`, `src/share/activity.types.ts` [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#现有技术栈维护]
|
|
|
@@ -99,12 +135,30 @@ Draft
|
|
|
- **样式开发**: 遵循 [Tailwind CSS样式规范](../architecture/tailwind-css-standards.md)
|
|
|
- **迁移指导**: 参考 [mini-demo迁移指导规范](../architecture/mini-demo-migration-guide.md)(包含精确样式迁移)
|
|
|
|
|
|
-### 通用CRUD使用模式
|
|
|
-- **路由创建**: 使用 `createCrudRoutes` 函数创建标准CRUD路由 [Source: src/server/api/users/index.ts#L9]
|
|
|
-- **搜索配置**: 配置 `searchFields` 支持关键词搜索 [Source: src/server/api/users/index.ts#L15]
|
|
|
-- **关联关系**: 配置 `relations` 字段加载关联数据 [Source: src/server/api/users/index.ts#L16]
|
|
|
-- **认证中间件**: 使用 `authMiddleware` 保护路由 [Source: src/server/api/users/index.ts#L17]
|
|
|
-- **前端调用**: 使用React Query调用通用CRUD API,支持分页、搜索、排序
|
|
|
+### 前端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` 进行认证保护
|
|
|
@@ -147,31 +201,42 @@ Draft
|
|
|
- **覆盖率目标**: 核心业务逻辑 > 80% [Source: architecture/testing-strategy.md#覆盖率目标]
|
|
|
|
|
|
**具体测试要求**:
|
|
|
-- 路线查询API的单元测试 (`tests/unit/server/routes/`) 和集成测试 (`tests/integration/server/routes/`)
|
|
|
+- **用户端路线查询API测试** (故事5.1已实现,需要验证集成)
|
|
|
- 正常查询场景:按出发地、目的地、日期查询
|
|
|
- - 边界条件:空查询结果、日期范围查询、分页查询
|
|
|
+ - 路线类型动态判断:验证去程/返程路线筛选逻辑
|
|
|
+ - 关联活动查询:验证通过路线查询关联的活动信息
|
|
|
- 排序功能:按价格、出发时间排序
|
|
|
- - 错误场景:无效参数、认证失败、权限不足
|
|
|
-- 活动查询API的单元测试 (`tests/unit/server/activities/`) 和集成测试 (`tests/integration/server/activities/`)
|
|
|
- - 正常筛选场景:按活动类型(去程/返程)筛选
|
|
|
- - 边界条件:无活动数据、活动状态筛选
|
|
|
- - 关联查询:活动关联的路线数据
|
|
|
- - 错误场景:无效类型参数、认证失败
|
|
|
-- 前端组件的单元测试 (`mini/tests/components/`)
|
|
|
- - 组件渲染:首页、活动选择、班次列表页面
|
|
|
- - 用户交互:查询表单提交、筛选条件变更
|
|
|
- - 状态管理:查询结果展示、加载状态处理
|
|
|
-- 查询功能的集成测试 (`mini/tests/pages/`)
|
|
|
- - 完整查询流程:首页查询 → 活动筛选 → 班次列表
|
|
|
+ - 边界条件:空查询结果、日期范围查询
|
|
|
+- **省市区三级联动测试**
|
|
|
+ - 省份列表获取和展示
|
|
|
+ - 城市列表根据省份动态加载
|
|
|
+ - 区县列表根据城市动态加载
|
|
|
+ - 完整省市区选择流程
|
|
|
+- **地点搜索组件测试**
|
|
|
+ - 按省市区筛选地点
|
|
|
+ - 地点名称模糊搜索
|
|
|
+ - 防抖搜索性能优化
|
|
|
+ - 地点选择交互
|
|
|
+- **前端组件单元测试** (`mini/tests/components/`)
|
|
|
+ - AreaCascader组件:省市区三级联动功能
|
|
|
+ - LocationSearch组件:地点搜索和选择功能
|
|
|
+ - RouteFilter组件:路线类型和车型筛选
|
|
|
+ - 页面组件:首页、活动选择、班次列表页面
|
|
|
+- **查询功能集成测试** (`mini/tests/pages/`)
|
|
|
+ - 完整查询流程:首页查询 → 活动选择 → 班次列表
|
|
|
+ - 省市区三级联动与地点搜索集成
|
|
|
+ - 路线类型动态筛选集成
|
|
|
- 数据一致性:前端展示与后端数据一致
|
|
|
- - 错误处理:网络错误、API错误处理
|
|
|
-- 完整出行流程的E2E测试 (`tests/e2e/travel-flow/`)
|
|
|
- - 用户登录 → 路线查询 → 活动筛选 → 查看班次列表
|
|
|
+- **完整出行流程E2E测试** (`tests/e2e/travel-flow/`)
|
|
|
+ - 用户登录 → 省市区选择 → 地点搜索 → 路线查询 → 活动筛选 → 班次列表
|
|
|
+ - 路线类型动态判断逻辑验证
|
|
|
+ - 省市区三级联动功能验证
|
|
|
- 边界场景:无数据、大量数据、并发查询
|
|
|
|
|
|
## Change Log
|
|
|
| Date | Version | Description | Author |
|
|
|
|------|---------|-------------|--------|
|
|
|
+| 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) |
|