00c4c13283
build / build (push) Successful in 1m19s
列表正文改为按需读取;保留完整导出、版本隔离和有效标签筛选。 验证:前端全量、Go全量及隔离PG全mirror竞态通过;覆盖首批回调、续载失败与筛选分页。
98 lines
4.0 KiB
Go
98 lines
4.0 KiB
Go
package qaopsmirror
|
|
|
|
import (
|
|
"knowledge-governance/internal/dobotaiops"
|
|
"knowledge-governance/internal/qaopsquality"
|
|
"time"
|
|
)
|
|
|
|
type DashboardCount struct {
|
|
Label string `json:"label"`
|
|
Count int `json:"count"`
|
|
}
|
|
type DashboardDaily struct {
|
|
Date string `json:"date"`
|
|
Count int `json:"count"`
|
|
}
|
|
type DashboardReported struct {
|
|
Week string `json:"week"`
|
|
WeekStart time.Time `json:"week_start"`
|
|
WeekEnd time.Time `json:"week_end"`
|
|
CoveragePercent float64 `json:"coverage_percent"`
|
|
CorrectnessPercent float64 `json:"correctness_percent"`
|
|
Source string `json:"source"`
|
|
}
|
|
|
|
type DashboardFrozen struct {
|
|
WeekStart time.Time `json:"week_start"`
|
|
WeekEnd time.Time `json:"week_end"`
|
|
FrozenAt *time.Time `json:"frozen_at"`
|
|
PolicyVersion string `json:"policy_version"`
|
|
Records int `json:"records"`
|
|
Coverage qaopsquality.Rate `json:"coverage"`
|
|
Correctness qaopsquality.Rate `json:"correctness"`
|
|
}
|
|
type DashboardRegion struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
Questions int `json:"questions"`
|
|
Users *int `json:"users"`
|
|
RosterPeople *int `json:"roster_people"`
|
|
Frequency *float64 `json:"frequency"`
|
|
UsageCoverage qaopsquality.Rate `json:"usage_coverage"`
|
|
}
|
|
type Dashboard struct {
|
|
Start time.Time `json:"start"`
|
|
End time.Time `json:"end"`
|
|
Keyword string `json:"keyword"`
|
|
Filters map[string]string `json:"filters,omitempty"`
|
|
AsOf time.Time `json:"as_of"`
|
|
LocalRevision int64 `json:"local_revision"`
|
|
Organization dobotaiops.OrganizationVersion `json:"organization"`
|
|
TotalIssues int `json:"total_issues"`
|
|
NewThisWeek int `json:"new_this_week"`
|
|
WeekStart time.Time `json:"week_start"`
|
|
MonthStart time.Time `json:"month_start"`
|
|
Quality qaopsquality.Summary `json:"quality"`
|
|
IssueTypes []DashboardCount `json:"issue_types"`
|
|
Products []DashboardCount `json:"products"`
|
|
Daily []DashboardDaily `json:"daily"`
|
|
Regions []DashboardRegion `json:"regions"`
|
|
FrozenWeeks []DashboardFrozen `json:"frozen_weeks"`
|
|
ReportedWeeks []DashboardReported `json:"reported_weeks"`
|
|
CumulativeWeeks []DashboardCumulative `json:"cumulative_weeks"`
|
|
QualityPeriod *DashboardQualityPeriod `json:"quality_period,omitempty"`
|
|
MonthlyQuality *DashboardStrictQuality `json:"monthly_quality,omitempty"`
|
|
CalendarMonths []DashboardMonth `json:"calendar_months"`
|
|
}
|
|
|
|
var dashboardLocation = time.FixedZone("Asia/Shanghai", 8*60*60)
|
|
|
|
func dashboardDay(at time.Time) time.Time {
|
|
t := at.In(dashboardLocation)
|
|
return time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, dashboardLocation)
|
|
}
|
|
func dashboardWeek(at time.Time) time.Time {
|
|
d := dashboardDay(at)
|
|
return d.AddDate(0, 0, -((int(d.Weekday()) + 6) % 7))
|
|
}
|
|
func dashboardPeriods(end time.Time) (time.Time, time.Time) {
|
|
cutoff := end.Add(-time.Nanosecond).In(dashboardLocation)
|
|
return time.Date(cutoff.Year(), cutoff.Month(), 1, 0, 0, 0, 0, dashboardLocation), dashboardWeek(cutoff)
|
|
}
|
|
func dashboardFrozenSeries(first, end time.Time, snapshots map[string]DashboardFrozen) []DashboardFrozen {
|
|
out := []DashboardFrozen{}
|
|
if first.IsZero() || !first.Before(end) {
|
|
return out
|
|
}
|
|
for at := dashboardWeek(first); at.Before(end) && len(out) < 5200; at = at.AddDate(0, 0, 7) {
|
|
key := at.Format("2006-01-02")
|
|
point, ok := snapshots[key]
|
|
if !ok {
|
|
point = DashboardFrozen{WeekStart: at, WeekEnd: at.AddDate(0, 0, 7)}
|
|
}
|
|
out = append(out, point)
|
|
}
|
|
return out
|
|
}
|