feat: axios loading & message
This commit is contained in:
parent
a1c23c8cf8
commit
28013b0e8e
@ -12,5 +12,5 @@ async def login(auth_data: LoginForm) -> Response[LoginResult]:
|
||||
user_obj = await get_user({"username": auth_data.username})
|
||||
if user_obj:
|
||||
if verify_password(auth_data.password, user_obj.password):
|
||||
return dict(id=user_obj.id, access_token=generate_token(user_obj.username))
|
||||
return Response(data=LoginResult(id=user_obj.id, token=generate_token(auth_data.username)))
|
||||
return Response(msg="账号或密码错误")
|
||||
|
@ -1,16 +1,18 @@
|
||||
from core.resp import Response
|
||||
from core.router import Router
|
||||
from core.security import get_password_hash
|
||||
from dbhelper.user import get_user_info, get_users, insert_user
|
||||
from schemas.common import ListAll
|
||||
from schemas.user import UserAdd, UserInfo, UserList, UserQuery
|
||||
|
||||
user = Router(prefix="/users", tags=["用户管理"])
|
||||
user = Router(prefix="/user", tags=["用户管理"])
|
||||
|
||||
|
||||
@user.post("", summary="用户添加")
|
||||
async def user_add(data: UserAdd) -> Response[UserInfo]:
|
||||
roles = data.rids
|
||||
del data.rids
|
||||
user.password = get_password_hash(user.password)
|
||||
return await insert_user(data, roles)
|
||||
|
||||
|
||||
|
@ -4,8 +4,9 @@ from tortoise import Tortoise
|
||||
async def init_orm():
|
||||
"""初始化orm"""
|
||||
await Tortoise.init(
|
||||
db_url="sqlite://mini.db", modules={"models": ["models"]}
|
||||
db_url="sqlite://mini.db", modules={"models": ["models"]},
|
||||
)
|
||||
await Tortoise.generate_schemas()
|
||||
|
||||
|
||||
async def close_orm():
|
||||
|
@ -28,5 +28,5 @@ class Msg(enum.Enum):
|
||||
|
||||
class Response(GenericModel, Generic[T]):
|
||||
code: Status = Status.OK
|
||||
msg: Union[Msg, str] = Msg.OK
|
||||
data: Optional[T]
|
||||
msg: Union[Msg, str] = Msg.OK
|
||||
|
BIN
backend/mini.db
BIN
backend/mini.db
Binary file not shown.
BIN
backend/mini.db-shm
Normal file
BIN
backend/mini.db-shm
Normal file
Binary file not shown.
0
backend/mini.db-wal
Normal file
0
backend/mini.db-wal
Normal file
@ -18,7 +18,7 @@ class LoginResult(BaseModel):
|
||||
"""登录响应模型"""
|
||||
|
||||
id: int = Field(..., description="用户ID")
|
||||
access_token: str = Field(..., description="token 串")
|
||||
token: str = Field(..., description="token 串")
|
||||
token_type: str = Field("Bearer", description="token 类型")
|
||||
|
||||
|
||||
|
@ -7,7 +7,7 @@ from models import UserModel, UserRoleModel
|
||||
from schemas.common import QueryData
|
||||
|
||||
UserRead = pydantic_model_creator(UserModel, name="UserOut", exclude=("password",))
|
||||
UserIn = pydantic_model_creator(UserModel, name="UserIn", exclude_readonly=True)
|
||||
UserIn = pydantic_model_creator(UserModel, name="UserIn", exclude_readonly=True, exclude=("status",))
|
||||
|
||||
UserRole = pydantic_model_creator(UserRoleModel, name="UserRole", exclude_readonly=True)
|
||||
|
||||
|
@ -1,15 +1,17 @@
|
||||
import { createApp } from 'vue'
|
||||
import { createPinia } from 'pinia'
|
||||
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import store from './stores'
|
||||
|
||||
import 'normalize.css'
|
||||
import '@/assets/base.css'
|
||||
import 'element-plus/theme-chalk/el-message.css'
|
||||
import 'element-plus/theme-chalk/el-loading.css'
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
app.use(createPinia())
|
||||
app.use(store)
|
||||
app.use(router)
|
||||
|
||||
app.mount('#app')
|
||||
|
@ -2,6 +2,10 @@ import { createRouter, createWebHistory } from 'vue-router'
|
||||
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: '/',
|
||||
redirect: '/login'
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
component: () => import('@/views/login.vue')
|
||||
|
@ -1,34 +1,35 @@
|
||||
import axios from "axios";
|
||||
import {message, ElLoading} from 'element-plus'
|
||||
import userStore from '@/stores/user'
|
||||
import { ElMessage, ElLoading } from 'element-plus'
|
||||
import {userStore} from '@/stores/user'
|
||||
|
||||
|
||||
const store = userStore()
|
||||
let loading
|
||||
|
||||
export default (config) => {
|
||||
|
||||
const instance = axios.create({
|
||||
baseURL: import.meta.env.VITE_BASE_URL,
|
||||
timeout: 5000,
|
||||
timeout: 10000,
|
||||
})
|
||||
|
||||
instance.interceptors.request.use(config => {
|
||||
ElLoading.service({
|
||||
title: '请求中.'
|
||||
loading = ElLoading.service({
|
||||
lock: true,
|
||||
text: '请求中...',
|
||||
background: 'rabg(0,0,0,0.7)'
|
||||
})
|
||||
config.headers.Authorization = store.accessToken
|
||||
config.headers.Authorization = userStore().accessToken
|
||||
return config
|
||||
})
|
||||
|
||||
instance.interceptors.response.use(res => {
|
||||
if (res.data.code !== 20000 ){
|
||||
message.error(res.data.msg)
|
||||
if (res.data.code !== 200 ){
|
||||
ElMessage.error(res.data.msg)
|
||||
}
|
||||
ElLoading.close()
|
||||
loading.close()
|
||||
return res.data
|
||||
}, err => {
|
||||
message.error(err)
|
||||
ElLoading.close()
|
||||
ElMessage.error(err)
|
||||
loading.close()
|
||||
return Promise.reject(err)
|
||||
})
|
||||
|
||||
|
9
frontend/src/service/user.js
Normal file
9
frontend/src/service/user.js
Normal file
@ -0,0 +1,9 @@
|
||||
import request from "./request";
|
||||
|
||||
export function login(data) {
|
||||
return request({
|
||||
url: "/login",
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
8
frontend/src/stores/index.js
Normal file
8
frontend/src/stores/index.js
Normal file
@ -0,0 +1,8 @@
|
||||
import { createPinia } from 'pinia'
|
||||
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
|
||||
|
||||
const pinia = createPinia()
|
||||
pinia.use(piniaPluginPersistedstate)
|
||||
|
||||
|
||||
export default pinia
|
@ -1,14 +1,25 @@
|
||||
import { ref, computed } from 'vue'
|
||||
import { defineStore } from 'pinia'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import {login} from '@/service/user'
|
||||
|
||||
export const userStore = defineStore('user', () => {
|
||||
const info = ref({})
|
||||
const uid = ref(0)
|
||||
const token = ref("")
|
||||
const accessToken = computed(() => 'Bearer ' + token)
|
||||
const accessToken = computed(() => 'Bearer ' + token.value)
|
||||
|
||||
return { info, token, accessToken }
|
||||
// 非setup语法时的actions
|
||||
const loginAction = async (data) => {
|
||||
const res = await login(data)
|
||||
token.value = res.data.token
|
||||
uid.value = res.data.id
|
||||
// 弹框提示登录成功
|
||||
ElMessage.success("登录成功.")
|
||||
}
|
||||
|
||||
return { uid, token, accessToken, loginAction }
|
||||
}, {
|
||||
persist: true,
|
||||
persist: true, // 解决pinia刷新时数据丢失问题
|
||||
})
|
||||
|
||||
// export const userStore = defineStore('user',{
|
||||
@ -19,5 +30,14 @@ export const userStore = defineStore('user', () => {
|
||||
// accessToken() {
|
||||
// return `Bearer ${this.token}`
|
||||
// }
|
||||
// },
|
||||
// actions: {
|
||||
// async loginAction(data){
|
||||
// const res = await login(data)
|
||||
// console.log(res)
|
||||
// this.token = res.data.token
|
||||
// // uid.value = res.data.id
|
||||
// }
|
||||
// },
|
||||
// persist: true
|
||||
// })
|
@ -2,6 +2,9 @@
|
||||
import { User, Lock } from '@element-plus/icons-vue'
|
||||
import {ref,reactive} from 'vue'
|
||||
|
||||
import { userStore } from '@/stores/user';
|
||||
|
||||
const store = userStore()
|
||||
// 表单配置
|
||||
const rules = {
|
||||
username: [
|
||||
@ -26,8 +29,8 @@
|
||||
if (!formEl) return
|
||||
formEl.validate( valid => {
|
||||
if (valid) {
|
||||
// 验证通过
|
||||
console.log('submit!')
|
||||
// 验证通过,执行登录逻辑
|
||||
store.loginAction(formData)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user