sync
Some checks are pending
Test / build (lts/*, ubuntu-latest) (push) Waiting to run
Test / build (lts/*, windows-latest) (push) Waiting to run

This commit is contained in:
Dustella 2025-03-05 11:39:17 +08:00
parent 3b3294d39f
commit 70298d740b
Signed by: Dustella
GPG Key ID: 35AA0AA3DC402D5C
23 changed files with 402 additions and 64 deletions

View File

@ -1,4 +1,3 @@
const KURONEKO_API = 'http://100.89.232.74:18200'
// export const API_BASE_URL = 'http://localhost:5000'
export const API_BASE_URL = import.meta.env.PROD ? 'https://gca-api.dustella.net:8443' : KURONEKO_API
export const API_BASE_URL = `/api`
// export const API_BASE_URL = 'https://gca-api.dustella.net:8443'

View File

@ -3,7 +3,6 @@ import { Button } from '~/components/ui/button'
import { Input } from '~/components/ui/input'
import { Label } from '~/components/ui/label'
import { authCode } from '~/composables'
import { API_BASE_URL } from '~/CONSTANT'
import manba from '../../public/pack.png'
const code = ref('')
@ -12,7 +11,7 @@ const remember = ref(false)
function auth() {
authCode.value = code.value
const resp = baseFetch(`${API_BASE_URL}/ping`, {
const resp = baseFetch(`/ping`, {
})
if (!resp.error.value) {
if (remember.value) {

View File

@ -1,6 +1,4 @@
<script setup lang="ts">
import { API_BASE_URL } from '~/CONSTANT'
const props = defineProps<{
waveType: '潮汐波' | '行星波'
isDay?: boolean
@ -52,7 +50,7 @@ const queryUrl = computed(() => {
query.set('month', selectedMonth.value)
}
// const query = `?station=${station}&year=${year}&model_name=${mode}&wind_type=${windType}&H=${selectedH.value}`
const path = `${API_BASE_URL}/radar/render/heatmap?${query}`
const path = `/radar/render/heatmap?${query}`
return path
})
@ -61,7 +59,7 @@ const urlModel = defineModel<string>()
syncRef(urlModel, queryUrl, { direction: 'rtl' })
onMounted(async () => {
const resp = await baseFetch(`${API_BASE_URL}/radar/metadata`).json()
const resp = await baseFetch(`/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

View File

@ -10,7 +10,6 @@
</route>
<script setup lang="ts">
import { API_BASE_URL } from '~/CONSTANT'
import { currentSaberDays, parseDayOfYear, refreshCurrentSaberDays, refreshPath, renderPath, saberPaths } from './utils'
const lat_ranges = [
@ -53,7 +52,7 @@ const urll = computed(() => {
query.set('day', selected.day)
query.set('cycle_no', selected.cycle_no.toString())
query.set('lat_range', selected.lat_range)
return `${API_BASE_URL}/saber/render/gravity_wave/per_day/power_wave_plot?${query}`
return `/saber/render/gravity_wave/per_day/power_wave_plot?${query}`
})
onMounted(async () => {

View File

@ -10,7 +10,6 @@
</route>
<script setup lang="ts">
import { API_BASE_URL } from '~/CONSTANT'
import { currentSaberDays, parseDayOfYear, refreshCurrentSaberDays, refreshPath, renderPath, saberPaths } from './utils'
const selected = reactive({
@ -56,7 +55,7 @@ const urll = computed(() => {
query.set('day', selected.day)
query.set('cycle_no', selected.cycle_no.toString())
query.set('lat_range', selected.lat_range)
return `${API_BASE_URL}/saber/render/gravity_wave/per_day/fft_ifft?${query}`
return `/saber/render/gravity_wave/per_day/fft_ifft?${query}`
})
onMounted(async () => {

View File

@ -10,7 +10,6 @@
</route>
<script setup lang="ts">
import { API_BASE_URL } from '~/CONSTANT'
import { refreshPath, renderPath, saberPaths } from './utils'
const currentMode = ref('月统计图')
@ -41,13 +40,13 @@ const urll = computed(() => {
const query = new URLSearchParams()
query.set('path', selected.path)
query.set('lat_range', selected.lat_range)
return `${API_BASE_URL}/saber/render/gravity_wave/per_month/power_wave_plot?${query}`
return `/saber/render/gravity_wave/per_month/power_wave_plot?${query}`
}
else {
const query = new URLSearchParams()
query.set('year', selected.year)
query.set('lat_range', selected.lat_range)
return `${API_BASE_URL}/saber/render/gravity_wave/per_year/power_wave_plot?${query}`
return `/saber/render/gravity_wave/per_year/power_wave_plot?${query}`
}
})

View File

@ -10,7 +10,6 @@
</route>
<script setup lang="ts">
import { API_BASE_URL } from '~/CONSTANT'
import { currentSaberDays, parseDayOfYear, refreshCurrentSaberDays, refreshPath, renderPath, saberPaths } from './utils'
const lat_ranges = [
@ -35,7 +34,7 @@ const urll = computed(() => {
query.set('day', selected.day)
query.set('height_no', selected.height_no.toString())
query.set('lat_ranges', selected.lat_ranges)
return `${API_BASE_URL}/saber/render/gravity_wave/per_day/wave_fitting?${query}`
return `/saber/render/gravity_wave/per_day/wave_fitting?${query}`
})
onMounted(async () => {

View File

@ -1,18 +1,16 @@
import { API_BASE_URL } from '~/CONSTANT'
const saberPaths = ref<string[]>([])
const currentSaberDays = ref<string>('')
async function refreshPath() {
if (saberPaths.value.length)
return
const resp = await baseFetch<string[]>(`${API_BASE_URL}/saber/metadata`).json()
const resp = await baseFetch<string[]>(`/saber/metadata`).json()
const data = resp.data.value
saberPaths.value = data!
}
async function refreshCurrentSaberDays(path: string) {
const resp = await baseFetch<string>(`${API_BASE_URL}/saber/metadata/list_days?path=${path}`).json()
const resp = await baseFetch<string>(`/saber/metadata/list_days?path=${path}`).json()
const data = resp.data.value
currentSaberDays.value = data!
}

View File

@ -31,11 +31,24 @@ interface UseAPIOnlineOptions {
}
export function useAPIOnline(options: UseAPIOnlineOptions = {}) {
// check current protocal, if is https, use wss, if is http, use ws
const wsProtocal = API_BASE_URL.startsWith('https') ? 'wss' : 'ws'
// check current protocol, if is https, use wss, if is http, use ws
const {
wsProtocol,
wsBaseURL,
} = (() => {
let wsProtocol = API_BASE_URL.startsWith('https') ? 'wss' : 'ws'
if (!API_BASE_URL.startsWith('http')) {
wsProtocol = location.protocol === 'https:' ? 'wss' : 'ws'
}
let wsBaseURL = API_BASE_URL.replace('https://', '').replace('http://', '')
if (!API_BASE_URL.startsWith('http')) {
wsBaseURL = location.host + API_BASE_URL
}
return { wsProtocol, wsBaseURL }
})()
const {
url = `${wsProtocal}://${API_BASE_URL.replace('https://', '').replace('http://', '')}/ping/ws`,
url = `${wsProtocol}://${wsBaseURL}/ping/ws`,
heartbeatInterval = 30000,
reconnectDelay = 5000,
onConnected,

View File

@ -8,7 +8,6 @@ meta:
<script setup lang="ts">
import type { ImageResult } from '~/components/ImageContainer.vue'
import { API_BASE_URL } from '~/CONSTANT'
const modes = [
'观测的二阶多项式拟合',
@ -17,6 +16,10 @@ const modes = [
'温度-水平风矢量图',
] as const
const nameModeMapping: Record<string, string> = {
'径向风-纬向风矢量图': '经向风-纬向风矢量图',
}
const allPaths = ref([] as string[])
const allStations = ref([] as string[])
@ -31,14 +34,14 @@ const currentPathesList = computed(() => {
})
onMounted(async () => {
await baseFetch<string []>(`${API_BASE_URL}/balloon/metadata`).json().then(({ data }) => {
await baseFetch<string []>(`/balloon/metadata`).json().then(({ data }) => {
const das = data.value!
allPaths.value = das
selected.selectedPath = das[0]
const _allStations = das.map((a: string) => {
const stationPattern = /data\/balloon\/(\w+)\//
return a.match(stationPattern)?.[1]
const stationPattern = /data\/balloon\/(.+)\//
return a.match(stationPattern)?.[1].split('/')[0] ?? ''
}) as string[]
const stations = Array.from(new Set(_allStations))
@ -65,7 +68,7 @@ function renderDate(str: string) {
const queryUrl = computed(() => {
const selectedMode = selected.selectedMode
const selectedDate = selected.selectedPath
return `${API_BASE_URL}/balloon/render/single?mode=${encodeURIComponent(selectedMode)}&path=${encodeURIComponent(selectedDate)}`
return `/balloon/render/single?mode=${encodeURIComponent(selectedMode)}&path=${encodeURIComponent(selectedDate)}`
})
const metadata = ref({} as Record<string, string>)
@ -141,7 +144,7 @@ async function customHandle(resp: Response) {
<Tabs v-model="selected.selectedMode" default-value="观测的二阶多项式拟合">
<TabsList class="grid grid-cols-1 w-full">
<TabsTrigger v-for="m in modes" :key="m" :value="m">
{{ m }}
{{ nameModeMapping[m] ?? m }}
</TabsTrigger>
</TabsList>
</Tabs>

View File

@ -7,11 +7,10 @@ meta:
</route>
<script setup lang="ts">
import { API_BASE_URL } from '~/CONSTANT'
const selectedMode = ref('w/f值统计结果')
const selectedStation = ref('LIN')
const allStations = ref([] as string[])
const allPaths = ref([] as string[])
const isIllegal = ref(false)
@ -19,12 +18,13 @@ const startYear = ref(2017)
const endYear = ref(2024)
onMounted(async () => {
await baseFetch<string []>(`${API_BASE_URL}/balloon/metadata`).json().then(({ data }) => {
await baseFetch<string []>(`/balloon/metadata`).json().then(({ data }) => {
const das = data.value!
allPaths.value = das
const _allStations = das.map((a: string) => {
const stationPattern = /data\/balloon\/(\w+)\//
return a.match(stationPattern)?.[1]
const stationPattern = /data\/balloon\/(.+)\//
return a.match(stationPattern)?.[1].split('/')[0] ?? ''
}) as string[]
const stations = Array.from(new Set(_allStations))
@ -33,6 +33,43 @@ onMounted(async () => {
})
})
const currentMinBeginYear = computed(() => {
const station = selectedStation.value
// filter out the data that belong to the selected station
const stationData = allPaths.value.filter(a => a.includes(station))
const stationYears = new Set(stationData.map((a) => {
const yearPattern = /-(\d{4})/
return Number.parseInt(a.match(yearPattern)?.[1] ?? '-1')
}).filter(a => a !== -1))
return Math.min(...Array.from(stationYears))
})
const currentMaxEndYear = computed(() => {
const station = selectedStation.value
// filter out the data that belong to the selected station
const stationData = allPaths.value.filter(a => a.includes(station))
const stationYears = new Set(stationData.map((a) => {
const yearPattern = /-(\d{4})/
return Number.parseInt(a.match(yearPattern)?.[1] ?? '-1')
}).filter(a => a !== -1))
const result = Math.max(...Array.from(stationYears))
return result
})
watch([currentMinBeginYear, currentMaxEndYear], () => {
if (startYear.value < currentMinBeginYear.value) {
startYear.value = currentMinBeginYear.value
}
if (endYear.value > currentMaxEndYear.value) {
endYear.value = currentMaxEndYear.value
}
// finally, if start year is greater than end year, set end year to start year
if (startYear.value > endYear.value) {
endYear.value = startYear.value
}
// or if
})
const modes = [
'w/f值统计结果',
@ -66,12 +103,18 @@ const mode_display_mapping = {
'纬向动量通量统计结果': '纬向动量通量统计',
'经向动量通量统计结果': '经向动量通量统计',
'horizontal propagation': '水平传播',
'每月上传/下传重力波占比': '每月上传/下传重力波占比',
'每月上传/下传重力波占比': '垂直传播',
'动能和势能分布情况': '动能和势能分布情况',
}
const queryUrl = computed(() => {
return `${API_BASE_URL}/balloon/render/year?mode=${encodeURIComponent(selectedMode.value)}&start_year=${startYear.value}&end_year=${endYear.value}`
const params = new URLSearchParams({
mode: selectedMode.value,
start_year: startYear.value.toString(),
end_year: endYear.value.toString(),
station: selectedStation.value,
})
return `/balloon/render/year?${params.toString()}`
})
watch([selectedMode, startYear, endYear], () => {
@ -102,12 +145,17 @@ watch([selectedMode, startYear, endYear], () => {
</SelectContent>
</Select>
</div>
<div>
<!-- {{ currentMaxEndYear }}{{ currentMinBeginYear }} -->
台站 {{ selectedStation }} 可选的数据范围为 {{ currentMinBeginYear }} - {{ currentMaxEndYear }}
</div>
<NumberField
id="start"
v-model:model-value="startYear" :format-options="{
useGrouping: false,
}" :default-value="2017" :min="2017" :max="2024"
}" :default-value="2017"
:min="currentMinBeginYear"
:max="endYear"
>
<Label for="start">起始年</Label>
<NumberFieldContent>
@ -122,7 +170,8 @@ watch([selectedMode, startYear, endYear], () => {
style: 'decimal',
notation: 'standard',
useGrouping: false,
}" :default-value="2017" :min="2017" :max="2024"
}" :default-value="2017"
:min="startYear" :max="currentMaxEndYear"
>
<Label for="end">终止年</Label>
<NumberFieldContent>
@ -146,7 +195,7 @@ watch([selectedMode, startYear, endYear], () => {
}))"
:key="mode" :value="mode"
>
{{ mode_display_mapping[mode] }}
{{ mode_display_mapping[mode] ?? mode }}
</SelectItem>
</SelectGroup>
</SelectContent>

View File

@ -79,10 +79,10 @@ const queryUrl = computed(() => {
<Tabs v-model:model-value="selected.mode">
<TabsList class="grid grid-cols-1 w-full">
<TabsTrigger value="mean_ktemp_Nz">
平均浮力频率和平均势能随高度变化
平均浮力频率随高度变化
</TabsTrigger>
<TabsTrigger value="mean_ktemp_Ptz">
平均势能mean_ktemp_Ptz随高度变化
平均势能随高度变化
</TabsTrigger>
</TabsList>
</Tabs>

View File

@ -7,7 +7,6 @@ meta:
</route>
<script setup lang="ts">
import { API_BASE_URL } from '~/CONSTANT'
/**
if mode == "布伦特-维萨拉频率分布":
await run_sync(p.plot_heatmap_tempNz)()
@ -51,7 +50,7 @@ const queryUrl = computed(() => {
q.set('year', selected.year)
q.set('mode', selected.mode)
q.set('lat_range', selected.lat_range)
return `${API_BASE_URL}/cosmic/render/gravity_wave/multiday?${q}`
return `/cosmic/render/gravity_wave/multiday?${q}`
})
</script>

View File

@ -0,0 +1,91 @@
<route lang="json">
{"meta":{
"title":"COSMIC",
"description":"行星波提取",
"group":"COSMIC",
"item_name":"行星波提取"
}}
</route>
<script setup lang="ts">
import DenseFramework from '~/components/DenseFramework.vue'
const selectedT = ref<'5' | '10' | '16'>('5')
const selectedH = ref(90)
const selectedRange = ref('-30')
const selectedYear = ref('2008')
const ranges = ['-30', '-60', '30', '60']
const fetchUrl = computed(() => {
const query = new URLSearchParams()
query.set('T', selectedT.value)
query.set('target_h', selectedH.value.toString())
query.set('target_lat', selectedRange.value)
query.set('year', selectedYear.value)
return `/cosmic/render/planet_wave/perday?${query}`
})
</script>
<template>
<DenseFramework :image-query="fetchUrl">
<Label>年份</Label>
<Select v-model="selectedYear">
<SelectTrigger>
<SelectValue placeholder="选择年份" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>年份</SelectLabel>
<SelectItem v-for="year in ['2008']" :key="year" :value="year">
{{ year }}
</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
<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>
<!-- TODO: not implemented -->
<Label>高度km</Label>
<NumberField
id="start"
v-model:model-value="selectedH" :format-options="{
useGrouping: false,
}" :default-value="94"
:step="10"
:max="110"
:min="70"
>
<NumberFieldContent>
<NumberFieldDecrement />
<NumberFieldInput />
<NumberFieldIncrement />
</NumberFieldContent>
</NumberField>
<Label>纬度带</Label>
<Select v-model="selectedRange">
<SelectTrigger>
<SelectValue placeholder="选择纬度带" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>纬度带</SelectLabel>
<SelectItem v-for="range in ranges" :key="range" :value="range">
{{ range }}
</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</DenseFramework>
</template>

View File

@ -9,7 +9,6 @@
<script setup lang="ts">
import DenseFramework from '~/components/DenseFramework.vue'
import { API_BASE_URL } from '~/CONSTANT'
const selectedT = ref<'5' | '10' | '16'>('5')
const selectedH = ref(90)
@ -24,7 +23,7 @@ const fetchUrl = computed(() => {
query.set('target_h', selectedH.value.toString())
query.set('target_lat', selectedRange.value)
query.set('k', selectedK.value.toString())
return `${API_BASE_URL}/cosmic/render/planet_wave/daily?${query}`
return `/cosmic/render/planet_wave/daily?${query}`
})
</script>

View File

@ -10,8 +10,6 @@
</route> -->
<script setup lang="ts">
import { API_BASE_URL } from '~/CONSTANT'
const selectedMode = ref('2日行星波')
const selectedWave = ref('潮汐波')
const selectedDateType = ref('day')
@ -57,12 +55,12 @@ const queryUrl = computed(() => {
query.set('month', selectedMonth.value)
}
// const query = `?station=${station}&year=${year}&model_name=${mode}&wind_type=${windType}&H=${selectedH.value}`
const path = `${API_BASE_URL}/radar/render/heatmap?${query}`
const path = `/radar/render/heatmap?${query}`
return path
})
onMounted(async () => {
const resp = await baseFetch(`${API_BASE_URL}/radar/metadata`).json()
const resp = await baseFetch(`/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

View File

@ -10,8 +10,6 @@
</route> -->
<script setup lang="ts">
import { API_BASE_URL } from '~/CONSTANT'
const selectedMode = ref('2日行星波')
const selectedWave = ref('潮汐波')
const selectedStation = ref('武汉左岭镇站')
@ -37,12 +35,12 @@ const queryUrl = computed(() => {
query.set('model_name', selectedWave.value === '潮汐波' ? '潮汐波' : selectedMode.value)
query.set('start_month', selectedMonthRange.start)
query.set('end_month', selectedMonthRange.end)
const path = `${API_BASE_URL}/radar/render/changes?${query}`
const path = `/radar/render/changes?${query}`
return path
})
onMounted(async () => {
const resp = await baseFetch(`${API_BASE_URL}/radar/metadata`).json()
const resp = await baseFetch(`/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

View File

@ -32,7 +32,7 @@ const currentComponent = computed(() => {
<TabsList class="grid grid-cols-1 w-full">
<TabsTrigger v-for="key in Object.keys(component_mapping)" :key="key" class="w-full" :value="key">
{{ {
day_cycle_power_wave_plot: '逐日波功率谱',
day_cycle_power_wave_plot: '平均浮力频率和平均势能随高度变化',
day_fft_ifft_plot: '逐日FFT/IFFT',
plot_wave_fitting: '逐日波形拟合',
}[key] }}

View File

@ -0,0 +1,188 @@
<route lang="json">
{
"meta":{
"title":"Saber 行星波月统计",
"description":"Saber 行星波月统计",
"group":"Saber",
"item_name":"行星波提取"
}
}
</route>
<script setup lang="ts">
import {
CalendarDate,
createCalendar,
DateFormatter,
type DateValue,
getLocalTimeZone,
toCalendar,
} from '@internationalized/date'
import { cn } from '~/lib/utils'
const df = new DateFormatter('zh-CN', {
dateStyle: 'long',
})
const ca = createCalendar('zh-CN')
const selected = reactive({
year: '2018',
T: '16',
k: 0,
H: 90,
range: '60',
})
const targetDate = ref<DateValue>()
function getDayOfYear(date: Date) {
const start = new Date(date.getFullYear(), 0, 0)
// @ts-expect-error date - start
const diff = date - start
const oneDay = 1000 * 60 * 60 * 24
return Math.floor(diff / oneDay)
}
watch(() => selected.year, () => {
targetDate.value = toCalendar(
new CalendarDate(Number.parseInt(selected.year), 1, 1),
ca,
).add({ days: Number.parseInt(selected.T) * 1.5 })
})
const minDateValue = computed(() => {
const currentYearBeginDate = new CalendarDate(Number.parseInt(selected.year), 1, 1)
return toCalendar(currentYearBeginDate, ca).add({ days: Number.parseInt(selected.T) * 1.5 })
})
const maxDateValue = computed(() => {
const currentYearBeginDate = new CalendarDate(Number.parseInt(selected.year) + 1, 1, 1)
return toCalendar(currentYearBeginDate, ca).subtract({ days: Number.parseInt(selected.T) * 1.5 })
})
const ranges = [
'-30',
'30',
'-60',
'60',
]
onMounted(() => {
targetDate.value = toCalendar(
new CalendarDate(Number.parseInt(selected.year), 1, 1),
ca,
).add({ days: Number.parseInt(selected.T) * 1.5 })
})
const queryUrl = computed(() => {
const q = new URLSearchParams()
if (!targetDate.value) {
return ''
}
const targetDay = getDayOfYear(targetDate.value.toDate(getLocalTimeZone()))
const startDay = targetDay - 1.5 * Number.parseInt(selected.T)
q.set('year', selected.year)
q.set('T', selected.T.toString())
q.set('k', selected.k.toString())
q.set('H', selected.H.toString())
q.set('lat_target', selected.range)
q.set('start_day', startDay.toString())
return `/saber/render/planet_wave/per_day?${q}`
})
</script>
<template>
<DenseFramework :image-query="queryUrl">
<Label>年份</Label>
<Select v-model="selected.year">
<SelectTrigger>
<SelectValue placeholder="选择年份" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>年份</SelectLabel>
<SelectItem v-for="year in ['2018', '2015']" :key="year" :value="year">
{{ year }}
</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
<Label>行星波周期</Label>
<!-- can be 510,16 -->
<!-- use Tabs -->
<Tabs v-model="selected.T" default-value="16">
<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>
<Label>高度km</Label>
<NumberField
id="start"
v-model:model-value="selected.H" :format-options="{
useGrouping: false,
}" :default-value="94"
:step="20"
:max="110"
:min="30"
>
<NumberFieldContent>
<NumberFieldDecrement />
<NumberFieldInput />
<NumberFieldIncrement />
</NumberFieldContent>
</NumberField>
<Label>纬度带</Label>
<Select v-model="selected.range">
<SelectTrigger>
<SelectValue placeholder="选择纬度带" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>纬度带</SelectLabel>
<SelectItem v-for="range in ranges" :key="range" :value="range">
{{ range }}
</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
<Label>日期</Label>
<Popover>
<PopoverTrigger as-child>
<Button
variant="outline"
:class="cn(
'w-full justify-start text-left font-normal',
!targetDate && 'text-muted-foreground',
)"
>
<span i-md-calendar />
{{ targetDate ? df.format(targetDate.toDate(getLocalTimeZone())) : "选择日期" }}
</Button>
</PopoverTrigger>
<PopoverContent class="w-auto p-0">
<!-- @ts-expect-error dsa -->
<Calendar
v-model="targetDate " initial-focus
:is-date-disabled="(date:DateValue) => date < minDateValue || date > maxDateValue"
:prevent-deselect="true"
/>
</PopoverContent>
</Popover>
<div>
拟合起始日期 {{ targetDate?.subtract({ days: 1.5 * Number.parseInt(selected.T) }) }}
<br>
拟合结束日期 {{ targetDate?.add({ days: (1.5 * Number.parseInt(selected.T)) }) }}
</div>
</DenseFramework>
</template>
<style scoped>
</style>

View File

@ -10,8 +10,6 @@
</route>
<script setup lang="ts">
import { API_BASE_URL } from '~/CONSTANT'
const selected = reactive({
year: '2018',
T: '16',
@ -34,7 +32,7 @@ const queryUrl = computed(() => {
q.set('k', selected.k.toString())
q.set('H', selected.H.toString())
q.set('lat_target', selected.range)
return `${API_BASE_URL}/saber/render/planet_wave/per_year/energy_plot?${q}`
return `/saber/render/planet_wave/per_year/energy_plot?${q}`
})
</script>

View File

@ -10,8 +10,6 @@
</route>
<script setup lang="ts">
import { API_BASE_URL } from '~/CONSTANT'
const years = ref([] as string[])
const ranges = ['0 ~ 5', '5 ~ 10', '10 ~ 15', '15 ~ 20']
const heights = [70, 72.5, 75, 77.5, 80, 82.5, 85, 87.5, 90, 92.5, 95, 97.5, 100, 102.5, 105, 107.5, 110, 112.5, 115, 117.5, 120].map(String)
@ -33,11 +31,11 @@ const queryUrl = computed(() => {
query.set('T', selectedT.value.toString())
query.set('lat_range', selectedRange.value)
query.set('height', selectedHeight.value)
return `${API_BASE_URL}/tidi/render/planet_wave/daily?${query}`
return `/tidi/render/planet_wave/daily?${query}`
})
onMounted(async () => {
const metas = await baseFetch<{ path: string [] }>(`${API_BASE_URL}/tidi/metadata`).json()
const metas = await baseFetch<{ path: string [] }>(`/tidi/metadata`).json()
const _years = metas.data.value.path.map((a: string) => {
const year_pattern = /data\/tidi\/(\d{4})\//
return a.match(year_pattern)?.[1]

4
typed-router.d.ts vendored
View File

@ -25,7 +25,8 @@ declare module 'vue-router/auto-routes' {
'/balloon/gravity_wave/1-year': RouteRecordInfo<'/balloon/gravity_wave/1-year', '/balloon/gravity_wave/1-year', Record<never, never>, Record<never, never>>,
'/cosmic/gravity_wave/0-perday': RouteRecordInfo<'/cosmic/gravity_wave/0-perday', '/cosmic/gravity_wave/0-perday', Record<never, never>, Record<never, never>>,
'/cosmic/gravity_wave/1-multiday': RouteRecordInfo<'/cosmic/gravity_wave/1-multiday', '/cosmic/gravity_wave/1-multiday', Record<never, never>, Record<never, never>>,
'/cosmic/planet_wave/0-daily': RouteRecordInfo<'/cosmic/planet_wave/0-daily', '/cosmic/planet_wave/0-daily', Record<never, never>, Record<never, never>>,
'/cosmic/planet_wave/0-perday': RouteRecordInfo<'/cosmic/planet_wave/0-perday', '/cosmic/planet_wave/0-perday', Record<never, never>, Record<never, never>>,
'/cosmic/planet_wave/1-daily': RouteRecordInfo<'/cosmic/planet_wave/1-daily', '/cosmic/planet_wave/1-daily', Record<never, never>, Record<never, never>>,
'/debug': RouteRecordInfo<'/debug', '/debug', Record<never, never>, Record<never, never>>,
'/radar/planet_wave/0-single': RouteRecordInfo<'/radar/planet_wave/0-single', '/radar/planet_wave/0-single', Record<never, never>, Record<never, never>>,
'/radar/planet_wave/1-stats': RouteRecordInfo<'/radar/planet_wave/1-stats', '/radar/planet_wave/1-stats', Record<never, never>, Record<never, never>>,
@ -35,6 +36,7 @@ declare module 'vue-router/auto-routes' {
'/radar/v2': RouteRecordInfo<'/radar/v2', '/radar/v2', Record<never, never>, Record<never, never>>,
'/saber/gravity_wave/0-perday': RouteRecordInfo<'/saber/gravity_wave/0-perday', '/saber/gravity_wave/0-perday', Record<never, never>, Record<never, never>>,
'/saber/gravity_wave/1-monthly': RouteRecordInfo<'/saber/gravity_wave/1-monthly', '/saber/gravity_wave/1-monthly', Record<never, never>, Record<never, never>>,
'/saber/planet_wave/0-perday': RouteRecordInfo<'/saber/planet_wave/0-perday', '/saber/planet_wave/0-perday', Record<never, never>, Record<never, never>>,
'/saber/planet_wave/1-monthly': RouteRecordInfo<'/saber/planet_wave/1-monthly', '/saber/planet_wave/1-monthly', Record<never, never>, Record<never, never>>,
'/tidi/gravity_wave/monthly': RouteRecordInfo<'/tidi/gravity_wave/monthly', '/tidi/gravity_wave/monthly', Record<never, never>, Record<never, never>>,
'/tidi/planet_wave/daily': RouteRecordInfo<'/tidi/planet_wave/daily', '/tidi/planet_wave/daily', Record<never, never>, Record<never, never>>,

View File

@ -11,6 +11,18 @@ import { defineConfig } from 'vite'
import vueDevTools from 'vite-plugin-vue-devtools'
export default defineConfig({
server: {
proxy: {
'/api': {
target: 'http://kuroneko:18200',
},
'/api/ping': {
target: 'ws://kuroneko:18200',
ws: true,
rewriteWsOrigin: false,
},
},
},
resolve: {
alias: {
'~/': `${path.resolve(__dirname, 'src')}/`,