mirror of
https://github.com/nagisa77/OpenIsle.git
synced 2026-02-24 07:00:49 +08:00
feat: email register and login
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
:root {
|
||||
--primary-color-hover: rgb(9, 95, 105);
|
||||
--primary-color: rgb(10, 110, 120);
|
||||
--primary-color-disabled: rgba(93, 152, 156, 0.5);
|
||||
--header-height: 60px;
|
||||
--header-background-color: white;
|
||||
--header-border-color: lightgray;
|
||||
|
||||
@@ -4,13 +4,13 @@ import router from './router'
|
||||
import './assets/global.css'
|
||||
import Toast, { POSITION } from 'vue-toastification'
|
||||
import 'vue-toastification/dist/index.css'
|
||||
import { useToast } from 'vue-toastification'
|
||||
|
||||
// Configurable API domain and port
|
||||
export const API_DOMAIN =
|
||||
process.env.VUE_APP_API_DOMAIN ||
|
||||
`${window.location.protocol}//${window.location.hostname}`
|
||||
export const API_PORT = process.env.VUE_APP_API_PORT || window.location.port
|
||||
export const API_DOMAIN = 'http://127.0.0.1'
|
||||
export const API_PORT = 8081
|
||||
export const API_BASE_URL = API_PORT ? `${API_DOMAIN}:${API_PORT}` : API_DOMAIN
|
||||
export const toast = useToast()
|
||||
|
||||
const app = createApp(App)
|
||||
app.use(router)
|
||||
|
||||
@@ -29,10 +29,17 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div class="login-page-button-primary" @click="submitLogin">
|
||||
<div v-if="!isWaitingForLogin" class="login-page-button-primary" @click="submitLogin">
|
||||
<div class="login-page-button-text">登录</div>
|
||||
</div>
|
||||
|
||||
<div v-else class="login-page-button-primary disabled">
|
||||
<div class="login-page-button-text">
|
||||
<i class="fas fa-spinner fa-spin"></i>
|
||||
登录中...
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="login-page-button-secondary">没有账号? <a class="login-page-button-secondary-link" href="/signup">注册</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -48,33 +55,36 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { API_BASE_URL } from '../main'
|
||||
import { API_BASE_URL, toast } from '../main'
|
||||
export default {
|
||||
name: 'LoginPageView',
|
||||
data() {
|
||||
return {
|
||||
username: '',
|
||||
password: ''
|
||||
password: '',
|
||||
isWaitingForLogin: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async submitLogin() {
|
||||
try {
|
||||
this.isWaitingForLogin = true
|
||||
const res = await fetch(`${API_BASE_URL}/api/auth/login`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ username: this.username, password: this.password })
|
||||
})
|
||||
this.isWaitingForLogin = false
|
||||
const data = await res.json()
|
||||
if (res.ok && data.token) {
|
||||
localStorage.setItem('token', data.token)
|
||||
this.$toast.success('登录成功')
|
||||
toast.success('登录成功')
|
||||
this.$router.push('/')
|
||||
} else {
|
||||
this.$toast.error(data.error || '登录失败')
|
||||
toast.error(data.error || '登录失败')
|
||||
}
|
||||
} catch (e) {
|
||||
this.$toast.error('登录失败')
|
||||
toast.error('登录失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -178,6 +188,16 @@ export default {
|
||||
background-color: var(--primary-color-hover);
|
||||
}
|
||||
|
||||
.login-page-button-primary.disabled {
|
||||
background-color: var(--primary-color-disabled);
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.login-page-button-primary.disabled:hover {
|
||||
background-color: var(--primary-color-disabled);
|
||||
}
|
||||
|
||||
.login-page-button {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
@@ -54,9 +54,15 @@
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="signup-page-button-primary" @click="sendVerification">
|
||||
<div v-if="!isWaitingForEmailSent" class="signup-page-button-primary" @click="sendVerification">
|
||||
<div class="signup-page-button-text">验证邮箱</div>
|
||||
</div>
|
||||
<div v-else class="signup-page-button-primary disabled">
|
||||
<div class="signup-page-button-text">
|
||||
<i class="fas fa-spinner fa-spin"></i>
|
||||
发送中...
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="signup-page-button-secondary">已经有账号? <a class="signup-page-button-secondary-link"
|
||||
href="/login">登录</a></div>
|
||||
@@ -72,9 +78,15 @@
|
||||
placeholder="邮箱验证码"
|
||||
>
|
||||
</div>
|
||||
<div class="signup-page-button-primary" @click="verifyCode">
|
||||
<div v-if="!isWaitingForEmailVerified" class="signup-page-button-primary" @click="verifyCode">
|
||||
<div class="signup-page-button-text">注册</div>
|
||||
</div>
|
||||
<div v-else class="signup-page-button-primary disabled">
|
||||
<div class="signup-page-button-text">
|
||||
<i class="fas fa-spinner fa-spin"></i>
|
||||
验证中...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -88,7 +100,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { API_BASE_URL } from '../main'
|
||||
import { API_BASE_URL, toast } from '../main'
|
||||
export default {
|
||||
name: 'SignupPageView',
|
||||
|
||||
@@ -102,7 +114,9 @@ export default {
|
||||
usernameError: '',
|
||||
passwordError: '',
|
||||
nickname: '',
|
||||
code: ''
|
||||
code: '',
|
||||
isWaitingForEmailSent: false,
|
||||
isWaitingForEmailVerified: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -127,46 +141,51 @@ export default {
|
||||
return
|
||||
}
|
||||
try {
|
||||
console.log('base url: ', API_BASE_URL)
|
||||
this.isWaitingForEmailSent = true
|
||||
const res = await fetch(`${API_BASE_URL}/api/auth/register`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
username: this.username,
|
||||
email: this.email,
|
||||
password: this.password
|
||||
password: this.password,
|
||||
})
|
||||
})
|
||||
this.isWaitingForEmailSent = false
|
||||
const data = await res.json()
|
||||
if (res.ok) {
|
||||
this.emailStep = 1
|
||||
this.$toast.success('验证码已发送,请查看邮箱')
|
||||
toast.success('验证码已发送,请查看邮箱')
|
||||
} else if (data.field) {
|
||||
if (data.field === 'username') this.usernameError = data.error
|
||||
if (data.field === 'email') this.emailError = data.error
|
||||
if (data.field === 'password') this.passwordError = data.error
|
||||
} else {
|
||||
this.$toast.error(data.error || '发送失败')
|
||||
toast.error(data.error || '发送失败')
|
||||
}
|
||||
} catch (e) {
|
||||
this.$toast.error('发送失败')
|
||||
toast.error('发送失败')
|
||||
}
|
||||
},
|
||||
async verifyCode() {
|
||||
try {
|
||||
this.isWaitingForEmailVerified = true
|
||||
const res = await fetch(`${API_BASE_URL}/api/auth/verify`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ username: this.username, code: this.code })
|
||||
})
|
||||
this.isWaitingForEmailVerified = false
|
||||
const data = await res.json()
|
||||
if (res.ok) {
|
||||
this.$toast.success('注册成功,请登录')
|
||||
toast.success('注册成功,请登录')
|
||||
this.$router.push('/login')
|
||||
} else {
|
||||
this.$toast.error(data.error || '注册失败')
|
||||
toast.error(data.error || '注册失败')
|
||||
}
|
||||
} catch (e) {
|
||||
this.$toast.error('注册失败')
|
||||
toast.error('注册失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -266,6 +285,16 @@ export default {
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.signup-page-button-primary.disabled {
|
||||
background-color: var(--primary-color-disabled);
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.signup-page-button-primary.disabled:hover {
|
||||
background-color: var(--primary-color-disabled);
|
||||
}
|
||||
|
||||
.signup-page-button-primary:hover {
|
||||
background-color: var(--primary-color-hover);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user