张延森 3 jaren geleden
bovenliggende
commit
99bd4260de

+ 2
- 1
config/dev.js Bestand weergeven

@@ -3,7 +3,8 @@ module.exports = {
3 3
     NODE_ENV: '"development"'
4 4
   },
5 5
   defineConstants: {
6
-    HOST: '"https://xlk.njyz.tech"', //正式
6
+    HOST: '"https://xlk.njyz.tech"',
7
+    // HOST: '"http://127.0.0.1:8088"',
7 8
     WSS_HOST: '"wss://xlk.njyz.tech"',
8 9
     OSS_PATH: '"https://zhiyun-image.oss-accelerate.aliyuncs.com/"',
9 10
     OSS_FAST_PATH: '"https://zhiyun-image.oss-accelerate.aliyuncs.com/"',

+ 9
- 6
src/app.jsx Bestand weergeven

@@ -3,6 +3,7 @@ import { Provider } from 'react-redux'
3 3
 import Taro from '@tarojs/taro'
4 4
 import { getLocation, getRouterParams } from '@/utils/tools'
5 5
 import login from '@/utils/login'
6
+import im from '@/utils/im'
6 7
 import store from './store'
7 8
 
8 9
 import './app.scss'
@@ -11,7 +12,10 @@ class App extends Component {
11 12
 
12 13
   componentDidMount () {}
13 14
 
14
-  componentDidShow () {}
15
+  componentDidShow (options) {
16
+    // 保留初始场景
17
+    Taro.setStorage('scene', options.scene)
18
+  }
15 19
 
16 20
   componentDidHide () {}
17 21
 
@@ -33,12 +37,11 @@ class App extends Component {
33 37
 
34 38
         // login
35 39
         login(payload).then((res) => {
36
-          // const { person: { personId } } = res
40
+          const { person: { personId } } = res
41
+          
42
+          // 初始化 im
43
+          im.init(personId)
37 44
 
38
-          // socket.createSocket({ id: personId });
39
-          // socket.onMessage(data => {
40
-          //   store.dispatch({ type: INCREASE_UNREADNUM })
41
-          // })
42 45
           // // 埋点
43 46
           // trackUserSource(router.params).then(r => this.updateTrack = r)
44 47
         })

+ 42
- 0
src/components/Auth/AuthAvatar.jsx Bestand weergeven

@@ -0,0 +1,42 @@
1
+import React, { useState } from 'react'
2
+import Taro from '@tarojs/taro'
3
+import { View, OpenData } from '@tarojs/components'
4
+import AuthBox from './AuthBox'
5
+import useAuth from './useAuth'
6
+import './style.scss'
7
+
8
+export default (props) => {
9
+  const [loading, setLoading] = useState(false)
10
+  const { updateUserInfo } = useAuth()
11
+
12
+  const handleUserProfile = (detail) => {
13
+    const { errMsg, ...data } = detail || {}
14
+    if (errMsg === 'getUserProfile:ok') {
15
+      setLoading(true)
16
+      updateUserInfo(data).then(() => {
17
+        setLoading(false)
18
+      }).catch((err) => {
19
+        console.error(err)
20
+        setLoading(false)
21
+      })
22
+    } else {
23
+      console.error(errMsg);
24
+      Taro.showToast({
25
+        title: '授权头像失败',
26
+        icon: 'none',
27
+        duration: 2000
28
+      })
29
+    }
30
+  }
31
+
32
+  return (
33
+    <AuthBox title='授权头像' openType='getUserInfo' loading={loading} onGetUserInfo={handleUserProfile}>
34
+      <View className='auth-avatar'>
35
+        <OpenData type='userAvatarUrl' />
36
+      </View>
37
+      <View className='auth-nickname'>
38
+        <OpenData type='userNickName' />
39
+      </View>
40
+    </AuthBox>
41
+  )
42
+}

+ 56
- 0
src/components/Auth/AuthBox.jsx Bestand weergeven

@@ -0,0 +1,56 @@
1
+import React from 'react'
2
+import Taro from '@tarojs/taro'
3
+import { View, Button } from '@tarojs/components'
4
+import './style.scss'
5
+
6
+export default (props) => {
7
+  const { loading, title, openType, onGetUserInfo, onGetPhoneNumber } = props
8
+
9
+  const handleGetUserInfo = () => {
10
+    Taro.getUserProfile({
11
+      lang: 'zh_CN',
12
+      desc: '用于完善个人资料',
13
+      success: (res) => {
14
+        onGetUserInfo(res)
15
+      }
16
+    })
17
+  }
18
+
19
+  const handlePhoneNumber = (e) => {
20
+    const { errMsg } = e.detail || {}
21
+    if (errMsg === 'getPhoneNumber:ok') {
22
+      onGetPhoneNumber(e.detail || {})
23
+    }
24
+  }
25
+
26
+  return (
27
+    <View className='auth-box'>
28
+      <View className='auth-header'>{title}</View>
29
+      <View className='auth-body'>
30
+        {props.children}
31
+      </View>
32
+      <View className='auth-footer'>
33
+        <Button className='auth-btn' type='default' plain>取消</Button>
34
+        {
35
+          openType === 'getUserInfo' ? (
36
+            <Button
37
+              className='auth-btn'
38
+              type='default'
39
+              onClick={handleGetUserInfo}
40
+              loading={loading}
41
+            >确定</Button>
42
+          ) : (
43
+            <Button
44
+              className='auth-btn'
45
+              type='default'
46
+              openType='getPhoneNumber'
47
+              lang='zh_CN'
48
+              onGetPhoneNumber={handlePhoneNumber}
49
+              loading={loading}
50
+            >确定</Button>
51
+          )
52
+        }
53
+      </View>
54
+    </View>
55
+  )
56
+}

+ 37
- 0
src/components/Auth/AuthPhone.jsx Bestand weergeven

@@ -0,0 +1,37 @@
1
+import React, { useState } from 'react'
2
+import Taro from '@tarojs/taro'
3
+import { View } from '@tarojs/components'
4
+import AuthBox from './AuthBox'
5
+import useAuth from './useAuth'
6
+import './style.scss'
7
+
8
+export default (props) => {
9
+  const [loading, setLoading] = useState(false)
10
+  const { updatePhoneNumber } = useAuth()
11
+
12
+  const handlePhoneNumber = (detail) => {
13
+    const { errMsg, ...data } = detail || {}
14
+    if (errMsg === 'getPhoneNumber:ok') {
15
+      setLoading(true)
16
+      updatePhoneNumber(data).then(() => {
17
+        setLoading(false)
18
+      }).catch((err) => {
19
+        console.error(err)
20
+        setLoading(false)
21
+      })
22
+    } else {
23
+      console.error(errMsg);
24
+      Taro.showToast({
25
+        title: '授权手机失败',
26
+        icon: 'none',
27
+        duration: 2000
28
+      })
29
+    }
30
+  }
31
+
32
+  return (
33
+    <AuthBox title='授权手机' openType='getPhoneNumber' loading={loading} onGetPhoneNumber={handlePhoneNumber}>
34
+      <View>请确认授权手机号,以便为您提供更优质的服务内容。</View>
35
+    </AuthBox>
36
+  )
37
+}

+ 45
- 0
src/components/Auth/style.scss Bestand weergeven

@@ -0,0 +1,45 @@
1
+.auth-box {
2
+  width: 100%;
3
+
4
+  .auth-header {
5
+    font-size: 32rpx;
6
+  }
7
+
8
+  .auth-body {
9
+    margin-top: 43rpx;
10
+    display: flex;
11
+    align-items: center;
12
+  }
13
+
14
+  .auth-footer {
15
+    margin-top: 50rpx;
16
+    text-align: center;
17
+  }
18
+
19
+  .auth-avatar {
20
+    width: 128rpx;
21
+    height: 128rpx;
22
+    border-radius: 50%;
23
+    overflow: hidden;
24
+    flex: none;
25
+  }
26
+
27
+  .auth-nickname {
28
+    margin-left: 1em;
29
+    flex: auto;
30
+  }
31
+
32
+  .auth-btn {
33
+    display: inline-block;
34
+    font-size: 30rpx;
35
+    background: #193C83;
36
+    border-radius: 39px;
37
+    color: #fff;
38
+    width: 236rpx;
39
+    height: 78rpx;
40
+
41
+    & + .auth-btn {
42
+      margin-left: 80rpx;
43
+    }
44
+  }
45
+}

+ 44
- 0
src/components/Auth/useAuth.js Bestand weergeven

@@ -0,0 +1,44 @@
1
+import { useCallback } from 'react'
2
+import { useDispatch } from 'react-redux'
3
+import Taro from '@tarojs/taro'
4
+import { dispatchUpdateUserInfo } from '@/actions/user'
5
+import { queryUserPhone } from '@/services/user'
6
+import { UPDATE_USER_INFO } from '@/constants/user'
7
+
8
+export default function useAuth() {
9
+  const dispatch = useDispatch()
10
+
11
+  const updateUserInfo = useCallback((data) => {
12
+    return new Promise((resolve, reject) => {
13
+      const sessionKey = Taro.getStorageSync('sessionKey')
14
+      Object.assign(data, { sessionKey })
15
+      dispatchUpdateUserInfo(data)(dispatch).then(() => {
16
+        resolve()
17
+      }).catch((err) => {
18
+        console.error(err)
19
+        reject(err)
20
+      })
21
+    })
22
+  }, [dispatch])
23
+
24
+  const updatePhoneNumber = useCallback((data) => {
25
+    return new Promise((resolve, reject) => {
26
+      const sessionKey = Taro.getStorageSync('sessionKey')
27
+      Object.assign(data, { sessionKey })
28
+      queryUserPhone(data).then((res) => {
29
+        dispatch({
30
+          type: UPDATE_USER_INFO,
31
+          payload: {
32
+            phone: res.phoneNumber
33
+          }
34
+        })
35
+        resolve()
36
+      }).catch((err) => {
37
+        console.error(err)
38
+        reject(err)
39
+      })
40
+    })
41
+  }, [dispatch])
42
+
43
+  return { updateUserInfo, updatePhoneNumber }
44
+}

+ 27
- 0
src/components/Overlay/index.jsx Bestand weergeven

@@ -0,0 +1,27 @@
1
+import React, { useMemo } from 'react'
2
+import { View } from '@tarojs/components'
3
+import './style.scss'
4
+
5
+export default (props) => {
6
+  const { visible = false, closeOnClick = false, onClose, style = {}, aligin = 'center' } = props
7
+
8
+  const handleClick = () => {
9
+    if (closeOnClick) {
10
+      onClose && onClose()
11
+    }
12
+  }
13
+
14
+  const classNames = useMemo(() => `overlay-warpper${visible ? ' visible' : ''}`, [visible])
15
+  const layStyle = {
16
+    ...style,
17
+    alignItems: aligin === 'top' ? 'flex-start' : ( aligin === 'bottom' ? 'flex-end' : 'center' )
18
+  }
19
+
20
+  return visible && (
21
+    <View className={classNames} style={layStyle} onClick={handleClick}>
22
+      <View>
23
+        {props.children}
24
+      </View>
25
+    </View>
26
+  )
27
+}

+ 22
- 0
src/components/Overlay/style.scss Bestand weergeven

@@ -0,0 +1,22 @@
1
+.overlay-warpper {
2
+  position: fixed;
3
+  top: 0;
4
+  left: 0;
5
+  width: 100vw;
6
+  height: 100vh;
7
+  background: rgba(0, 0, 0, .8);
8
+  z-index: 2000;
9
+  display: flex;
10
+  justify-content: center;
11
+  align-items: center;
12
+  transition: opacity 0.5s ease;
13
+  opacity: 0;
14
+
15
+  & > view {
16
+    flex: none;
17
+  }
18
+
19
+  &.visible {
20
+    opacity: 1;
21
+  }
22
+}

+ 1
- 1
src/components/Spin/style.scss Bestand weergeven

@@ -15,7 +15,7 @@ $width: 160px;
15 15
   }
16 16
 
17 17
   .mask-left, .mask-right {
18
-    background: #fff;
18
+    // background: #fff;
19 19
     top: 0;
20 20
     width: calc(50% + 1px);
21 21
     height: 100%;

+ 7
- 10
src/layout/Basic/index.jsx Bestand weergeven

@@ -1,9 +1,7 @@
1 1
 import React from 'react'
2 2
 import { connect } from 'react-redux'
3
-import { View } from '@tarojs/components'
4 3
 import Loading from '@/components/Loading'
5
-
6
-import './style.scss'
4
+import Overlay from '@/components/Overlay'
7 5
 
8 6
 const BasicLayout = (props) => {
9 7
   const {person, children, onProps, ...leftProps} = props
@@ -13,13 +11,12 @@ const BasicLayout = (props) => {
13 11
     onProps({person, ...leftProps})
14 12
   }
15 13
 
16
-  return null
17
-  // return loading ?
18
-  // (
19
-  //   <View className="page-loading-wrapper">
20
-  //     <Loading />
21
-  //   </View>
22
-  // ) : children || null
14
+  return loading ?
15
+  (
16
+    <Overlay visible={loading} style={{ background: 'rgba(255, 255, 255, .9)' }}>
17
+      <Loading />
18
+    </Overlay>
19
+  ) : children || null
23 20
 }
24 21
 
25 22
 export default connect(({ user }) => ({...user.userInfo || {}}))(BasicLayout)

+ 0
- 5
src/layout/Basic/style.scss Bestand weergeven

@@ -1,5 +0,0 @@
1
-
2
-.page-loading-wrapper {
3
-  margin-top: 30vw;
4
-  
5
-}

+ 32
- 7
src/layout/index.js Bestand weergeven

@@ -1,6 +1,13 @@
1 1
 import React, { useState, useEffect } from 'react'
2 2
 import { useRouter } from '@tarojs/taro'
3
+import { View } from '@tarojs/components'
4
+import Overlay from '@/components/Overlay'
5
+import AuthAvatar from '@/components/Auth/AuthAvatar'
6
+import AuthPhone from '@/components/Auth/AuthPhone'
3 7
 import BasicLayout from './Basic'
8
+import useAuth from './useAuth'
9
+
10
+import './style.scss'
4 11
 
5 12
 export default (Child) => (props) => {
6 13
   const [ready, setReady] = useState(false)
@@ -9,17 +16,35 @@ export default (Child) => (props) => {
9 16
   // 路由信息
10 17
   const router = useRouter()
11 18
 
19
+  const [authPhone, authAvatar] = useAuth(info?.person)
20
+
21
+  // 是否完成登录
22
+  const isLoged = !!info?.person?.personId
23
+
12 24
   useEffect(() => {
13
-    // const initedPerson = !!info?.person?.personId
14
-    // const initedRouter = !!router?.path
15
-    // setReady(initedPerson && initedRouter)
16
-    setReady(true)
17
-  })
25
+    setReady(isLoged)
26
+  }, [isLoged])
18 27
 
19 28
   return (
20 29
     <>
21
-      <BasicLayout onProps={setInfo} />    
22
-      {ready && <Child {...info} {...props} router={router} />}
30
+      <BasicLayout onProps={setInfo} />
31
+      {
32
+        ready && (
33
+          <>
34
+            <Overlay visible={authPhone} aligin='bottom'>
35
+              <View className='auth-wrapper'>
36
+                <AuthPhone />
37
+              </View>
38
+            </Overlay>
39
+            <Overlay visible={!authPhone && authAvatar} aligin='bottom'>
40
+              <View className='auth-wrapper'>
41
+                <AuthAvatar />
42
+              </View>
43
+            </Overlay>
44
+            <Child {...info} {...props} router={router} />
45
+          </>
46
+        )
47
+      }
23 48
     </>
24 49
   )
25 50
 }

+ 8
- 0
src/layout/style.scss Bestand weergeven

@@ -0,0 +1,8 @@
1
+.auth-wrapper {
2
+  width: 100vw;
3
+  box-sizing: border-box;
4
+  background: #fff;
5
+  border-top-left-radius: 24rpx;
6
+  border-top-right-radius: 24rpx;
7
+  padding: 40rpx;
8
+}

+ 37
- 0
src/layout/useAuth.js Bestand weergeven

@@ -0,0 +1,37 @@
1
+import { useState, useEffect } from 'react'
2
+import { useRouter } from '@tarojs/taro'
3
+import { routes } from '../routes'
4
+
5
+export default function useAuth(person) {
6
+  const [authPhone, setAuthPhone] = useState(false)
7
+  const [authAvatar, setAuthAvatar] = useState(false)
8
+  const { path } = useRouter()
9
+
10
+  useEffect(() => {
11
+    const current = routes.filter((route) => path.indexOf(route.page) > -1)[0]
12
+    if (current && current.auth && current.auth.length) {
13
+      // 如果需要授权手机
14
+      if (current.auth.indexOf('phone') > -1) {
15
+        if (person && !person.phone) {
16
+          setAuthPhone(true)
17
+        } else {
18
+          setAuthPhone(false)
19
+        }
20
+      }
21
+
22
+      // 如果需要授权头像
23
+      if (current.auth.indexOf('avatar') > -1) {
24
+        if (person && (!person.avatarurl || person.avatarurl.indexOf('default_avatar') > -1)) {
25
+          setAuthAvatar(true)
26
+        } else {
27
+          setAuthAvatar(false)
28
+        }
29
+      }
30
+    } else {
31
+      setAuthPhone(false)
32
+      setAuthAvatar(false)
33
+    }
34
+  }, [person, path])
35
+
36
+  return [authPhone, authAvatar]
37
+}

+ 2
- 3
src/reducers/user.js Bestand weergeven

@@ -16,7 +16,7 @@ const INITIAL_STATE = {
16 16
     extraInfo: {},
17 17
     miniApp: {},
18 18
   },
19
-  unReadNum: 0
19
+  unRead: true
20 20
 }
21 21
 
22 22
 export default function user(state = INITIAL_STATE, action) {
@@ -91,10 +91,9 @@ export default function user(state = INITIAL_STATE, action) {
91 91
       }
92 92
     }
93 93
     case ASSIGN_UNREADNUM: {
94
-      let { unReadNum } = action.payload
95 94
       return {
96 95
         ...state,
97
-        unReadNum
96
+        unRead: action.payload
98 97
       }
99 98
     }
100 99
     case INCREASE_UNREADNUM: {

+ 1
- 0
src/routes.js Bestand weergeven

@@ -10,6 +10,7 @@ const routes = [
10 10
     pkg: 'main',
11 11
     isTab: true,
12 12
     type: 'main',
13
+    // auth: ['phone', 'avatar']
13 14
   },
14 15
   {
15 16
     name: '视频',

+ 76
- 0
src/utils/im/index.js Bestand weergeven

@@ -0,0 +1,76 @@
1
+import IMSDK from './sdk'
2
+import initListeners from "./listeners"
3
+
4
+function IM() {
5
+  // 消息类型
6
+  const MESSAGETYPE = {
7
+    IMAGE: 'image',
8
+    TEXT: 'text',
9
+    CARD: 'card',
10
+  }
11
+
12
+  const sdk = IMSDK()
13
+  const listeners = initListeners()
14
+
15
+  let sendPerson;
16
+  let timer;
17
+
18
+  sdk.listen('onMessage', listeners.getListeners)
19
+
20
+  return {
21
+    MESSAGETYPE,
22
+    init,
23
+    listen: listeners.append,
24
+    connect: sdk.connect,
25
+    send,
26
+    sendMessage,
27
+  }
28
+
29
+  function bindPerson(person) {
30
+    sendPerson = person
31
+  }
32
+
33
+  function send(to) {
34
+    return function(type = MESSAGETYPE.TEXT) {
35
+      return function(message) {
36
+        return sendMessage(to, message, type)
37
+      }
38
+    }
39
+  }
40
+
41
+  function sendMessage(to, message, type = MESSAGETYPE.TEXT) {
42
+    return sdk.send(wrapData(to, message, type))
43
+  }
44
+
45
+  function wrapData(to, data, messageType) {
46
+    return JSON.stringify({
47
+      sendPerson,
48
+      receivePerson: to,
49
+      message: data,
50
+      messageType,
51
+      createDate: new Date().valueOf(),
52
+    })
53
+  }
54
+
55
+  function init(personId) {
56
+    // eslint-disable-next-line no-undef
57
+    const url = `${WSS_HOST}/wx/chat/${personId}`  
58
+
59
+    bindPerson(personId)
60
+
61
+    if (timer) {
62
+      clearInterval(timer)
63
+    }
64
+
65
+    timer = setInterval(() => {
66
+      if (sdk.getState() !== sdk.STATE.OPEN) {
67
+        im.connect({ url })
68
+      } else {
69
+        // sdk.send('ping')
70
+      }
71
+    }, 2 * 1000)
72
+  }
73
+}
74
+
75
+const im = IM();
76
+export default im;

+ 36
- 0
src/utils/im/listeners.js Bestand weergeven

@@ -0,0 +1,36 @@
1
+
2
+export default () => {
3
+  const listeners = []
4
+
5
+  function getIndex(name) {
6
+    for (let i = 0; i < listeners.length; i += 1) {
7
+      const fn = listeners[i]
8
+      if (fn.name === name) {
9
+        return i
10
+      }
11
+    }
12
+
13
+    return -1
14
+  }
15
+  
16
+  function remove(name) {
17
+    listeners = listeners.filter((f) => f.name !== name)
18
+  }
19
+
20
+  function append(name, fun) {
21
+    const pos = getIndex(name)
22
+    if (pos === -1) {
23
+      listeners.push({ name, fun })
24
+    }
25
+    return () => remove(name)
26
+  }
27
+
28
+  function getListeners() {
29
+    return listeners.map((listener) => listener.fun)
30
+  }
31
+
32
+  return {
33
+    getListeners,
34
+    append,
35
+  }
36
+}

+ 102
- 0
src/utils/im/sdk.js Bestand weergeven

@@ -0,0 +1,102 @@
1
+import Taro from '@tarojs/taro'
2
+
3
+export default function IMSDK() {
4
+  const STATE = {
5
+    CONNECTING: 0,
6
+    OPEN: 1,
7
+    CLOSING: 2,
8
+    CLOSED: 3,
9
+  }
10
+
11
+  const noop = () => []
12
+
13
+  const instanceRef = {
14
+    current: undefined,
15
+    onOpen: noop,
16
+    onMessage: noop,
17
+    onError: noop,
18
+    onClose: noop
19
+  }
20
+
21
+  const paramsRef = {
22
+    current: {}
23
+  }
24
+
25
+  return {
26
+    STATE,
27
+    getState,
28
+    connect,
29
+    listen,
30
+    send,
31
+  }
32
+
33
+  function getState() {
34
+    if (instanceRef.current) {
35
+      return instanceRef.current.readyState
36
+    }
37
+
38
+    return STATE.CLOSED
39
+  }
40
+
41
+  function listen(name, fns) {
42
+    if (typeof fns === 'function') {
43
+      instanceRef[name] = fns
44
+    }
45
+  }
46
+
47
+  function connect(options) {
48
+    Object.assign(paramsRef.current, options || {})
49
+    
50
+    if (instanceRef.current && instanceRef.current.readyState === STATE.OPEN) {
51
+      return Promise.resolve()
52
+    }
53
+
54
+    return new Promise((resolve, reject) => {
55
+      Taro.connectSocket({
56
+        ...paramsRef.current,
57
+        fail: (err) => reject(err),
58
+      }).then((task) => {
59
+        console.log('[WS][connect]', task)
60
+        instanceRef.current = task
61
+  
62
+        task.onOpen(function () {
63
+          console.log('[WS][onOpen]', paramsRef.current)
64
+          resolve()
65
+        })
66
+
67
+        task.onMessage(function (msg) {
68
+          console.info('[WS][onMessage]', msg)
69
+          instanceRef.onMessage().forEach((f) => f(msg))
70
+        })
71
+
72
+        task.onError(function (error) {
73
+          console.error('[WS][onError]', error)
74
+          instanceRef.onError().forEach((f) => f(error))
75
+        })
76
+
77
+        task.onClose(function (res) {
78
+          console.warn('[WS][onClose]', res)
79
+          instanceRef.onClose().forEach((f) => f(res))
80
+        })
81
+      })
82
+    })
83
+  }
84
+
85
+  function send(data) {
86
+    console.log('[WS][SEND]', data)
87
+    return new Promise((resovle, reject) => {
88
+      if (instanceRef.current) {
89
+        instanceRef.current.send({
90
+          data,
91
+          success: resovle,
92
+          fail: (err) => {
93
+            console.error('[WS][SEND]', err)
94
+            reject(err)
95
+          },
96
+        })
97
+      } else {
98
+        reject(STATE.CLOSED)
99
+      }
100
+    })
101
+  }
102
+}

+ 5
- 2
src/utils/login.js Bestand weergeven

@@ -38,9 +38,12 @@ export default (payload) => {
38 38
           }
39 39
 
40 40
           // 获取人员详细信息
41
+          // eslint-disable-next-line no-unused-vars
41 42
           queryUserInfo(person.personId).then(info => {
42
-            const { unReadNum } = info
43
-            dispatch({ type: ASSIGN_UNREADNUM, payload: { unReadNum } });
43
+            // const { unReadNum } = info
44
+
45
+            // 默认红点开始就有
46
+            dispatch({ type: ASSIGN_UNREADNUM, payload: true });
44 47
             resolve(data)
45 48
           }).catch(reject)
46 49
         }).catch(reject)