Merge pull request #59 from zaunist/fix/delete_failed
fix: delete agent or monitor failed
This commit is contained in:
9 files changed
+1425
-60
No files matched your search
@@ -0,0 +1,7 @@
|
||||
ALTER TABLE `agents` DROP COLUMN `cpu_usage`;--> statement-breakpoint
|
||||
ALTER TABLE `agents` DROP COLUMN `memory_total`;--> statement-breakpoint
|
||||
ALTER TABLE `agents` DROP COLUMN `memory_used`;--> statement-breakpoint
|
||||
ALTER TABLE `agents` DROP COLUMN `disk_total`;--> statement-breakpoint
|
||||
ALTER TABLE `agents` DROP COLUMN `disk_used`;--> statement-breakpoint
|
||||
ALTER TABLE `agents` DROP COLUMN `network_rx`;--> statement-breakpoint
|
||||
ALTER TABLE `agents` DROP COLUMN `network_tx`;
|
||||
File diff suppressed because it is too large.
Load diff
@@ -8,6 +8,13 @@
|
||||
"when": 1748308256007,
|
||||
"tag": "0000_romantic_next_avengers",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 1,
|
||||
"version": "6",
|
||||
"when": 1749736889133,
|
||||
"tag": "0001_fluffy_pestilence",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -32,7 +32,11 @@ export async function getAgentMetricsByIds(agentIds: number[]) {
|
||||
|
||||
// 获取单个客户端详情
|
||||
export async function getAgentById(id: number) {
|
||||
const agent = await db.select().from(agents).where(eq(agents.id, id)).limit(1);
|
||||
const agent = await db
|
||||
.select()
|
||||
.from(agents)
|
||||
.where(eq(agents.id, id))
|
||||
.limit(1);
|
||||
return agent[0];
|
||||
}
|
||||
|
||||
@@ -53,19 +57,22 @@ export async function createAgent(
|
||||
// 将 ipAddresses 数组转换为 JSON 字符串
|
||||
const ipAddressesJson = ipAddresses ? JSON.stringify(ipAddresses) : null;
|
||||
|
||||
const result = await db.insert(agents).values({
|
||||
name,
|
||||
token,
|
||||
created_by: createdBy,
|
||||
status,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
hostname,
|
||||
ip_addresses: ipAddressesJson,
|
||||
os,
|
||||
version,
|
||||
keepalive,
|
||||
}).returning();
|
||||
const result = await db
|
||||
.insert(agents)
|
||||
.values({
|
||||
name,
|
||||
token,
|
||||
created_by: createdBy,
|
||||
status,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
hostname,
|
||||
ip_addresses: ipAddressesJson,
|
||||
os,
|
||||
version,
|
||||
keepalive,
|
||||
})
|
||||
.returning();
|
||||
|
||||
if (!result) {
|
||||
throw new Error("创建客户端失败");
|
||||
@@ -74,17 +81,19 @@ export async function createAgent(
|
||||
}
|
||||
|
||||
// 更新客户端信息
|
||||
export async function updateAgent(
|
||||
agent: Agent
|
||||
) {
|
||||
export async function updateAgent(agent: Agent) {
|
||||
agent.updated_at = new Date().toISOString();
|
||||
|
||||
|
||||
// 从 agent 对象中排除 id 等索引相关属性,避免更新主键
|
||||
const { id, token, created_by, ...updateData } = agent;
|
||||
|
||||
try {
|
||||
// 确保 updateData 中不包含 id
|
||||
const updatedAgent = await db.update(agents).set(updateData).where(eq(agents.id, id)).returning();
|
||||
const updatedAgent = await db
|
||||
.update(agents)
|
||||
.set(updateData)
|
||||
.where(eq(agents.id, id))
|
||||
.returning();
|
||||
return updatedAgent[0];
|
||||
} catch (error) {
|
||||
console.error("更新客户端失败:", error);
|
||||
@@ -94,12 +103,13 @@ export async function updateAgent(
|
||||
|
||||
// 删除客户端
|
||||
export async function deleteAgent(id: number) {
|
||||
// 先删除关联的指标数据
|
||||
await db.delete(agentMetrics24h).where(eq(agentMetrics24h.agent_id, id));
|
||||
|
||||
const result = await db.delete(agents).where(eq(agents.id, id));
|
||||
|
||||
if (!result.success) {
|
||||
try {
|
||||
// 先删除关联的指标数据
|
||||
await db.delete(agentMetrics24h).where(eq(agentMetrics24h.agent_id, id));
|
||||
// 再删除客户端
|
||||
await db.delete(agents).where(eq(agents.id, id));
|
||||
} catch (error) {
|
||||
console.error("删除客户端失败:", error);
|
||||
throw new Error("删除客户端失败");
|
||||
}
|
||||
|
||||
@@ -115,9 +125,9 @@ export async function getAgentByToken(token: string) {
|
||||
// 获取活跃状态的客户端
|
||||
export async function getActiveAgents() {
|
||||
const activeAgents = await db
|
||||
.select()
|
||||
.from(agents)
|
||||
.where(eq(agents.status, "active"));
|
||||
.select()
|
||||
.from(agents)
|
||||
.where(eq(agents.status, "active"));
|
||||
return activeAgents;
|
||||
}
|
||||
|
||||
@@ -133,7 +143,9 @@ export async function setAgentInactive(id: number) {
|
||||
|
||||
// 插入客户端资源指标
|
||||
export async function insertAgentMetrics(metrics: Metrics[]) {
|
||||
return await db.batch(metrics.map(metric => db.insert(agentMetrics24h).values(metric)));
|
||||
return await db.batch(
|
||||
metrics.map((metric) => db.insert(agentMetrics24h).values(metric))
|
||||
);
|
||||
}
|
||||
|
||||
// 获取指定客户端资源指标
|
||||
|
||||
@@ -14,22 +14,18 @@ import { eq, desc, asc, lt } from "drizzle-orm";
|
||||
|
||||
// 获取需要检查的监控列表
|
||||
export async function getMonitorsToCheck() {
|
||||
|
||||
// 使用SQL表达式或自定义函数来处理日期计算
|
||||
const allmonitors = await db
|
||||
.select()
|
||||
.from(monitors)
|
||||
.execute();
|
||||
|
||||
const allmonitors = await db.select().from(monitors).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);
|
||||
|
||||
return now > lastCheckedTime + intervalMs;
|
||||
});
|
||||
|
||||
// 解析所有监控的 headers 字段
|
||||
|
||||
@@ -61,7 +61,6 @@ export const updateNotificationChannel = async (
|
||||
Omit<NotificationChannel, "id" | "created_at" | "updated_at">
|
||||
>
|
||||
): Promise<boolean> => {
|
||||
|
||||
const result = await db
|
||||
.update(notificationChannels)
|
||||
.set({
|
||||
@@ -245,7 +244,7 @@ export const getGlobalSettings = async (): Promise<{
|
||||
.select()
|
||||
.from(notificationSettings)
|
||||
.where(eq(notificationSettings.target_type, "global-agent"));
|
||||
|
||||
|
||||
return {
|
||||
monitorSettings: monitorSettings[0],
|
||||
agentSettings: agentSettings[0],
|
||||
@@ -279,19 +278,19 @@ export const createOrUpdateSettings = async (
|
||||
settings: Omit<NotificationSettings, "id" | "created_at" | "updated_at">
|
||||
): Promise<number> => {
|
||||
// 确保target_id为0时使用isNull,否则使用eq
|
||||
const condition = settings.target_id === 0 ? isNull(notificationSettings.target_id) : eq(notificationSettings.target_id, settings.target_id);
|
||||
const condition =
|
||||
settings.target_id === 0
|
||||
? isNull(notificationSettings.target_id)
|
||||
: eq(notificationSettings.target_id, settings.target_id);
|
||||
// 先检查是否已存在相同的设置
|
||||
const existingSettings = await db
|
||||
.select()
|
||||
.from(notificationSettings)
|
||||
.where(
|
||||
and(
|
||||
eq(notificationSettings.target_type, settings.target_type),
|
||||
condition
|
||||
)
|
||||
and(eq(notificationSettings.target_type, settings.target_type), condition)
|
||||
);
|
||||
|
||||
if (existingSettings.length === 1) {
|
||||
if (existingSettings.length > 0) {
|
||||
const existingSetting = existingSettings[0];
|
||||
// 如果已存在则更新
|
||||
await db
|
||||
@@ -418,29 +417,19 @@ export const getNotificationConfig = async (): Promise<NotificationConfig> => {
|
||||
// 获取所有渠道
|
||||
const channels = await getNotificationChannels();
|
||||
|
||||
console.log("channels", channels);
|
||||
|
||||
// 获取所有模板
|
||||
const templates = await getNotificationTemplates();
|
||||
|
||||
console.log("templates", templates);
|
||||
|
||||
// 获取全局设置
|
||||
const globalSettings = await getGlobalSettings();
|
||||
|
||||
console.log("globalSettings", globalSettings);
|
||||
|
||||
// 获取特定监控项设置
|
||||
const monitorSettings = await getSpecificSettings("monitor");
|
||||
|
||||
console.log("monitorSettings", monitorSettings);
|
||||
|
||||
// 获取特定客户端设置
|
||||
const agentSettings = await getSpecificSettings("agent");
|
||||
|
||||
console.log("agentSettings", agentSettings);
|
||||
|
||||
// 构建通知配置
|
||||
// 构建通知配置
|
||||
const config: NotificationConfig = {
|
||||
channels: channels,
|
||||
templates: templates,
|
||||
@@ -525,3 +514,31 @@ export const getNotificationConfig = async (): Promise<NotificationConfig> => {
|
||||
|
||||
return config;
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除通知设置
|
||||
* @param type 通知类型,"monitor" 或 "agent"
|
||||
* @param id 目标ID,监控或客户端的ID
|
||||
* @return {Promise<boolean>} 删除是否成功
|
||||
*/
|
||||
export const deleteNotificationSettings = async (
|
||||
type: "monitor" | "agent",
|
||||
id: number
|
||||
): Promise<boolean> => {
|
||||
// 执行删除操作
|
||||
try {
|
||||
await db
|
||||
.delete(notificationSettings)
|
||||
.where(
|
||||
and(
|
||||
eq(notificationSettings.target_type, type),
|
||||
eq(notificationSettings.target_id, id)
|
||||
)
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("[删除通知设置] 删除通知设置失败:", error);
|
||||
throw new Error("删除通知设置失败");
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
@@ -128,6 +128,9 @@ export async function deleteAgentService(agentId: number) {
|
||||
throw new Error("客户端不存在");
|
||||
}
|
||||
|
||||
// 删除客户端通知设置
|
||||
await AgentRepository.deleteNotificationSettings("agent", agent.id);
|
||||
|
||||
// 执行删除客户端
|
||||
await AgentRepository.deleteAgent(agent.id);
|
||||
|
||||
|
||||
@@ -265,7 +265,17 @@ export async function deleteMonitor(id: number) {
|
||||
return { success: false, message: "监控不存在", status: 404 };
|
||||
}
|
||||
|
||||
// 执行删除
|
||||
// 执行通知设置删除
|
||||
const notificationResult = await NotificationService.deleteNotificationSettings(
|
||||
"monitor",
|
||||
id
|
||||
);
|
||||
if (!notificationResult.success) {
|
||||
console.error("删除监控通知设置失败:", notificationResult.message);
|
||||
// 继续执行监控删除,不影响主流程
|
||||
}
|
||||
|
||||
// 执行monitor删除
|
||||
const result = await repositories.deleteMonitor(id);
|
||||
|
||||
if (!result.success) {
|
||||
|
||||
@@ -511,7 +511,7 @@ export async function sendNotification(
|
||||
// 过滤掉不存在的渠道
|
||||
const validChannels = channels.filter(
|
||||
(ch): ch is models.NotificationChannel => ch !== null
|
||||
)
|
||||
);
|
||||
|
||||
console.log(
|
||||
`[发送通知] 有效渠道数量: ${validChannels.length},类型分布:`,
|
||||
@@ -651,7 +651,7 @@ export async function shouldSendNotification(
|
||||
|
||||
// 获取此对象的特定设置
|
||||
const specificSettings = await repositories.getSpecificSettings(type, id);
|
||||
|
||||
|
||||
console.log(
|
||||
`[通知触发检查] 获取到特定设置数量: ${
|
||||
specificSettings ? specificSettings.length : 0
|
||||
@@ -777,3 +777,29 @@ export async function shouldSendNotification(
|
||||
|
||||
return { shouldSend, channels };
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除通知设置
|
||||
* @param type 通知类型
|
||||
* @param id 通知设置ID
|
||||
*/
|
||||
export async function deleteNotificationSettings(
|
||||
type: "monitor" | "agent",
|
||||
id: number
|
||||
): Promise<{ success: boolean; message?: string }> {
|
||||
try {
|
||||
console.log(`[删除通知设置] 开始删除${type}通知设置,ID=${id}`);
|
||||
// 执行删除操作
|
||||
await repositories.deleteNotificationSettings(type, id);
|
||||
} catch (error) {
|
||||
console.error("[删除通知设置] 删除通知设置失败:", error);
|
||||
return {
|
||||
success: false,
|
||||
message: error instanceof Error ? error.message : "删除通知设置失败",
|
||||
};
|
||||
}
|
||||
return {
|
||||
success: true,
|
||||
message: `${type}通知设置删除成功`,
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user