|
|
@@ -0,0 +1,323 @@
|
|
|
+# Story 5.8: 订单创建和支付
|
|
|
+
|
|
|
+## Status
|
|
|
+Draft
|
|
|
+
|
|
|
+## Story
|
|
|
+**As a** 出行用户
|
|
|
+**I want** 能够创建订单并完成支付
|
|
|
+**so that** 确认出行安排
|
|
|
+
|
|
|
+## Acceptance Criteria
|
|
|
+1. 选择路线和乘客后创建订单
|
|
|
+2. 计算订单总金额
|
|
|
+3. 集成微信支付完成支付流程
|
|
|
+4. 支付成功后更新订单状态
|
|
|
+5. 保存订单快照信息(路线快照、乘客快照)
|
|
|
+
|
|
|
+## Tasks / Subtasks
|
|
|
+- [ ] 创建订单创建API端点 (AC: 1, 2, 5)
|
|
|
+ - [ ] 创建 `packages/server/src/api/orders/create.ts` - 订单创建API(非通用CRUD路由)
|
|
|
+ - [ ] 实现订单创建业务逻辑(验证路线、计算金额、创建订单)
|
|
|
+ - [ ] 实现订单快照保存逻辑(路线快照、乘客快照)
|
|
|
+ - [ ] 添加订单创建验证和错误处理
|
|
|
+- [ ] 编写订单创建API集成测试 (AC: 1, 2, 5)
|
|
|
+ - [ ] 编写订单创建API集成测试
|
|
|
+ - [ ] 测试订单快照保存功能
|
|
|
+ - [ ] 测试订单金额计算逻辑
|
|
|
+ - [ ] 验证所有API测试通过
|
|
|
+- [ ] 创建微信小程序支付集成服务 (AC: 3, 4)
|
|
|
+ - [ ] 创建 `packages/server/src/modules/payment/payment.service.ts` - 支付服务(仅支持微信小程序支付)
|
|
|
+ - [ ] 实现微信支付JSAPI集成(预支付、支付回调)
|
|
|
+ - [ ] 实现支付状态管理(支付成功、失败、超时)
|
|
|
+ - [ ] 实现支付回调处理和订单状态更新
|
|
|
+- [ ] 创建微信小程序支付API端点 (AC: 3, 4)
|
|
|
+ - [ ] 创建 `packages/server/src/api/payment/create.ts` - 支付创建API(非通用CRUD路由,仅支持微信小程序支付)
|
|
|
+ - [ ] 实现微信支付JSAPI预支付参数生成
|
|
|
+ - [ ] 实现支付回调处理接口
|
|
|
+ - [ ] 添加支付验证和错误处理
|
|
|
+- [ ] 编写微信小程序支付集成测试 (AC: 3, 4)
|
|
|
+ - [ ] 编写支付API集成测试(仅测试微信小程序支付)
|
|
|
+ - [ ] 测试支付状态流转逻辑
|
|
|
+ - [ ] 测试支付回调处理功能
|
|
|
+ - [ ] 验证微信支付JSAPI参数生成逻辑
|
|
|
+ - [ ] 验证所有支付测试通过
|
|
|
+- [ ] 创建小程序下单页面 (AC: 1, 2)
|
|
|
+ - [ ] 创建 `mini/src/pages/order/order.tsx` - 下单页面
|
|
|
+ - [ ] 实现路线和乘客选择界面
|
|
|
+ - [ ] 实现订单金额计算和显示
|
|
|
+ - [ ] 实现订单创建和支付发起
|
|
|
+- [ ] 创建小程序支付成功页面 (AC: 4)
|
|
|
+ - [ ] 创建 `mini/src/pages/pay-success/pay-success.tsx` - 支付成功页面
|
|
|
+ - [ ] 实现支付结果展示
|
|
|
+ - [ ] 实现订单详情显示
|
|
|
+ - [ ] 实现返回首页或查看订单功能
|
|
|
+- [ ] 编写小程序页面组件测试 (AC: 1, 2, 4)
|
|
|
+ - [ ] 编写下单页面组件测试
|
|
|
+ - [ ] 编写支付成功页面组件测试
|
|
|
+ - [ ] 测试订单创建和支付流程
|
|
|
+ - [ ] 验证所有组件测试通过
|
|
|
+
|
|
|
+## Dev Notes
|
|
|
+
|
|
|
+### 数据模型设计
|
|
|
+基于 [docs/architecture/data-model-schema-changes.md#订单模型],订单实体已创建,包含以下关键属性:
|
|
|
+
|
|
|
+**订单实体关键属性** [Source: architecture/data-model-schema-changes.md#订单模型]:
|
|
|
+- `id`: number - 主键标识符
|
|
|
+- `userId`: number - 用户ID
|
|
|
+- `routeId`: number - 路线ID
|
|
|
+- `passengerCount`: number - 乘客数量
|
|
|
+- `totalAmount`: number - 订单总金额
|
|
|
+- `status`: string - 订单状态(待支付、待出发、行程中、已完成、已取消)
|
|
|
+- `paymentStatus`: string - 支付状态
|
|
|
+- `passengerSnapshots`: JSON - 乘客信息快照数组(下单时的多个乘客信息)
|
|
|
+- `routeSnapshot`: JSON - 路线信息快照(下单时的路线信息)
|
|
|
+- `createdAt`: Date - 创建时间
|
|
|
+
|
|
|
+**订单状态枚举定义** [Source: architecture/data-model-schema-changes.md#枚举定义]:
|
|
|
+```typescript
|
|
|
+export enum OrderStatus {
|
|
|
+ PENDING_PAYMENT = '待支付',
|
|
|
+ WAITING_DEPARTURE = '待出发',
|
|
|
+ IN_PROGRESS = '行程中',
|
|
|
+ COMPLETED = '已完成',
|
|
|
+ CANCELLED = '已取消'
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**支付状态枚举定义** [Source: architecture/data-model-schema-changes.md#枚举定义]:
|
|
|
+```typescript
|
|
|
+export enum PaymentStatus {
|
|
|
+ PENDING = '待支付',
|
|
|
+ PAID = '已支付',
|
|
|
+ FAILED = '支付失败',
|
|
|
+ REFUNDED = '已退款'
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### 订单处理流程
|
|
|
+基于 [docs/architecture/order-processing-workflow.md#下单流程],订单创建和支付流程必须遵循以下流程:
|
|
|
+
|
|
|
+**下单流程** [Source: architecture/order-processing-workflow.md#下单流程]:
|
|
|
+1. 用户选择路线和乘客
|
|
|
+2. 前端调用订单创建API
|
|
|
+3. 后端验证路线可用性和座位数量
|
|
|
+4. 创建订单记录并保存快照信息
|
|
|
+5. 返回订单详情和支付信息
|
|
|
+6. 前端发起支付请求
|
|
|
+7. 处理支付结果并更新订单状态
|
|
|
+
|
|
|
+**支付流程** [Source: architecture/order-processing-workflow.md#支付流程]:
|
|
|
+1. 小程序请求支付参数
|
|
|
+2. 后端调用微信支付统一下单API
|
|
|
+3. 微信支付返回预支付ID
|
|
|
+4. 后端生成支付签名返回给小程序
|
|
|
+5. 小程序调用微信支付接口
|
|
|
+6. 微信支付返回支付结果
|
|
|
+7. 小程序通知后端支付结果
|
|
|
+8. 后端更新订单支付状态
|
|
|
+
|
|
|
+### 支付集成设计
|
|
|
+基于 [docs/architecture/payment-integration-design.md#微信支付集成],微信支付集成必须遵循以下设计:
|
|
|
+
|
|
|
+**支付服务接口设计** [Source: architecture/payment-integration-design.md#支付服务接口设计]:
|
|
|
+```typescript
|
|
|
+interface CreatePaymentRequest {
|
|
|
+ orderId: number; // 订单ID
|
|
|
+ totalAmount: number; // 支付金额(分)
|
|
|
+ description: string; // 支付描述
|
|
|
+ openid?: string; // 用户OpenID
|
|
|
+}
|
|
|
+
|
|
|
+interface CreatePaymentResponse {
|
|
|
+ paymentId: string; // 支付ID
|
|
|
+ timeStamp: string; // 时间戳
|
|
|
+ nonceStr: string; // 随机字符串
|
|
|
+ package: string; // 预支付ID
|
|
|
+ signType: string; // 签名类型
|
|
|
+ paySign: string; // 签名
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**支付状态管理** [Source: architecture/payment-integration-design.md#支付状态管理]:
|
|
|
+```typescript
|
|
|
+export enum PaymentStatus {
|
|
|
+ PENDING = '待支付', // 订单创建,等待支付
|
|
|
+ PROCESSING = '支付中', // 支付进行中
|
|
|
+ SUCCESS = '支付成功', // 支付成功
|
|
|
+ FAILED = '支付失败', // 支付失败
|
|
|
+ REFUNDED = '已退款', // 已退款
|
|
|
+ CLOSED = '已关闭' // 支付关闭
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### 快照机制
|
|
|
+基于 [docs/architecture/order-processing-workflow.md#数据快照机制],订单必须保存以下快照信息:
|
|
|
+
|
|
|
+**快照内容** [Source: architecture/order-processing-workflow.md#快照内容]:
|
|
|
+- **路线快照**: 保存下单时的路线信息(上车点、下车点、出发时间、价格等)
|
|
|
+- **乘客快照**: 保存下单时的乘客信息(姓名、证件类型、证件号码等)
|
|
|
+
|
|
|
+**快照目的** [Source: architecture/order-processing-workflow.md#快照目的]:
|
|
|
+- 确保历史订单数据完整性
|
|
|
+- 防止路线信息变更影响历史订单
|
|
|
+- 支持订单追溯和争议处理
|
|
|
+
|
|
|
+### 文件位置
|
|
|
+基于 [docs/architecture/source-tree.md#实际项目结构],所有订单和支付相关文件必须放置在指定位置:
|
|
|
+
|
|
|
+**后端文件位置** [Source: architecture/source-tree.md#实际项目结构]:
|
|
|
+- **订单API**: `packages/server/src/api/orders/index.ts`
|
|
|
+- **支付服务**: `packages/server/src/modules/payment/payment.service.ts`
|
|
|
+- **订单实体**: `packages/server/src/modules/orders/order.entity.ts`
|
|
|
+- **Zod Schema**: `packages/server/src/modules/orders/order.schema.ts`
|
|
|
+
|
|
|
+**小程序文件位置** [Source: architecture/source-tree.md#实际项目结构]:
|
|
|
+- **下单页面**: `mini/src/pages/order/order.tsx`
|
|
|
+- **支付成功页面**: `mini/src/pages/pay-success/pay-success.tsx`
|
|
|
+
|
|
|
+### 技术栈要求
|
|
|
+基于 [docs/architecture/tech-stack.md#现有技术栈维护],必须使用项目标准技术栈:
|
|
|
+
|
|
|
+**后端框架** [Source: architecture/tech-stack.md#现有技术栈维护]:
|
|
|
+- **运行时**: Node.js 20.19.2
|
|
|
+- **框架**: Hono 4.8.5
|
|
|
+- **数据库**: PostgreSQL 17
|
|
|
+- **ORM**: TypeORM 0.3.25
|
|
|
+
|
|
|
+**小程序框架** [Source: architecture/tech-stack.md#现有技术栈维护]:
|
|
|
+- **前端框架**: Taro + React
|
|
|
+- **支付SDK**: 微信支付JSAPI
|
|
|
+
|
|
|
+### 开发规范要求
|
|
|
+基于 [docs/architecture/coding-standards.md#通用crud开发规范],必须遵循编码标准:
|
|
|
+
|
|
|
+**实体设计** [Source: architecture/coding-standards.md#通用crud开发规范]:
|
|
|
+- 使用TypeORM装饰器定义字段
|
|
|
+- 为所有字段添加 `comment` 配置,说明字段用途
|
|
|
+- 包含 `createdAt` 和 `updatedAt` 时间戳
|
|
|
+
|
|
|
+**Schema设计** [Source: architecture/coding-standards.md#通用crud开发规范]:
|
|
|
+- 创建和更新使用不同的schema
|
|
|
+- 响应schema应包含完整字段
|
|
|
+- 使用 `.optional()` 和 `.nullable()` 明确字段可选性
|
|
|
+
|
|
|
+### 非通用CRUD路由规范
|
|
|
+基于 [docs/architecture/non-generic-crud-standards.md#业务操作路由],订单创建API必须遵循非通用CRUD路由规范:
|
|
|
+
|
|
|
+**业务操作路由规范** [Source: architecture/non-generic-crud-standards.md#业务操作路由]:
|
|
|
+- 使用 `POST` 方法表示动作执行
|
|
|
+- 路径格式为 `/`(在订单模块下)
|
|
|
+- 包含完整的权限验证
|
|
|
+- 返回操作结果
|
|
|
+
|
|
|
+**文件组织规范** [Source: architecture/non-generic-crud-standards.md#文件组织]:
|
|
|
+- 每个非通用路由功能创建独立文件
|
|
|
+- 文件名反映功能用途(如 `create.ts`)
|
|
|
+- 在模块的 `index.ts` 中统一导出
|
|
|
+
|
|
|
+**代码结构规范** [Source: architecture/non-generic-crud-standards.md#代码结构]:
|
|
|
+- 路由定义在前,处理函数在后
|
|
|
+- 使用 try-catch 包装所有业务逻辑
|
|
|
+- 保持错误处理的一致性
|
|
|
+
|
|
|
+**订单创建路由代码模板** [Source: architecture/non-generic-crud-standards.md#代码模板]:
|
|
|
+```typescript
|
|
|
+import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
|
|
|
+import { authMiddleware } from '../../middleware/auth.middleware';
|
|
|
+import { OrderService } from '../../modules/orders/order.service';
|
|
|
+import { OrderCreateSchema, OrderResponseSchema } from '../../modules/orders/order.schema';
|
|
|
+
|
|
|
+// 订单创建路由定义
|
|
|
+const createOrderRoute = createRoute({
|
|
|
+ method: 'post',
|
|
|
+ path: '/',
|
|
|
+ middleware: [authMiddleware],
|
|
|
+ request: {
|
|
|
+ body: {
|
|
|
+ content: {
|
|
|
+ 'application/json': { schema: OrderCreateSchema }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ responses: {
|
|
|
+ 201: {
|
|
|
+ description: '订单创建成功',
|
|
|
+ content: { 'application/json': { schema: OrderResponseSchema } }
|
|
|
+ },
|
|
|
+ 400: { description: '参数错误' },
|
|
|
+ 401: { description: '未授权' },
|
|
|
+ 500: { description: '服务器错误' }
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+const app = new OpenAPIHono()
|
|
|
+ .openapi(createOrderRoute, async (c) => {
|
|
|
+ try {
|
|
|
+ const user = c.get('user');
|
|
|
+ const orderData = c.req.valid('json');
|
|
|
+
|
|
|
+ const orderService = new OrderService();
|
|
|
+ const order = await orderService.createOrder(user.id, orderData);
|
|
|
+
|
|
|
+ return c.json(order, 201);
|
|
|
+ } catch (error) {
|
|
|
+ console.error('订单创建失败:', error);
|
|
|
+ return c.json({
|
|
|
+ code: 500,
|
|
|
+ message: error instanceof Error ? error.message : '订单创建失败'
|
|
|
+ }, 500);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+export default app;
|
|
|
+```
|
|
|
+
|
|
|
+### Testing
|
|
|
+
|
|
|
+**测试要求** [Source: architecture/testing-strategy.md#主项目测试体系]:
|
|
|
+- **主项目测试位置**: `web/tests/unit/`, `web/tests/integration/`, `web/tests/e2e/` 目录
|
|
|
+- **主项目测试框架**: Vitest + Testing Library + hono/testing + Playwright
|
|
|
+- **小程序测试位置**: `mini/tests/` 目录
|
|
|
+- **覆盖率目标**: 核心业务逻辑 > 80%
|
|
|
+- **需要创建的测试文件**: 订单创建API集成测试、微信小程序支付集成测试、小程序页面组件测试
|
|
|
+
|
|
|
+**具体测试要求** [Source: architecture/testing-strategy.md#测试金字塔策略]:
|
|
|
+- **订单创建API集成测试** (P1优先级)
|
|
|
+ - 测试订单创建API端点
|
|
|
+ - 验证订单快照保存功能
|
|
|
+ - 测试订单金额计算逻辑
|
|
|
+ - 验证错误处理场景
|
|
|
+- **微信小程序支付集成测试** (P1优先级)
|
|
|
+ - 测试支付API端点(仅测试微信小程序支付)
|
|
|
+ - 测试支付状态流转逻辑
|
|
|
+ - 测试支付回调处理功能
|
|
|
+ - 验证微信支付JSAPI参数生成逻辑
|
|
|
+- **小程序页面组件测试** (P1优先级)
|
|
|
+ - 测试下单页面组件渲染
|
|
|
+ - 测试支付成功页面组件
|
|
|
+ - 验证订单创建和支付流程
|
|
|
+- **E2E订单创建支付流程测试** (P2优先级)
|
|
|
+ - 测试完整的订单创建和支付流程
|
|
|
+ - 验证支付结果处理
|
|
|
+ - 测试异常支付场景
|
|
|
+
|
|
|
+## Change Log
|
|
|
+| Date | Version | Description | Author |
|
|
|
+|------|---------|-------------|--------|
|
|
|
+| 2025-10-23 | 1.0 | 初始故事创建,基于史诗005 US005-08需求 | Bob (Scrum Master) |
|
|
|
+
|
|
|
+## Dev Agent Record
|
|
|
+*此部分由开发代理在实施过程中填写*
|
|
|
+
|
|
|
+### Agent Model Used
|
|
|
+
|
|
|
+### Debug Log References
|
|
|
+
|
|
|
+### Completion Notes List
|
|
|
+
|
|
|
+### File List
|
|
|
+
|
|
|
+## QA Results
|
|
|
+*此部分由QA代理在审查完成后填写*
|