lfqian commited on
Commit
2447a78
·
1 Parent(s): a69c83a

Fix dateBounds update: remove early pagination stop and add periodic dateBounds refresh

Browse files
src/lib/dataService.js CHANGED
@@ -191,52 +191,73 @@ class DataService {
191
  console.log(`[DataService] Page ${pageCount}: ${pageData.length} rows, date range: ${pageDates[0]} to ${lastFetchedDate}`)
192
  }
193
 
194
- // If we got less than pageSize, we're done
195
  if (pageData.length < pageSize) {
196
  console.log(`[DataService] Last page reached (got ${pageData.length} rows, expected ${pageSize})`)
197
  break
198
  }
199
 
200
- // If we've reached or passed the max date, we're done
201
- if (dbMaxDate && lastFetchedDate) {
202
- const lastFetchedDateStr = typeof lastFetchedDate === 'string' ? lastFetchedDate.split('T')[0] : lastFetchedDate
203
- const dbMaxDateStr = typeof dbMaxDate === 'string' ? dbMaxDate.split('T')[0] : dbMaxDate
204
- if (lastFetchedDateStr >= dbMaxDateStr) {
205
- console.log(`[DataService] Reached target max date ${dbMaxDateStr}, stopping`)
206
- break
207
- }
208
- }
209
-
210
  from += pageSize
211
  }
212
 
213
  // Log the final date range
214
  if (all.length > 0) {
215
  const dates = all.map(r => r && r.date).filter(Boolean).sort()
216
- console.log(`[DataService] Total fetched: ${all.length} rows across ${pageCount} pages, date range: ${dates[0]} to ${dates[dates.length - 1]}`)
 
 
217
  console.log(`[DataService] Last 10 dates:`, dates.slice(-10))
218
 
219
- // Verify we got the max date
220
- const fetchedMaxDate = dates[dates.length - 1]
221
  if (dbMaxDate) {
222
  const fetchedMaxDateStr = typeof fetchedMaxDate === 'string' ? fetchedMaxDate.split('T')[0] : fetchedMaxDate
223
  const dbMaxDateStr = typeof dbMaxDate === 'string' ? dbMaxDate.split('T')[0] : dbMaxDate
224
  console.log(`[DataService] Verification: DB max date = ${dbMaxDateStr}, Fetched max date = ${fetchedMaxDateStr}`)
225
- if (fetchedMaxDateStr !== dbMaxDateStr) {
226
- console.error(`[DataService] ERROR: Still missing data! DB has ${dbMaxDateStr} but we only fetched up to ${fetchedMaxDateStr}`)
227
- // Try one more page to see if we can get the missing data
228
- console.log(`[DataService] Attempting to fetch one more page starting from ${from}...`)
229
- const { data: extraData, error: extraError } = await supabase
 
 
 
 
 
 
 
230
  .from('trading_decisions')
231
  .select('id, agent_name, asset, model, date, price, recommended_action, news_count, sentiment, created_at, updated_at')
 
 
232
  .order('date', { ascending: true })
233
- .range(from, from + pageSize - 1)
234
- if (!extraError && extraData && extraData.length > 0) {
235
- console.log(`[DataService] Extra page fetched: ${extraData.length} rows`)
236
- all.push(...extraData)
237
- const newDates = all.map(r => r && r.date).filter(Boolean).sort()
238
- console.log(`[DataService] After extra page: date range: ${newDates[0]} to ${newDates[newDates.length - 1]}`)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
239
  }
 
 
240
  }
241
  }
242
  } else {
@@ -593,6 +614,59 @@ class DataService {
593
  return this.load(true)
594
  }
595
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
596
  /**
597
  * 获取当前状态
598
  */
 
191
  console.log(`[DataService] Page ${pageCount}: ${pageData.length} rows, date range: ${pageDates[0]} to ${lastFetchedDate}`)
192
  }
193
 
194
+ // If we got less than pageSize, we're done (no more data)
195
  if (pageData.length < pageSize) {
196
  console.log(`[DataService] Last page reached (got ${pageData.length} rows, expected ${pageSize})`)
197
  break
198
  }
199
 
200
+ // Continue to next page - don't stop early based on date comparison
201
+ // because pagination with order('date', ascending: true) might have
202
+ // multiple pages with the same date, and we need to fetch all pages
 
 
 
 
 
 
 
203
  from += pageSize
204
  }
205
 
206
  // Log the final date range
207
  if (all.length > 0) {
208
  const dates = all.map(r => r && r.date).filter(Boolean).sort()
209
+ const fetchedMinDate = dates[0]
210
+ const fetchedMaxDate = dates[dates.length - 1]
211
+ console.log(`[DataService] Total fetched: ${all.length} rows across ${pageCount} pages, date range: ${fetchedMinDate} to ${fetchedMaxDate}`)
212
  console.log(`[DataService] Last 10 dates:`, dates.slice(-10))
213
 
214
+ // Verify we got the max date - if not, fetch missing data by date range
 
215
  if (dbMaxDate) {
216
  const fetchedMaxDateStr = typeof fetchedMaxDate === 'string' ? fetchedMaxDate.split('T')[0] : fetchedMaxDate
217
  const dbMaxDateStr = typeof dbMaxDate === 'string' ? dbMaxDate.split('T')[0] : dbMaxDate
218
  console.log(`[DataService] Verification: DB max date = ${dbMaxDateStr}, Fetched max date = ${fetchedMaxDateStr}`)
219
+
220
+ if (fetchedMaxDateStr !== dbMaxDateStr && fetchedMaxDateStr < dbMaxDateStr) {
221
+ console.warn(`[DataService] Missing data detected! DB has ${dbMaxDateStr} but we only fetched up to ${fetchedMaxDateStr}`)
222
+ console.log(`[DataService] Fetching missing data from ${fetchedMaxDateStr} to ${dbMaxDateStr}...`)
223
+
224
+ // Fetch all data from the day after fetchedMaxDate to dbMaxDate
225
+ // Use gte (greater than or equal) to include the next day
226
+ const nextDay = new Date(fetchedMaxDateStr)
227
+ nextDay.setUTCDate(nextDay.getUTCDate() + 1)
228
+ const nextDayStr = nextDay.toISOString().split('T')[0]
229
+
230
+ const { data: missingData, error: missingError } = await supabase
231
  .from('trading_decisions')
232
  .select('id, agent_name, asset, model, date, price, recommended_action, news_count, sentiment, created_at, updated_at')
233
+ .gte('date', nextDayStr)
234
+ .lte('date', dbMaxDateStr)
235
  .order('date', { ascending: true })
236
+
237
+ if (!missingError && missingData && missingData.length > 0) {
238
+ console.log(`[DataService] Fetched ${missingData.length} missing rows`)
239
+ // Merge missing data, avoiding duplicates by id
240
+ const existingIds = new Set(all.map(r => r.id))
241
+ const newRows = missingData.filter(r => !existingIds.has(r.id))
242
+ all.push(...newRows)
243
+ console.log(`[DataService] Added ${newRows.length} new rows (${missingData.length - newRows.length} duplicates skipped)`)
244
+
245
+ // Re-sort all data by date
246
+ all.sort((a, b) => {
247
+ const dateA = typeof a.date === 'string' ? a.date.split('T')[0] : a.date
248
+ const dateB = typeof b.date === 'string' ? b.date.split('T')[0] : b.date
249
+ return dateA > dateB ? 1 : (dateA < dateB ? -1 : 0)
250
+ })
251
+
252
+ const finalDates = all.map(r => r && r.date).filter(Boolean).sort()
253
+ console.log(`[DataService] After fetching missing data: ${all.length} total rows, date range: ${finalDates[0]} to ${finalDates[finalDates.length - 1]}`)
254
+ } else if (missingError) {
255
+ console.error(`[DataService] Failed to fetch missing data:`, missingError)
256
+ } else {
257
+ console.warn(`[DataService] No missing data found (this might indicate a data inconsistency)`)
258
  }
259
+ } else if (fetchedMaxDateStr === dbMaxDateStr) {
260
+ console.log(`[DataService] ✓ Successfully fetched all data up to ${dbMaxDateStr}`)
261
  }
262
  }
263
  } else {
 
614
  return this.load(true)
615
  }
616
 
617
+ /**
618
+ * 更新 dateBounds,直接查询数据库的最新日期
619
+ * 这个方法可以独立调用,不需要重新加载所有数据
620
+ */
621
+ async updateDateBounds() {
622
+ try {
623
+ // 查询数据库的最小和最大日期
624
+ const [minDateResult, maxDateResult] = await Promise.all([
625
+ supabase
626
+ .from('trading_decisions')
627
+ .select('date')
628
+ .order('date', { ascending: true })
629
+ .limit(1),
630
+ supabase
631
+ .from('trading_decisions')
632
+ .select('date')
633
+ .order('date', { ascending: false })
634
+ .limit(1)
635
+ ])
636
+
637
+ let dbMinDate = null
638
+ let dbMaxDate = null
639
+
640
+ if (!minDateResult.error && minDateResult.data && minDateResult.data.length > 0) {
641
+ dbMinDate = minDateResult.data[0].date
642
+ }
643
+ if (!maxDateResult.error && maxDateResult.data && maxDateResult.data.length > 0) {
644
+ dbMaxDate = maxDateResult.data[0].date
645
+ }
646
+
647
+ // 如果查询到了新的日期,更新 dateBounds
648
+ if (dbMinDate || dbMaxDate) {
649
+ const oldMax = this.dateBounds.max ? this.dateBounds.max.toISOString().split('T')[0] : null
650
+ const newMax = dbMaxDate ? (typeof dbMaxDate === 'string' ? dbMaxDate.split('T')[0] : dbMaxDate) : null
651
+
652
+ // 只有当新日期确实更新时才更新
653
+ if (newMax && (!oldMax || newMax > oldMax)) {
654
+ this.dateBounds = {
655
+ min: dbMinDate ? new Date(dbMinDate) : this.dateBounds.min,
656
+ max: dbMaxDate ? new Date(dbMaxDate) : this.dateBounds.max
657
+ }
658
+ console.log(`[DataService] updateDateBounds: Updated dateBounds to min = ${this.dateBounds.min?.toISOString().split('T')[0]}, max = ${this.dateBounds.max?.toISOString().split('T')[0]}`)
659
+ // 通知所有订阅者
660
+ this._notify()
661
+ } else if (newMax && oldMax && newMax === oldMax) {
662
+ console.log(`[DataService] updateDateBounds: Date bounds already up to date (max = ${newMax})`)
663
+ }
664
+ }
665
+ } catch (e) {
666
+ console.error('[DataService] Error updating dateBounds:', e)
667
+ }
668
+ }
669
+
670
  /**
671
  * 获取当前状态
672
  */
src/views/LeaderboardView.vue CHANGED
@@ -118,7 +118,8 @@ export default {
118
  updatedClickCount: 0,
119
  asset: '',
120
  drawerVisible: false,
121
- unsubscribe: null
 
122
  }
123
  },
124
  watch: {
@@ -320,6 +321,18 @@ export default {
320
  if (!dataService.loaded && !dataService.loading) {
321
  dataService.load()
322
  }
 
 
 
 
 
 
 
 
 
 
 
 
323
  },
324
  beforeUnmount() {
325
  // 取消订阅
@@ -327,6 +340,11 @@ export default {
327
  this.unsubscribe()
328
  this.unsubscribe = null
329
  }
 
 
 
 
 
330
  }
331
  }
332
  </script>
 
118
  updatedClickCount: 0,
119
  asset: '',
120
  drawerVisible: false,
121
+ unsubscribe: null,
122
+ dateBoundsUpdateTimer: null
123
  }
124
  },
125
  watch: {
 
321
  if (!dataService.loaded && !dataService.loading) {
322
  dataService.load()
323
  }
324
+
325
+ // 定期更新 dateBounds(每30秒检查一次数据库的最新日期)
326
+ this.dateBoundsUpdateTimer = setInterval(() => {
327
+ dataService.updateDateBounds().catch(e => {
328
+ console.error('[LeaderboardView] Error updating dateBounds:', e)
329
+ })
330
+ }, 30000) // 30秒
331
+
332
+ // 组件挂载后立即更新一次
333
+ dataService.updateDateBounds().catch(e => {
334
+ console.error('[LeaderboardView] Error updating dateBounds on mount:', e)
335
+ })
336
  },
337
  beforeUnmount() {
338
  // 取消订阅
 
340
  this.unsubscribe()
341
  this.unsubscribe = null
342
  }
343
+ // 清除定时器
344
+ if (this.dateBoundsUpdateTimer) {
345
+ clearInterval(this.dateBoundsUpdateTimer)
346
+ this.dateBoundsUpdateTimer = null
347
+ }
348
  }
349
  }
350
  </script>