Feat: User Model + Login
用户数据表,前端可登录可获取用户信息
This commit is contained in:
@@ -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;
|
||||
@@ -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);
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import { useContext } from "react";
|
||||
|
||||
import GlobalContext from "@/components/GlobalContext";
|
||||
|
||||
function useGlobalContext() {
|
||||
return useContext(GlobalContext);
|
||||
}
|
||||
|
||||
export default useGlobalContext;
|
||||
+15
-2
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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="
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -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,5 +1,6 @@
|
||||
export interface IGlobalData {
|
||||
profile: {
|
||||
id?: string
|
||||
name: string
|
||||
avatar: string
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user