HaniBlindBox/.kiro/specs/menu-crud/design.md
2026-01-05 00:05:04 +08:00

6.2 KiB
Raw Blame History

Design Document: Menu CRUD

Overview

完善菜单管理页面的 CRUD 功能。后端 API 已完整实现,本设计主要关注前端实现:补充 API 接口定义、实现表单对话框、完善操作逻辑。

Architecture

┌─────────────────────────────────────────────────────────┐
│                    Menu Page (index.vue)                 │
├─────────────────────────────────────────────────────────┤
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────┐  │
│  │ Menu Table  │  │ Menu Dialog │  │ Delete Confirm  │  │
│  │ (Tree View) │  │   (Form)    │  │    Dialog       │  │
│  └─────────────┘  └─────────────┘  └─────────────────┘  │
├─────────────────────────────────────────────────────────┤
│                    Menu API (menu.ts)                    │
│  getMenuTree | createMenu | updateMenu | deleteMenu     │
├─────────────────────────────────────────────────────────┤
│                Backend API (已实现)                       │
│  GET /menus | POST /menus | PUT /menus/{id} | DELETE    │
└─────────────────────────────────────────────────────────┘

Components and Interfaces

Menu API 接口补充

// 创建菜单请求
export interface CreateMenuRequest {
  parentId: number
  name: string
  path?: string
  component?: string
  icon?: string
  menuType: number  // 1=目录, 2=菜单, 3=按钮
  permission?: string
  sortOrder: number
  status: number    // 1=显示, 0=隐藏
  isExternal: boolean
  isCache: boolean
}

// 更新菜单请求
export interface UpdateMenuRequest {
  parentId: number
  name: string
  path?: string
  component?: string
  icon?: string
  menuType: number
  permission?: string
  sortOrder: number
  status: number
  isExternal: boolean
  isCache: boolean
}

// API 函数
export function createMenu(data: CreateMenuRequest): Promise<ApiResponse<number>>
export function updateMenu(id: number, data: UpdateMenuRequest): Promise<ApiResponse<void>>
export function deleteMenu(id: number): Promise<ApiResponse<void>>
export function getMenuById(id: number): Promise<ApiResponse<MenuTree>>

Menu Form 表单字段

字段 类型 组件 验证规则
parentId number el-tree-select 可选默认0表示顶级
name string el-input 必填
menuType number el-radio-group 必填1/2/3
icon string el-input 可选,目录/菜单时显示
path string el-input 菜单类型时必填
component string el-input 菜单类型时必填
permission string el-input 按钮类型时必填
sortOrder number el-input-number 必填,>=0
status number el-radio-group 必填0/1
isExternal boolean el-switch 可选
isCache boolean el-switch 可选

表单验证逻辑

const formRules = {
  name: [{ required: true, message: '请输入菜单名称' }],
  menuType: [{ required: true, message: '请选择菜单类型' }],
  path: [{ 
    required: true, 
    validator: (rule, value, callback) => {
      if (formData.menuType === 2 && !value) {
        callback(new Error('菜单类型必须填写路由路径'))
      } else {
        callback()
      }
    }
  }],
  component: [{ 
    required: true,
    validator: (rule, value, callback) => {
      if (formData.menuType === 2 && !value) {
        callback(new Error('菜单类型必须填写组件路径'))
      } else {
        callback()
      }
    }
  }],
  permission: [{
    validator: (rule, value, callback) => {
      if (formData.menuType === 3 && !value) {
        callback(new Error('按钮类型必须填写权限标识'))
      } else {
        callback()
      }
    }
  }]
}

Data Models

表单数据模型

interface MenuFormData {
  id: number
  parentId: number
  name: string
  path: string
  component: string
  icon: string
  menuType: number
  permission: string
  sortOrder: number
  status: number
  isExternal: boolean
  isCache: boolean
}

// 默认值
const defaultFormData: MenuFormData = {
  id: 0,
  parentId: 0,
  name: '',
  path: '',
  component: '',
  icon: '',
  menuType: 2,
  permission: '',
  sortOrder: 0,
  status: 1,
  isExternal: false,
  isCache: true
}

Correctness Properties

A property is a characteristic or behavior that should hold true across all valid executions of a system.

本功能主要是 UI 交互,大部分验证在后端完成。以下是可测试的属性:

Property 1: 表单提交数据完整性 For any valid form submission, the request payload SHALL contain all required fields based on menuType. Validates: Requirements 6.1, 6.2, 6.3

Property 2: 父菜单选择排除自身 For any menu being edited, the parent menu selector SHALL NOT include the menu itself or its descendants. Validates: Requirements 4.3

Error Handling

场景 处理方式
API 请求失败 显示 ElMessage.error 提示错误信息
表单验证失败 阻止提交,显示字段错误提示
删除有子菜单的菜单 后端返回错误,前端显示提示
网络超时 显示网络错误提示

Testing Strategy

由于本功能主要是 UI 交互,测试策略以手动测试为主:

  1. 功能测试:验证新增、编辑、删除操作正常工作
  2. 表单验证测试:验证必填字段和条件必填逻辑
  3. 边界测试:测试空数据、特殊字符等边界情况