登录封装完成

This commit is contained in:
czm 2022-04-25 19:02:10 +08:00
parent 5bae62d34d
commit e7a130533d
19 changed files with 604 additions and 70 deletions

17
src/common/client.js Normal file
View File

@ -0,0 +1,17 @@
import Taro from "@tarojs/taro";
/**
* 设置 客户 本地存储
* @param {Object} clientInfo
*/
export const setClient = (clientInfo) => {
Taro.setStorageSync('client', clientInfo)
}
/**
* 返回 客户 本地存储
*/
export const getClient = () => {
Taro.getStorageSync('client') || null
}

135
src/common/fotmat.js Normal file
View File

@ -0,0 +1,135 @@
/**
* 移除井号
* @param {String} val code 编码
* @returns
*/
export const formatRemoveHashTag = (val = "") => {
// console.log('移除标签',val,val.endsWith("#"));
return val.endsWith("#") ? val.replace("#", "") : val;
};
/**
* 格式化编码+名称显示方式
* @param {String} code 编码
* @param {String} name 名称
* @param {*} mode 模式 both:code + 名称 name: 仅显示名称
* @returns
*/
export const formatHashTag = (code = "", name = "", mode = "both") => {
if (mode == 'both') {
return `${formatRemoveHashTag(code)}# ${name}`
} else if (mode == 'name') {
return `${name}`
}
}
const Digit = 10 * 10
/**
* 重量 进退位 单位
*/
export const weightDigit = 1000
/**
* 除以
* @param {*} val
* @param {*} digit
* @returns
*/
export const formatPriceDiv = (val, digit = Digit) => {
return strip(Number(val / digit)) || 0
}
/**
* 乘以
* @param {*} val
* @param {*} digit
* @returns
*/
export const formatPriceMul = (val, digit = Digit) => {
return strip(Number(val * digit)) || 0
}
/**
* 格式化重量单位 (乘以)
* @param {Number} val
* @returns
*/
export const formatWeightMul = (val, digit = weightDigit) => {
return strip(Number(val * digit)) || 0
}
/**
* 格式化重量单位 (除以)
* @param {*} val
*/
export const formatWeightDiv = (val, digit = weightDigit) => {
return strip(Number(val / digit)) || 0
}
export const formatDateTime = (val, fmt = "YYYY-MM-DD HH:mm:ss") => {
if (val) {
let time = new Date(val)
let Y = time.getFullYear()
let M = time.getMonth() + 1
let d = time.getDate()
let h = time.getHours()
let m = time.getMinutes()
let s = time.getSeconds()
fmt = fmt.replace('YYYY', Y).replace('MM', M.toString().padStart(2, '0')).replace('DD', d.toString().padStart(2, '0')).replace('HH', h.toString().padStart(2, '0')).replace('mm', m.toString().padStart(2, '0')).replace('ss', s.toString().padStart(2, '0'))
// fmt = fmt.replace('MM', M)
// fmt = fmt.replace('DD', d)
// fmt = fmt.replace('HH', h)
// fmt = fmt.replace('mm', m)
// fmt = fmt.replace('ss', s)
return fmt
} else {
return val
}
}
/**
* 精度
* @param {*} num
* @param {*} precision
* @returns
*/
export const strip = (num, precision = 12) => {
return +parseFloat(num.toPrecision(precision));
}
/**
* 转换金额单位
* @param {*} num 金额 / 数值
* @param {*} digit 转换单位
* @returns
*/
export const formatMillionYuan = (num, digit = 10000) => {
return num / digit > 1 ? { num: toDecimal2(num / digit), million: true } : { num, million: false }
}
/**
* 数值保留两位小数
* @param {*} x
* @returns
*/
export const toDecimal2 = (x) => {
var f = parseFloat(x);
if (isNaN(f)) {
return 0;
}
f = f + "";
let index = f.lastIndexOf('.');
if (index >= 0) {
let decimal = f.substring(index + 1);
if (decimal.length == 1) {
f = f.substring(0, index + 1) + decimal + "0";
} else {
f = f.substring(0, index + 1) + decimal.substring(0, 2);
}
}
return f;
}

34
src/common/system.js Normal file
View File

@ -0,0 +1,34 @@
import Taro from "@tarojs/taro";
/**
* 设置 系统 本地存储
* @param {Object} systemInfo
*/
export const setSystem = (systemInfo) => {
Taro.setStorageSync('system', JSON.stringify(systemInfo))
}
/**
* 返回 系统 本地存储
*/
export const getSystem = () => {
const result = Taro.getStorageSync('system')
return result ? JSON.parse(result) : null
}
/**
* 设置 小程序 本地存储
* @param {Object} systemInfo
*/
export const setAccountInfo = (systemInfo) => {
Taro.setStorageSync('accountInfo', JSON.stringify(systemInfo))
}
/**
* 返回 系统 本地存储
*/
export const getAccountInfo = () => {
const result = Taro.getStorageSync('accountInfo')
return result ? JSON.parse(result) : null
}

150
src/common/uploadImage.js Normal file
View File

@ -0,0 +1,150 @@
import Taro from '@tarojs/taro';
import { GET_UPLOAD_SIGN, CDN_UPLOAD_IMG, UPLOAD_CDN_URL } from './constant'
import { GetSignApi } from '@/api/cdn'
const { fetchData: GetSign, success, data: resData, msg, code } = GetSignApi()
// 上传图片 获取authPolicy
/*
scene 场景值区分上传文件的根路径
type 类型值区分上传业务bucket
*/
const getSecret = (scene, type) => {
return new Promise(async (resolve, reject) => {
const SAVE_PATH = `/${scene}/{filemd5}{day}{hour}{min}{sec}{.suffix}`;
let params = {
'method': 'post',
'save_key': SAVE_PATH
}
// 获取签名
await GetSign(params)
if (success.value) {
// console.log('返回签名',resData.value);
resolve(resData.value)
} else {
reject({
code: code.value || '9999',
msg: msg.value
});
}
})
}
const getFileType = (name) => {
if (!name) return false;
var imgType = ["gif", "jpeg", "jpg", "bmp", "png"];
var videoType = ["avi", "wmv", "mkv", "mp4", "mov", "rm", "3gp", "flv", "mpg", "rmvb", "quicktime"];
if (RegExp("\.?(" + imgType.join("|") + ")$", "i").test(name.toLowerCase())) {
return 'image';
} else if (RegExp("\.(" + videoType.join("|") + ")$", "i").test(name.toLowerCase())) {
return 'video';
} else {
return false;
}
}
const upYunbucket = (type) => {
var bucket = ""
switch (type) {
case "product":
bucket = "testzzfzyc"
break;
}
return bucket
}
/**
*
* @param {*} file 传入文件
* @param {String} secene 传入 'product'
* @param {String} type 传入 'product'
* @returns
*/
const uploadCDNImg = (file, secene, type) => {
// var file = event.target.files[0];
// var filetype = file.type
let filetype = file.tempFilePath
if (!getFileType(filetype)) {
Taro.showToast({
title: "上传文件类型错误",
icon: "none",
duration: 3800
})
return false
}
return new Promise((resolve, reject, race) => {
getSecret(secene, type)
.then(result => {
console.log('bucket', result.bucket);
var formdata = {
'authorization': result.authorization,
'policy': result.policy,
// "file": file.tempFilePath,
}
const uploadTask = Taro.uploadFile({
url: `${UPLOAD_CDN_URL}${result.bucket}`,
formData: formdata,
filePath: file.tempFilePath,
name: 'file',
success: res => {
resolve(JSON.parse(`${res.data}`))
},
fail: err => {
console.log(err)
reject(err)
}
})
uploadTask.progress(res => {
console.log('上传进度', res.progress);
if (res.progress < 100) {
Taro.showLoading({
title: '上传中...'
})
} else {
Taro.hideLoading()
}
})
})
.catch(result => {
reject(result)
Taro.showToast({
title: "获取密钥失败!",
icon: "none",
duration: 3800
})
})
})
}
const taroChooseImg = () => {
Taro.chooseImage({
count: 1,
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
success: (res) => {
console.log('res:', res)
Taro.chooseMessageFile({
count: 1,
})
},
fail: (err) => {
console.log('图片选择失败:', err)
}
})
}
export default uploadCDNImg

36
src/common/user.js Normal file
View File

@ -0,0 +1,36 @@
import Taro from "@tarojs/taro";
import { useStore } from "vuex";
import { computed } from "@vue/runtime-core";
/**
*
* @param {String} token
*/
export const setToken = (token) => {
Taro.setStorageSync('token', token)
}
/**
*
* @param {Object} userinfo
*/
export const setUserInfo = (userinfo) => {
Taro.setStorageSync('userInfo', userinfo)
}
/**
* 检查登录
*/
export const checkLogin = () => {
const store = useStore()
const token = computed(() => store.state.token)
console.log('checklogin token', token);
// 本地调试屏蔽
if (token == '') {
Taro.redirectTo({
url: '/pages/login/index',
})
}
}

94
src/common/util.js Normal file
View File

@ -0,0 +1,94 @@
/**
* 防抖
* @param {*} fn
* @param {*} delay
* @returns
*/
export const debounce = (fn, delay) => {
let timer = null;
return (...param) => {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
fn(...param);
}, delay);
};
}
/**
* 节流
* @param {*} fn
* @param {*} delay
* @returns
*/
export const throttle = (fn, delay) => {
let pre = 0;
return (...params) => {
let now = new Date().getTime();
console.log('相差:',now-pre)
if (now - pre > delay) {
fn(...params);
pre = now;
}
};
}
/**
* 批量过滤对象值为空的属性
* @param {Object} val 需要过滤的对象
* @param {Array} arr 排除过滤的属性
* @returns
*/
export const getFilterData = (val = {}, arr = []) => {
let res = {}
for(let key in val) {
if(val[key]!=undefined&&val[key]!=null&&(!arr.includes(key))){
if(val[key] instanceof Number){
console.log("+++",val[key]);
if(!isNaN(val[key])) {
res[key] = val[key]
}
}else{
res[key] = val[key]
}
}
}
return res
}
/**
* 对象深拷贝
* @param {*} object
* @returns
*/
export const copyObject = (object)=>{
if(object.constructor==Object){
let keys = Object.keys(object);
let newObject = {};
keys.map(key=>{
newObject[key]= copyObject(object[key]);
})
return newObject;
}else if(object.constructor==Array){
return object.map(item=>{
return copyObject(item);
})
}else{
return object;
}
}
/**
*
* @param {*} suffix
* !w80
!w100
!w160
!w200
!w400
!w800
!wh400
!w600
*/
export const screenshot = (url, suffix="!w200")=>{
return url+suffix;
}

View File

@ -2,7 +2,8 @@ import { Input, View } from "@tarojs/components";
import styles from "./index.module.scss" import styles from "./index.module.scss"
import CloseBtn from "@/components/closeBtn" import CloseBtn from "@/components/closeBtn"
import classnames from "classnames"; import classnames from "classnames";
import { memo, useEffect, useState } from "react"; import { debounce } from "@/common/util";
import { memo, useEffect, useRef, useState } from "react";
type Params = { type Params = {
clickOnSearch?: (val: string) => void clickOnSearch?: (val: string) => void
@ -14,7 +15,8 @@ type Params = {
style?: Object, style?: Object,
showBtn?: false|true, showBtn?: false|true,
btnStyle?: Object, btnStyle?: Object,
btnTitle?: string btnTitle?: string,
debounceTime?: number //防抖时间不设默认wei'ling
} }
export default memo(({ export default memo(({
@ -24,17 +26,21 @@ export default memo(({
placeholder = '输入搜索内容', placeholder = '输入搜索内容',
showIcon = true, showIcon = true,
showBtn = false, showBtn = false,
style = {},
btnStyle = {}, btnStyle = {},
placeIcon = 'inner', placeIcon = 'inner',
btnTitle = '搜索' btnTitle = '搜索',
debounceTime = 0
}:Params) => { }:Params) => {
const [inputCon , setInputCon] = useState('') const [inputCon , setInputCon] = useState('')
const debounceTimeRef = useRef(0)
useEffect(() => {
debounceTimeRef.current = debounceTime
}, [debounceTime])
const onInputEven = (e) => { const onInputEven = (e) => {
const value = e.detail.value const value = e.detail.value
setInputCon(value) changeData(value)
changeOnSearch?.(value)
} }
const clearInput = () => { const clearInput = () => {
@ -42,13 +48,18 @@ export default memo(({
changeOnSearch?.('') changeOnSearch?.('')
} }
const changeData = debounce((value) => {
setInputCon(value)
changeOnSearch?.(value)
}, debounceTimeRef.current)
const onSearch = () => { const onSearch = () => {
clickOnSearch?.(inputCon) clickOnSearch?.(inputCon)
} }
return ( return (
<> <>
<View className={styles.search_main} onClick={() => onSearch()} style={style}> <View className={styles.search_main} onClick={() => clickOnSearch?.(inputCon)}>
<View className={styles.search_con}> <View className={styles.search_con}>
{showIcon&&<View className={classnames('iconfont', 'icon-sousuo', styles.icon_a_sousuo1_self, placeIcon=='inner'?styles.icon_inner:styles.icon_out)}></View>} {showIcon&&<View className={classnames('iconfont', 'icon-sousuo', styles.icon_a_sousuo1_self, placeIcon=='inner'?styles.icon_inner:styles.icon_out)}></View>}
<Input placeholderStyle='color:#ABABAB; font-size:26rpx' className={classnames(placeIcon=='out'&&styles.input_out)} disabled={disabled} value={inputCon} placeholder={placeholder} onInput={(e) => onInputEven(e)}></Input> <Input placeholderStyle='color:#ABABAB; font-size:26rpx' className={classnames(placeIcon=='out'&&styles.input_out)} disabled={disabled} value={inputCon} placeholder={placeholder} onInput={(e) => onInputEven(e)}></Input>

View File

@ -1,2 +1,6 @@
export const GETUSER = 'GETUSER' export const SET_USERINFO = 'setUserInfo'
export const SETUSER = 'SETUSER' export const SET_TOKEN = 'setToken'
export const SET_SESSIONKEY = 'setSessionkey'
export const CLEAR_TOKEN = 'clearToken'
export const CLEAR_SESSIONKEY = 'clearSessionkey'
export const CLEAR_USERINFO = 'clearUserInfo'

View File

@ -30,7 +30,7 @@
margin-top: 10px; margin-top: 10px;
background-color: rgba(0,0,0, 0.5); background-color: rgba(0,0,0, 0.5);
padding: 0 10px; padding: 0 10px;
@include common_ellipsis @include common_ellipsis(1);
} }
} }
} }

View File

@ -10,6 +10,7 @@ import styles from './index.module.scss'
import { useEffect, useMemo, useState } from 'react'; import { useEffect, useMemo, useState } from 'react';
import useManualPullDownRefresh from '@/use/useManualPullDownRefresh'; import useManualPullDownRefresh from '@/use/useManualPullDownRefresh';
import { goLink } from '@/common/common'; import { goLink } from '@/common/common';
import useUserInfo from '@/use/useUserInfo';
type item = {title:string, img:string, url:string, id:number} type item = {title:string, img:string, url:string, id:number}
type params = { type params = {
@ -103,10 +104,7 @@ export default (props:params) => {
} }
}) })
useDidShow(() => { const {user} = useUserInfo()
Taro.getCurrentPages()
})
return ( return (
<View className={styles.main}> <View className={styles.main}>

View File

@ -20,6 +20,9 @@
text-align: center; text-align: center;
line-height: 44px; line-height: 44px;
} }
.search_input{
width: 300px;
}
} }
.products{ .products{
flex:1; flex:1;

View File

@ -10,7 +10,7 @@ import { goLink } from '@/common/common'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import Taro, { useDidShow, usePullDownRefresh, useRouter } from '@tarojs/taro' import Taro, { useDidShow, usePullDownRefresh, useRouter } from '@tarojs/taro'
import useManualPullDownRefresh from '@/use/useManualPullDownRefresh' import useManualPullDownRefresh from '@/use/useManualPullDownRefresh'
import useUserInfo from '@/use/useUserInfo'
export default () => { export default () => {
const tabs_list = [ const tabs_list = [
@ -47,31 +47,9 @@ export default () => {
}, 1000) }, 1000)
} }
const goto = function (e) {
var t = this
Taro.navigateTo({
url: '/pages/details/index',
events: {
// 为指定事件添加一个监听器,获取被打开页面传送到当前页面的数据
backFromTargetPage: function (backData) {
console.log('好啦,可以在这里写你的逻辑了', backData)
if (backData.from == 'page2') {
// 监听到 page2 返回
console.log('好啦,可以在这里写你的逻辑了', backData)
t.setData({
isBackFromPage2: !0
})
}
}
}
})
}
return ( return (
<MoveBtn onClick={() => setShowShopCart(!showShopCart)}> <MoveBtn onClick={() => setShowShopCart(!showShopCart)}>
<View className={styles.main}> <View className={styles.main}>
<View onClick={(e) => goto(e)}>aaa</View>
<Swiper/> <Swiper/>
<View className={styles.search}> <View className={styles.search}>
<View className={styles.search_collect}></View> <View className={styles.search_collect}></View>

View File

@ -24,7 +24,7 @@
color: $color_font_two; color: $color_font_two;
} }
textarea{ textarea{
background-color: $color_bg_one; background-color: #f3f3f3;
border-radius: 10px; border-radius: 10px;
width: 100%; width: 100%;
height: 313px; height: 313px;
@ -32,6 +32,7 @@
padding-bottom: 50px; padding-bottom: 50px;
box-sizing: border-box; box-sizing: border-box;
font-size: $font_size; font-size: $font_size;
border: 2px solid #e6e6e6;
} }
} }
.order_save_address{ .order_save_address{

View File

@ -10,13 +10,13 @@ type Param = {
export default ({onBlur, onSave}:Param) => { export default ({onBlur, onSave}:Param) => {
const [descData, setDescData] = useState({ const [descData, setDescData] = useState({
number: 0, number: 0,
value: '' value: '',
count: 10
}) })
const getDesc = useCallback((e) => { const getDesc = useCallback((e) => {
let value = e.detail.value let value = e.detail.value
setDescData({...descData, number:value.length, value}) let res = value.slice(0, descData.count)
setDescData({...descData, number:res.length, value: res})
},[]) },[])
const setSave = () => { const setSave = () => {
@ -26,8 +26,8 @@ export default ({onBlur, onSave}:Param) => {
<View className={styles.order_popup}> <View className={styles.order_popup}>
<View className={styles.order_popup_title}></View> <View className={styles.order_popup_title}></View>
<View className={styles.order_popup_input}> <View className={styles.order_popup_input}>
<Textarea placeholder="请添加备注" maxlength={200} cursorSpacing={100} onInput={(e) => getDesc(e)} onBlur={(e) => onBlur?.(e)}></Textarea> <Textarea placeholder="请添加备注" maxlength={10} cursorSpacing={100} onInput={(e) => getDesc(e)} onBlur={(e) => onBlur?.(e)}></Textarea>
<View className={styles.descDataNum}>{descData.number}/200</View> <View className={styles.descDataNum}>{descData.number}/{descData.count}</View>
</View> </View>
<View className={styles.order_save_address} onClick={() => setSave()}></View> <View className={styles.order_save_address} onClick={() => setSave()}></View>
</View> </View>

View File

@ -10,7 +10,7 @@ export default () => {
return ( return (
<View className={styles.main}> <View className={styles.main}>
<View className={styles.search}> <View className={styles.search}>
<Search style={{width: '100%'}} placeholder="请输入面料关键词" placeIcon="out" showBtn={true} clickOnSearch={() => goLink('/pages/searchList/index')}/> <Search style={{width: '100%'}} debounceTime={300} changeOnSearch={(e) => console.log(e)} placeholder="请输入面料关键词" placeIcon="out" showBtn={true} />
</View> </View>
<View className={styles.hot}> <View className={styles.hot}>
<View className={styles.hot_header}> <View className={styles.hot_header}>

View File

@ -1,23 +1,51 @@
import { GETUSER, SETUSER } from '../constants/userInfo' import Taro from '@tarojs/taro'
import { SET_USERINFO, SET_TOKEN, SET_SESSIONKEY, CLEAR_TOKEN, CLEAR_USERINFO, CLEAR_SESSIONKEY} from '../constants/userInfo'
const INIT_USER = { export type UserParam = {
name: '张三', name?:string,
phone: '110', phone?:string,
avatarUrl: '', avatarUrl?:string,
token: '',
} }
export default function counter (state = INIT_USER, action) { type Action = {
switch (action.type) { type?: string,
case GETUSER: data?: DataParam
return { }
...state,
} export type DataParam = {
case SETUSER: token?: string
return { sessionkey?: string,
...state, userInfo: UserParam
} }
const INIT_USER = {
userInfo: Taro.getStorageSync('userInfo')?JSON.parse(Taro.getStorageSync('userInfo')):null,
token: Taro.getStorageSync('token')||'',
session_key: Taro.getStorageSync('sessionkey')||'',
}
export default function counter (state = INIT_USER, action: Action) {
const {type, data} = action
switch (type) {
case SET_USERINFO:
Taro.setStorageSync('userInfo',JSON.stringify(data?.userInfo))
return {...state,...data}
case SET_TOKEN:
Taro.setStorageSync('token',JSON.stringify(data?.token))
return {...state,...data}
case SET_SESSIONKEY:
Taro.setStorageSync('sessionkey',JSON.stringify(data?.sessionkey))
return {...state,...data}
case CLEAR_TOKEN:
Taro.removeStorageSync('token')
return {...state, token:''}
case CLEAR_SESSIONKEY:
Taro.removeStorageSync('sessionkey')
return {...state, session_key:''}
case CLEAR_USERINFO:
Taro.removeStorageSync('userInfo')
return {...state, userInfo: null}
default: default:
return state return state
} }

View File

@ -193,9 +193,10 @@ export const useRequest = (options = {
title: `错误:${showStatus(statusCode)}` title: `错误:${showStatus(statusCode)}`
}) })
if (statusCode === 401) { if (statusCode === 401) {
Taro.reLaunch({ //未登录
url: '/pages/login/index' // Taro.reLaunch({
}) // url: '/pages/login/index'
// })
} }
} }
@ -209,6 +210,7 @@ export const useRequest = (options = {
stateRef.current.error = false stateRef.current.error = false
stateRef.current.loading = false stateRef.current.loading = false
setState(() => stateRef.current) setState(() => stateRef.current)
return stateRef.current
} }
return { return {

View File

@ -1,17 +1,17 @@
import { useEffect, useState } from "react" import { useEffect, useState } from "react"
import { WX_APPID } from "@/common/constant" import { WX_APPID } from "@/common/constant"
import useUserInfo from "./useUserInfo"
export default () => { export default () => {
const {setToken, setSessionKey, setUserInfo} = useUserInfo()
const [loginState, setLoginState] = useState({ const [loginState, setLoginState] = useState({
session_key: '', session_key: '',
token: '', token: '',
userInfo: '' userInfo: ''
}) })
useEffect(() => {
getToken()
}, [])
const getToken = () => { const getToken = () => {
Taro.login({ Taro.login({
success: function (res) { success: function (res) {
@ -34,6 +34,8 @@ export default () => {
session_key: data.session_key, session_key: data.session_key,
token: data.token token: data.token
}) })
setToken(data.token)
setLoginState(data.session_key)
} }
}) })
} else { } else {
@ -66,7 +68,7 @@ export default () => {
Appid: WX_APPID Appid: WX_APPID
}, },
success: (e) => { success: (e) => {
console.log('123123') setUserInfo({})
}, },
fail: (e) => { fail: (e) => {
console.log(e) console.log(e)

41
src/use/useUserInfo.ts Normal file
View File

@ -0,0 +1,41 @@
import { useDispatch, useSelector } from 'react-redux'
import { CLEAR_SESSIONKEY, SET_USERINFO, SET_TOKEN, SET_SESSIONKEY, CLEAR_USERINFO, CLEAR_TOKEN} from '@/constants/userInfo'
import {DataParam, UserParam} from '@/reducers/userInfo'
export default () => {
const user = useSelector((state:DataParam) => state.userInfo) as DataParam
const dispatch = useDispatch()
const setToken = (token: string) => {
dispatch({type:SET_TOKEN, data:{token}})
}
const setSessionKey = (sessionkey: string) => {
dispatch({type:SET_SESSIONKEY, data:{sessionkey}})
}
const setUserInfo = (userInfo: UserParam) => {
dispatch({type:SET_USERINFO, data:{userInfo}})
}
const removeUserInfo = () => {
dispatch({type:CLEAR_USERINFO})
}
const removeToken = () => {
dispatch({type:CLEAR_TOKEN})
}
const removeSessionKey = () => {
dispatch({type:CLEAR_SESSIONKEY})
}
return {
setToken,
setUserInfo,
setSessionKey,
removeUserInfo,
removeToken,
removeSessionKey,
user, //响应式数据返回
}
}