|
@@ -0,0 +1,1056 @@
|
|
|
|
|
+# 开发文档
|
|
|
|
|
+
|
|
|
|
|
+## 项目简介
|
|
|
|
|
+
|
|
|
|
|
+本项目是基于 Vue3 + TypeScript + Vite + Element Plus 的前端管理系统,采用前后端分离架构,提供完整的权限管理、CRUD操作等功能。
|
|
|
|
|
+
|
|
|
|
|
+## 技术栈
|
|
|
|
|
+
|
|
|
|
|
+- **框架**: Vue 3.4+ (Composition API)
|
|
|
|
|
+- **语言**: TypeScript 4.9+
|
|
|
|
|
+- **构建工具**: Vite 5.4+
|
|
|
|
|
+- **UI框架**: Element Plus 2.8+
|
|
|
|
|
+- **状态管理**: Pinia 2.0+
|
|
|
|
|
+- **路由**: Vue Router 4.4+
|
|
|
|
|
+- **CRUD框架**: Fast-Crud 1.21+
|
|
|
|
|
+- **HTTP客户端**: Axios 1.7+
|
|
|
|
|
+- **样式**: Tailwind CSS 3.2+ / SCSS
|
|
|
|
|
+
|
|
|
|
|
+## 环境要求
|
|
|
|
|
+
|
|
|
|
|
+- **Node.js**: >= 16.0.0 (推荐使用最新 LTS 版本)
|
|
|
|
|
+- **npm**: >= 7.0.0 (或使用 yarn)
|
|
|
|
|
+- **操作系统**: Windows / macOS / Linux
|
|
|
|
|
+
|
|
|
|
|
+## 快速开始
|
|
|
|
|
+
|
|
|
|
|
+### 1. 克隆项目
|
|
|
|
|
+
|
|
|
|
|
+```bash
|
|
|
|
|
+git clone <repository-url>
|
|
|
|
|
+cd zheda
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 2. 安装依赖
|
|
|
|
|
+
|
|
|
|
|
+使用 npm:
|
|
|
|
|
+```bash
|
|
|
|
|
+npm install
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+或使用 yarn:
|
|
|
|
|
+```bash
|
|
|
|
|
+yarn install
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+或使用国内镜像加速:
|
|
|
|
|
+```bash
|
|
|
|
|
+npm install --registry=https://registry.npm.taobao.org
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 3. 配置环境变量
|
|
|
|
|
+
|
|
|
|
|
+在项目根目录创建环境变量文件(根据实际需要选择):
|
|
|
|
|
+
|
|
|
|
|
+**开发环境** (`.env.development`):
|
|
|
|
|
+```env
|
|
|
|
|
+# 开发服务器端口
|
|
|
|
|
+VITE_PORT=8080
|
|
|
|
|
+
|
|
|
|
|
+# API 基础路径
|
|
|
|
|
+VITE_API_URL=http://localhost:8000/api/
|
|
|
|
|
+
|
|
|
|
|
+# 公共路径(开发环境通常为 ./)
|
|
|
|
|
+VITE_PUBLIC_PATH=./
|
|
|
|
|
+
|
|
|
|
|
+# 构建输出目录
|
|
|
|
|
+VITE_DIST_PATH=dist
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**生产环境** (`.env.production`):
|
|
|
|
|
+```env
|
|
|
|
|
+# API 基础路径(生产环境)
|
|
|
|
|
+VITE_API_URL=https://your-api-domain.com/api/
|
|
|
|
|
+
|
|
|
|
|
+# 公共路径(根据部署路径配置,如:/ 或 /admin/)
|
|
|
|
|
+VITE_PUBLIC_PATH=/
|
|
|
|
|
+
|
|
|
|
|
+# 构建输出目录
|
|
|
|
|
+VITE_DIST_PATH=dist
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**本地生产环境** (`.env.local_prod`):
|
|
|
|
|
+```env
|
|
|
|
|
+# 本地生产环境配置
|
|
|
|
|
+VITE_API_URL=http://localhost:8000/api/
|
|
|
|
|
+VITE_PUBLIC_PATH=/
|
|
|
|
|
+VITE_DIST_PATH=dist
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 4. 启动开发服务器
|
|
|
|
|
+
|
|
|
|
|
+```bash
|
|
|
|
|
+npm run dev
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+或
|
|
|
|
|
+
|
|
|
|
|
+```bash
|
|
|
|
|
+yarn dev
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+开发服务器启动后,访问: `http://localhost:8080` (端口可在环境变量中配置)
|
|
|
|
|
+
|
|
|
|
|
+## 项目结构
|
|
|
|
|
+
|
|
|
|
|
+```
|
|
|
|
|
+zheda/
|
|
|
|
|
+├── public/ # 静态资源目录(不会被 Vite 处理,直接复制到 dist)
|
|
|
|
|
+│ ├── favicon.ico # 网站图标
|
|
|
|
|
+│ ├── favicon1.ico # 备用图标
|
|
|
|
|
+│ ├── favicon2.ico # 备用图标
|
|
|
|
|
+│ └── version-build # 版本构建文件(自动生成)
|
|
|
|
|
+├── src/ # 源代码目录
|
|
|
|
|
+│ ├── api/ # API 接口定义
|
|
|
|
|
+│ │ ├── login/ # 登录相关接口
|
|
|
|
|
+│ │ │ └── index.ts # 登录 API
|
|
|
|
|
+│ │ ├── menu/ # 菜单相关接口
|
|
|
|
|
+│ │ └── system/ # 系统相关接口
|
|
|
|
|
+│ │ ├── loginBackground.ts
|
|
|
|
|
+│ │ └── ...
|
|
|
|
|
+│ ├── assets/ # 静态资源(图片、样式等)
|
|
|
|
|
+│ │ ├── style/ # 全局样式文件
|
|
|
|
|
+│ │ ├── iconfont/ # 图标字体文件
|
|
|
|
|
+│ │ └── *.png|jpg|svg # 图片资源
|
|
|
|
|
+│ ├── components/ # 公共组件(可复用的 Vue 组件)
|
|
|
|
|
+│ ├── directive/ # 自定义指令(Vue 指令)
|
|
|
|
|
+│ ├── i18n/ # 国际化配置(多语言支持)
|
|
|
|
|
+│ ├── layout/ # 布局组件(页面布局结构)
|
|
|
|
|
+│ ├── plugin/ # 插件配置(第三方插件初始化)
|
|
|
|
|
+│ │ └── permission/ # 权限插件
|
|
|
|
|
+│ ├── router/ # 路由配置
|
|
|
|
|
+│ │ ├── index.ts # 路由入口(路由实例和守卫)
|
|
|
|
|
+│ │ ├── backEnd.ts # 后端控制路由逻辑
|
|
|
|
|
+│ │ ├── frontEnd.ts # 前端控制路由逻辑
|
|
|
|
|
+│ │ └── route.ts # 路由定义(静态路由)
|
|
|
|
|
+│ ├── stores/ # Pinia 状态管理
|
|
|
|
|
+│ │ ├── index.ts # Store 入口
|
|
|
|
|
+│ │ ├── userInfo.ts # 用户信息 Store
|
|
|
|
|
+│ │ ├── routesList.ts # 路由列表 Store
|
|
|
|
|
+│ │ ├── btnPermission.ts # 按钮权限 Store
|
|
|
|
|
+│ │ ├── columnPermission.ts # 列权限 Store
|
|
|
|
|
+│ │ ├── themeConfig.ts # 主题配置 Store
|
|
|
|
|
+│ │ └── ... # 其他 Store
|
|
|
|
|
+│ ├── theme/ # 主题样式(颜色、布局等)
|
|
|
|
|
+│ ├── types/ # TypeScript 类型定义
|
|
|
|
|
+│ │ └── global.d.ts # 全局类型声明
|
|
|
|
|
+│ ├── utils/ # 工具函数
|
|
|
|
|
+│ │ ├── baseUrl.ts # 基础URL处理(API地址管理)
|
|
|
|
|
+│ │ ├── service.ts # HTTP请求封装(Axios封装)
|
|
|
|
|
+│ │ ├── storage.ts # 本地存储封装(LocalStorage/SessionStorage)
|
|
|
|
|
+│ │ ├── authFunction.ts # 权限验证函数
|
|
|
|
|
+│ │ ├── message.ts # 消息提示封装
|
|
|
|
|
+│ │ ├── dictionary.ts # 字典数据管理
|
|
|
|
|
+│ │ ├── upgrade.ts # 版本升级检查
|
|
|
|
|
+│ │ └── ... # 其他工具函数
|
|
|
|
|
+│ ├── views/ # 页面组件(业务页面)
|
|
|
|
|
+│ │ └── system/ # 系统管理模块
|
|
|
|
|
+│ │ └── company/ # 公司管理
|
|
|
|
|
+│ │ ├── crud.tsx # CRUD 配置
|
|
|
|
|
+│ │ ├── api.ts # API 接口
|
|
|
|
|
+│ │ └── index.vue # 页面组件
|
|
|
|
|
+│ ├── App.vue # 根组件(应用入口组件)
|
|
|
|
|
+│ ├── main.ts # 入口文件(应用初始化)
|
|
|
|
|
+│ └── settings.ts # Fast-Crud 配置(CRUD框架配置)
|
|
|
|
|
+├── dist/ # 构建输出目录(生产环境,gitignore)
|
|
|
|
|
+├── node_modules/ # 依赖包目录(gitignore)
|
|
|
|
|
+├── index.html # HTML 模板
|
|
|
|
|
+├── package.json # 项目依赖配置
|
|
|
|
|
+├── package-lock.json # 依赖锁定文件
|
|
|
|
|
+├── yarn.lock # Yarn 依赖锁定文件(如果使用 Yarn)
|
|
|
|
|
+├── tsconfig.json # TypeScript 配置
|
|
|
|
|
+├── vite.config.ts # Vite 构建配置
|
|
|
|
|
+├── tailwind.config.js # Tailwind CSS 配置
|
|
|
|
|
+├── postcss.config.js # PostCSS 配置
|
|
|
|
|
+├── .env.development # 开发环境变量(需要创建)
|
|
|
|
|
+├── .env.production # 生产环境变量(需要创建)
|
|
|
|
|
+├── .env.local_prod # 本地生产环境变量(需要创建)
|
|
|
|
|
+├── .gitignore # Git 忽略文件配置
|
|
|
|
|
+├── README.md # 项目说明文档
|
|
|
|
|
+├── DEVELOPMENT.md # 开发文档(本文档)
|
|
|
|
|
+└── DEPLOYMENT.md # 部署文档
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 目录详细说明
|
|
|
|
|
+
|
|
|
|
|
+#### `/src/api/` - API 接口层
|
|
|
|
|
+- **作用**: 统一管理所有后端 API 接口
|
|
|
|
|
+- **规范**:
|
|
|
|
|
+ - 按业务模块划分目录
|
|
|
|
|
+ - 每个模块创建独立的 `api.ts` 文件
|
|
|
|
|
+ - 使用统一的 `request` 方法进行请求
|
|
|
|
|
+- **示例**: 参考 `src/views/system/company/api.ts`
|
|
|
|
|
+
|
|
|
|
|
+#### `/src/stores/` - 状态管理
|
|
|
|
|
+- **作用**: 使用 Pinia 进行全局状态管理
|
|
|
|
|
+- **主要 Store**:
|
|
|
|
|
+ - `userInfo.ts`: 用户信息(登录状态、用户数据)
|
|
|
|
|
+ - `routesList.ts`: 路由列表(动态路由)
|
|
|
|
|
+ - `btnPermission.ts`: 按钮权限列表
|
|
|
|
|
+ - `themeConfig.ts`: 主题配置(布局、颜色等)
|
|
|
|
|
+- **使用方式**:
|
|
|
|
|
+ ```typescript
|
|
|
|
|
+ import { useUserInfo } from '/@/stores/userInfo';
|
|
|
|
|
+ const { userInfos } = storeToRefs(useUserInfo());
|
|
|
|
|
+ ```
|
|
|
|
|
+
|
|
|
|
|
+#### `/src/utils/` - 工具函数
|
|
|
|
|
+- **核心工具**:
|
|
|
|
|
+ - `service.ts`: HTTP 请求封装,包含请求/响应拦截器
|
|
|
|
|
+ - `storage.ts`: 本地存储封装(LocalStorage/SessionStorage)
|
|
|
|
|
+ - `authFunction.ts`: 权限验证函数(auth、auths、authAll)
|
|
|
|
|
+ - `baseUrl.ts`: API 基础地址管理
|
|
|
|
|
+ - `message.ts`: 消息提示封装
|
|
|
|
|
+ - `dictionary.ts`: 字典数据管理
|
|
|
|
|
+
|
|
|
|
|
+#### `/src/router/` - 路由系统
|
|
|
|
|
+- **路由模式**: Hash 模式(`createWebHashHistory`)
|
|
|
|
|
+- **路由控制**: 支持前端控制和后端控制两种模式
|
|
|
|
|
+ - 前端控制: 路由定义在前端,通过角色权限过滤
|
|
|
|
|
+ - 后端控制: 路由由后端返回,动态注册
|
|
|
|
|
+- **路由守卫**:
|
|
|
|
|
+ - 登录验证
|
|
|
|
|
+ - 权限验证
|
|
|
|
|
+ - 版本检查
|
|
|
|
|
+ - 路由缓存(keep-alive)
|
|
|
|
|
+
|
|
|
|
|
+#### `/src/views/` - 页面组件
|
|
|
|
|
+- **组织方式**: 按业务模块划分
|
|
|
|
|
+- **命名规范**: 使用 kebab-case(短横线命名)
|
|
|
|
|
+- **CRUD 页面**: 使用 Fast-Crud 框架,参考 `system/company/crud.tsx`
|
|
|
|
|
+
|
|
|
|
|
+## 开发指南
|
|
|
|
|
+
|
|
|
|
|
+### 代码规范
|
|
|
|
|
+
|
|
|
|
|
+项目使用 ESLint 进行代码检查,建议在提交代码前运行:
|
|
|
|
|
+
|
|
|
|
|
+```bash
|
|
|
|
|
+npm run lint-fix
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 添加新页面
|
|
|
|
|
+
|
|
|
|
|
+1. 在 `src/views/` 目录下创建页面组件
|
|
|
|
|
+2. 在 `src/router/` 中添加路由配置
|
|
|
|
|
+3. 如需 CRUD 功能,参考 `src/views/system/company/crud.tsx` 的实现方式
|
|
|
|
|
+
|
|
|
|
|
+### API 接口调用
|
|
|
|
|
+
|
|
|
|
|
+#### 1. 创建 API 文件
|
|
|
|
|
+
|
|
|
|
|
+在 `src/api/` 或对应业务模块目录下创建 API 文件,例如 `src/views/system/company/api.ts`:
|
|
|
|
|
+
|
|
|
|
|
+```typescript
|
|
|
|
|
+import { request } from '/@/utils/service';
|
|
|
|
|
+import { UserPageQuery, AddReq, DelReq, EditReq, InfoReq } from '@fast-crud/fast-crud';
|
|
|
|
|
+
|
|
|
|
|
+// API 前缀(统一管理)
|
|
|
|
|
+export const apiPrefix = '/api/platform-admin/tenants/';
|
|
|
|
|
+
|
|
|
|
|
+// 获取列表(分页查询)
|
|
|
|
|
+export function GetList(query: UserPageQuery) {
|
|
|
|
|
+ return request({
|
|
|
|
|
+ url: apiPrefix,
|
|
|
|
|
+ method: 'get',
|
|
|
|
|
+ params: query,
|
|
|
|
|
+ });
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 获取详情
|
|
|
|
|
+export function GetObj(id: InfoReq) {
|
|
|
|
|
+ return request({
|
|
|
|
|
+ url: apiPrefix + id,
|
|
|
|
|
+ method: 'get',
|
|
|
|
|
+ });
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 新增
|
|
|
|
|
+export function AddObj(obj: AddReq) {
|
|
|
|
|
+ return request({
|
|
|
|
|
+ url: apiPrefix,
|
|
|
|
|
+ method: 'post',
|
|
|
|
|
+ data: obj,
|
|
|
|
|
+ });
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 更新
|
|
|
|
|
+export function UpdateObj(obj: EditReq) {
|
|
|
|
|
+ return request({
|
|
|
|
|
+ url: apiPrefix + obj.id + '/',
|
|
|
|
|
+ method: 'put',
|
|
|
|
|
+ data: obj,
|
|
|
|
|
+ });
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 删除
|
|
|
|
|
+export function DelObj(id: DelReq) {
|
|
|
|
|
+ return request({
|
|
|
|
|
+ url: apiPrefix + id + '/',
|
|
|
|
|
+ method: 'delete',
|
|
|
|
|
+ data: { id },
|
|
|
|
|
+ });
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 自定义接口示例
|
|
|
|
|
+export function updateTenantStatus(id: string, status: number) {
|
|
|
|
|
+ return request({
|
|
|
|
|
+ url: `${apiPrefix}${id}/activate/`,
|
|
|
|
|
+ method: 'post',
|
|
|
|
|
+ data: { status },
|
|
|
|
|
+ });
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+#### 2. 在组件中使用 API
|
|
|
|
|
+
|
|
|
|
|
+```typescript
|
|
|
|
|
+import { GetList, AddObj, UpdateObj, DelObj } from './api';
|
|
|
|
|
+
|
|
|
|
|
+// 在 setup 函数中使用
|
|
|
|
|
+const loadData = async () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await GetList({ page: 1, limit: 10 });
|
|
|
|
|
+ console.log(res.data);
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('加载数据失败', error);
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+#### 3. API 请求配置说明
|
|
|
|
|
+
|
|
|
|
|
+**请求拦截器** (`src/utils/service.ts`):
|
|
|
|
|
+- 自动添加 `Authorization` 头(从 SessionStorage 获取 token)
|
|
|
|
|
+- 统一设置 `baseURL`(从环境变量获取)
|
|
|
|
|
+- 参数序列化(处理布尔值、空值等)
|
|
|
|
|
+
|
|
|
|
|
+**响应拦截器**:
|
|
|
|
|
+- 统一处理错误码(400、401、403、500 等)
|
|
|
|
|
+- 401 自动跳转登录页
|
|
|
|
|
+- 统一错误提示
|
|
|
|
|
+
|
|
|
|
|
+**请求配置选项**:
|
|
|
|
|
+```typescript
|
|
|
|
|
+request({
|
|
|
|
|
+ url: '/api/xxx',
|
|
|
|
|
+ method: 'get' | 'post' | 'put' | 'delete',
|
|
|
|
|
+ params: {}, // GET 请求参数
|
|
|
|
|
+ data: {}, // POST/PUT 请求体
|
|
|
|
|
+ headers: {}, // 自定义请求头
|
|
|
|
|
+ timeout: 20000, // 超时时间(毫秒)
|
|
|
|
|
+ responseType: 'blob', // 响应类型(用于文件下载)
|
|
|
|
|
+ unpack: false, // 是否解包响应数据
|
|
|
|
|
+})
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+#### 4. 文件下载
|
|
|
|
|
+
|
|
|
|
|
+项目提供了文件下载工具函数:
|
|
|
|
|
+
|
|
|
|
|
+```typescript
|
|
|
|
|
+import { downloadFile, downloadFilePost } from '/@/utils/service';
|
|
|
|
|
+
|
|
|
|
|
+// GET 方式下载
|
|
|
|
|
+downloadFile({
|
|
|
|
|
+ url: '/api/export/',
|
|
|
|
|
+ params: { id: 1 },
|
|
|
|
|
+ method: 'get',
|
|
|
|
|
+ filename: '导出文件'
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+// POST 方式下载
|
|
|
|
|
+downloadFilePost({
|
|
|
|
|
+ url: '/api/export/',
|
|
|
|
|
+ data: { ids: [1, 2, 3] },
|
|
|
|
|
+ method: 'post',
|
|
|
|
|
+ filename: '导出文件'
|
|
|
|
|
+});
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 使用 Fast-Crud
|
|
|
|
|
+
|
|
|
|
|
+项目集成了 Fast-Crud 框架,可以快速生成 CRUD 页面。参考 `src/views/system/company/crud.tsx` 的实现。
|
|
|
|
|
+
|
|
|
|
|
+#### 1. 基本结构
|
|
|
|
|
+
|
|
|
|
|
+```typescript
|
|
|
|
|
+import * as api from './api';
|
|
|
|
|
+import { UserPageQuery, AddReq, DelReq, EditReq, CreateCrudOptionsProps, CreateCrudOptionsRet } from '@fast-crud/fast-crud';
|
|
|
|
|
+
|
|
|
|
|
+export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
|
|
|
|
+ // 分页查询
|
|
|
|
|
+ const pageRequest = async (query: UserPageQuery) => {
|
|
|
|
|
+ return await api.GetList(query);
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // 编辑请求
|
|
|
|
|
+ const editRequest = async ({ form, row }: EditReq) => {
|
|
|
|
|
+ form.id = row.id;
|
|
|
|
|
+ return await api.UpdateObj(form);
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // 删除请求
|
|
|
|
|
+ const delRequest = async ({ row }: DelReq) => {
|
|
|
|
|
+ return await api.DelObj(row.id);
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // 新增请求
|
|
|
|
|
+ const addRequest = async ({ form }: AddReq) => {
|
|
|
|
|
+ return await api.AddObj(form);
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ return {
|
|
|
|
|
+ crudOptions: {
|
|
|
|
|
+ // CRUD 配置
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+};
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+#### 2. 主要配置项
|
|
|
|
|
+
|
|
|
|
|
+**请求配置**:
|
|
|
|
|
+```typescript
|
|
|
|
|
+request: {
|
|
|
|
|
+ pageRequest, // 分页查询
|
|
|
|
|
+ addRequest, // 新增
|
|
|
|
|
+ editRequest, // 编辑
|
|
|
|
|
+ delRequest, // 删除
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**工具栏配置**:
|
|
|
|
|
+```typescript
|
|
|
|
|
+toolbar: {
|
|
|
|
|
+ buttons: {
|
|
|
|
|
+ search: { show: true }, // 搜索按钮
|
|
|
|
|
+ refresh: { show: true }, // 刷新按钮
|
|
|
|
|
+ export: { show: true }, // 导出按钮
|
|
|
|
|
+ columns: { show: true }, // 列设置按钮
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**搜索配置**:
|
|
|
|
|
+```typescript
|
|
|
|
|
+search: {
|
|
|
|
|
+ col: { span: 3 }, // 每列占用的栅格数
|
|
|
|
|
+ show: true, // 显示搜索区域
|
|
|
|
|
+ autoSearch: true, // 自动搜索
|
|
|
|
|
+ buttons: {
|
|
|
|
|
+ search: { size: 'small' }, // 查询按钮大小
|
|
|
|
|
+ reset: { size: 'small' }, // 重置按钮大小
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**操作栏配置**:
|
|
|
|
|
+```typescript
|
|
|
|
|
+actionbar: {
|
|
|
|
|
+ buttons: {
|
|
|
|
|
+ add: {
|
|
|
|
|
+ size: 'small',
|
|
|
|
|
+ show: true, // 或使用权限: auth('company:Create')
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**行操作配置**:
|
|
|
|
|
+```typescript
|
|
|
|
|
+rowHandle: {
|
|
|
|
|
+ fixed: 'right', // 固定在右侧
|
|
|
|
|
+ width: 260, // 操作栏宽度
|
|
|
|
|
+ buttons: {
|
|
|
|
|
+ view: { // 查看按钮
|
|
|
|
|
+ size: 'small',
|
|
|
|
|
+ text: '查看',
|
|
|
|
|
+ show: true,
|
|
|
|
|
+ },
|
|
|
|
|
+ edit: { // 编辑按钮
|
|
|
|
|
+ size: 'small',
|
|
|
|
|
+ show: true,
|
|
|
|
|
+ },
|
|
|
|
|
+ remove: { // 删除按钮
|
|
|
|
|
+ show: false,
|
|
|
|
|
+ },
|
|
|
|
|
+ // 自定义按钮
|
|
|
|
|
+ customAction: {
|
|
|
|
|
+ size: 'small',
|
|
|
|
|
+ text: '自定义操作',
|
|
|
|
|
+ click: async ({ row }) => {
|
|
|
|
|
+ // 自定义操作逻辑
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**列配置**:
|
|
|
|
|
+```typescript
|
|
|
|
|
+columns: {
|
|
|
|
|
+ name: {
|
|
|
|
|
+ title: '名称',
|
|
|
|
|
+ type: 'input', // 字段类型
|
|
|
|
|
+ search: { show: true }, // 是否显示在搜索区域
|
|
|
|
|
+ form: { // 表单配置
|
|
|
|
|
+ rules: [{ required: true, message: '名称必填' }],
|
|
|
|
|
+ component: { placeholder: '请输入名称' },
|
|
|
|
|
+ },
|
|
|
|
|
+ column: { minWidth: 120 }, // 列配置
|
|
|
|
|
+ },
|
|
|
|
|
+ status: {
|
|
|
|
|
+ title: '状态',
|
|
|
|
|
+ type: 'dict-select', // 字典选择器
|
|
|
|
|
+ search: { show: true },
|
|
|
|
|
+ dict: dict({
|
|
|
|
|
+ data: [
|
|
|
|
|
+ { value: 1, label: '启用' },
|
|
|
|
|
+ { value: 0, label: '禁用' },
|
|
|
|
|
+ ]
|
|
|
|
|
+ }),
|
|
|
|
|
+ },
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+#### 3. 字段类型
|
|
|
|
|
+
|
|
|
|
|
+Fast-Crud 支持多种字段类型:
|
|
|
|
|
+- `input`: 文本输入框
|
|
|
|
|
+- `textarea`: 多行文本
|
|
|
|
|
+- `number`: 数字输入框
|
|
|
|
|
+- `password`: 密码输入框
|
|
|
|
|
+- `select`: 下拉选择
|
|
|
|
|
+- `dict-select`: 字典选择器
|
|
|
|
|
+- `date`: 日期选择器
|
|
|
|
|
+- `datetime`: 日期时间选择器
|
|
|
|
|
+- `switch`: 开关
|
|
|
|
|
+- `radio`: 单选框
|
|
|
|
|
+- `checkbox`: 复选框
|
|
|
|
|
+- `upload`: 文件上传
|
|
|
|
|
+- `editor`: 富文本编辑器
|
|
|
|
|
+
|
|
|
|
|
+#### 4. 完整示例
|
|
|
|
|
+
|
|
|
|
|
+参考 `src/views/system/company/crud.tsx` 查看完整的 CRUD 配置示例。
|
|
|
|
|
+
|
|
|
|
|
+### 状态管理
|
|
|
|
|
+
|
|
|
|
|
+使用 Pinia 进行状态管理,store 文件位于 `src/stores/` 目录。
|
|
|
|
|
+
|
|
|
|
|
+#### 1. Store 结构
|
|
|
|
|
+
|
|
|
|
|
+```typescript
|
|
|
|
|
+// src/stores/userInfo.ts 示例
|
|
|
|
|
+import { defineStore } from 'pinia';
|
|
|
|
|
+import { Session } from '/@/utils/storage';
|
|
|
|
|
+
|
|
|
|
|
+export const useUserInfo = defineStore('userInfo', {
|
|
|
|
|
+ state: (): UserInfosState => ({
|
|
|
|
|
+ userInfos: {
|
|
|
|
|
+ username: '',
|
|
|
|
|
+ avatar: '',
|
|
|
|
|
+ roles: [],
|
|
|
|
|
+ // ...其他用户信息
|
|
|
|
|
+ },
|
|
|
|
|
+ }),
|
|
|
|
|
+ actions: {
|
|
|
|
|
+ // 设置用户信息
|
|
|
|
|
+ setUserInfos(data: any) {
|
|
|
|
|
+ this.userInfos = data;
|
|
|
|
|
+ },
|
|
|
|
|
+ // 清除用户信息
|
|
|
|
|
+ clearUserInfos() {
|
|
|
|
|
+ this.userInfos = {
|
|
|
|
|
+ username: '',
|
|
|
|
|
+ avatar: '',
|
|
|
|
|
+ roles: [],
|
|
|
|
|
+ };
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ persist: {
|
|
|
|
|
+ key: 'userInfo',
|
|
|
|
|
+ storage: Session, // 使用 SessionStorage
|
|
|
|
|
+ },
|
|
|
|
|
+});
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+#### 2. 使用 Store
|
|
|
|
|
+
|
|
|
|
|
+```typescript
|
|
|
|
|
+import { useUserInfo } from '/@/stores/userInfo';
|
|
|
|
|
+import { storeToRefs } from 'pinia';
|
|
|
|
|
+
|
|
|
|
|
+// 在 setup 中使用
|
|
|
|
|
+const userInfoStore = useUserInfo();
|
|
|
|
|
+const { userInfos } = storeToRefs(userInfoStore);
|
|
|
|
|
+
|
|
|
|
|
+// 调用 actions
|
|
|
|
|
+userInfoStore.setUserInfos(newData);
|
|
|
|
|
+
|
|
|
|
|
+// 直接访问 state
|
|
|
|
|
+console.log(userInfoStore.userInfos);
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+#### 3. 主要 Store 说明
|
|
|
|
|
+
|
|
|
|
|
+**userInfo.ts** - 用户信息
|
|
|
|
|
+- 存储当前登录用户的信息
|
|
|
|
|
+- 包含用户名、头像、角色等
|
|
|
|
|
+
|
|
|
|
|
+**routesList.ts** - 路由列表
|
|
|
|
|
+- 存储动态路由列表
|
|
|
|
|
+- 用于路由权限控制
|
|
|
|
|
+
|
|
|
|
|
+**btnPermission.ts** - 按钮权限
|
|
|
|
|
+- 存储当前用户的按钮权限列表
|
|
|
|
|
+- 配合 `auth()` 函数使用
|
|
|
|
|
+
|
|
|
|
|
+**themeConfig.ts** - 主题配置
|
|
|
|
|
+- 存储主题相关配置(布局、颜色等)
|
|
|
|
|
+- 支持持久化存储
|
|
|
|
|
+
|
|
|
|
|
+#### 4. Store 持久化
|
|
|
|
|
+
|
|
|
|
|
+项目使用 `pinia-plugin-persist` 实现 Store 持久化:
|
|
|
|
|
+
|
|
|
|
|
+```typescript
|
|
|
|
|
+persist: {
|
|
|
|
|
+ key: 'storeKey', // 存储的 key
|
|
|
|
|
+ storage: Session, // 存储方式:Session 或 Local
|
|
|
|
|
+ paths: ['userInfos'], // 需要持久化的字段
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 样式开发
|
|
|
|
|
+
|
|
|
|
|
+- 支持 Tailwind CSS 工具类
|
|
|
|
|
+- 支持 SCSS 预处理器
|
|
|
|
|
+- 全局样式位于 `src/assets/style/` 和 `src/theme/`
|
|
|
|
|
+
|
|
|
|
|
+### 权限系统
|
|
|
|
|
+
|
|
|
|
|
+项目实现了完整的权限控制系统,包括路由权限、按钮权限和字段权限。
|
|
|
|
|
+
|
|
|
|
|
+#### 1. 按钮权限
|
|
|
|
|
+
|
|
|
|
|
+使用 `auth()` 函数进行按钮权限验证:
|
|
|
|
|
+
|
|
|
|
|
+```typescript
|
|
|
|
|
+import { auth } from '/@/utils/authFunction';
|
|
|
|
|
+
|
|
|
|
|
+// 单个权限验证
|
|
|
|
|
+if (auth('company:Create')) {
|
|
|
|
|
+ // 有权限,显示按钮
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 多个权限验证(满足一个即可)
|
|
|
|
|
+import { auths } from '/@/utils/authFunction';
|
|
|
|
|
+if (auths(['company:Create', 'company:Edit'])) {
|
|
|
|
|
+ // 有任一权限即可
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 多个权限验证(全部满足)
|
|
|
|
|
+import { authAll } from '/@/utils/authFunction';
|
|
|
|
|
+if (authAll(['company:Create', 'company:Edit'])) {
|
|
|
|
|
+ // 必须全部有权限
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+在模板中使用:
|
|
|
|
|
+```vue
|
|
|
|
|
+<template>
|
|
|
|
|
+ <el-button v-if="auth('company:Create')" @click="handleAdd">
|
|
|
|
|
+ 新增
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script setup>
|
|
|
|
|
+import { auth } from '/@/utils/authFunction';
|
|
|
|
|
+</script>
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+#### 2. 路由权限
|
|
|
|
|
+
|
|
|
|
|
+路由权限在路由守卫中自动处理(`src/router/index.ts`):
|
|
|
|
|
+- 未登录用户自动跳转到登录页
|
|
|
|
|
+- 根据用户角色动态加载路由
|
|
|
|
|
+- 支持前端控制和后端控制两种模式
|
|
|
|
|
+
|
|
|
|
|
+#### 3. 字段权限
|
|
|
|
|
+
|
|
|
|
|
+字段权限通过 `columnPermission` Store 管理,可以控制表格列的显示。
|
|
|
|
|
+
|
|
|
|
|
+### 国际化
|
|
|
|
|
+
|
|
|
|
|
+项目支持多语言,配置文件位于 `src/i18n/` 目录。
|
|
|
|
|
+
|
|
|
|
|
+#### 使用方式
|
|
|
|
|
+
|
|
|
|
|
+```typescript
|
|
|
|
|
+import { useI18n } from 'vue-i18n';
|
|
|
|
|
+
|
|
|
|
|
+const { t } = useI18n();
|
|
|
|
|
+const message = t('common.save'); // 获取翻译文本
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+#### 添加新语言
|
|
|
|
|
+
|
|
|
|
|
+1. 在 `src/i18n/` 目录下创建语言文件
|
|
|
|
|
+2. 在 `src/i18n/index.ts` 中注册新语言
|
|
|
|
|
+3. 使用 `useI18n().locale.value = 'en'` 切换语言
|
|
|
|
|
+
|
|
|
|
|
+## 常用命令
|
|
|
|
|
+
|
|
|
|
|
+```bash
|
|
|
|
|
+# 启动开发服务器
|
|
|
|
|
+npm run dev
|
|
|
|
|
+
|
|
|
|
|
+# 构建生产版本
|
|
|
|
|
+npm run build
|
|
|
|
|
+
|
|
|
|
|
+# 构建本地生产版本(使用 local_prod 环境变量)
|
|
|
|
|
+npm run build:local
|
|
|
|
|
+
|
|
|
|
|
+# 代码检查和自动修复
|
|
|
|
|
+npm run lint-fix
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+## 开发注意事项
|
|
|
|
|
+
|
|
|
|
|
+1. **路径别名**:
|
|
|
|
|
+ - `/@/` 指向 `src/` 目录
|
|
|
|
|
+ - `@views` 指向 `src/views` 目录
|
|
|
|
|
+
|
|
|
|
|
+2. **环境变量**:
|
|
|
|
|
+ - 所有环境变量必须以 `VITE_` 开头才能在代码中访问
|
|
|
|
|
+ - 使用 `import.meta.env.VITE_XXX` 访问环境变量
|
|
|
|
|
+
|
|
|
|
|
+3. **API 请求**:
|
|
|
|
|
+ - 所有 API 请求会自动添加认证 token(从 Cookie 中获取)
|
|
|
|
|
+ - 请求拦截器配置在 `src/utils/service.ts`
|
|
|
|
|
+
|
|
|
|
|
+4. **版本管理**:
|
|
|
|
|
+ - 构建时会自动生成版本文件到 `public/version-build`
|
|
|
|
|
+ - 生产环境会自动检查版本更新
|
|
|
|
|
+
|
|
|
|
|
+5. **浏览器兼容性**:
|
|
|
|
|
+ - 支持 Edge ≥ 79, Firefox ≥ 78, Chrome ≥ 64, Safari ≥ 12
|
|
|
|
|
+ - 不支持 IE11 及以下版本
|
|
|
|
|
+
|
|
|
|
|
+## 组件开发规范
|
|
|
|
|
+
|
|
|
|
|
+### 1. 组件命名
|
|
|
|
|
+
|
|
|
|
|
+- **文件命名**: 使用 PascalCase(大驼峰),如 `UserProfile.vue`
|
|
|
|
|
+- **组件注册**: 使用 kebab-case(短横线),如 `<user-profile />`
|
|
|
|
|
+- **目录命名**: 使用 kebab-case,如 `user-profile/`
|
|
|
|
|
+
|
|
|
|
|
+### 2. 组件结构
|
|
|
|
|
+
|
|
|
|
|
+```vue
|
|
|
|
|
+<template>
|
|
|
|
|
+ <!-- 模板内容 -->
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script setup lang="ts">
|
|
|
|
|
+// 1. 导入依赖
|
|
|
|
|
+import { ref, computed, onMounted } from 'vue';
|
|
|
|
|
+import { useRouter } from 'vue-router';
|
|
|
|
|
+
|
|
|
|
|
+// 2. 定义 Props
|
|
|
|
|
+interface Props {
|
|
|
|
|
+ title: string;
|
|
|
|
|
+ count?: number;
|
|
|
|
|
+}
|
|
|
|
|
+const props = withDefaults(defineProps<Props>(), {
|
|
|
|
|
+ count: 0,
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+// 3. 定义 Emits
|
|
|
|
|
+const emit = defineEmits<{
|
|
|
|
|
+ change: [value: number];
|
|
|
|
|
+ update: [value: string];
|
|
|
|
|
+}>();
|
|
|
|
|
+
|
|
|
|
|
+// 4. 响应式数据
|
|
|
|
|
+const loading = ref(false);
|
|
|
|
|
+const data = ref([]);
|
|
|
|
|
+
|
|
|
|
|
+// 5. 计算属性
|
|
|
|
|
+const total = computed(() => props.count * 2);
|
|
|
|
|
+
|
|
|
|
|
+// 6. 方法
|
|
|
|
|
+const handleClick = () => {
|
|
|
|
|
+ emit('change', 1);
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 7. 生命周期
|
|
|
|
|
+onMounted(() => {
|
|
|
|
|
+ // 初始化逻辑
|
|
|
|
|
+});
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style scoped lang="scss">
|
|
|
|
|
+/* 样式 */
|
|
|
|
|
+</style>
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 3. 代码规范
|
|
|
|
|
+
|
|
|
|
|
+- 使用 TypeScript 进行类型定义
|
|
|
|
|
+- 使用 Composition API(`<script setup>`)
|
|
|
|
|
+- 遵循 ESLint 规则
|
|
|
|
|
+- 组件内方法按功能分组
|
|
|
|
|
+- 添加必要的注释
|
|
|
|
|
+
|
|
|
|
|
+## Git 工作流程
|
|
|
|
|
+
|
|
|
|
|
+### 1. 分支管理
|
|
|
|
|
+
|
|
|
|
|
+- `main/master`: 主分支,生产环境代码
|
|
|
|
|
+- `develop`: 开发分支
|
|
|
|
|
+- `feature/xxx`: 功能分支
|
|
|
|
|
+- `bugfix/xxx`: 修复分支
|
|
|
|
|
+- `hotfix/xxx`: 紧急修复分支
|
|
|
|
|
+
|
|
|
|
|
+### 2. 提交规范
|
|
|
|
|
+
|
|
|
|
|
+使用约定式提交格式:
|
|
|
|
|
+
|
|
|
|
|
+```
|
|
|
|
|
+<type>(<scope>): <subject>
|
|
|
|
|
+
|
|
|
|
|
+<body>
|
|
|
|
|
+
|
|
|
|
|
+<footer>
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**type 类型**:
|
|
|
|
|
+- `feat`: 新功能
|
|
|
|
|
+- `fix`: 修复 bug
|
|
|
|
|
+- `docs`: 文档更新
|
|
|
|
|
+- `style`: 代码格式调整
|
|
|
|
|
+- `refactor`: 代码重构
|
|
|
|
|
+- `perf`: 性能优化
|
|
|
|
|
+- `test`: 测试相关
|
|
|
|
|
+- `chore`: 构建/工具相关
|
|
|
|
|
+
|
|
|
|
|
+**示例**:
|
|
|
|
|
+```bash
|
|
|
|
|
+git commit -m "feat(company): 添加公司管理功能"
|
|
|
|
|
+git commit -m "fix(api): 修复接口请求超时问题"
|
|
|
|
|
+git commit -m "docs(readme): 更新开发文档"
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 3. 代码审查
|
|
|
|
|
+
|
|
|
|
|
+- 提交前运行 `npm run lint-fix` 检查代码
|
|
|
|
|
+- 创建 Pull Request 进行代码审查
|
|
|
|
|
+- 确保所有测试通过后再合并
|
|
|
|
|
+
|
|
|
|
|
+## 调试技巧
|
|
|
|
|
+
|
|
|
|
|
+### 1. Vue DevTools
|
|
|
|
|
+
|
|
|
|
|
+安装 Vue DevTools 浏览器扩展:
|
|
|
|
|
+- Chrome: [Vue.js devtools](https://chrome.google.com/webstore/detail/vuejs-devtools)
|
|
|
|
|
+- Firefox: [Vue.js devtools](https://addons.mozilla.org/firefox/addon/vue-js-devtools/)
|
|
|
|
|
+
|
|
|
|
|
+功能:
|
|
|
|
|
+- 查看组件树
|
|
|
|
|
+- 检查组件 props、data、computed
|
|
|
|
|
+- 查看 Pinia Store 状态
|
|
|
|
|
+- 时间旅行调试
|
|
|
|
|
+
|
|
|
|
|
+### 2. 浏览器开发者工具
|
|
|
|
|
+
|
|
|
|
|
+**Network 面板**:
|
|
|
|
|
+- 查看 API 请求和响应
|
|
|
|
|
+- 检查请求头、响应头
|
|
|
|
|
+- 分析请求性能
|
|
|
|
|
+
|
|
|
|
|
+**Console 面板**:
|
|
|
|
|
+- 查看日志输出
|
|
|
|
|
+- 调试 JavaScript 代码
|
|
|
|
|
+- 查看错误堆栈
|
|
|
|
|
+
|
|
|
|
|
+**Vue 面板** (需要 Vue DevTools):
|
|
|
|
|
+- 查看组件实例
|
|
|
|
|
+- 检查响应式数据
|
|
|
|
|
+- 修改组件状态
|
|
|
|
|
+
|
|
|
|
|
+### 3. 断点调试
|
|
|
|
|
+
|
|
|
|
|
+在代码中使用 `debugger` 语句:
|
|
|
|
|
+
|
|
|
|
|
+```typescript
|
|
|
|
|
+const handleClick = () => {
|
|
|
|
|
+ debugger; // 浏览器会在此处暂停
|
|
|
|
|
+ // 后续代码
|
|
|
|
|
+};
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 4. 日志调试
|
|
|
|
|
+
|
|
|
|
|
+使用 `console` 方法进行调试:
|
|
|
|
|
+
|
|
|
|
|
+```typescript
|
|
|
|
|
+console.log('普通日志', data);
|
|
|
|
|
+console.warn('警告信息', warning);
|
|
|
|
|
+console.error('错误信息', error);
|
|
|
|
|
+console.table(arrayData); // 表格形式显示数组
|
|
|
|
|
+console.group('分组'); // 分组日志
|
|
|
|
|
+console.groupEnd();
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 5. 性能分析
|
|
|
|
|
+
|
|
|
|
|
+使用浏览器 Performance 面板:
|
|
|
|
|
+- 录制页面性能
|
|
|
|
|
+- 分析渲染性能
|
|
|
|
|
+- 查找性能瓶颈
|
|
|
|
|
+
|
|
|
|
|
+### 6. 网络调试
|
|
|
|
|
+
|
|
|
|
|
+**代理配置** (`vite.config.ts`):
|
|
|
|
|
+```typescript
|
|
|
|
|
+proxy: {
|
|
|
|
|
+ '/api': {
|
|
|
|
|
+ target: 'http://localhost:8000',
|
|
|
|
|
+ changeOrigin: true,
|
|
|
|
|
+ rewrite: (path) => path.replace(/^\/api/, ''),
|
|
|
|
|
+ },
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Mock 数据**: 可以使用 Mock.js 或 MSW 进行接口模拟
|
|
|
|
|
+
|
|
|
|
|
+## 常见问题
|
|
|
|
|
+
|
|
|
|
|
+### 1. 依赖安装失败
|
|
|
|
|
+
|
|
|
|
|
+**问题**: npm install 失败或速度慢
|
|
|
|
|
+
|
|
|
|
|
+**解决方案**:
|
|
|
|
|
+- 使用国内镜像: `npm install --registry=https://registry.npm.taobao.org`
|
|
|
|
|
+- 清除缓存: `npm cache clean --force`
|
|
|
|
|
+- 删除 `node_modules` 和 `package-lock.json` 后重新安装
|
|
|
|
|
+
|
|
|
|
|
+### 2. 端口被占用
|
|
|
|
|
+
|
|
|
|
|
+**问题**: 启动开发服务器时提示端口被占用
|
|
|
|
|
+
|
|
|
|
|
+**解决方案**:
|
|
|
|
|
+- 修改 `.env.development` 中的 `VITE_PORT` 配置
|
|
|
|
|
+- 或终止占用端口的进程
|
|
|
|
|
+
|
|
|
|
|
+### 3. API 请求跨域
|
|
|
|
|
+
|
|
|
|
|
+**问题**: 开发环境 API 请求出现跨域错误
|
|
|
|
|
+
|
|
|
|
|
+**解决方案**:
|
|
|
|
|
+- 检查后端 CORS 配置
|
|
|
|
|
+- 或在 `vite.config.ts` 中配置代理(已配置 `/gitee` 代理示例)
|
|
|
|
|
+
|
|
|
|
|
+### 4. TypeScript 类型错误
|
|
|
|
|
+
|
|
|
|
|
+**问题**: TypeScript 编译报错
|
|
|
|
|
+
|
|
|
|
|
+**解决方案**:
|
|
|
|
|
+- 检查 `tsconfig.json` 配置
|
|
|
|
|
+- 确保安装了所有类型定义包(@types/*)
|
|
|
|
|
+- 使用 `// @ts-ignore` 临时忽略(不推荐)
|
|
|
|
|
+- 添加类型定义文件(`.d.ts`)
|
|
|
|
|
+
|
|
|
|
|
+### 5. 路由跳转问题
|
|
|
|
|
+
|
|
|
|
|
+**问题**: 路由跳转后页面不更新或出现 404
|
|
|
|
|
+
|
|
|
|
|
+**解决方案**:
|
|
|
|
|
+- 检查路由配置是否正确
|
|
|
|
|
+- 确认路由模式(Hash 模式)
|
|
|
|
|
+- 检查路由守卫逻辑
|
|
|
|
|
+- 清除浏览器缓存
|
|
|
|
|
+
|
|
|
|
|
+### 6. 权限验证失败
|
|
|
|
|
+
|
|
|
|
|
+**问题**: 有权限但按钮不显示或接口返回 403
|
|
|
|
|
+
|
|
|
|
|
+**解决方案**:
|
|
|
|
|
+- 检查权限标识是否正确
|
|
|
|
|
+- 确认用户权限数据已加载
|
|
|
|
|
+- 检查 `auth()` 函数调用
|
|
|
|
|
+- 查看后端权限配置
|
|
|
|
|
+
|
|
|
|
|
+### 7. 样式不生效
|
|
|
|
|
+
|
|
|
|
|
+**问题**: 修改样式后页面没有变化
|
|
|
|
|
+
|
|
|
|
|
+**解决方案**:
|
|
|
|
|
+- 检查样式作用域(scoped)
|
|
|
|
|
+- 确认样式文件已正确导入
|
|
|
|
|
+- 检查 Tailwind CSS 类名是否正确
|
|
|
|
|
+- 清除浏览器缓存并重新构建
|
|
|
|
|
+
|
|
|
|
|
+### 8. 环境变量不生效
|
|
|
|
|
+
|
|
|
|
|
+**问题**: 修改环境变量后不生效
|
|
|
|
|
+
|
|
|
|
|
+**解决方案**:
|
|
|
|
|
+- 确认环境变量以 `VITE_` 开头
|
|
|
|
|
+- 重启开发服务器
|
|
|
|
|
+- 检查环境变量文件位置
|
|
|
|
|
+- 使用 `import.meta.env.VITE_XXX` 访问
|
|
|
|
|
+
|
|
|
|
|
+### 9. 构建失败
|
|
|
|
|
+
|
|
|
|
|
+**问题**: `npm run build` 失败
|
|
|
|
|
+
|
|
|
|
|
+**解决方案**:
|
|
|
|
|
+- 检查 Node.js 版本是否符合要求
|
|
|
|
|
+- 清除 `node_modules` 和 `dist` 目录
|
|
|
|
|
+- 删除 `package-lock.json` 重新安装
|
|
|
|
|
+- 检查代码语法错误
|
|
|
|
|
+- 查看构建日志中的具体错误信息
|
|
|
|
|
+
|
|
|
|
|
+### 10. 依赖版本冲突
|
|
|
|
|
+
|
|
|
|
|
+**问题**: 安装依赖时出现版本冲突警告
|
|
|
|
|
+
|
|
|
|
|
+**解决方案**:
|
|
|
|
|
+- 使用 `npm install --legacy-peer-deps` 安装
|
|
|
|
|
+- 更新冲突的依赖包到兼容版本
|
|
|
|
|
+- 使用 `npm audit fix` 修复安全漏洞
|
|
|
|
|
+
|
|
|
|
|
+## 参考资料
|
|
|
|
|
+
|
|
|
|
|
+- [Vue 3 官方文档](https://cn.vuejs.org/)
|
|
|
|
|
+- [Vite 官方文档](https://cn.vitejs.dev/)
|
|
|
|
|
+- [Element Plus 官方文档](https://element-plus.org/zh-CN/)
|
|
|
|
|
+- [Fast-Crud 文档](http://fast-crud.docmirror.cn/)
|
|
|
|
|
+- [Pinia 官方文档](https://pinia.vuejs.org/zh/)
|
|
|
|
|
+
|
|
|
|
|
+## 贡献指南
|
|
|
|
|
+
|
|
|
|
|
+1. Fork 项目
|
|
|
|
|
+2. 创建特性分支 (`git checkout -b feature/AmazingFeature`)
|
|
|
|
|
+3. 提交更改 (`git commit -m 'Add some AmazingFeature'`)
|
|
|
|
|
+4. 推送到分支 (`git push origin feature/AmazingFeature`)
|
|
|
|
|
+5. 开启 Pull Request
|
|
|
|
|
+
|
|
|
|
|
+## 许可证
|
|
|
|
|
+
|
|
|
|
|
+MIT License
|
|
|
|
|
+
|