---
description: 管理端 Vue3（@apps/admin）路由、API、权限与列表页
globs: apps/admin/**/*
alwaysApply: false
---

# Admin（Vue 3 + Vite）

## 栈与别名

- **Vue 3** + **Vite** + **Pinia** + **Vue Router** + **Element Plus** + **VXE Table**；样式可用 **UnoCSS**、SCSS（全局主题见 `vite.config` 中 `additionalData`）。
- 路径别名：`@/` → `src/`，`#/` → `types/`（API 类型、全局声明）。
- 构建脚本区分 Web（`bs:*`）与 Tauri 桌面端（`cs:*`）；改构建逻辑前确认目标形态。壳工程在 `src-tauri/`。
- 环境：`.env.development` / `.env.production`；勿提交密钥。

## API 层

- HTTP 封装：`src/utils/request`（默认导出 `$http`）。
- 接口函数放在 `src/api/**`，返回 **`$http.request<Req, Res>({ url, method, params/data })`**，类型从 `#/api/**` 或 `types/api/**/*.d.ts` 引入。
- 新增后端接口后，优先生成类型，再手写薄封装；url 与 server 路径一致（如 `/system/user/list`）。

## 状态与路由

- Pinia store：`src/store/modules/`（如 `auth`、`permission`、`tagsView`）；登录与 token 与 `@/utils/auth` 配合。
- 动态路由：`store/modules/permission.ts` 与 `router/guard.ts` 联动；勿绕开守卫硬编码跳转。

## 权限

- 按钮级权限：**`v-auth`** 指令 + `hasPermission`（`directives/modules/permission.ts`）。
- 权限码来自当前路由 `meta.perms`；超级管理员 `userId === 1` 跳过校验。
- 列表操作栏用 `ToolButtons`，内部已配合 `hasPermission`。

## 列表页模式

- **VXE Table** + **`FormView/SearchForm`** 查询表单 + **`ToolButtons`** 操作栏。
- 响应式布局可用 **`Grid`** / **`GridItem`**；字典展示用 **`DictTag`**；富文本用 **`WangEditor`**。

## Vue 组件

- 优先 **Composition API**（`<script setup>`），与现有页面风格一致。
- 图表用 ECharts（见 `views/charts`）。

## 共享库

- 可从 **`@llcz/common`** 引入纯工具（如 `isArray` 用于权限判断）；勿在 common 中引入 Vue/UI。

## 注释约定

遵循全仓 **`comment-standards.mdc`**。Admin 侧额外强调：

- **`src/api/**`**：接口函数 JSDoc 写清业务语义与特殊参数（分页字段名、导出格式）；url 与 server 一致，差异处注释原因。
- **`src/store/modules/`**：permission、auth 等核心模块的 action 注释**状态变更意图**（如「清空 tagsView 再注入动态路由」），避免误改守卫链路。
- **列表页**（VXE Table + SearchForm）：查询条件与后端 DTO 的映射、默认排序/分页、导出列与权限码，在 `setup` 或 composable 顶部用块注释说明。
- **权限**：`v-auth` 旁非显而易见的权限码、超级管理员例外逻辑，注释对应菜单/按钮的业务含义。
- **动态路由**：`permission.ts` / `router/guard.ts` 中绕开常规流程的分支（白名单、外链、404 回退）必须注释「为什么」。
- **复杂组件**（`FormView`、`ToolButtons`、图表页）：props 默认值或 hack（如表格高度、resize 监听）注释平台/布局原因。
- **勿注释**：Element Plus / VXE 常规用法、已有类型的 API 入参字段名复述。
