update
This commit is contained in:
parent
50f7272230
commit
613aca84cb
@ -8,7 +8,11 @@
|
||||
"build": "vite build",
|
||||
"serve": "vite preview"
|
||||
},
|
||||
"keywords": ["vue", "meida", "fashion"],
|
||||
"keywords": [
|
||||
"vue",
|
||||
"meida",
|
||||
"fashion"
|
||||
],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
@ -16,6 +20,7 @@
|
||||
"axios": "^1.8.4",
|
||||
"vite": "^6.3.0",
|
||||
"vue": "^3.5.13",
|
||||
"vue-router": "^4.5.0"
|
||||
"vue-router": "^4.5.0",
|
||||
"vuex": "^4.1.0"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import store from './store'
|
||||
import './assets/main.css'
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
app.use(router)
|
||||
app.use(store)
|
||||
app.mount('#app')
|
||||
@ -1,5 +1,6 @@
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import Home from '../views/Home.vue'
|
||||
import store from '../store'
|
||||
|
||||
const routes = [
|
||||
{
|
||||
@ -7,10 +8,23 @@ const routes = [
|
||||
name: 'home',
|
||||
component: Home
|
||||
},
|
||||
{
|
||||
path: '/password',
|
||||
name: 'password',
|
||||
component: () => import('../views/PasswordProtection.vue')
|
||||
},
|
||||
{
|
||||
path: '/tryon-history',
|
||||
name: 'tryon-history',
|
||||
component: () => import('../views/TryonHistory.vue')
|
||||
component: () => import('../views/TryonHistory.vue'),
|
||||
meta: { requiresAuth: true },
|
||||
beforeEnter: (to, from, next) => {
|
||||
if (store.getters.isAuthenticated) {
|
||||
next()
|
||||
} else {
|
||||
next('/password')
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
30
src/store/index.js
Normal file
30
src/store/index.js
Normal file
@ -0,0 +1,30 @@
|
||||
import { createStore } from 'vuex'
|
||||
|
||||
const store = createStore({
|
||||
state: {
|
||||
isAuthenticated: false
|
||||
},
|
||||
mutations: {
|
||||
setAuthenticated(state, value) {
|
||||
state.isAuthenticated = value
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
authenticate({ commit }, password) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (password === '147258') {
|
||||
commit('setAuthenticated', true)
|
||||
resolve(true)
|
||||
} else {
|
||||
commit('setAuthenticated', false)
|
||||
reject(new Error('密码错误'))
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
isAuthenticated: state => state.isAuthenticated
|
||||
}
|
||||
})
|
||||
|
||||
export default store
|
||||
@ -3,7 +3,7 @@
|
||||
<div class="hero">
|
||||
<h1>欢迎使用美搭</h1>
|
||||
<p>您的个人时尚穿搭助手</p>
|
||||
<router-link to="/tryon-history" class="btn btn-primary">查看穿搭历史</router-link>
|
||||
<router-link to="/password" class="btn btn-primary">查看穿搭历史</router-link>
|
||||
</div>
|
||||
|
||||
<div class="features mt-20">
|
||||
|
||||
115
src/views/PasswordProtection.vue
Normal file
115
src/views/PasswordProtection.vue
Normal file
@ -0,0 +1,115 @@
|
||||
<template>
|
||||
<div class="password-protection">
|
||||
<div class="password-form card">
|
||||
<h2>访问受限</h2>
|
||||
<p>请输入密码查看穿搭历史</p>
|
||||
|
||||
<div class="input-group">
|
||||
<input
|
||||
type="password"
|
||||
v-model="password"
|
||||
placeholder="请输入密码"
|
||||
@keyup.enter="validatePassword"
|
||||
/>
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
@click="validatePassword"
|
||||
:disabled="loading"
|
||||
>
|
||||
{{ loading ? '验证中...' : '确认' }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div v-if="errorMessage" class="error-message">
|
||||
{{ errorMessage }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useStore } from 'vuex'
|
||||
|
||||
const router = useRouter()
|
||||
const store = useStore()
|
||||
|
||||
const password = ref('')
|
||||
const errorMessage = ref('')
|
||||
const loading = ref(false)
|
||||
|
||||
const validatePassword = async () => {
|
||||
if (!password.value) {
|
||||
errorMessage.value = '请输入密码'
|
||||
return
|
||||
}
|
||||
|
||||
loading.value = true
|
||||
errorMessage.value = ''
|
||||
|
||||
try {
|
||||
await store.dispatch('authenticate', password.value)
|
||||
router.push('/tryon-history')
|
||||
} catch (error) {
|
||||
errorMessage.value = error.message
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.password-protection {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 70vh;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.password-form {
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
padding: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.password-form h2 {
|
||||
margin-bottom: 10px;
|
||||
color: #fe2c55;
|
||||
}
|
||||
|
||||
.password-form p {
|
||||
margin-bottom: 25px;
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
.input-group {
|
||||
display: flex;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.input-group input {
|
||||
flex: 1;
|
||||
padding: 10px 15px;
|
||||
border: 1px solid #333;
|
||||
border-radius: 4px 0 0 4px;
|
||||
background-color: #1a1a1a;
|
||||
color: #f0f0f0;
|
||||
}
|
||||
|
||||
.input-group input:focus {
|
||||
outline: none;
|
||||
border-color: #fe2c55;
|
||||
}
|
||||
|
||||
.input-group button {
|
||||
border-radius: 0 4px 4px 0;
|
||||
}
|
||||
|
||||
.error-message {
|
||||
color: #fe2c55;
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="tryon-history">
|
||||
<div class="tryon-history">
|
||||
<div v-if="loading" class="loading">
|
||||
<p>加载中...</p>
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user