// 仅读取 build 后的报告 JSON,本地渲染 qiye.html(不执行 BuildReportFromRawSources)。
//
// go run ./cmd/qygl_report_preview -in resources/dev-report/built.json
// go run ./cmd/qygl_report_preview -in built.json -addr :8899 -watch
//
// 每次打开/刷新页面都会重新读取 -in 文件;加 -watch 后保存 JSON 会自动刷新浏览器。
package main
import (
"bytes"
"encoding/json"
"flag"
"fmt"
"html/template"
"log"
"net/http"
"os"
"path/filepath"
)
func parseBuiltReport(data []byte) (map[string]interface{}, error) {
var root map[string]interface{}
if err := json.Unmarshal(data, &root); err != nil {
return nil, err
}
if _, ok := root["jiguangFull"]; ok {
return nil, fmt.Errorf("检测到 raw 字段 jiguangFull,请先执行: go run ./cmd/qygl_report_build -in -out built.json")
}
if k, _ := root["kind"].(string); k == "full" {
r, ok := root["report"].(map[string]interface{})
if !ok {
return nil, fmt.Errorf("kind=full 时缺少 report 对象")
}
return r, nil
}
if r, ok := root["report"].(map[string]interface{}); ok {
return r, nil
}
if root["entName"] != nil || root["basic"] != nil || root["reportTime"] != nil {
return root, nil
}
return nil, fmt.Errorf("不是有效的 build 后报告(根级应有 entName、basic、reportTime 之一,或 {\"report\":{...}} / kind=full)")
}
func fileVersionTag(path string) (string, error) {
st, err := os.Stat(path)
if err != nil {
return "", err
}
return fmt.Sprintf("%d-%d", st.ModTime().UnixNano(), st.Size()), nil
}
func renderPage(tmpl *template.Template, report map[string]interface{}, injectLive bool) ([]byte, error) {
reportBytes, err := json.Marshal(report)
if err != nil {
return nil, err
}
var buf bytes.Buffer
if err := tmpl.Execute(&buf, map[string]interface{}{
"ReportJSON": template.JS(reportBytes),
}); err != nil {
return nil, err
}
b := buf.Bytes()
if !injectLive {
return b, nil
}
script := ``
closing := []byte("