update: iter 1.5
This commit is contained in:
parent
7783049690
commit
b8e4e63cf1
2
auto-imports.d.ts
vendored
2
auto-imports.d.ts
vendored
@ -8,6 +8,7 @@ export {}
|
||||
declare global {
|
||||
const EffectScope: typeof import('vue')['EffectScope']
|
||||
const asyncComputed: typeof import('@vueuse/core')['asyncComputed']
|
||||
const authCode: typeof import('./src/composables/fetch')['authCode']
|
||||
const autoResetRef: typeof import('@vueuse/core')['autoResetRef']
|
||||
const baseFetch: typeof import('./src/composables/fetch')['baseFetch']
|
||||
const computed: typeof import('vue')['computed']
|
||||
@ -309,6 +310,7 @@ declare module 'vue' {
|
||||
interface ComponentCustomProperties {
|
||||
readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']>
|
||||
readonly asyncComputed: UnwrapRef<typeof import('@vueuse/core')['asyncComputed']>
|
||||
readonly authCode: UnwrapRef<typeof import('./src/composables/fetch')['authCode']>
|
||||
readonly autoResetRef: UnwrapRef<typeof import('@vueuse/core')['autoResetRef']>
|
||||
readonly baseFetch: UnwrapRef<typeof import('./src/composables/fetch')['baseFetch']>
|
||||
readonly computed: UnwrapRef<typeof import('vue')['computed']>
|
||||
|
||||
1
components.d.ts
vendored
1
components.d.ts
vendored
@ -14,6 +14,7 @@ declare module 'vue' {
|
||||
Alert: typeof import('./src/components/ui/alert/Alert.vue')['default']
|
||||
AlertDescription: typeof import('./src/components/ui/alert/AlertDescription.vue')['default']
|
||||
AlertTitle: typeof import('./src/components/ui/alert/AlertTitle.vue')['default']
|
||||
AuthBlock: typeof import('./src/components/AuthBlock.vue')['default']
|
||||
AutoForm: typeof import('./src/components/ui/auto-form/AutoForm.vue')['default']
|
||||
AutoFormField: typeof import('./src/components/ui/auto-form/AutoFormField.vue')['default']
|
||||
AutoFormFieldArray: typeof import('./src/components/ui/auto-form/AutoFormFieldArray.vue')['default']
|
||||
|
||||
40
src/App.vue
40
src/App.vue
@ -34,7 +34,22 @@ import {
|
||||
SidebarProvider,
|
||||
SidebarRail,
|
||||
} from '~/components/ui/sidebar'
|
||||
import { authCode } from './composables'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
function logout() {
|
||||
localStorage.clear()
|
||||
sessionStorage.clear()
|
||||
authCode.value = ''
|
||||
router.push('/auth')
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (!authCode.value) {
|
||||
router.push('/auth')
|
||||
}
|
||||
})
|
||||
// This is sample data.
|
||||
const data = {
|
||||
user: {
|
||||
@ -60,7 +75,7 @@ const data = {
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Saber',
|
||||
title: 'SABER',
|
||||
url: '#',
|
||||
icon: 'game-icons:cracked-saber',
|
||||
isActive: true,
|
||||
@ -139,15 +154,14 @@ const data = {
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div>
|
||||
<!-- <TopHeader /> -->
|
||||
<div v-if="$route.path === '/auth'">
|
||||
<RouterView />
|
||||
</div>
|
||||
<div>
|
||||
<div v-else>
|
||||
<SidebarProvider>
|
||||
<Sidebar collapsible="icon">
|
||||
<SidebarHeader>
|
||||
<Alert>
|
||||
<Terminal class="h-4 w-4" />
|
||||
<AlertTitle>服务状态正常</AlertTitle>
|
||||
</Alert>
|
||||
</SidebarHeader>
|
||||
@ -183,6 +197,7 @@ const data = {
|
||||
:to="subItem.url"
|
||||
active-class="bg-accent-foreground text-accent"
|
||||
>
|
||||
<span> </span>
|
||||
<span>{{ subItem.title }}</span>
|
||||
</RouterLink>
|
||||
</SidebarMenuSubButton>
|
||||
@ -210,11 +225,16 @@ const data = {
|
||||
<ChevronsUpDown class="ml-auto size-4" />
|
||||
</SidebarMenuButton>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent class="min-w-56 w-[--radix-dropdown-menu-trigger-width] rounded-lg" side="bottom" align="end" :side-offset="4">
|
||||
<DropdownMenuItem>
|
||||
<Icon icon="heroicons-solid:logout" class="h-4 w-4" />
|
||||
退出系统
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuContent
|
||||
class="min-w-56 w-[--radix-dropdown-menu-trigger-width] rounded-lg" side="bottom" align="end"
|
||||
:side-offset="4"
|
||||
>
|
||||
<div @click="logout">
|
||||
<DropdownMenuItem>
|
||||
<Icon icon="heroicons-solid:logout" class="h-4 w-4" />
|
||||
退出系统
|
||||
</DropdownMenuItem>
|
||||
</div>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
<Button variant="outline" size="icon" class="ml-auto h-8 w-8">
|
||||
|
||||
@ -1,2 +1,3 @@
|
||||
export const API_BASE_URL = 'http://localhost:5000'
|
||||
// export const API_BASE_URL = 'https://gca-api.dustella.net:8443'
|
||||
// export const API_BASE_URL = 'http://localhost:5000'
|
||||
// export const API_BASE_URL = 'http://localhost:18200'
|
||||
export const API_BASE_URL = 'https://gca-api.dustella.net:8443'
|
||||
|
||||
BIN
src/assets/map.avif
Normal file
BIN
src/assets/map.avif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 124 KiB |
77
src/components/AuthBlock.vue
Normal file
77
src/components/AuthBlock.vue
Normal file
@ -0,0 +1,77 @@
|
||||
<script setup lang="ts">
|
||||
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('')
|
||||
const router = useRouter()
|
||||
const remember = ref(false)
|
||||
|
||||
function auth() {
|
||||
authCode.value = code.value
|
||||
const resp = baseFetch(`${API_BASE_URL}/ping`, {
|
||||
})
|
||||
if (!resp.error.value) {
|
||||
if (remember.value) {
|
||||
localStorage.setItem('authCode', code.value)
|
||||
}
|
||||
else {
|
||||
sessionStorage.setItem('authCode', code.value)
|
||||
}
|
||||
router.push('/')
|
||||
return
|
||||
}
|
||||
// eslint-disable-next-line no-alert
|
||||
alert('认证失败')
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-full lg:grid lg:grid-cols-2 lg:min-h-[600px] xl:min-h-[800px]">
|
||||
<div class="hidden p-30 lg:block">
|
||||
<img
|
||||
:src="manba"
|
||||
alt="Image"
|
||||
class="h-full w-full object-cover dark:brightness-[0.2] dark:grayscale"
|
||||
>
|
||||
</div>
|
||||
<div class="flex items-center justify-center bg-muted py-12">
|
||||
<div class="grid mx-auto w-[350px] gap-6">
|
||||
<div class="grid gap-2 text-center">
|
||||
<h1 class="text-3xl font-bold">
|
||||
系统认证
|
||||
</h1>
|
||||
<p class="text-balance text-muted-foreground">
|
||||
本系统仅供内部使用
|
||||
</p>
|
||||
</div>
|
||||
<div class="grid gap-4">
|
||||
<div class="grid gap-2">
|
||||
<div class="flex items-center">
|
||||
<Label for="password">口令</Label>
|
||||
</div>
|
||||
<Input id="password" v-model="code" type="password" required />
|
||||
</div>
|
||||
<div flex="~ items-center gap-2">
|
||||
<Checkbox id="remember" v-model="remember" />
|
||||
<Label for="remember" class="flex items-center">
|
||||
记住我
|
||||
</Label>
|
||||
</div>
|
||||
<Button type="submit" class="w-full" @click.prevent="auth">
|
||||
认证
|
||||
</Button>
|
||||
</div>
|
||||
<div class="mt-4 text-center text-sm">
|
||||
丢失密码?请前往后端重置
|
||||
<!-- <a href="#" class="underline">
|
||||
Sign up
|
||||
</a> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -7,9 +7,18 @@ export interface ImageResult {
|
||||
message?: string
|
||||
}
|
||||
|
||||
defineProps<{
|
||||
const props = defineProps<{
|
||||
imageResult: ImageResult
|
||||
}>()
|
||||
|
||||
function download() {
|
||||
if (props.imageResult.result === 'success') {
|
||||
const a = document.createElement('a')
|
||||
a.href = props.imageResult.imageUrl
|
||||
a.download = 'image.png'
|
||||
a.click()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -26,7 +35,7 @@ defineProps<{
|
||||
{{ imageResult.message }}
|
||||
</div>
|
||||
|
||||
<Button type="submit" size="sm" class="ml-auto gap-1.5">
|
||||
<Button type="submit" size="sm" class="ml-auto gap-1.5" @click.prevent="download">
|
||||
下载图片
|
||||
<CornerDownLeft class="size-3.5" />
|
||||
</Button>
|
||||
|
||||
@ -1,6 +1,12 @@
|
||||
import { createFetch } from '@vueuse/core'
|
||||
import { API_BASE_URL } from '~/CONSTANT'
|
||||
|
||||
export const authCode = ref(
|
||||
localStorage.getItem('authCode')
|
||||
|| sessionStorage.getItem('authCode')
|
||||
|| '',
|
||||
)
|
||||
|
||||
export const baseFetch = createFetch({
|
||||
baseUrl: API_BASE_URL,
|
||||
options: {
|
||||
|
||||
12
src/pages/auth.vue
Normal file
12
src/pages/auth.vue
Normal file
@ -0,0 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<AuthBlock />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -37,10 +37,28 @@ const modes = [
|
||||
'Temperature amplitude (K)',
|
||||
'纬向动量通量统计结果',
|
||||
'经向动量通量统计结果',
|
||||
'horizontal propagation',
|
||||
'每月上传/下传重力波占比',
|
||||
'动能和势能分布情况',
|
||||
]
|
||||
// 'horizontal propagation',
|
||||
// '每月上传/下传重力波占比',
|
||||
// '动能和势能分布情况',
|
||||
] as const
|
||||
|
||||
const mode_display_mapping = {
|
||||
'w/f值统计结果': '本征频率与惯性频率的比值',
|
||||
'周期统计结果': '周期统计',
|
||||
'垂直波长分布': '垂直波长',
|
||||
'水平波长分布': '水平波长',
|
||||
'纬向本征相速度': '纬向本征相速度',
|
||||
'经向本征相速度': '经向本征相速度',
|
||||
'垂直本征相速度': '垂直本征相速度',
|
||||
'Zonal wind amplitude (m/s)': '纬向风扰动幅度',
|
||||
'扰动振幅统计结果': '经向风扰动幅度',
|
||||
'Temperature amplitude (K)': '温度扰动振幅',
|
||||
'纬向动量通量统计结果': '纬向动量通量统计',
|
||||
'经向动量通量统计结果': '经向动量通量统计',
|
||||
'horizontal propagation': 'horizontal propagation',
|
||||
'每月上传/下传重力波占比': '每月上传/下传重力波占比',
|
||||
'动能和势能分布情况': '动能和势能分布情况',
|
||||
}
|
||||
|
||||
async function refreshImage() {
|
||||
const url = `${API_BASE_URL}/balloon/render/year?mode=${encodeURIComponent(selectedMode.value)}&start_year=${startYear.value}&end_year=${endYear.value}`
|
||||
@ -57,7 +75,6 @@ watch([selectedMode, startYear, endYear], () => {
|
||||
return
|
||||
}
|
||||
isIllegal.value = false
|
||||
refreshImage()
|
||||
})
|
||||
</script>
|
||||
|
||||
@ -65,16 +82,21 @@ watch([selectedMode, startYear, endYear], () => {
|
||||
<DenseFramework :image-result="imageResult" @submit="refreshImage">
|
||||
<div flex="col gap-5 ~ justify-center">
|
||||
<div>
|
||||
<Label>计算模式</Label>
|
||||
<Label>统计参数</Label>
|
||||
<Select v-model="selectedMode">
|
||||
<SelectTrigger class="w-[180px]">
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select a fruit" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectLabel>模式</SelectLabel>
|
||||
<SelectItem v-for="mode in modes" :key="mode" :value="mode">
|
||||
{{ mode }}
|
||||
<SelectItem
|
||||
v-for="mode in Array.from(modes).sort(((a, b) => {
|
||||
return mode_display_mapping[a].length - mode_display_mapping[b].length
|
||||
}))"
|
||||
:key="mode" :value="mode"
|
||||
>
|
||||
{{ mode_display_mapping[mode] }}
|
||||
</SelectItem>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
|
||||
@ -46,7 +46,7 @@ onFetchResponse(async (resp) => {
|
||||
|
||||
<template>
|
||||
<DenseFramework :image-result="imageResult" @submit="execute">
|
||||
<Label for="T_range">滑动窗口</Label>
|
||||
<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">
|
||||
|
||||
@ -1,3 +1,15 @@
|
||||
<route lang="json">
|
||||
{
|
||||
"meta":{
|
||||
"title":"TIDI 行星波月统计",
|
||||
"icon":"mdi:telescope",
|
||||
"group":"TIDI",
|
||||
"item_name":"行星波月统计"
|
||||
|
||||
}
|
||||
}
|
||||
</route>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { ImageResult } from '~/components/ImageContainer.vue'
|
||||
import { API_BASE_URL } from '~/CONSTANT'
|
||||
|
||||
1
typed-router.d.ts
vendored
1
typed-router.d.ts
vendored
@ -20,6 +20,7 @@ declare module 'vue-router/auto-routes' {
|
||||
export interface RouteNamedMap {
|
||||
'/': RouteRecordInfo<'/', '/', Record<never, never>, Record<never, never>>,
|
||||
'/[...all]': RouteRecordInfo<'/[...all]', '/:all(.*)', { all: ParamValue<true> }, { all: ParamValue<false> }>,
|
||||
'/auth': RouteRecordInfo<'/auth', '/auth', Record<never, never>, Record<never, never>>,
|
||||
'/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>>,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user