引入ky
This commit is contained in:
parent
2707070af5
commit
db3872cc3a
12
package-lock.json
generated
12
package-lock.json
generated
@ -8,6 +8,7 @@
|
|||||||
"name": "surl-front",
|
"name": "surl-front",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"ky": "^1.5.0",
|
||||||
"pinia": "^2.2.0",
|
"pinia": "^2.2.0",
|
||||||
"vite-plugin-vuetify": "^2.0.3",
|
"vite-plugin-vuetify": "^2.0.3",
|
||||||
"vue": "^3.4.31",
|
"vue": "^3.4.31",
|
||||||
@ -890,6 +891,17 @@
|
|||||||
"he": "bin/he"
|
"he": "bin/he"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ky": {
|
||||||
|
"version": "1.5.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/ky/-/ky-1.5.0.tgz",
|
||||||
|
"integrity": "sha512-bkQo+UqryW6Zmo/DsixYZE4Z9t2mzvNMhceyIhuMuInb3knm5Q+GNGMKveydJAj+Z6piN1SwI6eR/V0G+Z0BtA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sindresorhus/ky?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/magic-string": {
|
"node_modules/magic-string": {
|
||||||
"version": "0.30.10",
|
"version": "0.30.10",
|
||||||
"resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.10.tgz",
|
"resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.10.tgz",
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"ky": "^1.5.0",
|
||||||
"pinia": "^2.2.0",
|
"pinia": "^2.2.0",
|
||||||
"vite-plugin-vuetify": "^2.0.3",
|
"vite-plugin-vuetify": "^2.0.3",
|
||||||
"vue": "^3.4.31",
|
"vue": "^3.4.31",
|
||||||
|
@ -54,12 +54,11 @@ function toogleLocale() {
|
|||||||
localStorage.setItem('locale', current.value)
|
localStorage.setItem('locale', current.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleTheme () {
|
function toggleTheme() {
|
||||||
const currentTheme = theme.global.current.value.dark ? 'light' : 'dark'
|
const currentTheme = theme.global.current.value.dark ? 'light' : 'dark'
|
||||||
theme.global.name.value = currentTheme
|
theme.global.name.value = currentTheme
|
||||||
localStorage.setItem('theme', currentTheme)
|
localStorage.setItem('theme', currentTheme)
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -67,21 +66,29 @@ function toggleTheme () {
|
|||||||
<v-app>
|
<v-app>
|
||||||
<v-app-bar>
|
<v-app-bar>
|
||||||
<v-container class="mx-auto d-flex align-center justify-start">
|
<v-container class="mx-auto d-flex align-center justify-start">
|
||||||
<v-btn class="home-menu-button" :text="t('$vuetify.menu.home')" to="/" :active="false" prepend-icon="mdi-home"></v-btn>
|
<v-btn class="home-menu-button" :text="t('$vuetify.menu.home')" to="/" :active="false"
|
||||||
<v-btn class="home-menu-button" :text="t('$vuetify.menu.services')" to="/services" :active="false"></v-btn>
|
prepend-icon="mdi-home"></v-btn>
|
||||||
|
<v-btn class="home-menu-button" :text="t('$vuetify.menu.services')" to="/services" :active="false"
|
||||||
|
prepend-icon="mdi-database"></v-btn>
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
<v-text-field class="home-search-box" density="compact" :label="t('$vuetify.menu.search')" rounded="lg"
|
<v-text-field class="home-search-box" density="compact" :label="t('$vuetify.menu.search')" rounded="lg"
|
||||||
variant="solo-filled"
|
variant="solo-filled"
|
||||||
flat hide-details single-line append-inner-icon="mdi-magnify"></v-text-field>
|
flat hide-details single-line append-inner-icon="mdi-magnify"></v-text-field>
|
||||||
<v-btn icon="mdi-theme-light-dark" class="ml-10" @click="toggleTheme"></v-btn>
|
<v-btn icon="mdi-theme-light-dark" class="ml-10" @click="toggleTheme"
|
||||||
<v-btn icon="mdi-translate" class="ml-2" @click="toogleLocale"></v-btn>
|
v-tooltip="t('$vuetify.menu.themeSwitchTitle')"></v-btn>
|
||||||
|
<v-btn icon="mdi-translate" class="ml-2" @click="toogleLocale" v-tooltip="t('$vuetify.menu.languageSwitchTitle')"></v-btn>
|
||||||
|
<v-badge dot color="red">
|
||||||
<v-btn icon="mdi-account" class="ml-2" id="avatar"></v-btn>
|
<v-btn icon="mdi-account" class="ml-2" id="avatar"></v-btn>
|
||||||
|
</v-badge>
|
||||||
|
|
||||||
<v-menu open-on-hover activator="#avatar" open-delay="0" close-delay="500" location="bottom" width="150">
|
<v-menu open-on-hover activator="#avatar" open-delay="0" close-delay="500" location="bottom" width="150">
|
||||||
<v-list>
|
<v-list>
|
||||||
<v-list-item value="1" @click="showLoginDialog = true; isLoginFaild = false" v-if="!userinfoStore.isLogin" append-icon="mdi-login">
|
<v-list-item value="1" @click="showLoginDialog = true; isLoginFaild = false" v-if="!userinfoStore.isLogin"
|
||||||
|
append-icon="mdi-login">
|
||||||
<v-list-item-title>{{ t('$vuetify.user.login') }}</v-list-item-title>
|
<v-list-item-title>{{ t('$vuetify.user.login') }}</v-list-item-title>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
<v-list-item value="2" :active="false" @click="logout" v-if="userinfoStore.isLogin" append-icon="mdi-logout">
|
<v-list-item value="2" :active="false" @click="logout" v-if="userinfoStore.isLogin"
|
||||||
|
append-icon="mdi-logout">
|
||||||
<v-list-item-title>{{ t('$vuetify.user.logout') }}</v-list-item-title>
|
<v-list-item-title>{{ t('$vuetify.user.logout') }}</v-list-item-title>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
</v-list>
|
</v-list>
|
||||||
@ -91,32 +98,39 @@ function toggleTheme () {
|
|||||||
<v-main class="px-10">
|
<v-main class="px-10">
|
||||||
<router-view/>
|
<router-view/>
|
||||||
</v-main>
|
</v-main>
|
||||||
|
<v-footer>footer</v-footer>
|
||||||
</v-app>
|
</v-app>
|
||||||
</v-responsive>
|
</v-responsive>
|
||||||
<v-dialog v-model="showLoginDialog" persistent width="400">
|
<v-dialog v-model="showLoginDialog" persistent width="400">
|
||||||
<v-card prepend-icon="mdi-login" :title="t('$vuetify.login.title')" class="px-10">
|
<v-card prepend-icon="mdi-login" :title="t('$vuetify.login.title')" class="px-10">
|
||||||
<v-text-field class="login-dialong-input" flat prepend-inner-icon="mdi-account-outline" :label="t('$vuetify.login.username')"
|
<v-text-field class="login-dialong-input" flat prepend-inner-icon="mdi-account-outline"
|
||||||
|
:label="t('$vuetify.login.username')"
|
||||||
density="compact" @input="resetLoginError"
|
density="compact" @input="resetLoginError"
|
||||||
hide-details single-line rounded="lg" variant="solo-filled" v-model="username"></v-text-field>
|
hide-details single-line rounded="lg" variant="solo-filled" v-model="username"></v-text-field>
|
||||||
<v-text-field class="login-dialong-input" flat prepend-inner-icon="mdi-lock-outline" :label="t('$vuetify.login.password')"
|
<v-text-field class="login-dialong-input" flat prepend-inner-icon="mdi-lock-outline"
|
||||||
|
:label="t('$vuetify.login.password')"
|
||||||
density="compact" hide-details single-line v-model="password" rounded="lg" variant="solo-filled"
|
density="compact" hide-details single-line v-model="password" rounded="lg" variant="solo-filled"
|
||||||
:type="passwordVisibleState ? 'text' :'password'" title="password" @input="resetLoginError"
|
:type="passwordVisibleState ? 'text' :'password'" title="password" @input="resetLoginError"
|
||||||
:append-inner-icon="passwordVisibleState ? 'mdi-eye-off' : 'mdi-eye'"
|
:append-inner-icon="passwordVisibleState ? 'mdi-eye-off' : 'mdi-eye'"
|
||||||
@click:append-inner="passwordVisibleState = !passwordVisibleState"></v-text-field>
|
@click:append-inner="passwordVisibleState = !passwordVisibleState"></v-text-field>
|
||||||
<v-alert class="text-medium-emphasis text-caption mb-2" type="warning" icon="mdi-alert" closable
|
<v-alert class="text-medium-emphasis text-caption mb-2" type="warning" icon="mdi-alert" closable
|
||||||
v-model="isLoginFaild">{{ t('$vuetify.login.failedNote') }}</v-alert>
|
v-model="isLoginFaild">{{ t('$vuetify.login.failedNote') }}
|
||||||
|
</v-alert>
|
||||||
<v-card color="surface-variant mt-5" variant="tonal">
|
<v-card color="surface-variant mt-5" variant="tonal">
|
||||||
<v-card-text class="text-medium-emphasis text-caption">
|
<v-card-text class="text-medium-emphasis text-caption">
|
||||||
{{ t('$vuetify.login.agreement') }}
|
{{ t('$vuetify.login.agreement') }}
|
||||||
<v-label class="text-caption"><a href="/input" target="_blank">{{ t('$vuetify.login.termsOfService') }}</a></v-label>
|
<v-label class="text-caption"><a href="/input" target="_blank">{{ t('$vuetify.login.termsOfService') }}</a>
|
||||||
|
</v-label>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
</v-card>
|
</v-card>
|
||||||
|
|
||||||
<v-checkbox class="login-dialong-input" :label="t('$vuetify.login.rememberMe')" hide-details color="primary"></v-checkbox>
|
<v-checkbox class="login-dialong-input" :label="t('$vuetify.login.rememberMe')" hide-details
|
||||||
|
color="primary"></v-checkbox>
|
||||||
<v-card-actions>
|
<v-card-actions>
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
<v-btn :text="t('$vuetify.login.button.cancel')" @click="showLoginDialog = false"></v-btn>
|
<v-btn :text="t('$vuetify.login.button.cancel')" @click="showLoginDialog = false"></v-btn>
|
||||||
<v-btn :loading="loading" color="primary" :text="t('$vuetify.login.button.login')" @click="tryLogin" :icon="loginIcon"
|
<v-btn :loading="loading" color="primary" :text="t('$vuetify.login.button.login')" @click="tryLogin"
|
||||||
|
:icon="loginIcon"
|
||||||
:disabled="loginDisabled">
|
:disabled="loginDisabled">
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</v-card-actions>
|
</v-card-actions>
|
||||||
@ -134,6 +148,6 @@ function toggleTheme () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.home-menu-button {
|
.home-menu-button {
|
||||||
width: 100px;
|
width: 120px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
@ -1,6 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {request} from "../../script/functions.ts";
|
import {request} from "../../script/functions.ts";
|
||||||
import {ref} from "vue";
|
import {ref, watch} from "vue";
|
||||||
|
|
||||||
interface Urls {
|
interface Urls {
|
||||||
key: string,
|
key: string,
|
||||||
@ -14,14 +14,12 @@ interface Surls {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const urls = ref<Urls[]>([])
|
const urls = ref<Urls[]>([])
|
||||||
|
const selected = ref([])
|
||||||
|
|
||||||
|
watch(selected, () => console.log(selected.value))
|
||||||
|
|
||||||
async function getSurl() {
|
async function getSurl() {
|
||||||
const requestPromise = request('api/surl/get', {
|
const requestPromise = request('api/surl/get')
|
||||||
method: 'GET',
|
|
||||||
headers: {
|
|
||||||
'Authorization': 'Bearer ' + localStorage.getItem('token') || ''
|
|
||||||
}
|
|
||||||
})
|
|
||||||
try {
|
try {
|
||||||
const request = await requestPromise
|
const request = await requestPromise
|
||||||
const body: Surls = await request.json()
|
const body: Surls = await request.json()
|
||||||
@ -34,8 +32,9 @@ async function getSurl() {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<v-btn @click="getSurl">get</v-btn>
|
<v-btn @click="getSurl">get</v-btn>
|
||||||
<v-data-table :items="urls"
|
<v-data-table :items="urls" :item-value="item => item" show-select v-model="selected"
|
||||||
:headers="[{title: 'KEY', value: 'key', key: 'key'}, {title: 'URL', value: 'value', key: 'value'}]">
|
v-slot:header.data-table-select height="400" fixed-header
|
||||||
|
:headers="[{title: 'KEY', value: 'key', key: 'key', align: 'center'}, {title: 'URL', value: 'value', key: 'value'}]">
|
||||||
</v-data-table>
|
</v-data-table>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -16,12 +16,18 @@ interface Msg {
|
|||||||
value?: any
|
value?: any
|
||||||
}
|
}
|
||||||
|
|
||||||
async function request(path: string, init: RequestInit): Promise<Response> {
|
async function request(path: string, init: RequestInit = {}): Promise<Response> {
|
||||||
const useSiteConfig = useSiteConfigStore()
|
const useSiteConfig = useSiteConfigStore()
|
||||||
const siteConfig = useSiteConfig.siteConfig
|
const siteConfig = useSiteConfig.siteConfig
|
||||||
const protocol = siteConfig.protocol
|
const protocol = siteConfig.protocol
|
||||||
const host = siteConfig.host
|
const host = siteConfig.host
|
||||||
return fetch(`${protocol}://${host}/${path}`, init)
|
return fetch(`${protocol}://${host}/${path}`, {
|
||||||
|
...init,
|
||||||
|
headers: {
|
||||||
|
...init.headers,
|
||||||
|
'Authorization': `Bearer ${useUserinfoStore().token}`
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function login(username: string, password: string): Promise<boolean> {
|
async function login(username: string, password: string): Promise<boolean> {
|
||||||
|
Loading…
Reference in New Issue
Block a user