张延森 4 years ago
parent
commit
6c075758b0

+ 56
- 20
src/components/GetUserIcon/index.jsx View File

@@ -1,37 +1,73 @@
1 1
 import React, { useState } from 'react'
2
+import Taro from '@tarojs/taro'
2 3
 import { Button } from '@tarojs/components'
3 4
 import request, { apis } from '@/utils/request'
4
-import Taro from '@tarojs/taro'
5
-import { store, useModel } from '@/store'
5
+import { useModel } from '@/store'
6 6
 import '@/assets/css/reset.less'
7 7
 import '@/assets/css/iconfont.less'
8 8
 import './index.less'
9 9
 
10 10
 export default function GetUserIcon (props) {
11
-
12
-  const { setUser } = store.getModel('user').getState()
13
-  const { user } = useModel('user')
14
-  const { Show = false, Close = () => { } } = props
11
+  const [showPannel, setShowPannel] = useState(true)
12
+  const { user, setUser } = useModel('user')
15 13
 
16 14
   const ToGetUserIcon = (e) => { // 授权用户头像
17
-    if (e.detail.userInfo !== undefined) {
18
-      setUser({ ...user, avatarurl: e.detail.userInfo.avatarUrl, nickname: e.detail.userInfo.nickName })
19
-      Taro.showToast({ title: '头像授权成功', icon: 'none' })
15
+    const { errMsg, ...data } = e.detail
16
+    if (errMsg === 'getUserInfo:ok') {
17
+      request({
18
+        ...apis.userAutInfo,
19
+        data: {
20
+          sessionKey: Taro.getStorageSync('sessionKey'),
21
+          ...data,
22
+        }
23
+      }).then(res => {
24
+        const { person } = res
25
+        setUser({
26
+          ...user,
27
+          ...person
28
+        })
29
+        if (props.onOk) {
30
+          props.onOk(res)
31
+        }
32
+      }).catch(er => {
33
+        setShowPannel(true)
34
+        if (props.onError) {
35
+          props.onError(er.message || er.errMsg || er)
36
+        }
37
+      })
20 38
     } else {
21
-      Taro.showToast({ title: '头像授权失败', icon: 'none' })
39
+      setShowPannel(true)
40
+      if (props.onError) {
41
+        props.onError(errMsg)
42
+      }
43
+    }
44
+  }
45
+
46
+  const handleCancel = () => {
47
+    if (props.onCancel) {
48
+      props.onCancel()
22 49
     }
23
-    Close()
24 50
   }
25 51
 
26
-  return (
27
-    <view className='GetUserIcon' style={{ display: Show ? 'block' : 'none' }}>
28
-      <view className='centerLabel'>
29
-        <text>您暂未授权头像</text>
30
-        <view className='flex-h'>
31
-          <text className='flex-item' onClick={Close}>取消</text>
32
-          <Button className='flex-item' open-type='getUserInfo' lang='zh_CN' ongetuserinfo={ToGetUserIcon}>去授权</Button>
33
-        </view>
34
-      </view>
52
+  return props.visible && (
53
+    <view className='GetUserIcon'>
54
+      {
55
+        showPannel && (
56
+          <view className='centerLabel'>
57
+            <text>您暂未授权头像</text>
58
+            <view className='flex-h'>
59
+              <text className='flex-item' onClick={handleCancel}>取消</text>
60
+              <Button
61
+                className='flex-item'
62
+                open-type='getUserInfo'
63
+                lang='zh_CN'
64
+                onGetUserInfo={ToGetUserIcon}
65
+                onTap={() => setShowPannel(false)}
66
+              >去授权</Button>
67
+            </view>
68
+          </view>
69
+        )
70
+      }
35 71
     </view>
36 72
   )
37 73
 }

+ 55
- 28
src/components/GetUserPhone/index.jsx View File

@@ -1,44 +1,71 @@
1 1
 import React, { useState } from 'react'
2
+import Taro from '@tarojs/taro'
2 3
 import { Button } from '@tarojs/components'
3 4
 import request, { apis } from '@/utils/request'
4
-import Taro from '@tarojs/taro'
5
-import { store, useModel } from '@/store'
5
+import { useModel } from '@/store'
6 6
 import '@/assets/css/reset.less'
7 7
 import '@/assets/css/iconfont.less'
8 8
 import './index.less'
9 9
 
10 10
 export default function GetUserPhone (props) {
11
-
12
-  const { setUser } = store.getModel('user').getState()
13
-  const { user } = useModel('user')
14
-  const { Show = false, Close = () => { } } = props
11
+  const [showPannel, setShowPannel] = useState(true)
12
+  const { user, setUser } = useModel('user')
15 13
 
16 14
   const ToGetUserPhone = (e) => { // 授权手机号
17
-    Close()
18
-    request({
19
-      ...apis.getUserPhone,
20
-      data: {
21
-        sessionKey: Taro.getStorageSync('sessionKey'),
22
-        encryptedData: e.detail.encryptedData,
23
-        iv: e.detail.iv
15
+    const { errMsg, ...data } = e.detail
16
+    if (errMsg === 'getPhoneNumber:ok') {
17
+      request({
18
+        ...apis.getUserPhone,
19
+        data: {
20
+          sessionKey: Taro.getStorageSync('sessionKey'),
21
+          encryptedData: data.encryptedData,
22
+          iv: data.iv
23
+        }
24
+      }).then((res) => {
25
+        setUser({ ...user, phone: res.phoneNumber })
26
+
27
+        if (props.onOk) {
28
+          props.onOk(res)
29
+        }
30
+      }).catch((er) => {
31
+        setShowPannel(true)
32
+        if (props.onError) {
33
+          props.onError(er.message || er.errMsg || er)
34
+        }
35
+      })
36
+    } else {
37
+      setShowPannel(true)
38
+      if (props.onError) {
39
+        props.onError(errMsg)
24 40
       }
25
-    }).then((res) => {
26
-      setUser({ ...user, phone: res.phoneNumber })
27
-      Taro.showToast({ title: '手机授权成功', icon: 'none' })
28
-    }).catch(() => {
29
-      Taro.showToast({ title: '手机授权失败', icon: 'none' })
30
-    })
41
+    }
31 42
   }
32 43
 
33
-  return (
34
-    <view className='GetUserPhone' style={{display: Show ? 'block' : 'none'}}>
35
-      <view className='centerLabel'>
36
-        <text>您暂未授权手机号</text>
37
-        <view className='flex-h'>
38
-          <text className='flex-item' onClick={Close}>取消</text>
39
-          <Button className='flex-item' open-type='getPhoneNumber' lang='zh_CN' onGetphonenumber={ToGetUserPhone}>去授权</Button>
40
-        </view>
41
-      </view>
44
+  const handleCancel = () => {
45
+    if (props.onCancel) {
46
+      props.onCancel()
47
+    }
48
+  }
49
+
50
+  return props.visible && (
51
+    <view className='GetUserPhone'>
52
+      {
53
+        showPannel && (
54
+          <view className='centerLabel'>
55
+            <text>您暂未授权手机号</text>
56
+            <view className='flex-h'>
57
+              <text className='flex-item' onClick={handleCancel}>取消</text>
58
+              <Button
59
+                className='flex-item'
60
+                open-type='getPhoneNumber'
61
+                lang='zh_CN'
62
+                onGetphonenumber={ToGetUserPhone}
63
+                onTap={() => setShowPannel(false)}
64
+              >去授权</Button>
65
+            </view>
66
+          </view>
67
+        )
68
+      }
42 69
     </view>
43 70
   )
44 71
 }

+ 73
- 2
src/layouts/index.jsx View File

@@ -1,17 +1,88 @@
1
-import React from 'react'
1
+import React, { useState, useEffect } from 'react'
2
+import Taro from '@tarojs/taro'
2 3
 import { useModel } from '@/store'
3 4
 import Spin from '@/components/Spin'
5
+import GetUserPhone from '@/components/GetUserPhone/index'
6
+import GetUserIcon from '@/components/GetUserIcon/index'
4 7
 import useMountTrack from '@/utils/hooks/useMountTrack'
8
+import { getPage } from '@/utils'
9
+
10
+const pages = require('../pages')
11
+
12
+const showError = err => {
13
+  Taro.showModal({
14
+    title: '错误',
15
+    content: err,
16
+    showCancel: false
17
+  })
18
+}
5 19
 
6 20
 export default function(props) {
21
+  const [showAuthBasic, setShowAuthBasic] = useState(false)
22
+  const [showAuthYeZhu, setShowAuthYeZhu] = useState(false)
23
+  const [showAuthPhone, setShowAuthPhone] = useState(false)
7 24
   const { user } = useModel('user')
8 25
 
9 26
   const loading = !user || !user.personId
27
+  const isAuthedBasic = user && user.avatarurl && user.nickname
28
+  const isAuthedPhone = user && user.phone
29
+  const isAuthedYeZhu = user
30
+
31
+  const page = getPage()
32
+  const needAuthBasic = (page.auth || []).indexOf('avatar') > -1
33
+  const needAuthYeZhu = (page.auth || []).indexOf('yezhu') > -1
34
+  const needAuthPhone = (page.auth || []).indexOf('phone') > -1
10 35
   
11 36
   // 埋点
12 37
   useMountTrack()
13 38
 
39
+  // 授权手机
40
+  useEffect(() => {
41
+    if (!isAuthedPhone && needAuthPhone) {
42
+      setShowAuthPhone(true)
43
+    } else {
44
+      setShowAuthPhone(false)
45
+    }
46
+  }, [isAuthedPhone, needAuthPhone])
47
+
48
+  // 认证业主
49
+  useEffect(() => {
50
+    // 如果当前是认证业务页面
51
+    if (page.isYeZhuRenZheng) {
52
+      return
53
+    }
54
+
55
+    if (isAuthedPhone && !isAuthedYeZhu) {
56
+      const renZhengPage = pages.filter(x => x.isYeZhuRenZheng)[0]
57
+      if (renZhengPage) {
58
+        // 跳转到业主认证页面
59
+        // to = renZhengPage.page
60
+      }
61
+    }
62
+  }, [needAuthYeZhu, isAuthedPhone, page])
63
+
64
+  // 授权头像
65
+  useEffect(() => {
66
+    let needShow = false
67
+
68
+    // 授权手机之后才授权头像
69
+    if (isAuthedPhone) {
70
+      // 要求业主认证的
71
+      if (isAuthedYeZhu || !needAuthYeZhu) {
72
+        if (!isAuthedBasic && needAuthBasic) {
73
+          needShow = true
74
+        }
75
+      }
76
+    }
77
+
78
+    setShowAuthBasic(needShow)
79
+  }, [isAuthedBasic, needAuthBasic, isAuthedPhone, isAuthedYeZhu, needAuthYeZhu])
80
+
14 81
   return (
15
-    <Spin loading={loading}>{ props.children }</Spin>
82
+    <Spin loading={loading}>
83
+      <GetUserIcon visible={showAuthBasic} onError={err => showError(`授权头像失败: ${err}`)} />
84
+      <GetUserPhone visible={showAuthPhone} onError={err => showError(`授权手机失败: ${err}`)} />
85
+      { props.children }
86
+    </Spin>
16 87
   )
17 88
 }

+ 30
- 1
src/pages.js View File

@@ -3,6 +3,7 @@ const Main = [
3 3
   {
4 4
     name: '首页',
5 5
     page: 'pages/ShouYe/index',
6
+    auth: [],
6 7
     track: {
7 8
       event: 'index',
8 9
       eventType: 'main',
@@ -11,6 +12,7 @@ const Main = [
11 12
   {
12 13
     name: '首页-活动',
13 14
     page: 'pages/ShouYe/HuoDong/index',
15
+    auth: ['avatar'],
14 16
     track: {
15 17
       event: 'list',
16 18
       eventType: 'activity',
@@ -19,6 +21,7 @@ const Main = [
19 21
   {
20 22
     name: '首页-资讯',
21 23
     page: 'pages/ShouYe/ZiXun/index',
24
+    auth: ['avatar'],
22 25
     track: {
23 26
       event: 'list',
24 27
       eventType: 'news',
@@ -30,6 +33,7 @@ const Property = [
30 33
   {
31 34
     name: '物业',
32 35
     page: 'pages/WuYe/index',
36
+    auth: ['avatar', 'phone', 'yezhu'],
33 37
     track: {
34 38
       event: 'list',
35 39
       eventType: 'property',
@@ -38,6 +42,7 @@ const Property = [
38 42
   {
39 43
     name: '物业-服务详情',
40 44
     page: 'pages/WuYe/FuWuDetail/index',
45
+    auth: ['avatar', 'phone', 'yezhu'],
41 46
     track: {
42 47
       event: 'detail',
43 48
       eventType: 'property',
@@ -46,6 +51,7 @@ const Property = [
46 51
   {
47 52
     name: '物业-公告详情',
48 53
     page: 'pages/WuYe/GongGaoDetail/index',
54
+    auth: ['avatar', 'phone', 'yezhu'],
49 55
     track: {
50 56
       event: 'detail',
51 57
       eventType: 'property',
@@ -54,11 +60,13 @@ const Property = [
54 60
   {
55 61
     name: '物业-报修区域',
56 62
     page: 'pages/WuYe/BaoXiuQuYu/index',
63
+    auth: ['avatar', 'phone', 'yezhu'],
57 64
     type: 'property',
58 65
   },
59 66
   {
60 67
     name: '物业-添加报修',
61 68
     page: 'pages/WuYe/TianJiaBaoXiu/index',
69
+    auth: ['avatar', 'phone', 'yezhu'],
62 70
     track: {
63 71
       event: 'detail',
64 72
       eventType: 'property',
@@ -67,6 +75,7 @@ const Property = [
67 75
   {
68 76
     name: '物业-报修详情',
69 77
     page: 'pages/WuYe/BaoXiuDetail/index',
78
+    auth: ['avatar', 'phone', 'yezhu'],
70 79
     track: {
71 80
       event: 'detail',
72 81
       eventType: 'property',
@@ -75,6 +84,7 @@ const Property = [
75 84
   {
76 85
     name: '物业-编辑报修',
77 86
     page: 'pages/WuYe/XiuGaiBaoXiu/index',
87
+    auth: ['avatar', 'phone', 'yezhu'],
78 88
     track: {
79 89
       event: 'detail',
80 90
       eventType: 'property',
@@ -83,6 +93,7 @@ const Property = [
83 93
   {
84 94
     name: '物业-报修费用',
85 95
     page: 'pages/WuYe/BaoXiuFeiYong/index',
96
+    auth: ['avatar', 'phone', 'yezhu'],
86 97
     track: {
87 98
       event: 'detail',
88 99
       eventType: 'property',
@@ -91,6 +102,7 @@ const Property = [
91 102
   {
92 103
     name: '物业-缴费详情',
93 104
     page: 'pages/WuYe/JiaoFeiDetail/index',
105
+    auth: ['avatar', 'phone', 'yezhu'],
94 106
     track: {
95 107
       event: 'detail',
96 108
       eventType: 'property',
@@ -102,6 +114,7 @@ const Activity = [
102 114
   {
103 115
     name: '活动',
104 116
     page: 'pages/HuoDong/index',
117
+    auth: ['avatar'],
105 118
     track: {
106 119
       event: 'list',
107 120
       eventType: 'activity',
@@ -110,6 +123,7 @@ const Activity = [
110 123
   {
111 124
     name: '活动-活动详情',
112 125
     page: 'pages/HuoDong/HuoDongDetail/index',
126
+    auth: ['avatar', 'phone'],
113 127
     track: {
114 128
       event: 'detail',
115 129
       eventType: 'activity',
@@ -118,6 +132,7 @@ const Activity = [
118 132
   {
119 133
     name: '活动-资讯详情',
120 134
     page: 'pages/HuoDong/ZiXunDetail/index',
135
+    auth: ['avatar', 'phone'],
121 136
     track: {
122 137
       event: 'detail',
123 138
       eventType: 'news',
@@ -129,6 +144,7 @@ const Shop = [
129 144
   {
130 145
     name: '福利',
131 146
     page: 'pages/FuLi/index',
147
+    auth: ['avatar', 'phone'],
132 148
     track: {
133 149
       event: 'list',
134 150
       eventType: 'shop',
@@ -137,6 +153,7 @@ const Shop = [
137 153
   {
138 154
     name: '福利-商品详情',
139 155
     page: 'pages/FuLi/ShangPinXiangQing/index',
156
+    auth: ['avatar', 'phone'],
140 157
     track: {
141 158
       event: 'detail',
142 159
       eventType: 'shop',
@@ -145,6 +162,7 @@ const Shop = [
145 162
   {
146 163
     name: '福利-商品兑换',
147 164
     page: 'pages/FuLi/ShangPinDuiHuan/index',
165
+    auth: ['avatar', 'phone'],
148 166
     track: {
149 167
       event: 'exchange',
150 168
       eventType: 'shop',
@@ -153,6 +171,7 @@ const Shop = [
153 171
   {
154 172
     name: '福利-积分规则',
155 173
     page: 'pages/FuLi/JiFenGuiZe/index',
174
+    auth: ['avatar', 'phone'],
156 175
     track: {
157 176
       event: 'points_rule',
158 177
       eventType: 'shop',
@@ -161,6 +180,7 @@ const Shop = [
161 180
   {
162 181
     name: '福利-积分明细',
163 182
     page: 'pages/FuLi/JiFenMingXi/index',
183
+    auth: ['avatar', 'phone'],
164 184
     track: {
165 185
       event: 'points_details',
166 186
       eventType: 'shop',
@@ -172,6 +192,7 @@ const Other = [
172 192
   {
173 193
     name: '我的',
174 194
     page: 'pages/WoDe/index',
195
+    auth: ['avatar', 'phone'],
175 196
     track: {
176 197
       event: 'list',
177 198
       eventType: 'other',
@@ -180,6 +201,7 @@ const Other = [
180 201
   {
181 202
     name: '我的-个人信息',
182 203
     page: 'pages/WoDe/GeRenXinXi/index',
204
+    auth: ['avatar', 'phone'],
183 205
     track: {
184 206
       event: 'detail',
185 207
       eventType: 'other',
@@ -188,19 +210,23 @@ const Other = [
188 210
   {
189 211
     name: '我的-我的认证',
190 212
     page: 'pages/WoDe/WoDeRenZheng/index',
213
+    auth: ['avatar', 'phone', 'yezhu'],
191 214
     type: 'other',
192 215
   },
193 216
   {
194 217
     name: '我的-业主认证',
195 218
     page: 'pages/WoDe/YeZhuRenZheng/index',
219
+    auth: ['avatar', 'phone', 'yezhu'],
196 220
     track: {
197 221
       event: 'detail',
198 222
       eventType: 'property',
199
-    }
223
+    },
224
+    isYeZhuRenZheng: true,
200 225
   },
201 226
   {
202 227
     name: '我的-业主审核',
203 228
     page: 'pages/WoDe/YeZhuShenHe/index',
229
+    auth: ['avatar', 'phone', 'yezhu'],
204 230
     track: {
205 231
       event: 'detail',
206 232
       eventType: 'property',
@@ -209,6 +235,7 @@ const Other = [
209 235
   {
210 236
     name: '我的-我的活动',
211 237
     page: 'pages/WoDe/WoDeHuoDong/index',
238
+    auth: ['avatar', 'phone'],
212 239
     track: {
213 240
       event: 'list',
214 241
       eventType: 'activity',
@@ -217,6 +244,7 @@ const Other = [
217 244
   {
218 245
     name: '我的-推荐二维码',
219 246
     page: 'pages/WoDe/TuiJianErWeiMa/index',
247
+    auth: ['avatar', 'phone'],
220 248
     track: {
221 249
       event: 'detail',
222 250
       eventType: 'other',
@@ -225,6 +253,7 @@ const Other = [
225 253
   {
226 254
     name: '我的-推荐分享',
227 255
     page: 'pages/WoDe/TuiJianFenXiang/index',
256
+    auth: ['avatar', 'phone'],
228 257
     track: {
229 258
       event: 'detail',
230 259
       eventType: 'other',

+ 0
- 10
src/pages/ShouYe/index.jsx View File

@@ -1,7 +1,5 @@
1 1
 import React, { useState, useEffect } from 'react'
2 2
 import NavHeader from '@/components/NavHeader/index'
3
-import GetUserPhone from '@/components/GetUserPhone/index'
4
-import GetUserIcon from '@/components/GetUserIcon/index'
5 3
 import { Swiper, SwiperItem, Text } from '@tarojs/components'
6 4
 import request, { apis } from '@/utils/request'
7 5
 import { useModel } from '@/store'
@@ -15,8 +13,6 @@ import './index.less'
15 13
 export default function Index (props) {
16 14
 
17 15
   const { user } = useModel('user')
18
-  const [ShowGetUserPhoneLayer, setShowGetUserPhoneLayer] = useState(false)
19
-  const [ShowGetUserIconLayer, setShowGetUserIconLayer] = useState(false)
20 16
   const [ShowAdvLayer, setShowAdvLayer] = useState(false)
21 17
   const [IsPull, setIsPull] = useState(false)
22 18
   const [OwnerList] = useState([
@@ -266,12 +262,6 @@ export default function Index (props) {
266 262
           </view>
267 263
 
268 264
         </view>
269
-
270
-        {/* 获取用户手机号授权 */}
271
-        <GetUserPhone Show={ShowGetUserPhoneLayer} Close={() => { setShowGetUserPhoneLayer(false) }}></GetUserPhone>
272
-
273
-        {/* 获取用户头像 */}
274
-        <GetUserIcon Show={ShowGetUserIconLayer} Close={() => { setShowGetUserIconLayer(false) }}></GetUserIcon>
275 265
       </view >
276 266
     </Page>
277 267
   )

+ 7
- 1
src/utils/api.js View File

@@ -140,7 +140,13 @@ const $api = {
140 140
   setShare: { // 分享
141 141
     method: 'put',
142 142
     url: `${prefix}/:type/share/:id`
143
-  }
143
+  },
144
+
145
+  // 授权头像等基本信息
146
+  userAutInfo: {
147
+    method: 'post',
148
+    url: `${prefix}/signup`
149
+  },
144 150
 
145 151
 }
146 152
 

+ 2
- 3
src/utils/hooks/useMountTrack.js View File

@@ -1,10 +1,9 @@
1 1
 import React, { useEffect, useRef } from 'react'
2 2
 import { getCurrentInstance } from '@tarojs/taro'
3 3
 import { useModel } from '@/store'
4
+import { getPage } from '@/utils'
4 5
 import request, { apis } from '../request'
5 6
 
6
-const pages = require('../../pages')
7
-
8 7
 /**
9 8
  * 页面埋点
10 9
  * params 一般不需要传值,
@@ -22,7 +21,7 @@ export default function useMountTrack(params) {
22 21
     }
23 22
 
24 23
     const router = getCurrentInstance().router
25
-    const page = pages.filter(x => router.path.indexOf(x.page) > -1)[0]
24
+    const page = getPage()
26 25
     if (!page) {
27 26
       return
28 27
     }

+ 9
- 0
src/utils/index.js View File

@@ -1,3 +1,12 @@
1
+import { getCurrentInstance } from '@tarojs/taro'
2
+
3
+const pages = require('../pages')
1 4
 
2 5
 // 深度拷贝
3 6
 export const deepCopy = x => JSON.parse(JSON.stringify(X))
7
+
8
+// 获取当前页面配置
9
+export const getPage = () => {
10
+  const router = getCurrentInstance().router
11
+  return pages.filter(x => router.path.indexOf(x.page) > -1)[0]
12
+}

+ 2
- 3
src/utils/track.js View File

@@ -1,6 +1,5 @@
1 1
 import request, { apis } from './request'
2
-
3
-const pages = require('../pages')
2
+import { getPage } from '.'
4 3
 
5 4
 /**
6 5
  * 用户来源
@@ -10,7 +9,7 @@ const pages = require('../pages')
10 9
 export async function trackUserSource(router, qrcode) {
11 10
   const { path, scene, params } = router || {}
12 11
 
13
-  const page = pages.filter(x => path.indexOf(x.page) > -1)[0] || {}
12
+  const page = getPage()
14 13
 
15 14
   const trackPayload = {
16 15
     ...(page.track || {}),