(route: RouteLocationNormalizedLoaded, router: Router, options: UseTimeSelectOptions)
| 28 | } |
| 29 | |
| 30 | export function useTimeSelect(route: RouteLocationNormalizedLoaded, router: Router, options: UseTimeSelectOptions) { |
| 31 | const { activeTab, isInitialLoad, currentSessionId, onTimeRangeChange } = options |
| 32 | |
| 33 | // ==================== 核心状态 ==================== |
| 34 | |
| 35 | /** TimeSelect v-model 绑定值 */ |
| 36 | const timeRangeValue = ref<TimeRangeValue | null>(null) |
| 37 | |
| 38 | /** 完整时间范围(由 TimeSelect 通过 emit 设置) */ |
| 39 | const fullTimeRange = ref<{ start: number; end: number } | null>(null) |
| 40 | |
| 41 | /** 可选年份列表(由 TimeSelect 通过 emit 设置,group-chat 的 ViewTab 需要) */ |
| 42 | const availableYears = ref<number[]>([]) |
| 43 | |
| 44 | // ==================== 派生计算 ==================== |
| 45 | |
| 46 | /** 时间过滤参数(用于 API 调用) */ |
| 47 | const timeFilter = computed(() => { |
| 48 | const v = timeRangeValue.value |
| 49 | if (!v) return undefined |
| 50 | return { startTs: v.startTs, endTs: v.endTs } |
| 51 | }) |
| 52 | |
| 53 | /** Tab 内容 key(确保时间筛选切换时组件能正确刷新) */ |
| 54 | const timeFilterKey = computed(() => { |
| 55 | const v = timeRangeValue.value |
| 56 | if (!v) return 'init' |
| 57 | return `${v.startTs}-${v.endTs}` |
| 58 | }) |
| 59 | |
| 60 | /** 用于 OverviewTab / ViewTab 的 selectedYear(null=全部,number=指定年份) */ |
| 61 | const selectedYearForOverview = computed(() => { |
| 62 | const v = timeRangeValue.value |
| 63 | if (!v || v.isFullRange) return null |
| 64 | return new Date(v.startTs * 1000).getFullYear() |
| 65 | }) |
| 66 | |
| 67 | /** |
| 68 | * 从 URL query 构建 TimeSelect 初始状态。 |
| 69 | * 优先级:URL 参数 > 缓存(上次用户设置)> 默认值(最近一年) |
| 70 | */ |
| 71 | const initialTimeState = computed<Partial<TimeSelectState>>(() => { |
| 72 | const q = route.query |
| 73 | const m = q.timeMode as TimeSelectMode | undefined |
| 74 | if (m) { |
| 75 | return { |
| 76 | mode: m, |
| 77 | recentDays: q.timeDays ? Number(q.timeDays) : undefined, |
| 78 | year: q.timeYear ? Number(q.timeYear) : undefined, |
| 79 | quarterYear: q.timeYear ? Number(q.timeYear) : undefined, |
| 80 | quarter: q.timeQuarter ? Number(q.timeQuarter) : undefined, |
| 81 | customStart: (q.timeStart as string) || undefined, |
| 82 | customEnd: (q.timeEnd as string) || undefined, |
| 83 | } |
| 84 | } |
| 85 | if (currentSessionId.value && timeStateCache.has(currentSessionId.value)) { |
| 86 | return timeStateCache.get(currentSessionId.value)! |
| 87 | } |
no test coverage detected