# 前端交互域 - 详细设计 **文档类型**: 详细设计文档 **生成日期**: 2026-05-18 **数据来源**: ether-admin 代码库分析 + REVERSE-AUTH.md + 路由/状态管理/API层源码 --- ## 一、功能点清单 | 编号 | 模块 | 功能点 | 页面文件 | 实现状态 | |------|------|--------|---------|---------| | FE-001 | 认证 | 用户登录 | auth/Login.vue | 已实现 | | FE-002 | 布局 | 主框架布局 | Layout.vue | 已实现 | | FE-003 | 仪表盘 | 数据概览 | Dashboard.vue | 已实现 | | FE-004 | 系统管理 | 用户管理 | system/Users.vue | 已实现 | | FE-005 | 系统管理 | 用户详情 | system/UserDetail.vue | 已实现 | | FE-006 | 系统管理 | 角色管理 | system/Roles.vue | 已实现 | | FE-007 | 系统管理 | 权限管理 | system/Permissions.vue | 已实现 | | FE-008 | 系统管理 | 组织架构 | system/Depts.vue | 已实现 | | FE-009 | 系统管理 | 审计日志 | system/Audit.vue | 已实现 | | FE-010 | 系统管理 | 系统设置 | system/Settings.vue | 已实现 | | FE-011 | 项目管理 | 项目列表 | project/List.vue | 已实现 | | FE-012 | 项目管理 | 项目选择器 | project/components/ProjectSelector.vue | 已实现 | | FE-013 | 设备管理 | 设备列表 | equipment/EquipmentList.vue | 已实现 | | FE-014 | 设备管理 | 设备详情 | equipment/EquipmentDetail.vue | 已实现 | | FE-015 | 设备管理 | 设备健康预测 | equipment/EquipmentHealth.vue | 已实现 | | FE-016 | 设备管理 | 维保计划 | equipment/MaintenancePlan.vue | 已实现 | | FE-017 | 设备管理 | 维保工单 | equipment/MaintenanceTask.vue | 已实现 | | FE-018 | 设备管理 | 巡检管理 | equipment/Inspection.vue | 已实现 | | FE-019 | 点检管理 | 点检模板 | inspection/TemplateList.vue | 已实现 | | FE-020 | 维保管理 | 维保计划 | maintenance/PlanList.vue | 已实现 | | FE-021 | 维保管理 | 维保任务 | maintenance/TaskList.vue | 已实现 | | FE-022 | 能耗管理 | 计量点管理 | energy/MeterList.vue | 已实现 | | FE-023 | 能耗管理 | 能耗录入 | energy/ConsumptionRecord.vue | 已实现 | | FE-024 | 能耗管理 | 能耗统计 | energy/EnergyStatistics.vue | 已实现 | | FE-025 | 备件管理 | 备件列表 | sparepart/SparePartList.vue | 已实现 | | FE-026 | 备件管理 | 备件详情 | sparepart/SparePartDetail.vue | 已实现 | | FE-027 | 备件管理 | 入库/出库 | sparepart/StockOperation.vue | 已实现 | | FE-028 | 工单管理 | 工单列表 | ops/WorkOrder.vue | 已实现 | | FE-029 | 空间管理 | 空间抽屉 | space/SpaceDrawer.vue | 已实现 | | FE-030 | 设备组件 | 照片管理 | equipment/components/PhotoManager.vue | 已实现 | | FE-031 | 设备组件 | 文档管理 | equipment/components/DocumentManager.vue | 已实现 | --- ## 二、技术架构 ### 2.1 技术栈 | 技术 | 版本 | 用途 | |------|------|------| | Vue | 3.x | 前端框架(Composition API) | | TypeScript | 5.x | 类型安全 | | Ant Design Vue | 4.x | UI组件库 | | Pinia | 2.x | 状态管理 | | Vue Router | 4.x | 路由管理 | | Vite | 5.x | 构建工具 | | Axios | 1.x | HTTP客户端 | | ECharts | 5.x | 图表可视化 | ### 2.2 目录结构 ``` ether-admin/src/ ├── api/ # API调用层 │ ├── auth.ts # 认证API │ ├── user.ts # 用户管理API │ ├── role.ts # 角色管理API │ ├── permission.ts # 权限管理API │ ├── dept.ts # 部门管理API │ ├── audit.ts # 审计日志API │ ├── system.ts # 系统配置API │ ├── project.ts # 项目管理API │ ├── space.ts # 空间管理API │ ├── equipment.ts # 设备管理API │ ├── equipment-health.ts # 设备健康API │ ├── maintenance-plan.ts # 维保计划API │ ├── maintenance-task.ts # 维保工单API │ ├── inspection-template.ts # 点检模板API │ ├── inspection-record.ts # 巡检记录API │ ├── inspection-item.ts # 巡检项API │ ├── energy.ts # 能耗管理API │ ├── sparepart.ts # 备件管理API │ ├── work-order.ts # 工单管理API │ ├── maintenance.ts # 维保API(旧) │ └── userManagement.ts # 用户管理API(旧) ├── stores/ # Pinia状态管理 │ └── user.ts # 用户状态Store ├── types/ # TypeScript类型定义 │ ├── index.ts # 全局类型 │ ├── project.ts # 项目相关类型 │ ├── space.ts # 空间相关类型 │ └── projectMember.ts # 项目成员类型 ├── utils/ # 工具函数 │ └── request.ts # Axios封装 ├── router/ # 路由配置 │ └── index.ts # 路由表+守卫 └── views/ # 页面组件 ├── auth/ # 认证页面 ├── system/ # 系统管理页面 ├── project/ # 项目管理页面 ├── equipment/ # 设备管理页面 ├── inspection/ # 点检管理页面 ├── maintenance/ # 维保管理页面 ├── energy/ # 能耗管理页面 ├── sparepart/ # 备件管理页面 ├── ops/ # 运营管理页面 └── space/ # 空间管理页面 ``` ### 2.3 路由设计 #### 2.3.1 路由表 | 路径 | 路由名 | 组件 | 标题 | 权限要求 | |------|--------|------|------|---------| | `/login` | Login | auth/Login.vue | 登录 | 无 | | `/dashboard` | Dashboard | Dashboard.vue | 仪表盘 | 已登录 | | `/system/users` | Users | system/Users.vue | 用户管理 | SYS_ADMIN | | `/system/roles` | Roles | system/Roles.vue | 角色管理 | SYS_ADMIN | | `/system/permissions` | Permissions | system/Permissions.vue | 权限管理 | SYS_ADMIN | | `/system/depts` | Depts | system/Depts.vue | 组织架构 | SYS_ADMIN | | `/system/audit` | Audit | system/Audit.vue | 审计日志 | SYS_ADMIN | | `/system/settings` | Settings | system/Settings.vue | 系统设置 | SYS_ADMIN | | `/project/list` | ProjectList | project/List.vue | 项目管理 | 已登录 | | `/equipment/list` | EquipmentList | equipment/EquipmentList.vue | 设备管理 | 已登录 | | `/equipment/detail/:id` | EquipmentDetail | equipment/EquipmentDetail.vue | 设备详情 | 已登录 | | `/equipment/health` | EquipmentHealth | equipment/EquipmentHealth.vue | 设备健康预测 | 已登录 | | `/equipment/maintenance-plan` | MaintenancePlan | equipment/MaintenancePlan.vue | 维保计划 | 已登录 | | `/equipment/maintenance-task` | MaintenanceTask | equipment/MaintenanceTask.vue | 维保工单 | 已登录 | | `/equipment/inspection` | Inspection | equipment/Inspection.vue | 巡检管理 | 已登录 | | `/inspection/templates` | InspectionTemplates | inspection/TemplateList.vue | 点检模板 | 已登录 | | `/maintenance/plans` | MaintenancePlans | maintenance/PlanList.vue | 维保计划 | 已登录 | | `/maintenance/tasks` | MaintenanceTasks | maintenance/TaskList.vue | 维保任务 | 已登录 | | `/energy/meters` | EnergyMeters | energy/MeterList.vue | 计量点管理 | 已登录 | | `/energy/consumption` | EnergyConsumption | energy/ConsumptionRecord.vue | 能耗录入 | 已登录 | | `/energy/statistics` | EnergyStatistics | energy/EnergyStatistics.vue | 能耗统计 | 已登录 | | `/sparepart/list` | SparePartList | sparepart/SparePartList.vue | 备件管理 | 已登录 | | `/sparepart/detail/:id` | SparePartDetail | sparepart/SparePartDetail.vue | 备件详情 | 已登录 | | `/sparepart/stock/in` | SparePartInStock | sparepart/StockOperation.vue | 备件入库 | 已登录 | | `/sparepart/stock/out` | SparePartOutStock | sparepart/StockOperation.vue | 备件出库 | 已登录 | #### 2.3.2 路由守卫 ```typescript router.beforeEach((to, _from, next) => { const userStore = useUserStore() // 1. 白名单路由直接放行(/login) if (to.path === '/login') return next() // 2. 未登录跳转登录页 if (!userStore.isLoggedIn()) return next('/login') // 3. 检查角色权限(meta.requiredRoles) const requiredRoles = to.meta?.requiredRoles as string[] | undefined if (requiredRoles?.length && !userStore.hasAnyRole(requiredRoles)) { return next({ path: '/', query: { from: to.fullPath } }) } next() }) ``` #### 2.3.3 懒加载策略 所有路由组件均使用动态导入(`() => import()`),Vite自动代码分割: ```typescript component: () => import('@/views/system/Users.vue') ``` #### 2.3.4 权限控制 - **路由级权限**: 通过 `meta.requiredRoles` 声明所需角色,守卫中校验 - **系统管理模块**: 统一要求 `SYS_ADMIN` 角色 - **业务模块**: 仅要求已登录(无特定角色限制) - **无权限处理**: 重定向到首页,通过 query.from 记录来源路径 --- ### 2.4 状态管理 #### 2.4.1 Pinia Store设计 **useUserStore**(当前唯一Store) | 状态 | 类型 | 说明 | 持久化 | |------|------|------|--------| | token | `ref` | JWT Token | localStorage | | userInfo | `ref<{username, realName} \| null>` | 用户基本信息 | localStorage | | roles | `ref` | 角色列表 | localStorage | | 计算属性 | 类型 | 说明 | |---------|------|------| | isAdmin | `computed` | 是否SYS_ADMIN角色 | | 方法 | 参数 | 返回值 | 说明 | |------|------|--------|------| | hasRole | role: string | boolean | 判断是否拥有指定角色 | | hasAnyRole | checkRoles: string[] | boolean | 判断是否拥有任一角色 | | login | data: LoginRequest | Promise | 登录并存储Token/角色/用户信息 | | logout | -- | Promise | 登出并清除所有状态 | | isLoggedIn | -- | boolean | 检查登录状态(含Token过期校验) | | initFromStorage | -- | void | 从localStorage恢复状态 | #### 2.4.2 持久化策略 | 数据 | 存储位置 | Key | 格式 | |------|---------|-----|------| | Token | localStorage | `token` | 字符串 | | 用户信息 | localStorage | `userInfo` | JSON字符串 | | 角色列表 | localStorage | `roles` | JSON数组字符串 | **Token过期校验**: ```typescript isLoggedIn() { // 1. 检查Token存在性 // 2. 检查JWT三段式格式 // 3. 解析payload.exp检查过期 // 4. 过期则自动logout } ``` --- ### 2.5 API层设计 #### 2.5.1 请求封装(request.ts) **Axios实例配置**: | 配置项 | 值 | 说明 | |--------|-----|------| | baseURL | `VITE_API_BASE_URL` | 环境变量配置 | | timeout | `VITE_REQUEST_TIMEOUT \|\| 10000` | 请求超时 | **请求拦截器**: 1. 从localStorage获取Token 2. 注入 `Authorization: Bearer {token}` Header 3. 初始化重试计数器 `__retryCount` **响应拦截器**: 1. **业务错误处理**: 检查 `ApiResponse.code`,非200/0/00000视为业务错误 2. **HTTP错误分类处理**: | 状态码 | 处理方式 | |--------|---------| | 400 | message.error("请求参数错误") | | 401 | 清除Token,跳转/login | | 403 | message.error("没有权限执行此操作") | | 404 | message.error("请求的资源不存在") | | 422 | message.error("数据验证失败") | | 429 | message.error("操作太频繁") | | 500 | message.error("服务器内部错误") | | 502/503/504 | message.error("服务暂时不可用") | 3. **网络错误处理**: ERR_NETWORK / ECONNABORTED / ERR_CANCELED 4. **自动重试**: GET请求在5xx/网络错误/超时时自动重试,最多2次,间隔1秒 #### 2.5.2 错误处理策略 | 错误类型 | 处理方式 | 用户感知 | |---------|---------|---------| | 业务错误(ApiResponse.code != 0) | message.error(res.message) | 顶部错误提示 | | 401未授权 | 清除Token + 跳转登录 | 自动跳转登录页 | | 403无权限 | message.error | 顶部错误提示 | | 网络错误 | message.error | 顶部错误提示 | | 请求超时 | 自动重试1次 + message.error | 顶部错误提示 | | 请求取消 | 静默处理 | 无感知 | #### 2.5.3 类型安全 **统一响应类型**: ```typescript interface ApiResponse { code: number message: string data: T } ``` **API函数类型约束**: 所有API函数显式指定 `ApiResponse` 泛型参数 ```typescript export const getUsers = (params?) => { return request.get>('/api/auth/users', { params }) } ``` #### 2.5.4 分页封装 **分页响应类型**(多版本共存): ```typescript // 通用版本(project.ts定义) interface PageResponse { content: T[] totalElements: number totalPages: number size: number number: number first: boolean last: boolean empty: boolean } // 工单版本(work-order.ts定义) interface PageResponse { content: T[] page: number size: number totalElements: number totalPages: number first: boolean last: boolean } ``` **分页请求参数**: ```typescript params: { page?: number; size?: number; keyword?: string; status?: string } ``` --- ## 三、页面设计 ### 3.1 登录页 | 属性 | 值 | |------|-----| | 页面路径 | `/login` | | 路由名 | Login | | 组件 | `views/auth/Login.vue` | | 权限要求 | 无 | | 布局 | 独立页面(不使用Layout) | **功能描述**: 用户名+密码登录,调用 `POST /api/auth/login` **核心组件**: Ant Design Vue Form + Input + Button **数据流**: 1. 用户输入用户名和密码 2. 调用 `userStore.login({username, password})` 3. login内部调用 `auth.ts -> loginApi()` 4. 成功后存储Token/角色/用户信息到localStorage 5. 路由跳转到 `/dashboard` --- ### 3.2 仪表盘 | 属性 | 值 | |------|-----| | 页面路径 | `/dashboard` | | 路由名 | Dashboard | | 组件 | `views/Dashboard.vue` | | 权限要求 | 已登录 | **功能描述**: 系统数据概览,展示关键指标 **核心组件**: Ant Design Vue Card + Statistic + ECharts图表 **数据流**: 汇总各模块统计数据 --- ### 3.3 用户管理 | 属性 | 值 | |------|-----| | 页面路径 | `/system/users` | | 路由名 | Users | | 组件 | `views/system/Users.vue` | | 权限要求 | SYS_ADMIN | **功能描述**: 用户列表CRUD、角色分配、项目关联 **核心组件**: Table + Modal + Form + Select **数据流**: - 列表: `GET /api/auth/users` -> Table渲染 - 创建: Form提交 -> `POST /api/auth/users` - 编辑: Form提交 -> `PUT /api/auth/users/{id}` - 删除: 确认弹窗 -> `DELETE /api/auth/users/{id}` - 角色分配: 多选Modal -> `POST /api/auth/users/{id}/roles` - 项目查看: `GET /api/auth/users/{id}/projects` --- ### 3.4 用户详情 | 属性 | 值 | |------|-----| | 页面路径 | 从用户管理跳转 | | 路由名 | UserDetail | | 组件 | `views/system/UserDetail.vue` | | 权限要求 | SYS_ADMIN | **功能描述**: 用户详细信息查看、密码修改 **核心组件**: Descriptions + Form + Modal **数据流**: - 详情: `GET /api/auth/users/{id}` - 修改密码: `PUT /api/auth/users/{id}/password` --- ### 3.5 角色管理 | 属性 | 值 | |------|-----| | 页面路径 | `/system/roles` | | 路由名 | Roles | | 组件 | `views/system/Roles.vue` | | 权限要求 | SYS_ADMIN | **功能描述**: 角色CRUD、权限分配 **核心组件**: Table + Modal + Form + Tree(权限树) **数据流**: - 列表: `GET /api/auth/roles` - 创建: `POST /api/auth/roles` - 权限分配: `POST /api/auth/roles/{id}/permissions` - 角色用户: `GET /api/auth/roles/{id}/users` --- ### 3.6 权限管理 | 属性 | 值 | |------|-----| | 页面路径 | `/system/permissions` | | 路由名 | Permissions | | 组件 | `views/system/Permissions.vue` | | 权限要求 | SYS_ADMIN | **功能描述**: 权限CRUD、按类型筛选 **核心组件**: Table + Modal + Form + Select(类型筛选) **数据流**: - 列表: `GET /api/auth/permissions` - 创建: `POST /api/auth/permissions` - 按模块查询: `GET /api/auth/permissions/module/{module}` --- ### 3.7 组织架构 | 属性 | 值 | |------|-----| | 页面路径 | `/system/depts` | | 路由名 | Depts | | 组件 | `views/system/Depts.vue` | | 权限要求 | SYS_ADMIN | **功能描述**: 部门树展示、CRUD、成员查看 **核心组件**: Tree + Modal + Form + Table **数据流**: - 部门树: `GET /api/auth/depts/tree` - 创建: `POST /api/auth/depts` - 成员: `GET /api/auth/depts/{deptId}/members` - 按类型: `GET /api/auth/depts/by-type/{deptType}` --- ### 3.8 审计日志 | 属性 | 值 | |------|-----| | 页面路径 | `/system/audit` | | 路由名 | Audit | | 组件 | `views/system/Audit.vue` | | 权限要求 | SYS_ADMIN | **功能描述**: 操作日志查询、统计 **核心组件**: Table + DatePicker + Select(模块/操作类型) **数据流**: - 日志列表: `GET /api/audit-logs` (分页+筛选) - 模块列表: `GET /api/audit-logs/modules` - 操作类型: `GET /api/audit-logs/actions` - 统计: `GET /api/audit-logs/stats` --- ### 3.9 系统设置 | 属性 | 值 | |------|-----| | 页面路径 | `/system/settings` | | 路由名 | Settings | | 组件 | `views/system/Settings.vue` | | 权限要求 | SYS_ADMIN | **功能描述**: 系统配置键值对管理 **核心组件**: Form + Input + Button **数据流**: - 获取配置: `GET /api/config` - 更新配置: `PUT /api/config` --- ### 3.10 项目管理 | 属性 | 值 | |------|-----| | 页面路径 | `/project/list` | | 路由名 | ProjectList | | 组件 | `views/project/List.vue` | | 权限要求 | 已登录 | **功能描述**: 项目CRUD、状态管理、成员管理、配置管理 **核心组件**: Table + Modal + Form + Tabs **数据流**: - 列表: `GET /api/mdm/projects` (分页) - 创建: `POST /api/mdm/projects` - 状态变更: `PUT /api/mdm/projects/{id}/status` - 成员管理: `GET/POST/DELETE /api/auth/projects/{projectId}/members` - 编码生成: `GET /api/mdm/projects/generate-code` - 删除检查: `GET /api/mdm/projects/{id}/delete-check` - 配置: `GET/PUT /api/mdm/projects/{id}/config` - 选择器: `GET /api/mdm/projects/selector` --- ### 3.11 设备列表 | 属性 | 值 | |------|-----| | 页面路径 | `/equipment/list` | | 路由名 | EquipmentList | | 组件 | `views/equipment/EquipmentList.vue` | | 权限要求 | 已登录 | **功能描述**: 设备CRUD、按项目/类型/归属筛选、导入导出 **核心组件**: Table + Modal + Form + Upload + Select **数据流**: - 列表: `GET /api/asset/equipment/by-project/{projectId}` - 创建: `POST /api/asset/equipment` - 按类型: `GET /api/asset/equipment/by-type` - 按归属: `GET /api/asset/equipment/by-ownership` - 导入: `POST /api/asset/equipment/import` - 导出: `GET /api/asset/equipment/export` - 统计: `GET /api/asset/equipment/stats/by-type/{projectId}` --- ### 3.12 设备详情 | 属性 | 值 | |------|-----| | 页面路径 | `/equipment/detail/:id` | | 路由名 | EquipmentDetail | | 组件 | `views/equipment/EquipmentDetail.vue` | | 权限要求 | 已登录 | **功能描述**: 设备完整信息展示、扩展信息编辑、照片/文档管理 **核心组件**: Tabs + Descriptions + Form + PhotoManager + DocumentManager **数据流**: - 详情: `GET /api/asset/equipment/{id}` - 电梯扩展: `GET/PUT /api/asset/equipment/{id}/elevator` - 暖通扩展: `GET/PUT /api/asset/equipment/{id}/hvac` - 能源扩展: `GET/PUT /api/asset/equipment/{id}/energy` - 消防扩展: `GET/PUT /api/asset/equipment/{id}/fire` --- ### 3.13 设备健康预测 | 属性 | 值 | |------|-----| | 页面路径 | `/equipment/health` | | 路由名 | EquipmentHealth | | 组件 | `views/equipment/EquipmentHealth.vue` | | 权限要求 | 已登录 | **功能描述**: 设备健康度评分、故障历史、MTBF/MTTR分析 **核心组件**: Card + ECharts + Table **数据流**: - 健康度: `GET /api/asset/equipment-health/{equipmentId}` - 历史趋势: `GET /api/asset/equipment-health/{id}/history` - 计算: `POST /api/asset/equipment-health/calculate` - 故障历史: `GET /api/asset/equipment-health/failure-history/{id}` - MTBF: `GET /api/asset/equipment-health/mtbf/{id}` - MTTR: `GET /api/asset/equipment-health/mttr/{id}` --- ### 3.14 维保计划(设备模块) | 属性 | 值 | |------|-----| | 页面路径 | `/equipment/maintenance-plan` | | 路由名 | MaintenancePlan | | 组件 | `views/equipment/MaintenancePlan.vue` | | 权限要求 | 已登录 | **功能描述**: 维保计划CRUD **核心组件**: Table + Modal + Form **数据流**: - 列表: `GET /api/mdm/maintenance-plans?projectId=` - 创建: `POST /api/mdm/maintenance-plans` - 更新: `PUT /api/mdm/maintenance-plans/{id}` - 删除: `DELETE /api/mdm/maintenance-plans/{id}` --- ### 3.15 维保工单(设备模块) | 属性 | 值 | |------|-----| | 页面路径 | `/equipment/maintenance-task` | | 路由名 | MaintenanceTask | | 组件 | `views/equipment/MaintenanceTask.vue` | | 权限要求 | 已登录 | **功能描述**: 维保工单管理、状态流转 **核心组件**: Table + Modal + Form + Steps **数据流**: - 列表: `GET /api/ops/maintenance-tasks?projectId=` - 派单: `POST /api/ops/maintenance-tasks/{id}/assign` - 开始: `POST /api/ops/maintenance-tasks/{id}/start` - 完成: `POST /api/ops/maintenance-tasks/{id}/complete-details` - 验收: `POST /api/ops/maintenance-tasks/{id}/verify` - 取消: `POST /api/ops/maintenance-tasks/{id}/cancel` - 统计: `GET /api/ops/maintenance-tasks/stats` --- ### 3.16 巡检管理(设备模块) | 属性 | 值 | |------|-----| | 页面路径 | `/equipment/inspection` | | 路由名 | Inspection | | 组件 | `views/equipment/Inspection.vue` | | 权限要求 | 已登录 | **功能描述**: 巡检记录管理 **核心组件**: Table + Modal + Form **数据流**: - 记录列表: `GET /api/mdm/inspection-records?projectId=` - 创建: `POST /api/mdm/inspection-records` - 完成: `POST /api/mdm/inspection-records/{id}/complete` --- ### 3.17 点检模板 | 属性 | 值 | |------|-----| | 页面路径 | `/inspection/templates` | | 路由名 | InspectionTemplates | | 组件 | `views/inspection/TemplateList.vue` | | 权限要求 | 已登录 | **功能描述**: 点检模板CRUD、检查项管理 **核心组件**: Table + Modal + Form + DynamicFormItems **数据流**: - 列表: `GET /api/ops/inspection-templates?projectId=` - 创建: `POST /api/ops/inspection-templates` - 更新: `PUT /api/ops/inspection-templates/{id}` - 删除: `DELETE /api/ops/inspection-templates/{id}` --- ### 3.18 维保计划(维保模块) | 属性 | 值 | |------|-----| | 页面路径 | `/maintenance/plans` | | 路由名 | MaintenancePlans | | 组件 | `views/maintenance/PlanList.vue` | | 权限要求 | 已登录 | **功能描述**: 维保计划列表(与设备模块维保计划共享API) --- ### 3.19 维保任务(维保模块) | 属性 | 值 | |------|-----| | 页面路径 | `/maintenance/tasks` | | 路由名 | MaintenanceTasks | | 组件 | `views/maintenance/TaskList.vue` | | 权限要求 | 已登录 | **功能描述**: 维保任务列表(与设备模块维保工单共享API) --- ### 3.20 计量点管理 | 属性 | 值 | |------|-----| | 页面路径 | `/energy/meters` | | 路由名 | EnergyMeters | | 组件 | `views/energy/MeterList.vue` | | 权限要求 | 已登录 | **功能描述**: 能源计量点CRUD **核心组件**: Table + Modal + Form + Select **数据流**: - 列表: `GET /api/ops/energy/meters?projectId=` - 创建: `POST /api/ops/energy/meters` - 更新: `PUT /api/ops/energy/meters/{id}` - 删除: `DELETE /api/ops/energy/meters/{id}` --- ### 3.21 能耗录入 | 属性 | 值 | |------|-----| | 页面路径 | `/energy/consumption` | | 路由名 | EnergyConsumption | | 组件 | `views/energy/ConsumptionRecord.vue` | | 权限要求 | 已登录 | **功能描述**: 能耗数据录入与查看 **核心组件**: Table + Modal + Form + InputNumber **数据流**: - 录入: `POST /api/ops/energy/consumption` - 记录: `GET /api/ops/energy/consumption/{meterId}` --- ### 3.22 能耗统计 | 属性 | 值 | |------|-----| | 页面路径 | `/energy/statistics` | | 路由名 | EnergyStatistics | | 组件 | `views/energy/EnergyStatistics.vue` | | 权限要求 | 已登录 | **功能描述**: 按类型统计、单方能耗 **核心组件**: Card + ECharts + DatePicker **数据流**: - 按类型统计: `GET /api/ops/energy/statistics/by-type` - 单方能耗: `GET /api/ops/energy/statistics/unit-consumption` --- ### 3.23 备件列表 | 属性 | 值 | |------|-----| | 页面路径 | `/sparepart/list` | | 路由名 | SparePartList | | 组件 | `views/sparepart/SparePartList.vue` | | 权限要求 | 已登录 | **功能描述**: 备件CRUD、低库存预警 **核心组件**: Table + Modal + Form + Badge **数据流**: - 列表: `GET /api/ops/spare-parts?projectId=` - 创建: `POST /api/ops/spare-parts` - 低库存: `GET /api/ops/spare-parts/low-stock` --- ### 3.24 备件详情 | 属性 | 值 | |------|-----| | 页面路径 | `/sparepart/detail/:id` | | 路由名 | SparePartDetail | | 组件 | `views/sparepart/SparePartDetail.vue` | | 权限要求 | 已登录 | **功能描述**: 备件详情、库存记录 **核心组件**: Descriptions + Table **数据流**: - 详情: `GET /api/ops/spare-parts/{id}` - 记录: `GET /api/ops/spare-parts/{id}/records` --- ### 3.25 入库/出库 | 属性 | 值 | |------|-----| | 页面路径 | `/sparepart/stock/in` 或 `/sparepart/stock/out` | | 路由名 | SparePartInStock / SparePartOutStock | | 组件 | `views/sparepart/StockOperation.vue`(共用) | | 权限要求 | 已登录 | **功能描述**: 备件入库/出库操作 **核心组件**: Form + InputNumber + Select **数据流**: - 入库: `POST /api/ops/spare-parts/in-stock` - 出库: `POST /api/ops/spare-parts/out-stock` --- ### 3.26 工单管理 | 属性 | 值 | |------|-----| | 页面路径 | 通过路由未直接注册,从其他入口跳转 | | 路由名 | WorkOrder | | 组件 | `views/ops/WorkOrder.vue` | | 权限要求 | 已登录 | **功能描述**: 工单全生命周期管理 **核心组件**: Table + Modal + Form + Steps + Rate **数据流**: - 列表: `GET /api/wo/work-orders` (分页+多条件筛选) - 创建: `POST /api/wo/work-orders` - 派单: `POST /api/wo/work-orders/{id}/assign` - 开始: `POST /api/wo/work-orders/{id}/start` - 完成: `POST /api/wo/work-orders/{id}/complete` - 验收: `POST /api/wo/work-orders/{id}/verify` - 挂起: `POST /api/wo/work-orders/{id}/suspend` - 恢复: `POST /api/wo/work-orders/{id}/resume` - 退回: `POST /api/wo/work-orders/{id}/return` - 取消: `POST /api/wo/work-orders/{id}/cancel` - 统计: `GET /api/wo/work-orders/stats` - 工单项: `GET/POST /api/wo/work-orders/{id}/items` --- ### 3.27 空间抽屉 | 属性 | 值 | |------|-----| | 页面路径 | 作为组件被其他页面引用 | | 组件 | `views/space/SpaceDrawer.vue` | | 权限要求 | 已登录 | **功能描述**: 空间树选择抽屉 **核心组件**: Drawer + Tree **数据流**: - 空间树: `GET /api/mdm/space-nodes/project/{projectId}/tree` --- ## 四、组件设计 ### 4.1 公共组件 #### 4.1.1 Layout(主框架布局) **文件**: `views/Layout.vue` **功能**: 系统主布局框架,包含侧边栏菜单、顶部导航、内容区域 **核心结构**: - 左侧:侧边栏菜单(Ant Design Vue Layout.Sider + Menu) - 顶部:Header(项目选择器、用户信息、登出按钮) - 中间:Content(router-view渲染区域) **菜单分组**: | 菜单组 | 子菜单 | |--------|--------| | 仪表盘 | Dashboard | | 系统管理 | 用户管理、角色管理、权限管理、组织架构、审计日志、系统设置 | | 项目管理 | 项目列表 | | 设备管理 | 设备列表、设备健康预测、维保计划、维保工单、巡检管理 | | 点检管理 | 点检模板 | | 维保管理 | 维保计划、维保任务 | | 能耗管理 | 计量点管理、能耗录入、能耗统计 | | 备件管理 | 备件列表、备件入库、备件出库 | #### 4.1.2 ProjectSelector(项目选择器) **文件**: `views/project/components/ProjectSelector.vue` **功能**: 全局项目切换组件,切换后所有API请求自动携带新项目ID **核心交互**: 1. 下拉选择项目 2. 切换后设置 `X-Project-ID` Header 3. 刷新当前页面数据 **数据流**: - 项目列表: `GET /api/mdm/projects/selector` #### 4.1.3 SpaceDrawer(空间选择抽屉) **文件**: `views/space/spaceDrawer.vue` **功能**: 树形空间选择器,用于设备关联空间、账单关联房产等场景 **核心交互**: 1. 点击触发打开Drawer 2. 加载空间树 3. 点击节点选中 4. 确认后返回选中的SpaceNode **数据流**: - 空间树: `GET /api/mdm/space-nodes/project/{projectId}/tree` --- ### 4.2 业务组件 #### 4.2.1 PhotoManager(照片管理) **文件**: `views/equipment/components/PhotoManager.vue` **功能**: 设备照片上传、预览、删除 **核心交互**: 1. 按类型分类(外观、铭牌、安装位置、环境) 2. 上传照片(调用uploadFile模拟) 3. 预览大图 4. 删除照片 **数据结构**: ```typescript interface EquipmentPhoto { type: string // 照片类型 url: string // 照片URL remark?: string // 备注 } ``` #### 4.2.2 DocumentManager(文档管理) **文件**: `views/equipment/components/DocumentManager.vue` **功能**: 设备电子文档上传、下载、删除 **核心交互**: 1. 按类型分类(手册manual、证书certificate、合同contract、其他other) 2. 上传文档 3. 下载文档 4. 删除文档 **数据结构**: ```typescript interface EquipmentDocument { name: string url: string size?: number type: 'manual' | 'certificate' | 'contract' | 'other' remark?: string } ``` --- ## 五、类型定义 ### 5.1 全局类型(types/index.ts) ```typescript // API统一响应 interface ApiResponse { code: number message: string data: T } // 分页信息 interface PaginationInfo { current: number pageSize: number total?: number } // 登录请求 interface LoginRequest { username: string password: string } // 登录响应 interface LoginResponse { token: string userId: string username: string realName: string roles: string[] } // 用户 interface User { id: string username: string realName?: string phone?: string email?: string avatar?: string status: 'ACTIVE' | 'LOCKED' | 'DISABLED' lastLoginTime?: string lastLoginIp?: string roles?: Role[] employeeNo?: string position?: string staffType?: StaffType projectId?: string } // 角色 interface Role { id: string code: string name: string description?: string type?: string status: 'ACTIVE' | 'DISABLED' dataScope?: string permissions?: Permission[] } // 权限 interface Permission { id: string code: string name: string type: string path?: string component?: string icon?: string resource?: string method?: string description?: string sortOrder?: number visible?: boolean } // 项目 interface Project { id: string code: string name: string description?: string address?: string projectType?: 'RESIDENTIAL' | 'OFFICE' | 'INDUSTRIAL_PARK' province?: string city?: string district?: string status: 'ACTIVE' | 'DISABLED' | 'PENDING' | 'ARCHIVED' createdAt?: string updatedAt?: string } ``` ### 5.2 各模块类型 #### 5.2.1 用户相关类型 ```typescript type UserType = 'ENTERPRISE' | 'PROJECT_STAFF' | 'RESIDENT' | 'CUSTOMER' type EmployeeCategory = 'ENTERPRISE' | 'MANAGEMENT' type StaffType = 'SECURITY' | 'CLEANING' | 'GARDEN' | 'MAINTENANCE' | 'CUSTOMER_SERVICE' | 'GENERAL' type ResidentType = 'OWNER' | 'FAMILY' | 'TENANT' ``` #### 5.2.2 项目相关类型(types/project.ts) ```typescript type ProjectStatus = 'ACTIVE' | 'DISABLED' | 'PENDING' | 'ARCHIVED' type ProjectType = 'RESIDENTIAL' | 'OFFICE' | 'INDUSTRIAL_PARK' interface ProjectQuery { keyword?: string status?: ProjectStatus page?: number size?: number sort?: string } interface PageResponse { content: T[] totalElements: number totalPages: number size: number number: number first: boolean last: boolean empty: boolean } interface ProjectStatistics { memberCount: number buildingCount: number roomCount: number ownerCount: number tenantCount: number activeTaskCount: number completedTaskCount: number } interface ProjectMember { id: string projectId: string userId: string userName: string realName?: string phone?: string roleInProject: string joinedAt: string status: 'ACTIVE' | 'INACTIVE' } interface ProjectConfig { id: string projectId: string enableReservation: boolean enableVisitor: boolean enableComplaint: boolean enablePayment: boolean enableAnnouncement: boolean enableSurvey: boolean enableVote: boolean enableMaintenance: boolean enableAsset: boolean customConfig?: string updatedAt: string } interface ProjectDeleteCheckVO { canDelete: boolean reason?: string statistics: ProjectDeleteStatistics } ``` #### 5.2.3 空间相关类型(types/space.ts) ```typescript type SpaceNodeCategory = 'BUILDING' | 'PARKING' | 'FACILITY' | 'AREA' type SpaceNodeType = 'BUILDING' | 'UNIT' | 'FLOOR' | 'ROOM' | 'SHOP' | 'GARAGE' | 'PARKING_AREA' | 'PARKING_SPACE' | 'EQUIPMENT_ROOM' | 'PROPERTY_OFFICE' | 'SECURITY_ROOM' | 'PUBLIC_AREA' | 'GREEN_AREA' | 'ROAD' interface SpaceNode { id: string projectId: string code: string name: string fullName?: string nodeCategory: SpaceNodeCategory nodeType: SpaceNodeType parentId?: string treePath?: string level?: number buildingArea?: number usableArea?: number status?: string // ...更多字段 } interface SpaceNodeTree extends SpaceNode { children: SpaceNodeTree[] } ``` #### 5.2.4 设备相关类型(api/equipment.ts内联) ```typescript type SystemType = 'ELEVATOR' | 'HVAC' | 'FIRE_PROTECTION' | 'PLUMBING' | 'ELECTRICAL' | 'SECURITY' | 'LANDSCAPE' | 'ENERGY_METER' type EquipmentType = 'ELEVATOR' | 'HVAC' | 'FIRE_PROTECTION' | 'PLUMBING' | 'ELECTRICAL' | 'ENERGY_METER' | 'SECURITY' | 'LANDSCAPE' | 'KITCHEN' | 'OTHER' type OwnershipType = 'PROJECT' | 'COMPANY' | 'OWNER' | 'RENTAL' interface Equipment { id: string equipmentCode: string equipmentName: string projectId: string equipmentType?: EquipmentType systemType?: SystemType ownershipType?: OwnershipType status?: string operationStatus?: string // ...更多字段 photos?: EquipmentPhoto[] documents?: EquipmentDocument[] } ``` #### 5.2.5 工单相关类型(api/work-order.ts内联) ```typescript type WorkOrderSource = 'OWNER' | 'MAINTENANCE' | 'INSPECTION' | 'FAULT' | 'REGULATORY' | 'MANUAL' type WorkOrderType = 'REPAIR' | 'INSPECTION' | 'SECURITY' | 'CLEANING' | 'PROPERTY' | 'CONSULTATION' type WorkOrderPriority = 'LOW' | 'MEDIUM' | 'HIGH' | 'URGENT' type WorkOrderStatus = 'PENDING' | 'ASSIGNED' | 'IN_PROGRESS' | 'SUSPENDED' | 'RETURNED' | 'COMPLETED' | 'VERIFIED' | 'CANCELLED' interface WorkOrder { id?: string workNo?: string source: WorkOrderSource type: WorkOrderType title: string priority: WorkOrderPriority status: WorkOrderStatus projectId?: string equipmentId?: string assignedTo?: string // ...更多字段 } ``` #### 5.2.6 维保相关类型(api/maintenance-*.ts内联) ```typescript type PlanType = 'PREVENTIVE' | 'CORRECTIVE' type PlanStatus = 'ACTIVE' | 'INACTIVE' | 'SUSPENDED' type TaskType = 'PREVENTIVE' | 'CORRECTIVE' | 'EMERGENCY' type TaskPriority = 'LOW' | 'MEDIUM' | 'HIGH' | 'URGENT' type TaskStatus = 'PENDING' | 'ASSIGNED' | 'IN_PROGRESS' | 'COMPLETED' | 'VERIFIED' | 'CANCELLED' type TriggerType = 'PLAN' | 'INSPECTION' | 'FAULT' | 'MANUAL' ``` #### 5.2.7 能耗相关类型(api/energy.ts内联) ```typescript interface EnergyMeter { id?: string meterCode: string meterName: string energyType: string installationLocation?: string ratedCapacity?: number unitPrice?: number status?: string } interface EnergyConsumption { id?: string meterId: string consumptionDate: string previousReading: number currentReading: number consumption: number amount?: number recordMethod?: string } ``` #### 5.2.8 备件相关类型(api/sparepart.ts内联) ```typescript interface SparePart { id: string name: string code: string categoryId?: string projectId: string unit?: string currentStock?: number safeStock?: number lowStockWarning?: boolean } interface StockRecord { id: string sparePartId: string operationType: 'IN' | 'OUT' quantity: number beforeStock?: number afterStock?: number relatedOrderId?: string } ``` --- ## 六、交互规范 ### 6.1 表单验证规范 | 场景 | 验证规则 | 组件 | |------|---------|------| | 必填字段 | `required: true, message: '请输入xxx'` | a-form-item + rules | | 字符串长度 | `min: 2, max: 50, message: '长度2-50位'` | a-input | | 手机号 | `pattern: /^1[3-9]\d{9}$/, message: '请输入正确手机号'` | a-input | | 邮箱 | `type: 'email', message: '请输入正确邮箱'` | a-input | | 数字范围 | `type: 'number', min: 0, max: 99999` | a-input-number | | 唯一性 | 异步验证,调用后端接口 | 自定义validator | | 提交前验证 | `form.validate()` 全量校验 | a-form | ### 6.2 列表查询规范 | 规范项 | 实现方式 | |--------|---------| | 分页 | 后端分页,参数 `page`(从0开始)+ `size` | | 搜索 | 关键词搜索参数 `keyword`,模糊匹配用户名/姓名/编码 | | 筛选 | 下拉选择参数(status/type等),多条件组合 | | 排序 | 后端默认排序(通常按createdAt DESC) | | 刷新 | 切换页码/筛选条件后自动重新查询 | | 空状态 | Ant Design Vue Table `locale.emptyText` | ### 6.3 状态展示规范 **颜色映射表**: | 状态类型 | 映射规则 | Tag颜色 | |---------|---------|---------| | 用户状态 | ACTIVE=green, LOCKED=red, DISABLED=gray | a-tag color | | 项目状态 | ACTIVE=success, DISABLED=error, PENDING=warning, ARCHIVED=default | a-tag color | | 工单状态 | PENDING=default, ASSIGNED=blue, IN_PROGRESS=orange, COMPLETED=green, VERIFIED=cyan, CANCELLED=red | a-tag color | | 工单优先级 | LOW=green, MEDIUM=blue, HIGH=orange, URGENT=red | a-tag color | | 工单来源 | OWNER=purple, MAINTENANCE=blue, INSPECTION=cyan, FAULT=red | a-tag color | | 维保任务状态 | PENDING=default, ASSIGNED=blue, IN_PROGRESS=orange, COMPLETED=green, VERIFIED=cyan, CANCELLED=red | a-tag color | | 巡检状态 | NORMAL=green, WARNING=orange, ABNORMAL=red | a-tag color | | 设备状态 | NORMAL=green, WARNING=orange, ABNORMAL=red | a-tag color | ### 6.4 操作确认规范 | 操作类型 | 确认方式 | 说明 | |---------|---------|------| | 删除 | `Modal.confirm` + 红色警告 | "确定要删除xxx吗?此操作不可恢复" | | 状态变更 | `Modal.confirm` | "确定要将状态从xxx变更为yyy吗?" | | 批量操作 | `Modal.confirm` + 数量提示 | "确定要删除选中的N条记录吗?" | | 取消工单 | `Modal.confirm` + 原因输入 | 需填写取消原因 | | 表单提交 | 无确认 | 直接提交 | | 登出 | 无确认 | 直接登出 | --- ## 七、权限控制 ### 7.1 路由级权限(meta.requiredRoles) **实现方式**: Vue Router `beforeEach` 守卫 ```typescript // 路由定义 { path: 'system/users', meta: { title: '用户管理', requiredRoles: ['SYS_ADMIN'] } } // 守卫校验 const requiredRoles = to.meta?.requiredRoles as string[] | undefined if (requiredRoles?.length && !userStore.hasAnyRole(requiredRoles)) { return next({ path: '/', query: { from: to.fullPath } }) } ``` **当前权限配置**: | 路由 | requiredRoles | |------|--------------| | /system/* (6个页面) | `['SYS_ADMIN']` | | 其他业务页面 | 无(仅要求已登录) | ### 7.2 按钮级权限(v-if + hasRole) **实现方式**: Pinia Store `hasRole` / `hasAnyRole` 方法 ```html 删除 ``` **当前使用场景**: 有限,大部分页面未做按钮级权限控制 **建议增强**: | 操作 | 建议权限检查 | |------|------------| | 创建/编辑/删除 | `userStore.hasAnyRole(['SYS_ADMIN', 'PROJECT_ADMIN'])` | | 审批操作 | `userStore.hasRole('FINANCE_STAFF')` | | 系统配置 | `userStore.hasRole('SYS_ADMIN')` | ### 7.3 数据级权限(后端控制) **实现方式**: 后端 DataScopeService + X-Project-ID Header | 数据范围 | 编码 | 后端过滤逻辑 | |---------|------|------------| | 全部数据 | ALL | 不做数据过滤 | | 项目数据 | PROJECT | 过滤 project_id = X-Project-ID | | 部门数据 | DEPARTMENT | 过滤 project_id + dept_id | | 本人数据 | SELF | 过滤 assigned_to / created_by = 当前用户ID | **前端配合**: 1. 请求拦截器自动注入 `X-Project-ID` Header(从ProjectSelector获取) 2. 前端不做数据过滤,完全依赖后端返回 3. 列表页面根据返回数据渲染,不额外过滤