Explorar o código

📝 docs(stories): 创建故事004.002信用额度管理UI模块

- 创建多租户信用额度管理UI模块故事文档
- 包含完整的任务分解和技术指导
- 总结故事004.001的9个经验教训
- 标注参考的其他UI模块文件路径
- 包含完整的测试策略和要求

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
yourname hai 1 mes
pai
achega
37413019c8
Modificáronse 1 ficheiros con 298 adicións e 0 borrados
  1. 298 0
      docs/stories/004.002.credit-balance-management-ui-mt.story.md

+ 298 - 0
docs/stories/004.002.credit-balance-management-ui-mt.story.md

@@ -0,0 +1,298 @@
+# Story 004.002: 创建多租户信用额度管理UI模块
+
+## Status
+Draft
+
+## Story
+**As a** 后台管理员,
+**I want** 有一个界面来管理用户信用额度,
+**so that** 方便地设置和调整用户额度
+
+## Acceptance Criteria
+1. 创建用户额度管理页面,显示用户列表和当前额度
+2. 实现额度设置和调整功能
+3. 提供额度使用记录查询界面
+4. 显示用户欠款统计信息
+5. 界面风格与现有后台保持一致
+6. 添加权限控制,只有管理员可访问
+
+## Tasks / Subtasks
+- [ ] **创建多租户信用额度管理UI模块包结构** (AC: 1, 2, 3, 4, 5, 6)
+  - [ ] 创建包目录:`packages/credit-balance-management-ui-mt/`
+  - [ ] 配置package.json依赖关系(参考:`packages/user-management-ui-mt/package.json`)
+  - [ ] 配置TypeScript编译选项(参考:`packages/user-management-ui-mt/tsconfig.json`)
+  - [ ] 配置Vitest测试环境(参考:`packages/user-management-ui-mt/vitest.config.ts`)
+  - [ ] 配置ESLint配置(参考:`packages/user-management-ui-mt/eslint.config.js`)
+
+- [ ] **创建API客户端** (AC: 1, 2, 3, 4)
+  - [ ] 创建API客户端文件:`src/api/creditBalanceClient.ts`(参考:`packages/user-management-ui-mt/src/api/userClient.ts`)
+  - [ ] 实现额度查询API客户端方法
+  - [ ] 实现额度设置API客户端方法
+  - [ ] 实现额度调整API客户端方法
+  - [ ] 实现额度变更记录查询API客户端方法
+  - [ ] 实现结账恢复额度API客户端方法
+
+- [ ] **创建类型定义** (AC: 1, 2, 3, 4)
+  - [ ] 创建类型文件:`src/types/creditBalance.ts`(参考:`packages/user-management-ui-mt/src/types/index.ts`)
+  - [ ] 定义额度查询响应类型
+  - [ ] 定义额度变更记录类型
+  - [ ] 定义额度设置请求类型
+  - [ ] 定义额度调整请求类型
+
+- [ ] **创建React Hooks** (AC: 1, 2, 3, 4)
+  - [ ] 创建hooks文件:`src/hooks/useCreditBalance.ts`(参考:`packages/user-management-ui-mt/src/hooks/useUsers.ts`)
+  - [ ] 实现额度查询hook(useCreditBalance)
+  - [ ] 实现额度设置hook(useSetCreditLimit)
+  - [ ] 实现额度调整hook(useAdjustCreditLimit)
+  - [ ] 实现额度变更记录查询hook(useCreditBalanceLogs)
+  - [ ] 实现结账恢复额度hook(useCheckoutCreditBalance)
+
+- [ ] **创建额度管理主组件** (AC: 1, 2, 3, 4, 5)
+  - [ ] 创建主组件:`src/components/CreditBalanceManagement.tsx`(参考:`packages/user-management-ui-mt/src/components/UserManagement.tsx`)
+  - [ ] 实现用户额度列表表格显示
+  - [ ] 实现额度设置表单对话框
+  - [ ] 实现额度调整表单对话框
+  - [ ] 实现额度变更记录查询界面
+  - [ ] 实现欠款统计信息显示
+  - [ ] 实现结账恢复额度功能
+
+- [ ] **实现权限控制** (AC: 6)
+  - [ ] 添加管理员权限检查(参考:`packages/user-management-ui-mt/src/components/UserManagement.tsx`中的权限控制)
+  - [ ] 实现只有管理员角色才能访问额度管理界面
+  - [ ] 添加权限不足时的错误提示
+
+- [ ] **编写测试** (AC: 1, 2, 3, 4, 5, 6)
+  - [ ] **组件单元测试**:测试额度管理组件功能(参考:`packages/user-management-ui-mt/tests/unit/UserManagement.test.tsx`)
+  - [ ] **集成测试**:测试API集成和权限控制(参考:`packages/user-management-ui-mt/tests/integration/userManagement.integration.test.tsx`)
+  - [ ] **权限测试**:测试管理员和非管理员访问权限
+  - [ ] 确保测试覆盖率 ≥ 80%
+
+- [ ] **配置包导出和集成** (AC: 1, 2, 3, 4, 5, 6)
+  - [ ] 创建主入口文件:`src/index.ts` 导出所有模块接口(参考:`packages/user-management-ui-mt/src/index.ts`)
+  - [ ] 配置包导出,确保可以正确导入和使用
+  - [ ] 更新根package.json的workspace配置
+
+## Dev Notes
+
+### 技术栈信息 [Source: architecture/tech-stack.md]
+- **前端框架**: React 19.1.0 + TypeScript
+- **路由**: React Router v7
+- **状态管理**: @tanstack/react-query (服务端状态) + Context (本地状态)
+- **UI组件库**: shadcn/ui (基于Radix UI)
+- **构建工具**: Vite 7.0.0
+- **样式**: Tailwind CSS 4.1.11
+- **HTTP客户端**: 基于Hono Client的封装 + axios适配器
+
+### 项目结构信息 [Source: architecture/source-tree.md]
+- **包管理**: 使用pnpm workspace管理多包依赖关系
+- **包架构层次**:
+  - **基础设施层**: shared-types → shared-utils → shared-crud
+  - **测试基础设施**: shared-test-util
+  - **业务模块层**: 多租户模块包(-mt后缀),支持租户数据隔离
+  - **前端界面层**: 共享UI组件包 + 单租户管理界面包 + 多租户管理界面包
+  - **应用层**: server (重构后)
+- **多租户架构**:
+  - **包复制策略**: 基于Epic-007方案,通过复制单租户包创建多租户版本
+  - **租户隔离**: 通过租户ID实现数据隔离,支持多租户部署
+  - **前端包**: 10个多租户管理界面包,支持租户上下文管理
+  - **后端包**: 10个多租户模块包,支持租户数据隔离
+  - **共享组件**: `@d8d/shared-ui-components` 提供46+基础UI组件
+- **文件命名**: 保持现有kebab-case命名约定
+- **模块化架构**: 采用分层包结构,支持按需安装和独立开发
+
+### 组件架构信息 [Source: architecture/component-architecture.md]
+**实际项目组件组织**:
+```text
+src/client/
+├── admin/                 # 管理后台应用
+│   ├── components/        # 管理后台专用组件
+│   ├── hooks/            # 管理后台Hooks
+│   ├── layouts/          # 布局组件
+│   ├── pages/            # 页面组件
+│   ├── routes.tsx        # 路由配置
+│   └── index.tsx         # 管理后台入口
+├── home/                 # 用户前台应用
+├── components/           # 共享UI组件
+│   └── ui/              # shadcn/ui组件库(50+组件)
+├── hooks/               # 共享Hooks
+├── lib/                 # 工具库
+├── utils/               # 工具函数
+└── api.ts               # API客户端配置
+```
+
+### 编码标准 [Source: architecture/coding-standards.md]
+- **代码风格**: TypeScript严格模式,一致的缩进和命名
+- **测试位置**: `__tests__` 文件夹与源码并列(但实际使用`tests/`目录)
+- **覆盖率目标**: 核心业务逻辑 > 80%
+- **测试类型**: 单元测试、集成测试、E2E测试
+- **现有API兼容性**: 确保测试不破坏现有API契约
+
+### 从故事004.001学到的经验教训
+1. **PostgreSQL类型兼容性**: PostgreSQL不支持`tinyint`类型,需要改为`smallint`
+2. **集成测试数据库连接**: 使用`IntegrationTestDatabase`类替代`createIntegrationTestDb`函数
+3. **路由架构**: 参照订单模块采用链式聚合模式,使用独立路由文件聚合导出
+4. **测试写法**: 使用真实JWT令牌和RPC风格API调用
+5. **类型检查**: 注意分页参数类型、枚举使用、referenceId类型等问题
+6. **小数精度**: TypeORM decimal字段返回字符串,在服务中需要转换为数字
+7. **数据库索引**: 避免重复创建相同索引名称
+8. **认证失败**: 创建测试数据工厂,使用真实用户实体生成JWT令牌
+9. **Zod验证**: 将Schema中的`z.number()`改为`z.coerce.number()`
+
+### 数据模型设计 [Source: docs/prd/epic-004-credit-payment.md#数据库设计]
+**credit_balance_mt表结构**:
+```sql
+CREATE TABLE credit_balance_mt (
+  id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
+  tenant_id INT UNSIGNED NOT NULL COMMENT '租户ID',
+  user_id INT UNSIGNED NOT NULL COMMENT '用户ID',
+  total_limit DECIMAL(10,2) DEFAULT 0.00 COMMENT '总额度',
+  used_amount DECIMAL(10,2) DEFAULT 0.00 COMMENT '已用额度',
+  available_amount DECIMAL(10,2) GENERATED ALWAYS AS (total_limit - used_amount) STORED COMMENT '可用额度',
+  is_enabled TINYINT DEFAULT 1 COMMENT '是否启用(0:禁用,1:启用)',
+  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  UNIQUE KEY uk_tenant_user (tenant_id, user_id),
+  INDEX idx_tenant_id (tenant_id),
+  INDEX idx_user_id (user_id)
+) COMMENT='用户信用额度表';
+```
+
+**credit_balance_log_mt表结构**:
+```sql
+CREATE TABLE credit_balance_log_mt (
+  id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
+  tenant_id INT UNSIGNED NOT NULL COMMENT '租户ID',
+  user_id INT UNSIGNED NOT NULL COMMENT '用户ID',
+  change_type VARCHAR(20) NOT NULL COMMENT '变更类型: SET_LIMIT(设置额度), PAYMENT(支付扣减), CHECKOUT(结账恢复), CANCEL_ORDER(取消订单恢复), REFUND(退款恢复), ADJUST(调整额度)',
+  change_amount DECIMAL(10,2) NOT NULL COMMENT '变更金额(正数表示增加额度,负数表示减少额度)',
+  before_total DECIMAL(10,2) COMMENT '变更前总额度',
+  after_total DECIMAL(10,2) COMMENT '变更后总额度',
+  before_used DECIMAL(10,2) COMMENT '变更前已用额度',
+  after_used DECIMAL(10,2) COMMENT '变更后已用额度',
+  reference_id VARCHAR(100) COMMENT '关联ID(订单号等)',
+  remark VARCHAR(500) COMMENT '备注',
+  operator_id INT UNSIGNED COMMENT '操作人ID',
+  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+  INDEX idx_tenant_user (tenant_id, user_id),
+  INDEX idx_reference (reference_id),
+  INDEX idx_created (created_at)
+) COMMENT='额度变更记录表';
+```
+
+### API设计 [Source: docs/prd/epic-004-credit-payment.md#API设计]
+**对外API(供UI调用)**:
+1. `GET /api/credit-balance/{userId}` - 查询用户额度
+2. `PUT /api/credit-balance/{userId}` - 设置用户额度
+3. `POST /api/credit-balance/{userId}/adjust` - 调整用户额度
+4. `GET /api/credit-balance/{userId}/logs` - 查询额度变更记录
+5. `POST /api/credit-balance/payment` - 额度支付
+6. `POST /api/credit-balance/checkout` - 结账恢复额度
+
+**服务接口(供其他模块调用)**:
+1. `CreditBalanceService.restoreBalanceForCancelOrder(orderId, userId, amount)` - 取消订单恢复额度
+2. `CreditBalanceService.restoreBalanceForRefund(orderId, userId, refundAmount)` - 退款恢复额度
+
+**设计说明**:
+- **结账恢复**: 需要人工确认,因此通过信用管理UI手动触发,调用`/api/credit-balance/checkout`接口
+- **取消订单恢复**: 自动触发,订单模块在取消订单时直接调用`CreditBalanceService.restoreBalanceForCancelOrder()`方法
+- **退款恢复**: 自动触发,支付模块在退款处理时直接调用`CreditBalanceService.restoreBalanceForRefund()`方法
+- **模块间调用**: 使用PNPM工作空间,通过`@d8d/credit-balance-module-mt`包名导入服务类进行直接调用
+
+### 文件位置和命名约定
+- **UI模块包**: `packages/credit-balance-management-ui-mt/`
+- **API客户端文件**: `packages/credit-balance-management-ui-mt/src/api/creditBalanceClient.ts`
+- **类型文件**: `packages/credit-balance-management-ui-mt/src/types/creditBalance.ts`
+- **Hooks文件**: `packages/credit-balance-management-ui-mt/src/hooks/useCreditBalance.ts`
+- **主组件文件**: `packages/credit-balance-management-ui-mt/src/components/CreditBalanceManagement.tsx`
+- **测试文件**: `packages/credit-balance-management-ui-mt/tests/` 目录下
+- **主入口文件**: `packages/credit-balance-management-ui-mt/src/index.ts` (导出所有模块接口)
+
+### 参考的现有UI模块文件路径
+1. **用户管理UI模块**: `packages/user-management-ui-mt/` - 主要参考
+   - `src/components/UserManagement.tsx` - 主组件实现
+   - `src/api/userClient.ts` - API客户端实现
+   - `src/hooks/useUsers.ts` - React Hooks实现
+   - `src/types/index.ts` - 类型定义
+   - `tests/integration/userManagement.integration.test.tsx` - 集成测试
+
+2. **广告管理UI模块**: `packages/advertisement-management-ui-mt/`
+   - `src/components/AdvertisementManagement.tsx` - 表格和表单实现
+
+3. **文件管理UI模块**: `packages/file-management-ui-mt/`
+   - `src/components/FileManagement.tsx` - 文件上传和列表实现
+
+### 权限控制要求
+- 只有管理员角色(admin)可以访问额度管理界面
+- 需要在组件中添加权限检查逻辑
+- 权限不足时显示错误提示或重定向到登录页面
+
+### 界面设计要求
+- 使用shadcn/ui组件库,保持与现有后台界面风格一致
+- 表格显示用户列表,包含用户ID、用户名、总额度、已用额度、可用额度、是否启用等列
+- 提供额度设置和调整表单对话框
+- 提供额度变更记录查询界面,支持分页和筛选
+- 显示用户欠款统计信息卡片
+- 提供结账恢复额度功能按钮
+
+### 技术约束
+- **多租户支持**: 组件需要支持多租户上下文,通过租户ID进行数据隔离
+- **API集成**: 使用RPC风格的Hono Client进行API调用,确保类型安全
+- **状态管理**: 使用React Query进行服务端状态管理,确保数据同步
+- **错误处理**: 完整的错误处理机制,显示友好的错误提示
+- **加载状态**: 显示加载状态,提升用户体验
+- **表单验证**: 使用react-hook-form + zod进行表单验证
+
+### 集成点
+1. **额度模块集成**: 调用`@d8d/credit-balance-module-mt`的API接口
+2. **用户模块集成**: 显示用户信息,需要关联用户ID和用户名
+3. **权限系统集成**: 集成现有权限控制系统,确保只有管理员可访问
+4. **UI组件库集成**: 使用`@d8d/shared-ui-components`共享UI组件
+
+### 没有在架构文档中找到的特定指导
+- 具体的React组件实现示例
+- 具体的React Query hooks实现示例
+- 具体的权限检查实现示例
+- 具体的shadcn/ui组件使用示例
+
+## Testing
+### 测试标准 [Source: architecture/testing-strategy.md]
+- **测试文件位置**: `packages/credit-balance-management-ui-mt/tests/` 目录下
+- **单元测试位置**: `tests/unit/**/*.test.tsx`
+- **集成测试位置**: `tests/integration/**/*.test.tsx`
+- **测试框架**: Vitest + Testing Library + React Testing Library
+- **覆盖率要求**: 单元测试 ≥ 80%,集成测试 ≥ 60%
+- **测试模式**: 使用测试数据工厂模式,避免硬编码测试数据
+- **API模拟**: 使用MSW或Vitest的mock功能模拟API调用
+
+### 测试策略要求
+- **单元测试**: 验证单个组件功能、hooks逻辑、工具函数
+- **集成测试**: 验证API集成、权限控制、组件间协作
+- **权限测试**: 测试管理员和非管理员访问权限
+- **错误处理测试**: 测试各种错误场景和异常情况
+- **表单测试**: 测试表单验证、提交、错误处理
+- **表格测试**: 测试表格显示、分页、筛选功能
+
+### 测试数据管理
+- 使用测试数据工厂模式创建测试数据
+- 模拟API响应,避免真实API调用
+- 使用唯一标识符确保测试数据隔离
+- 模拟用户认证和权限状态
+
+## Change Log
+| Date | Version | Description | Author |
+|------|---------|-------------|--------|
+| 2025-12-02 | 1.0 | 初始故事创建 | Bob (Scrum Master) |
+
+## Dev Agent Record
+*此部分由开发代理在实现过程中填写*
+
+### Agent Model Used
+
+### Debug Log References
+
+### Completion Notes List
+
+### File List
+
+## QA Results
+*此部分由QA代理在审查完成后填写*