first commit.
This commit is contained in:
15
src/shared/api.ts
Normal file
15
src/shared/api.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import http from "../utils/http";
|
||||
|
||||
export function login(data: { username: string; password: string }) {
|
||||
return http.post("login", data);
|
||||
}
|
||||
|
||||
export function logout() {
|
||||
return http.get("logout");
|
||||
}
|
||||
|
||||
export function getUserInfo(username: string) {
|
||||
return http.get("profile", {
|
||||
params: { username },
|
||||
});
|
||||
}
|
||||
16
src/shared/stores/login.ts
Normal file
16
src/shared/stores/login.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { defineStore } from "pinia";
|
||||
import { ref } from "vue";
|
||||
|
||||
export const useLoginStore = defineStore("login", () => {
|
||||
const visible = ref(false);
|
||||
|
||||
function show() {
|
||||
visible.value = true;
|
||||
}
|
||||
|
||||
function hide() {
|
||||
visible.value = false;
|
||||
}
|
||||
|
||||
return { visible, show, hide };
|
||||
});
|
||||
51
src/shared/stores/user.ts
Normal file
51
src/shared/stores/user.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import { defineStore } from "pinia";
|
||||
import { computed, ref } from "vue";
|
||||
import {
|
||||
PROBLEM_PERMISSION,
|
||||
STORAGE_KEY,
|
||||
USER_TYPE,
|
||||
} from "../../utils/constants";
|
||||
import storage from "../../utils/storage";
|
||||
import { getUserInfo } from "../api";
|
||||
|
||||
export const useUserStore = defineStore("user", () => {
|
||||
const profile = ref<any>({});
|
||||
const isLoaded = ref(false);
|
||||
const user = computed(() => profile.value.user || {});
|
||||
const isAuthed = computed(() => !!user.value.email);
|
||||
const isAdminRole = computed(
|
||||
() =>
|
||||
user.value.admin_type === USER_TYPE.ADMIN ||
|
||||
user.value.admin_type === USER_TYPE.SUPER_ADMIN
|
||||
);
|
||||
const isSuperAdmin = computed(
|
||||
() => user.value.admin_type === USER_TYPE.SUPER_ADMIN
|
||||
);
|
||||
const hasProblemPermission = computed(
|
||||
() => user.value.problem_permission !== PROBLEM_PERMISSION.NONE
|
||||
);
|
||||
|
||||
async function getMyProfile() {
|
||||
isLoaded.value = false;
|
||||
const res = await getUserInfo("");
|
||||
isLoaded.value = true;
|
||||
profile.value = res.data || {};
|
||||
storage.set(STORAGE_KEY.AUTHED, !!user.value.email);
|
||||
}
|
||||
|
||||
function clearMyProfile() {
|
||||
profile.value = {};
|
||||
storage.clear();
|
||||
}
|
||||
return {
|
||||
profile,
|
||||
isLoaded,
|
||||
user,
|
||||
isAdminRole,
|
||||
isSuperAdmin,
|
||||
hasProblemPermission,
|
||||
isAuthed,
|
||||
getMyProfile,
|
||||
clearMyProfile,
|
||||
};
|
||||
});
|
||||
93
src/shared/user/login.vue
Normal file
93
src/shared/user/login.vue
Normal file
@@ -0,0 +1,93 @@
|
||||
<script setup lang="ts">
|
||||
import { FormInstance } from "element-plus";
|
||||
import { reactive, ref } from "vue";
|
||||
import { useSignupStore } from "../../oj/stores/signup";
|
||||
import { login } from "../../shared/api";
|
||||
import { useLoginStore } from "../stores/login";
|
||||
import { useUserStore } from "../stores/user";
|
||||
|
||||
const loginStore = useLoginStore();
|
||||
const signupStore = useSignupStore();
|
||||
const userStore = useUserStore();
|
||||
const loading = ref(false);
|
||||
const errorMessage = ref("");
|
||||
const loginRef = ref<FormInstance>();
|
||||
const form = reactive({
|
||||
username: "",
|
||||
password: "",
|
||||
});
|
||||
const rules = reactive({
|
||||
username: [{ required: true, message: "用户名必填", trigger: "blur" }],
|
||||
password: [
|
||||
{ required: true, message: "密码必填", trigger: "blur" },
|
||||
{ min: 6, max: 20, message: "长度在6到20位之间", trigger: "change" },
|
||||
],
|
||||
});
|
||||
|
||||
async function submit() {
|
||||
if (!loginRef.value) return;
|
||||
await loginRef.value.validate(async (valid) => {
|
||||
if (valid) {
|
||||
loading.value = true;
|
||||
errorMessage.value = "";
|
||||
try {
|
||||
await login(form);
|
||||
loginStore.hide();
|
||||
await userStore.getMyProfile();
|
||||
} catch (err) {
|
||||
errorMessage.value = "用户名或密码不正确";
|
||||
}
|
||||
loading.value = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function goSignup() {
|
||||
loginStore.hide();
|
||||
signupStore.show();
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-dialog
|
||||
style="max-width: 400px"
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="false"
|
||||
v-model="loginStore.visible"
|
||||
title="登录"
|
||||
>
|
||||
<el-form
|
||||
ref="loginRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
label-position="right"
|
||||
label-width="70px"
|
||||
>
|
||||
<el-form-item label="用户名" required prop="username">
|
||||
<el-input v-model="form.username"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="密码" required prop="password">
|
||||
<el-input
|
||||
v-model="form.password"
|
||||
type="password"
|
||||
show-password
|
||||
@change="submit"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :loading="loading" @click="submit"
|
||||
>登录</el-button
|
||||
>
|
||||
<el-button @click="goSignup">没有账号,立即注册</el-button>
|
||||
</el-form-item>
|
||||
<el-alert
|
||||
v-if="errorMessage"
|
||||
:title="errorMessage"
|
||||
show-icon
|
||||
type="error"
|
||||
/>
|
||||
</el-form>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
Reference in New Issue
Block a user