Feat: User Model + Login

用户数据表,前端可登录可获取用户信息
This commit is contained in:
2022-05-22 12:36:15 +08:00
parent b03c9339bd
commit 04eb8628d4
13 changed files with 283 additions and 46 deletions
-14
View File
@@ -1,14 +0,0 @@
import { createContext } from "react";
import { IGlobalData } from "@/types/GlobalData";
import { initalState, IAction } from "@/hooks/useGlobalData";
const GlobalContext = createContext<{ globalData: IGlobalData, setGlobalData: React.Dispatch<IAction> }>({
globalData: initalState,
setGlobalData() {}
});
GlobalContext.displayName = "GlobalContext";
export default GlobalContext;
+2 -2
View File
@@ -1,6 +1,6 @@
// React
import React, { useState } from "react";
import useGlobalContext from "@/hooks/useGlobalContext";
import { useGlobalContext } from "@/hooks/useGlobal";
// UI
@@ -47,7 +47,7 @@ function Aside() {
<Link to="/acgm">随机动漫音乐</Link>
<Link to="/bili">哔哩哔哩小窗</Link>
<Link to="/bing">必应每日壁纸</Link>
{profile.name && <Link to="/admin">轻管理</Link>}
{profile.id && <Link to="/admin">轻管理</Link>}
</nav>
</nav>
</nav>
@@ -1,18 +1,31 @@
import { useReducer } from "react";
import { createContext, useReducer, useContext } from "react";
import { IGlobalData } from "@/types/GlobalData";
export const initalState: IGlobalData = {
profile: {
name: "加载中",
avatar: ""
}
};
export type IAction =
| { type: "all", value: IGlobalData }
| { type: "profile", value: Partial<IGlobalData["profile"]> }
export const initalState: IGlobalData = {
profile: {
name: "",
avatar: ""
}
};
//
// Context
//
export const GlobalContext = createContext<{ globalData: IGlobalData, setGlobalData: React.Dispatch<IAction> }>({
globalData: initalState,
setGlobalData() {}
});
GlobalContext.displayName = "GlobalContext";
//
// Reducer
//
function reducer(state: IGlobalData, action: IAction): IGlobalData {
if (!action) return state;
@@ -35,10 +48,16 @@ function reducer(state: IGlobalData, action: IAction): IGlobalData {
return state;
}
function useGlobalData(): [IGlobalData, React.Dispatch<IAction>]{
let [state, dispatch] = useReducer(reducer, initalState);
return [state, dispatch];
//
// Reducer Hooks
//
export function useGlobalData() {
return useReducer(reducer, initalState);
}
export default useGlobalData;
//
// Context Hooks
//
export function useGlobalContext() {
return useContext(GlobalContext);
}
-9
View File
@@ -1,9 +0,0 @@
import { useContext } from "react";
import GlobalContext from "@/components/GlobalContext";
function useGlobalContext() {
return useContext(GlobalContext);
}
export default useGlobalContext;
+15 -2
View File
@@ -1,8 +1,10 @@
import React, { lazy } from "react";
import ReactDOM from "react-dom";
import useGlobalData from "@/hooks/useGlobalData";
import GlobalContext from "@/components/GlobalContext";
import { useGlobalData, GlobalContext } from "@/hooks/useGlobal";
import { useRequest } from "ahooks";
import getUserInfo from "./server/api/auth/userinfo";
import "./kico.css";
import "./index.css";
@@ -33,6 +35,17 @@ const admin = lazy(() => import("./pages/admin"));
function App() {
let [globalData, setGlobalData] = useGlobalData();
const getUserInfoRequest = useRequest(getUserInfo, {
onSuccess: (res) => {
if (res.code === 0){
setGlobalData({ type: "profile", value: { name: "未登录" } });
}
else if (res.data) {
setGlobalData({ type: "profile", value: res.data });
}
}
});
return (
<GlobalContext.Provider value={{ globalData, setGlobalData }}>
<Router>
+1 -1
View File
@@ -3,7 +3,7 @@ import React from "react";
import { useNavigate } from "react-router-dom";
import { useRequest } from "ahooks";
import useStat from "@/hooks/useStat";
import useGlobalContext from "@/hooks/useGlobalContext";
import { useGlobalContext } from "@/hooks/useGlobal";
// UI
+7 -3
View File
@@ -10,8 +10,6 @@ export default Api(
const jwt = await useInject(JwtService);
const token = await jwt.sign({ name: "Paul" });
const user = await prisma.user.findFirst({
where: {
name: ctx.query.username,
@@ -26,6 +24,11 @@ export default Api(
}
}
const token = await jwt.sign({
id: user.id,
name: user.name
});
// Token
ctx.cookies.set("paul-token", token, {
maxAge: 60 * 60 * 24 * 2 * 100,
@@ -43,7 +46,8 @@ export default Api(
msg: "Success",
data: {
profile: {
name: "Paul",
id: user.id,
name: user.name,
avatar: "https://sdn.geekzu.org/avatar/d22eb460ecab37fcd7205e6a3c55c228?s=200&r=X&d=",
},
token
+51
View File
@@ -0,0 +1,51 @@
import { Api, Get, Query, useContext, useInject } from "@midwayjs/hooks";
import { JwtService } from "@midwayjs/jwt";
import { prisma } from "../../utils/prisma";
export default Api(
Get(),
Query<{ username: string, password: string }>(),
async () => {
const ctx = useContext();
const jwt = await useInject(JwtService);
const token = ctx.cookies.get("paul-token");
if (!token) {
return {
code: 0,
msg: "Not Login"
}
}
const jwtContent = jwt.decode(token) as Record<string, any>;
if (!jwtContent.id) {
return {
code: 0,
msg: "Invalid Token"
}
}
const user = await prisma.user.findUnique({
where: {
id: jwtContent.id
}
});
if (!user) {
return {
code: 0,
msg: "Not Login"
}
}
return {
code: 1,
msg: "Success",
data: {
...user,
avatar: "https://sdn.geekzu.org/avatar/d22eb460ecab37fcd7205e6a3c55c228?s=200&r=X&d="
}
}
}
);
+1 -1
View File
@@ -11,7 +11,7 @@ export class JwtStrategy extends PassportStrategy(
@Config("jwt")
jwtConfig: any;
async validate(payload) {
async validate(payload: any) {
console.log("payload", payload);
return payload;
+1
View File
@@ -1,5 +1,6 @@
export interface IGlobalData {
profile: {
id?: string
name: string
avatar: string
}