|
|
@@ -0,0 +1,378 @@
|
|
|
+# Story 5.10: 个人中心管理
|
|
|
+
|
|
|
+## Status
|
|
|
+In Progress - MVP Basic UI Completed
|
|
|
+
|
|
|
+## Story
|
|
|
+**As a** 出行用户
|
|
|
+**I want** 能够查看和管理我的个人信息
|
|
|
+**so that** 方便地管理我的出行服务
|
|
|
+
|
|
|
+## Acceptance Criteria
|
|
|
+1. 查看个人基本信息(头像、用户名、邮箱、注册时间)
|
|
|
+2. 头像上传和更新功能
|
|
|
+3. 快速访问基础功能(编辑资料、乘客管理、设置)
|
|
|
+4. 退出登录功能
|
|
|
+5. 账号信息展示(用户ID、最近登录时间)
|
|
|
+
|
|
|
+## Tasks / Subtasks
|
|
|
+- [x] 从 mini-demo 迁移我的页面 (AC: 1, 3, 4, 5)
|
|
|
+ - [x] 分析 mini-demo 我的页面结构和功能
|
|
|
+ - [x] 迁移页面到 `mini/src/pages/profile/`
|
|
|
+ - [x] 转换文件格式:`.js/.wxml/.wxss` → `.tsx` (React + TypeScript)
|
|
|
+ - [x] 转换样式系统:WXSS → Tailwind CSS
|
|
|
+ - [x] 转换状态管理:小程序 Page data → React useState
|
|
|
+ - [x] 转换事件处理:bindtap → onClick
|
|
|
+ - [x] 实现用户信息展示区域
|
|
|
+ - [x] 实现基础功能菜单
|
|
|
+ - [x] 实现退出登录功能
|
|
|
+ - [x] 实现账号信息展示
|
|
|
+- [ ] 按照 mini-demo 样式规范重构页面 (AC: 1, 3, 4, 5)
|
|
|
+ - [ ] 重构用户信息区域为渐变背景样式
|
|
|
+ - [ ] 添加会员信息卡片组件
|
|
|
+ - [ ] 重构功能菜单为网格布局
|
|
|
+ - [ ] 添加客服与帮助区域
|
|
|
+ - [ ] 实现精确的样式迁移
|
|
|
+ - [ ] 添加会员等级和积分展示
|
|
|
+ - [ ] 实现会员进度条组件
|
|
|
+ - [ ] 添加版本信息展示
|
|
|
+- [ ] 集成后端API完成功能 (AC: 2)
|
|
|
+ - [ ] 创建用户信息API端点
|
|
|
+ - [ ] 实现用户头像上传和更新功能
|
|
|
+ - [ ] 集成头像上传API到前端
|
|
|
+ - [ ] 实现编辑资料功能
|
|
|
+ - [ ] 实现设置页面功能
|
|
|
+- [ ] 编写小程序页面组件测试 (AC: 1, 3, 4, 5)
|
|
|
+ - [ ] 编写我的页面组件测试
|
|
|
+ - [ ] 测试用户信息展示功能
|
|
|
+ - [ ] 测试功能菜单跳转
|
|
|
+ - [ ] 测试退出登录流程
|
|
|
+ - [ ] 验证所有组件测试通过
|
|
|
+
|
|
|
+## Dev Notes
|
|
|
+
|
|
|
+### 数据模型设计
|
|
|
+基于 [docs/architecture/data-model-schema-changes.md#用户模型],用户实体已创建,包含以下关键属性:
|
|
|
+
|
|
|
+**用户实体关键属性** [Source: architecture/data-model-schema-changes.md#用户模型]:
|
|
|
+- `id`: number - 主键标识符
|
|
|
+- `username`: string - 唯一用户名(主要登录标识)
|
|
|
+- `email`: string | null - 可选邮箱地址
|
|
|
+- `avatarFileId`: number | null - 头像文件ID
|
|
|
+- `createdAt`: Date - 创建时间
|
|
|
+
|
|
|
+**订单统计数据结构** [Source: architecture/data-model-schema-changes.md#订单模型]:
|
|
|
+```typescript
|
|
|
+interface UserStats {
|
|
|
+ totalOrders: number;
|
|
|
+ pendingDepartureOrders: number;
|
|
|
+ completedOrders: number;
|
|
|
+ totalTrips: number;
|
|
|
+ lastTripDate: Date | null;
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### API端点设计
|
|
|
+基于 [docs/architecture/source-tree.md#实际项目结构],用户相关API端点必须遵循以下文件组织:
|
|
|
+
|
|
|
+**用户API文件位置** [Source: architecture/source-tree.md#实际项目结构]:
|
|
|
+- **用户信息API**: `packages/server/src/api/users/profile.ts`
|
|
|
+- **用户统计API**: `packages/server/src/api/users/stats.ts`
|
|
|
+- **用户模块**: `packages/server/src/modules/users/user.service.ts`
|
|
|
+- **用户实体**: `packages/server/src/modules/users/user.entity.ts`
|
|
|
+- **Zod Schema**: `packages/server/src/modules/users/user.schema.ts`
|
|
|
+
|
|
|
+### 非通用CRUD路由规范
|
|
|
+基于 [docs/architecture/non-generic-crud-standards.md#统计查询路由],用户统计API必须遵循非通用CRUD路由规范:
|
|
|
+
|
|
|
+**统计查询路由规范** [Source: architecture/non-generic-crud-standards.md#统计查询路由]:
|
|
|
+- 使用 `GET` 方法
|
|
|
+- 路径以 `/stats` 结尾
|
|
|
+- 返回聚合数据而非分页列表
|
|
|
+- 包含完整的错误处理
|
|
|
+
|
|
|
+**用户统计路由代码模板** [Source: architecture/non-generic-crud-standards.md#统计查询路由]:
|
|
|
+```typescript
|
|
|
+import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
|
|
|
+import { authMiddleware } from '../../middleware/auth.middleware';
|
|
|
+import { UserService } from '../../modules/users/user.service';
|
|
|
+import { UserStatsSchema } from '../../modules/users/user.schema';
|
|
|
+
|
|
|
+const statsRoute = createRoute({
|
|
|
+ method: 'get',
|
|
|
+ path: '/',
|
|
|
+ middleware: [authMiddleware],
|
|
|
+ responses: {
|
|
|
+ 200: {
|
|
|
+ description: '成功获取用户统计信息',
|
|
|
+ content: { 'application/json': { schema: UserStatsSchema } }
|
|
|
+ },
|
|
|
+ 401: { description: '未授权' },
|
|
|
+ 500: { description: '服务器错误' }
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+const app = new OpenAPIHono()
|
|
|
+ .openapi(statsRoute, async (c) => {
|
|
|
+ try {
|
|
|
+ const user = c.get('user');
|
|
|
+ const userService = new UserService();
|
|
|
+ const stats = await userService.getUserStats(user.id);
|
|
|
+ return c.json(stats, 200);
|
|
|
+ } catch (error) {
|
|
|
+ console.error('获取用户统计信息失败:', error);
|
|
|
+ return c.json({
|
|
|
+ code: 500,
|
|
|
+ message: error instanceof Error ? error.message : '获取统计信息失败'
|
|
|
+ }, 500);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+export default app;
|
|
|
+```
|
|
|
+
|
|
|
+### 当前MVP状态
|
|
|
+**页面迁移状态**: ✅ 基础功能已完成,需要样式重构
|
|
|
+- **迁移位置**: `mini/src/pages/profile/index.tsx`
|
|
|
+- **技术栈**: React + TypeScript + Tailwind CSS + shadcn/ui
|
|
|
+- **状态管理**: React useState + useAuth hook
|
|
|
+- **事件处理**: onClick 事件绑定
|
|
|
+
|
|
|
+**已实现功能**:
|
|
|
+- ✅ 用户信息展示区域(头像、用户名、邮箱、注册时间)
|
|
|
+- ✅ 头像上传组件(UI已集成,API待连接)
|
|
|
+- ✅ 基础功能菜单(编辑资料、乘客管理、设置、隐私政策、帮助反馈)
|
|
|
+- ✅ 退出登录功能
|
|
|
+- ✅ 账号信息展示(用户ID、最近登录时间)
|
|
|
+
|
|
|
+**待完成功能**:
|
|
|
+- 🔄 按照 mini-demo 样式规范重构页面
|
|
|
+- 🔄 头像上传API集成
|
|
|
+- 🔄 编辑资料功能实现
|
|
|
+- 🔄 设置页面功能实现
|
|
|
+- 🔄 乘客管理页面跳转
|
|
|
+
|
|
|
+**技术架构**:
|
|
|
+- 使用 `TabBarLayout` 布局组件
|
|
|
+- 集成 `useAuth` hook 进行用户认证
|
|
|
+- 使用 `AvatarUpload` 组件处理头像上传
|
|
|
+- 响应式设计和移动端优化
|
|
|
+
|
|
|
+### 样式迁移规范
|
|
|
+基于 [docs/architecture/mini-demo-migration-guide.md#我的页面样式迁移],必须遵循以下样式规范:
|
|
|
+
|
|
|
+#### 用户信息区域样式迁移
|
|
|
+**原WXSS样式**:
|
|
|
+```css
|
|
|
+.user-section {
|
|
|
+ background: linear-gradient(135deg, #4A90C2 0%, #357ABD 100%);
|
|
|
+ padding: 40rpx 32rpx 32rpx 32rpx;
|
|
|
+ color: #fff;
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**Tailwind迁移要求**:
|
|
|
+```tsx
|
|
|
+<View className="bg-gradient-to-br from-primary to-primary-dark p-[40rpx_32rpx_32rpx_32rpx] text-white">
|
|
|
+ {/* 用户信息内容 */}
|
|
|
+</View>
|
|
|
+```
|
|
|
+
|
|
|
+#### 会员卡片样式迁移
|
|
|
+**原WXSS样式**:
|
|
|
+```css
|
|
|
+.member-card {
|
|
|
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
|
+ border-radius: 20rpx;
|
|
|
+ padding: 24rpx;
|
|
|
+ color: #fff;
|
|
|
+ box-shadow: 0 6rpx 24rpx rgba(102, 126, 234, 0.3);
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**Tailwind迁移要求**:
|
|
|
+```tsx
|
|
|
+<View className="bg-gradient-to-br from-[#667eea] to-[#764ba2] rounded-card p-[24rpx] text-white shadow-[0_6rpx_24rpx_rgba(102,126,234,0.3)]">
|
|
|
+ {/* 会员卡片内容 */}
|
|
|
+</View>
|
|
|
+```
|
|
|
+
|
|
|
+#### 功能菜单样式迁移
|
|
|
+**原WXSS样式**:
|
|
|
+```css
|
|
|
+.menu-grid {
|
|
|
+ background: #FFFFFF;
|
|
|
+ border-radius: 20rpx;
|
|
|
+ overflow: hidden;
|
|
|
+ box-shadow: 0 4rpx 20rpx rgba(0,0,0,0.08);
|
|
|
+ border: 1rpx solid #E5E5EA;
|
|
|
+}
|
|
|
+
|
|
|
+.menu-item {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ padding: 28rpx 32rpx;
|
|
|
+ border-bottom: 2rpx solid #E5E5EA;
|
|
|
+ transition: background-color 0.3s ease;
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**Tailwind迁移要求**:
|
|
|
+```tsx
|
|
|
+<View className="bg-white rounded-card shadow-medium border border-border overflow-hidden">
|
|
|
+ <View className="flex items-center p-[28rpx_32rpx] border-b-2 border-border transition-colors duration-300 active:bg-gray-50">
|
|
|
+ {/* 菜单项内容 */}
|
|
|
+ </View>
|
|
|
+</View>
|
|
|
+```
|
|
|
+
|
|
|
+#### 精确样式迁移要求
|
|
|
+1. **颜色系统**: 必须使用 Tailwind 配置中定义的颜色变量
|
|
|
+2. **渐变效果**: 使用 `bg-gradient-to-br` 实现精确渐变
|
|
|
+3. **阴影层次**: 使用配置的阴影系统(light/medium/heavy)
|
|
|
+4. **圆角设计**: 使用 `rounded-card`、`rounded-button` 等预设圆角
|
|
|
+5. **间距布局**: 使用 `p-[40rpx_32rpx_32rpx_32rpx]` 等精确间距
|
|
|
+6. **字体系统**: 保持与 mini-demo 相同的字体大小和权重
|
|
|
+
|
|
|
+#### 组件结构迁移要求
|
|
|
+**原小程序结构**:
|
|
|
+```xml
|
|
|
+<view class="mine-page">
|
|
|
+ <!-- 用户信息区域 -->
|
|
|
+ <view class="user-section">...</view>
|
|
|
+ <!-- 会员信息卡片 -->
|
|
|
+ <view class="member-section">...</view>
|
|
|
+ <!-- 功能菜单 -->
|
|
|
+ <view class="menu-section">...</view>
|
|
|
+ <!-- 客服与帮助 -->
|
|
|
+ <view class="service-section">...</view>
|
|
|
+ <!-- 版本信息 -->
|
|
|
+ <view class="version-info">...</view>
|
|
|
+</view>
|
|
|
+```
|
|
|
+
|
|
|
+**React迁移结构**:
|
|
|
+```tsx
|
|
|
+<View className="min-h-screen bg-gray-50 pb-10">
|
|
|
+ {/* 用户信息区域 */}
|
|
|
+ <View className="bg-gradient-to-br from-primary to-primary-dark p-[40rpx_32rpx_32rpx_32rpx] text-white">
|
|
|
+ {/* 用户信息内容 */}
|
|
|
+ </View>
|
|
|
+
|
|
|
+ {/* 会员信息卡片 */}
|
|
|
+ <View className="m-[24rpx_32rpx]">
|
|
|
+ <MemberCard />
|
|
|
+ </View>
|
|
|
+
|
|
|
+ {/* 功能菜单 */}
|
|
|
+ <View className="m-[24rpx_32rpx]">
|
|
|
+ <MenuSection />
|
|
|
+ </View>
|
|
|
+
|
|
|
+ {/* 客服与帮助 */}
|
|
|
+ <View className="m-[24rpx_32rpx]">
|
|
|
+ <ServiceSection />
|
|
|
+ </View>
|
|
|
+
|
|
|
+ {/* 版本信息 */}
|
|
|
+ <View className="text-center py-8">
|
|
|
+ <Text className="text-[22rpx] text-gray-400">去看出行 v1.0.0</Text>
|
|
|
+ </View>
|
|
|
+</View>
|
|
|
+```
|
|
|
+
|
|
|
+### 视觉一致性检查清单
|
|
|
+基于 [docs/architecture/mini-demo-migration-guide.md#视觉一致性检查清单],必须确保:
|
|
|
+- [ ] 颜色系统完全匹配 mini-demo 设计
|
|
|
+- [ ] 渐变效果与 mini-demo 一致
|
|
|
+- [ ] 阴影层次和强度相同
|
|
|
+- [ ] 圆角设计完全一致
|
|
|
+- [ ] 间距布局精确匹配
|
|
|
+- [ ] 字体大小和权重一致
|
|
|
+- [ ] 按钮交互效果相同
|
|
|
+- [ ] 会员卡片效果一致
|
|
|
+
|
|
|
+### 技术栈要求
|
|
|
+基于 [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
|
|
|
+- **状态管理**: React Query
|
|
|
+- **样式系统**: Tailwind CSS + shadcn/ui
|
|
|
+
|
|
|
+### Taro小程序开发规范
|
|
|
+基于 [docs/architecture/taro-mini-program-standards.md],必须遵循Taro小程序开发规范:
|
|
|
+
|
|
|
+**组件开发规范** [Source: architecture/taro-mini-program-standards.md#组件开发规范]:
|
|
|
+- 使用函数组件和Hooks
|
|
|
+- 全面使用TypeScript确保类型安全
|
|
|
+- 使用React Query管理服务端状态
|
|
|
+
|
|
|
+**API调用规范** [Source: architecture/taro-mini-program-standards.md#api调用规范]:
|
|
|
+- 使用RPC客户端进行API调用
|
|
|
+- 统一的错误处理机制
|
|
|
+- 合理的缓存策略
|
|
|
+
|
|
|
+### 开发规范要求
|
|
|
+基于 [docs/architecture/coding-standards.md#通用crud开发规范],必须遵循编码标准:
|
|
|
+
|
|
|
+**API设计规范** [Source: architecture/coding-standards.md#通用crud开发规范]:
|
|
|
+- 使用Zod Schema进行请求和响应验证
|
|
|
+- 包含完整的错误处理
|
|
|
+- 使用统一的响应格式
|
|
|
+- 包含权限验证中间件
|
|
|
+
|
|
|
+### 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集成测试、用户统计API集成测试、小程序页面组件测试
|
|
|
+
|
|
|
+**具体测试要求** [Source: architecture/testing-strategy.md#测试金字塔策略]:
|
|
|
+- **用户信息API集成测试** (P1优先级)
|
|
|
+ - 测试用户信息API端点
|
|
|
+ - 验证用户基本信息查询功能
|
|
|
+ - 测试头像上传和更新功能
|
|
|
+ - 验证权限控制(只能查看自己的信息)
|
|
|
+- **用户统计API集成测试** (P1优先级)
|
|
|
+ - 测试用户统计API端点
|
|
|
+ - 验证订单统计查询逻辑
|
|
|
+ - 测试出行次数统计
|
|
|
+ - 验证统计数据的准确性
|
|
|
+- **小程序页面组件测试** (P1优先级)
|
|
|
+ - 测试我的页面组件渲染
|
|
|
+ - 测试用户信息展示功能
|
|
|
+ - 测试订单统计展示功能
|
|
|
+ - 测试功能菜单跳转
|
|
|
+- **E2E个人中心流程测试** (P2优先级)
|
|
|
+ - 测试完整的个人中心访问流程
|
|
|
+ - 验证用户信息正确显示
|
|
|
+ - 测试功能菜单跳转
|
|
|
+
|
|
|
+## Change Log
|
|
|
+| Date | Version | Description | Author |
|
|
|
+|------|---------|-------------|--------|
|
|
|
+| 2025-10-24 | 1.0 | 初始故事创建,基于史诗005 US005-10需求 | Bob (Scrum Master) |
|
|
|
+
|
|
|
+## Dev Agent Record
|
|
|
+*此部分由开发代理在实施过程中填写*
|
|
|
+
|
|
|
+### Agent Model Used
|
|
|
+
|
|
|
+### Debug Log References
|
|
|
+
|
|
|
+### Completion Notes List
|
|
|
+
|
|
|
+### File List
|
|
|
+
|
|
|
+## QA Results
|
|
|
+*此部分由QA代理在审查完成后填写*
|