新增注册
This commit is contained in:
parent
09d6ac57fe
commit
d50bd58504
12
package-lock.json
generated
12
package-lock.json
generated
@ -8,7 +8,6 @@
|
|||||||
"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",
|
||||||
@ -891,17 +890,6 @@
|
|||||||
"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,7 +9,6 @@
|
|||||||
"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",
|
||||||
|
90
src/components/items/RegisterDialog.vue
Normal file
90
src/components/items/RegisterDialog.vue
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import {ref} from "vue";
|
||||||
|
import {useLocale} from "vuetify";
|
||||||
|
import {register} from "../../script/functions.ts";
|
||||||
|
|
||||||
|
const {t} = useLocale()
|
||||||
|
const showDialog = defineModel<boolean>('showDialog')
|
||||||
|
const username = ref('')
|
||||||
|
const password = ref('')
|
||||||
|
const confirmPassword = ref('')
|
||||||
|
const isRegisterFailed = ref(false)
|
||||||
|
const registerFailedNote = ref('')
|
||||||
|
const loading = ref(false)
|
||||||
|
const registerIcon = ref<any>(null)
|
||||||
|
const disableRegister = ref(false)
|
||||||
|
|
||||||
|
async function tryRegister() {
|
||||||
|
loading.value = true
|
||||||
|
if (password.value !== confirmPassword.value) {
|
||||||
|
isRegisterFailed.value = true
|
||||||
|
registerFailedNote.value = t('$vuetify.register.passwordConfirmInvalidNote')
|
||||||
|
} else if (!username.value.match(/^[a-zA-Z0-9_-]{4,16}$/)) {
|
||||||
|
isRegisterFailed.value = true
|
||||||
|
registerFailedNote.value = t('$vuetify.register.usernameInvalidNote')
|
||||||
|
} else if (!password.value.match(/^[a-zA-Z0-9_-]{8,}$/)) {
|
||||||
|
isRegisterFailed.value = true
|
||||||
|
registerFailedNote.value = t('$vuetify.register.passwordInvalidNote')
|
||||||
|
} else {
|
||||||
|
isRegisterFailed.value = !await register(username.value, password.value)
|
||||||
|
if (isRegisterFailed.value) {
|
||||||
|
registerFailedNote.value = t('$vuetify.register.failedNote')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loading.value = false
|
||||||
|
if (isRegisterFailed.value == false) {
|
||||||
|
registerIcon.value = "mdi-check"
|
||||||
|
disableRegister.value = true
|
||||||
|
setTimeout(() => {
|
||||||
|
showDialog.value = false
|
||||||
|
registerIcon.value = null
|
||||||
|
loading.value = false
|
||||||
|
disableRegister.value = false
|
||||||
|
}, 1500)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetRegisterFailed() {
|
||||||
|
isRegisterFailed.value = false
|
||||||
|
registerFailedNote.value = ''
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<v-dialog v-model="showDialog" width="450" persistent>
|
||||||
|
<v-card prepend-icon="mdi-account-plus" :title="t('$vuetify.register.title')" class="px-10">
|
||||||
|
<v-text-field class="register-dialog-input" flat hide-details density="compact" single-line rounded="lg"
|
||||||
|
variant="solo-filled" prepend-inner-icon="mdi-account-outline" @input="resetRegisterFailed"
|
||||||
|
:label="t('$vuetify.register.username')" v-model="username"></v-text-field>
|
||||||
|
<v-text-field class="register-dialog-input" flat density="compact" rounded="lg" @input="resetRegisterFailed"
|
||||||
|
variant="solo-filled" prepend-inner-icon="mdi-lock-outline" type="password" hide-details single-line
|
||||||
|
:label="t('$vuetify.register.password')" v-model="password"></v-text-field>
|
||||||
|
<v-text-field class="register-dialog-input" flat hide-details density="compact" single-line rounded="lg"
|
||||||
|
variant="solo-filled" prepend-inner-icon="mdi-lock-check-outline" @input="resetRegisterFailed"
|
||||||
|
:label="t('$vuetify.register.confirmPassword')" v-model="confirmPassword" type="password">
|
||||||
|
</v-text-field>
|
||||||
|
<v-alert v-model="isRegisterFailed" type="warning" class="text-medium-emphasis text-caption mb-2" closable>
|
||||||
|
{{ registerFailedNote }}
|
||||||
|
</v-alert>
|
||||||
|
<v-card color="surface-variant mt-5" variant="tonal">
|
||||||
|
<v-card-text class="text-medium-emphasis text-caption">
|
||||||
|
{{ t('$vuetify.login.agreement') }}
|
||||||
|
<v-label class="text-caption"><a href="/input" target="_blank">{{ t('$vuetify.login.termsOfService') }}</a>
|
||||||
|
</v-label>
|
||||||
|
</v-card-text>
|
||||||
|
</v-card>
|
||||||
|
<v-card-actions>
|
||||||
|
<v-btn :text="t('$vuetify.register.button.cancel')" @click="showDialog = false"></v-btn>
|
||||||
|
<v-btn :text="t('$vuetify.register.button.register')" color="primary" @click="tryRegister"
|
||||||
|
:loading="loading" :disabled="disableRegister" :icon="registerIcon"></v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.register-dialog-input {
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
</style>
|
@ -3,6 +3,7 @@ import {ref} from "vue";
|
|||||||
import {login, logout} from "../../script/functions";
|
import {login, logout} from "../../script/functions";
|
||||||
import {useUserinfoStore} from "../../stores/userinfo-store.ts";
|
import {useUserinfoStore} from "../../stores/userinfo-store.ts";
|
||||||
import {useLocale, useTheme} from "vuetify";
|
import {useLocale, useTheme} from "vuetify";
|
||||||
|
import RegisterDialog from "../items/RegisterDialog.vue";
|
||||||
|
|
||||||
const {t, current} = useLocale()
|
const {t, current} = useLocale()
|
||||||
const theme = useTheme()
|
const theme = useTheme()
|
||||||
@ -14,11 +15,12 @@ const passwordVisibleState = ref(false)
|
|||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const loginDisabled = ref(false)
|
const loginDisabled = ref(false)
|
||||||
const loginIcon = ref<any>(null)
|
const loginIcon = ref<any>(null)
|
||||||
const isLoginFaild = ref(false)
|
const isLoginFailed = ref(false)
|
||||||
|
const showRegisterDialog = ref(false)
|
||||||
|
|
||||||
async function tryLogin() {
|
async function tryLogin() {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
isLoginFaild.value = false
|
isLoginFailed.value = false
|
||||||
const isSuccess = await login(username.value, password.value)
|
const isSuccess = await login(username.value, password.value)
|
||||||
if (isSuccess) {
|
if (isSuccess) {
|
||||||
loginIcon.value = "mdi-check"
|
loginIcon.value = "mdi-check"
|
||||||
@ -30,16 +32,16 @@ async function tryLogin() {
|
|||||||
loginIcon.value = null
|
loginIcon.value = null
|
||||||
}, 1500)
|
}, 1500)
|
||||||
} else {
|
} else {
|
||||||
isLoginFaild.value = true
|
isLoginFailed.value = true
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetLoginError() {
|
function resetLoginError() {
|
||||||
isLoginFaild.value = false
|
isLoginFailed.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
function toogleLocale() {
|
function toggleLocale() {
|
||||||
switch (current.value) {
|
switch (current.value) {
|
||||||
case 'en':
|
case 'en':
|
||||||
current.value = 'zhHans';
|
current.value = 'zhHans';
|
||||||
@ -76,14 +78,15 @@ function toggleTheme() {
|
|||||||
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 icon="mdi-theme-light-dark" class="ml-10" @click="toggleTheme"
|
||||||
v-tooltip="t('$vuetify.menu.themeSwitchTitle')"></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-btn icon="mdi-translate" class="ml-2" @click="toggleLocale"
|
||||||
|
v-tooltip="t('$vuetify.menu.languageSwitchTitle')"></v-btn>
|
||||||
<v-badge dot color="red">
|
<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-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"
|
<v-list-item value="1" @click="showLoginDialog = true; isLoginFailed = false" v-if="!userinfoStore.isLogin"
|
||||||
append-icon="mdi-login">
|
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>
|
||||||
@ -91,6 +94,10 @@ function toggleTheme() {
|
|||||||
append-icon="mdi-logout">
|
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-item value="3" :active="false" @click="showRegisterDialog = true" v-if="!userinfoStore.isLogin"
|
||||||
|
append-icon="mdi-account-plus">
|
||||||
|
<v-list-item-title>{{ t('$vuetify.user.register') }}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
</v-list>
|
</v-list>
|
||||||
</v-menu>
|
</v-menu>
|
||||||
</v-container>
|
</v-container>
|
||||||
@ -105,20 +112,20 @@ function toggleTheme() {
|
|||||||
</v-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="450">
|
||||||
<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"
|
<v-text-field class="login-dialog-input" flat prepend-inner-icon="mdi-account-outline"
|
||||||
:label="t('$vuetify.login.username')"
|
: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"
|
<v-text-field class="login-dialog-input" flat prepend-inner-icon="mdi-lock-outline"
|
||||||
:label="t('$vuetify.login.password')"
|
: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" closable v-model="isLoginFailed">
|
||||||
v-model="isLoginFaild">{{ t('$vuetify.login.failedNote') }}
|
{{ t('$vuetify.login.failedNote') }}
|
||||||
</v-alert>
|
</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">
|
||||||
@ -128,10 +135,9 @@ function toggleTheme() {
|
|||||||
</v-card-text>
|
</v-card-text>
|
||||||
</v-card>
|
</v-card>
|
||||||
|
|
||||||
<v-checkbox class="login-dialong-input" :label="t('$vuetify.login.rememberMe')" hide-details
|
<v-checkbox class="login-dialog-input" :label="t('$vuetify.login.rememberMe')" hide-details
|
||||||
color="primary"></v-checkbox>
|
color="primary"></v-checkbox>
|
||||||
<v-card-actions>
|
<v-card-actions>
|
||||||
<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"
|
<v-btn :loading="loading" color="primary" :text="t('$vuetify.login.button.login')" @click="tryLogin"
|
||||||
:icon="loginIcon"
|
:icon="loginIcon"
|
||||||
@ -140,6 +146,7 @@ function toggleTheme() {
|
|||||||
</v-card-actions>
|
</v-card-actions>
|
||||||
</v-card>
|
</v-card>
|
||||||
</v-dialog>
|
</v-dialog>
|
||||||
|
<RegisterDialog v-model:showDialog="showRegisterDialog"></RegisterDialog>
|
||||||
</template>
|
</template>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.home-search-box {
|
.home-search-box {
|
||||||
@ -147,7 +154,7 @@ function toggleTheme() {
|
|||||||
min-width: 200px;
|
min-width: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-dialong-input {
|
.login-dialog-input {
|
||||||
margin: 10px 0;
|
margin: 10px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,32 +1,10 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref} from "vue";
|
import RegisterDialog from "../items/RegisterDialog.vue";
|
||||||
|
|
||||||
const showDialog = ref(true)
|
|
||||||
const passwordVisibleState = ref(false)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<v-dialog v-model="showDialog" persistent width="500">
|
<RegisterDialog></RegisterDialog>
|
||||||
<v-card prepend-icon="mdi-login" title="LOGIN" class="px-10">
|
|
||||||
<v-text-field class="login-dialong-input" flat prepend-icon="mdi-account" label="USERNAME" density="compact"
|
|
||||||
hide-details single-line
|
|
||||||
rounded="lg" variant="solo-filled"></v-text-field>
|
|
||||||
<v-text-field class="login-dialong-input" flat prepend-icon="mdi-lock" label="PASSWORD" density="compact"
|
|
||||||
hide-details single-line
|
|
||||||
rounded="lg" variant="solo-filled" :type="passwordVisibleState ? 'text' :'password'"
|
|
||||||
:append-inner-icon="passwordVisibleState ? 'mdi-eye-off' : 'mdi-eye'"
|
|
||||||
@click:append-inner="passwordVisibleState = !passwordVisibleState"></v-text-field>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-spacer></v-spacer>
|
|
||||||
<v-btn text="CANCEL" @click="showDialog = false"></v-btn>
|
|
||||||
<v-btn color="primary" text="OK" @click="showDialog = false"></v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</v-dialog>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.login-dialong-input {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
@ -54,6 +54,24 @@ async function login(username: string, password: string): Promise<boolean> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function register(username: string, password: string): Promise<boolean> {
|
||||||
|
const responsePromise = request('reg', {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({username, password}),
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
mode: 'cors'
|
||||||
|
})
|
||||||
|
try {
|
||||||
|
const response = await responsePromise
|
||||||
|
const body: Msg = await response.json()
|
||||||
|
return body.code == 0
|
||||||
|
} catch (_) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function logout() {
|
function logout() {
|
||||||
const userinfoStore = useUserinfoStore()
|
const userinfoStore = useUserinfoStore()
|
||||||
userinfoStore.setToken('')
|
userinfoStore.setToken('')
|
||||||
@ -64,12 +82,12 @@ async function checkLogin(): Promise<boolean> {
|
|||||||
const userinfoStore = useUserinfoStore()
|
const userinfoStore = useUserinfoStore()
|
||||||
if (userinfoStore.isLogin) {
|
if (userinfoStore.isLogin) {
|
||||||
try {
|
try {
|
||||||
const reponse = await request('loginCheck', {
|
const response = await request('loginCheck', {
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Bearer ${userinfoStore.token}`
|
'Authorization': `Bearer ${userinfoStore.token}`
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const body: Msg = await reponse.json()
|
const body: Msg = await response.json()
|
||||||
return body.code == 0
|
return body.code == 0
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
return false
|
return false
|
||||||
@ -79,4 +97,4 @@ async function checkLogin(): Promise<boolean> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export {request, login, logout, checkLogin}
|
export {request, login, logout, checkLogin, register}
|
@ -12,7 +12,8 @@ const en: LocaleInterface = {
|
|||||||
},
|
},
|
||||||
user: {
|
user: {
|
||||||
login: 'Login',
|
login: 'Login',
|
||||||
logout: 'Logout'
|
logout: 'Logout',
|
||||||
|
register: 'Register'
|
||||||
},
|
},
|
||||||
login: {
|
login: {
|
||||||
title: 'Login',
|
title: 'Login',
|
||||||
@ -26,6 +27,23 @@ const en: LocaleInterface = {
|
|||||||
login: 'LOGIN',
|
login: 'LOGIN',
|
||||||
cancel: 'CANCEL'
|
cancel: 'CANCEL'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
register: {
|
||||||
|
title: "REGISTER",
|
||||||
|
username: "USERNAME",
|
||||||
|
password: "PASSWORD",
|
||||||
|
confirmPassword: "CONFIRM PASSWORD",
|
||||||
|
usernameInvalidNote: "Invalid username format",
|
||||||
|
passwordInvalidNote: "Invalid password format",
|
||||||
|
passwordConfirmInvalidNote: "Password confirmation does not match the password",
|
||||||
|
failedNote: "Register failed",
|
||||||
|
rememberMe: "string",
|
||||||
|
agreement: "string",
|
||||||
|
termsOfService: "string",
|
||||||
|
button: {
|
||||||
|
register: "string",
|
||||||
|
cancel: "string"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export default en
|
export default en
|
@ -9,7 +9,8 @@ export default interface LocaleInterface {
|
|||||||
},
|
},
|
||||||
user: {
|
user: {
|
||||||
login: string,
|
login: string,
|
||||||
logout: string
|
logout: string,
|
||||||
|
register: string
|
||||||
},
|
},
|
||||||
login: {
|
login: {
|
||||||
title: string,
|
title: string,
|
||||||
@ -24,6 +25,23 @@ export default interface LocaleInterface {
|
|||||||
cancel: string
|
cancel: string
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
register: {
|
||||||
|
title: string,
|
||||||
|
username: string,
|
||||||
|
password: string,
|
||||||
|
confirmPassword: string,
|
||||||
|
usernameInvalidNote: string,
|
||||||
|
passwordInvalidNote: string,
|
||||||
|
passwordConfirmInvalidNote: string,
|
||||||
|
failedNote: string,
|
||||||
|
rememberMe: string,
|
||||||
|
agreement: string,
|
||||||
|
termsOfService: string,
|
||||||
|
button: {
|
||||||
|
register: string,
|
||||||
|
cancel: string
|
||||||
|
}
|
||||||
|
}
|
||||||
// ==================
|
// ==================
|
||||||
// vuetify
|
// vuetify
|
||||||
// ==================
|
// ==================
|
||||||
|
@ -12,7 +12,8 @@ const zhHans: LocaleInterface = {
|
|||||||
},
|
},
|
||||||
user: {
|
user: {
|
||||||
login: '登录',
|
login: '登录',
|
||||||
logout: '退出'
|
logout: '退出',
|
||||||
|
register: '注册',
|
||||||
},
|
},
|
||||||
login: {
|
login: {
|
||||||
title: '登录',
|
title: '登录',
|
||||||
@ -26,6 +27,23 @@ const zhHans: LocaleInterface = {
|
|||||||
login: '登录',
|
login: '登录',
|
||||||
cancel: '取消'
|
cancel: '取消'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
register: {
|
||||||
|
title: "注册",
|
||||||
|
username: "用户名,大小写字母和数字,4-16位",
|
||||||
|
password: "密码,大小写字母、数字、下划线,8-16位",
|
||||||
|
confirmPassword: "确认密码",
|
||||||
|
usernameInvalidNote: "用户名不符合规则",
|
||||||
|
passwordInvalidNote: "密码不符合规则",
|
||||||
|
passwordConfirmInvalidNote: "两次输入的密码不一致",
|
||||||
|
failedNote: "注册失败, 用户名重复或网络异常",
|
||||||
|
rememberMe: "string",
|
||||||
|
agreement: "string",
|
||||||
|
termsOfService: "string",
|
||||||
|
button: {
|
||||||
|
register: "注册",
|
||||||
|
cancel: "取消"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export default zhHans
|
export default zhHans
|
Loading…
Reference in New Issue
Block a user