import { Provide, Inject } from "@midwayjs/core"; import { InjectRepository } from "@midwayjs/sequelize"; import SysUser from "../entity/sysUser.entity"; import SysOperationLog from "../entity/sysOperationLog.entity"; import dayjs from "dayjs"; import { Op } from "sequelize"; @Provide() export class DashboardService { @InjectRepository(SysOperationLog) logModel!: typeof SysOperationLog; async getDashboardStats(): Promise { const mockDeviceTotal = 1256; const mockDeviceOnline = 1089; const mockAlertToday = 23; const activeUsers = await this.getActiveUserCount(7); const loginTrend = await this.getLoginTrend(7); const deviceTrend = this.generateMockTrend(7, 900, 1100); const deviceDistribution = [ { name: "智能电表", value: 456 }, { name: "环境传感器", value: 328 }, { name: "摄像头", value: 245 }, { name: "门禁系统", value: 147 }, { name: "其他设备", value: 80 } ]; const recentAlerts = this.generateMockAlerts(10); const recentActivities = await this.getRecentActivities(10); return { deviceTotal: mockDeviceTotal, deviceOnline: mockDeviceOnline, alertToday: mockAlertToday, activeUsers, deviceTrend, deviceTypeDistribution: deviceDistribution, recentAlerts, recentActivities }; } private async getActiveUserCount(days: number): Promise { const cutoffDate = dayjs().subtract(days, "day").toDate(); try { const count = await this.logModel.count({ where: { action: "用户登录", created_at: { [Op.gte]: cutoffDate } }, distinct: true, col: "userId" }); return count || 12; } catch (error) { return 12; } } private async getLoginTrend(days: number): Promise { const trend = []; for (let i = days - 1; i >= 0; i--) { const date = dayjs().subtract(i, "day").format("YYYY-MM-DD"); try { const count = await this.logModel.count({ where: { action: "用户登录", created_at: { [Op.between]: [dayjs(date).startOf("day").toDate(), dayjs(date).endOf("day").toDate()] } } }); trend.push({ date, value: count || Math.floor(Math.random() * 50) + 20 }); } catch (error) { trend.push({ date, value: Math.floor(Math.random() * 50) + 20 }); } } return trend; } private async getRecentActivities(limit: number): Promise { try { const logs = await this.logModel.findAll({ order: [["created_at", "DESC"]], limit, attributes: ["id", "action", "module", "ip", "created_at"] }); return logs.map((log) => ({ id: log.id, user: String(log.userId || "系统"), action: log.action, module: log.module, ip: log.ip, time: dayjs(log.created_at).format("MM-DD HH:mm") })); } catch (error) { return this.generateMockActivities(limit); } } private generateMockTrend(days: number, min: number, max: number): any[] { const trend = []; for (let i = days - 1; i >= 0; i--) { trend.push({ date: dayjs().subtract(i, "day").format("YYYY-MM-DD"), online: Math.floor(Math.random() * (max - min)) + min, offline: Math.floor(Math.random() * 200) + 50 }); } return trend; } private generateMockAlerts(count: number): any[] { const alertTypes = ["离线告警", "异常数据", "通信故障", "电量低", "温度超标"]; const devices = ["电表#1001", "传感器#2003", "摄像头#3012", "门禁#4005"]; const levels = ["high", "medium", "low"]; const alerts = []; for (let i = 0; i < count; i++) { alerts.push({ id: i + 1, type: alertTypes[Math.floor(Math.random() * alertTypes.length)], device: devices[Math.floor(Math.random() * devices.length)], level: levels[Math.floor(Math.random() * levels.length)], time: dayjs() .subtract(Math.floor(Math.random() * 60), "minute") .format("HH:mm"), status: Math.random() > 0.5 ? "pending" : "resolved" }); } return alerts.sort((a, b) => a.time.localeCompare(b.time)); } private generateMockActivities(count: number): any[] { const actions = [ { user: "管理员", action: "用户登录", module: "认证" }, { user: "操作员A", action: "修改设备配置", module: "设备管理" }, { user: "管理员", action: "创建新用户", module: "用户管理" }, { user: "操作员B", action: "查看告警列表", module: "监控中心" }, { user: "系统", action: "自动备份完成", module: "系统" }, { user: "操作员A", action: "导出数据报表", module: "数据分析" }, { user: "管理员", action: "更新系统配置", module: "系统设置" }, { user: "操作员C", action: "处理告警事件", module: "监控中心" }, { user: "系统", action: "定时任务执行", module: "系统" }, { user: "操作员B", action: "添加新设备", module: "设备管理" } ]; return actions.slice(0, count).map((item, index) => ({ id: index + 1, ...item, ip: "192.168.1." + Math.floor(Math.random() * 255), time: dayjs() .subtract(index * 30, "minute") .format("MM-DD HH:mm") })); } }