张延森 4 年前
父节点
当前提交
f3c1278b45

+ 1
- 1
config/dev.js 查看文件

3
     NODE_ENV: '"development"'
3
     NODE_ENV: '"development"'
4
   },
4
   },
5
   defineConstants: {
5
   defineConstants: {
6
-    HOST: 'https://a.t.njyunzhi.com'
6
+    HOST: '"https://a.t.njyunzhi.com"'
7
   },
7
   },
8
   mini: {
8
   mini: {
9
     debugReact: true
9
     debugReact: true

+ 1
- 0
config/prod.js 查看文件

3
     NODE_ENV: '"production"'
3
     NODE_ENV: '"production"'
4
   },
4
   },
5
   defineConstants: {
5
   defineConstants: {
6
+    HOST: '"https://a.t.njyunzhi.com"'
6
   },
7
   },
7
   mini: {},
8
   mini: {},
8
   h5: {
9
   h5: {

+ 3
- 32
src/app.config.js 查看文件

1
-export default {
2
-  pages: [
3
-    'pages/ShouYe/index', // tab-首页
4
-    'pages/ShouYe/HuoDong/index', // 首页-活动
5
-    'pages/ShouYe/ZiXun/index', // 首页-资讯
6
-
7
-    'pages/WuYe/index', // tab-物业
8
-    'pages/WuYe/FuWuDetail/index', // 物业-服务详情
9
-    'pages/WuYe/GongGaoDetail/index', // 物业-公告详情
10
-    'pages/WuYe/BaoXiuQuYu/index', // 物业-报修区域
11
-    'pages/WuYe/TianJiaBaoXiu/index', // 物业-添加报修
12
-    'pages/WuYe/BaoXiuDetail/index', // 物业-报修详情
13
-    'pages/WuYe/BaoXiuFeiYong/index', // 物业-报修费用
14
-    'pages/WuYe/JiaoFeiDetail/index', // 物业-缴费详情
15
-
16
-    'pages/HuoDong/index', // tab-活动
17
-    'pages/HuoDong/HuoDongDetail/index', // 活动-活动详情
18
-    'pages/HuoDong/ZiXunDetail/index', // 活动-资讯详情
1
+const pages = require('./pages')
19
 
2
 
20
-    'pages/FuLi/index', // tab-福利
21
-    'pages/FuLi/ShangPinXiangQing/index', // 福利-商品详情
22
-    'pages/FuLi/ShangPinDuiHuan/index', // 福利-商品兑换
23
-    'pages/FuLi/JiFenGuiZe/index', // 福利-积分规则
24
-    'pages/FuLi/JiFenMingXi/index', // 福利-积分明细
25
-
26
-    'pages/WoDe/index', // tab-我的
27
-    'pages/WoDe/GeRenXinXi/index', // 我的-个人信息
28
-    'pages/WoDe/YeZhuRenZheng/index', // 我的-业主认证
29
-    'pages/WoDe/YeZhuShenHe/index', // 我的-业主审核
30
-    'pages/WoDe/WoDeHuoDong/index', // 我的-我的活动
31
-    'pages/WoDe/TuiJianErWeiMa/index', // 我的-推荐二维码
32
-    'pages/WoDe/TuiJianFenXiang/index', // 我的-推荐分享
33
-  ],
3
+export default {
4
+  pages: pages.map(x => x.page),
34
   tabBar: {
5
   tabBar: {
35
     color: '#666666',
6
     color: '#666666',
36
     selectedColor: '#971C21',
7
     selectedColor: '#971C21',

+ 39
- 4
src/app.js 查看文件

1
 import React, { Component } from 'react'
1
 import React, { Component } from 'react'
2
-import Taro from '@tarojs/taro'
2
+import Taro, { getCurrentInstance } from '@tarojs/taro'
3
 import { StoreRoot, store } from './store'
3
 import { StoreRoot, store } from './store'
4
+import { deepCopy } from './utils'
5
+import request, { apis } from './utils/request'
6
+import { trackUserSource } from './utils/track'
4
 import './app.less'
7
 import './app.less'
5
 
8
 
6
 class App extends Component {
9
 class App extends Component {
10
+  updateTracing;
7
 
11
 
8
   onLaunch (options) {
12
   onLaunch (options) {
9
     // 此处获取不到 state, 因为 app 不会刷新
13
     // 此处获取不到 state, 因为 app 不会刷新
10
-    const { setUser } = store.getModel('user').getState()
11
     const { setSysInfo } = store.getModel('sys').getState()
14
     const { setSysInfo } = store.getModel('sys').getState()
12
-
15
+    
13
     // 预拉取数据
16
     // 预拉取数据
14
     wx.getBackgroundFetchData({
17
     wx.getBackgroundFetchData({
15
       fetchType: 'pre',
18
       fetchType: 'pre',
22
         }
25
         }
23
       }
26
       }
24
     })
27
     })
28
+  }
29
+
30
+  // 在此处是为了兼容热启动
31
+  componentDidShow() {
32
+    const { setUser } = store.getModel('user').getState()
33
+
34
+    // 保存刚进入系统时的router
35
+    const router = getCurrentInstance().router
36
+
37
+    // 如果是分享或者扫码
38
+    // scene 与其它参数时互斥的. 有 scene 说明时扫码进来的
39
+    const { from, recommender, scene } = router.params
25
 
40
 
26
     // 登录
41
     // 登录
27
     Taro.login({
42
     Taro.login({
28
       success: res => {
43
       success: res => {
29
         if (res.errMsg === 'login:ok') {
44
         if (res.errMsg === 'login:ok') {
30
-          // res.code
45
+          request({ ...apis.login, params: { code: res.code, from, recommender, scene } }).then(x => {
46
+            setUser(x.person)
47
+            Taro.setStorage({ key: 'token', data: x.token })
48
+
49
+            // 埋点
50
+            if (recommender || x.scene) {
51
+              updateTracing = trackUserSource(router, x.scene)
52
+            }
53
+          })
31
         }
54
         }
32
       }
55
       }
33
     })
56
     })
34
   }
57
   }
35
 
58
 
59
+  componentDidHide() {
60
+    if (this.updateTracing) {
61
+      this.updateTracing()
62
+    }
63
+  }
64
+
65
+  componentWillUnmount() {
66
+    if (this.updateTracing) {
67
+      this.updateTracing()
68
+    }
69
+  }
70
+
36
   // this.props.children 是将要会渲染的页面
71
   // this.props.children 是将要会渲染的页面
37
   render () {
72
   render () {
38
     return (
73
     return (

+ 65
- 0
src/pages.js 查看文件

1
+
2
+module.exports = [
3
+  {
4
+    name: '首页',
5
+    page: 'pages/ShouYe/index',
6
+    type: 'main',
7
+  },
8
+
9
+  {
10
+    name: '物业',
11
+    page: 'pages/WuYe/index',
12
+    type: 'property',
13
+  },
14
+
15
+  {
16
+    name: '活动',
17
+    page: 'pages/HuoDong/index',
18
+    type: 'activity',
19
+  },
20
+
21
+  {
22
+    name: '福利',
23
+    page: 'pages/FuLi/index',
24
+    type: 'shop',
25
+  },
26
+
27
+  {
28
+    name: '我的',
29
+    page: 'pages/WoDe/index',
30
+    type: 'other',
31
+  }
32
+  
33
+  // [
34
+  //   'pages/ShouYe/index', // tab-首页
35
+  //   'pages/ShouYe/HuoDong/index', // 首页-活动
36
+  //   'pages/ShouYe/ZiXun/index', // 首页-资讯
37
+
38
+  //   'pages/WuYe/index', // tab-物业
39
+  //   'pages/WuYe/FuWuDetail/index', // 物业-服务详情
40
+  //   'pages/WuYe/GongGaoDetail/index', // 物业-公告详情
41
+  //   'pages/WuYe/BaoXiuQuYu/index', // 物业-报修区域
42
+  //   'pages/WuYe/TianJiaBaoXiu/index', // 物业-添加报修
43
+  //   'pages/WuYe/BaoXiuDetail/index', // 物业-报修详情
44
+  //   'pages/WuYe/BaoXiuFeiYong/index', // 物业-报修费用
45
+  //   'pages/WuYe/JiaoFeiDetail/index', // 物业-缴费详情
46
+
47
+  //   'pages/HuoDong/index', // tab-活动
48
+  //   'pages/HuoDong/HuoDongDetail/index', // 活动-活动详情
49
+  //   'pages/HuoDong/ZiXunDetail/index', // 活动-资讯详情
50
+
51
+  //   'pages/FuLi/index', // tab-福利
52
+  //   'pages/FuLi/ShangPinXiangQing/index', // 福利-商品详情
53
+  //   'pages/FuLi/ShangPinDuiHuan/index', // 福利-商品兑换
54
+  //   'pages/FuLi/JiFenGuiZe/index', // 福利-积分规则
55
+  //   'pages/FuLi/JiFenMingXi/index', // 福利-积分明细
56
+
57
+  //   'pages/WoDe/index', // tab-我的
58
+  //   'pages/WoDe/GeRenXinXi/index', // 我的-个人信息
59
+  //   'pages/WoDe/YeZhuRenZheng/index', // 我的-业主认证
60
+  //   'pages/WoDe/YeZhuShenHe/index', // 我的-业主审核
61
+  //   'pages/WoDe/WoDeHuoDong/index', // 我的-我的活动
62
+  //   'pages/WoDe/TuiJianErWeiMa/index', // 我的-推荐二维码
63
+  //   'pages/WoDe/TuiJianFenXiang/index', // 我的-推荐分享
64
+  // ],
65
+]

+ 2
- 0
src/store/models/index.js 查看文件

1
 import useSystem from './useSystem'
1
 import useSystem from './useSystem'
2
+import useAppRouter from './useAppRouter'
2
 import useUser from './useUser'
3
 import useUser from './useUser'
3
 
4
 
4
 const models = {
5
 const models = {
6
+  'appRouter': useAppRouter,
5
   'sys': useSystem,
7
   'sys': useSystem,
6
   'user': useUser,
8
   'user': useUser,
7
 }
9
 }

+ 12
- 0
src/store/models/useAppRouter.js 查看文件

1
+import React, { useEffect, useState } from 'react'
2
+import Taro from '@tarojs/taro'
3
+
4
+// 保存系统进入时的参数
5
+export default function useAppRouter() {
6
+  const [router, setRouter] = useState()
7
+
8
+  return {
9
+    router,
10
+    setRouter
11
+  }
12
+}

+ 2
- 1
src/store/models/useSystem.js 查看文件

1
 import React, { useEffect, useState } from 'react'
1
 import React, { useEffect, useState } from 'react'
2
 import Taro from '@tarojs/taro'
2
 import Taro from '@tarojs/taro'
3
 
3
 
4
-export default function useBar() {
4
+// 保存系统相关参数
5
+export default function useSystem() {
5
   const [sysInfo, setSysInfo] = useState()
6
   const [sysInfo, setSysInfo] = useState()
6
 
7
 
7
   // const updateSysInfo = data => {
8
   // const updateSysInfo = data => {

+ 1
- 1
src/store/models/useUser.js 查看文件

1
 import React, { useEffect, useState } from 'react'
1
 import React, { useEffect, useState } from 'react'
2
 import Taro from '@tarojs/taro'
2
 import Taro from '@tarojs/taro'
3
 
3
 
4
-export default function useBar() {
4
+export default function useUser() {
5
   const [user, setUser] = useState({})
5
   const [user, setUser] = useState({})
6
 
6
 
7
   // const updateUser = data => {
7
   // const updateUser = data => {

+ 24
- 4
src/utils/api.js 查看文件

1
-const prefix = process.env.NODE_ENV === 'production' ? '' : '/api'
1
+const host = HOST
2
+const prefix = `${host}/api/wx`
2
 
3
 
3
 const $api = {
4
 const $api = {
4
-  Demo: {
5
-    method: 'get',
6
-    url: `${prefix}/wx`
5
+  login: {
6
+    method: 'post',
7
+    url: `${prefix}/login`
8
+  },
9
+
10
+  saveShareFrom: {
11
+    method: 'post',
12
+    url: `${prefix}/share-person`
13
+  },
14
+
15
+  // 埋点
16
+  saveTracking: {
17
+    method: 'post',
18
+    url: `${prefix}/taPersonVisitRecord`
19
+  },
20
+
21
+  // 更新埋点
22
+  updateTracking: {
23
+    method: 'put',
24
+    url: `${prefix}/taPersonVisitRecord/:id`
7
   }
25
   }
26
+
8
 }
27
 }
9
 
28
 
29
+
10
 export default $api
30
 export default $api

+ 3
- 0
src/utils/index.js 查看文件

1
+
2
+// 深度拷贝
3
+export const deepCopy = x => JSON.parse(JSON.stringify(X))

+ 46
- 17
src/utils/request.js 查看文件

1
 import Taro from '@tarojs/taro'
1
 import Taro from '@tarojs/taro'
2
+import log from './rtLog'
3
+import $api from './api'
2
 
4
 
3
 const accountInfo = Taro.getAccountInfoSync()
5
 const accountInfo = Taro.getAccountInfoSync()
4
 const appId = accountInfo.miniProgram.appId
6
 const appId = accountInfo.miniProgram.appId
7
   return Object.entries(query || {}).map(pair => `${encodeURIComponent(pair[0])}=${encodeURIComponent(pair[1])}`).join('&')
9
   return Object.entries(query || {}).map(pair => `${encodeURIComponent(pair[0])}=${encodeURIComponent(pair[1])}`).join('&')
8
 }
10
 }
9
 
11
 
12
+const transPathArgs = (path, args) => {
13
+  return path.split('/').map(part => {
14
+    return part && part.indexOf(':') === 0 ? args[part.substring(1)] : part
15
+  }).join('/')
16
+}
17
+
18
+/**
19
+ * 发起请求
20
+ * 
21
+ * @param {*} options 
22
+ */
10
 const request = options => {
23
 const request = options => {
11
-  const { url, params, header, ...leftOpts } = options || {}
24
+  // args     path 参数
25
+  // params   query 参数
26
+  // data     body 参数
27
+  const { args, params, silent, url, header, ...leftOpts } = options || {}
12
 
28
 
13
   let realURL = url
29
   let realURL = url
14
-  if (!params) {
30
+  if (args) {
31
+    realURL = transPathArgs(url, args)
32
+  }
33
+
34
+  if (params) {
15
     realURL += `?${query2String(params)}`
35
     realURL += `?${query2String(params)}`
16
   }
36
   }
17
 
37
 
34
       ...config,
54
       ...config,
35
       success: res => {
55
       success: res => {
36
         if (res.statusCode >= 300) {
56
         if (res.statusCode >= 300) {
37
-          const errMsg = `网络错误: ${res.statusCode}`
38
-          Taro.showToast({
39
-            title: errMsg,
40
-            icon: 'none',
41
-            duration: 3000
42
-          })
57
+          log.error(res, '==>', config)
58
+
59
+          if (!silent) {
60
+            const errMsg = `网络错误: ${res.statusCode}`
61
+            Taro.showToast({
62
+              title: errMsg,
63
+              icon: 'none',
64
+              duration: 3000
65
+            })
66
+          }
43
           return
67
           return
44
         }
68
         }
45
 
69
 
51
         }
75
         }
52
       },
76
       },
53
       fail: err => {
77
       fail: err => {
54
-        console.error(err)
78
+        log.error(err, '==>', config)
55
 
79
 
56
-        const message = err.errMsg || err.message || ''
57
-        const errMsg = message.indexOf('java') > -1 ? '服务内部错误' : `网络错误: ${message}`
58
-
59
-        Taro.showToast({
60
-          title: errMsg,
61
-          icon: 'none',
62
-          duration: 3000
63
-        })
80
+        if (!silent) {
81
+          const message = err.errMsg || err.message || ''
82
+          const errMsg = message.indexOf('java') > -1 ? '服务内部错误' : `网络错误: ${message}`
83
+  
84
+          Taro.showToast({
85
+            title: errMsg,
86
+            icon: 'none',
87
+            duration: 3000
88
+          })
89
+        }
64
 
90
 
65
         // reject(err)
91
         // reject(err)
66
       }
92
       }
71
 // request 不带 loading, 也不带错误处理
97
 // request 不带 loading, 也不带错误处理
72
 export default request
98
 export default request
73
 
99
 
100
+//
101
+export const apis = $api
102
+
74
 // 比 request 增加了 loading 以及 错误提示
103
 // 比 request 增加了 loading 以及 错误提示
75
 export function request2(options) {
104
 export function request2(options) {
76
   const { showOk, okMessage, showLoading, ...config } = options || {}
105
   const { showOk, okMessage, showLoading, ...config } = options || {}

+ 30
- 0
src/utils/rtLog.js 查看文件

1
+
2
+let logger = wx.getRealtimeLogManager ? wx.getRealtimeLogManager() : null;
3
+
4
+function info(...args) {
5
+  // 本地打印
6
+  console.info(...args)
7
+
8
+  // 远程提交
9
+  if (logger) {
10
+    logger.info(...args)
11
+  }
12
+}
13
+
14
+function error(...args) {
15
+  console.error(...args)
16
+
17
+  if (logger) {
18
+    logger.error(...args)
19
+  }
20
+}
21
+
22
+function warn(...args) {
23
+  console.warn(...args)
24
+
25
+  if (logger) {
26
+    logger.warn(...args)
27
+  }
28
+}
29
+
30
+export default { info, error, warn }

+ 40
- 0
src/utils/track.js 查看文件

1
+import request, { apis } from './request'
2
+
3
+const pages = require('../pages')
4
+
5
+/**
6
+ * 用户来源
7
+ * @param {*} router 
8
+ */
9
+// eslint-disable-next-line import/prefer-default-export
10
+export async function trackUserSource(router, qrcode) {
11
+  const { path, scene, params } = router || {}
12
+
13
+  const pageInfo = pages.filter(x => path.indexOf(x.page) > -1)[0] || { type: 'other', name: '其他' }
14
+
15
+  const trackPayload = {
16
+    event: 'start',
17
+    eventType: pageInfo.type,
18
+    propertyName: pageInfo.name,
19
+    data: '{}',
20
+    id: params.id,
21
+    buildingId: undefined,
22
+    realScene: scene,
23
+    sceneId: params.scene,
24
+    sharePersonId: (qrcode || {}).recommender || params.recommender,
25
+  }
26
+
27
+  try {
28
+    const sceneList = [1005, 1006, 1053, 1042, 1007, 1008, 1011, 1012, 1013, 1045, 1046, 1047, 1048, 1058, 1067, 1000]
29
+
30
+    if (sceneList.indexOf(trackPayload.sceneId) === -1) {
31
+      trackPayload.sceneId = 1000
32
+    }
33
+    const { recordId } = await request({ ...apis.saveTracking, silent: true, data: trackPayload })
34
+
35
+    return () => request({ ...apis.updateTracking, silent: true, args: { id: recordId } })
36
+  } catch (e) {
37
+    console.error('进入小程序埋点出错:', e);
38
+    return function () { }
39
+  }
40
+}