fix: 修复前端页面的一些bug
This commit is contained in:
parent
0a5a6ec4e2
commit
87ff8f44d7
@ -38,6 +38,10 @@ func main() {
|
|||||||
var historicalEnd = flag.String("historical_end", "", "历史数据结束日期(格式YYYY-MM-DD)")
|
var historicalEnd = flag.String("historical_end", "", "历史数据结束日期(格式YYYY-MM-DD)")
|
||||||
// 覆盖风:使用彩云实况替换导出中的风速/风向
|
// 覆盖风:使用彩云实况替换导出中的风速/风向
|
||||||
var useWindOverride = flag.Bool("wind", false, "使用彩云实况覆盖导出CSV中的风速/风向")
|
var useWindOverride = flag.Bool("wind", false, "使用彩云实况覆盖导出CSV中的风速/风向")
|
||||||
|
// 历史CSV导出
|
||||||
|
var exportRangeOnly = flag.Bool("export_range", false, "按日期范围导出10分钟CSV(含ZTD融合),并退出。日期格式支持 YYYY-MM-DD 或 YYYYMMDD")
|
||||||
|
var exportStart = flag.String("export_start", "", "导出起始日期(含),格式 YYYY-MM-DD 或 YYYYMMDD")
|
||||||
|
var exportEnd = flag.String("export_end", "", "导出结束日期(含),格式 YYYY-MM-DD 或 YYYYMMDD")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
// 设置日志
|
// 设置日志
|
||||||
@ -87,6 +91,32 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 历史CSV范围导出
|
||||||
|
if *exportRangeOnly {
|
||||||
|
if *exportStart == "" || *exportEnd == "" {
|
||||||
|
log.Fatalln("export_range 需要提供 --export_start 与 --export_end 日期(YYYY-MM-DD 或 YYYYMMDD)")
|
||||||
|
}
|
||||||
|
var opts tools.ExporterOptions
|
||||||
|
if *useWindOverride {
|
||||||
|
token := os.Getenv("CAIYUN_TOKEN")
|
||||||
|
if token == "" {
|
||||||
|
token = config.GetConfig().Forecast.CaiyunToken
|
||||||
|
}
|
||||||
|
if token == "" {
|
||||||
|
log.Println("警告: 指定了 --wind 但未提供彩云 token,忽略风覆盖")
|
||||||
|
} else {
|
||||||
|
opts.OverrideWindWithCaiyun = true
|
||||||
|
opts.CaiyunToken = token
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exporter := tools.NewExporterWithOptions(opts)
|
||||||
|
if err := exporter.ExportRange(context.Background(), *exportStart, *exportEnd); err != nil {
|
||||||
|
log.Fatalf("export_range 失败: %v", err)
|
||||||
|
}
|
||||||
|
log.Println("export_range 完成")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// 工具:按日期抓取当天0点到当前时间+3小时(两家)
|
// 工具:按日期抓取当天0点到当前时间+3小时(两家)
|
||||||
if *forecastDay != "" {
|
if *forecastDay != "" {
|
||||||
if err := tools.RunForecastFetchForDay(context.Background(), *forecastDay); err != nil {
|
if err := tools.RunForecastFetchForDay(context.Background(), *forecastDay); err != nil {
|
||||||
|
|||||||
@ -317,6 +317,56 @@ func (e *Exporter) exportBucket(ctx context.Context, bucketStart, bucketEnd time
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 导出一个日期范围内的全部10分钟桶(CST),start 与 end 为“日期起止(含)”
|
||||||
|
func (e *Exporter) ExportRange(ctx context.Context, startDate, endDate string) error {
|
||||||
|
// 解析日期,支持 YYYY-MM-DD 或 YYYYMMDD
|
||||||
|
parse := func(s string) (time.Time, error) {
|
||||||
|
if len(s) == 8 {
|
||||||
|
// YYYYMMDD -> YYYY-MM-DD
|
||||||
|
s = s[:4] + "-" + s[4:6] + "-" + s[6:8]
|
||||||
|
}
|
||||||
|
loc := e.loc
|
||||||
|
if loc == nil {
|
||||||
|
loc = time.FixedZone("CST", 8*3600)
|
||||||
|
}
|
||||||
|
return time.ParseInLocation("2006-01-02", s, loc)
|
||||||
|
}
|
||||||
|
|
||||||
|
fromDay, err := parse(startDate)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("起始日期解析失败: %v", err)
|
||||||
|
}
|
||||||
|
toDay, err := parse(endDate)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("结束日期解析失败: %v", err)
|
||||||
|
}
|
||||||
|
if toDay.Before(fromDay) {
|
||||||
|
return fmt.Errorf("结束日期早于起始日期")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 日期起止 -> 时间范围(含):[fromDay 00:00, toDay 23:59:59]
|
||||||
|
from := time.Date(fromDay.Year(), fromDay.Month(), fromDay.Day(), 0, 0, 0, 0, e.loc)
|
||||||
|
to := time.Date(toDay.Year(), toDay.Month(), toDay.Day(), 23, 59, 59, 0, e.loc)
|
||||||
|
|
||||||
|
firstBucket := from.Truncate(10 * time.Minute)
|
||||||
|
lastBucket := to.Truncate(10 * time.Minute)
|
||||||
|
|
||||||
|
for b := firstBucket; !b.After(lastBucket); b = b.Add(10 * time.Minute) {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return ctx.Err()
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
bucketStart := b
|
||||||
|
bucketEnd := b.Add(10 * time.Minute)
|
||||||
|
if err := e.exportBucket(ctx, bucketStart, bucketEnd); err != nil {
|
||||||
|
// 不中断整个范围导出,记录错误继续
|
||||||
|
e.logger.Printf("范围导出: 桶 %s-%s 导出失败: %v", bucketStart.Format("2006-01-02 15:04:05"), bucketEnd.Format("2006-01-02 15:04:05"), err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (e *Exporter) lookupZTD(ctx context.Context, deviceID string, bucketEnd time.Time) string {
|
func (e *Exporter) lookupZTD(ctx context.Context, deviceID string, bucketEnd time.Time) string {
|
||||||
if e.my == nil {
|
if e.my == nil {
|
||||||
return ""
|
return ""
|
||||||
|
|||||||
@ -8,13 +8,18 @@ const WeatherTable = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const showPastEl = document.getElementById('showPastForecast');
|
const showPastEl = document.getElementById('showPastForecast');
|
||||||
const nowTs = Date.now();
|
const endInput = document.getElementById('endDate')?.value;
|
||||||
const future3hTs = nowTs + 3 * 60 * 60 * 1000;
|
let endTs = Date.now();
|
||||||
|
if (endInput) {
|
||||||
|
const d = new Date(endInput);
|
||||||
|
if (!isNaN(d)) endTs = d.getTime();
|
||||||
|
}
|
||||||
|
const future3hTs = endTs + 3 * 60 * 60 * 1000;
|
||||||
const showPast = !!(showPastEl && showPastEl.checked);
|
const showPast = !!(showPastEl && showPastEl.checked);
|
||||||
const displayedForecast = forecastData.filter(item => {
|
const displayedForecast = forecastData.filter(item => {
|
||||||
const t = new Date(item.date_time).getTime();
|
const t = new Date(item.date_time).getTime();
|
||||||
const isFuture3h = t > nowTs && t <= future3hTs;
|
const isFuture3h = t > endTs && t <= future3hTs;
|
||||||
const isPast = t <= nowTs;
|
const isPast = t <= endTs;
|
||||||
return isFuture3h || (showPast && isPast);
|
return isFuture3h || (showPast && isPast);
|
||||||
});
|
});
|
||||||
const taggedHistory = historyData.map(item => ({ ...item, __source: '实测' }));
|
const taggedHistory = historyData.map(item => ({ ...item, __source: '实测' }));
|
||||||
|
|||||||
@ -533,7 +533,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="table-container" id="tableContainer">
|
<div class="table-container" id="tableContainer">
|
||||||
<div id="forecastToggleContainer" style="padding: 8px 12px; font-size: 12px; color: #666; display: none; display: flex; justify-content: center; align-items: center;">
|
<div id="forecastToggleContainer" style="padding: 8px 12px;font-size: 12px;color: #666;display: none;display: flex;justify-content: flex-start;align-items: center;align-content: center;">
|
||||||
<label style="display: flex; align-items: flex-start; gap: 5px;">
|
<label style="display: flex; align-items: flex-start; gap: 5px;">
|
||||||
<input type="checkbox" id="showPastForecast" style="vertical-align: middle;" x-model="showPastForecast" @change="window.WeatherTable.display(window.WeatherApp.cachedHistoryData, window.WeatherApp.cachedForecastData)">
|
<input type="checkbox" id="showPastForecast" style="vertical-align: middle;" x-model="showPastForecast" @change="window.WeatherTable.display(window.WeatherApp.cachedHistoryData, window.WeatherApp.cachedForecastData)">
|
||||||
显示历史预报
|
显示历史预报
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user