# Lyzsys 前端开发文档 ## 目录 - [项目概述](#项目概述) - [技术栈](#技术栈) - [项目结构](#项目结构) - [开发指南](#开发指南) - [核心功能](#核心功能) - [组件库](#组件库) - [样式指南](#样式指南) - [部署指南](#部署指南) --- ## 项目概述 Lyzsys 前端是基于 Vue 3 + TypeScript + Element Plus 构建的现代化管理系统,采用 Composition API 和模块化架构,支持多租户、权限管理、国际化等功能。 ### 核心特性 - **Vue 3 Composition API**: 充分利用 Vue 3 的新特性 - **TypeScript**: 完整的类型支持 - **Vite 构建**: 极速的开发体验 - **Element Plus**: 企业级 UI 组件库 - **权限管理**: 基于 RBAC 的权限控制 - **国际化**: 支持多语言切换 - **主题定制**: 灵活的主题配置 --- ## 技术栈 ### 核心框架 | 技术 | 版本 | 说明 | |------|------|------| | Vue | 3.2+ | 渐进式 JavaScript 框架 | | TypeScript | 4.x | JavaScript 的超集 | | Vite | 4.x | 下一代前端构建工具 | | Vue Router | 4.x | Vue.js 官方路由管理器 | | Pinia | 2.x | Vue 官方状态管理库 | ### UI 框架 | 技术 | 版本 | 说明 | |------|------|------| | Element Plus | 2.x | 基于 Vue 3 的组件库 | | UnoCSS | - | 原子化 CSS 引擎 | | Animate.css | - | CSS 动画库 | | Iconify | - | 统一的图标框架 | ### 工具库 | 技术 | 版本 | 说明 | |------|------|------| | Axios | - | HTTP 客户端 | | Day.js | - | 轻量级日期处理库 | | Lodash | - | JavaScript 实用工具库 | | Crypto-js | - | JavaScript 加密库 | | DOMPurify | - | XSS 过滤器 | | WangEditor | - | 富文本编辑器 | | ECharts | - | 数据可视化库 | ### 开发工具 | 技术 | 版本 | 说明 | |------|------|------| | ESLint | - | 代码检查工具 | | Prettier | - | 代码格式化工具 | | Stylelint | - | CSS 代码检查工具 | | Commitlint | - | Git 提交信息检查 | | unplugin-auto-import | - | 自动导入 API | | unplugin-vue-components | - | 自动导入组件 | --- ## 项目结构 ### 目录结构 ``` lyzsys-ui-admin/ ├── .github/ # GitHub Actions 配置 ├── .husky/ # Git Hooks 配置 ├── .vscode/ # VSCode 配置 ├── public/ # 静态资源 ├── src/ # 源代码 │ ├── api/ # API 接口管理 │ │ ├── ai/ # AI 相关接口 │ │ ├── bpm/ # 工作流接口 │ │ ├── crm/ # CRM 接口 │ │ ├── erp/ # ERP 接口 │ │ ├── system/ # 系统管理接口 │ │ └── login/ # 登录接口 │ ├── assets/ # 静态资源 │ │ ├── images/ # 图片 │ │ ├── styles/ # 样式文件 │ │ └── svg/ # SVG 图标 │ ├── components/ # 全局组件 │ ├── config/ # 全局配置 │ ├── directives/ # 自定义指令 │ ├── hooks/ # 组合式函数 │ ├── layout/ # 布局组件 │ ├── locales/ # 国际化文件 │ │ ├── en/ # 英文 │ │ └── zh-CN/ # 简体中文 │ ├── plugins/ # 插件配置 │ ├── router/ # 路由配置 │ ├── store/ # 状态管理 │ │ ├── modules/ # 模块化 Store │ │ └── index.ts # Store 入口 │ ├── styles/ # 全局样式 │ ├── types/ # TypeScript 类型定义 │ ├── utils/ # 工具函数 │ ├── views/ # 页面组件 │ ├── App.vue # 应用根组件 │ ├── main.ts # 应用入口 │ └── permission.ts # 路由权限控制 ├── types/ # 全局类型定义 ├── .env.base # 基础环境变量 ├── .env.dev # 开发环境变量 ├── .env.pro # 生产环境变量 ├── .env.test # 测试环境变量 ├── .eslintrc.js # ESLint 配置 ├── .gitignore # Git 忽略文件 ├── .prettierrc.js # Prettier 配置 ├── index.html # HTML 模板 ├── package.json # 项目依赖 ├── tsconfig.json # TypeScript 配置 └── vite.config.ts # Vite 配置 ``` ### 核心文件说明 #### main.ts 应用入口文件,负责初始化 Vue 应用: ```typescript import { createApp } from 'vue' import App from './App.vue' import router from './router' import { setupStore } from './store' import { setupRouter } from './router' import { setupElPlus, setupIcons } from './plugins' async function bootstrap() { const app = createApp(App) // 配置 Store setupStore(app) // 配置 Router await setupRouter(app) // 配置插件 setupElPlus(app) setupIcons(app) // 挂载应用 app.mount('#app') } bootstrap() ``` #### App.vue 应用根组件: ```vue ``` #### permission.ts 路由权限控制: ```typescript import router from './router' import { useUserStore } from './store/modules/user' import { usePermissionStore } from './store/modules/permission' router.beforeEach(async (to, from, next) => { const userStore = useUserStore() const permissionStore = usePermissionStore() // 检查是否登录 if (userStore.getToken) { // 已登录 if (to.path === '/login') { next({ path: '/' }) } else { // 检查是否已获取权限 if (permissionStore.getIsAddRouters) { next() } else { // 获取权限和路由 await permissionStore.generateRoutes() next({ ...to, replace: true }) } } } else { // 未登录 if (to.path === '/login') { next() } else { next(`/login?redirect=${to.path}`) } } }) ``` --- ## 开发指南 ### 环境准备 #### 必需软件 | 软件 | 版本要求 | 下载地址 | |------|----------|----------| | Node.js | 16+ | https://nodejs.org/ | | pnpm | 8+ | https://pnpm.io/ | | VSCode | 最新版 | https://code.visualstudio.com/ | #### 推荐插件 - Vue - Official - TypeScript Vue Plugin (Volar) - ESLint - Prettier - Code formatter - Stylelint - UnoCSS ### 快速开始 #### 1. 克隆项目 ```bash git clone https://github.com/your-org/lyzsys.git cd lyzsys/lyzsys-ui-admin ``` #### 2. 安装依赖 ```bash pnpm install ``` #### 3. 启动开发服务器 ```bash pnpm dev ``` #### 4. 访问应用 - 应用地址: http://localhost:5173 - 用户名: admin - 密码: admin123 ### 开发规范 #### 命名规范 **文件命名**: - 组件文件:大驼峰 `UserList.vue` - 工具文件:小驼峰 `formatDate.ts` - 样式文件:小驼峰 `userList.scss` **变量命名**: ```typescript // 常量:全大写 const MAX_SIZE = 100 // 变量:小驼峰 const userName = 'admin' // 接口:大驼峰 interface UserInfo { id: number name: string } // 类型:大驼峰 type UserRole = 'admin' | 'user' // 枚举:大驼峰 enum UserStatus { Active = 'active', Inactive = 'inactive' } ``` **组件命名**: ```vue ``` #### 注释规范 **函数注释**: ```typescript /** * 获取用户列表 * @param params 查询参数 * @returns 用户列表 */ async function getUserList(params: UserPageReqVO) { return await userApi.getUserPage(params) } ``` **组件注释**: ```vue ``` #### 代码风格 **使用 Composition API**: ```vue ``` **使用 TypeScript**: ```typescript interface User { id: number name: string email: string } type UserRole = 'admin' | 'user' | 'guest' const user: User = { id: 1, name: 'Admin', email: 'admin@example.com' } const role: UserRole = 'admin' ``` ### 组件开发 #### 创建组件 ```vue ``` #### 组件通信 **Props**: ```vue ``` **Emits**: ```vue ``` **Slots**: ```vue ``` ### API 开发 #### API 定义 ```typescript // api/system/user/index.ts import request from '@/utils/request' // 获取用户分页 export function getUserPage(params: UserPageReqVO) { return request.get({ url: '/system/user/page', params }) } // 获取用户详情 export function getUser(id: number) { return request.get({ url: `/system/user/get?id=${id}` }) } // 创建用户 export function createUser(data: UserCreateReqVO) { return request.post({ url: '/system/user/create', data }) } // 更新用户 export function updateUser(data: UserUpdateReqVO) { return request.put({ url: '/system/user/update', data }) } // 删除用户 export function deleteUser(id: number) { return request.delete({ url: `/system/user/delete?id=${id}` }) } ``` #### API 调用 ```vue ``` ### 路由开发 #### 路由配置 ```typescript // router/modules/system.ts import type { AppRouteModule } from '@/router/types' const system: AppRouteModule = { path: '/system', name: 'System', component: 'LAYOUT', redirect: '/system/user', meta: { title: '系统管理', icon: 'system', orderNo: 1000 }, children: [ { path: 'user', name: 'SystemUser', component: () => import('@/views/system/user/index.vue'), meta: { title: '用户管理', icon: 'user', noCache: true } }, { path: 'role', name: 'SystemRole', component: () => import('@/views/system/role/index.vue'), meta: { title: '角色管理', icon: 'role', noCache: true } } ] } export default system ``` #### 路由跳转 ```typescript import { useRouter } from 'vue-router' const router = useRouter() // 路径跳转 router.push('/system/user') // 命名路由跳转 router.push({ name: 'SystemUser' }) // 带参数跳转 router.push({ path: '/system/user', query: { id: 1 } }) // 替换当前路由 router.replace('/system/user') // 后退 router.back() // 前进 router.forward() ``` ### 状态管理 #### Store 定义 ```typescript // store/modules/user.ts import { defineStore } from 'pinia' import { getUserInfo, login } from '@/api/system/user' interface UserState { token: string userInfo: UserInfo | null } export const useUserStore = defineStore('user', { state: (): UserState => ({ token: '', userInfo: null }), getters: { getToken: (state) => state.token, getUserInfo: (state) => state.userInfo }, actions: { setToken(token: string) { this.token = token }, async login(params: LoginReqVO) { const { data } = await login(params) this.setToken(data.token) }, async getUserInfoAction() { const { data } = await getUserInfo() this.userInfo = data }, async logout() { this.token = '' this.userInfo = null } }, persist: { key: 'user-store', storage: localStorage } }) ``` #### Store 使用 ```vue ``` --- ## 核心功能 ### 权限管理 #### 权限指令 ```vue ``` #### 权限函数 ```typescript import { usePermission } from '@/hooks/web/usePermission' const { hasPermission, hasRole } = usePermission() // 检查权限 if (hasPermission(['system:user:create'])) { // 有权限 } // 检查角色 if (hasRole(['admin'])) { // 是管理员 } ``` ### 国际化 #### 使用翻译 ```vue ``` #### 添加翻译 ```typescript // locales/zh-CN/common.ts export default { title: 'Lyzsys 管理系统', welcome: '欢迎,{name}', logout: '退出登录' } ``` ```typescript // locales/en/common.ts export default { title: 'Lyzsys Admin', welcome: 'Welcome, {name}', logout: 'Logout' } ``` ### 主题定制 #### 修改主题色 ```typescript // styles/variables.scss $primary-color: #409eff; $success-color: #67c23a; $warning-color: #e6a23c; $danger-color: #f56c6c; $error-color: #f56c6c; ``` #### 动态切换主题 ```vue ``` ### 文件上传 #### 单文件上传 ```vue ``` #### 多文件上传 ```vue ``` ### 表单验证 #### 表单定义 ```vue ``` ### 表格操作 #### 基础表格 ```vue ``` #### 分页表格 ```vue ``` --- ## 组件库 ### Element Plus #### 按钮 ```vue 默认按钮 主要按钮 成功按钮 警告按钮 危险按钮 文字按钮 ``` #### 表单 ```vue ``` #### 选择器 ```vue ``` #### 日期选择器 ```vue ``` #### 对话框 ```vue 这是一段内容 ``` #### 消息提示 ```typescript import { ElMessage, ElMessageBox, ElNotification } from 'element-plus' // 消息提示 ElMessage.success('操作成功') ElMessage.warning('警告消息') ElMessage.error('错误消息') ElMessage.info('提示消息') // 确认框 ElMessageBox.confirm('确定要删除吗?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }) .then(() => { ElMessage.success('删除成功') }) .catch(() => { ElMessage.info('已取消删除') }) // 通知 ElNotification({ title: '通知', message: '这是一条通知消息', type: 'success' }) ``` ### 自定义组件 #### 图表组件 (ECharts) ```vue ``` #### 富文本编辑器 (WangEditor) ```vue ``` --- ## 样式指南 ### CSS 预处理器 使用 SCSS 作为 CSS 预处理器: ```scss // 使用变量 $primary-color: #409eff; $border-radius: 4px; // 使用嵌套 .button { background: $primary-color; border-radius: $border-radius; &:hover { background: darken($primary-color, 10%); } &.active { background: lighten($primary-color, 10%); } } ``` ### UnoCSS 使用原子化 CSS: ```vue ``` ### 响应式设计 ```scss // 使用媒体查询 .container { padding: 20px; @media (max-width: 768px) { padding: 10px; } @media (max-width: 480px) { padding: 5px; } } ``` ### 主题定制 ```scss // 自定义主题色 :root { --el-color-primary: #409eff; --el-color-success: #67c23a; --el-color-warning: #e6a23c; --el-color-danger: #f56c6c; } // 暗黑模式 .dark { --el-bg-color: #1a1a1a; --el-text-color-primary: #ffffff; } ``` --- ## 部署指南 ### 本地构建 ```bash # 开发环境构建 pnpm build:dev # 生产环境构建 pnpm build:prod # 测试环境构建 pnpm build:test ``` ### 环境变量配置 ```bash # .env.base VITE_BASE_URL=/api # .env.dev VITE_BASE_URL=http://localhost:48080 # .env.prod VITE_BASE_URL=https://api.example.com ``` ### Docker 部署 #### 1. 构建镜像 ```bash docker build -t lyzsys/lyzsys-ui-admin:latest . ``` #### 2. 运行容器 ```bash docker run -d \ --name lyzsys-ui-admin \ -p 80:80 \ lyzsys/lyzsys-ui-admin:latest ``` ### Nginx 配置 ```nginx server { listen 80; server_name example.com; root /usr/share/nginx/html; index index.html; location / { try_files $uri $uri/ /index.html; } location /api { proxy_pass http://backend:48080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } gzip on; gzip_types text/plain text/css application/json application/javascript; } ``` --- ## 附录 ### 常见问题 #### Q1: 如何添加新页面? 1. 在 `views/` 目录下创建页面组件 2. 在 `router/modules/` 中配置路由 3. 添加国际化翻译(如需要) 4. 在后台系统中配置菜单权限 #### Q2: 如何调用后端 API? 1. 在 `api/` 目录下创建 API 文件 2. 定义 API 接口函数 3. 在组件中导入并调用 4. 处理响应数据 #### Q3: 如何实现权限控制? 1. 使用 `v-hasPermi` 指令控制按钮显示 2. 使用 `v-hasRole` 指令控制角色访问 3. 在路由配置中设置权限 meta 4. 后端接口进行权限验证 #### Q4: 如何切换语言? 1. 在 `locales/` 目录下添加语言文件 2. 使用 `$t()` 函数进行翻译 3. 在语言切换器中调用 `setLocale()` 方法 ### 参考资源 - [Vue 3 官方文档](https://cn.vuejs.org/) - [TypeScript 官方文档](https://www.typescriptlang.org/zh/) - [Vite 官方文档](https://cn.vitejs.dev/) - [Element Plus 官方文档](https://element-plus.org/zh-CN/) - [Pinia 官方文档](https://pinia.vuejs.org/zh/) - [UnoCSS 官方文档](https://unocss.dev/) --- **文档版本**: v1.0.0 **最后更新**: 2025-01-19 **维护团队**: Lyzsys 开发团队