40 KiB
前端交互域 - 详细设计
文档类型: 详细设计文档 生成日期: 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 路由守卫
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自动代码分割:
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<string> |
JWT Token | localStorage |
| userInfo | ref<{username, realName} | null> |
用户基本信息 | localStorage |
| roles | ref<string[]> |
角色列表 | localStorage |
| 计算属性 | 类型 | 说明 |
|---|---|---|
| isAdmin | computed<boolean> |
是否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过期校验:
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 |
请求超时 |
请求拦截器:
- 从localStorage获取Token
- 注入
Authorization: Bearer {token}Header - 初始化重试计数器
__retryCount
响应拦截器:
- 业务错误处理: 检查
ApiResponse.code,非200/0/00000视为业务错误 - 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("服务暂时不可用") |
- 网络错误处理: ERR_NETWORK / ECONNABORTED / ERR_CANCELED
- 自动重试: 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 类型安全
统一响应类型:
interface ApiResponse<T> {
code: number
message: string
data: T
}
API函数类型约束: 所有API函数显式指定 ApiResponse<T> 泛型参数
export const getUsers = (params?) => {
return request.get<ApiResponse<any>>('/api/auth/users', { params })
}
2.5.4 分页封装
分页响应类型(多版本共存):
// 通用版本(project.ts定义)
interface PageResponse<T> {
content: T[]
totalElements: number
totalPages: number
size: number
number: number
first: boolean
last: boolean
empty: boolean
}
// 工单版本(work-order.ts定义)
interface PageResponse<T> {
content: T[]
page: number
size: number
totalElements: number
totalPages: number
first: boolean
last: boolean
}
分页请求参数:
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
数据流:
- 用户输入用户名和密码
- 调用
userStore.login({username, password}) - login内部调用
auth.ts -> loginApi() - 成功后存储Token/角色/用户信息到localStorage
- 路由跳转到
/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
核心交互:
- 下拉选择项目
- 切换后设置
X-Project-IDHeader - 刷新当前页面数据
数据流:
- 项目列表:
GET /api/mdm/projects/selector
4.1.3 SpaceDrawer(空间选择抽屉)
文件: views/space/spaceDrawer.vue
功能: 树形空间选择器,用于设备关联空间、账单关联房产等场景
核心交互:
- 点击触发打开Drawer
- 加载空间树
- 点击节点选中
- 确认后返回选中的SpaceNode
数据流:
- 空间树:
GET /api/mdm/space-nodes/project/{projectId}/tree
4.2 业务组件
4.2.1 PhotoManager(照片管理)
文件: views/equipment/components/PhotoManager.vue
功能: 设备照片上传、预览、删除
核心交互:
- 按类型分类(外观、铭牌、安装位置、环境)
- 上传照片(调用uploadFile模拟)
- 预览大图
- 删除照片
数据结构:
interface EquipmentPhoto {
type: string // 照片类型
url: string // 照片URL
remark?: string // 备注
}
4.2.2 DocumentManager(文档管理)
文件: views/equipment/components/DocumentManager.vue
功能: 设备电子文档上传、下载、删除
核心交互:
- 按类型分类(手册manual、证书certificate、合同contract、其他other)
- 上传文档
- 下载文档
- 删除文档
数据结构:
interface EquipmentDocument {
name: string
url: string
size?: number
type: 'manual' | 'certificate' | 'contract' | 'other'
remark?: string
}
五、类型定义
5.1 全局类型(types/index.ts)
// API统一响应
interface ApiResponse<T> {
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 用户相关类型
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)
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<T> {
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)
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内联)
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内联)
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内联)
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内联)
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内联)
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 守卫
// 路由定义
{
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 方法
<a-button v-if="userStore.hasRole('SYS_ADMIN')" @click="handleDelete">
删除
</a-button>
当前使用场景: 有限,大部分页面未做按钮级权限控制
建议增强:
| 操作 | 建议权限检查 |
|---|---|
| 创建/编辑/删除 | 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 |
前端配合:
- 请求拦截器自动注入
X-Project-IDHeader(从ProjectSelector获取) - 前端不做数据过滤,完全依赖后端返回
- 列表页面根据返回数据渲染,不额外过滤