package render import ( "fmt" "git.5iot.com/iotlcm-public/iotlcm-bot/internal/archive" "sort" "strings" ) func supplyBlock(a archive.RunArchive) string { if !isTrafficUsage(a.Run.Operation) || a.Run.SyncType == "replay" { return "" } s, present := a.Run.Supply() if !present { return "" } if s == nil { return "供料观测:不可用(遥测格式非法);业务结果不受影响" } status := []string{} if s.Partial { status = append(status, "partial") } if s.Truncated { status = append(status, "truncated") } if len(status) == 0 { status = append(status, "完整") } unknown, unconfirmed := s.Summary.UnknownMS, s.Summary.UnconfirmedMS lines := []string{"供料观测(Run 首轮扫描窗口,约1秒分辨率,时间为采样估计)", fmt.Sprintf("目标 %d · 有效 %d · 确认缺料 %d · unknown 通道 %d", s.Summary.Targets, s.Summary.Valid, s.Summary.Confirmed, s.Summary.Unknown), fmt.Sprintf("最长中断 %.1f秒 · 累计 %.1f通道秒(允许通道重叠)", float64(s.Summary.LongestMS)/1000, float64(s.Summary.TotalMS)/1000), fmt.Sprintf("待确认空闲 %.1f通道秒 · unknown %.1f通道秒 · %s", float64(unconfirmed)/1000, float64(unknown)/1000, strings.Join(status, " / "))} if s.Truncated { lines = append(lines, "明细已截断;Run摘要覆盖全部目标,归档保留最长等待前100通道") } if s.Summary.Confirmed == 0 && !s.Partial && !s.Truncated && s.Summary.Unknown == 0 && unconfirmed == 0 && s.Summary.Valid == s.Summary.Targets { lines = append(lines, "约1秒分辨率下未发现确认缺料") } channels := append([]archive.SupplyChannel(nil), s.Channels...) sort.Slice(channels, func(i, j int) bool { a, b := channels[i], channels[j] av, bv := max(a.Startup.LongestMS, a.Confirmed.LongestMS), max(b.Startup.LongestMS, b.Confirmed.LongestMS) if av == bv { return a.Key < b.Key } return av > bv }) for _, c := range channels[:min(5, len(channels))] { longest := max(c.Startup.LongestMS, c.Confirmed.LongestMS) if longest == 0 { continue } phase := "未记录" var phaseMS int64 for k, v := range c.Stages { if v > phaseMS || (v == phaseMS && k < phase) { phase, phaseMS = k, v } } signal := "" if longest >= 5000 { signal = "(≥5秒排查信号)" } lines = append(lines, fmt.Sprintf("%s:最长 %.1f秒%s;启动 %.1f秒 / 后续 %.1f秒;同期主要生产者阶段 %s %.1f秒", c.Key, float64(longest)/1000, signal, float64(c.Startup.TotalMS)/1000, float64(c.Confirmed.TotalMS)/1000, phase, float64(phaseMS)/1000)) } lines = append(lines, "小于采样间隔的中断可能漏检;同期阶段不证明因果,5秒提示不构成SLA。完整明细见归档。") return strings.Join(lines, "\n") }