diff --git a/backend/src/api/users.ts b/backend/src/api/users.ts index 9b27539..3ac175b 100644 --- a/backend/src/api/users.ts +++ b/backend/src/api/users.ts @@ -110,14 +110,11 @@ users.delete("/:id", async (c) => { users.post("/:id/change-password", async (c) => { try { const id = parseInt(c.req.param("id")); - const payload = c.get("jwtPayload"); const passwordData = await c.req.json(); const result = await changePasswordService( id, passwordData, - payload.id, - payload.role ); return c.json( diff --git a/backend/src/db/seed.ts b/backend/src/db/seed.ts index e6ae77f..3437677 100644 --- a/backend/src/db/seed.ts +++ b/backend/src/db/seed.ts @@ -58,9 +58,8 @@ export async function createAdminUser(): Promise { // 如果不存在管理员用户,则创建一个 if (adminUser.length === 0) { console.log("创建管理员用户..."); - // 密码: admin123 - const salt = await bcrypt.genSalt(10); - const hashedPassword = await bcrypt.hash("admin123", salt); + + const hashedPassword = await bcrypt.hash("admin123", 10); const now = new Date().toISOString(); await db.insert(users).values({ diff --git a/backend/src/index.ts b/backend/src/index.ts index 6730725..3052710 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -71,6 +71,8 @@ export default { // 添加定时任务,每分钟执行一次监控检查和客户端状态检查 async scheduled(event: any, env: any, ctx: any) { try { + // 初始化 drizzle 实例 + config.initDb(env); await jobs.runScheduledTasks(event, env, ctx); } catch (error) { console.error("定时任务执行出错:", error); diff --git a/backend/src/jobs/agent-task.ts b/backend/src/jobs/agent-task.ts index 2fdeea1..2f3b3b8 100644 --- a/backend/src/jobs/agent-task.ts +++ b/backend/src/jobs/agent-task.ts @@ -27,19 +27,20 @@ export const checkAgentsStatus = async (c: any) => { console.log("定时任务: 检查客户端状态..."); // 检查所有客户端的最后更新时间,如果超过60分钟没有更新,将状态设置为inactive - const inactiveThreshold = 60 * 60 * 1000; // 60分钟,单位毫秒 const now = new Date(); // 查询所有状态为active的客户端 - const activeAgents = await getActiveAgents(c.env); + const activeAgents = await getActiveAgents(); - if (!activeAgents.results || activeAgents.results.length === 0) { + console.log("定时任务: 活跃状态的客户端数量:", activeAgents); // 调试用,输出活跃客户端数量,确保正确获取到数据 + + if (!activeAgents || activeAgents.length === 0) { console.log("定时任务: 没有活跃状态的客户端"); return; } // 检查每个活跃客户端的最后更新时间 - for (const agent of activeAgents.results as AgentResult[]) { + for (const agent of activeAgents as AgentResult[]) { const lastUpdateTime = new Date(agent.updated_at); const timeDiff = now.getTime() - lastUpdateTime.getTime(); @@ -50,7 +51,7 @@ export const checkAgentsStatus = async (c: any) => { ); // 更新客户端状态为inactive - await setAgentInactive(c.env, agent.id); + await setAgentInactive(agent.id); // 处理通知 await handleAgentOfflineNotification(c.env, agent.id, agent.name); diff --git a/backend/src/jobs/monitor-task.ts b/backend/src/jobs/monitor-task.ts index c89e307..1cc6708 100644 --- a/backend/src/jobs/monitor-task.ts +++ b/backend/src/jobs/monitor-task.ts @@ -13,28 +13,24 @@ const monitorTask = new Hono<{ Bindings: Bindings }>(); async function checkMonitors(c: any) { try { console.log("开始执行监控检查..."); - // 获取当前时间 - const now = new Date(); // 查询需要检查的监控 const monitors = await getMonitorsToCheck(); - console.log(`找到 ${monitors?.results?.length || 0} 个需要检查的监控`); + console.log(`找到 ${monitors?.length || 0} 个需要检查的监控`); - if (!monitors.results || monitors.results.length === 0) { + if (!monitors || monitors.length === 0) { return { success: true, message: "没有需要检查的监控", checked: 0 }; } // 检查每个监控 const results = await Promise.all( - monitors.results.map(async (monitorItem: any) => { - // 确保正确的类型转换 - const monitor = monitorItem as Monitor; + monitors.map(async (monitor: Monitor) => { + console.log(`开始检查监控: ${monitor.name} (ID: ${monitor.id})`); const checkResult = await checkMonitor(monitor); - // 处理通知 + console.log(`检查完成,状态: ${checkResult}`); await handleMonitorNotification(c, monitor, checkResult); - return checkResult; }) ); diff --git a/backend/src/repositories/agent.ts b/backend/src/repositories/agent.ts index bf63107..836c116 100644 --- a/backend/src/repositories/agent.ts +++ b/backend/src/repositories/agent.ts @@ -1,4 +1,3 @@ -import { Bindings } from "../models/db"; import { Agent, Metrics } from "../models/agent"; import { agents, agentMetrics24h } from "../db/schema"; import { db } from "../config"; @@ -111,10 +110,11 @@ export async function getAgentByToken(token: string) { // 获取活跃状态的客户端 export async function getActiveAgents() { - return await db - .select("id", "name", "updated_at", "keepalive") - .from(agents) - .where(eq(agents.status, "active")); + const activeAgents = await db + .select() + .from(agents) + .where(eq(agents.status, "active")); + return activeAgents; } // 设置客户端为离线状态 diff --git a/backend/src/repositories/monitor.ts b/backend/src/repositories/monitor.ts index 990731b..e1b91af 100644 --- a/backend/src/repositories/monitor.ts +++ b/backend/src/repositories/monitor.ts @@ -6,7 +6,7 @@ import { monitorStatusHistory24h, monitorDailyStats, } from "../db/schema"; -import { eq, desc, asc, and, or, isNull, gte } from "drizzle-orm"; +import { eq, desc, asc, lt } from "drizzle-orm"; /** * 监控相关的数据库操作 @@ -14,22 +14,27 @@ import { eq, desc, asc, and, or, isNull, gte } from "drizzle-orm"; // 获取需要检查的监控列表 export async function getMonitorsToCheck() { - // 这里的查询写的是有问题的,需要获取的是当前时间大于last_checked + interval的监控 - // 但是interval是字符串,需要转换为数字 - // 并且last_checked是字符串,需要转换为日期 - const result = await db + + // 使用SQL表达式或自定义函数来处理日期计算 + const allmonitors = await db .select() .from(monitors) - .where( - and( - eq(monitors.active, 1), - or(isNull(monitors.last_checked), gte(monitors.interval, 0)) - ) - ); + .execute(); + + // 在JavaScript中进行日期计算筛选 + const now = new Date().getTime(); + const monitorsToCheck = allmonitors.filter((monitor: Monitor) => { + if (!monitor.last_checked) return true; // 如果没有检查过,需要检查 + + const lastCheckedTime = new Date(monitor.last_checked).getTime(); + const intervalMs = (monitor.interval || 60) * 1000; // 转换为毫秒 + + return now > (lastCheckedTime + intervalMs); + }); // 解析所有监控的 headers 字段 - if (result.results) { - result.results.forEach((monitor: Monitor) => { + if (monitorsToCheck) { + monitorsToCheck.forEach((monitor: Monitor) => { if (typeof monitor.headers === "string") { try { monitor.headers = JSON.parse(monitor.headers); @@ -39,7 +44,7 @@ export async function getMonitorsToCheck() { } }); } - return result; + return monitorsToCheck; } // 获取单个监控详情 diff --git a/backend/src/repositories/users.ts b/backend/src/repositories/users.ts index eb29421..5bc7cc8 100644 --- a/backend/src/repositories/users.ts +++ b/backend/src/repositories/users.ts @@ -173,7 +173,7 @@ export async function updateUserPassword(id: number, hashedPassword: string) { .where(eq(users.id, id)) .returning(); - if (!result.success) { + if (!result) { throw new Error("更新密码失败"); } diff --git a/backend/src/services/AgentService.ts b/backend/src/services/AgentService.ts index e9e72e7..fa81f18 100644 --- a/backend/src/services/AgentService.ts +++ b/backend/src/services/AgentService.ts @@ -45,8 +45,8 @@ export async function getAgentDetail(agentId: number) { const { token, ...rest } = agent; return { - ...rest, - ip_addresses: getFormattedIPAddresses(agent.ip_addresses as any), + ...rest, + ip_addresses: getFormattedIPAddresses(agent.ip_addresses as any), }; } @@ -96,7 +96,7 @@ export async function updateAgentService( // 执行更新 const updatedAgent = await AgentRepository.updateAgent(agent); - + return { success: true, message: "客户端信息已更新", @@ -120,7 +120,7 @@ export async function updateAgentService( * @param agentId 客户端ID * @returns 删除结果 */ -export async function deleteAgentService( agentId: number) { +export async function deleteAgentService(agentId: number) { try { // 获取客户端信息 const agent = await AgentRepository.getAgentById(agentId); @@ -266,9 +266,7 @@ export async function registerAgentService( * @param status 客户端指标 * @returns 更新结果 */ -export async function updateAgentStatusService( - status: any -) { +export async function updateAgentStatusService(status: any) { try { const statusData = Array.isArray(status) ? status : [status]; const norlmalInfo = { @@ -304,7 +302,7 @@ export async function updateAgentStatusService( agent.status = norlmalInfo.status; console.log("update agent info: ", agent); - + await AgentRepository.updateAgent(agent); } @@ -361,20 +359,18 @@ export async function getAgentById(id: number) { return await AgentRepository.getAgentById(id); } -export async function getActiveAgents(env: any) { +export async function getActiveAgents() { return await AgentRepository.getActiveAgents(); } -export async function setAgentInactive(env: any, id: number) { +export async function setAgentInactive(id: number) { return await AgentRepository.setAgentInactive(id); } -export async function getAgentMetrics( agentId: number) { +export async function getAgentMetrics(agentId: number) { return await AgentRepository.getAgentMetrics(agentId); } -export async function getLatestAgentMetrics( - agentId: number -) { +export async function getLatestAgentMetrics(agentId: number) { return await AgentRepository.getLatestAgentMetrics(agentId); } diff --git a/backend/src/services/DashboardService.ts b/backend/src/services/DashboardService.ts index 4141b18..01994c8 100644 --- a/backend/src/services/DashboardService.ts +++ b/backend/src/services/DashboardService.ts @@ -17,7 +17,7 @@ export async function getDashboardData() { }); } return { - monitors: monitors.monitors, + monitors: monitors, agents: agents, }; } diff --git a/backend/src/services/MonitorService.ts b/backend/src/services/MonitorService.ts index 3091353..67eddd0 100644 --- a/backend/src/services/MonitorService.ts +++ b/backend/src/services/MonitorService.ts @@ -88,7 +88,7 @@ export async function checkMonitor(monitor: models.Monitor) { const status = isExpectedStatus ? "up" : "down"; // 记录状态历史 - await repositories.insertMonitorStatusHistory( + const res = await repositories.insertMonitorStatusHistory( monitor.id, status, responseTime, @@ -96,6 +96,8 @@ export async function checkMonitor(monitor: models.Monitor) { error ); + console.log(`监控 ${monitor.name} (${monitor.url}) 检查完成. ${res}`); + // 更新监控状态 await repositories.updateMonitorStatus(monitor.id, status, responseTime); diff --git a/backend/src/services/StatusService.ts b/backend/src/services/StatusService.ts index ba1c5d0..0c39747 100644 --- a/backend/src/services/StatusService.ts +++ b/backend/src/services/StatusService.ts @@ -137,8 +137,6 @@ export async function getStatusPagePublicData() { // 获取所有配置 const configsResult = await repositories.getAllStatusPageConfigs(); - console.log("configsResult", configsResult); - if (!configsResult || configsResult.length === 0) { console.log("没有找到任何配置"); @@ -160,15 +158,12 @@ export async function getStatusPagePublicData() { config.id as number ); - console.log("selectedMonitors", selectedMonitors); // 获取选中的客户端 const selectedAgents = await repositories.getSelectedAgents( config.id as number ); - console.log("selectedAgents", selectedAgents); - // 获取监控项详细信息 let monitors: any[] = []; if (selectedMonitors && selectedMonitors.length > 0) { diff --git a/backend/src/services/UserService.ts b/backend/src/services/UserService.ts index 6a77015..b5ad9d0 100644 --- a/backend/src/services/UserService.ts +++ b/backend/src/services/UserService.ts @@ -1,5 +1,6 @@ import { compare, hash } from "bcryptjs"; import * as repositories from "../repositories"; +import { error } from "console"; export async function getAllUsersService(userRole: string) { try { @@ -213,40 +214,28 @@ export async function changePasswordService( passwordData: { currentPassword?: string; newPassword: string; - }, - currentUserId: number, - userRole: string + } ) { try { - // 检查权限(仅允许用户本人或管理员) - if (userRole !== "admin" && currentUserId !== id) { - return { success: false, message: "无权修改此用户密码", status: 403 }; - } - - // 管理员可以不提供当前密码 - if (userRole !== "admin" && !passwordData.currentPassword) { - return { success: false, message: "必须提供当前密码", status: 400 }; - } - if (!passwordData.newPassword) { - return { success: false, message: "必须提供新密码", status: 400 }; + throw error("new password is required"); } // 获取用户 const user = await repositories.getFullUserById(id); if (!user) { - return { success: false, message: "用户不存在", status: 404 }; + throw error("user not found"); } // 非管理员需要验证当前密码 - if (userRole !== "admin" && passwordData.currentPassword) { + if (passwordData.currentPassword) { const isPasswordValid = await compare( passwordData.currentPassword, user.password ); if (!isPasswordValid) { - return { success: false, message: "当前密码不正确", status: 400 }; + throw error("current password is invalid"); } } @@ -259,6 +248,6 @@ export async function changePasswordService( return { success: true, message: "密码已更新", status: 200 }; } catch (error) { console.error("修改密码错误:", error); - return { success: false, message: "修改密码失败", status: 500 }; + return { success: false, message: error, status: 500 }; } }