更新依赖和一些基础的功能
This commit is contained in:
34
src/App.vue
34
src/App.vue
@@ -1,38 +1,10 @@
|
||||
<script setup>
|
||||
import HelloWorld from './components/HelloWorld.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="bg-gray-100 min-h-screen">
|
||||
<header class="bg-gradient-to-r from-blue-500 to-indigo-600 text-white py-4 px-6 flex items-center justify-between">
|
||||
<div class="flex items-center space-x-4">
|
||||
<!-- Logo -->
|
||||
<img src="https://via.placeholder.com/40" alt="Logo" class="h-8 w-8 rounded-full">
|
||||
<span class="font-bold">My App</span>
|
||||
</div>
|
||||
|
||||
<!-- Menu -->
|
||||
<nav class="hidden md:flex space-x-4">
|
||||
<a href="#" class="hover:text-gray-300">Home</a>
|
||||
<a href="#" class="hover:text-gray-300">About</a>
|
||||
<a href="#" class="hover:text-gray-300">Services</a>
|
||||
<a href="#" class="hover:text-gray-300">Contact</a>
|
||||
</nav>
|
||||
|
||||
<!-- User Profile -->
|
||||
<div class="flex items-center space-x-4">
|
||||
<button class="text-sm bg-gray-800 hover:bg-gray-700 text-white font-bold py-2 px-4 rounded">
|
||||
Personal Center
|
||||
</button>
|
||||
<img src="https://via.placeholder.com/40" alt="User Avatar" class="h-8 w-8 rounded-full cursor-pointer">
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="p-6">
|
||||
<slot></slot>
|
||||
</main>
|
||||
</div>
|
||||
<router-view />
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
<style lang='scss' scoped>
|
||||
|
||||
</style>
|
||||
|
||||
75
src/api/request.js
Normal file
75
src/api/request.js
Normal file
@@ -0,0 +1,75 @@
|
||||
import axios from 'axios';
|
||||
import {message as msg} from "ant-design-vue";
|
||||
|
||||
// 创建 Axios 实例
|
||||
const service = axios.create({
|
||||
baseURL: '/api/', // 这里可以设置你的 API 基础地址
|
||||
timeout: 5000 // 请求超时时间
|
||||
});
|
||||
|
||||
// 请求拦截器
|
||||
service.interceptors.request.use(
|
||||
config => {
|
||||
// 从本地存储中获取 token
|
||||
const token = localStorage.getItem('token');
|
||||
if (token) {
|
||||
// 设置请求头中的 Authorization
|
||||
config.headers['Authorization'] = `Bearer ${token}`;
|
||||
}
|
||||
return config;
|
||||
},
|
||||
error => {
|
||||
console.log(error); // 打印错误信息
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
// 响应拦截器
|
||||
service.interceptors.response.use(
|
||||
response => {
|
||||
const {code, result, message} = response.data;
|
||||
if (code === 0) {
|
||||
return result;
|
||||
} else {
|
||||
if (code === 401) {
|
||||
msg.error(message).then(r => {
|
||||
localStorage.removeItem('token');
|
||||
localStorage.removeItem('user');
|
||||
window.location.href = '/'
|
||||
msg.destroy()
|
||||
})
|
||||
return;
|
||||
}
|
||||
msg.error(message).then(r => {
|
||||
msg.destroy()
|
||||
})
|
||||
}
|
||||
},
|
||||
error => {
|
||||
console.log('err' + error); // 打印错误信息
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
// 封装 get 请求
|
||||
const get = (url, params = {}) => {
|
||||
return service.get(url, { params });
|
||||
};
|
||||
|
||||
// 封装 post 请求
|
||||
const post = (url, data = {}) => {
|
||||
return service.post(url, data);
|
||||
};
|
||||
|
||||
// 封装上传文件请求
|
||||
const upload = (url, file) => {
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
return service.post(url, formData, {
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export { get, post, upload };
|
||||
10
src/api/request/upload.js
Normal file
10
src/api/request/upload.js
Normal file
@@ -0,0 +1,10 @@
|
||||
import {upload} from '../request.js'
|
||||
|
||||
const prefix = 'upload'
|
||||
|
||||
export function uploadImageApi(credentials) {
|
||||
return upload(`${prefix}/image`, credentials)
|
||||
}
|
||||
export function uploadVideoApi(credentials) {
|
||||
return upload(`${prefix}/video`, credentials)
|
||||
}
|
||||
92
src/api/request/user.js
Normal file
92
src/api/request/user.js
Normal file
@@ -0,0 +1,92 @@
|
||||
import {get, post} from '../request.js'
|
||||
|
||||
const prefix = 'user'
|
||||
|
||||
/**
|
||||
* 登录
|
||||
* @param credentials
|
||||
* @returns {Promise<axios.AxiosResponse<any>>}
|
||||
*/
|
||||
export function loginApi(credentials) {
|
||||
return post('login', credentials)
|
||||
}
|
||||
/**
|
||||
* 注册
|
||||
* @param credentials
|
||||
* @returns {Promise<axios.AxiosResponse<any>>}
|
||||
*/
|
||||
export function registerApi(credentials) {
|
||||
return post('register', credentials)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户列表
|
||||
* @param credentials
|
||||
* @returns {Promise<axios.AxiosResponse<any>>}
|
||||
*/
|
||||
export function userListApi(credentials) {
|
||||
return get(`${prefix}/list`, credentials)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前登录用户信息
|
||||
* @param credentials
|
||||
* @returns {Promise<axios.AxiosResponse<any>>}
|
||||
*/
|
||||
export function userMyInfoApi(credentials) {
|
||||
return get(`${prefix}/my-info`, credentials)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户统计信息
|
||||
* @param credentials
|
||||
* @returns {Promise<axios.AxiosResponse<any>>}
|
||||
*/
|
||||
export function userStatsApi(credentials) {
|
||||
return get(`${prefix}/user-stats`, credentials)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建用户
|
||||
* @param credentials
|
||||
* @returns {Promise<axios.AxiosResponse<any>>}
|
||||
*/
|
||||
export function createUserApi(credentials) {
|
||||
return post(`${prefix}/create`, credentials)
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户
|
||||
* @param credentials
|
||||
* @returns {Promise<axios.AxiosResponse<any>>}
|
||||
*/
|
||||
export function updateUserApi(credentials) {
|
||||
return post(`${prefix}/update`, credentials)
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户
|
||||
* @param credentials
|
||||
* @returns {Promise<axios.AxiosResponse<any>>}
|
||||
*/
|
||||
export function deleteUserApi(credentials) {
|
||||
return post(`${prefix}/delete`, credentials)
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置密码
|
||||
* @param credentials
|
||||
* @returns {Promise<axios.AxiosResponse<any>>}
|
||||
*/
|
||||
export function resetPasswordApi(credentials) {
|
||||
return post(`${prefix}/reset-password`, credentials)
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置密码
|
||||
* @param credentials
|
||||
* @returns {Promise<axios.AxiosResponse<any>>}
|
||||
*/
|
||||
export function changePasswordApi(credentials) {
|
||||
return post(`${prefix}/change-password`, credentials)
|
||||
}
|
||||
32
src/layouts/Header.vue
Normal file
32
src/layouts/Header.vue
Normal file
@@ -0,0 +1,32 @@
|
||||
<script setup lang="ts">
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<header class="bg-gradient-to-r from-blue-500 to-indigo-600 text-white py-4 px-6 flex items-center justify-between">
|
||||
<div class="flex items-center space-x-4">
|
||||
<!-- Logo -->
|
||||
<img src="https://via.placeholder.com/40" alt="Logo" class="h-8 w-8 rounded-full">
|
||||
<span class="font-bold">My App</span>
|
||||
</div>
|
||||
|
||||
<!-- Menu -->
|
||||
<nav class="hidden md:flex space-x-4">
|
||||
<a href="#" class="hover:text-gray-300">首页</a>
|
||||
<a href="#" class="hover:text-gray-300">About</a>
|
||||
<a href="#" class="hover:text-gray-300">Services</a>
|
||||
<a href="#" class="hover:text-gray-300">Contact</a>
|
||||
</nav>
|
||||
|
||||
<!-- User Profile -->
|
||||
<div class="flex items-center space-x-4">
|
||||
<button class="text-sm bg-gray-800 hover:bg-gray-700 text-white font-bold py-2 px-4 rounded">
|
||||
Personal Center
|
||||
</button>
|
||||
<img src="https://via.placeholder.com/40" alt="User Avatar" class="h-8 w-8 rounded-full cursor-pointer">
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
13
src/main.js
13
src/main.js
@@ -1,5 +1,16 @@
|
||||
import { createApp } from 'vue'
|
||||
import { createPinia } from 'pinia'
|
||||
import Antd from 'ant-design-vue'
|
||||
import './style.css'
|
||||
import App from './App.vue'
|
||||
// 注册路由
|
||||
import router from './router'
|
||||
|
||||
createApp(App).mount('#app')
|
||||
const app = createApp(App)
|
||||
|
||||
|
||||
// 注册Ant Design组件
|
||||
app.use(createPinia())
|
||||
app.use(router)
|
||||
app.use(Antd)
|
||||
app.mount('#app')
|
||||
|
||||
38
src/router/index.js
Normal file
38
src/router/index.js
Normal file
@@ -0,0 +1,38 @@
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
import MainLayout from '@/layouts/Header.vue'
|
||||
|
||||
// 在路由配置中添加个人中心路由
|
||||
const routes = [
|
||||
{
|
||||
path: '/',
|
||||
component: MainLayout,
|
||||
children: [
|
||||
{ path: '', name: 'Home', component: () => import('@/views/index/index.vue') },
|
||||
]
|
||||
},
|
||||
]
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes,
|
||||
scrollBehavior(to, from, savedPosition) {
|
||||
return savedPosition || { top: 0 }
|
||||
}
|
||||
})
|
||||
|
||||
router.beforeEach((to, from) => {
|
||||
const userStore = useUserStore()
|
||||
if (to.meta.requiresAuth && !userStore.user) {
|
||||
return { name: 'Login', query: { redirect: to.fullPath } }
|
||||
}
|
||||
})
|
||||
|
||||
export default router
|
||||
|
||||
router.beforeEach((to, from) => {
|
||||
const userStore = useUserStore()
|
||||
if (to.meta.requiresAuth && !userStore.user) {
|
||||
return { name: 'Login', query: { redirect: to.fullPath } }
|
||||
}
|
||||
})
|
||||
87
src/stores/user.js
Normal file
87
src/stores/user.js
Normal file
@@ -0,0 +1,87 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref, computed } from 'vue'
|
||||
import {loginApi, registerApi} from "@/api/request/user.js";
|
||||
import {message, notification} from "ant-design-vue";
|
||||
|
||||
export const useUserStore = defineStore('user', () => {
|
||||
const user = ref(JSON.parse(localStorage.getItem('user') || 'null'))
|
||||
const modal = ref(localStorage.getItem('authModal') || 'false')
|
||||
|
||||
// 添加初始化状态校验
|
||||
const initUser = () => {
|
||||
const userData = localStorage.getItem('user')
|
||||
if (!userData) return null
|
||||
try {
|
||||
return JSON.parse(userData)
|
||||
} catch {
|
||||
localStorage.removeItem('user')
|
||||
localStorage.removeItem('token')
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
const isAuthenticated = computed(() => !!user.value?.nick_name)
|
||||
|
||||
function login(credentials, functionName) {
|
||||
console.log(functionName, 'sssssssssssss')
|
||||
loginApi({
|
||||
account: credentials.username,
|
||||
password: credentials.password,
|
||||
remember: credentials.remember,
|
||||
}).then((res) => {
|
||||
const userData = {
|
||||
nick_name: res.nick_name,
|
||||
role_name: res.role_name,
|
||||
role_value: res.role_value,
|
||||
}
|
||||
user.value = userData;
|
||||
localStorage.setItem('user', JSON.stringify(userData))
|
||||
localStorage.setItem('token', res.token)
|
||||
notification.success({
|
||||
message: '登录成功',
|
||||
description: `欢迎回来${res.nick_name}`,
|
||||
})
|
||||
functionName()
|
||||
})
|
||||
}
|
||||
function register(credentials, functionName) {
|
||||
registerApi({
|
||||
account: credentials.username,
|
||||
password: credentials.password,
|
||||
email: credentials.email,
|
||||
code: credentials.code,
|
||||
}).then((res) => {
|
||||
const userData = {
|
||||
nick_name: res.nick_name,
|
||||
role_name: res.role_name,
|
||||
role_value: res.role_value,
|
||||
}
|
||||
user.value = userData;
|
||||
localStorage.setItem('user', JSON.stringify(userData))
|
||||
localStorage.setItem('token', res.token)
|
||||
message.success('注册成功')
|
||||
functionName()
|
||||
})
|
||||
}
|
||||
|
||||
function logout() {
|
||||
user.value = null
|
||||
localStorage.removeItem('user')
|
||||
localStorage.removeItem('token')
|
||||
}
|
||||
|
||||
function setModal(value) {
|
||||
modal.value = modal.value === 'false' ? 'true' : 'false';
|
||||
localStorage.setItem('authModal', value)
|
||||
}
|
||||
|
||||
return {
|
||||
modal,
|
||||
user,
|
||||
isAuthenticated,
|
||||
setModal,
|
||||
login,
|
||||
register,
|
||||
logout
|
||||
}
|
||||
})
|
||||
11
src/views/index/index.vue
Normal file
11
src/views/index/index.vue
Normal file
@@ -0,0 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
你好
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user