完成项目整体结构搭建,包含: 1. 前端Vue3+TS+Vite+Antd项目基础配置与核心依赖 2. 后端MidwayJS+TypeORM+JWT权限认证框架 3. 完整的用户、角色、权限、日志数据库表结构 4. 核心业务模块API与基础服务实现 5. 全局样式、路由、状态管理配置
22 KiB
22 KiB
智能物联网设备后台管理系统 - 技术架构文档
1. 架构设计
flowchart TB
subgraph Frontend [前端层 - Vue3]
A[Vue 3 + TypeScript]
B[Ant Design Vue]
C[Vuex/Pinia 状态管理]
D[Vue Router 路由]
E[Axios HTTP客户端]
end
subgraph Backend [后端层 - Midway.js]
F[Midway Controller]
G[Midway Service]
H[Middleware 中间件]
I[JWT 认证]
J[RBAC 权限控制]
end
subgraph Data [数据层]
K[(MySQL 数据库)]
L[Redis 缓存]
M[Sequelize ORM]
end
Frontend -->|HTTP/REST API| Backend
Backend -->|SQL/ORM| Data
K <--> L
2. 技术选型说明
前端技术栈
- 框架:Vue 3 (Composition API) + TypeScript 5.x
- UI组件库:Ant Design Vue 4.x
- 构建工具:Vite 5.x
- 状态管理:Pinia (Vue官方推荐)
- 路由:Vue Router 4.x
- HTTP客户端:Axios + 请求拦截器
- 图表库:ECharts 5.x (用于仪表盘)
- 代码规范:ESLint + Prettier
后端技术栈
- 框架:Midway.js 3.x (基于Koa的企业级Node.js框架)
- 语言:TypeScript
- ORM:Sequelize 6.x (MySQL)
- 认证:jsonwebtoken (JWT)
- 加密:bcryptjs (密码哈希)
- 验证:class-validator + class-transformer
- 日志:midway-logger
- 缓存:ioredis (Redis)
数据存储
- 主数据库:MySQL 8.0+
- 缓存数据库:Redis 6.x
- 文件存储:本地文件系统 / OSS(可选扩展)
开发工具
- 包管理器:Yarn (遵循项目规则)
- 版本控制:Git
- 代码规范:Husky + lint-staged (Git钩子)
3. 项目目录结构
smart-grid-iot-admin/
├── client/ # 前端项目
│ ├── public/
│ │ └── favicon.ico
│ ├── src/
│ │ ├── api/ # API接口定义
│ │ │ ├── user.ts # 用户相关接口
│ │ │ ├── role.ts # 角色权限接口
│ │ │ └── system.ts # 系统设置接口
│ │ ├── assets/ # 静态资源
│ │ │ ├── images/
│ │ │ └── styles/
│ │ │ └── variables.less # 全局样式变量
│ │ ├── components/ # 公共组件
│ │ │ └── common/
│ │ ├── layouts/ # 布局组件
│ │ │ └── AdminLayout.vue # 后台主布局
│ │ ├── router/ # 路由配置
│ │ │ └── index.ts
│ │ ├── stores/ # Pinia状态管理
│ │ │ ├── user.ts # 用户状态
│ │ │ └── permission.ts # 权限状态
│ │ ├── utils/ # 工具函数
│ │ │ ├── request.ts # Axios封装
│ │ │ └── auth.ts # Token管理
│ │ ├── views/ # 页面视图
│ │ │ ├── login/ # 登录页
│ │ │ ├── dashboard/ # 仪表盘
│ │ │ ├── system/ # 系统管理
│ │ │ │ ├── user/ # 用户管理
│ │ │ │ └── role/ # 角色权限
│ │ │ └── settings/ # 系统设置
│ │ ├── App.vue
│ │ └── main.ts
│ ├── .env.development
│ ├── .env.production
│ ├── index.html
│ ├── package.json
│ ├── tsconfig.json
│ └── vite.config.ts
│
├── server/ # 后端项目
│ ├── src/
│ │ ├── config/ # 配置文件
│ │ │ ├── config.default.ts # 默认配置
│ │ │ └── config.prod.ts # 生产环境配置
│ │ ├── controller/ # 控制器层
│ │ │ ├── home.controller.ts
│ │ │ ├── user.controller.ts
│ │ │ ├── role.controller.ts
│ │ │ └── system.controller.ts
│ │ ├── service/ # 服务层
│ │ │ ├── user.service.ts
│ │ │ ├── role.service.ts
│ │ │ ├── auth.service.ts
│ │ │ └── system.service.ts
│ │ ├── middleware/ # 中间件
│ │ │ ├── auth.middleware.ts # JWT认证中间件
│ │ │ └── rbac.middleware.ts # RBAC权限中间件
│ │ ├── entity/ # 数据模型
│ │ │ ├── user.entity.ts
│ │ │ ├── role.entity.ts
│ │ │ ├── permission.entity.ts
│ │ │ └── log.entity.ts
│ │ ├── dto/ # 数据传输对象
│ │ │ ├── user.dto.ts
│ │ │ └── role.dto.ts
│ │ ├── interface/ # 类型定义
│ │ │ └── index.ts
│ │ ├── util/ # 工具函数
│ │ │ ├── crypto.ts
│ │ │ └── token.ts
│ │ └── configuration.ts # Midway入口
│ ├── package.json
│ ├── tsconfig.json
│ └── midway.bootstrap.ts
│
├── .gitignore
├── README.md
└── package.json # 根package.json (workspace)
4. 路由定义
前端路由
| 路径 | 组件 | 权限要求 | 说明 |
|---|---|---|---|
| /login | views/login/index.vue | 无需认证 | 登录页 |
| / | layouts/AdminLayout.vue | 需认证 | 主布局 |
| /dashboard | views/dashboard/index.vue | 需认证 | 仪表盘 |
| /system/user | views/system/user/index.vue | user:list | 用户列表 |
| /system/user/:id | views/system/user/detail.vue | user:detail | 用户详情 |
| /system/role | views/system/role/index.vue | role:list | 角色列表 |
| /settings/basic | views/settings/basic.vue | system:settings | 基本设置 |
| /settings/security | views/settings/security.vue | system:security | 安全设置 |
| /log/operation | views/log/operation.vue | log:operation | 操作日志 |
后端API路由
| 方法 | 路径 | 控制器 | 说明 |
|---|---|---|---|
| POST | /api/auth/login | AuthController | 用户登录 |
| POST | /api/auth/logout | AuthController | 用户登出 |
| GET | /api/user/list | UserController | 获取用户列表 |
| POST | /api/user/create | UserController | 创建用户 |
| PUT | /api/user/update/:id | UserController | 更新用户 |
| DELETE | /api/user/delete/:id | UserController | 删除用户 |
| GET | /api/role/list | RoleController | 获取角色列表 |
| GET | /api/role/:id/permissions | RoleController | 获取角色权限 |
| PUT | /api/role/:id/permissions | RoleController | 更新角色权限 |
| GET | /api/settings | SystemController | 获取系统设置 |
| PUT | /api/settings | SystemController | 更新系统设置 |
| GET | /api/dashboard/stats | HomeController | 仪表盘统计数据 |
| GET | /api/log/list | LogController | 获取操作日志 |
5. API接口定义
5.1 认证相关接口
POST /api/auth/login - 用户登录
请求体:
interface LoginDTO {
username: string; // 用户名 (必填, 3-20字符)
password: string; // 密码 (必填, 6-20字符)
captcha?: string; // 验证码 (可选)
rememberMe?: boolean; // 记住我 (可选)
}
响应:
interface LoginResponse {
code: number; // 状态码 200
message: string; // 提示信息
data: {
accessToken: string; // JWT Token
refreshToken?: string;
userInfo: {
id: number;
username: string;
nickname: string;
avatar?: string;
roles: string[]; // 角色标识数组
permissions: string[]; // 权限标识数组
};
};
}
POST /api/auth/logout - 用户登出
响应:
interface LogoutResponse {
code: number;
message: string;
}
5.2 用户管理接口
GET /api/user/list - 获取用户列表
查询参数:
interface UserQuery {
page: number; // 页码 (默认1)
pageSize: number; // 每页条数 (默认10)
keyword?: string; // 搜索关键词(用户名/昵称/手机号)
status?: number; // 状态 (0-禁用 1-启用)
roleId?: number; // 角色ID筛选
}
响应:
interface UserListResponse {
code: number;
data: {
list: UserInfo[];
total: number;
page: number;
pageSize: number;
};
}
interface UserInfo {
id: number;
username: string;
nickname: string;
email?: string;
phone?: string;
avatar?: string;
status: number; // 0-禁用 1-启用
roles: RoleInfo[];
createdAt: Date;
updatedAt: Date;
}
POST /api/user/create - 创建用户
请求体:
interface CreateUserDTO {
username: string; // 必填, 3-20字符
password: string; // 必填, 6-20字符
nickname: string; // 必填, 2-20字符
email?: string;
phone?: string;
roleIds: number[]; // 角色ID数组
status?: number; // 默认1-启用
}
PUT /api/user/update/:id - 更新用户
请求体:
interface UpdateUserDTO {
nickname?: string;
email?: string;
phone?: string;
avatar?: string;
roleIds?: number[];
status?: number;
password?: string; // 可选,如需修改密码
}
DELETE /api/user/delete/:id - 删除用户
响应:
interface DeleteResponse {
code: number;
message: string;
}
5.3 角色权限接口
GET /api/role/list - 获取角色列表
响应:
interface RoleListResponse {
code: number;
data: RoleInfo[];
}
interface RoleInfo {
id: number;
name: string; // 角色名称
code: string; // 角色标识
description?: string;
permissions: PermissionTree[];
userCount: number; // 关联用户数
createdAt: Date;
}
GET /api/role/:id/permissions - 获取角色权限树
响应:
interface PermissionTreeResponse {
code: number;
data: PermissionTree[];
}
interface PermissionTree {
id: number;
name: string; // 权限名称
code: string; // 权限标识
type: 'menu' | 'button' | 'api';
parentId?: number;
children?: PermissionTree[];
checked?: boolean; // 是否已选中
}
PUT /api/role/:id/permissions - 更新角色权限
请求体:
interface UpdatePermissionDTO {
permissionIds: number[]; // 选中的权限ID数组
}
5.4 系统设置接口
GET /api/settings - 获取系统设置
响应:
interface SettingsResponse {
code: number;
data: SystemSettings;
}
interface SystemSettings {
basic: {
siteName: string; // 站点名称
logo?: string; // Logo URL
sessionTimeout: number; // 会话超时(分钟)
};
security: {
passwordMinLength: number; // 密码最小长度
maxLoginAttempts: number; // 最大登录尝试次数
lockoutDuration: number; // 锁定时长(分钟)
ipWhitelist: string[]; // IP白名单
};
notification: {
enableEmail: boolean;
emailSmtpConfig?: object;
};
}
PUT /api/settings - 更新系统设置
请求体: 同SystemSettings结构
5.5 仪表盘接口
GET /api/dashboard/stats - 统计数据
响应:
interface DashboardStatsResponse {
code: number;
data: {
deviceTotal: number;
deviceOnline: number;
alertToday: number;
activeUsers: number;
deviceTrend: TrendData[]; // 近7天设备趋势
deviceTypeDistribution: PieData[]; // 设备类型分布
recentAlerts: AlertItem[]; // 最近告警
recentActivities: ActivityItem[]; // 最近活动
};
}
5.6 操作日志接口
GET /api/log/list - 获取操作日志
查询参数:
interface LogQuery {
page: number;
pageSize: number;
operator?: string; // 操作人
actionType?: string; // 操作类型
startTime?: Date;
endTime?: Date;
}
响应:
interface LogListResponse {
code: number;
data: {
list: LogItem[];
total: number;
};
}
interface LogItem {
id: number;
userId: number;
username: string;
action: string; // 操作描述
module: string; // 操作模块
method: string; // 请求方法
url: string; // 请求URL
ipAddress: string;
userAgent?: string;
statusCode: number; // 响应状态码
duration: number; // 请求耗时(ms)
createdAt: Date;
}
6. 服务器架构图
flowchart LR
subgraph Client [客户端]
Request[HTTP请求]
end
subgraph Middleware [中间件层]
A[CORS跨域]
B[Body解析]
C[JWT认证]
D[RBAC权限]
E[参数校验]
F[日志记录]
end
subgraph Controller [控制器层]
G[AuthController]
H[UserController]
I[RoleController]
J[SystemController]
K[HomeController]
L[LogController]
end
subgraph Service [服务层业务逻辑]
M[AuthService]
N[UserService]
O[RoleService]
P[SystemService]
Q[DashboardService]
R[LogService]
end
subgraph Repository [数据访问层]
S[UserRepository]
T[RoleRepository]
U[PermissionRepository]
V[LogRepository]
end
subgraph Database [(数据库)]
W[(MySQL)]
X[(Redis)]
end
Request --> Middleware
A --> B --> C --> D --> E --> F
F --> G & H & I & J & K & L
G --> M
H --> N
I --> O
J --> P
K --> Q
L --> R
M & N & O & P & Q & R --> S & T & U & V
S & T & U & V --> W
M & N & O --> X
7. 数据模型设计
7.1 实体关系图 (ER Diagram)
erDiagram
USERS ||--o{ USER_ROLES : has
ROLES ||--o{ USER_ROLES : assigned_to
ROLES ||--o{ ROLE_PERMISSIONS : contains
PERMISSIONS ||--o{ ROLE_PERMISSIONS : belong_to
USERS ||--o{ OPERATION_LOGS : creates
USERS {
bigint id PK "主键"
varchar username UK "用户名(唯一)"
varchar password "加密密码"
varchar nickname "昵称"
varchar email "邮箱"
varchar phone "手机号"
varchar avatar "头像URL"
tinyint status "状态(0禁用/1启用)"
datetime created_at "创建时间"
datetime updated_at "更新时间"
}
ROLES {
bigint id PK "主键"
varchar name "角色名称"
varchar code UK "角色编码(唯一)"
varchar description "描述"
datetime created_at "创建时间"
datetime updated_at "更新时间"
}
PERMISSIONS {
bigint id PK "主键"
varchar name "权限名称"
varchar code UK "权限编码(唯一)"
varchar type "类型(menu/button/api)"
bigint parent_id FK "父权限ID"
int sort_order "排序"
varchar icon "图标"
varchar route "路由路径"
}
USER_ROLES {
bigint id PK "主键"
bigint user_id FK "用户ID"
bigint role_id FK "角色ID"
}
ROLE_PERMISSIONS {
bigint id PK "主键"
bigint role_id FK "角色ID"
bigint permission_id FK "权限ID"
}
OPERATION_LOGS {
bigint id PK "主键"
bigint user_id FK "操作用户ID"
varchar action "操作描述"
varchar module "操作模块"
varchar method "请求方法"
varchar url "请求URL"
varchar ip_address "IP地址"
varchar user_agent "浏览器UA"
int status_code "响应状态码"
int duration "请求耗时(ms)"
text request_params "请求参数"
text response_data "响应数据"
datetime created_at "操作时间"
}
7.2 数据定义语言 (DDL)
-- 用户表
CREATE TABLE `users` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`username` varchar(50) NOT NULL COMMENT '用户名',
`password` varchar(255) NOT NULL COMMENT '加密密码',
`nickname` varchar(50) DEFAULT NULL COMMENT '昵称',
`email` varchar(100) DEFAULT NULL COMMENT '邮箱',
`phone` varchar(20) DEFAULT NULL COMMENT '手机号',
`avatar` varchar(255) DEFAULT NULL COMMENT '头像URL',
`status` tinyint NOT NULL DEFAULT '1' COMMENT '状态: 0-禁用 1-启用',
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户表';
-- 角色表
CREATE TABLE `roles` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(50) NOT NULL COMMENT '角色名称',
`code` varchar(50) NOT NULL COMMENT '角色编码',
`description` varchar(255) DEFAULT NULL COMMENT '描述',
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_code` (`code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='角色表';
-- 权限表
CREATE TABLE `permissions` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(50) NOT NULL COMMENT '权限名称',
`code` varchar(100) NOT NULL COMMENT '权限编码',
`type` enum('menu','button','api') NOT NULL DEFAULT 'menu' COMMENT '权限类型',
`parent_id` bigint DEFAULT NULL COMMENT '父权限ID',
`sort_order` int NOT NULL DEFAULT '0' COMMENT '排序',
`icon` varchar(50) DEFAULT NULL COMMENT '图标',
`route` varchar(255) DEFAULT NULL COMMENT '路由路径',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_code` (`code`),
KEY `idx_parent_id` (`parent_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='权限表';
-- 用户-角色关联表
CREATE TABLE `user_roles` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`user_id` bigint NOT NULL COMMENT '用户ID',
`role_id` bigint NOT NULL COMMENT '角色ID',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_user_role` (`user_id`, `role_id`),
KEY `idx_role_id` (`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户角色关联表';
-- 角色-权限关联表
CREATE TABLE `role_permissions` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`role_id` bigint NOT NULL COMMENT '角色ID',
`permission_id` bigint NOT NULL COMMENT '权限ID',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_role_permission` (`role_id`, `permission_id`),
KEY `idx_permission_id` (`permission_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='角色权限关联表';
-- 操作日志表
CREATE TABLE `operation_logs` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`user_id` bigint DEFAULT NULL COMMENT '操作用户ID',
`action` varchar(255) NOT NULL COMMENT '操作描述',
`module` varchar(50) DEFAULT NULL COMMENT '操作模块',
`method` varchar(10) DEFAULT NULL COMMENT '请求方法',
`url` varchar(500) DEFAULT NULL COMMENT '请求URL',
`ip_address` varchar(45) DEFAULT NULL COMMENT 'IP地址',
`user_agent` varchar(500) DEFAULT NULL COMMENT '浏览器UA',
`status_code` int DEFAULT NULL COMMENT '响应状态码',
`duration` int DEFAULT NULL COMMENT '请求耗时(ms)',
`request_params` text COMMENT '请求参数(JSON)',
`response_data` text COMMENT '响应数据(JSON)',
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '操作时间',
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`),
Key `idx_created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='操作日志表';
-- 初始化管理员账户 (密码: admin123456, bcrypt加密)
INSERT INTO `users` (`username`, `password`, `nickname`, `status`) VALUES
('admin', '$2b$10$xxxxxxxxxxxxxxxxxxxxxxx', '超级管理员', 1);
-- 初始化角色
INSERT INTO `roles` (`name`, `code`, `description`) VALUES
('超级管理员', 'super_admin', '拥有系统所有权限'),
('普通管理员', 'admin', '拥有大部分管理权限'),
('运维人员', 'operator', '拥有设备管理和查看权限');
-- 初始化基础权限 (菜单权限)
INSERT INTO `permissions` (`name`, `code`, `type`, `parent_id`, `sort_order`, `route`) VALUES
('仪表盘', 'dashboard', 'menu', NULL, 1, '/dashboard'),
('系统管理', 'system', 'menu', NULL, 2, '/system'),
('用户管理', 'user:list', 'button', NULL, 3, NULL),
('角色管理', 'role:list', 'button', NULL, 4, NULL),
('系统设置', 'system:settings', 'button', NULL, 5, NULL);
8. 安全设计
8.1 认证机制
- JWT Token: Access Token (2小时有效) + Refresh Token (7天有效)
- 密码存储: bcrypt加密 (saltRounds = 10)
- 登录保护: 验证码(可选)、IP限制、账户锁定
8.2 权限控制
- RBAC模型: 用户 → 角色 → 权限 三层权限体系
- 前端路由守卫: 根据权限动态生成可访问路由
- 后端接口鉴权: 每个接口验证Token + 权限码
- 按钮级别控制: 前端根据权限指令令牌控制按钮显隐
8.3 数据安全
- SQL注入防护: 使用ORM参数化查询
- XSS防护: 输入过滤 + 输出转义
- CSRF防护: SameSite Cookie + Token验证
- 敏感数据加密: 手机号、邮箱脱敏显示
9. 性能优化策略
前端优化
- 路由懒加载: 使用动态import()按需加载页面组件
- 组件按需加载: Ant Design Vue按需引入
- 状态缓存: keep-alive缓存常用页面
- 资源压缩: Gzip/Brotli压缩
- CDN加速: 静态资源CDN分发
后端优化
- Redis缓存: 用户权限缓存、系统设置缓存、热点数据缓存
- 连接池: MySQL连接池、Redis连接池
- 索引优化: 数据库查询关键字段建立索引
- 分页查询: 所有列表接口强制分页
- 日志异步: 操作日志异步写入
10. 部署方案
开发环境
- 本地开发: 前端Vite Dev Server + 后端Midway热重载
- 数据库: 本地MySQL + Redis
- 代理配置: Vite代理API请求到后端
生产环境
- 前端: 构建静态文件 -> Nginx托管
- 后端: PM2进程管理 -> Node.js运行
- 数据库: 云数据库RDS + Redis云服务
- 反向代理: Nginx负载均衡 + SSL证书