|
|
@@ -0,0 +1,141 @@
|
|
|
+# Story 006.002: 实现智能新增和删除功能
|
|
|
+
|
|
|
+## Status
|
|
|
+Draft
|
|
|
+
|
|
|
+## Story
|
|
|
+**As a** 管理员用户,
|
|
|
+**I want** 在树形省市区管理页面中直接新增和删除省市区数据,
|
|
|
+**so that** 我可以更高效地管理省市区层级关系,简化操作流程。
|
|
|
+
|
|
|
+## Acceptance Criteria
|
|
|
+1. 在树形结构中直接新增市和区:省级节点显示"新增市"按钮,市级节点显示"新增区"按钮
|
|
|
+2. 重新设计 AreaForm 组件,移除层级和父级选择字段
|
|
|
+3. 智能预填层级和父级信息:
|
|
|
+ - 页面顶部"新增省":层级自动为"省/直辖市",无父级
|
|
|
+ - 省级节点"新增市":层级自动为"市",父级自动为当前省份
|
|
|
+ - 市级节点"新增区":层级自动为"区/县",父级自动为当前城市
|
|
|
+4. 后端新增批量删除API:`DELETE /areas/:id/with-children`
|
|
|
+5. 前端调用新的批量删除API,支持递归删除子节点
|
|
|
+6. 删除确认对话框显示准确的子节点数量
|
|
|
+7. 验证新增和删除功能正常工作
|
|
|
+
|
|
|
+## Tasks / Subtasks
|
|
|
+- [ ] 重新设计 AreaForm 组件,移除层级和父级选择字段 (web/src/client/admin/components/AreaForm.tsx)
|
|
|
+- [ ] 在 AreaTreeAsync 组件中添加节点操作按钮:省级节点显示"新增市",市级节点显示"新增区" (web/src/client/admin/components/AreaTreeAsync.tsx)
|
|
|
+- [ ] 实现智能预填逻辑:根据操作上下文自动设置层级和父级信息
|
|
|
+- [ ] 后端实现批量删除API:`DELETE /areas/:id/with-children` (packages/server/src/api/admin/areas/index.ts)
|
|
|
+- [ ] 前端集成批量删除API,支持递归删除子节点
|
|
|
+- [ ] 实现删除确认对话框,显示准确的子节点数量
|
|
|
+- [ ] 添加错误处理和重试机制
|
|
|
+- [ ] 编写单元测试,验证智能预填功能
|
|
|
+- [ ] 编写集成测试,验证批量删除API
|
|
|
+- [ ] 编写E2E测试,验证完整的增删功能流程
|
|
|
+
|
|
|
+## Dev Notes
|
|
|
+
|
|
|
+### 技术栈要求
|
|
|
+- **前端框架**: React 19.1.0+,使用函数组件和Hooks [Source: architecture/tech-stack.md#L13]
|
|
|
+- **状态管理**: @tanstack/react-query 5.83.0+,服务端状态管理 [Source: architecture/tech-stack.md#L18]
|
|
|
+- **UI组件库**: shadcn/ui,基于Radix UI的组件库 [Source: architecture/admin-dashboard-standards.md#L26]
|
|
|
+- **HTTP客户端**: 基于Hono Client的封装 [Source: architecture/component-architecture.md#L50]
|
|
|
+
|
|
|
+### 项目结构
|
|
|
+- **AreaForm组件**: `web/src/client/admin/components/AreaForm.tsx` [Source: architecture/source-tree.md#L110]
|
|
|
+- **AreaTreeAsync组件**: `web/src/client/admin/components/AreaTreeAsync.tsx` [Source: 006.001.story.md#L28]
|
|
|
+- **后端API**: `packages/server/src/api/admin/areas/index.ts` [Source: architecture/source-tree.md#L66]
|
|
|
+- **现有树形API**: `packages/server/src/api/admin/areas/tree.ts` [Source: architecture/source-tree.md#L67]
|
|
|
+
|
|
|
+### API 集成
|
|
|
+- **现有区域API**: `GET /api/v1/admin/areas` 获取区域列表 [Source: packages/server/src/api/admin/areas/index.ts]
|
|
|
+- **现有树形API**: `GET /api/v1/admin/areas/tree` 获取完整树形结构 [Source: packages/server/src/api/admin/areas/tree.ts#L8-L47]
|
|
|
+- **子树API**: `GET /api/v1/admin/areas/tree/{id}` 按需加载子树 [Source: packages/server/src/api/admin/areas/tree.ts#L95-L150]
|
|
|
+- **新增批量删除API**: `DELETE /api/v1/admin/areas/:id/with-children` 删除节点及所有子节点
|
|
|
+
|
|
|
+### 数据模型
|
|
|
+- **AreaNode 接口**: 包含 id, name, code, level, parentId, isDisabled, children 等字段 [Source: web/src/client/admin/pages/Areas.tsx#L27-L36]
|
|
|
+- **层级定义**: 1=省/直辖市, 2=市, 3=区/县 [Source: web/src/client/admin/pages/Areas.tsx#L304-L311]
|
|
|
+- **智能预填逻辑**:
|
|
|
+ - 页面顶部"新增省": level=1, parentId=null
|
|
|
+ - 省级节点"新增市": level=2, parentId=当前省份ID
|
|
|
+ - 市级节点"新增区": level=3, parentId=当前城市ID
|
|
|
+
|
|
|
+### 组件交互
|
|
|
+- **AreaForm 组件**: 现有的表单组件,需要移除层级和父级选择字段,改为智能预填 [Source: web/src/client/admin/components/AreaForm.tsx]
|
|
|
+- **AreaTreeAsync 组件**: 异步加载树形组件,需要添加节点操作按钮 [Source: 006.001.story.md#L28]
|
|
|
+- **Dialog 组件**: 使用 shadcn/ui 对话框组件 [Source: web/src/client/admin/pages/Areas.tsx#L551-L565]
|
|
|
+- **Confirm Dialog**: 删除确认对话框,显示子节点数量
|
|
|
+
|
|
|
+### 批量删除API设计
|
|
|
+- **端点**: `DELETE /api/v1/admin/areas/:id/with-children`
|
|
|
+- **参数**:
|
|
|
+ - `id`: 要删除的区域ID (路径参数)
|
|
|
+ - `recursive`: 是否递归删除子节点 (查询参数,默认true)
|
|
|
+- **响应**:
|
|
|
+ - 成功: 200 OK,返回删除的节点数量
|
|
|
+ - 失败: 相应错误状态码和错误信息
|
|
|
+- **实现要求**: 使用数据库事务保证数据一致性
|
|
|
+
|
|
|
+### 错误处理
|
|
|
+- **表单提交失败**: 显示用户友好的错误信息
|
|
|
+- **删除操作失败**: 显示具体的失败原因
|
|
|
+- **网络错误**: 实现重试机制
|
|
|
+- **数据一致性**: 确保删除操作的原子性
|
|
|
+
|
|
|
+### 用户体验
|
|
|
+- **加载状态**: 显示异步操作进度指示器
|
|
|
+- **操作反馈**: 使用 Sonner toast 通知操作结果 [Source: architecture/admin-dashboard-standards.md#L33]
|
|
|
+- **确认对话框**: 删除前显示准确的子节点数量,防止误操作
|
|
|
+- **响应式设计**: 支持桌面端和移动端 [Source: architecture/admin-dashboard-standards.md#L508-L523]
|
|
|
+
|
|
|
+### 项目结构对齐
|
|
|
+- **组件位置**: 符合现有的组件组织模式
|
|
|
+- **API设计**: 遵循现有的RESTful API规范
|
|
|
+- **文件命名**: 保持现有的kebab-case命名约定 [Source: architecture/source-tree.md#L166]
|
|
|
+- **导入导出**: 使用ES模块和现有别名系统 [Source: architecture/source-tree.md#L170]
|
|
|
+
|
|
|
+## Testing
|
|
|
+
|
|
|
+### 测试标准
|
|
|
+- **测试文件位置**:
|
|
|
+ - 前端单元测试: `web/tests/unit/client/admin/components/AreaForm.test.tsx` [Source: architecture/testing-strategy.md#L27]
|
|
|
+ - 前端集成测试: `web/tests/integration/client/admin/pages/AreasTreePage.test.tsx` [Source: architecture/testing-strategy.md#L37]
|
|
|
+ - 后端API测试: `packages/server/tests/integration/api/admin/areas.test.ts` [Source: architecture/testing-strategy.md#L183]
|
|
|
+- **测试框架**: Vitest + Testing Library (前端) / Vitest + hono/testing (后端) [Source: architecture/testing-strategy.md#L29]
|
|
|
+- **测试模式**: 使用 Happy DOM 环境进行前端组件测试 [Source: architecture/testing-strategy.md#L97-L106]
|
|
|
+- **覆盖率要求**: 核心业务逻辑 ≥ 80% [Source: architecture/testing-strategy.md#L30]
|
|
|
+
|
|
|
+### 关键测试场景
|
|
|
+- AreaForm组件智能预填功能测试
|
|
|
+- 节点操作按钮显示逻辑测试
|
|
|
+- 批量删除API功能测试
|
|
|
+- 删除确认对话框显示准确的子节点数量
|
|
|
+- 错误处理和重试机制测试
|
|
|
+- 数据一致性测试(删除操作原子性)
|
|
|
+
|
|
|
+### 测试数据管理
|
|
|
+- **测试数据工厂**: 创建测试区域数据,包含层级关系
|
|
|
+- **数据库事务**: 集成测试使用事务回滚保证数据隔离
|
|
|
+- **边界测试**: 测试空节点、单节点、多层级节点的删除操作
|
|
|
+
|
|
|
+## Change Log
|
|
|
+| Date | Version | Description | Author |
|
|
|
+|------|---------|-------------|---------|
|
|
|
+| 2025-10-28 | 1.0 | 初始故事创建 | Bob (Scrum Master) |
|
|
|
+
|
|
|
+## Dev Agent Record
|
|
|
+
|
|
|
+### Agent Model Used
|
|
|
+*此部分将由开发代理在实施过程中填写*
|
|
|
+
|
|
|
+### Debug Log References
|
|
|
+*此部分将由开发代理在实施过程中填写*
|
|
|
+
|
|
|
+### Completion Notes List
|
|
|
+*此部分将由开发代理在实施过程中填写*
|
|
|
+
|
|
|
+### File List
|
|
|
+*此部分将由开发代理在实施过程中填写*
|
|
|
+
|
|
|
+## QA Results
|
|
|
+*此部分将由QA代理在质量保证过程中填写*
|