fix: schedule task error and change password error

This commit is contained in:
zaunist committed 2025-06-04 01:11:55 +08:00
1 parent c7a80aab2c
commit 0207782a6a
13 files changed
+61 -79

No files matched your search

-3
View File
@@ -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(
+2 -3
View File
@@ -58,9 +58,8 @@ export async function createAdminUser(): Promise<void> {
// 如果不存在管理员用户,则创建一个
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({
+2
View File
@@ -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);
+6 -5
View File
@@ -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);
+5 -9
View File
@@ -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;
})
);
+5 -5
View File
@@ -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;
}
// 设置客户端为离线状态
+19 -14
View File
@@ -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;
}
// 获取单个监控详情
+1 -1
View File
@@ -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("更新密码失败");
}
+10 -14
View File
@@ -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);
}
+1 -1
View File
@@ -17,7 +17,7 @@ export async function getDashboardData() {
});
}
return {
monitors: monitors.monitors,
monitors: monitors,
agents: agents,
};
}
+3 -1
View File
@@ -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);
-5
View File
@@ -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) {
+7 -18
View File
@@ -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 };
}
}