| 版本 | 日期 | 描述 | 作者 |
|---|---|---|---|
| 2.5 | 2025-10-25 | 根据代码核对更新订单导出功能故事US005-14,完善技术实现细节 | John (PM) |
| 2.4 | 2025-10-25 | 添加管理后台订单数据导出功能故事US005-14,顺延原有故事编号 | John (PM) |
| 2.3 | 2025-10-25 | 添加微信小程序环境自动登录获取openid故事US005-13,顺延原有故事编号 | John (PM) |
| 2.2 | 2025-10-25 | 添加小程序手机号获取集成故事US005-12,顺延原有故事编号 | John (PM) |
| 2.1 | 2025-10-20 | 添加车型和路线配置增强故事US005-04,顺延原有故事编号 | John (PM) |
| 2.0 | 2025-10-19 | 添加样式迁移合规性修复故事US005-03,顺延原有故事编号 | John (PM) |
| 1.9 | 2025-10-17 | 添加省市区实体设计方案,支持标准化行政区划数据管理 | John (PM) |
| 1.8 | 2025-10-17 | 采用地点实体方案,统一管理地点信息,支持省市区查询 | John (PM) |
| 1.7 | 2025-10-17 | 优化查询逻辑,明确通过路线查询活动的实现方式 | John (PM) |
| 1.6 | 2025-10-17 | 优化活动实体设计,添加举办地点字段,去程/返程动态判断 | John (PM) |
| 1.5 | 2025-10-16 | 为乘客、订单、用户添加管理后台查看故事 | John (PM) |
| 1.4 | 2025-10-16 | 修正数据模型,移除班次实体,与架构文档保持一致 | Bob (Scrum Master) |
| 1.3 | 2025-10-16 | 添加管理后台故事US005-01,确保故事闭环 | John (PM) |
| 1.2 | 2025-10-15 | 添加我的页面到MVP迁移范围 | John (PM) |
| 1.1 | 2025-10-15 | 重构页面迁移为用户故事任务 | John (PM) |
| 1.0 | 2025-10-15 | 基于实际项目状态创建Epic 005 | John (PM) |
实现出行服务的核心功能,包括路线查询、活动筛选、订单管理、乘客管理、支付集成等,将mini-demo的核心页面功能迁移到真实的后端系统。
mini-demo包含14个页面,Epic 005将页面迁移作为用户故事的具体任务进行拆分:
作为 系统管理员 我希望 能够配置活动、路线等基础数据 以便 用户能够查询和使用出行服务
验收标准:
管理后台页面任务:
作为 出行用户 我希望 能够查询出行路线和筛选活动类型 以便 快速找到适合的出行方案
验收标准:
页面迁移任务:
作为 产品经理 我希望 确保所有迁移页面严格遵守样式迁移规范 以便 保持用户体验一致性和设计系统完整性
验收标准:
技术实现任务:
作为 系统管理员 我希望 能够配置完整的车型枚举和独立的出行方式字段 以便 支持更灵活的出行服务组合查询
组合查询逻辑:
具体实现要求:
组合查询API参数映射:
vehicleType=bus&travelMode=carpoolvehicleType=business&travelMode=carpool,charter(支持两种出行方式)vehicleType=bus,business&travelMode=charter(支持两种车型)验收标准:
技术实现任务:
查询逻辑实现细节:
vehicleType=bus,business和travelMode=carpool,charter界面修改任务:
API修改任务:
API查询参数设计:
vehicleType: 支持逗号分隔的多个车型(如bus,business)travelMode: 支持逗号分隔的多个出行方式(如carpool,charter)vehicleType和travelMode参数同时存在时进行组合筛选作为 系统管理员 我希望 能够查看所有用户的乘客信息 以便 了解用户乘车人情况和进行数据统计
验收标准:
管理后台页面任务:
作为 出行用户 我希望 能够管理我的乘客信息 以便 快速选择乘车人
验收标准:
页面迁移任务:
作为 系统管理员 我希望 能够查看所有订单信息和状态 以便 监控订单流程和处理异常订单
验收标准:
管理后台页面任务:
作为 出行用户 我希望 能够创建订单并完成支付 以便 确认出行安排
验收标准:
页面迁移任务:
作为 出行用户 我希望 能够查看和管理我的订单状态 以便 了解出行安排进度
验收标准:
页面迁移任务:
作为 出行用户 我希望 能够查看和管理我的个人信息 以便 方便地管理我的出行服务
验收标准:
MVP已实现功能:
待完善功能:
技术状态:
样式迁移要求:
linear-gradient(135deg, #4A90C2 0%, #357ABD 100%)linear-gradient(135deg, #667eea 0%, #764ba2 100%)作为 系统 我希望 集成微信支付功能 以便 支持用户完成订单支付
验收标准:
wechatpay-node-v3 SDK 完整实现备注: 退款功能MVP已标记为不需要,当前仅支持支付功能
技术实现详情:
packages/server/src/modules/payment/payment.service.tspackages/server/src/api/payment/create.ts待支付 → 支付中 → 已支付/支付失败 状态流转作为 出行用户 我希望 能够通过微信小程序一键获取我的手机号 以便 快速完成订单联系信息填写
验收标准:
getPhoneNumber 功能调用技术实现方案:
getPhoneNumber 组件phone 字段前端实现细节:
// 订单确认页面手机号获取逻辑
const handleGetPhoneNumber = async (e: any) => {
if (e.detail.errMsg === 'getPhoneNumber:ok') {
// 调用后端手机号解密API
const phoneData = await authClient.phone.$post({
json: {
code: e.detail.code,
encryptedData: e.detail.encryptedData,
iv: e.detail.iv
}
});
// 更新用户信息和页面状态
setPhoneNumber(phoneData.phoneNumber);
setHasPhoneNumber(true);
}
}
后端实现细节:
packages/server/src/modules/auth/mini-auth.service.tsdecryptPhoneNumber(code: string, encryptedData: string, iv: string)API设计:
// 手机号解密API
POST /api/v1/auth/phone
{
"code": "微信小程序获取的code",
"encryptedData": "加密数据",
"iv": "加密算法的初始向量"
}
// 响应
{
"phoneNumber": "13812345678",
"countryCode": "86",
"purePhoneNumber": "13812345678"
}
API路由位置:
packages/server/src/api/auth/phone/post.tspackages/server/src/api/auth/index.ts 中添加安全考虑:
依赖关系:
测试策略:
作为 微信小程序用户 我希望 在微信小程序环境中能够通过微信一键登录并获取我的openid 以便 便捷使用出行服务,无需手动输入账号密码
验收标准:
wx.login 获取code技术实现方案:
wx.login API获取code,支持用户信息授权前端实现细节:
// 微信小程序登录页面登录逻辑
const handleWechatLogin = async () => {
try {
// 1. 获取用户信息授权
const userProfile = await Taro.getUserProfile({
desc: '用于完善用户资料'
});
// 2. 获取登录code
const loginRes = await Taro.login();
if (!loginRes.code) {
throw new Error('获取登录凭证失败');
}
// 3. 使用RPC client调用后端小程序登录API
const response = await authClient['mini-login'].$post({
json: {
code: loginRes.code,
userInfo: userProfile.userInfo
}
});
if (response.status === 200) {
const { token, user, isNewUser } = await response.json();
// 4. 保存token和用户信息
Taro.setStorageSync('userInfo', user);
Taro.setStorageSync('mini_token', token);
Taro.showToast({
title: isNewUser ? '注册成功' : '登录成功',
icon: 'success',
duration: 1500
});
// 跳转到首页
setTimeout(() => {
Taro.switchTab({ url: '/pages/home/index' });
}, 1500);
} else {
const errorData = await response.json();
throw new Error(errorData.message || '登录失败');
}
} catch (error) {
// 错误处理逻辑
}
}
// 应用启动时调用
App({
onLaunch() {
autoLogin();
}
});
后端实现细节:
packages/server/src/modules/auth/mini-auth.service.tsminiLogin(code: string)jscode2session API获取openid和session_keyAPI设计:
// 小程序自动登录API
POST /api/v1/auth/mini-login
{
"code": "微信小程序登录获取的code",
"userInfo": {
"nickName": "用户昵称",
"avatarUrl": "头像URL"
}
}
// 响应
{
"token": "JWT认证token",
"user": {
"id": "用户ID",
"username": "用户名",
"nickname": "昵称",
"phone": "手机号",
"email": "邮箱",
"avatarFileId": "头像文件ID",
"registrationSource": "注册来源"
},
"isNewUser": true
}
API路由位置:
packages/server/src/api/auth/mini-login/post.tspackages/server/src/api/auth/index.ts 中注册用户实体扩展:
// 在User实体中已添加微信相关字段
@Entity('users')
export class UserEntity {
// 现有字段...
@Column({ name: 'openid', type: 'varchar', length: 255, nullable: true, unique: true })
openid!: string | null;
@Column({ name: 'unionid', type: 'varchar', length: 255, nullable: true })
unionid!: string | null;
@Column({ name: 'registration_source', type: 'varchar', length: 20, default: 'web' })
registrationSource!: string;
}
安全考虑:
依赖关系:
测试策略:
实现状态总结:
作为 系统管理员 我希望 能够在管理后台的订单管理页面导出订单数据为xlsx格式 以便 进行数据分析和报表制作
验收标准:
实际可导出数据字段(基于代码核对):
iduser.username, user.phoneroute.name, route.descriptionpassengerCounttotalAmountstatus (待支付、待出发、行程中、已完成、已取消)paymentStatus (待支付、支付中、已支付、支付失败、已退款、已关闭)createdAtupdatedAtpassengerSnapshots (包含姓名、证件类型、证件号码等)技术实现方案(基于实际代码架构):
xlsx 库生成Excel文件pageSize参数支持大量数据查询前端实现细节(基于实际代码结构):
// 订单导出功能实现 - 基于实际Orders.tsx页面结构
const handleExportOrders = async () => {
try {
// 1. 显示导出进度
setExporting(true);
// 2. 获取当前页面筛选条件(基于现有filters和searchParams)
const exportFilters = {
status: filters.status,
paymentStatus: filters.paymentStatus,
search: searchParams.search,
pageSize: 10000 // 使用大pageSize获取所有数据
};
// 3. 调用现有订单API获取数据
const response = await orderClient.$get({
query: {
page: 1,
pageSize: 10000,
keyword: searchParams.search,
filters: JSON.stringify({
status: filters.status,
paymentStatus: filters.paymentStatus
})
}
});
if (response.status !== 200) {
throw new Error('获取订单数据失败');
}
const ordersData = await response.json();
const orders = ordersData.data || [];
// 4. 生成Excel文件
const workbook = XLSX.utils.book_new();
const worksheet = XLSX.utils.json_to_sheet(orders.map(order => ({
'订单编号': `#${order.id}`,
'用户名': order.user?.username || '未知用户',
'手机号': order.user?.phone || '未知',
'路线名称': order.route?.name || '未知路线',
'路线描述': order.route?.description || '无描述',
'乘客数量': order.passengerCount,
'订单金额': `¥${order.totalAmount}`,
'订单状态': order.status,
'支付状态': order.paymentStatus,
'创建时间': format(new Date(order.createdAt), 'yyyy-MM-dd HH:mm:ss'),
'更新时间': format(new Date(order.updatedAt), 'yyyy-MM-dd HH:mm:ss'),
'乘客信息': order.passengerSnapshots?.map((p: any, index: number) =>
`乘客${index + 1}: ${p.name || '未知'} (${p.idType || '未知'}: ${p.idNumber || '未知'})`
).join('; ') || '无乘客信息'
})));
// 5. 设置表头样式
XLSX.utils.book_append_sheet(workbook, worksheet, '订单数据');
// 6. 生成文件并下载
const fileName = `订单数据_${dayjs().format('YYYYMMDD_HHmmss')}.xlsx`;
XLSX.writeFile(workbook, fileName);
// 7. 显示成功提示
message.success(`订单数据导出成功,共导出 ${orders.length} 条记录`);
} catch (error) {
console.error('导出失败:', error);
message.error('导出失败,请重试');
} finally {
setExporting(false);
}
};
后端API现状(基于代码核对):
GET /api/v1/admin/orders 已存在page, pageSize, keyword, filters (JSON格式)user 和 route 关联数据管理后台页面任务:
技术实现任务:
性能优化策略:
pageSize参数安全考虑:
依赖关系:
实现状态总结:
基于架构文档设计,需要实现以下实体:
基于对现有设计的分析,活动实体需要进行以下优化:
问题识别:
优化方案:
数据模型示例:
地点 (Location)
├── 名称 (name)
├── 省份 (province)
├── 城市 (city)
├── 区县 (district)
├── 详细地址 (address)
├── 纬度 (latitude)
└── 经度 (longitude)
活动 (Activity)
├── 名称 (name)
├── 描述 (description)
├── 举办地点 (venueLocation) → 关联Location
├── 开始时间 (startDate)
└── 结束时间 (endDate)
路线 (Route)
├── 出发地 (startLocation) → 关联Location
├── 目的地 (endLocation) → 关联Location
├── 上车点 (pickupPoint)
├── 下车点 (dropoffPoint)
├── 车型 (vehicleType) → VehicleType枚举(大巴/中巴/小车/商务车)
├── 出行方式 (travelMode) → TravelMode枚举(拼车/包车)
├── 关联活动 (activity)
└── 其他信息...
基于发现的省市区数据文件,需要实现标准化的省市区数据管理:
问题识别:
优化方案:
省市区实体设计:
省市区 (Area)
├── ID (id) - 主键
├── 父级ID (parentId) - 关联父级区域,0表示顶级(省/直辖市)
├── 名称 (name) - 区域名称
├── 层级 (level) - 1:省/直辖市, 2:市, 3:区/县
├── 代码 (code) - 行政区划代码
├── 创建时间 (createdAt)
└── 更新时间 (updatedAt)
数据来源和使用:
scripts/省市区.csv (包含3282条完整记录)scripts/generate-area-sql.mjs (CSV转SQL导入脚本)地点实体优化:
地点 (Location)
├── 名称 (name)
├── 省份 (province) → 关联AreaEntity (level=1)
├── 城市 (city) → 关联AreaEntity (level=2)
├── 区县 (district) → 关联AreaEntity (level=3)
├── 详细地址 (address)
├── 纬度 (latitude)
└── 经度 (longitude)
省市区查询逻辑设计:
API设计示例:
// 获取省份列表
GET /api/v1/areas/provinces
// 获取城市列表
GET /api/v1/areas/cities?provinceId=1
// 获取区县列表
GET /api/v1/areas/districts?cityId=34
// 地点查询(支持省市区筛选)
GET /api/v1/locations?provinceId=1&cityId=34&districtId=36
优势:
基于优化的数据模型,查询逻辑需要相应调整:
地点查询:
路线查询:
vehicleType=bus&travelMode=carpoolvehicleType=business&travelMode=carpool,chartervehicleType=bus,business&travelMode=charter活动查询:
API设计示例:
// 查询地点(支持省市区筛选)
GET /api/v1/locations?province=北京市&city=北京市&name=工人体育场
// 查询路线(支持组合查询)
GET /api/v1/routes?startLocationId=123&endLocationId=456&date=2025-10-15&type=departure&vehicleType=bus,business&travelMode=carpool,charter
// 响应:路线列表,包含完整的地点信息和活动信息
{
routes: [
{
id: 1,
startLocation: {
id: 123,
name: "中关村",
province: "北京市",
city: "北京市",
district: "海淀区"
},
endLocation: {
id: 456,
name: "工人体育场",
province: "北京市",
city: "北京市",
district: "朝阳区"
},
vehicleType: "bus",
travelMode: "carpool",
activity: {
id: 1,
name: "中超联赛北京国安主场赛事",
venueLocation: {
id: 456,
name: "工人体育场",
province: "北京市",
city: "北京市",
district: "朝阳区"
}
}
}
]
}
需要新增以下API端点:
管理后台API:
GET /api/v1/admin/locations - 地点管理列表POST /api/v1/admin/locations - 创建地点PUT /api/v1/admin/locations/:id - 更新地点DELETE /api/v1/admin/locations/:id - 删除地点GET /api/v1/admin/activities - 活动管理列表POST /api/v1/admin/activities - 创建活动PUT /api/v1/admin/activities/:id - 更新活动DELETE /api/v1/admin/activities/:id - 删除活动GET /api/v1/admin/routes - 路线管理列表POST /api/v1/admin/routes - 创建路线PUT /api/v1/admin/routes/:id - 更新路线DELETE /api/v1/admin/routes/:id - 删除路线用户端API:
GET /api/v1/locations - 地点查询(支持省份、城市、区县、名称等参数)GET /api/v1/routes - 路线查询(支持出发地、目的地、日期、类型等参数,返回包含活动信息的路线列表)
vehicleType:车型筛选,支持多值(如bus,business)travelMode:出行方式筛选,支持多值(如carpool,charter)GET /api/v1/activities - 活动列表查询(基础信息查询)POST /api/v1/orders - 创建订单GET /api/v1/orders - 订单列表GET /api/v1/orders/:id - 订单详情PUT /api/v1/orders/:id/cancel - 取消订单POST /api/v1/passengers - 添加乘客GET /api/v1/passengers - 乘客列表PUT /api/v1/passengers/:id - 更新乘客DELETE /api/v1/passengers/:id - 删除乘客页面迁移任务已分配到各个用户故事中,确保每个页面迁移与对应的业务功能同步开发:
文档状态: 已更新 最后更新: 2025-10-25 下次评审: 2025-11-01