Skip to content

新增业务模块

下面以“部门管理”为例,说明一个标准 CRUD 模块的落地过程。

1. 定义类型

ts
export interface DepartmentRow {
  id: number
  name: string
  status: string
  createdAt: string
}

export interface DepartmentForm {
  id?: number
  name: string
  status: string
}

类型可放在模块目录,也可在多个模块共享时放入 src/types

2. 定义 API

src/api/system/department/index.ts 中集中定义列表、详情、新增、更新、删除、批量删除和导出接口。列表返回 PageResult<DepartmentRow>,写接口开启成功提示。

生产接口推荐:

行为方法路径
分页列表GET/api/system/departments
详情GET/api/system/departments/:id
新增POST/api/system/departments
更新PUT/api/system/departments/:id
删除DELETE/api/system/departments/:id
批量删除DELETE/api/system/departments/batch

3. 创建列表页

创建 src/views/system/department/index.vue

  • 使用 SearchItem[] 描述名称、状态等筛选条件。
  • 使用 Table 展示列、分页、选择状态和加载失败状态。
  • 查询前设置 loading,失败时设置 loadError=true
  • 搜索或重置时将页码回到 1。
  • 枚举选项来自 dictStore.options('common_status')
  • 状态列使用 dictStore.tag('common_status', row.status)

4. 创建表单弹窗

创建 components/save.vue,对外暴露 open(row?)

  1. 新增时恢复默认表单,编辑时请求详情或复制行数据。
  2. 打开前清除上次校验状态。
  3. 提交前运行 Naive UI 表单验证。
  4. 根据是否存在主键选择 create/update API。
  5. 成功后关闭弹窗并触发 emit('success'),父页面重新查询。

不要只做前端必填校验;后端仍需执行完整的类型、长度、范围、权限和唯一性校验。

5. 配置操作列

ts
const rowActions = useRowActions<DepartmentRow>({
  inline: [
    {
      label: '编辑',
      type: 'primary',
      auth: 'update',
      onClick: (row) => saveRef.value?.open(row),
    },
    {
      label: '删除',
      type: 'error',
      auth: 'delete',
      confirm: (row) => `确认删除“${row.name}”吗?`,
      onClick: async (row) => {
        await deleteApi(row.id)
        await queryList()
      },
    },
  ],
})

列定义中使用 render: (row) => rowActions.render(row)auth 与当前路由 meta.actionList 比对,无权限的操作自动隐藏。

6. 批量操作

给 Table 开启选择列,监听 update:checkedRowKeys,使用 useBatchOptions 分批串行处理。操作结束后清空选择并刷新列表。服务端如返回逐项结果数组,组合式函数会展示结果表格。

7. 配置后端菜单

后端菜单中增加:

json
{
  "id": 120,
  "parent_id": 100,
  "path": "/system/department",
  "name": "SystemDepartment",
  "title": "部门管理",
  "component": "system/department/index.vue",
  "icon": "Iconpark-Peoples",
  "is_hide": "N",
  "fixed_tab": "N",
  "action_list": [
    { "action": "create" },
    { "action": "update" },
    { "action": "delete" },
    { "action": "export" }
  ]
}

component 必须能匹配 src/views/**/*.vue。菜单 name 应全局唯一,path 不得与静态路由冲突。

8. 验收

  • 无权限账号看不到菜单和按钮,并且直接调用接口也被后端拒绝。
  • 查询、分页、重置、空数据、加载失败、重复提交均表现正确。
  • 新增、编辑、删除、批量操作后数据一致。
  • 刷新页面与直接访问深层 URL 正常。
  • 中英文、明暗主题和窄屏布局无明显问题。

基于 MIT License 开源