feat: save login token to localStorage for test
This commit is contained in:
parent
b951e34206
commit
6f6e6997ad
@ -5,6 +5,7 @@ const AppConfig = {
|
||||
API_PREFIX: 'http://chat.wx.wm-app.xyz',
|
||||
DEPLOY_DIR: '/',
|
||||
PUBLIC_PATH: '/',
|
||||
LOGIN_TOKEN_KEY: 'chat.user.token',
|
||||
},
|
||||
test: {
|
||||
CLIENT_ID: 'uziRFTVYkcgnGjAx',
|
||||
@ -12,6 +13,7 @@ const AppConfig = {
|
||||
API_PREFIX: 'http://chat.wx.wm-app.xyz',
|
||||
DEPLOY_DIR: (process.env.DEPLOY_DIR || '/'),
|
||||
PUBLIC_PATH: (process.env.PUBLIC_PATH || './'),
|
||||
LOGIN_TOKEN_KEY: 'chat.user.token',
|
||||
},
|
||||
production: {
|
||||
CLIENT_ID: 'aVjsh87iWEuhZdWC',
|
||||
@ -19,6 +21,7 @@ const AppConfig = {
|
||||
API_PREFIX: 'http://chat.wx.wm-app.xyz',
|
||||
DEPLOY_DIR: (process.env.DEPLOY_DIR || '/'),
|
||||
PUBLIC_PATH: (process.env.PUBLIC_PATH || './'),
|
||||
LOGIN_TOKEN_KEY: 'chat.user.token',
|
||||
}
|
||||
}
|
||||
export default AppConfig
|
||||
|
25
src/App.tsx
25
src/App.tsx
@ -1,10 +1,11 @@
|
||||
import React, {useEffect, useState} from 'react'
|
||||
import Login from "./components/Login";
|
||||
import {useSetState} from "ahooks";
|
||||
import {useMount, useSetState} from "ahooks";
|
||||
import {info, UserModel} from "./services/api";
|
||||
import Vip from "./components/vip";
|
||||
import Button from "./components/Button";
|
||||
import {io} from 'socket.io-client'
|
||||
import { useEffectOnce } from './utils/useEffectOnce';
|
||||
|
||||
|
||||
type MessageItem = {
|
||||
@ -14,7 +15,7 @@ type MessageItem = {
|
||||
content: string[];
|
||||
avatar: string;
|
||||
}
|
||||
|
||||
const LOGIN_TOKEN_KEY = APP_CONFIG.LOGIN_TOKEN_KEY;
|
||||
const avatar = 'https://www.cdnjson.com/images/2023/01/31/qwrgFf.jpg',
|
||||
avatar1 = 'https://www.cdnjson.com/images/2023/02/25/AI.png',
|
||||
globalMessageList: MessageItem[] = [
|
||||
@ -29,8 +30,10 @@ const avatar = 'https://www.cdnjson.com/images/2023/01/31/qwrgFf.jpg',
|
||||
avatar: avatar1
|
||||
},
|
||||
],
|
||||
|
||||
socket = io(APP_CONFIG.API_PREFIX, {
|
||||
autoConnect: false
|
||||
autoConnect: false,
|
||||
path:`/socket.io`
|
||||
})
|
||||
let messageIndex = 5, lastMessage = 0, initSocket = false;
|
||||
|
||||
@ -51,7 +54,7 @@ function App() {
|
||||
|
||||
function logout() {
|
||||
//TODO 调用注销登录接口
|
||||
localStorage.removeItem("chat-login")
|
||||
localStorage.removeItem(LOGIN_TOKEN_KEY)
|
||||
setState({user: undefined})
|
||||
}
|
||||
|
||||
@ -88,7 +91,7 @@ function App() {
|
||||
}
|
||||
|
||||
function loadUserInfo() {
|
||||
if (localStorage.getItem("chat-login")) {
|
||||
if (!localStorage.getItem(LOGIN_TOKEN_KEY)) {
|
||||
return;
|
||||
}
|
||||
info().then(user => {
|
||||
@ -147,7 +150,7 @@ function App() {
|
||||
})();
|
||||
};
|
||||
// 监听
|
||||
useEffect(loadUserInfo, [])
|
||||
useEffectOnce(loadUserInfo)
|
||||
useEffect(() => {
|
||||
if (messageList.length == 0) return;
|
||||
scrollToBottom();
|
||||
@ -203,16 +206,18 @@ function App() {
|
||||
</>)}
|
||||
</Button>
|
||||
{state.user?.vip &&
|
||||
<div className="open-vip" onClick={() => setState({showVip: true})}>+增加次数<</div>}
|
||||
<div className="open-vip" onClick={() => setState({showVip: true})}>+ 增加次数 ></div>}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{state.showLogin && <Login
|
||||
onClose={(logged) => {
|
||||
onClose={(logged,data) => {
|
||||
setState({showLogin: false})
|
||||
localStorage.setItem("chat-login", "yes")
|
||||
logged && loadUserInfo()
|
||||
if(logged && data){
|
||||
localStorage.setItem(LOGIN_TOKEN_KEY, data.token)
|
||||
loadUserInfo()
|
||||
}
|
||||
}}
|
||||
/>}
|
||||
{state.showVip && <Vip onClose={(opened) => {
|
||||
|
@ -4,10 +4,10 @@ import IconClose from "./icons/IconClose";
|
||||
import Button from "./Button";
|
||||
import {useSetState, useCountDown} from "ahooks";
|
||||
import Checkbox from "./Checkbox";
|
||||
import {login, sendCode} from "../services/api";
|
||||
import {login, sendCode, UserModel} from "../services/api";
|
||||
|
||||
export type LoginProps = {
|
||||
onClose: (logged?: boolean) => void
|
||||
onClose: (logged?: boolean,user?: UserModel) => void
|
||||
}
|
||||
|
||||
const Login: React.FC<LoginProps> = (props) => {
|
||||
@ -45,8 +45,8 @@ const Login: React.FC<LoginProps> = (props) => {
|
||||
return;
|
||||
}
|
||||
setState({error: '', loginLoading: true})
|
||||
login(data).then(() => {
|
||||
props.onClose(true)
|
||||
login(data).then((ret) => {
|
||||
props.onClose(true,ret)
|
||||
}).catch(error).finally(() => {
|
||||
setState({
|
||||
loginLoading: false
|
||||
|
@ -11,10 +11,11 @@ export type UserModel = {
|
||||
export function login(data: any) {
|
||||
return post<UserModel>('/api/user/login', data)
|
||||
}
|
||||
export function info() {
|
||||
return get<UserModel>('/api/user/info')
|
||||
}
|
||||
|
||||
export function info() {
|
||||
const token = localStorage.getItem(APP_CONFIG.LOGIN_TOKEN_KEY)
|
||||
return post<UserModel>('/api/user/info', {token})
|
||||
}
|
||||
|
||||
export function sendCode(phone: string) {
|
||||
return post('/api/sendCode', {phone})
|
||||
|
@ -15,17 +15,21 @@ const Axios = axios.create({
|
||||
baseURL: APP_CONFIG.API_PREFIX,
|
||||
timeout: 20000, // 设置超时时长
|
||||
headers: {
|
||||
'Content-Type': JSON_FORMAT,
|
||||
'Content-Type': JSON_FORMAT
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
// 请求前拦截
|
||||
// Axios.interceptors.request.use(config => {
|
||||
// return config
|
||||
// }, err => {
|
||||
// return Promise.reject(err)
|
||||
// })
|
||||
Axios.interceptors.request.use(config => {
|
||||
const token = localStorage.getItem(APP_CONFIG.LOGIN_TOKEN_KEY)
|
||||
if (token) {
|
||||
config.headers['token'] = token;
|
||||
}
|
||||
return config
|
||||
}, err => {
|
||||
return Promise.reject(err)
|
||||
})
|
||||
//
|
||||
// // 返回后拦截
|
||||
// Axios.interceptors.response.use(res => {
|
||||
|
27
src/utils/useEffectOnce.ts
Normal file
27
src/utils/useEffectOnce.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import {useEffect, useRef, useState} from "react"
|
||||
|
||||
export function useEffectOnce(effect:Function) {
|
||||
const effectFn = useRef(effect)
|
||||
const destroyFn = useRef<Function>()
|
||||
const effectCalled = useRef(false)
|
||||
const rendered = useRef(false)
|
||||
const [, refresh] = useState(0)
|
||||
|
||||
if (effectCalled.current) {
|
||||
rendered.current = true
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!effectCalled.current) {
|
||||
destroyFn.current = effectFn.current()
|
||||
effectCalled.current = true
|
||||
}
|
||||
|
||||
refresh(1)
|
||||
|
||||
return () => {
|
||||
if (rendered.current === false) return
|
||||
if (destroyFn.current) destroyFn.current()
|
||||
}
|
||||
}, [])
|
||||
}
|
3
src/vite-env.d.ts
vendored
3
src/vite-env.d.ts
vendored
@ -11,6 +11,7 @@ interface IAppConfigItem {
|
||||
* 静态资源目录
|
||||
*/
|
||||
PUBLIC_PATH?: string
|
||||
LOGIN_TOKEN_KEY: string
|
||||
}
|
||||
|
||||
type IAPP_ENV = 'development' | 'test' | 'production'
|
||||
@ -19,4 +20,4 @@ type IAppConfig = {
|
||||
};
|
||||
// 常量配置类型
|
||||
declare const APP_ENV: IAPP_ENV;
|
||||
declare const APP_CONFIG: IAppConfigItem;
|
||||
declare const APP_CONFIG: IAppConfigItem;
|
Loading…
x
Reference in New Issue
Block a user