chore: snapshot production code before Apple Design UI refinement

This commit is contained in:
lingniu
2026-09-17 18:05:57 +08:00
parent 9f0a87f49e
commit f7e7176f88
90 changed files with 8990 additions and 328 deletions
@@ -0,0 +1,133 @@
package main
import (
"context"
"database/sql"
"encoding/json"
"flag"
"fmt"
_ "github.com/go-sql-driver/mysql"
_ "github.com/taosdata/driver-go/v3/taosWS"
"lingniu/vehicle-data-platform/apps/api/internal/config"
"lingniu/vehicle-data-platform/apps/api/internal/dailygeo"
"log"
"os"
"os/signal"
"syscall"
"time"
)
func main() {
if e := run(); e != nil {
log.Fatal(e)
}
}
func run() error {
mode := flag.String("mode", "status", "status, backfill, resolve, or live")
from := flag.String("from", "", "first historical date, defaults to first hydrogen day")
to := flag.String("to", "", "last historical date, defaults to yesterday")
concurrency := flag.Int("concurrency", 3, "maximum concurrent geocoding requests (1-8)")
flag.Parse()
cfg := config.Load()
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer cancel()
db, e := sql.Open("mysql", cfg.MySQLDSN)
if e != nil {
return e
}
defer db.Close()
db.SetMaxOpenConns(12)
if *from == "" {
if e = db.QueryRowContext(ctx, `SELECT COALESCE(DATE_FORMAT(MIN(stat_date),'%Y-%m-%d'),'') FROM vehicle_open_daily_energy WHERE energy_type='HYDROGEN'`).Scan(from); e != nil {
return e
}
}
if *to == "" {
*to = time.Now().In(dailygeo.Shanghai).AddDate(0, 0, -1).Format("2006-01-02")
}
first, e := time.ParseInLocation("2006-01-02", *from, dailygeo.Shanghai)
if e != nil {
return e
}
last, e := time.ParseInLocation("2006-01-02", *to, dailygeo.Shanghai)
if e != nil {
return e
}
if first.After(last) {
return fmt.Errorf("invalid date range")
}
if *mode == "status" {
return printStatus(ctx, db, *from, *to)
}
if cfg.AMapAPIKey == "" {
return fmt.Errorf("AMAP_API_KEY required")
}
td, e := sql.Open(cfg.TDengineDriver, cfg.TDengineDSN)
if e != nil {
return e
}
defer td.Close()
td.SetMaxOpenConns(2)
w := dailygeo.New(db, td, cfg.TDengineDatabase, &dailygeo.AMap{Key: cfg.AMapAPIKey})
w.Concurrency = *concurrency
if *mode == "live" {
w.Run(ctx)
return ctx.Err()
}
if *mode != "backfill" && *mode != "resolve" {
return fmt.Errorf("invalid mode")
}
return w.WithLock(ctx, "vehicle_daily_geography_backfill", func() error {
if *mode == "backfill" {
for d := first; !d.After(last); d = d.AddDate(0, 0, 1) {
rctx, c := context.WithTimeout(ctx, 90*time.Second)
n, e := w.RefreshDay(rctx, d.Format("2006-01-02"))
c()
if e != nil {
return e
}
log.Printf("daily_geography_seed date=%s points=%d", d.Format("2006-01-02"), n)
}
}
for {
n, failed, e := w.ResolvePending(ctx, *from, *to, 1000)
log.Printf("daily_geography_batch resolved=%d failed=%d error=%v", n, failed, e)
if ctx.Err() != nil {
return ctx.Err()
}
if e != nil && failed == 0 {
return e
}
if n+failed == 0 {
break
}
}
return printStatus(ctx, db, *from, *to)
})
}
func printStatus(ctx context.Context, db *sql.DB, from, to string) error {
rows, e := db.QueryContext(ctx, `SELECT status,COUNT(*) FROM vehicle_daily_geography WHERE stat_date BETWEEN ? AND ? GROUP BY status`, from, to)
if e != nil {
return e
}
defer rows.Close()
counts := map[string]int{}
for rows.Next() {
var s string
var n int
if e = rows.Scan(&s, &n); e != nil {
return e
}
counts[s] = n
}
if e = rows.Err(); e != nil {
return e
}
rows.Close()
var missing int
e = db.QueryRowContext(ctx, `SELECT COUNT(*) FROM vehicle_open_daily_energy h LEFT JOIN vehicle_daily_geography g ON g.vin=h.vin COLLATE utf8mb4_unicode_ci AND g.stat_date=h.stat_date WHERE h.energy_type='HYDROGEN' AND h.stat_date BETWEEN ? AND ? AND g.vin IS NULL`, from, to).Scan(&missing)
if e != nil {
return e
}
return json.NewEncoder(os.Stdout).Encode(map[string]any{"from": from, "to": to, "counts": counts, "hydrogenDaysMissing": missing})
}