# Yudao UI Admin Vben

> 芋道管理后台前端框架专家（基于 Vue Vben Admin v5）。适用于管理后台前端页面开发、CRUD 模块创建、API 定义、表格/表单/弹窗组件使用、路由配置、国际化、权限控制等任务。支持多 UI 库变体（Ant Design Vue、Element Plus、Naive UI、TDesign）。

- Skill: `xingyu4j/yudao-ui-admin-vben` (Agent Skill, multi-file: 5 files)
- Install (CLI): `npx skillmds@latest add xingyu4j/yudao-ui-admin-vben`
- Raw SKILL.md: https://api.skillmd.com/api/skills/xingyu4j/yudao-ui-admin-vben/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: xingyu4j (https://skillmd.com/u/xingyu4j)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/xingyu4j/yudao-ui-admin-vben

---


# 芋道管理后台前端（yudao-ui-admin-vben）

基于 **Vue Vben Admin v5**（pnpm workspaces + Turborepo monorepo），使用 Vue 3 + TypeScript + Vite 构建的企业级管理后台前端。提供多套 UI 库变体（Ant Design Vue、Element Plus、Naive UI、TDesign），与 ruoyi-vue-pro 后端配套。

## 项目结构

→ 详见 [yudao-ui-dir](references/yudao-ui-dir.md)

## 开发指南

| 主题 | 说明 | 参考 |
|------|------|------|
| 新增 CRUD 页面 | 创建完整前端 CRUD：API + 表格 + 表单弹窗 + 路由 | [yudao-ui-crud](references/yudao-ui-crud.md) |
| 新增 API | 添加带类型的后端 API 调用定义 | [yudao-ui-add-api](references/yudao-ui-add-api.md) |
| 组件参考 | VxeTable、Form、Modal 等核心组件用法 | [yudao-ui-components](references/yudao-ui-components.md) |

## 关键约定

### 路径别名

- `#/*` 映射到各应用的 `./src/*`（在 `package.json#imports` 中定义）
- 应用内部导入始终使用 `#/` 前缀：`import { $t } from '#/locales'`
- 共享包使用 `@vben/` 前缀：`import { preferences } from '@vben/preferences'`

### 依赖管理

- 内部包：`"workspace:*"`
- 第三方包：`"catalog:"`（版本在 `pnpm-workspace.yaml#catalog` 中集中管理）

### 代码风格

- 所有 Vue SFC 使用 `<script lang="ts" setup>`
- 仅使用 Composition API，禁止 Options API
- 使用 TailwindCSS 工具类进行样式开发
- 所有用户可见文本使用 `$t('key')` 国际化
- 遵循 Conventional Commits 规范

### API 请求

所有 API 通过 `requestClient`（基于 `@vben/request` 的 Axios 封装）调用：

```ts
import { requestClient } from '#/api/request';

// GET 请求
requestClient.get<ResultType>('/path', { params })

// POST 请求
requestClient.post<ResultType>('/path', data)

// PUT 请求
requestClient.put<ResultType>('/path', data)

// DELETE 请求
requestClient.delete('/path?id=1')

// 下载
requestClient.download('/path', { params })

// 上传
requestClient.upload('/path', { file, ...data })
```

后端返回格式 `{ code: 0, data: T, msg: '' }`，`requestClient` 自动解包为 `data`。

### API 文件组织

```
src/api/
├── core/           # 核心 API（登录、菜单等）
├── system/         # 系统管理模块
│   ├── dept/
│   │   └── index.ts
│   ├── user/
│   │   └── index.ts
│   └── ...
├── infra/          # 基础设施模块
├── bpm/            # 工作流模块
├── request.ts      # requestClient 配置
└── index.ts
```

### API 定义模式

```ts
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';

export namespace SystemXxxApi {
  export interface Xxx {
    id?: number;
    name: string;
    status: number;
    createTime?: Date;
  }
}

/** 查询分页 */
export function getXxxPage(params: PageParam) {
  return requestClient.get<PageResult<SystemXxxApi.Xxx>>('/system/xxx/page', { params });
}

/** 查询详情 */
export function getXxx(id: number) {
  return requestClient.get<SystemXxxApi.Xxx>(`/system/xxx/get?id=${id}`);
}

/** 新增 */
export function createXxx(data: SystemXxxApi.Xxx) {
  return requestClient.post('/system/xxx/create', data);
}

/** 修改 */
export function updateXxx(data: SystemXxxApi.Xxx) {
  return requestClient.put('/system/xxx/update', data);
}

/** 删除 */
export function deleteXxx(id: number) {
  return requestClient.delete(`/system/xxx/delete?id=${id}`);
}

/** 批量删除 */
export function deleteXxxList(ids: number[]) {
  return requestClient.delete(`/system/xxx/delete-list?ids=${ids.join(',')}`);
}

/** 精简列表（下拉选项） */
export function getSimpleXxxList() {
  return requestClient.get<SystemXxxApi.Xxx[]>('/system/xxx/simple-list');
}
```

### 页面文件组织

```
src/views/system/xxx/
├── data.ts            # 表单 Schema + 表格列定义
├── index.vue          # 列表页面（VxeTable Grid）
├── modules/
│   └── form.vue       # 新建/编辑弹窗（Modal + Form）
└── components/        # 页面特有组件（可选）
```

### 权限控制

TableAction 组件支持 `auth` 属性进行权限控制：

```ts
{
  label: '新增',
  auth: ['system:xxx:create'],  // 权限编码数组
  onClick: handleCreate,
}
```

指令方式：
```vue
<button v-access:code="['system:xxx:create']">新增</button>
```

组件方式：
```vue
<AccessControl :codes="['system:xxx:create']">
  <button>新增</button>
</AccessControl>
```

### 字典使用

```ts
import { DICT_TYPE } from '@vben/constants';
import { getDictOptions } from '@vben/hooks';

// 在表单中使用
{
  fieldName: 'status',
  component: 'RadioGroup',
  componentProps: {
    options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'),
  },
}

// 在表格中使用
{
  field: 'status',
  title: '状态',
  cellRender: {
    name: 'CellDict',
    props: { type: DICT_TYPE.COMMON_STATUS },
  },
}
```

### 国际化

```ts
import { $t } from '#/locales';

// 模板中
{{ $t('ui.actionTitle.create', ['用户']) }}

// 脚本中
$t('ui.actionMessage.deleteConfirm', [row.name])
```

常用 i18n key：
- `ui.actionTitle.create` / `edit` / `delete` / `deleteBatch`
- `ui.actionMessage.deleteConfirm` / `deleteBatchConfirm` / `deleteSuccess` / `operationSuccess`
- `common.edit` / `common.delete` / `common.status`

### 路由配置

前端路由仅用于不需要后端菜单管理的页面（如"我的站内信"）：

```ts
// src/router/routes/modules/system.ts
const routes: RouteRecordRaw[] = [
  {
    path: '/system/xxx',
    component: () => import('#/views/system/xxx/index.vue'),
    name: 'SystemXxx',
    meta: {
      title: 'Xxx管理',
      icon: 'ant-design:xxx-outlined',
      hideInMenu: true,     // 不显示在菜单（由后端菜单管理）
    },
  },
];
```

大部分页面通过后端菜单动态注册路由，无需手动配置前端路由。

### 应用变体

| 应用 | UI 库 | 路径 |
|------|-------|------|
| `web-antd` | Ant Design Vue | `apps/web-antd` |
| `web-antdv-next` | Ant Design Vue (Next) | `apps/web-antdv-next` |
| `web-ele` | Element Plus | `apps/web-ele` |
| `web-naive` | Naive UI | `apps/web-naive` |
| `web-tdesign` | TDesign Vue | `apps/web-tdesign` |

各应用在 `src/adapter/` 中桥接通用组件到具体 UI 库。

### 请求拦截器

`src/api/request.ts` 中的拦截器：
1. **请求拦截**：附加 `Bearer Token` + `Accept-Language` + `tenant-id` 请求头
2. **响应拦截**：API 解密（可选） → 解包 `{ code, data, msg }` → Token 刷新 → 错误提示

## 核心包参考

| 包名 | 路径 | 用途 |
|------|------|------|
| `@vben/request` | `packages/effects/request` | 基于 Axios 的 RequestClient |
| `@vben/common-ui` | `packages/effects/common-ui` | 共享 UI（Page、Modal、Drawer 等） |
| `@vben/hooks` | `packages/effects/hooks` | `useAppConfig`、`getDictOptions` 等 |
| `@vben/stores` | `packages/stores` | 全局 Pinia Store |
| `@vben/constants` | `packages/constants` | 全局常量（DICT_TYPE 等） |
| `@vben/utils` | `packages/utils` | 工具函数（handleTree 等） |
| `@vben/preferences` | `packages/preferences` | 响应式偏好管理器 |
| `@vben/locales` | `packages/locales` | vue-i18n 工具 |
| `@vben/access` | `packages/effects/access` | 路由/菜单生成，权限指令 |

## 常用命令

```bash
pnpm dev:antd           # 启动 Ant Design Vue 变体
pnpm dev:ele            # 启动 Element Plus 变体
pnpm build:antd         # 构建 Ant Design Vue 变体
pnpm lint               # ESLint 检查
pnpm format             # 代码格式化
pnpm test:unit          # 运行单元测试
pnpm check:type         # TypeScript 类型检查
```

