feat: 周报 metadata 扩展到 16 字段,抽取 buildWeeklyMetadata 辅助函数
This commit is contained in:
parent
e5bdf61cce
commit
a5f19ebeda
|
|
@ -88,6 +88,7 @@ export async function collectWeeklyReportData(
|
||||||
currentStatus: t.current_status,
|
currentStatus: t.current_status,
|
||||||
isResolved,
|
isResolved,
|
||||||
steps,
|
steps,
|
||||||
|
availability: t.availability,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -166,6 +167,60 @@ export async function collectWeeklyReportData(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 从采集数据构建 metadata JSON */
|
||||||
|
export function buildWeeklyMetadata(data: WeeklyReportData): string {
|
||||||
|
const faultTickets = [...data.gpuFaultTickets, ...data.storageFaultTickets]
|
||||||
|
const resolvedTickets = faultTickets.filter(t => t.isResolved)
|
||||||
|
|
||||||
|
const resolvedCount = resolvedTickets.length
|
||||||
|
|
||||||
|
const durations = resolvedTickets
|
||||||
|
.map(t => {
|
||||||
|
if (!t.closeTime) return 0
|
||||||
|
const assign = new Date(t.assignTime).getTime()
|
||||||
|
const close = new Date(t.closeTime).getTime()
|
||||||
|
return Math.round((close - assign) / 60000)
|
||||||
|
})
|
||||||
|
.filter(d => d > 0)
|
||||||
|
const avgDurationMinutes = durations.length > 0
|
||||||
|
? Math.round(durations.reduce((s, d) => s + d, 0) / durations.length)
|
||||||
|
: 0
|
||||||
|
|
||||||
|
const ongoingCount = data.pendingCount
|
||||||
|
|
||||||
|
const faultTicketCount = data.totalFaultCount
|
||||||
|
|
||||||
|
const affectedDeviceIps = new Set(faultTickets.map(t => t.deviceIp))
|
||||||
|
const affectedDeviceCount = affectedDeviceIps.size
|
||||||
|
|
||||||
|
const availabilities = faultTickets
|
||||||
|
.map(t => t.availability)
|
||||||
|
.filter((a): a is number => a !== null && a !== undefined)
|
||||||
|
const avgAvailability = availabilities.length > 0
|
||||||
|
? Math.round(availabilities.reduce((s, v) => s + v, 0) / availabilities.length * 10000) / 100
|
||||||
|
: 100
|
||||||
|
|
||||||
|
const reportLabel = `图灵IT基础设施运营周报(${data.weekLabel})`
|
||||||
|
|
||||||
|
return JSON.stringify({
|
||||||
|
gpuCount: data.gpuTotal,
|
||||||
|
storageCount: data.storageTotal,
|
||||||
|
totalTickets: data.gpuFaultTickets.length + data.storageFaultTickets.length + data.otherTickets.length,
|
||||||
|
gpuFaultCount: data.gpuFaultTickets.length,
|
||||||
|
storageFaultCount: data.storageFaultTickets.length,
|
||||||
|
otherTicketCount: data.otherTickets.length,
|
||||||
|
avgAvailability,
|
||||||
|
resolvedCount,
|
||||||
|
avgDurationMinutes,
|
||||||
|
ongoingCount,
|
||||||
|
faultTicketCount,
|
||||||
|
affectedDeviceCount,
|
||||||
|
faultFreeDays: null,
|
||||||
|
availabilityDetails: null,
|
||||||
|
reportLabel,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/** 异步生成周报 */
|
/** 异步生成周报 */
|
||||||
export async function generateWeeklyReport(reportId: number): Promise<void> {
|
export async function generateWeeklyReport(reportId: number): Promise<void> {
|
||||||
const db = getDb()
|
const db = getDb()
|
||||||
|
|
@ -185,14 +240,7 @@ export async function generateWeeklyReport(reportId: number): Promise<void> {
|
||||||
const filePath = path.join(REPORTS_DIR, fileName)
|
const filePath = path.join(REPORTS_DIR, fileName)
|
||||||
fs.writeFileSync(filePath, buffer)
|
fs.writeFileSync(filePath, buffer)
|
||||||
|
|
||||||
const metadata = JSON.stringify({
|
const metadata = buildWeeklyMetadata(data)
|
||||||
gpuCount: data.gpuTotal,
|
|
||||||
storageCount: data.storageTotal,
|
|
||||||
totalTickets: data.gpuFaultTickets.length + data.storageFaultTickets.length + data.otherTickets.length,
|
|
||||||
gpuFaultCount: data.gpuFaultTickets.length,
|
|
||||||
storageFaultCount: data.storageFaultTickets.length,
|
|
||||||
otherTicketCount: data.otherTickets.length,
|
|
||||||
})
|
|
||||||
|
|
||||||
db.prepare(
|
db.prepare(
|
||||||
"UPDATE reports SET status = 'completed', file_path = ?, file_name = ?, metadata = ? WHERE id = ?"
|
"UPDATE reports SET status = 'completed', file_path = ?, file_name = ?, metadata = ? WHERE id = ?"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue