mirror of https://github.com/halo-dev/halo
parent
9dc7016f06
commit
9765dd5529
|
@ -34,6 +34,7 @@
|
|||
"floating-vue": "2.0.0-beta.16",
|
||||
"lodash.clonedeep": "^4.5.0",
|
||||
"pinia": "^2.0.14",
|
||||
"qs": "^6.11.0",
|
||||
"uuid": "^8.3.2",
|
||||
"vue": "^3.2.37",
|
||||
"vue-filepond": "^7.0.3",
|
||||
|
@ -46,6 +47,8 @@
|
|||
"@types/jsdom": "^16.2.14",
|
||||
"@types/lodash.clonedeep": "4.5.7",
|
||||
"@types/node": "^17.0.45",
|
||||
"@types/qs": "^6.9.7",
|
||||
"@types/uuid": "^8.3.4",
|
||||
"@vitejs/plugin-vue": "^2.3.3",
|
||||
"@vitejs/plugin-vue-jsx": "^1.3.10",
|
||||
"@vitest/ui": "^0.15.2",
|
||||
|
|
|
@ -5,4 +5,17 @@ const axiosInstance = axios.create({
|
|||
withCredentials: true,
|
||||
});
|
||||
|
||||
axiosInstance.interceptors.response.use(
|
||||
(response) => {
|
||||
return response;
|
||||
},
|
||||
async (error) => {
|
||||
console.log("error", error);
|
||||
if (error.response.status === 401) {
|
||||
window.location.href = "/#/login";
|
||||
}
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
export { axiosInstance };
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
const { themeable } = require("tailwindcss-themeable");
|
||||
|
||||
module.exports = {
|
||||
content: ["./index.html", "./src/**/*.{vue,js,ts,jsx,tsx}"],
|
||||
content: ["./src/**/*.{vue,js,ts,jsx,tsx}"],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [
|
||||
require("tailwindcss-safe-area"),
|
||||
require("@tailwindcss/aspect-ratio"),
|
||||
themeable({
|
||||
defaultTheme: "default",
|
||||
themes: [
|
||||
|
|
|
@ -12,6 +12,8 @@ importers:
|
|||
'@types/jsdom': ^16.2.14
|
||||
'@types/lodash.clonedeep': 4.5.7
|
||||
'@types/node': ^17.0.45
|
||||
'@types/qs': ^6.9.7
|
||||
'@types/uuid': ^8.3.4
|
||||
'@vitejs/plugin-vue': ^2.3.3
|
||||
'@vitejs/plugin-vue-jsx': ^1.3.10
|
||||
'@vitest/ui': ^0.15.2
|
||||
|
@ -36,6 +38,7 @@ importers:
|
|||
postcss: ^8.4.14
|
||||
prettier: ^2.7.1
|
||||
prettier-plugin-tailwindcss: ^0.1.11
|
||||
qs: ^6.11.0
|
||||
sass: ^1.53.0
|
||||
start-server-and-test: ^1.14.0
|
||||
tailwindcss: ^3.1.4
|
||||
|
@ -65,6 +68,7 @@ importers:
|
|||
floating-vue: 2.0.0-beta.16_vue@3.2.37
|
||||
lodash.clonedeep: 4.5.0
|
||||
pinia: 2.0.14_j6bzmzd4ujpabbp5objtwxyjp4
|
||||
qs: 6.11.0
|
||||
uuid: 8.3.2
|
||||
vue: 3.2.37
|
||||
vue-filepond: 7.0.3_filepond@4.30.4+vue@3.2.37
|
||||
|
@ -76,6 +80,8 @@ importers:
|
|||
'@types/jsdom': 16.2.14
|
||||
'@types/lodash.clonedeep': 4.5.7
|
||||
'@types/node': 17.0.45
|
||||
'@types/qs': 6.9.7
|
||||
'@types/uuid': 8.3.4
|
||||
'@vitejs/plugin-vue': 2.3.3_vite@2.9.12+vue@3.2.37
|
||||
'@vitejs/plugin-vue-jsx': 1.3.10
|
||||
'@vitest/ui': 0.15.2
|
||||
|
@ -1472,7 +1478,7 @@ packages:
|
|||
axios: 0.24.0
|
||||
form-data: 4.0.0
|
||||
js-base64: 3.7.2
|
||||
qs: 6.10.3
|
||||
qs: 6.11.0
|
||||
tslib: 2.4.0
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
|
@ -2156,6 +2162,10 @@ packages:
|
|||
resolution: {integrity: sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==}
|
||||
dev: true
|
||||
|
||||
/@types/uuid/8.3.4:
|
||||
resolution: {integrity: sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==}
|
||||
dev: true
|
||||
|
||||
/@types/web-bluetooth/0.0.14:
|
||||
resolution: {integrity: sha512-5d2RhCard1nQUC3aHcq/gHzWYO6K0WJmAbjO7mQJgCQKtZpgXxv1rOM6O/dBDhDYYVutk1sciOgNSe+5YyfM8A==}
|
||||
|
||||
|
@ -5763,6 +5773,14 @@ packages:
|
|||
engines: {node: '>=0.6'}
|
||||
dependencies:
|
||||
side-channel: 1.0.4
|
||||
dev: true
|
||||
|
||||
/qs/6.11.0:
|
||||
resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==}
|
||||
engines: {node: '>=0.6'}
|
||||
dependencies:
|
||||
side-channel: 1.0.4
|
||||
dev: false
|
||||
|
||||
/qs/6.5.3:
|
||||
resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==}
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
<script lang="ts" setup>
|
||||
import { VButton, VInput, VSpace } from "@halo-dev/components";
|
||||
import { v4 as uuid } from "uuid";
|
||||
import { axiosInstance } from "@halo-dev/admin-shared";
|
||||
import qs from "qs";
|
||||
import logo from "../../../assets/logo.svg";
|
||||
import { onMounted, ref } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
|
||||
interface LoginForm {
|
||||
_csrf: string;
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
interface LoginFormState {
|
||||
logging: boolean;
|
||||
state: LoginForm;
|
||||
}
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const loginForm = ref<LoginFormState>({
|
||||
logging: false,
|
||||
state: {
|
||||
_csrf: "",
|
||||
username: "admin",
|
||||
password: "wsYdVrLTYnLbzN6e",
|
||||
},
|
||||
});
|
||||
|
||||
const handleGenerateToken = async () => {
|
||||
const token = uuid();
|
||||
loginForm.value.state._csrf = token;
|
||||
document.cookie = `XSRF-TOKEN=${token}; Path=/;`;
|
||||
};
|
||||
|
||||
const handleLogin = async () => {
|
||||
try {
|
||||
loginForm.value.logging = true;
|
||||
|
||||
await axiosInstance.post(
|
||||
`http://localhost:8090/login`,
|
||||
qs.stringify(loginForm.value.state),
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
}
|
||||
);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
} finally {
|
||||
await router.replace({ name: "Dashboard" });
|
||||
loginForm.value.logging = false;
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
handleGenerateToken();
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div class="flex h-screen flex-col items-center justify-center">
|
||||
<img :src="logo" alt="Logo" class="mb-8 w-20" />
|
||||
<div class="login-form w-72">
|
||||
<VSpace class="w-full" direction="column" spacing="lg">
|
||||
<VInput
|
||||
v-model="loginForm.state.username"
|
||||
placeholder="用户名"
|
||||
></VInput>
|
||||
<VInput v-model="loginForm.state.password" placeholder="密码"></VInput>
|
||||
<VButton block type="secondary" @click="handleLogin">登录</VButton>
|
||||
</VSpace>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
|
@ -9,12 +9,18 @@ import UserDetail from "./UserDetail.vue";
|
|||
import ProfileModification from "./ProfileModification.vue";
|
||||
import PasswordChange from "./PasswordChange.vue";
|
||||
import PersonalAccessTokens from "./PersonalAccessTokens.vue";
|
||||
import Login from "./Login.vue";
|
||||
import { IconUserSettings } from "@halo-dev/components";
|
||||
|
||||
export default definePlugin({
|
||||
name: "userModule",
|
||||
components: [],
|
||||
routes: [
|
||||
{
|
||||
path: "/login",
|
||||
name: "Login",
|
||||
component: Login,
|
||||
},
|
||||
{
|
||||
path: "/users",
|
||||
component: BlankLayout,
|
||||
|
|
Loading…
Reference in New Issue