added cosmic, added passcode
This commit is contained in:
parent
f80f93a9b3
commit
52deafb19f
2
auto-imports.d.ts
vendored
2
auto-imports.d.ts
vendored
@ -9,6 +9,7 @@ declare global {
|
||||
const EffectScope: typeof import('vue')['EffectScope']
|
||||
const asyncComputed: typeof import('@vueuse/core')['asyncComputed']
|
||||
const autoResetRef: typeof import('@vueuse/core')['autoResetRef']
|
||||
const baseFetch: typeof import('./src/composables/fetch')['baseFetch']
|
||||
const computed: typeof import('vue')['computed']
|
||||
const computedAsync: typeof import('@vueuse/core')['computedAsync']
|
||||
const computedEager: typeof import('@vueuse/core')['computedEager']
|
||||
@ -309,6 +310,7 @@ declare module 'vue' {
|
||||
readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']>
|
||||
readonly asyncComputed: UnwrapRef<typeof import('@vueuse/core')['asyncComputed']>
|
||||
readonly autoResetRef: UnwrapRef<typeof import('@vueuse/core')['autoResetRef']>
|
||||
readonly baseFetch: UnwrapRef<typeof import('./src/composables/fetch')['baseFetch']>
|
||||
readonly computed: UnwrapRef<typeof import('vue')['computed']>
|
||||
readonly computedAsync: UnwrapRef<typeof import('@vueuse/core')['computedAsync']>
|
||||
readonly computedEager: UnwrapRef<typeof import('@vueuse/core')['computedEager']>
|
||||
|
||||
14
src/App.vue
14
src/App.vue
@ -107,11 +107,23 @@ const data = {
|
||||
isActive: true,
|
||||
items: [
|
||||
{
|
||||
title: '波动',
|
||||
title: '行星波月统计',
|
||||
url: '/tidi/waves',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'COSMIC',
|
||||
url: '#',
|
||||
icon: 'mdi:telescope',
|
||||
isActive: true,
|
||||
items: [
|
||||
{
|
||||
title: '行星波月统计',
|
||||
url: '/cosmic/stats',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
关于: [
|
||||
|
||||
111
src/components/CoolBack.vue
Normal file
111
src/components/CoolBack.vue
Normal file
@ -0,0 +1,111 @@
|
||||
<script setup lang="ts">
|
||||
import type { P5I } from 'p5i'
|
||||
import { p5i } from 'p5i'
|
||||
import { onMounted, onUnmounted, ref } from 'vue'
|
||||
|
||||
const el = ref<HTMLCanvasElement | null>(null)
|
||||
|
||||
const {
|
||||
mount,
|
||||
unmount,
|
||||
createCanvas,
|
||||
background,
|
||||
noFill,
|
||||
stroke,
|
||||
noise,
|
||||
noiseSeed,
|
||||
resizeCanvas,
|
||||
cos,
|
||||
sin,
|
||||
TWO_PI,
|
||||
} = p5i()
|
||||
|
||||
let w = window.innerWidth
|
||||
let h = window.innerHeight
|
||||
const offsetY = window.scrollY
|
||||
|
||||
const SCALE = 200
|
||||
const LENGTH = 10
|
||||
const SPACING = 15
|
||||
|
||||
function getForceOnPoint(x: number, y: number, z: number) {
|
||||
// https://p5js.org/reference/#/p5/noise
|
||||
return (noise(x / SCALE, y / SCALE, z) - 0.5) * 2 * TWO_PI
|
||||
}
|
||||
|
||||
const existingPoints = new Set<string>()
|
||||
const points: { x: number, y: number, opacity: number }[] = []
|
||||
|
||||
function addPoints() {
|
||||
for (let x = -SPACING / 2; x < w + SPACING; x += SPACING) {
|
||||
for (let y = -SPACING / 2; y < h + offsetY + SPACING; y += SPACING) {
|
||||
const id = `${x}-${y}`
|
||||
if (existingPoints.has(id))
|
||||
continue
|
||||
existingPoints.add(id)
|
||||
points.push({ x, y, opacity: Math.random() * 0.5 + 0.5 })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setup() {
|
||||
createCanvas(w, h)
|
||||
background('#ffffff')
|
||||
stroke('#ccc')
|
||||
noFill()
|
||||
|
||||
noiseSeed(+new Date())
|
||||
|
||||
addPoints()
|
||||
}
|
||||
|
||||
function draw({ circle }: P5I) {
|
||||
background('#ffffff')
|
||||
const t = +new Date() / 10000
|
||||
|
||||
for (const p of points) {
|
||||
const { x, y } = p
|
||||
const rad = getForceOnPoint(x, y, t)
|
||||
const length = (noise(x / SCALE, y / SCALE, t * 2) + 0.5) * LENGTH
|
||||
const nx = x + cos(rad) * length
|
||||
const ny = y + sin(rad) * length
|
||||
stroke(180, 180, 180, (Math.abs(cos(rad)) * 0.5 + 0.5) * p.opacity * 255)
|
||||
circle(nx, ny - offsetY, 1)
|
||||
}
|
||||
}
|
||||
|
||||
function restart() {
|
||||
if (el.value)
|
||||
mount(el.value, { setup, draw })
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
restart()
|
||||
|
||||
useEventListener('resize', () => {
|
||||
w = window.innerWidth
|
||||
h = window.innerHeight
|
||||
resizeCanvas(w, h)
|
||||
addPoints()
|
||||
})
|
||||
|
||||
// Uncomment to enable scroll-based animation
|
||||
// Tho there is some lag when scrolling, not sure if it's solvable
|
||||
// useEventListener('scroll', () => {
|
||||
// offsetY = window.scrollY
|
||||
// addPoints()
|
||||
// }, { passive: true })
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
unmount()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- <Paper> -->
|
||||
<div relative h-100 class="overflow-hidden">
|
||||
<div ref="el" pointer-events-none overflow-hidden />
|
||||
</div>
|
||||
<!-- </Paper> -->
|
||||
</template>
|
||||
21
src/composables/fetch.ts
Normal file
21
src/composables/fetch.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { createFetch } from '@vueuse/core'
|
||||
import { API_BASE_URL } from '~/CONSTANT'
|
||||
|
||||
export const baseFetch = createFetch({
|
||||
baseUrl: API_BASE_URL,
|
||||
options: {
|
||||
async beforeFetch({ options }) {
|
||||
const code = '0101'
|
||||
options.headers = {
|
||||
...options.headers,
|
||||
Authorization: `${code}`,
|
||||
}
|
||||
return { options }
|
||||
},
|
||||
|
||||
},
|
||||
fetchOptions: {
|
||||
mode: 'cors',
|
||||
},
|
||||
|
||||
})
|
||||
@ -1 +1,2 @@
|
||||
export * from './dark'
|
||||
export * from './fetch'
|
||||
|
||||
@ -35,11 +35,12 @@ const form = useForm()
|
||||
const stagedDates = ref<string[]>([])
|
||||
|
||||
onMounted(async () => {
|
||||
await fetch(`${API_BASE_URL}/balloon/metadata`).then(resp => resp.json()).then((data) => {
|
||||
stagedDates.value = data
|
||||
await baseFetch<string []>(`${API_BASE_URL}/balloon/metadata`).json().then(({ data }) => {
|
||||
const das = data.value!
|
||||
stagedDates.value = das
|
||||
formSchema.value = z.object({
|
||||
selectedMode: z.enum(modes).describe('选择一个模式'),
|
||||
selectedDate: z.enum(data.map((d: string) => {
|
||||
selectedDate: z.enum(das.map((d: string) => {
|
||||
const datePattern = /_\d{8}T\d{6}/
|
||||
if (!datePattern.test(d)) {
|
||||
return ''
|
||||
@ -51,7 +52,7 @@ onMounted(async () => {
|
||||
return capture[0]
|
||||
})),
|
||||
}).describe('选择一个日期')
|
||||
form.setFieldValue('selectedDate', data[0])
|
||||
form.setFieldValue('selectedDate', data.value![0])
|
||||
form.setFieldValue('selectedMode', modes[0])
|
||||
})
|
||||
})
|
||||
@ -60,8 +61,9 @@ async function get_image(
|
||||
selectedMode: string,
|
||||
selectedDate: string,
|
||||
) {
|
||||
const resp = await fetch(`${API_BASE_URL}/balloon/render/single?mode=${encodeURIComponent(selectedMode)}&path=${encodeURIComponent(selectedDate)}`)
|
||||
const { response } = await baseFetch(`${API_BASE_URL}/balloon/render/single?mode=${encodeURIComponent(selectedMode)}&path=${encodeURIComponent(selectedDate)}`)
|
||||
// check for MIME Type, check if is png
|
||||
const resp = response.value!
|
||||
const isPng = resp.headers.get('Content-Type') === 'image/png'
|
||||
if (!isPng) {
|
||||
imageResult.result = 'error' as const
|
||||
|
||||
@ -44,8 +44,8 @@ const modes = [
|
||||
|
||||
async function refreshImage() {
|
||||
const url = `${API_BASE_URL}/balloon/render/year?mode=${encodeURIComponent(selectedMode.value)}&start_year=${startYear.value}&end_year=${endYear.value}`
|
||||
const resp = await fetch(url)
|
||||
const blob = await resp.blob()
|
||||
const { data } = await baseFetch(url).arrayBuffer()
|
||||
const blob = new Blob([data.value!])
|
||||
const u = URL.createObjectURL(blob)
|
||||
imageResult.result = 'success'
|
||||
imageResult.imageUrl = u
|
||||
|
||||
64
src/pages/cosmic/stats.vue
Normal file
64
src/pages/cosmic/stats.vue
Normal file
@ -0,0 +1,64 @@
|
||||
<route lang="json">
|
||||
{"meta":{
|
||||
"title":"COSMIC",
|
||||
"description":"行星波月统计",
|
||||
"group":"COSMIC",
|
||||
"item_name":"行星波月统计"
|
||||
}}
|
||||
</route>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { ImageResult } from '~/components/ImageContainer.vue'
|
||||
import DenseFramework from '~/components/DenseFramework.vue'
|
||||
import { API_BASE_URL } from '~/CONSTANT'
|
||||
|
||||
const imageResult = reactive<ImageResult>({
|
||||
result: 'idle',
|
||||
imageUrl: '',
|
||||
message: '',
|
||||
})
|
||||
|
||||
const selectedT = ref<'5' | '10' | '16'>('5')
|
||||
|
||||
const fetchUrl = computed(() => {
|
||||
const query = new URLSearchParams()
|
||||
query.set('T_', selectedT.value)
|
||||
return `${API_BASE_URL}/cosmic/temp_render?${query}`
|
||||
})
|
||||
|
||||
const { onFetchResponse, isFetching, execute } = baseFetch(fetchUrl, {
|
||||
immediate: false,
|
||||
})
|
||||
|
||||
watch(isFetching, (isFetching) => {
|
||||
if (isFetching) {
|
||||
imageResult.result = 'pending'
|
||||
}
|
||||
})
|
||||
|
||||
onFetchResponse(async (resp) => {
|
||||
const blob = await resp.blob()
|
||||
const url = URL.createObjectURL(blob)
|
||||
imageResult.result = 'success'
|
||||
imageResult.imageUrl = url
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DenseFramework :image-result="imageResult" @submit="execute">
|
||||
<Label for="T_range">滑动窗口</Label>
|
||||
<Tabs id="T_range" v-model="selectedT" default-value="5">
|
||||
<TabsList class="grid grid-cols-3 w-full">
|
||||
<TabsTrigger value="5">
|
||||
5
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="10">
|
||||
10
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="16">
|
||||
16
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
</Tabs>
|
||||
</DenseFramework>
|
||||
</template>
|
||||
@ -13,7 +13,7 @@
|
||||
import type { ImageResult } from '~/components/ImageContainer.vue'
|
||||
import { API_BASE_URL } from '~/CONSTANT'
|
||||
|
||||
const selectedMode = ref('潮汐波')
|
||||
const selectedMode = ref('2日行星波')
|
||||
const selectedWave = ref('潮汐波')
|
||||
const selectedDateType = ref('day')
|
||||
const selectedStation = ref('武汉左岭镇站')
|
||||
@ -68,7 +68,7 @@ const queryUrl = computed(() => {
|
||||
return path
|
||||
})
|
||||
|
||||
const { onFetchResponse, isFetching, execute } = useFetch(queryUrl, { immediate: false })
|
||||
const { onFetchResponse, isFetching, execute } = baseFetch(queryUrl, { immediate: false })
|
||||
|
||||
onFetchResponse(async (resp) => {
|
||||
const blob = await resp.blob()
|
||||
@ -84,8 +84,8 @@ watch(isFetching, (fetching) => {
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
const resp = await fetch(`${API_BASE_URL}/radar/metadata`)
|
||||
const data = await resp.json()
|
||||
const resp = await baseFetch(`${API_BASE_URL}/radar/metadata`).json()
|
||||
const data = await resp.data.value
|
||||
// use regex to extract the year from the path,
|
||||
// ./radar/data\\武汉左岭镇站\\2017\\ZLT_MET01_DLL_L21_01D_20170316.txt
|
||||
const station_pattern = /data\/(.*?)\//
|
||||
@ -109,6 +109,12 @@ onMounted(async () => {
|
||||
|
||||
paths.value = data
|
||||
})
|
||||
|
||||
watch(selectedYear, (newV) => {
|
||||
selectedDate.value = Array.from(dates.value).filter(
|
||||
d => d.startsWith(newV),
|
||||
)[0]
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -128,7 +134,7 @@ onMounted(async () => {
|
||||
</Tabs>
|
||||
<div v-if="selectedWave === '行星波'">
|
||||
<Label>行星波类型</Label>
|
||||
<Tabs v-model="selectedMode" default-value="uwind">
|
||||
<Tabs v-model="selectedMode" default-value="2日行星波">
|
||||
<TabsList class="grid grid-cols-4 w-full">
|
||||
<TabsTrigger v-for="m in modes" :key="m" :value="m">
|
||||
{{ m.replace("行星波", "") }}
|
||||
|
||||
@ -47,7 +47,7 @@ const queryUrl = computed(() => {
|
||||
return path
|
||||
})
|
||||
|
||||
const { onFetchResponse, isFetching, execute } = useFetch(queryUrl, { immediate: false })
|
||||
const { onFetchResponse, isFetching, execute } = baseFetch(queryUrl, { immediate: false })
|
||||
|
||||
onFetchResponse(async (resp) => {
|
||||
const blob = await resp.blob()
|
||||
@ -63,8 +63,8 @@ watch(isFetching, (fetching) => {
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
const resp = await fetch(`${API_BASE_URL}/radar/metadata`)
|
||||
const data = await resp.json()
|
||||
const resp = await baseFetch(`${API_BASE_URL}/radar/metadata`).json()
|
||||
const data = await resp.data.value!
|
||||
// use regex to extract the year from the path,
|
||||
// ./radar/data\\武汉左岭镇站\\2017\\ZLT_MET01_DLL_L21_01D_20170316.txt
|
||||
const station_pattern = /data\/(.*?)\//
|
||||
|
||||
@ -32,7 +32,7 @@ const urll = computed(() => {
|
||||
const query = `path=${path}&day=${day}&cycle_no=${selected.cycle_no}`
|
||||
return `${API_BASE_URL}/saber/render/day_cycle_power_wave_plot?${query}`
|
||||
})
|
||||
const { onFetchResponse, isFetching, execute } = useFetch(
|
||||
const { onFetchResponse, isFetching, execute } = baseFetch(
|
||||
urll,
|
||||
{ immediate: false },
|
||||
)
|
||||
@ -50,20 +50,23 @@ onFetchResponse(async (resp) => {
|
||||
imageResult.imageUrl = url
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
refreshPath()
|
||||
onMounted(async () => {
|
||||
await refreshPath()
|
||||
selected.path = saberPaths.value[0]
|
||||
})
|
||||
|
||||
watch(() => selected.path, () => {
|
||||
refreshCurrentSaberDays(selected.path)
|
||||
if (selected.day === '') {
|
||||
watch(() => selected.path, async () => {
|
||||
if (selected.path === '') {
|
||||
return
|
||||
}
|
||||
await refreshCurrentSaberDays(selected.path)
|
||||
if (selected.day === '' && currentSaberDays.value.length > 0) {
|
||||
selected.day = currentSaberDays.value[0]
|
||||
}
|
||||
})
|
||||
|
||||
function renderPath(path: string) {
|
||||
const yearPattern = /\/data\\(\d{4})/
|
||||
const yearPattern = /\/data\/(\d{4})/
|
||||
const year = path.match(yearPattern)?.[1]
|
||||
const monthPattern = /Temp_O3_(.*)(\d{4})/
|
||||
const month = path.match(monthPattern)?.[1]
|
||||
|
||||
@ -32,7 +32,7 @@ const urll = computed(() => {
|
||||
const query = `path=${path}&day=${day}&cycle_no=${selected.cycle_no}`
|
||||
return `${API_BASE_URL}/saber/render/day_fft_ifft_plot?${query}`
|
||||
})
|
||||
const { onFetchResponse, isFetching, execute } = useFetch(
|
||||
const { onFetchResponse, isFetching, execute } = baseFetch(
|
||||
urll,
|
||||
{ immediate: false },
|
||||
)
|
||||
@ -50,20 +50,20 @@ onFetchResponse(async (resp) => {
|
||||
imageResult.imageUrl = url
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
refreshPath()
|
||||
onMounted(async () => {
|
||||
await refreshPath()
|
||||
selected.path = saberPaths.value[0]
|
||||
})
|
||||
|
||||
watch(() => selected.path, () => {
|
||||
refreshCurrentSaberDays(selected.path)
|
||||
watch(() => selected.path, async () => {
|
||||
await refreshCurrentSaberDays(selected.path)
|
||||
if (selected.day === '') {
|
||||
selected.day = currentSaberDays.value[0]
|
||||
}
|
||||
})
|
||||
|
||||
function renderPath(path: string) {
|
||||
const yearPattern = /\/data\\(\d{4})/
|
||||
const yearPattern = /\/data\/(\d{4})/
|
||||
const year = path.match(yearPattern)?.[1]
|
||||
const monthPattern = /Temp_O3_(.*)(\d{4})/
|
||||
const month = path.match(monthPattern)?.[1]
|
||||
|
||||
@ -29,7 +29,7 @@ const urll = computed(() => {
|
||||
const query = `path=${path}`
|
||||
return `${API_BASE_URL}/saber/render/month_power_wave_plot?${query}`
|
||||
})
|
||||
const { onFetchResponse, execute, isFetching } = useFetch(
|
||||
const { onFetchResponse, execute, isFetching } = baseFetch(
|
||||
urll,
|
||||
{ immediate: false },
|
||||
)
|
||||
@ -47,13 +47,13 @@ onFetchResponse(async (resp) => {
|
||||
imageResult.imageUrl = url
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
refreshPath()
|
||||
onMounted(async () => {
|
||||
await refreshPath()
|
||||
selected.path = saberPaths.value[0]
|
||||
})
|
||||
|
||||
function renderPath(path: string) {
|
||||
const yearPattern = /\/data\\(\d{4})/
|
||||
const yearPattern = /\/data\/(\d{4})/
|
||||
const year = path.match(yearPattern)?.[1]
|
||||
const monthPattern = /Temp_O3_(.*)(\d{4})/
|
||||
const month = path.match(monthPattern)?.[1]
|
||||
|
||||
@ -32,7 +32,7 @@ const urll = computed(() => {
|
||||
const query = `path=${path}&day=${day}&height=${selected.height_no}`
|
||||
return `${API_BASE_URL}/saber/render/plot_wave_fitting?${query}`
|
||||
})
|
||||
const { onFetchResponse, execute, isFetching } = useFetch(
|
||||
const { onFetchResponse, execute, isFetching } = baseFetch(
|
||||
urll,
|
||||
{ immediate: false },
|
||||
)
|
||||
@ -50,20 +50,20 @@ onFetchResponse(async (resp) => {
|
||||
imageResult.imageUrl = url
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
refreshPath()
|
||||
onMounted(async () => {
|
||||
await refreshPath()
|
||||
selected.path = saberPaths.value[0]
|
||||
})
|
||||
|
||||
watch(() => selected.path, () => {
|
||||
refreshCurrentSaberDays(selected.path)
|
||||
watch(() => selected.path, async () => {
|
||||
await refreshCurrentSaberDays(selected.path)
|
||||
if (saberPaths.value.length > 0) {
|
||||
selected.path = saberPaths.value[0]
|
||||
}
|
||||
})
|
||||
|
||||
function renderPath(path: string) {
|
||||
const yearPattern = /\/data\\(\d{4})/
|
||||
const yearPattern = /\/data\/(\d{4})/
|
||||
const year = path.match(yearPattern)?.[1]
|
||||
const monthPattern = /Temp_O3_(.*)(\d{4})/
|
||||
const month = path.match(monthPattern)?.[1]
|
||||
|
||||
@ -6,15 +6,15 @@ const currentSaberDays = ref<string>('')
|
||||
async function refreshPath() {
|
||||
if (saberPaths.value.length)
|
||||
return
|
||||
const resp = await fetch(`${API_BASE_URL}/saber/metadata`)
|
||||
const data = await resp.json()
|
||||
saberPaths.value = data
|
||||
const resp = await baseFetch<string[]>(`${API_BASE_URL}/saber/metadata`).json()
|
||||
const data = resp.data.value
|
||||
saberPaths.value = data!
|
||||
}
|
||||
|
||||
async function refreshCurrentSaberDays(path: string) {
|
||||
const resp = await fetch(`${API_BASE_URL}/saber/metadata/list_days?path=${path}`)
|
||||
const data = await resp.json()
|
||||
currentSaberDays.value = data
|
||||
const resp = await baseFetch<string>(`${API_BASE_URL}/saber/metadata/list_days?path=${path}`).json()
|
||||
const data = resp.data.value
|
||||
currentSaberDays.value = data!
|
||||
}
|
||||
|
||||
export { currentSaberDays, refreshCurrentSaberDays, refreshPath, saberPaths }
|
||||
|
||||
@ -15,7 +15,7 @@ const selectedYear = ref('2017')
|
||||
|
||||
// const k = [ -4,-3,-2,-1,0,1,2,3,4]
|
||||
const selectedK = ref(0)
|
||||
const selectedT = ref(15)
|
||||
const selectedT = ref('5')
|
||||
|
||||
const queryUrl = computed(() => {
|
||||
const query = new URLSearchParams()
|
||||
@ -26,7 +26,7 @@ const queryUrl = computed(() => {
|
||||
return `${API_BASE_URL}/tidi/render/wave?${query}`
|
||||
})
|
||||
|
||||
const { execute, onFetchResponse, isFetching } = useFetch(queryUrl, { immediate: false })
|
||||
const { execute, onFetchResponse, isFetching } = baseFetch(queryUrl, { immediate: false })
|
||||
|
||||
watch(isFetching, (fetching) => {
|
||||
if (fetching) {
|
||||
@ -42,13 +42,14 @@ onFetchResponse(async (resp) => {
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
const metas = await fetch(`${API_BASE_URL}/tidi/metadata`).then(resp => resp.json())
|
||||
const _years = metas.path.map((a: string) => {
|
||||
const metas = await baseFetch<{ path: string [] }>(`${API_BASE_URL}/tidi/metadata`).json()
|
||||
const _years = metas.data.value.path.map((a: string) => {
|
||||
const year_pattern = /data\/(\d{4})\//
|
||||
return a.match(year_pattern)?.[1]
|
||||
})
|
||||
_years.sort()
|
||||
years.value = Array.from(new Set(_years))
|
||||
selectedYear.value = years.value[0]
|
||||
})
|
||||
</script>
|
||||
|
||||
@ -100,8 +101,8 @@ onMounted(async () => {
|
||||
<TabsTrigger value="10">
|
||||
10
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="15">
|
||||
15
|
||||
<TabsTrigger value="16">
|
||||
16
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
</Tabs>
|
||||
|
||||
1
typed-router.d.ts
vendored
1
typed-router.d.ts
vendored
@ -22,6 +22,7 @@ declare module 'vue-router/auto-routes' {
|
||||
'/[...all]': RouteRecordInfo<'/[...all]', '/:all(.*)', { all: ParamValue<true> }, { all: ParamValue<false> }>,
|
||||
'/balloon/single': RouteRecordInfo<'/balloon/single', '/balloon/single', Record<never, never>, Record<never, never>>,
|
||||
'/balloon/year': RouteRecordInfo<'/balloon/year', '/balloon/year', Record<never, never>, Record<never, never>>,
|
||||
'/cosmic/stats': RouteRecordInfo<'/cosmic/stats', '/cosmic/stats', Record<never, never>, Record<never, never>>,
|
||||
'/radar/v1': RouteRecordInfo<'/radar/v1', '/radar/v1', Record<never, never>, Record<never, never>>,
|
||||
'/radar/v2': RouteRecordInfo<'/radar/v2', '/radar/v2', Record<never, never>, Record<never, never>>,
|
||||
'/saber/day_cycle_power_wave_plot': RouteRecordInfo<'/saber/day_cycle_power_wave_plot', '/saber/day_cycle_power_wave_plot', Record<never, never>, Record<never, never>>,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user