Chandrasekhar711/Disaster-Management-Emergency-Alert-System-DM-EAS-

GitHub: Chandrasekhar711/Disaster-Management-Emergency-Alert-System-DM-EAS-

基于MERN栈构建的灾害管理与应急警报系统,支持市民实时上报灾害事件、SOS广播警报以及多应急机构基于地图的协同响应与调度。

Stars: 0 | Forks: 0

# 🚨 灾害管理与应急警报系统 (DM-EAS) 一个适用于生产环境的 MERN 技术栈 Web 应用程序,具备地理空间功能,用于实时灾害管理、应急响应协调和事件跟踪。 ## 🌟 功能 ### 核心功能 - **实时事件报告** - 市民可以上传照片/视频并附带地理位置报告灾害 - **地理空间跟踪** - 使用 MongoDB 地理空间查询查找半径内的事件 - **实时仪表盘** - 通过 WebSocket 进行实时事件更新 - **机构管理** - 警察、消防、医疗、救援协同响应 - **SOS 警报** - 关键紧急情况触发器,支持广播通知 - **分析仪表盘** - 使用 Recharts 进行事件统计和趋势分析 - **交互式地图** - 基于 Leaflet 的实时事件可视化 - **基于角色的访问控制** - 市民、机构、管理员权限 - **媒体上传** - 支持事件照片和视频 ### 安全功能 - JWT 身份验证,token 有效期为 7 天 - 双重登录支持:邮箱或用户 ID - 唯一的用户 ID 字段(4-20 个字符,字母数字 + 下划线) - 使用 bcryptjs 进行密码哈希处理(盐因子为 10) - 使用 express-validator 进行输入验证(前端 + 后端) - CORS 配置 - 使用 RBAC 保护 API 路由 - 安全的错误处理及提示信息 - 不区分大小写的用户身份验证 - 做好限流准备 ### UI/UX 功能 - 现代毛玻璃设计 - 流畅的 Framer Motion 动画 - Tailwind CSS 响应式布局 - 做好适配深色/浅色模式准备 - 定制的卡片和组件 - 加载骨架屏 - Toast 通知 - 响应式移动端设计 ## 🏗️ 架构 ### 技术栈 ``` Frontend: - React 18 with Vite - Zustand for state management - Socket.IO for real-time updates - Framer Motion for animations - Recharts for analytics - Leaflet for maps - Tailwind CSS for styling Backend: - Node.js + Express.js - MongoDB with geospatial indexing - Socket.IO for real-time broadcasting - JWT for authentication - Bcrypt for password hashing ``` ### 项目结构 ``` IMSD/ ├── backend/ │ ├── controllers/ │ │ ├── authController.js │ │ └── incidentController.js │ ├── routes/ │ │ ├── authRoutes.js │ │ └── incidentRoutes.js │ ├── models/ │ │ ├── User.js │ │ └── Incident.js │ ├── middleware/ │ │ ├── auth.js │ │ ├── errorHandler.js │ │ └── validation.js │ ├── services/ │ │ ├── authService.js │ │ └── incidentService.js │ ├── utils/ │ │ ├── tokenUtils.js │ │ └── responseHandler.js │ ├── config/ │ │ ├── database.js │ │ └── socket.js │ ├── server.js │ ├── package.json │ └── .env.example │ └── frontend/ ├── src/ │ ├── components/ │ │ ├── common.jsx │ │ ├── ProtectedRoute.jsx │ │ ├── Navbar.jsx │ │ └── IncidentCard.jsx │ ├── pages/ │ │ ├── LoginPage.jsx │ │ ├── RegisterPage.jsx │ │ ├── DashboardPage.jsx │ │ ├── ReportIncidentPage.jsx │ │ ├── AnalyticsPage.jsx │ │ ├── MapPage.jsx │ │ └── ErrorPage.jsx │ ├── services/ │ │ ├── apiClient.js │ │ ├── api.js │ │ └── socket.js │ ├── context/ │ │ └── store.js │ ├── utils/ │ │ └── auth.js │ ├── App.jsx │ ├── main.jsx │ └── index.css ├── index.html ├── vite.config.js ├── tailwind.config.js ├── postcss.config.js ├── package.json └── .env.example ``` ## 🚀 快速开始 ### 前置条件 - Node.js (v16+) - MongoDB (v4.4+) - npm 或 yarn ### 后端配置 1. **进入后端目录** cd backend 2. **安装依赖** npm install 3. **创建 .env 文件** cp .env.example .env 4. **配置环境变量** MONGODB_URI=mongodb://localhost:27017/dm-eas JWT_SECRET=your_jwt_secret_key_here_minimum_32_characters PORT=5000 NODE_ENV=development FRONTEND_URL=http://localhost:5173 5. **启动 MongoDB** mongod 6. **运行后端服务器** npm run dev 服务器运行在 `http://localhost:5000` ### 前端配置 1. **进入前端目录** cd frontend 2. **安装依赖** npm install 3. **创建 .env.local 文件** cp .env.example .env.local 4. **配置环境变量** VITE_API_URL=http://localhost:5000/api VITE_SOCKET_URL=http://localhost:5000 5. **启动开发服务器** npm run dev 应用运行在 `http://localhost:5173` 6. **构建生产环境** npm run build ## 📝 API 文档 ### 身份验证接口 #### 注册用户 ``` POST /api/auth/register Content-Type: application/json { "name": "John Doe", "userId": "john_doe", "email": "user@example.com", "phone": "9876543210", "password": "password123", "role": "citizen", "department": null } ``` **注意**:必须提供 `userId`,长度必须为 4-20 个字符,仅支持字母数字 + 下划线。 #### 使用邮箱或用户 ID 登录 ``` POST /api/auth/login Content-Type: application/json { "emailOrUserId": "john_doe", "password": "password123" } ``` **或者使用邮箱:** ``` { "emailOrUserId": "user@example.com", "password": "password123" } ``` **注意**:系统会自动检测邮箱(包含 @)或用户 ID(4-20 个字符) #### 获取个人资料 ``` GET /api/auth/profile Authorization: Bearer ``` ### 事件接口 #### 创建事件 ``` POST /api/incidents Authorization: Bearer Content-Type: application/json { "title": "Building Fire", "description": "Large fire reported at commercial building", "type": "fire", "severity": "critical", "location": { "coordinates": [77.1025, 28.7041], "address": "123 Main Street, Delhi" }, "media": [] } ``` #### 获取所有事件 ``` GET /api/incidents?page=1&limit=10&type=fire&status=reported&severity=high ``` #### 获取附近事件 ``` GET /api/incidents/nearby?longitude=77.1025&latitude=28.7041&radius=5000 ``` #### 获取事件详情 ``` GET /api/incidents/:id ``` #### 更新事件状态 ``` PUT /api/incidents/:id/status Authorization: Bearer Content-Type: application/json { "status": "responding" } ``` #### 指派响应人员 ``` POST /api/incidents/:id/assign Authorization: Bearer Content-Type: application/json { "userId": "objectId", "department": "fire" } ``` #### 触发 SOS ``` POST /api/incidents/:id/sos Authorization: Bearer ``` #### 获取统计数据 ``` GET /api/incidents/stats ``` ## 🔌 WebSocket 事件 ### 服务端 → 客户端事件 ``` // New incident created socket.on('new-incident', (incident) => { // Handle new incident }); // Existing incident updated socket.on('incident-update', (incident) => { // Handle incident update }); // SOS alert triggered socket.on('sos-alert', (data) => { // Handle SOS alert }); // General notification socket.on('notification', (data) => { // Handle notification }); ``` ### 客户端 → 服务端事件 ``` // Join incident updates room socket.emit('join-incident-updates'); // Join SOS alerts room socket.emit('join-sos-alerts'); // Join live map room socket.emit('join-live-map'); // Join global notifications room socket.emit('join-global-notifications'); // Subscribe to user-specific updates socket.emit('subscribe-user', userId); // Send notification socket.emit('send-notification', { message: 'Alert!' }); ``` ## 🗄️ MongoDB Schema ### User Schema ``` { name: String, userId: String (unique, 4-20 chars, alphanumeric + underscore), email: String (unique), phone: String, password: String (hashed with bcryptjs), role: 'citizen' | 'authority' | 'admin', department: 'police' | 'fire' | 'medical' | 'rescue' | 'civil_defense', location: { type: Point, coordinates: [longitude, latitude] }, address: String, isVerified: Boolean, isActive: Boolean, profileImage: String, bio: String, incidentsReported: [ObjectId], incidentsAssigned: [ObjectId], createdAt: Date, updatedAt: Date } ``` ### Incident Schema ``` { title: String, description: String, type: 'flood' | 'fire' | 'accident' | 'earthquake' | 'hazard' | 'other', status: 'reported' | 'verified' | 'responding' | 'resolved' | 'cancelled', severity: 'low' | 'medium' | 'high' | 'critical', location: { type: Point, coordinates: [longitude, latitude], address: String }, media: [{ url: String, type: 'image' | 'video', uploadedAt: Date }], reportedBy: ObjectId (User), verifiedBy: ObjectId (User), assignedTo: [{ userId: ObjectId, department: String, assignedAt: Date }], responders: [ObjectId], comments: [{ author: ObjectId, text: String, createdAt: Date }], isSOS: Boolean, sosTriggeredAt: Date, sosTriggeredBy: ObjectId, viewCount: Number, affectedPeople: Number, estimatedDamage: 'minimal' | 'moderate' | 'severe' | 'catastrophic', resolutionNotes: String, resolvedAt: Date, priority: Number, createdAt: Date, updatedAt: Date } ``` ## 🔐 基于角色的访问控制 ### 市民角色 - 报告事件 - 查看公开事件 - 为事件添加评论 - 触发 SOS - 查看个人资料 ### 机构角色(已验证) - 所有市民权限 - 验证事件 - 更新事件状态 - 指派响应人员 - 查看分析数据 - 访问受保护的 endpoint ### 管理员角色 - 所有权限 - 用户管理 - 机构验证 - 系统管理 - 完整的分析数据访问权限 ## 🧪 测试演示账号 ``` Citizen Account: User ID: demo_citizen Email: citizen@demo.com Password: password123 Authority Account: User ID: demo_officer Email: officer@demo.com Password: password123 Admin Account: User ID: admin_user Email: admin@demo.com Password: password123 Login Options: - Use User ID (e.g., demo_citizen) - Use Email (e.g., citizen@demo.com) System automatically detects which format is being used ``` ## 📊 API 响应示例 ### 创建事件响应 ``` { "success": true, "message": "Incident reported successfully", "data": { "_id": "507f1f77bcf86cd799439011", "title": "Building Fire", "description": "Large fire at commercial building", "type": "fire", "status": "reported", "severity": "critical", "location": { "type": "Point", "coordinates": [77.1025, 28.7041], "address": "123 Main Street, Delhi" }, "reportedBy": { "_id": "507f1f77bcf86cd799439012", "name": "John Doe", "email": "john@example.com" }, "createdAt": "2024-02-19T10:30:00Z" } } ``` ### 获取事件响应 ``` { "success": true, "message": "Incidents retrieved successfully", "data": [ { "_id": "507f1f77bcf86cd799439011", "title": "Building Fire", "description": "Large fire at commercial building", "type": "fire", "status": "verified", "severity": "critical", "isSOS": false, "location": { "coordinates": [77.1025, 28.7041], "address": "123 Main Street, Delhi" }, "reportedBy": { "name": "John Doe" }, "createdAt": "2024-02-19T10:30:00Z" } ], "pagination": { "page": 1, "limit": 10, "total": 45, "pages": 5, "hasNextPage": true, "hasPrevPage": false } } ``` ## 🛠️ 开发 ### 后端开发 ``` cd backend npm run dev # Start with nodemon npm start # Start production build ``` ### 前端开发 ``` cd frontend npm run dev # Start Vite dev server npm run build # Build for production npm run preview # Preview production build ``` ## 📦 部署 ### 后端部署 (Heroku/Railway) 1. 推送代码到 Git 仓库 2. 在托管平台上设置环境变量 3. 部署到托管平台 4. 需要 MongoDB Atlas 连接字符串 ### 前端部署 (Vercel/Netlify) 1. 构建:`npm run build` 2. 部署 `dist` 文件夹 3. 配置环境变量 4. 将 API_URL 设置为生产环境后端 ## 🔄 实时功能 ### 实时更新 - 事件创建广播给所有已连接用户 - 状态更新实时传播 - SOS 警报触发关键广播 - 评论添加即时更新 ### Socket.IO 集成 - 带有指数退避的自动重连 - 支持 WebSocket 和轮询传输 - 基于房间的事件隔离 - 特定用户的订阅 ## 🎨 自定义 ### 配色方案 编辑 [tailwind.config.js](frontend/tailwind.config.js): ``` colors: { primary: { /* Blue tones */ }, alert: { /* Red/Alert tones */ } } ``` ### 地图样式 修改 [MapPage.jsx](frontend/src/pages/MapPage.jsx) 中的地图提供商 ### API Base URL 在 [apiClient.js](frontend/src/services/apiClient.js) 中更新 ## 📚 文档 - **API 文档**:查看上方的 [API 文档](#📝-api-documentation) - **数据库 Schema**:查看上方的 [MongoDB Schema](#🗄️-mongodb-schema) - **WebSocket 事件**:查看上方的 [WebSocket 事件](#🔌-websocket-events) - **Socket 配置**:[backend/config/socket.js](backend/config/socket.js) ## 🐛 故障排除 ### MongoDB 连接问题 ``` # 检查 MongoDB 正在运行 mongod --version # 验证 .env 中的 connection string ``` ### WebSocket 连接失败 - 确保后端在正确的端口上运行 - 检查 CORS 源配置 - 验证防火墙设置 ### CORS 错误 - 在后端的 .env 中更新 `FRONTEND_URL` - 验证 [server.js](backend/server.js) 中的 CORS 中间件配置 ### 登录问题 - 清除浏览器 cookie 和 localStorage - 确认已设置 JWT_SECRET - 检查数据库中是否存在该用户 ## 📝 环境变量 ### 后端 (.env) ``` MONGODB_URI=mongodb://localhost:27017/dm-eas JWT_SECRET=<32+ character secret> PORT=5000 NODE_ENV=development FRONTEND_URL=http://localhost:5173 MAX_FILE_SIZE=5242880 ``` ### 前端 (.env.local) ``` VITE_API_URL=http://localhost:5000/api VITE_SOCKET_URL=http://localhost:5000 ``` ## 🤝 贡献 1. Fork 该仓库 2. 创建功能分支:`git checkout -b feature/amazing-feature` 3. 提交更改:`git commit -m 'Add amazing feature'` 4. 推送到分支:`git push origin feature/amazing-feature` 5. 发起 Pull Request ## 📄 许可证 本项目基于 MIT 许可证授权 - 详情请参阅 LICENSE 文件。 ## 👥 支持 如需支持,请发送电子邮件至 support@dm-eas.com 或在 GitHub 上提交 issue。 ## 🙈 鸣谢 - MongoDB 提供的地理空间功能 - Socket.IO 提供的实时通信 - Recharts 提供的精美分析图表 - Leaflet 提供的交互式地图 - Framer Motion 提供的流畅动画 - Tailwind CSS 提供的实用优先样式 **为应急管理和灾害响应倾心打造 ❤️** 最后更新:2024 年 2 月
标签:MERN技术栈, MITM代理, 地理空间追踪, 实时通信, 应急响应系统, 灾害管理, 角色权限控制