张延森 před 3 roky
rodič
revize
b391f5203e

+ 7
- 0
src/app.jsx Zobrazit soubor

@@ -37,6 +37,13 @@ class App extends Component {
37 37
   onLaunch (options) {
38 38
     // 加载远程字体
39 39
     this.loadFontFace()
40
+
41
+    // 当前设备相关
42
+    Taro.getSystemInfo({
43
+      success: (data) => {
44
+        Taro.setStorage({ key: 'systemInfo', data })
45
+      }
46
+    })
40 47
   
41 48
     getLocation().then((loc) => {
42 49
       getRouterParams(options).then(router => {

+ 12
- 0
src/components/Auth/AuthRole.jsx Zobrazit soubor

@@ -0,0 +1,12 @@
1
+import React from 'react'
2
+import { useSelector } from 'react-redux'
3
+
4
+export default (props) => {
5
+  const { role } = props
6
+
7
+  const { person } = useSelector(s => s.user.userInfo)
8
+  const { personType } = person || {}
9
+  const isSame = personType === role
10
+
11
+  return isSame ? props.children : null
12
+}

+ 75
- 0
src/components/Poster/index.jsx Zobrazit soubor

@@ -0,0 +1,75 @@
1
+import React, { useEffect, useState } from 'react'
2
+import Taro from '@tarojs/taro'
3
+import { Canvas, View } from '@tarojs/components'
4
+import rtLog from '@/utils/rtLog'
5
+import { getConfig, getCanvas } from './sdk'
6
+
7
+export default (props) => {
8
+  const { poster, miniCode, name, desc = '长按识别在线看房', onStart, onEnd } = props
9
+
10
+  const [posterData, setPosterData] = useState()
11
+  const [codeData, setCodeData] = useState()
12
+  const [canvas, setCanvas] = useState()
13
+
14
+  useEffect(() => {
15
+    Taro.nextTick(() => {
16
+      getCanvas('#canvas-poster').then(setCanvas)
17
+    })
18
+  }, [])
19
+
20
+  useEffect(() => {
21
+    if (poster) {
22
+      Taro.downloadFile({
23
+        url: poster,
24
+        success: (res) => {
25
+          if (res.statusCode === 200) {
26
+            setPosterData(res.tempFilePath)
27
+          }
28
+        },
29
+        fail: (err) => {
30
+          rtLog.error(err)
31
+          Taro.showToast({
32
+            title: '下载海报图出错',
33
+            icon: 'none',
34
+          })
35
+        }
36
+      })
37
+    }
38
+  }, [poster])
39
+  
40
+  useEffect(() => {
41
+    if (miniCode) {
42
+      Taro.downloadFile({
43
+        url: miniCode,
44
+        success: (res) => {
45
+          if (res.statusCode === 200) {
46
+            setCodeData(res.tempFilePath)
47
+          }
48
+        },
49
+        fail: (err) => {
50
+          rtLog.error(err)
51
+          Taro.showToast({
52
+            title: '下载海报二维码出错',
53
+            icon: 'none',
54
+          })
55
+        }
56
+      })
57
+    }
58
+  }, [miniCode])
59
+
60
+  useEffect(() => {
61
+    if (canvas && posterData && codeData) {
62
+      onStart()
63
+      const config = getConfig()
64
+      const dpr = config.systemInfo.pixelRatio
65
+      const ctx = canvas.getContext('2d')
66
+      canvas.width = config.canvas.width
67
+      canvas.height = config.canvas.height
68
+      ctx.scale(dpr, dpr)
69
+
70
+      //
71
+    }
72
+  }, [canvas, posterData, codeData, onStart, onEnd])
73
+
74
+  return <View style={{width: 0, height: 0}}><Canvas type='2d' id='canvas-poster' /></View>
75
+}

+ 112
- 0
src/components/Poster/sdk.js Zobrazit soubor

@@ -0,0 +1,112 @@
1
+import Taro from '@tarojs/taro'
2
+
3
+/**
4
+ * 获取配置
5
+ * @returns 
6
+ */
7
+export function getConfig() {
8
+  // https://developers.weixin.qq.com/miniprogram/dev/api/base/system/wx.getSystemInfo.html
9
+  const systemInfo = Taro.getStorageSync('systemInfo')
10
+  const { windowWidth, pixelRatio } = systemInfo
11
+
12
+  // canvas
13
+  const canvas = {
14
+    width: windowWidth * pixelRatio,
15
+    // 设计稿宽高比 2.16  = height / width
16
+    height: windowWidth * pixelRatio * 2.16,
17
+  }
18
+
19
+  // 图片
20
+  const image = {
21
+    width: canvas.width,
22
+    height: canvas.width * 16 / 9, // 图片宽高 9 : 16
23
+    x: 0,
24
+    y: 0,
25
+  }
26
+
27
+  // 头像
28
+  const avatar = {
29
+    width: 88,
30
+    height: 88,
31
+    x: 30,
32
+    y: image.height + 50,
33
+  }
34
+
35
+  // 小程序码
36
+  const miniCode = {
37
+    width: 132,
38
+    height: 132,
39
+    x: canvas.width - 132 - 30,  // 128 是宽度, 30 是右边距
40
+    y: image.height + 50,
41
+  }
42
+
43
+  // 姓名
44
+  const name = {
45
+    // https://developer.mozilla.org/zh-CN/docs/Web/CSS/font
46
+    font: '28px',
47
+    // https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/fillStyle
48
+    fillStyle: '#333333',
49
+
50
+    // 60 是头像左边距 + 小程序码右边距
51
+    // 40 是文字距离头像的左边距 20 + 距离小程序码的右边距 20
52
+    maxWidth: canvas.width - 60 - avatar.width - miniCode.width - 40,
53
+
54
+    x: image.height + 66,
55
+    // 30 是头像左边距, 20 文字距离头像的左边距
56
+    y: 30 + avatar.width + 20,
57
+  }
58
+
59
+  // 说明
60
+  const desc = {
61
+    font: '20px',
62
+    fillStyle: '#666666',
63
+    maxWidth: name.maxWidth,
64
+    x: name.x,
65
+    y: image.height + 106,
66
+  }
67
+
68
+  return {
69
+    systemInfo,
70
+    canvas,
71
+    image,
72
+    miniCode,
73
+    name,
74
+    desc,
75
+  }
76
+}
77
+
78
+/**
79
+ * 绘制图像
80
+ * @param {*} ctx 
81
+ * @param {*} image 
82
+ * @param {*} config 
83
+ */
84
+export function drawImage(ctx, image, config) {
85
+  ctx.drawImage(image, config.x, config.y, config.width, config.height)
86
+}
87
+
88
+/**
89
+ * 绘制文字
90
+ * @param {*} ctx 
91
+ * @param {*} text 
92
+ * @param {*} config 
93
+ */
94
+export function darwText(ctx, text, config) {
95
+  ctx.setFillStyle(config.fillStyle)
96
+  ctx.font = config.font
97
+  ctx.fillText(text, config.x, config.y, config.maxWidth)
98
+}
99
+
100
+/**
101
+ * 获取 canvas
102
+ * @param {*} selector 
103
+ * @returns 
104
+ */
105
+export function getCanvas(selector) {
106
+  return new Promise((resolve) => {
107
+    const query = Taro.createSelectorQuery()
108
+    query.select(selector)
109
+      .node((res) => resolve(res.node))
110
+      .exec()
111
+  })
112
+}

+ 33
- 17
src/pages/index/buildingDetail/components/DetailBottom/index.jsx Zobrazit soubor

@@ -2,6 +2,9 @@ import React from 'react'
2 2
 import Taro from '@tarojs/taro'
3 3
 import { useSelector } from 'react-redux'
4 4
 import { Image } from '@tarojs/components'
5
+import AuthRole from '@/components/auth/AuthRole'
6
+import Poster from '@/components/Poster'
7
+import { ROLE_CODE } from '@/constants/user'
5 8
 import './index.scss'
6 9
 
7 10
 export default function DetailBottom (props) {
@@ -33,25 +36,38 @@ export default function DetailBottom (props) {
33 36
     }
34 37
   }
35 38
 
39
+  const handleRecommender = () => {
40
+    const params = `buildingId=${Info?.buildingId}&buildingName=${Info?.buildingName}`
41
+
42
+    Taro.navigateTo({
43
+      url: `/pages/mine/recommendUser/index?${params}`
44
+    })
45
+  }
46
+
36 47
   return (
37
-    <view className='components DetailBottom flex-h'>
38
-      <view className='Item'>
39
-        <Image mode='heightFix' src={require('@/assets/buildingDetail-icon3.png')}></Image>
40
-        <text>一键海报</text>
41
-      </view>
42
-      <view className='Item'>
43
-        <Image mode='heightFix' src={require('@/assets/buildingDetail-icon1.png')}></Image>
44
-        <text>一键带看</text>
45
-      </view>
46
-      <view className='Item'>
47
-        <Image mode='heightFix' src={require('@/assets/buildingDetail-icon2.png')}></Image>
48
-        <text>一键推荐</text>
49
-      </view>
50
-      <view className='flex-item'></view>
51
-      <view className='Btn'>
52
-        <text onClick={handleChat}>一键咨询</text>
53
-        <text className='active' onClick={handleCall}>一键电话</text>
48
+    <view>
49
+      <view className='components DetailBottom flex-h'>
50
+        <view className='Item'>
51
+          <Image mode='heightFix' src={require('@/assets/buildingDetail-icon3.png')}></Image>
52
+          <text>一键海报</text>
53
+        </view>
54
+        <view className='Item'>
55
+          <Image mode='heightFix' src={require('@/assets/buildingDetail-icon1.png')}></Image>
56
+          <text>一键带看</text>
57
+        </view>
58
+        <AuthRole role={ROLE_CODE.CONSULTANT}>
59
+          <view className='Item' onClick={handleRecommender}>
60
+            <Image mode='heightFix' src={require('@/assets/buildingDetail-icon2.png')}></Image>
61
+            <text>一键推荐</text>
62
+          </view>
63
+        </AuthRole>
64
+        <view className='flex-item'></view>
65
+        <view className='Btn'>
66
+          <text onClick={handleChat}>一键咨询</text>
67
+          <text className='active' onClick={handleCall}>一键电话</text>
68
+        </view>
54 69
       </view>
70
+      <Poster />
55 71
     </view>
56 72
   )
57 73
 }

+ 1
- 1
src/pages/index/buildingDetail/index.config.js Zobrazit soubor

@@ -1,3 +1,3 @@
1 1
 export default {
2
-  navigationBarTitleText: '楼盘详情'
2
+  navigationBarTitleText: '楼盘详情',
3 3
 }

+ 1
- 6
yarn.lock Zobrazit soubor

@@ -3284,16 +3284,11 @@ class-utils@^0.3.5:
3284 3284
     isobject "^3.0.0"
3285 3285
     static-extend "^0.1.1"
3286 3286
 
3287
-classnames@^2.2.5:
3287
+classnames@^2.2.5, classnames@^2.3.1:
3288 3288
   version "2.3.1"
3289 3289
   resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e"
3290 3290
   integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==
3291 3291
 
3292
-classnames@^2.3.1:
3293
-  version "2.3.1"
3294
-  resolved "https://registry.npm.taobao.org/classnames/download/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e"
3295
-  integrity sha1-38+jiR4wbsHa0QXQ6I9EF7hTXo4=
3296
-
3297 3292
 clean-css@4.2.x, clean-css@^4.2.1:
3298 3293
   version "4.2.3"
3299 3294
   resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78"