refactor: 构建 login 微模块
10
src/http/apis/user/index.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import type * as Login from "./type"
|
||||
import { request } from "@/http/request"
|
||||
|
||||
/** 获取当前登陆用户详情 */
|
||||
export function getUserInfoApi() {
|
||||
return request<Login.UserInfoResponseData>({
|
||||
url: "users/info",
|
||||
method: "get"
|
||||
})
|
||||
}
|
1
src/http/apis/user/type.ts
Normal file
@ -0,0 +1 @@
|
||||
export type UserInfoResponseData = ApiResponseData<{ username: string, roles: string[] }>
|
@ -1,6 +1,6 @@
|
||||
<script lang="ts" setup>
|
||||
import Svg403 from "@@/assets/images/error/403.svg?component" // vite-svg-loader 插件的功能
|
||||
import Layout from "./components/Layout.vue"
|
||||
import Svg403 from "./images/403.svg?component" // vite-svg-loader 插件的功能
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<script lang="ts" setup>
|
||||
import Svg404 from "@@/assets/images/error/404.svg?component" // vite-svg-loader 插件的功能
|
||||
import Layout from "./components/Layout.vue"
|
||||
import Svg404 from "./images/404.svg?component" // vite-svg-loader 插件的功能
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 60 KiB |
@ -17,11 +17,3 @@ export function loginApi(data: Login.LoginRequestData) {
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/** 获取用户详情 */
|
||||
export function getUserInfoApi() {
|
||||
return request<Login.UserInfoResponseData>({
|
||||
url: "users/info",
|
||||
method: "get"
|
||||
})
|
||||
}
|
@ -10,5 +10,3 @@ export interface LoginRequestData {
|
||||
export type LoginCodeResponseData = ApiResponseData<string>
|
||||
|
||||
export type LoginResponseData = ApiResponseData<{ token: string }>
|
||||
|
||||
export type UserInfoResponseData = ApiResponseData<{ username: string, roles: string[] }>
|
@ -28,7 +28,7 @@ const props = defineProps<Props>()
|
||||
width: 120px;
|
||||
height: 95px;
|
||||
transform: translateY(12%);
|
||||
@include backgroundImage("@@/assets/images/login/face.png");
|
||||
@include backgroundImage("../images/face.png");
|
||||
.hand-down-left,
|
||||
.hand-down-right {
|
||||
z-index: 2;
|
||||
@ -40,12 +40,12 @@ const props = defineProps<Props>()
|
||||
.hand-down-left {
|
||||
bottom: 3px;
|
||||
left: -35px;
|
||||
@include backgroundImage("@@/assets/images/login/hand-down-left.png");
|
||||
@include backgroundImage("../images/hand-down-left.png");
|
||||
}
|
||||
.hand-down-right {
|
||||
bottom: 3px;
|
||||
right: -40px;
|
||||
@include backgroundImage("@@/assets/images/login/hand-down-right.png");
|
||||
@include backgroundImage("../images/hand-down-right.png");
|
||||
}
|
||||
.hand-up-left,
|
||||
.hand-up-right {
|
||||
@ -59,12 +59,12 @@ const props = defineProps<Props>()
|
||||
.hand-up-left {
|
||||
bottom: 11px;
|
||||
left: -5px;
|
||||
@include backgroundImage("@@/assets/images/login/hand-up-left.png");
|
||||
@include backgroundImage("../images/hand-up-left.png");
|
||||
}
|
||||
.hand-up-right {
|
||||
bottom: 11px;
|
||||
right: 5px;
|
||||
@include backgroundImage("@@/assets/images/login/hand-up-right.png");
|
||||
@include backgroundImage("../images/hand-up-right.png");
|
||||
}
|
||||
.close-eyes {
|
||||
z-index: 1;
|
||||
@ -72,7 +72,7 @@ const props = defineProps<Props>()
|
||||
height: 100%;
|
||||
opacity: 0;
|
||||
transition: opacity 0.1s linear 0.1s;
|
||||
@include backgroundImage("@@/assets/images/login/close-eyes.png");
|
||||
@include backgroundImage("../images/close-eyes.png");
|
||||
}
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
@ -1,18 +1,20 @@
|
||||
<script lang="ts" setup>
|
||||
import type { LoginRequestData } from "@/http/apis/login/type"
|
||||
import type { FormInstance, FormRules } from "element-plus"
|
||||
import { getLoginCodeApi } from "@/http/apis/login"
|
||||
import type { LoginRequestData } from "./apis/type"
|
||||
import { useUserStore } from "@/pinia/stores/user"
|
||||
import ThemeSwitch from "@@/components/ThemeSwitch/index.vue"
|
||||
import { Key, Loading, Lock, Picture, User } from "@element-plus/icons-vue"
|
||||
import { ElMessage } from "element-plus"
|
||||
import { reactive, ref } from "vue"
|
||||
import { useRouter } from "vue-router"
|
||||
import { getLoginCodeApi, loginApi } from "./apis"
|
||||
import Owl from "./components/Owl.vue"
|
||||
import { useFocus } from "./composables/useFocus"
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
const userStore = useUserStore()
|
||||
|
||||
const { isFocus, handleBlur, handleFocus } = useFocus()
|
||||
|
||||
/** 登录表单元素的引用 */
|
||||
@ -53,7 +55,8 @@ function handleLogin() {
|
||||
return
|
||||
}
|
||||
loading.value = true
|
||||
useUserStore().login(loginFormData).then(() => {
|
||||
loginApi(loginFormData).then(({ data }) => {
|
||||
userStore.setToken(data.token)
|
||||
router.push({ path: "/" })
|
||||
}).catch(() => {
|
||||
createCode()
|
||||
|
@ -1,9 +1,8 @@
|
||||
import type { LoginRequestData } from "@/http/apis/login/type"
|
||||
import { getUserInfoApi, loginApi } from "@/http/apis/login"
|
||||
import { getUserInfoApi } from "@/http/apis/user"
|
||||
import { pinia } from "@/pinia"
|
||||
import { resetRouter } from "@/router"
|
||||
import { routerConfig } from "@/router/config"
|
||||
import { getToken, removeToken, setToken } from "@@/utils/cache/cookies"
|
||||
import { setToken as _setToken, getToken, removeToken } from "@@/utils/cache/cookies"
|
||||
import { defineStore } from "pinia"
|
||||
import { ref } from "vue"
|
||||
import { useSettingsStore } from "./settings"
|
||||
@ -17,11 +16,10 @@ export const useUserStore = defineStore("user", () => {
|
||||
const tagsViewStore = useTagsViewStore()
|
||||
const settingsStore = useSettingsStore()
|
||||
|
||||
// 登录
|
||||
const login = async ({ username, password, code }: LoginRequestData) => {
|
||||
const { data } = await loginApi({ username, password, code })
|
||||
setToken(data.token)
|
||||
token.value = data.token
|
||||
// 设置 Token
|
||||
const setToken = async (value: string) => {
|
||||
_setToken(value)
|
||||
token.value = value
|
||||
}
|
||||
|
||||
// 获取用户详情
|
||||
@ -36,7 +34,7 @@ export const useUserStore = defineStore("user", () => {
|
||||
const changeRoles = async (role: string) => {
|
||||
const newToken = `token-${role}`
|
||||
token.value = newToken
|
||||
setToken(newToken)
|
||||
_setToken(newToken)
|
||||
// 用刷新页面代替重新登录
|
||||
window.location.reload()
|
||||
}
|
||||
@ -65,7 +63,7 @@ export const useUserStore = defineStore("user", () => {
|
||||
}
|
||||
}
|
||||
|
||||
return { token, roles, username, login, getInfo, changeRoles, logout, resetToken }
|
||||
return { token, roles, username, setToken, getInfo, changeRoles, logout, resetToken }
|
||||
})
|
||||
|
||||
/**
|
||||
|