Browse Source

Merge branch 'dev' of http://git.ycjcjy.com/zhiyuxing/estateagents-admin-manager into dev

张延森 5 years ago
parent
commit
0ee82a22f7
36 changed files with 1545 additions and 140 deletions
  1. 1
    1
      config/routes.js
  2. 1
    1
      package.json
  3. 1
    1
      src/components/GlobalHeader/AvatarDropdown.jsx
  4. 45
    0
      src/components/SelectButton/WxDictSelect.jsx
  5. 1
    1
      src/pages/activity/SignList.jsx
  6. 23
    0
      src/pages/activity/drainage/DrainageList.jsx
  7. 32
    8
      src/pages/building/list/add/components/base.jsx
  8. 1
    1
      src/pages/building/list/add/components/buildingImage.jsx
  9. 26
    8
      src/pages/building/list/add/components/buildingProjectType.jsx
  10. 29
    0
      src/pages/building/list/add/components/imageSet.jsx
  11. 37
    18
      src/pages/building/list/add/components/modalImage.jsx
  12. 250
    0
      src/pages/building/list/add/components/modalPanoramaImage.jsx
  13. 182
    0
      src/pages/building/list/add/components/panoramaImage.jsx
  14. 3
    0
      src/pages/building/list/add/index.jsx
  15. 4
    3
      src/pages/building/list/index.jsx
  16. 1
    1
      src/pages/carouselFigure/editCarousel.jsx
  17. 158
    0
      src/pages/customer/customerlist/components/assistConsultant.jsx
  18. 10
    1
      src/pages/customer/customerlist/customerDetail.jsx
  19. 26
    0
      src/pages/customer/customerlist/index.jsx
  20. 10
    1
      src/pages/customer/customerlist/publicCustomerDetail.jsx
  21. 53
    5
      src/pages/customer/drift/index.jsx
  22. 11
    4
      src/pages/indexEcharts/components/IntentionalCustomers.jsx
  23. 289
    0
      src/pages/indexEcharts/components/UserBehaviorIndex.jsx
  24. 1
    7
      src/pages/indexEcharts/components/UserConversion.jsx
  25. 3
    0
      src/pages/indexEcharts/components/UserSex.jsx
  26. 20
    12
      src/pages/indexEcharts/components/UserSource.jsx
  27. 139
    0
      src/pages/indexEcharts/components/UserSourceDetail.jsx
  28. 9
    14
      src/pages/indexEcharts/components/UserSourcepie.jsx
  29. 2
    2
      src/pages/indexEcharts/index.jsx
  30. 55
    38
      src/pages/indexEcharts/userSource.jsx
  31. 58
    6
      src/pages/news/list/editNewsList.jsx
  32. 1
    1
      src/pages/record/drainage/DrainageVisitRecordList.jsx
  33. 8
    0
      src/pages/staff/list/editStaff.jsx
  34. 1
    1
      src/pages/style/GoodsList.less
  35. 49
    0
      src/services/apis.js
  36. 5
    5
      src/utils/request.js

+ 1
- 1
config/routes.js View File

296
               },
296
               },
297
               {
297
               {
298
                 path: '/activity/helpActivity/signList',
298
                 path: '/activity/helpActivity/signList',
299
-                name: '报名列表',
299
+                name: '助力记录',
300
                 hideInMenu: true,
300
                 hideInMenu: true,
301
                 component: './activity/helpActivity/signList',
301
                 component: './activity/helpActivity/signList',
302
               },
302
               },

+ 1
- 1
package.json View File

64
     "react-dom": "^16.8.6",
64
     "react-dom": "^16.8.6",
65
     "react-zmage": "^0.8.5",
65
     "react-zmage": "^0.8.5",
66
     "redux": "^4.0.1",
66
     "redux": "^4.0.1",
67
-    "umi": "^2.8.7",
67
+    "umi": "^2.13.3",
68
     "umi-plugin-pro-block": "^1.3.2",
68
     "umi-plugin-pro-block": "^1.3.2",
69
     "umi-plugin-react": "^1.9.5",
69
     "umi-plugin-react": "^1.9.5",
70
     "umi-request": "^1.0.8",
70
     "umi-request": "^1.0.8",

+ 1
- 1
src/components/GlobalHeader/AvatarDropdown.jsx View File

79
       <>
79
       <>
80
         <HeaderDropdown overlay={menuHeaderDropdown}>
80
         <HeaderDropdown overlay={menuHeaderDropdown}>
81
             <span className={`${styles.action} ${styles.account}`}>
81
             <span className={`${styles.action} ${styles.account}`}>
82
-              <Avatar size="small" className={styles.avatar} src={currentUser.avatar} alt="avatar" />
82
+              <Avatar size="small" className={styles.avatar} src={currentUser.avatar === null ? currentUser.photo:currentUser.avatar} alt="avatar" />
83
               <span className={styles.name}>{currentUser.userName}</span>
83
               <span className={styles.name}>{currentUser.userName}</span>
84
             </span>
84
             </span>
85
         </HeaderDropdown>
85
         </HeaderDropdown>

+ 45
- 0
src/components/SelectButton/WxDictSelect.jsx View File

1
+import React, { useState, useEffect, useRef } from 'react';
2
+import { Select } from 'antd';
3
+import apis from '../../services/apis';
4
+import request from '../../utils/request'
5
+
6
+const { Option } = Select;
7
+
8
+/**
9
+ *
10
+ *
11
+ * @param {*} props
12
+ * @returns
13
+ */
14
+const WxDictSelect = props => {
15
+  const [data, setData] = useState([])
16
+  const [value, setValue] = useState([])
17
+  useEffect(() => {
18
+    getWxDictList();
19
+  }, [props.value])
20
+
21
+
22
+  const getWxDictList = e => {
23
+    request({ ...apis.wxDict.list, params: { pageNumber: 1, pageSize: 999 } }).then(data => {
24
+        setData(data.records)
25
+        // 默认选中第一个
26
+    })
27
+  }
28
+
29
+  return (
30
+      <Select
31
+      showSearch
32
+      value={props.value}
33
+      style={{ width: '250px' }}
34
+      placeholder="请选择用户来源"
35
+      onChange={props.onChange}
36
+      filterOption={(input, option) =>
37
+        option.props.children && option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
38
+      }>
39
+          {data.map(wxDict => (
40
+            <Option key={wxDict.sceneType} value={wxDict.sceneType}>{wxDict.sceneAlias}</Option>
41
+          ))}
42
+      </Select>
43
+  )
44
+}
45
+export default WxDictSelect

+ 1
- 1
src/pages/activity/SignList.jsx View File

121
         const link = document.createElement('a')
121
         const link = document.createElement('a')
122
         link.style.display = 'none'
122
         link.style.display = 'none'
123
         link.href = url
123
         link.href = url
124
-        link.setAttribute('download', '助力者记录.xlsx')
124
+        link.setAttribute('download', '报名列表.xlsx')
125
         document.body.append(link)
125
         document.body.append(link)
126
         link.click()
126
         link.click()
127
       }).catch(() => {
127
       }).catch(() => {

+ 23
- 0
src/pages/activity/drainage/DrainageList.jsx View File

73
     });
73
     });
74
   }
74
   }
75
 
75
 
76
+  const newQrcode = row => {
77
+    const x = new XMLHttpRequest();
78
+    const resourceUrl = row.qrCode
79
+    console.log(resourceUrl);
80
+    x.open('GET', resourceUrl, true);
81
+    x.responseType = 'blob';
82
+    x.onload = function (e) {
83
+      const url = window.URL.createObjectURL(x.response)
84
+      const a = document.createElement('a');
85
+      a.href = url;
86
+      a.style.display = 'none'
87
+      a.download = 'H5二维码.png';
88
+      a.click();
89
+    }
90
+    x.send();
91
+  }
92
+
76
   const exchangeDrainage = drainage => () => {
93
   const exchangeDrainage = drainage => () => {
77
     if(drainage.status === 1){
94
     if(drainage.status === 1){
78
       if(drainage.isMiniapp){
95
       if(drainage.isMiniapp){
206
               数据
223
               数据
207
             </span>
224
             </span>
208
           </AuthButton>
225
           </AuthButton>
226
+          <AuthButton name="admin.taDrainage.id.delete" noRight={null}>
227
+            <span>{datas.isMiniapp === false ? "" : <span style={{ right: '20px', bottom: ' 10px', fontSize: ' 0.106rem', color: '#FF7E48', cursor: 'pointer', marginLeft: 20 }} onClick={newQrcode.bind(this, datas)}>
228
+              下载二维码
229
+            </span>}</span>
230
+            
231
+          </AuthButton >
209
         </>
232
         </>
210
       ),
233
       ),
211
     },
234
     },

+ 32
- 8
src/pages/building/list/add/components/base.jsx View File

45
 
45
 
46
   const [poi, setPoi] = useState([])
46
   const [poi, setPoi] = useState([])
47
   const [videoImage, setVideoImage] = useState(false)
47
   const [videoImage, setVideoImage] = useState(false)
48
+  const [priceTypeList, setPriceTypeList] = useState([])
48
 
49
 
49
   // 存放所以 buildingData 基础信息
50
   // 存放所以 buildingData 基础信息
50
   const [buildingData, setBuildingData] = useState({})
51
   const [buildingData, setBuildingData] = useState({})
83
    // 获取详情信息
84
    // 获取详情信息
84
    function getById(currentId) {
85
    function getById(currentId) {
85
     request({ ...apis.building.buildingGetById, urlData: { id: currentId } }).then(res => {
86
     request({ ...apis.building.buildingGetById, urlData: { id: currentId } }).then(res => {
86
-      if (res.openingDate !== null) {
87
-        res.openingDate = moment(res.openingDate)
88
-      }
87
+      // if (res.openingDate !== null) {
88
+      //   res.openingDate = moment(res.openingDate)
89
+      // }
90
+      //构造下拉框
91
+      setPriceTypeList(res.buildingProjectType)
89
       if (res.receivedDate !== null) {
92
       if (res.receivedDate !== null) {
90
         res.receivedDate = moment(res.receivedDate)
93
         res.receivedDate = moment(res.receivedDate)
91
       }
94
       }
161
       data.mapJson = poi
164
       data.mapJson = poi
162
     }
165
     }
163
 
166
 
164
-    data.openingDate = moment(data.openingDate, 'yyyy-MM-dd HH:mm:ss')
167
+    // data.openingDate = moment(data.openingDate, 'yyyy-MM-dd HH:mm:ss')
165
     data.receivedDate = moment(data.receivedDate, 'yyyy-MM-dd HH:mm:ss')
168
     data.receivedDate = moment(data.receivedDate, 'yyyy-MM-dd HH:mm:ss')
166
     // 项目主图
169
     // 项目主图
167
     data.img = data.avatarImage && data.avatarImage.map((item, index) => ({ imgType: 'banner', url: item, orderNo: index + 1 }))
170
     data.img = data.avatarImage && data.avatarImage.map((item, index) => ({ imgType: 'banner', url: item, orderNo: index + 1 }))
304
     return newPoi
307
     return newPoi
305
   }
308
   }
306
 
309
 
310
+  //组装项目类型
311
+  function getBuildingProjectTypeList(e) {
312
+    console.log(e,"项目类型------")
313
+    setPriceTypeList(e)
314
+  }
315
+
307
   function setFormMapScopeTagValue(keyType, item) {
316
   function setFormMapScopeTagValue(keyType, item) {
308
     const tag = item.data.map(t => ({ tagName: t.name, delete: true, automatic: true }))
317
     const tag = item.data.map(t => ({ tagName: t.name, delete: true, automatic: true }))
309
     switch (keyType) {
318
     switch (keyType) {
357
           <Form.Item label="项目类型">
366
           <Form.Item label="项目类型">
358
             {getFieldDecorator('buildingProjectType', {
367
             {getFieldDecorator('buildingProjectType', {
359
               rules: [{ required: true, message: '请选择项目类型' }],
368
               rules: [{ required: true, message: '请选择项目类型' }],
360
-            })(<BudildingProjectType />)}
369
+            })(<BudildingProjectType onChange={e => getBuildingProjectTypeList(e)}/>)}
361
           </Form.Item>
370
           </Form.Item>
362
-          <Form.Item label="均价" >
363
-            {getFieldDecorator('price')(<Input type="number" style={{ width: '210px' }}/>)}元/m²
371
+          <Form.Item label="列表展示均价" >
372
+            {/* {getFieldDecorator('price')(<Input type="number" style={{ width: '210px' }}/>)}元/m² */}
373
+            {getFieldDecorator('buildingTypeId')(
374
+              <Select placeholder="请选择项目类型的价格">
375
+                    {
376
+                      priceTypeList.map((item, _) => <Option value={item.buildingTypeId}>{item.buildingTypeName}</Option>)
377
+                    }
378
+              </Select>)}
364
           </Form.Item>
379
           </Form.Item>
365
           <Form.Item label="开盘时间" >
380
           <Form.Item label="开盘时间" >
366
-            {getFieldDecorator('openingDate')(<DatePicker format="YYYY/MM/DD" />)}
381
+            {getFieldDecorator('openingDate')(<Input placeholder="预计xxxx年xx月开盘" maxLength = "15"/>)}
367
           </Form.Item>
382
           </Form.Item>
368
           <Form.Item label="电话" >
383
           <Form.Item label="电话" >
369
             {getFieldDecorator('tel', {
384
             {getFieldDecorator('tel', {
549
           <Form.Item label="装修标准" >
564
           <Form.Item label="装修标准" >
550
             {getFieldDecorator('decoration')(<Input />)}
565
             {getFieldDecorator('decoration')(<Input />)}
551
           </Form.Item>
566
           </Form.Item>
567
+          <Form.Item label="开发商" >
568
+            {getFieldDecorator('propertyDeveloper')(<Input placeholder="不超过15个字" maxLength = "15"/>)}
569
+          </Form.Item>
570
+          <Form.Item label="备案名" >
571
+            {getFieldDecorator('recordName')(<Input placeholder="不超过15个字" maxLength = "15"/>)}
572
+          </Form.Item>
573
+          <Form.Item label="楼栋总数" >
574
+            {getFieldDecorator('buildingNum')(<Input min={0} type="number" style={{ width: 80}}/>)}
575
+          </Form.Item>
552
           {/* <Form.Item label="交房时间" >
576
           {/* <Form.Item label="交房时间" >
553
             {getFieldDecorator('receivedDate')(<DatePicker />)}
577
             {getFieldDecorator('receivedDate')(<DatePicker />)}
554
           </Form.Item> */}
578
           </Form.Item> */}

+ 1
- 1
src/pages/building/list/add/components/buildingImage.jsx View File

123
             })(<Input />)}
123
             })(<Input />)}
124
           </Form.Item>
124
           </Form.Item>
125
           {
125
           {
126
-            !props.noImage && <Form.Item label="选择图片">
126
+            !props.noImage && <Form.Item label="选择图片" help="建议图片尺寸256px*252px,比例4:3,格式:jpg">
127
             {getFieldDecorator('img', {
127
             {getFieldDecorator('img', {
128
               rules: [
128
               rules: [
129
                 {
129
                 {

+ 26
- 8
src/pages/building/list/add/components/buildingProjectType.jsx View File

1
 import React, { useEffect, useState } from 'react'
1
 import React, { useEffect, useState } from 'react'
2
-import { Button, Radio, Icon, Form, Input, Row, Col, Modal, notification, Checkbox, InputNumber } from 'antd';
2
+import { Button, Radio, Icon, Form, Input, Row, Col, Modal, notification, Checkbox, Select, InputNumber } from 'antd';
3
 import { render } from 'react-dom';
3
 import { render } from 'react-dom';
4
 import request from '../../../../../utils/request';
4
 import request from '../../../../../utils/request';
5
 import apis from '../../../../../services/apis';
5
 import apis from '../../../../../services/apis';
28
   }
28
   }
29
 
29
 
30
   onChange(e, name) {
30
   onChange(e, name) {
31
-    // console.log(e.target.value)
31
+    // console.log(e)
32
     this.props.form.validateFieldsAndScroll((err, values) => {
32
     this.props.form.validateFieldsAndScroll((err, values) => {
33
       if (!err) {
33
       if (!err) {
34
         // console.log('Received values of form: ', values);
34
         // console.log('Received values of form: ', values);
35
-        const currentValue = e.target.value
35
+        const currentValue = name === 'marketStatus' ? e : e.target.value
36
         if (currentValue === '') {
36
         if (currentValue === '') {
37
           values[name] = null
37
           values[name] = null
38
         } else {
38
         } else {
54
     const { getFieldDecorator } = this.props.form;
54
     const { getFieldDecorator } = this.props.form;
55
 
55
 
56
     // this.props.form.setFieldsValue(this.props.type)
56
     // this.props.form.setFieldsValue(this.props.type)
57
-    console.log(this.props.type)
57
+    // console.log(this.props.type,"33333333")
58
     return (
58
     return (
59
       <>
59
       <>
60
         <Col span={11} style={{
60
         <Col span={11} style={{
66
 
66
 
67
           <p style={{ padding: '20px', borderBottom: '1px solid #eee' }}>{this.props.type.buildingTypeName || ''}  <Button type="link" style={{ position: 'absolute', right: '16px' }} icon="close" onClick={() => this.close()} /></p>
67
           <p style={{ padding: '20px', borderBottom: '1px solid #eee' }}>{this.props.type.buildingTypeName || ''}  <Button type="link" style={{ position: 'absolute', right: '16px' }} icon="close" onClick={() => this.close()} /></p>
68
 
68
 
69
-          <Form {...formItemLayout} style={{ padding: '10px 0px 10px 10px' }}>
69
+          <Form {...formItemLayout} style={{ padding: '5px 0px 5px 5px' }}>
70
             <Form.Item label="类型编号" style={{ display: 'none' }}>
70
             <Form.Item label="类型编号" style={{ display: 'none' }}>
71
               {getFieldDecorator('buildingTypeId')(<Input disabled />)}
71
               {getFieldDecorator('buildingTypeId')(<Input disabled />)}
72
             </Form.Item>
72
             </Form.Item>
73
             <Form.Item label="状态" style={{ display: 'none' }}>
73
             <Form.Item label="状态" style={{ display: 'none' }}>
74
               {getFieldDecorator('status')(<Input disabled />)}
74
               {getFieldDecorator('status')(<Input disabled />)}
75
             </Form.Item>
75
             </Form.Item>
76
-            <Form.Item label="价格">
77
-              {getFieldDecorator('price')(<Input type="number" placeholder="元/㎡" onChange={e => this.onChange(e, 'price')} />)}
76
+            <Form.Item label="价格类型">
77
+                {getFieldDecorator('priceType')(
78
+                  <Radio.Group onChange={e => this.onChange(e, 'priceType')} >
79
+                    <Radio value="average">均价</Radio>
80
+                    <Radio value="total">总价</Radio>
81
+                  </Radio.Group>
82
+                )}
83
+              </Form.Item>
84
+            <Form.Item label="价格区间" help='最高价与最低价一致时,只展示一个'>
85
+              {getFieldDecorator('startPrice')(<Input placeholder="最低价" style={{width: '60px'}} maxLength="9" onChange={e => this.onChange(e, 'startPrice')} />)} --
86
+              {getFieldDecorator('endPrice')(<Input placeholder="最高价" style={{width: '60px'}} maxLength="9" onChange={e => this.onChange(e, 'endPrice')} />)}{this.props.type.priceType === "average" ? "元/㎡" : "万元/套"}
78
             </Form.Item>
87
             </Form.Item>
88
+            <Form.Item label="销售状态" >
89
+            {getFieldDecorator('marketStatus')(
90
+              <Select placeholder="销售状态" onChange={e => this.onChange(e, 'marketStatus')} >
91
+                <Option value="待售">待售</Option>
92
+                <Option value="在售">在售</Option>
93
+                <Option value="售罄">售罄</Option>
94
+              </Select>,
95
+            )}
96
+          </Form.Item>
79
             <Form.Item label="装修标准">
97
             <Form.Item label="装修标准">
80
               {getFieldDecorator('decoration')(<Input onChange={e => this.onChange(e, 'decoration')} />)}
98
               {getFieldDecorator('decoration')(<Input onChange={e => this.onChange(e, 'decoration')} />)}
81
             </Form.Item>
99
             </Form.Item>
136
     const { projectType } = this.state
154
     const { projectType } = this.state
137
     const buildingType = projectType.filter(item => checked.includes(`${item.buildingTypeId}`))
155
     const buildingType = projectType.filter(item => checked.includes(`${item.buildingTypeId}`))
138
 
156
 
139
-    const tempDate = buildingType.map(item => ({ buildingTypeId: item.buildingTypeId, buildingTypeName: item.buildingTypeName, price: null, decoration: null, rightsYear: null, status: '1' }))
157
+    const tempDate = buildingType.map(item => ({ buildingTypeId: item.buildingTypeId, buildingTypeName: item.buildingTypeName, startPrice: null,endPrice: null,priceType: "average", decoration: null, rightsYear: null, status: '1' }))
140
     const updateProjectDate = this.updateProjectType(tempDate)
158
     const updateProjectDate = this.updateProjectType(tempDate)
141
     console.log('updateProjectDate: ', updateProjectDate)
159
     console.log('updateProjectDate: ', updateProjectDate)
142
     this.setState({ data: updateProjectDate })
160
     this.setState({ data: updateProjectDate })

+ 29
- 0
src/pages/building/list/add/components/imageSet.jsx View File

25
   },
25
   },
26
 ]
26
 ]
27
 
27
 
28
+const houseType = [
29
+  {
30
+    id: 1,
31
+    name: '1室',
32
+  },
33
+  {
34
+    id: 2,
35
+    name: '2室',
36
+  },
37
+  {
38
+    id: 3,
39
+    name: '3室',
40
+  },
41
+  {
42
+    id: 4,
43
+    name: '4室',
44
+  },
45
+  {
46
+    id: 5,
47
+    name: '5室及以上',
48
+  },
49
+]
50
+
28
 /**
51
 /**
29
  *图片设置
52
  *图片设置
30
  *
53
  *
115
       key: 'marketStatus',
138
       key: 'marketStatus',
116
       render: (_, record) => <span>{ (saleType.filter(x => x.id == record.marketStatus)[0] || {}).name }</span>,
139
       render: (_, record) => <span>{ (saleType.filter(x => x.id == record.marketStatus)[0] || {}).name }</span>,
117
     },
140
     },
141
+    {
142
+      title: '户型',
143
+      dataIndex: 'houseType',
144
+      key: 'houseType',
145
+      render: (_, record) => <span>{ (houseType.filter(x => x.id == record.houseType)[0] || {}).name }</span>,
146
+    },
118
     {
147
     {
119
       title: '面积',
148
       title: '面积',
120
       dataIndex: 'buildingArea',
149
       dataIndex: 'buildingArea',

+ 37
- 18
src/pages/building/list/add/components/modalImage.jsx View File

42
   },
42
   },
43
 ]
43
 ]
44
 
44
 
45
+const houseType = [
46
+  {
47
+    id: '1',
48
+    name: '1室',
49
+  },
50
+  {
51
+    id: '2',
52
+    name: '2室',
53
+  },
54
+  {
55
+    id: '3',
56
+    name: '3室',
57
+  },
58
+  {
59
+    id: '4',
60
+    name: '4室',
61
+  },
62
+  {
63
+    id: '5',
64
+    name: '5室及以上',
65
+  },
66
+]
67
+
45
 /**
68
 /**
46
  * 图片信息
69
  * 图片信息
47
  *
70
  *
186
                   </Select>,
209
                   </Select>,
187
                 )}
210
                 )}
188
               </Form.Item>
211
               </Form.Item>
189
-              <Form.Item label="图片">
212
+              <Form.Item label="图片" help="建议图片尺寸336px*336px,比例1:1,格式:jpg">
190
               {getFieldDecorator('img', {
213
               {getFieldDecorator('img', {
191
                   rules: [{ required: true, message: '请上传户型图片' }],
214
                   rules: [{ required: true, message: '请上传户型图片' }],
192
               })(
215
               })(
194
                 <ImageUpload />,
217
                 <ImageUpload />,
195
               )}
218
               )}
196
               </Form.Item>
219
               </Form.Item>
220
+              <Form.Item label="户型">
221
+                {getFieldDecorator('houseType', {
222
+                  rules: [{ required: true, message: '请选择户型' }],
223
+                })(
224
+                  <Select placeholder="户型">
225
+                    {
226
+                      houseType.map((item, _) => <Option value={item.id}>{item.name}</Option>)
227
+                    }
228
+                  </Select>,
229
+                )}
230
+              </Form.Item>
197
               <Form.Item label="面积" help="单位 ㎡">
231
               <Form.Item label="面积" help="单位 ㎡">
198
-                {getFieldDecorator('buildingArea', {
199
-                  rules: [{ message: '请填写面积' },
200
-                          {
201
-                            pattern: new RegExp('^[1-9][0-9]*(\.[0-9]{1,2})?$'),
202
-                            message: '只允许输入数字',
203
-                          },
204
-                  ],
205
-                })(<Input type="number" />)}
232
+                {getFieldDecorator('buildingArea')(<Input type="number" precision = '2' min='0.00' step='0.01'/>)}
206
               </Form.Item>
233
               </Form.Item>
207
               <Form.Item label="套内面积" help="单位 ㎡">
234
               <Form.Item label="套内面积" help="单位 ㎡">
208
-                {getFieldDecorator('insideArea', {
209
-                  rules: [
210
-                    // { required: true, message: '请填写套内面积' },
211
-                          {
212
-                            pattern: new RegExp('^[1-9][0-9]*(\.[0-9]{1,2})?$'),
213
-                            message: '只允许输入数字',
214
-                          },
215
-                  ],
216
-                })(<Input type="number" />)}
235
+                {getFieldDecorator('insideArea')(<Input type="number" precision = '2' min='0.00' step='0.01'/>)}
217
               </Form.Item>
236
               </Form.Item>
218
               <Form.Item style={{ width: '400px', margin: 'auto', display: 'flex', justifyContent: 'space-between' }}>
237
               <Form.Item style={{ width: '400px', margin: 'auto', display: 'flex', justifyContent: 'space-between' }}>
219
                 <Button type="primary" htmlType="submit">保存</Button>
238
                 <Button type="primary" htmlType="submit">保存</Button>

+ 250
- 0
src/pages/building/list/add/components/modalPanoramaImage.jsx View File

1
+import React, { useState, useEffect } from 'react';
2
+import { Form, Icon, Input, Button, DatePicker, Select, Card, Row, Col, Pagination, Alert, Table, Avatar, Radio, Modal, Descriptions, notification } from 'antd';
3
+import moment from 'moment';
4
+import request from '../../../../../utils/request';
5
+import apis from '../../../../../services/apis';
6
+import Styles from '../style.less';
7
+import ImageUpload from '../../../../../components/XForm/ImageUpload'
8
+import ImageListUpload from '../../../../../components/XForm/ImageListUpload'
9
+import Wangedit from '../../../../../components/Wangedit/Wangedit'
10
+
11
+
12
+const { Option } = Select;
13
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
14
+const { Meta } = Card;
15
+
16
+const { TextArea } = Input;
17
+
18
+const formItemLayout = {
19
+  labelCol: {
20
+    xs: { span: 24 },
21
+    sm: { span: 2 },
22
+  },
23
+  wrapperCol: {
24
+    xs: { span: 24 },
25
+    sm: { span: 16 },
26
+  },
27
+};
28
+
29
+const saleType = [
30
+  {
31
+    id: 1,
32
+    name: '待售',
33
+  },
34
+  {
35
+    id: 2,
36
+    name: '售罄',
37
+  },
38
+  {
39
+    id: 3,
40
+    name: '在售',
41
+  },
42
+]
43
+
44
+const houseType = [
45
+  {
46
+    id: '1',
47
+    name: '1室',
48
+  },
49
+  {
50
+    id: '2',
51
+    name: '2室',
52
+  },
53
+  {
54
+    id: '3',
55
+    name: '3室',
56
+  },
57
+  {
58
+    id: '4',
59
+    name: '4室',
60
+  },
61
+  {
62
+    id: '5',
63
+    name: '5室及以上',
64
+  },
65
+]
66
+  
67
+/**
68
+ * 图片信息
69
+ *
70
+ * @param {*} props
71
+ * @returns
72
+ */
73
+class ModalPanoramaImage extends React.Component {
74
+  constructor(props) {
75
+    super(props);
76
+    this.state = {
77
+       visibleData: { visible: false, apartmentId: '', buildingId: '',panoramaType: "apartment" },
78
+    }
79
+  }
80
+
81
+  // 挂载之后
82
+  // componentDidMount() {
83
+  //
84
+  // }
85
+
86
+  componentDidUpdate(preProps, preState) {
87
+    if (this.props.visibleData.visible !== preState.visibleData.visible) {
88
+      console.log(this.props.visibleData)
89
+      this.getById()
90
+      this.setState({ visibleData: this.props.visibleData });
91
+    }
92
+  }
93
+
94
+  // 弹框确定按钮
95
+  // eslint-disable-next-line react/sort-comp
96
+  handleOk() {
97
+    this.setState({ visibleData: { visible: false, apartmentId: '', buildingId: '' } })
98
+  }
99
+
100
+  // 弹框取消按钮
101
+  handleCancel() {
102
+    // this.setState({ visibleData: { visible: false, apartmentId: '', buildingId: '' } })
103
+    this.props.onSuccess()
104
+  }
105
+
106
+  getById(params) {
107
+    const { apartmentId } = this.props.visibleData
108
+    if (apartmentId === '' || apartmentId === undefined) {
109
+      return
110
+    }
111
+
112
+    // 网路请求
113
+    request({ ...apis.building.buildingApartmentGetById, urlData: { id: apartmentId }, params: { ...params } }).then(res => {
114
+      // res.img = res.buildingImgList.map(item => item.url)
115
+      if (res.buildingImgList) {
116
+        res.img = res.buildingImgList[0].url
117
+      }
118
+      
119
+      this.props.form.setFieldsValue(res)
120
+    }).catch(err => {
121
+     this.openNotificationWithIcon('error', err)
122
+    })
123
+  }
124
+
125
+  openNotificationWithIcon = (type, message) => {
126
+    notification[type]({
127
+      message,
128
+      description:
129
+        '',
130
+    });
131
+  };
132
+
133
+  // 提交
134
+  handleSubmit(e) {
135
+    e.preventDefault();
136
+    this.props.form.validateFields((err, values) => {
137
+      if (!err) {
138
+        this.submitData(values)
139
+      }
140
+    });
141
+  }
142
+
143
+  submitData(data) {
144
+    data.buildingId = this.props.visibleData.buildingId;
145
+    const api = apis.paorama.add;
146
+
147
+    // 网路请求
148
+    request({ ...api, data: { ...data } }).then(() => {
149
+      // eslint-disable-next-line no-unused-expressions
150
+      this.openNotificationWithIcon('success', '操作成功')
151
+
152
+      // 传递父组件事件
153
+      // onSuccess() 是自定义
154
+      this.props.onSuccess()
155
+
156
+      // this.setState({ visibleData: { visible: false, apartmentId: '', buildingId: '' } }, () => console.log('回调:', this.state.visibleData))
157
+    }).catch(err => {
158
+      // eslint-disable-next-line no-unused-expressions
159
+      this.openNotificationWithIcon('error', err)
160
+    })
161
+  }
162
+
163
+  radioOnChange(e) {
164
+    this.setState({ visibleData: { ...this.state.visibleData, panoramaType: e.target.value } })
165
+  }
166
+
167
+  /**
168
+   * 取消按钮
169
+   *
170
+   * @memberof ModalImage
171
+   */
172
+  closeModal() {
173
+    this.setState({ visibleData: { visible: false, apartmentId: '', buildingId: '' } })
174
+  }
175
+
176
+  render() {
177
+    const { getFieldDecorator } = this.props.form;
178
+    return (
179
+      <>
180
+        <Modal
181
+            title="新增全景图"
182
+            width={1100}
183
+            destroyOnClose="true"
184
+            footer={null}
185
+            visible={this.state.visibleData.visible}
186
+            onOk={() => this.handleOk()}
187
+            onCancel={e => this.handleCancel(e)}
188
+          >
189
+            <Form {...formItemLayout} onSubmit={e => this.handleSubmit(e)}>
190
+              <Form.Item label="全景类型">
191
+                {getFieldDecorator('panoramaType', {
192
+                  rules: [
193
+                    {
194
+                      required: true,
195
+                      message: '请选择全景类型',
196
+                    },
197
+                  ],
198
+                })(
199
+                  <Radio.Group onChange={(e) => this.radioOnChange(e)}>
200
+                    <Radio value="apartment">户型</Radio>
201
+                    <Radio value="building">项目</Radio>
202
+                  </Radio.Group>,
203
+                )}
204
+              </Form.Item>
205
+              { this.state.visibleData.panoramaType == "apartment" && <Form.Item label="全景内容">
206
+                {getFieldDecorator('apartmentId', {
207
+                  rules: [{ required: true, message: '请选择全景内容' }],
208
+                })(
209
+                  <Select placeholder="户型">
210
+                    {
211
+                      (this.state.visibleData.panoramaList || []).map((item, _) => <Option value={item.apartmentId}>{item.apartmentName}</Option>)
212
+                    }
213
+                  </Select>,
214
+                )}
215
+              </Form.Item>}
216
+              { this.state.visibleData.panoramaType == "building" && <Form.Item label="全景内容">
217
+                {getFieldDecorator('content', {
218
+                  rules: [{ required: true, message: '请输入全景内容' }],
219
+                })(
220
+                  <Input />,
221
+                )}
222
+              </Form.Item>}
223
+              <Form.Item label="选择封面" help="建议图片尺寸750px*600px,比例5:4,格式:jpg">
224
+              {getFieldDecorator('coverImg', {
225
+                  rules: [{ required: true, message: '请上传封面图片' }],
226
+              })(
227
+                // <ImageListUpload />,
228
+                <ImageUpload />,
229
+              )}
230
+              </Form.Item>
231
+              <Form.Item label="链接地址">
232
+                {getFieldDecorator('panoramaLink', {
233
+                  rules: [{ required: true, message: '请输入链接地址' }],
234
+                })(<Input />)}
235
+              </Form.Item>
236
+              <Form.Item style={{ width: '400px', margin: 'auto', display: 'flex', justifyContent: 'space-between' }}>
237
+                <Button type="primary" htmlType="submit">保存</Button>
238
+                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
239
+                <Button onClick={() => this.handleCancel()}>取消</Button>
240
+              </Form.Item>
241
+            </Form>
242
+        </Modal>
243
+      </>
244
+    );
245
+  }
246
+}
247
+
248
+const WrappedModalPanoramaImageForm = Form.create({ name: 'modalPanoramaImage' })(ModalPanoramaImage);
249
+
250
+export default WrappedModalPanoramaImageForm

+ 182
- 0
src/pages/building/list/add/components/panoramaImage.jsx View File

1
+import React, { useState, useEffect } from 'react';
2
+import { Form, Icon, Input, Button, DatePicker, Select, Card, Row, Col, Pagination, Alert, Radio, Tag, Tooltip, Tabs, Table, notification, Modal } from 'antd';
3
+import moment from 'moment';
4
+import request from '../../../../../utils/request';
5
+import apis from '../../../../../services/apis';
6
+import Styles from '../style.less';
7
+import { router } from 'umi';
8
+import ModalPanoramaImage from './modalPanoramaImage';
9
+
10
+const { confirm } = Modal;
11
+
12
+
13
+const saleType = [
14
+  {
15
+    id: 1,
16
+    name: '待售',
17
+  },
18
+  {
19
+    id: 2,
20
+    name: '售罄',
21
+  },
22
+  {
23
+    id: 3,
24
+    name: '在售',
25
+  },
26
+]
27
+
28
+const houseType = [
29
+  {
30
+    id: 1,
31
+    name: '1室',
32
+  },
33
+  {
34
+    id: 2,
35
+    name: '2室',
36
+  },
37
+  {
38
+    id: 3,
39
+    name: '3室',
40
+  },
41
+  {
42
+    id: 4,
43
+    name: '4室',
44
+  },
45
+  {
46
+    id: 5,
47
+    name: '5室及以上',
48
+  },
49
+]
50
+
51
+/**
52
+ *图片设置
53
+ *
54
+ * @param {*} props
55
+ * @returns
56
+ */
57
+function panoramaImage(props) {
58
+  // eslint-disable-next-line react-hooks/rules-of-hooks
59
+  const [data, setData] = useState([])
60
+
61
+  // eslint-disable-next-line react-hooks/rules-of-hooks
62
+  const [visibleData, setVisibleData] = useState({ visible: false, apartmentId: '', buildingId: '' })
63
+
64
+  // eslint-disable-next-line react-hooks/rules-of-hooks
65
+  useEffect(() => {
66
+    getList()
67
+  }, [])
68
+
69
+  function openNotificationWithIcon(type, message) {
70
+    notification[type]({
71
+      message,
72
+      description:
73
+        '',
74
+    });
75
+  }
76
+
77
+  function getList(params) {
78
+    // 网路请求
79
+    request({ ...apis.paorama.list, urlData: { id: props.building.buildingId }, params: { ...params, apartmentType: 'apart' } }).then(res => {
80
+      setData(res)
81
+    }).catch(err => {
82
+      openNotificationWithIcon('error', err.message)
83
+    })
84
+  }
85
+
86
+  /**
87
+   *回调事件
88
+   *
89
+   */
90
+  function onModalChange() {
91
+    getList()
92
+    setVisibleData({ visible: false, apartmentId: '', buildingId: '' })
93
+  }
94
+
95
+  /**
96
+   *打开编辑页
97
+   *
98
+   * @param {*} record
99
+   */
100
+  function showEdi(record) {
101
+    // 网路请求
102
+    request({ ...apis.paorama.panoramaApartList, params: { buildingId:  props.building.buildingId } }).then(res => {
103
+      setVisibleData({ visible: true, apartmentId: record === undefined ? '' : record.apartmentId, buildingId: props.building.buildingId, panoramaType: "apartment", panoramaList: res })
104
+     }).catch(err => {
105
+      this.openNotificationWithIcon('error', err)
106
+     })
107
+  }
108
+
109
+  /**
110
+   * 删除
111
+   *
112
+   * @param {*} record
113
+   */
114
+  function deleteApartment(record) {
115
+    confirm({
116
+      title: '确认删除当前数据?',
117
+      content: '确定后成功删除,点击取消则放弃当前操作',
118
+      okText: '确定',
119
+      cancelText: '取消',
120
+      onOk() {
121
+        // 网路请求
122
+        request({ ...apis.paorama.delete, urlData: { id: record.panoramaId } }).then(res => {
123
+          getList()
124
+          openNotificationWithIcon('success', '操作成功')
125
+        }).catch(err => {
126
+          // openNotificationWithIcon('error', err.message)
127
+        })
128
+      },
129
+      onCancel() {},
130
+    });
131
+  }
132
+
133
+
134
+  const columns = [
135
+    {
136
+      title: '封面图',
137
+      dataIndex: 'coverImg',
138
+      key: 'coverImg',
139
+      render: (x, record) =>  <img style={{ width: '150px', height: '120px' }} src={x} alt="" />,
140
+    },
141
+    {
142
+      title: '类型',
143
+      dataIndex: 'panoramaType',
144
+      key: 'panoramaType',
145
+      render: (x, record) => <span>{x === "apartment" ? "户型" : "项目"}</span>,
146
+    },
147
+    {
148
+      title: '内容',
149
+      dataIndex: 'content',
150
+      key: 'content',
151
+    },
152
+    {
153
+      title: '链接地址',
154
+      dataIndex: 'panoramaLink',
155
+      key: 'panoramaLink',
156
+    },
157
+    {
158
+      title: '操作',
159
+      dataIndex: 'apartmentId',
160
+      key: 'apartmentId',
161
+      render: (_, record) => (
162
+        <>
163
+          <Button type="link" style={{ color: 'red' }} onClick={() => deleteApartment(record)}>删除</Button>
164
+        </>
165
+      ),
166
+    },
167
+  ]
168
+
169
+  return (
170
+    <>
171
+      <Button type="primary" onClick={() => showEdi()}>新增全景图</Button>
172
+      <Button type="danger" style={{ marginLeft: '18px'}} onClick={() => router.go(-1)}>返回</Button>
173
+      <Table dataSource={data} columns={columns} pagination={false} rowKey="imageSet" />
174
+
175
+      {/* 编辑页 */}
176
+      {/*  onSuccess是子组件传递事件信息  */}
177
+      <ModalPanoramaImage visibleData={visibleData} key="ModalImage" onSuccess={() => onModalChange()}/>
178
+    </>
179
+  )
180
+}
181
+
182
+export default panoramaImage

+ 3
- 0
src/pages/building/list/add/index.jsx View File

12
 import TagGroup from './components/tags'
12
 import TagGroup from './components/tags'
13
 import Base from './components/base'
13
 import Base from './components/base'
14
 import Apartment from './components/imageSet'
14
 import Apartment from './components/imageSet'
15
+import PanoramaImage from './components/panoramaImage'
15
 import Poster from './components/poster'
16
 import Poster from './components/poster'
16
 import Share from './components/share'
17
 import Share from './components/share'
17
 import BuildingImage from './components/buildingImage';
18
 import BuildingImage from './components/buildingImage';
64
         <Radio.Button value="base">基本信息</Radio.Button>
65
         <Radio.Button value="base">基本信息</Radio.Button>
65
         <Radio.Button value="apartment">户型库</Radio.Button>
66
         <Radio.Button value="apartment">户型库</Radio.Button>
66
         <Radio.Button value="image">项目相册</Radio.Button>
67
         <Radio.Button value="image">项目相册</Radio.Button>
68
+        <Radio.Button value="panorama">全景图片</Radio.Button>
67
         <Radio.Button value="poster">海报图片</Radio.Button>
69
         <Radio.Button value="poster">海报图片</Radio.Button>
68
         <Radio.Button value="share">分享设置</Radio.Button>
70
         <Radio.Button value="share">分享设置</Radio.Button>
69
       </Radio.Group>
71
       </Radio.Group>
71
         { tab === 'base' && <Base building={{ buildingId: buildingData.buildingId || (props.location.query && props.location.query.id) }} onSuccess={e => buildingOnSuccess(e)}/> }
73
         { tab === 'base' && <Base building={{ buildingId: buildingData.buildingId || (props.location.query && props.location.query.id) }} onSuccess={e => buildingOnSuccess(e)}/> }
72
         { (tab === 'apartment' && <Apartment building={buildingData} />)}
74
         { (tab === 'apartment' && <Apartment building={buildingData} />)}
73
         { (tab === 'image' && <BuildingImage building={buildingData} />)}
75
         { (tab === 'image' && <BuildingImage building={buildingData} />)}
76
+        { (tab === 'panorama' && <PanoramaImage building={buildingData} />)}
74
         { (tab === 'poster' && <Poster building={buildingData} />)}
77
         { (tab === 'poster' && <Poster building={buildingData} />)}
75
         { (tab === 'share' && <Share building={buildingData} />)}
78
         { (tab === 'share' && <Share building={buildingData} />)}
76
       </div>
79
       </div>

+ 4
- 3
src/pages/building/list/index.jsx View File

1
 import React, { useState, useEffect } from 'react';
1
 import React, { useState, useEffect } from 'react';
2
-import { Form, Icon, Input, Button, DatePicker, Select, Card, Row, Col, Pagination, Alert, notification, Modal } from 'antd';
2
+import { Form, Icon, Input, Button, DatePicker, Select, Card, Row, message, Col, Pagination, Alert, notification, Modal } from 'antd';
3
 import moment from 'moment';
3
 import moment from 'moment';
4
 import request from '../../../utils/request';
4
 import request from '../../../utils/request';
5
 import apis from '../../../services/apis';
5
 import apis from '../../../services/apis';
59
           openNotificationWithIcon('success', '操作成功')
59
           openNotificationWithIcon('success', '操作成功')
60
           props.onSuccess()
60
           props.onSuccess()
61
         }).catch(err => {
61
         }).catch(err => {
62
-          openNotificationWithIcon('error', err.message)
62
+          // openNotificationWithIcon('error', err.message)
63
+          message.info(err.msg || err.message)
63
         })
64
         })
64
 
65
 
65
         modal.destroy();
66
         modal.destroy();
174
   const { getFieldDecorator } = props.form
175
   const { getFieldDecorator } = props.form
175
 
176
 
176
   // eslint-disable-next-line react-hooks/rules-of-hooks
177
   // eslint-disable-next-line react-hooks/rules-of-hooks
177
-  const [dataSource, setDataSource] = useState({ records: [] })
178
+  const [dataSource, setDataSource] = useState({ records: [],size: 0 })
178
 
179
 
179
   // eslint-disable-next-line react-hooks/rules-of-hooks
180
   // eslint-disable-next-line react-hooks/rules-of-hooks
180
   useEffect(() => {
181
   useEffect(() => {

+ 1
- 1
src/pages/carouselFigure/editCarousel.jsx View File

164
           name: 'image',
164
           name: 'image',
165
           type: FieldTypes.ImageUploader,
165
           type: FieldTypes.ImageUploader,
166
           value: data.image,
166
           value: data.image,
167
-          help: () => (locationType ? '建议图片尺寸:750*420px,比例16:9,格式:jpg,用于积分商城banner轮播' : '建议图片尺寸:750*464px,比例1.:0.618,格式:jpg,用于:首页顶部banner轮播'),
167
+          help: () => (locationType ? '建议图片尺寸:750*250px,比例3:1,格式:jpg,用于积分商城banner轮播' : '建议图片尺寸:750*464px,比例1.:0.618,格式:jpg,用于:首页顶部banner轮播'),
168
           rules: [
168
           rules: [
169
             { required: true, message: '请上传轮播图' },
169
             { required: true, message: '请上传轮播图' },
170
           ],
170
           ],

+ 158
- 0
src/pages/customer/customerlist/components/assistConsultant.jsx View File

1
+import React, { useState, useEffect } from 'react';
2
+import { Form, Icon, Input, Button, DatePicker, Select, Card, Row, Col, Pagination, Alert, Table, Avatar, Radio, Modal, Descriptions, notification } from 'antd';
3
+import moment from 'moment';
4
+import request from '../../../../utils/request';
5
+import apis from '../../../../services/apis';
6
+import Styles from '../style.less';
7
+import BuildSelect from '../../../../components/SelectButton/BuildSelect'
8
+
9
+
10
+const { Option } = Select;
11
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
12
+const { Meta } = Card;
13
+
14
+/**
15
+ * 分配置业顾问
16
+ *
17
+ * @param {*} props
18
+ * @returns
19
+ */
20
+class ModalAttribution extends React.Component {
21
+  constructor(props) {
22
+    super(props);
23
+    this.state = {
24
+       dataSource: { records: [] },
25
+       visibleData: { visible: false, customerId: '', buildingName: '' },
26
+    }
27
+  }
28
+
29
+  // 挂载之后
30
+  componentDidMount() {
31
+    // this.getList({ pageNumber: 1, pageSize: 5 })
32
+  }
33
+
34
+  componentDidUpdate(preProps, preState) {
35
+    console.log(this.props.visibleData)
36
+    if (this.props.visibleData.visible !== preState.visibleData.visible) {
37
+      this.getList({ pageNumber: 1, pageSize: 5, customerId: this.props.visibleData.customerId })
38
+      this.setState({ visibleData: this.props.visibleData });
39
+    }
40
+  }
41
+
42
+  // 弹框确定按钮
43
+  // eslint-disable-next-line react/sort-comp
44
+  handleOk() {
45
+    this.props.onCancel()
46
+  }
47
+
48
+  // 弹框取消按钮
49
+  handleCancel() {
50
+    this.props.onCancel()
51
+  }
52
+
53
+  changBuilding(buildingId){
54
+    this.getUserList({ pageNumber: 1, pageSize: 5, buildingId: buildingId })
55
+    this.setState({ visibleData: { visible: this.props.visibleData.visible, customerId: this.props.visibleData.customerId, buildingName: buildingId } });
56
+  }
57
+
58
+  getUserList(params){
59
+    console.log('params: ', params)
60
+    if (params.buildingId === '' || params.buildingId === null || params.buildingId === undefined) {
61
+      return
62
+    }
63
+    // 网路请求
64
+    request({ ...apis.customer.buildingConsultant, params: { ...params } }).then(res => {
65
+      this.setState({ dataSource: res })
66
+    }).catch(err => {
67
+      
68
+    })
69
+  }
70
+
71
+  getList(params) {
72
+    // 网路请求
73
+    request({ ...apis.customer.buildingConsultant, params: { ...params } }).then(res => {
74
+      this.setState({ dataSource: res })
75
+    }).catch(err => {
76
+      
77
+    })
78
+  }
79
+
80
+  openNotificationWithIcon = (type, message) => {
81
+    notification[type]({
82
+      message,
83
+      description:
84
+        '',
85
+    });
86
+  };
87
+
88
+   // 分页
89
+  onChange(pageNum) {
90
+    this.getList({ pageNumber: pageNum, pageSize: 5, buildingId: this.props.visibleData.buildingId })
91
+  }
92
+
93
+  // 提交
94
+  submitGm(record) {
95
+    // 网路请求
96
+    request({ ...apis.customer.consultantAssist, urlData: { id: this.state.visibleData.customerId }, data: { userId: record.userId } }).then(res => {
97
+      // eslint-disable-next-line no-unused-expressions
98
+      this.openNotificationWithIcon('success', '操作成功')
99
+      this.handleCancel()
100
+    }).catch(err => {
101
+      // eslint-disable-next-line no-unused-expressions
102
+      this.openNotificationWithIcon('error', err)
103
+    })
104
+  }
105
+
106
+  render() {
107
+    const columns = [
108
+      // {
109
+      //   title: '编号',
110
+      //   dataIndex: 'userId',
111
+      //   key: 'userId',
112
+      // },
113
+      {
114
+        title: '姓名',
115
+        dataIndex: 'userName',
116
+        key: 'userName',
117
+      },
118
+      {
119
+        title: '电话',
120
+        dataIndex: 'phone',
121
+        key: 'phone',
122
+      },
123
+      {
124
+        title: '部门',
125
+        dataIndex: 'department',
126
+        key: 'department',
127
+      },
128
+      {
129
+        title: '岗位',
130
+        dataIndex: 'position',
131
+        key: 'position',
132
+      },
133
+      {
134
+        title: '操作',
135
+        dataIndex: 'personId',
136
+        key: 'personId',
137
+        // eslint-disable-next-line no-nested-ternary
138
+        render: (_, record) => <>{ <Button type="danger" onClick={() => this.submitGm(record)}>确定</Button>}</>, },
139
+    ]
140
+    return (
141
+      <>
142
+        <Modal
143
+            title="分配置业顾问"
144
+            width={800}
145
+            destroyOnClose="true"
146
+            footer={null}
147
+            visible={this.state.visibleData.visible}
148
+            onCancel={(e) => this.handleCancel(e)}
149
+          >
150
+            <BuildSelect onChange={this.changBuilding.bind(this)} value={this.state.visibleData.buildingName} />
151
+            <Table rowKey="assistConsultant" dataSource={this.state.dataSource.records} columns={columns} pagination={{ total: this.state.dataSource.total, onChange: e => this.onChange(e) }} />
152
+          </Modal>
153
+      </>
154
+    );
155
+  }
156
+}
157
+
158
+export default ModalAttribution

+ 10
- 1
src/pages/customer/customerlist/customerDetail.jsx View File

5
 import apis from '../../../services/apis';
5
 import apis from '../../../services/apis';
6
 import request from '../../../utils/request';
6
 import request from '../../../utils/request';
7
 import moment from 'moment';
7
 import moment from 'moment';
8
+import BuildSelect from '../../../components/SelectButton/BuildSelect'
8
 
9
 
9
 import router from 'umi/router';
10
 import router from 'umi/router';
10
 
11
 
19
   const [tableData, setTableDataData] = useState([{}])
20
   const [tableData, setTableDataData] = useState([{}])
20
   const [dataConsultant, setDataonsultant] = useState({})
21
   const [dataConsultant, setDataonsultant] = useState({})
21
   const [intentionData, setIntentionData] = useState([])
22
   const [intentionData, setIntentionData] = useState([])
23
+  const [buildingIdValue, setBuildingIdData] = useState()
22
 
24
 
23
   // eslint-disable-next-line react-hooks/rules-of-hooks
25
   // eslint-disable-next-line react-hooks/rules-of-hooks
24
   useEffect(() => {
26
   useEffect(() => {
71
       setDataonsultant(res.geoInfo)
73
       setDataonsultant(res.geoInfo)
72
     })
74
     })
73
   }
75
   }
76
+
77
+  function changBuilding(buildingId) {
78
+    setBuildingIdData(buildingId)
79
+    getById({ pageNumber: 1, pageSize: 10, buildingId: buildingId })
80
+  }
81
+
74
   const columns = [
82
   const columns = [
75
     {
83
     {
76
       title: '访问事件',
84
       title: '访问事件',
190
       </div>
198
       </div>
191
       <div className={styles.recordBox}>
199
       <div className={styles.recordBox}>
192
         <p className={styles.tableName}>访问记录</p>
200
         <p className={styles.tableName}>访问记录</p>
193
-        <Table dataSource={tableData.records} columns={columns} pagination={{ pageSize: 10, total: tableData.total, onChange }} />
201
+        <BuildSelect onChange={changBuilding} value={buildingIdValue} />
202
+        <Table dataSource={tableData.records} columns={columns} style={{marginTop: '15px'}} pagination={{ pageSize: 10, total: tableData.total, onChange }} />
194
         {/* <Pagination showQuickJumper defaultCurrent={1} total={data.records} onChange={e => changePageNum(e)} current={data.visitRecords.total}/> */}
203
         {/* <Pagination showQuickJumper defaultCurrent={1} total={data.records} onChange={e => changePageNum(e)} current={data.visitRecords.total}/> */}
195
       </div>
204
       </div>
196
 
205
 

+ 26
- 0
src/pages/customer/customerlist/index.jsx View File

7
 import router from 'umi/router';
7
 import router from 'umi/router';
8
 
8
 
9
 import Attribution from './components/attribution'
9
 import Attribution from './components/attribution'
10
+import AssistConsultant from './components/assistConsultant'
10
 import IntegralRecord from './components/integralRecord'
11
 import IntegralRecord from './components/integralRecord'
11
 import ModalRecommendRecord from './components/recommend'
12
 import ModalRecommendRecord from './components/recommend'
12
 import ChangeStatus from './components/changeStatus'
13
 import ChangeStatus from './components/changeStatus'
13
 import BuildSelect from '../../../components/SelectButton/BuildSelect'
14
 import BuildSelect from '../../../components/SelectButton/BuildSelect'
14
 import AuthButton from '@/components/AuthButton';
15
 import AuthButton from '@/components/AuthButton';
16
+import WxDictSelect from '@/components/SelectButton/WxDictSelect';
15
 
17
 
16
 
18
 
17
 const { Option } = Select;
19
 const { Option } = Select;
54
   // 推荐客户
56
   // 推荐客户
55
   const [recommendVisibleData, setRecommendVisibleData] = useState({ visible: false, customerId: '' })
57
   const [recommendVisibleData, setRecommendVisibleData] = useState({ visible: false, customerId: '' })
56
 
58
 
59
+  const [assistVisibleData, setAssistVisibleData] = useState({visible: false, customerId: ''})
60
+
57
   // eslint-disable-next-line react-hooks/rules-of-hooks
61
   // eslint-disable-next-line react-hooks/rules-of-hooks
58
   useEffect(() => {
62
   useEffect(() => {
59
     getList({ pageNumber: 1, pageSize: 10, customerType })
63
     getList({ pageNumber: 1, pageSize: 10, customerType })
159
     setStatusVisibleData({ visible: false, customerId: '', status: '' })
163
     setStatusVisibleData({ visible: false, customerId: '', status: '' })
160
     setRecommendVisibleData({ visible: true, customerId: personId })
164
     setRecommendVisibleData({ visible: true, customerId: personId })
161
   }
165
   }
166
+
167
+  //分配置业顾问
168
+  function assistConsultant(personId) {
169
+    setGVisibleData({ visible: false, customerId: '', realtyConsultant: '', buildingId: '' })
170
+    setRecordVisibleData({ visible: false, customerId: '' })
171
+    setStatusVisibleData({ visible: false, customerId: '' })
172
+    setRecommendVisibleData({ visible: false, customerId: '' })
173
+    setAssistVisibleData({ visible: true, customerId: personId })
174
+  }
175
+
162
   function toCustomerDateil(record) {
176
   function toCustomerDateil(record) {
163
     router.push({
177
     router.push({
164
       pathname: '/customer/customerlist/customerDetail',
178
       pathname: '/customer/customerlist/customerDetail',
211
     setGVisibleData({ visible: false, customerId: '', realtyConsultant: '', buildingId: '' })
225
     setGVisibleData({ visible: false, customerId: '', realtyConsultant: '', buildingId: '' })
212
     setStatusVisibleData({ visible: false, customerId: '', status: '' })
226
     setStatusVisibleData({ visible: false, customerId: '', status: '' })
213
     setRecommendVisibleData({ visible: false, customerId: '' })
227
     setRecommendVisibleData({ visible: false, customerId: '' })
228
+    setAssistVisibleData({ visible: false, customerId: ''})
214
     getList({ pageNum: 1, pageSize: 10, customerType, ...props.form.getFieldsValue() })
229
     getList({ pageNum: 1, pageSize: 10, customerType, ...props.form.getFieldsValue() })
215
   }
230
   }
216
 
231
 
271
           <AuthButton name="admin.customer.recommend" noRight={null}>
286
           <AuthButton name="admin.customer.recommend" noRight={null}>
272
             <Button className={customerType === 'private' ? Styles.displayS : Styles.text } type="link" onClick={() => showRecommend(record.personId)}>推荐客户</Button>
287
             <Button className={customerType === 'private' ? Styles.displayS : Styles.text } type="link" onClick={() => showRecommend(record.personId)}>推荐客户</Button>
273
           </AuthButton>
288
           </AuthButton>
289
+          <AuthButton name="admin.customer.assign" noRight={null}>
290
+            <Button className={customerType === 'private' ? Styles.displayS : Styles.text } type="link" onClick={() => assistConsultant(record.personId)}>分配置业顾问</Button>
291
+          </AuthButton>
274
         </>
292
         </>
275
       ),
293
       ),
276
     },
294
     },
425
             <Input placeholder="置业顾问电话" />,
443
             <Input placeholder="置业顾问电话" />,
426
           )}
444
           )}
427
         </Form.Item>}
445
         </Form.Item>}
446
+        <Form.Item>
447
+          {getFieldDecorator('sceneType')(
448
+            <WxDictSelect />,
449
+          )}
450
+        </Form.Item>
428
         <Form.Item>
451
         <Form.Item>
429
             <AuthButton name="admin.customer.recommend.search" noRight={null}>
452
             <AuthButton name="admin.customer.recommend.search" noRight={null}>
430
               <Button type="primary" htmlType="submit" >
453
               <Button type="primary" htmlType="submit" >
476
 
499
 
477
       {/* 推荐客户 */}
500
       {/* 推荐客户 */}
478
       <ModalRecommendRecord visibleData={recommendVisibleData} onCancel={() => closeAll()}/>
501
       <ModalRecommendRecord visibleData={recommendVisibleData} onCancel={() => closeAll()}/>
502
+
503
+      {/* 分配置业顾问 */}
504
+      <AssistConsultant visibleData={assistVisibleData} onCancel={() => closeAll()}/>
479
     </>
505
     </>
480
   );
506
   );
481
 }
507
 }

+ 10
- 1
src/pages/customer/customerlist/publicCustomerDetail.jsx View File

5
 import apis from '../../../services/apis';
5
 import apis from '../../../services/apis';
6
 import request from '../../../utils/request';
6
 import request from '../../../utils/request';
7
 import moment from 'moment';
7
 import moment from 'moment';
8
+import BuildSelect from '../../../components/SelectButton/BuildSelect'
8
 
9
 
9
 import router from 'umi/router';
10
 import router from 'umi/router';
10
 
11
 
19
   const [tableData, setTableDataData] = useState([{ }])
20
   const [tableData, setTableDataData] = useState([{ }])
20
   const [dataConsultant, setDataonsultant] = useState({})
21
   const [dataConsultant, setDataonsultant] = useState({})
21
   const [intentionData, setIntentionData] = useState([])
22
   const [intentionData, setIntentionData] = useState([])
23
+  const [buildingIdValue, setBuildingIdData] = useState()
22
 
24
 
23
   // eslint-disable-next-line react-hooks/rules-of-hooks
25
   // eslint-disable-next-line react-hooks/rules-of-hooks
24
   useEffect(() => {
26
   useEffect(() => {
72
       setDataonsultant(res.geoInfo)
74
       setDataonsultant(res.geoInfo)
73
     })
75
     })
74
   }
76
   }
77
+
78
+  function changBuilding(buildingId) {
79
+    setBuildingIdData(buildingId)
80
+    getById({ pageNumber: 1, pageSize: 10, buildingId: buildingId })
81
+  }
82
+
75
   const columns = [
83
   const columns = [
76
     {
84
     {
77
       title: '访问事件',
85
       title: '访问事件',
158
       </div>
166
       </div>
159
       <div className={publicStyle.recordBox}>
167
       <div className={publicStyle.recordBox}>
160
         <p className={publicStyle.tableName}>访问记录</p>
168
         <p className={publicStyle.tableName}>访问记录</p>
161
-        <Table dataSource={tableData.records} columns={columns} pagination={{ pageSize: 10, total: tableData.total, onChange }} />
169
+        <BuildSelect onChange={changBuilding} value={buildingIdValue} />
170
+        <Table dataSource={tableData.records} columns={columns} style={{marginTop: '15px'}} pagination={{ pageSize: 10, total: tableData.total, onChange }} />
162
       </div>
171
       </div>
163
     </>
172
     </>
164
   )
173
   )

+ 53
- 5
src/pages/customer/drift/index.jsx View File

1
 import React, { useState, useEffect } from 'react';
1
 import React, { useState, useEffect } from 'react';
2
-import { Table, Avatar, Alert } from 'antd';
2
+import { Form, Table, Avatar, Alert, Select, Button } from 'antd';
3
 
3
 
4
 import request from '../../../utils/request';
4
 import request from '../../../utils/request';
5
 import apis from '../../../services/apis';
5
 import apis from '../../../services/apis';
6
 import Styles from './style.less'
6
 import Styles from './style.less'
7
+import WxDictSelect from '@/components/SelectButton/WxDictSelect';
7
 
8
 
8
-function costomerDrift() {
9
+function costomerDrift(props) {
10
+  const { getFieldDecorator } = props.form
9
   // eslint-disable-next-line react-hooks/rules-of-hooks
11
   // eslint-disable-next-line react-hooks/rules-of-hooks
10
   const [dataSources, setDataSources] = useState({ records: [] })
12
   const [dataSources, setDataSources] = useState({ records: [] })
11
 
13
 
37
     getList({ pageNumber: pageNum, pageSize: 10 })
39
     getList({ pageNumber: pageNum, pageSize: 10 })
38
   }
40
   }
39
 
41
 
42
+  //重置搜索
43
+  function handleReset() {
44
+    props.form.resetFields();
45
+    getList({ pageNumber: '1', pageSize: '10' })
46
+  }
47
+
48
+  // 提交事件
49
+  function handleSubmit(e) {
50
+    e.preventDefault();
51
+    props.form.validateFields((err, values) => {
52
+      if (!err) {
53
+        console.log('提交数据: ', values)
54
+        const { startDate } = values
55
+        getList({ pageNum: 1, pageSize: 10, ...values })
56
+      }
57
+    });
58
+  }
59
+
40
   const columns = [
60
   const columns = [
41
     {
61
     {
42
       title: '头像',
62
       title: '头像',
56
       // eslint-disable-next-line no-nested-ternary
76
       // eslint-disable-next-line no-nested-ternary
57
       render: (_, record) => <><span>{ record.gender === '1' ? '男' : record.gender === '2' ? '女' : '未知' }</span></>,
77
       render: (_, record) => <><span>{ record.gender === '1' ? '男' : record.gender === '2' ? '女' : '未知' }</span></>,
58
     },
78
     },
79
+    {
80
+      title: '用户来源',
81
+      dataIndex: 'sceneAlias',
82
+      key: 'sceneAlias',
83
+      render: (_, record) => <><span>{ record.sceneAlias ? record.sceneAlias : '其他'}</span></>,
84
+    },
59
   ];
85
   ];
60
-
86
+  
61
   return (
87
   return (
88
+    <>
89
+      <Form layout="inline" onSubmit={e => handleSubmit(e, props)}>
90
+        <Form.Item>
91
+          {getFieldDecorator('sceneType')(
92
+            <WxDictSelect />,
93
+          )}
94
+        </Form.Item>
95
+
96
+        <Form.Item>
97
+            {/* <AuthButton name="admin.customer.recommend.search" noRight={null}> */}
98
+            <Button type="primary" htmlType="submit" >
99
+              查询
100
+            </Button>
101
+            {/* </AuthButton> */}
102
+            <Button style={{ marginLeft: 8 }} onClick={handleReset}>
103
+              重置
104
+            </Button>
105
+        </Form.Item>
106
+      </Form>
107
+      <Table dataSource={dataSources.records} rowKey="drift" columns={columns} pagination={{ total: dataSources.total, onChange }} />
108
+    </>
62
     // eslint-disable-next-line max-len
109
     // eslint-disable-next-line max-len
63
-    <Table dataSource={dataSources.records} rowKey="drift" columns={columns} pagination={{ total: dataSources.total, onChange }} />
110
+    
64
   )
111
   )
65
 }
112
 }
66
 
113
 
67
-export default costomerDrift
114
+const WrappedBody = Form.create()(costomerDrift);
115
+export default WrappedBody

+ 11
- 4
src/pages/indexEcharts/components/IntentionalCustomers.jsx View File

10
   const [data, setData] = useState({ records: [] })
10
   const [data, setData] = useState({ records: [] })
11
   const [buildingId, setBuildingId] = useState('')
11
   const [buildingId, setBuildingId] = useState('')
12
   useEffect(() => {
12
   useEffect(() => {
13
-    IntentionUsers()
13
+    IntentionUsers({ pageNum: 1, pageSize: 5 })
14
     // getUserBehaviorProfile(formatDate(props.startDate, props.endDate))
14
     // getUserBehaviorProfile(formatDate(props.startDate, props.endDate))
15
 
15
 
16
   }, [])
16
   }, [])
17
   function IntentionUsers (params) {
17
   function IntentionUsers (params) {
18
     request({
18
     request({
19
       ...apis.indexEcharts.intentionUsers,
19
       ...apis.indexEcharts.intentionUsers,
20
-      params: { pageSize: 9999, ...params }
20
+      params: { ...params }
21
     }).then((data) => {
21
     }).then((data) => {
22
+      console.log(data,"datadata")
22
       setData(data)
23
       setData(data)
23
     })
24
     })
24
   }
25
   }
25
 
26
 
27
+  // 分页
28
+  function onChange(pageNum) {
29
+    // eslint-disable-next-line react-hooks/rules-of-hooks
30
+    IntentionUsers({ pageNum: pageNum, pageSize: 5, buildingId })
31
+  }
32
+
26
   // getIntentionUsers({ commit }, payload) {
33
   // getIntentionUsers({ commit }, payload) {
27
   //   return new Promise((resolve, reject) => {
34
   //   return new Promise((resolve, reject) => {
28
   //     request({
35
   //     request({
78
   ];
85
   ];
79
 
86
 
80
   function handleBuildingChange (e) {
87
   function handleBuildingChange (e) {
81
-    IntentionUsers({ buildingId: e })
88
+    IntentionUsers({  pageNum: 1, pageSize: 5, buildingId: e })
82
     setBuildingId(e)
89
     setBuildingId(e)
83
   }
90
   }
84
   return (
91
   return (
88
 
95
 
89
         <BuildSelect slot='action' onChange={(e => handleBuildingChange(e))} value={buildingId}></BuildSelect>
96
         <BuildSelect slot='action' onChange={(e => handleBuildingChange(e))} value={buildingId}></BuildSelect>
90
 
97
 
91
-        <Table rowKey="IntentionalCustomers" dataSource={data.records} columns={columns} style={{marginTop:'15px'}} pagination={false} scroll={{ y: 500 }} />
98
+        <Table rowKey="IntentionalCustomers" dataSource={data.records} columns={columns} style={{marginTop:'15px'}} pagination={{ total: data.total, defaultPageSize: 5, onChange: e => onChange(e) }} scroll={{ y: 500 }} />
92
 
99
 
93
       </div>
100
       </div>
94
 
101
 

+ 289
- 0
src/pages/indexEcharts/components/UserBehaviorIndex.jsx View File

1
+import React, { Component, useState, useEffect } from 'react';
2
+import EChart from '../../../components/EchartsTest/EChart';
3
+import request from '../../../utils/request';
4
+import apis from '../../../services/apis';
5
+import moment from 'moment';
6
+import router from 'umi/router';
7
+import 'echarts/lib/component/dataZoom'
8
+import { Table, Select, Row, Col, Menu, Dropdown, Button, Icon, message, Modal } from 'antd';
9
+import BuildSelect from '../../../components/SelectButton/BuildSelect'
10
+
11
+const { Option } = Select;
12
+
13
+
14
+const eventcolumns = [
15
+  {
16
+    title: '编号',
17
+    dataIndex: 'recordId',
18
+    key: 'recordId',
19
+    align: 'center',
20
+    width: '16%',
21
+  },
22
+  {
23
+    title: '访问时间',
24
+    dataIndex: 'visitTime',
25
+    key: 'visitTime',
26
+    align: 'center',
27
+    width: '18%',
28
+    render: (x, row) => (
29
+      <>
30
+        <span>{ moment(row.visitTime).format('YYYY-MM-DD hh:mm:ss') }</span>
31
+      </>
32
+    ),
33
+  },
34
+  {
35
+    title: '离开时间',
36
+    dataIndex: 'leaveTime',
37
+    key: 'leaveTime',
38
+    align: 'center',
39
+    width: '18%',
40
+    render: (x, row) => (
41
+      <>
42
+        <span>{ row.leaveTime && moment(row.leaveTime).format('YYYY-MM-DD hh:mm:ss') }</span>
43
+      </>
44
+    ),
45
+  },
46
+]
47
+
48
+
49
+class EventcoModal extends React.Component {
50
+  constructor(props) {
51
+    super(props)
52
+    this.state = {
53
+      eventList: [],
54
+      visibleData: { visible: false, row: {} },
55
+    }
56
+  }
57
+
58
+  componentDidUpdate(prevProps) {
59
+    if (this.props.visibleData.visible !== prevProps.visibleData.visible) {
60
+      // eslint-disable-next-line react/no-did-update-set-state
61
+      this.setState({ visibleData: this.props.visibleData }, () => {
62
+        this.showDetails(this.props.visibleData.row)
63
+      })
64
+    }
65
+  }
66
+
67
+  showDetails = row => {
68
+    request({
69
+      ...apis.indexEcharts.userBehavior.profile,
70
+      params: { event: row.event, personId: row.personId },
71
+    }).then(data => {
72
+        this.setState({ eventList: data })
73
+    })
74
+  }
75
+
76
+  handleOk = e => {
77
+    this.props.onSuccess()
78
+  };
79
+
80
+  handleCancel = e => {
81
+    this.props.onSuccess()
82
+  };
83
+
84
+  render() {
85
+    return (
86
+      <>
87
+        <Modal
88
+          title="访问详情"
89
+          visible={this.state.visibleData.visible}
90
+          onOk={() => this.handleOk()}
91
+          onCancel={() => this.handleCancel()}
92
+          footer={null}
93
+        >
94
+         <Table rowKey="UserBehavior" dataSource={this.state.eventList} columns={eventcolumns} pagination={false} rowKey="eventall" scroll={{ y: 400 }} />
95
+        </Modal>
96
+      </>
97
+    )
98
+  }
99
+}
100
+
101
+
102
+const formatDate = (start, end) => {
103
+  const startDate = `${moment(start).format('YYYY-MM-DDT00:00:00.000')}Z`
104
+  const endDate = `${moment(end).format('YYYY-MM-DDT23:59:59.999')}Z`
105
+  return { startDate, endDate }
106
+}
107
+const UserBehaviorIndex = props => {
108
+  const [data, setData] = useState({ records: [] })
109
+  const [visibleData, setVisibleData] = useState({ visible: false, row: {} })
110
+  const [buildingId, setBuildingId] = useState('')
111
+
112
+  // 柱图
113
+  useEffect(() => {
114
+    const date = formatDate(props.startDate, props.endDate)
115
+    getUserBehaviorSummary({
116
+      ...date,
117
+      activity: props.activity,
118
+      event: props.event,
119
+      eventType: props.eventType,
120
+      buildingId: props.buildingId,
121
+    })
122
+    // getUserBehaviorProfile(formatDate(props.startDate, props.endDate))
123
+  }, [props.startDate, props.endDate, props.activity, props.event, props.eventType, props.buildingId])
124
+
125
+  const [recordList, setList] = useState([])
126
+  function getUserBehaviorSummary(params) {
127
+    request({
128
+      ...apis.indexEcharts.userBehavior.tsUserBehavior,
129
+      params,
130
+    }).then(data => {
131
+      setData(data || {})
132
+      // setList((data.data.records || []).filter(e => e.activity !== '客户'))
133
+    })
134
+  }
135
+
136
+
137
+  const seriesMaker = (data.selectUserBehavior || []).filter(e => e.activity !== '客户' && e.activity !== '首页').reduce((series, item) => {
138
+    let { date, activityCount, activity } = item
139
+    date = moment(date).format('YYYY-MM-DD')
140
+    if (!activityCount) activityCount = 0
141
+
142
+    // 使用对象, 可以去重
143
+    series[`${activity}`] = (series[`${activity}`] || []).concat([[date, activityCount]])
144
+
145
+    return series;
146
+  }, {})
147
+
148
+
149
+  const dataZoom = props.dataZoom ? [
150
+    {
151
+      type: 'inside',
152
+      start: 0,
153
+      end: 100,
154
+    },
155
+    {
156
+      type: 'slider',
157
+      start: 0,
158
+      end: 100,
159
+    },
160
+  ] : undefined
161
+
162
+
163
+  const options = {
164
+    title: {},
165
+    icon: 'rect',
166
+    legend: {
167
+      show: true,
168
+      zlevel: 10,
169
+      itemGap: 100,
170
+    },
171
+    color: ['#F12B3E', '#FE929C', '#647CE1', '#A2B9FF', '#FF844F', '#FFBB9D'],
172
+    tooltip: {
173
+      trigger: 'axis',
174
+    },
175
+    xAxis: { type: 'category' },
176
+    yAxis: {},
177
+    dataZoom,
178
+    series: Object.keys(seriesMaker).map(x => ({
179
+        type: 'line',
180
+        smooth: true,
181
+        name: x,
182
+        data: seriesMaker[x],
183
+      })),
184
+  }
185
+  function handleBuildingChange(e) {
186
+    const date = formatDate(props.startDate, props.endDate)
187
+    getUserBehaviorSummary({
188
+      ...date,
189
+      activity: props.activity,
190
+      event: props.event,
191
+      eventType: props.eventType,
192
+      buildingId: e,
193
+    })
194
+    setBuildingId(e)
195
+  }
196
+
197
+  function showDetails(row) {
198
+    setVisibleData({ visible: true, row })
199
+  }
200
+
201
+  function onSuccess() {
202
+    setVisibleData({ visible: false, row: {} })
203
+  }
204
+
205
+
206
+  const style = {
207
+    width: '100%',
208
+    height: '400px',
209
+
210
+  }
211
+
212
+  const columns = [
213
+    {
214
+      title: '访问事件',
215
+      dataIndex: 'eventName',
216
+      key: 'eventName',
217
+      align: 'center',
218
+      width: '16%',
219
+
220
+    },
221
+    {
222
+      title: '访问用户',
223
+      dataIndex: 'userName',
224
+      key: 'userName',
225
+      align: 'center',
226
+      width: '15%',
227
+
228
+    },
229
+    {
230
+      title: '访问次数',
231
+      dataIndex: 'accessCount',
232
+      key: 'accessCount',
233
+      align: 'center',
234
+      width: '17%',
235
+
236
+      render: (x, row) => (
237
+        <>
238
+          <span style={{ color: '#EF273A', cursor: 'pointer' }} onClick={() => showDetails(row)}> {row.accessCount}</span>
239
+        </>
240
+      ),
241
+    },
242
+    {
243
+      title: '首次访问时间',
244
+      dataIndex: 'visitTime',
245
+      key: 'visitTime',
246
+      align: 'center',
247
+      width: '18%',
248
+      render: (x, row) => (
249
+        <>
250
+          <span>{ row.visitTime && moment(row.visitTime).format('YYYY-MM-DD hh:mm:ss') }</span>
251
+        </>
252
+      ),
253
+    },
254
+    {
255
+      title: '离开时间',
256
+      dataIndex: 'leaveTime',
257
+      key: 'leaveTime',
258
+      width: '18%',
259
+      align: 'center',
260
+      render: (x, row) => (
261
+        <>
262
+          <span>{ row.leaveTime && moment(row.leaveTime).format('YYYY-MM-DD hh:mm:ss') }</span>
263
+        </>
264
+      ),
265
+    },
266
+  ]
267
+
268
+
269
+  return (
270
+    <>
271
+      <div>
272
+        {/* <p onClick={() => router.push('/indexEcharts/userBehavior')} style={{cursor: 'pointer'}}> */}
273
+          <span style={{ borderBottom: '1px solid #f02d40', color: '#333', fontSize: '0.12rem', fontWeight: '600' }}>用户行为</span>
274
+          {!props.BuildSelectHide && <span style={{ fontSize: '0.09rem', color: '#888', marginLeft: '0.06rem' }}>最近七天</span>}
275
+        {/* </p> */}
276
+        <div style={{ float: 'right', marginTop: '-40px', marginBottom: '20px' }}>
277
+          {!props.BuildSelectHide && <BuildSelect slot="action" onChange={(e => handleBuildingChange(e))} value={buildingId}></BuildSelect>}
278
+        </div>
279
+        <EChart options={options} style={style} />
280
+        {false &&
281
+          <Table rowKey="UserBehaviorTwo" dataSource={recordList} columns={columns} pagination={false} rowKey="userbehavior" scroll={{ y: 500 }} />
282
+        }
283
+      </div>
284
+      <EventcoModal visibleData={visibleData} onSuccess={() => onSuccess()} />
285
+    </>
286
+  )
287
+}
288
+
289
+export default UserBehaviorIndex

+ 1
- 7
src/pages/indexEcharts/components/UserConversion.jsx View File

79
       radius: ['34%', '52%'],
79
       radius: ['34%', '52%'],
80
       avoidLabelOverlap: false,
80
       avoidLabelOverlap: false,
81
       label: {
81
       label: {
82
-        normal: {
83
-          show: false,
84
-          position: 'center',
85
-          color: '#666666',
86
-          fontSize: 22,
87
-          formatter: '{d}%'
88
-        },
82
+        formatter: '{b} {@value}',
89
         emphasis: {
83
         emphasis: {
90
           show: true,
84
           show: true,
91
           formatter: '{d}%',
85
           formatter: '{d}%',

+ 3
- 0
src/pages/indexEcharts/components/UserSex.jsx View File

51
       name: '性别比例',
51
       name: '性别比例',
52
       center: ['44%', '65%'],
52
       center: ['44%', '65%'],
53
       radius: ['34%', '52%'],
53
       radius: ['34%', '52%'],
54
+      label: {
55
+        formatter: '{b} {@value}',
56
+      },
54
       data:
57
       data:
55
         dataset,
58
         dataset,
56
     }
59
     }

+ 20
- 12
src/pages/indexEcharts/components/UserSource.jsx View File

16
 }
16
 }
17
 
17
 
18
 const UserSource = (props) => {
18
 const UserSource = (props) => {
19
-  const [data, setData] = useState({ records: [] })
19
+  const [xData, setxData] = useState([])
20
+  const [fromData, setFromData] = useState([])
21
+  const [registerData, setRegisterData] = useState([])
20
   //柱图
22
   //柱图
21
   useEffect(() => {
23
   useEffect(() => {
22
     userResource(formatDate(props.startDate, props.endDate))
24
     userResource(formatDate(props.startDate, props.endDate))
24
 
26
 
25
   function userResource(params) {
27
   function userResource(params) {
26
     request({
28
     request({
27
-      ...apis.indexEcharts.userResource,
29
+      ...apis.indexEcharts.selectPersonFrom,
28
       params,
30
       params,
29
     }).then((data) => {
31
     }).then((data) => {
30
-      setData(data)
31
-      console.log(data,"datadatadatadatavvvdatadatav")
32
+      console.log(data,"222222")
33
+      setxData(data.tdWxDicts.map(x =>  x.sceneAlias))
34
+      setFromData(data.tdWxDicts.map(x => x.fromData))
35
+      setRegisterData(data.tdWxDicts.map(x => x.registerSum))
32
       props.onSuccess(data)
36
       props.onSuccess(data)
33
     })
37
     })
34
   }
38
   }
35
 
39
 
36
-  const dataset = data || {};
37
-  const source = dataset.columnar || [];
38
   const subtitle = '最近7天';
40
   const subtitle = '最近7天';
39
   const baroptions = {
41
   const baroptions = {
40
     title: { },
42
     title: { },
41
-    xAxis: { type: 'category' },
43
+    xAxis: { 
44
+              type: 'category',
45
+              data: xData,
46
+              axisLabel: {rotate: 45}
47
+            },
42
     legend: {
48
     legend: {
43
       left: '20%',
49
       left: '20%',
44
       data: ['所有用户', '注册用户']
50
       data: ['所有用户', '注册用户']
51
       {
57
       {
52
         type: 'bar', name: '所有用户', datasetIndex: 0,
58
         type: 'bar', name: '所有用户', datasetIndex: 0,
53
         barWidth: 20,
59
         barWidth: 20,
60
+        data: fromData,
54
         itemStyle: {
61
         itemStyle: {
55
           normal: {
62
           normal: {
56
             barBorderRadius: [20, 20, 0, 0],
63
             barBorderRadius: [20, 20, 0, 0],
70
         type: 'bar',
77
         type: 'bar',
71
         name: '注册用户',
78
         name: '注册用户',
72
         barWidth: 20,
79
         barWidth: 20,
80
+        data: registerData,
73
         itemStyle: {
81
         itemStyle: {
74
           normal: {
82
           normal: {
75
             barBorderRadius: [20, 20, 0, 0],
83
             barBorderRadius: [20, 20, 0, 0],
87
 
95
 
88
       },
96
       },
89
     ],
97
     ],
90
-    dataset: {
91
-      id: 'bar',
92
-      dimensions: ['fromName', 'userCount', 'registered'],
93
-      source: source,
94
-    },
98
+    // dataset: {
99
+    //   id: 'bar',
100
+    //   dimensions: ['fromName', 'userCount', 'registered'],
101
+    //   source: source,
102
+    // },
95
   }
103
   }
96
 
104
 
97
 
105
 

+ 139
- 0
src/pages/indexEcharts/components/UserSourceDetail.jsx View File

1
+import React, { Component, useState, useEffect } from 'react';
2
+import echarts from 'echarts/lib/echarts';
3
+import EChart from '../../../components/EchartsTest/EChart';
4
+import request from '../../../utils/request';
5
+import apis from '../../../services/apis';
6
+import moment from 'moment';
7
+import router from 'umi/router';
8
+import { Table, Select, Row, Col, Menu, Dropdown, Button, Icon, message } from 'antd';
9
+
10
+import styles from '../styles.less'
11
+
12
+const formatDate = (start, end) => {
13
+  const startDate = moment(start).format('YYYY-MM-DDT00:00:00.000') + 'Z'
14
+  const endDate = moment(end).format('YYYY-MM-DDT23:59:59.999') + 'Z'
15
+  return { startDate, endDate }
16
+}
17
+
18
+const UserSourceDetail = (props) => {
19
+  const [xData, setxData] = useState([])
20
+  const [fromData, setFromData] = useState([])
21
+  const [registerData, setRegisterData] = useState([])
22
+  //柱图
23
+  useEffect(() => {
24
+    userResource(formatDate(props.startDate, props.endDate))
25
+  }, [props.startDate, props.endDate])
26
+
27
+  function userResource(params) {
28
+    request({
29
+      ...apis.indexEcharts.selectPersonFromGroupByDay,
30
+      params,
31
+    }).then((data) => {
32
+      setxData(data.map(x =>  x.createTime))
33
+      setFromData(data.map(x => x.fromNum))
34
+      setRegisterData(data.map(x => x.registeredNum))
35
+      props.onSuccess(data)
36
+    })
37
+  }
38
+
39
+  const subtitle = '最近7天';
40
+  const baroptions = {
41
+    title: {
42
+    },
43
+    tooltip: {
44
+        trigger: 'axis'
45
+    },
46
+    legend: {
47
+        data: ['新用户数', '授权注册']
48
+    },
49
+    toolbox: {
50
+        show: true,
51
+        feature: {
52
+            dataZoom: {
53
+                yAxisIndex: 'none'
54
+            },
55
+            dataView: {readOnly: false},
56
+            magicType: {type: ['line', 'bar']},
57
+            restore: {},
58
+            saveAsImage: {}
59
+        }
60
+    },
61
+    xAxis: {
62
+        type: 'category',
63
+        boundaryGap: false,
64
+        data: xData
65
+    },
66
+    yAxis: {
67
+        type: 'value',
68
+        axisLabel: {
69
+            formatter: '{value} °C'
70
+        }
71
+    },
72
+    series: [
73
+        {
74
+            name: '新用户数',
75
+            type: 'line',
76
+            data: fromData,
77
+            markPoint: {
78
+                data: [
79
+                    {type: 'max', name: '最大值'},
80
+                    {type: 'min', name: '最小值'}
81
+                ]
82
+            },
83
+            markLine: {
84
+                data: [
85
+                    {type: 'average', name: '平均值'}
86
+                ]
87
+            }
88
+        },
89
+        {
90
+            name: '授权注册',
91
+            type: 'line',
92
+            data: registerData,
93
+            markPoint: {
94
+                data: [
95
+                    {name: '周最低', value: -2, xAxis: 1, yAxis: -1.5}
96
+                ]
97
+            },
98
+            markLine: {
99
+                data: [
100
+                    {type: 'average', name: '平均值'},
101
+                    [{
102
+                        symbol: 'none',
103
+                        x: '90%',
104
+                        yAxis: 'max'
105
+                    }, {
106
+                        symbol: 'circle',
107
+                        label: {
108
+                            position: 'start',
109
+                            formatter: '最大值'
110
+                        },
111
+                        type: 'max',
112
+                        name: '最高点'
113
+                    }]
114
+                ]
115
+            }
116
+        }
117
+    ]
118
+}
119
+
120
+  const barstyle = {
121
+    width: '100%',
122
+    height: '480px',
123
+    minWidth: '400px'
124
+  }
125
+
126
+  return (
127
+    <>
128
+      <div>
129
+      <p onClick={()=>router.push('/indexEcharts/userSource')}><span style={{borderBottom:'1px solid #f02d40',cursor: 'pointer',color:'#333',fontSize:'0.12rem',fontWeight:'600'}}>用户来源</span> {!props.BuildSelectHide && <span style={{ fontSize: '0.09rem', color: '#888', marginLeft: '0.06rem' }}>最近七天</span>}</p>
130
+
131
+        <EChart options={baroptions} style={barstyle} />
132
+
133
+      </div>
134
+
135
+    </>
136
+  )
137
+}
138
+
139
+export default UserSourceDetail;

+ 9
- 14
src/pages/indexEcharts/components/UserSourcepie.jsx View File

45
     legend: {
45
     legend: {
46
       orient: 'vertical',
46
       orient: 'vertical',
47
       x: 'left',
47
       x: 'left',
48
-      data: ['来源置业顾问', '来源全民经纪人', '自主进入'],
48
+      data: ['来源置业', '来源客户', '其他'],
49
     },
49
     },
50
     tooltip: {
50
     tooltip: {
51
       // trigger: 'item',
51
       // trigger: 'item',
53
     },
53
     },
54
     series: [
54
     series: [
55
       {
55
       {
56
+        name: '用户来源',
56
         type: 'pie',
57
         type: 'pie',
57
-        center: ['40%', '65%'],
58
-        radius: ['34%', '52%'],
58
+        center: ['50%', '65%'],
59
+        radius: ['25%', '40%'],
59
         label: {
60
         label: {
60
-          normal: {
61
-            show: false,
62
-            position: 'center',
63
-            color: '#666666',
64
-            fontSize: 22,
65
-            formatter: '{d}%'
66
-          },
61
+          formatter: '{b} {@value}',
67
           emphasis: {
62
           emphasis: {
68
             show: true,
63
             show: true,
69
             formatter: '{d}%',
64
             formatter: '{d}%',
71
               fontSize: '22',
66
               fontSize: '22',
72
               fontWeight: 'bold'
67
               fontWeight: 'bold'
73
             }
68
             }
74
-          }
69
+          },
75
         },
70
         },
76
       },
71
       },
77
 
72
 
80
     dataset: {
75
     dataset: {
81
       id: 'pie',
76
       id: 'pie',
82
       source: [
77
       source: [
83
-        { '用户来源': '来源置业顾问', value: person_realty_consultant, },
84
-        { '用户来源': '来源全民经纪人', value: person_estate_agent },
85
-        { '用户来源': '自主进入', value: person_null },
78
+        { '用户来源': '来源置业', value: person_realty_consultant, },
79
+        { '用户来源': '来源客户', value: person_estate_agent },
80
+        { '用户来源': '其他', value: person_null },
86
       ]
81
       ]
87
     },
82
     },
88
   }
83
   }

+ 2
- 2
src/pages/indexEcharts/index.jsx View File

6
 import apis from '../../services/apis';
6
 import apis from '../../services/apis';
7
 import UserSource from './components/UserSource.jsx';
7
 import UserSource from './components/UserSource.jsx';
8
 import UserSourcepie from './components/UserSourcepie.jsx';
8
 import UserSourcepie from './components/UserSourcepie.jsx';
9
-import UserBehavior from './components/UserBehavior.jsx';
9
+import UserBehaviorIndex from './components/UserBehaviorIndex.jsx';
10
 import UserActive from './components/UserActive';
10
 import UserActive from './components/UserActive';
11
 import UserSex from './components/UserSex';
11
 import UserSex from './components/UserSex';
12
 import NewUsers from './components/NewUsers'
12
 import NewUsers from './components/NewUsers'
56
       }
56
       }
57
       {checkData.includes('user_behavior') &&
57
       {checkData.includes('user_behavior') &&
58
         <div className={styles.behavior}>
58
         <div className={styles.behavior}>
59
-          <UserBehavior tableShow={false} endDate={endDate} startDate={startDate} dataZoom={false}></UserBehavior>
59
+          <UserBehaviorIndex tableShow={false} endDate={endDate} startDate={startDate} dataZoom={false}></UserBehaviorIndex>
60
         </div>
60
         </div>
61
       }
61
       }
62
       <div style={{ display: 'flex' }}>
62
       <div style={{ display: 'flex' }}>

+ 55
- 38
src/pages/indexEcharts/userSource.jsx View File

21
 // }
21
 // }
22
 
22
 
23
 let daterange = []
23
 let daterange = []
24
-let tableTitle = ['日期']
24
+let tableTitle = ['类型']
25
 
25
 
26
-const columns = [
26
+let columns = [
27
   {
27
   {
28
     title: '日期',
28
     title: '日期',
29
-    dataIndex: 'label',
30
-    key: 'label',
31
-    width:'20%'
29
+    dataIndex: 'createTime',
30
+    key: 'createTime',
32
   },
31
   },
33
-  {
34
-    title: '名片分享',
35
-    dataIndex: '名片分享',
36
-    key: '名片分享',
37
-  },
38
-  {
39
-    title: '生成海报',
40
-    dataIndex: '生成海报',
41
-    key: '生成海报',
42
-  },
43
-  {
44
-    title: '小程序搜索',
45
-    dataIndex: '小程序搜索',
46
-    key: '小程序搜索',
47
-  },
48
-  {
49
-    title: '好友分享',
50
-    dataIndex: '好友分享',
51
-    key: '好友分享',
52
-
53
-  },
54
-
55
-
32
+  // {
33
+  //   title: '名片分享',
34
+  //   dataIndex: '名片分享',
35
+  //   key: '名片分享',
36
+  // },
37
+  // {
38
+  //   title: '生成海报',
39
+  //   dataIndex: '生成海报',
40
+  //   key: '生成海报',
41
+  // },
42
+  // {
43
+  //   title: '小程序搜索',
44
+  //   dataIndex: '小程序搜索',
45
+  //   key: '小程序搜索',
46
+  // },
47
+  // {
48
+  //   title: '好友分享',
49
+  //   dataIndex: '好友分享',
50
+  //   key: '好友分享',
51
+  // },
56
 ]
52
 ]
57
 
53
 
54
+// let columns = [
55
+//   {
56
+//     title: '类型',
57
+//     dataIndex: 'value',
58
+//     key: 'value',
59
+//   }
60
+// ]
61
+
58
 class Header extends React.Component {
62
 class Header extends React.Component {
59
 
63
 
60
   constructor(props) {
64
   constructor(props) {
72
     this.setState({ endDate: new Date(), startDate: moment().subtract(7, 'day').toDate() })
76
     this.setState({ endDate: new Date(), startDate: moment().subtract(7, 'day').toDate() })
73
   }
77
   }
74
 
78
 
75
-
76
-
77
   formatDate = (start, end) => {
79
   formatDate = (start, end) => {
78
     const tempStartDate = `${moment(start).format('YYYY-MM-DDT00:00:00.000')}Z`
80
     const tempStartDate = `${moment(start).format('YYYY-MM-DDT00:00:00.000')}Z`
79
     const tempEndDate = `${moment(end).format('YYYY-MM-DDT23:59:59.999')}Z`
81
     const tempEndDate = `${moment(end).format('YYYY-MM-DDT23:59:59.999')}Z`
111
 
113
 
112
   onTabledatas = (e) => {
114
   onTabledatas = (e) => {
113
     console.log('this.state.userType: ', this.state.userType)
115
     console.log('this.state.userType: ', this.state.userType)
114
-    const data = (e.data || []).reduce((acc, item) => {
115
-      const { date, fromName, count, registered } = item
116
-      const num = this.state.userType === 'registered' ? registered : count
116
+    e.tdWxDicts.map(x => {
117
+        columns = columns.filter(y => y.key != x.sceneType).concat({
118
+          title: x.sceneAlias,
119
+          dataIndex: x.sceneType,
120
+          key: x.sceneType,
121
+        })
122
+    })
123
+    const data = (e.list || []).reduce((acc, item) => {
124
+      const { sceneType, fromNum, registeredNum, createTime } = item
125
+      const num = this.state.userType === 'registered' ? registeredNum : fromNum
126
+      acc[createTime] = { ...acc[createTime], ...item, [`${sceneType}`]: !num ? 0 : num }
127
+      return acc
128
+    }, {})
117
 
129
 
118
-      tableTitle = tableTitle.indexOf(fromName) > -1 ? tableTitle : tableTitle.concat(fromName) // eslint-disable-line
119
-      acc[date] = { ...acc[date], [`${fromName}`]: !num ? 0 : num }
130
+    const dictData =  e.tdWxDicts.reduce((acc,item,index) => {
131
+      const { sceneType } = item
132
+      acc[sceneType] = 0
133
+      return acc
134
+    },{})
120
 
135
 
136
+    const tableData = Object.keys(data).map(k => data[k]).reduce((acc,item,index) => {
137
+      acc[index] = { ...dictData, ...item }
121
       return acc
138
       return acc
122
-    }, {})
139
+    },[])
123
 
140
 
124
-    this.setState({ tableData: Object.keys(data).map(x => ({ label: x, ...data[x] })) })
141
+    this.setState({ tableData })
125
 
142
 
126
   }
143
   }
127
 
144
 
152
             Today: [moment(), moment()],
169
             Today: [moment(), moment()],
153
             'This Month': [moment().startOf('month'), moment().endOf('month')],
170
             'This Month': [moment().startOf('month'), moment().endOf('month')],
154
           }}
171
           }}
155
-          showTime
172
+          // showTime
156
           // format="YYYY/MM/DD HH:mm:ss"
173
           // format="YYYY/MM/DD HH:mm:ss"
157
           onChange={(_dates, dateStrings) => this.onChangetime(_dates, dateStrings)}
174
           onChange={(_dates, dateStrings) => this.onChangetime(_dates, dateStrings)}
158
         />
175
         />

+ 58
- 6
src/pages/news/list/editNewsList.jsx View File

7
 import router from 'umi/router';
7
 import router from 'umi/router';
8
 import BuildSelect from '../../../components/SelectButton/BuildSelect'
8
 import BuildSelect from '../../../components/SelectButton/BuildSelect'
9
 import NewsTypeSelect from '../../../components/SelectButton/NewTypeSelect'
9
 import NewsTypeSelect from '../../../components/SelectButton/NewTypeSelect'
10
-import XForm, { FieldTypes } from '../../../components/XForm';
10
+import  { FieldTypes, createForm } from '../../../components/XForm';
11
 import Wangedit from '../../../components/Wangedit/Wangedit'
11
 import Wangedit from '../../../components/Wangedit/Wangedit'
12
 import request from '../../../utils/request'
12
 import request from '../../../utils/request'
13
 import ImageUploader from '../../../components/XForm/ImageUpload';
13
 import ImageUploader from '../../../components/XForm/ImageUpload';
20
 
20
 
21
 const { MonthPicker, RangePicker, WeekPicker } = DatePicker;
21
 const { MonthPicker, RangePicker, WeekPicker } = DatePicker;
22
 const { TextArea } = Input;
22
 const { TextArea } = Input;
23
+
24
+let detailVisible = false;
25
+let urlVisible = false;
26
+
27
+const setExtraData = (data) => {
28
+  detailVisible = data.newsDetailType == '1'
29
+  urlVisible = data.newsDetailType == '0'
30
+}
31
+
32
+const handleFormValueChange = (props, changedValues, allValues) => {
33
+    setExtraData(allValues)
34
+}
35
+
36
+const XForm = createForm({ onValuesChange: handleFormValueChange })
37
+
23
 /**
38
 /**
24
  *
39
  *
25
  *
40
  *
30
   const [ tab, changeTab ] = useState('basic')
45
   const [ tab, changeTab ] = useState('basic')
31
   const newsId = props.location.query.newsId
46
   const newsId = props.location.query.newsId
32
   const [ dynamicData, setDynamicData ] = useState({})
47
   const [ dynamicData, setDynamicData ] = useState({})
33
-  
34
-  
48
+
35
     useEffect(() => {
49
     useEffect(() => {
36
       if(newsId){
50
       if(newsId){
37
         getDynamicData(newsId);
51
         getDynamicData(newsId);
41
   // 查询列表
55
   // 查询列表
42
   const getDynamicData = (newsId) => {
56
   const getDynamicData = (newsId) => {
43
     request({ ...apis.news.get, urlData: { id: newsId },}).then((data) => {
57
     request({ ...apis.news.get, urlData: { id: newsId },}).then((data) => {
44
-        setDynamicData(data)
58
+      setDynamicData(data)
59
+      detailVisible = data.newsDetailType == '1'
60
+      urlVisible = data.newsDetailType == '0'
45
     }).catch((err) => {
61
     }).catch((err) => {
46
       console.log(err)
62
       console.log(err)
47
       message.info(err.msg || err.message)
63
       message.info(err.msg || err.message)
48
     })
64
     })
49
     }
65
     }
50
 
66
 
51
-  
67
+  // const changeRadio = (e) => {
68
+  //   console.log(e.target.value,'eeee')
69
+  //   if(e.target.value == "1"){
70
+  //     detailVisible = true
71
+  //     urlVisible = false
72
+  //   }
73
+  //   if(e.target.value == "0"){
74
+  //     detailVisible = false
75
+  //     urlVisible = true
76
+  //   }
77
+  // }
52
 
78
 
53
   const cancelPage = () =>{
79
   const cancelPage = () =>{
54
     router.push({
80
     router.push({
103
       },
129
       },
104
       {
130
       {
105
         label: '资讯详情',
131
         label: '资讯详情',
132
+        name: 'newsDetailType',
133
+        render: <Radio.Group> 
134
+                <Radio value={1}>自定义</Radio>
135
+                <Radio value={0}>公众号链接</Radio>
136
+                </Radio.Group>,
137
+        value: dynamicData.newsDetailType,
138
+        rules: [
139
+          {required: true, message: '请选择资讯类型'},
140
+        ]
141
+      },
142
+      {
143
+        label: '详情内容',
106
         name: 'newsDetail',
144
         name: 'newsDetail',
107
         render: <Wangedit />,
145
         render: <Wangedit />,
146
+        hidden: () => !detailVisible,
108
         value: dynamicData.newsDetail,
147
         value: dynamicData.newsDetail,
148
+        rules: [
149
+          {required: true, message: '请输入详情内容'},
150
+        ]
151
+      },
152
+      {
153
+        label: '公众号链接',
154
+        name: 'newsDetail',
155
+        type: FieldTypes.Text,
156
+        hidden: () => !urlVisible,
157
+        value: dynamicData.newsDetail,
158
+        rules: [
159
+          {required: true, message: '请输入公众号链接'},
160
+        ]
109
       },
161
       },
110
     ]
162
     ]
111
   
163
   
138
       }
190
       }
139
     }
191
     }
140
     
192
     
141
-    return <XForm onSubmit={handleSubmit} onCancel={cancelPage} fields={fields}></XForm>
193
+    return <XForm onSubmit={handleSubmit} onCancel={cancelPage}  fields={fields}></XForm>
142
   }
194
   }
143
   
195
   
144
   const Poster = (props) => {
196
   const Poster = (props) => {

+ 1
- 1
src/pages/record/drainage/DrainageVisitRecordList.jsx View File

83
       dataIndex: 'personType',
83
       dataIndex: 'personType',
84
       key: 'personType',
84
       key: 'personType',
85
       align: 'center',
85
       align: 'center',
86
-      render: (text, record) => <span>{record.shareName ? record.consultantId === null || record.consultantId === '' ? '普通客户' : '置业顾问' : ''}</span>,
86
+      render: (text, record) => <span>{record.personType === 'Realty Consultant' ? '置业顾问' : '普通客户' }</span>,
87
     },
87
     },
88
   ];
88
   ];
89
   
89
   

+ 8
- 0
src/pages/staff/list/editStaff.jsx View File

256
       </Radio.Group>,
256
       </Radio.Group>,
257
       value: userData.status != null ? userData.status.toString() : "1"
257
       value: userData.status != null ? userData.status.toString() : "1"
258
     },
258
     },
259
+    {
260
+      label: '权重',
261
+      name: 'weight',
262
+      type: FieldTypes.Number,
263
+      render: <Input type="number" style={{ width: 150}} />,
264
+      value: userData.weight,
265
+      help: '数字越大越靠前',
266
+    },
259
   ]
267
   ]
260
 
268
 
261
   console.log('--------->', fields)
269
   console.log('--------->', fields)

+ 1
- 1
src/pages/style/GoodsList.less View File

11
 
11
 
12
 .imgPerfect {
12
 .imgPerfect {
13
   width: 120px;
13
   width: 120px;
14
-  height: 67.5px;
14
+  height: 40px;
15
 }
15
 }
16
 
16
 
17
 .imgIndex {
17
 .imgIndex {

+ 49
- 0
src/services/apis.js View File

253
       url: `${prefix}/customer/recommend/edit/:id`,
253
       url: `${prefix}/customer/recommend/edit/:id`,
254
       action: 'admin.customer.recommend.edit.id.put',
254
       action: 'admin.customer.recommend.edit.id.put',
255
     },
255
     },
256
+    consultantAssist: {
257
+      method: 'POST',
258
+      url: `${prefix}/customer/consultant/assist/:id`,
259
+      action: 'admin.customer.consultant.assist.id.put',
260
+    },
256
     taPointsRecords: {
261
     taPointsRecords: {
257
       method: 'GET',
262
       method: 'GET',
258
       url: `${prefix}/mine/taPointsRecords/:id`,
263
       url: `${prefix}/mine/taPointsRecords/:id`,
320
       url: `${prefix}/selectUserResource`,
325
       url: `${prefix}/selectUserResource`,
321
       action: 'userStatistics',
326
       action: 'userStatistics',
322
     },
327
     },
328
+    selectPersonFrom: {
329
+      method: 'GET',
330
+      url: `${prefix}/selectPersonFrom`,
331
+      action: 'userStatistics',
332
+    },
333
+    selectPersonFromGroupByDay: {
334
+      method: 'GET',
335
+      url: `${prefix}/selectPersonFromGroupByDay`,
336
+      action: 'userStatistics',
337
+    },
323
     list:{
338
     list:{
324
       method:'Get',
339
       method:'Get',
325
       url: `${prefix}/indexStatistical`,
340
       url: `${prefix}/indexStatistical`,
336
         url: `${prefix}/selectEventAll`,
351
         url: `${prefix}/selectEventAll`,
337
         action: 'behaviorIncident',
352
         action: 'behaviorIncident',
338
       },
353
       },
354
+      tsUserBehavior: {
355
+        method: 'GET',
356
+        url: `${prefix}/tsUserBehavior`,
357
+        action: 'tsUserBehavior',
358
+      },
339
     },
359
     },
340
     bizEvent: {
360
     bizEvent: {
341
       dict: {
361
       dict: {
999
     action: 'admin.thirdPartyMiniapp.id.get',
1019
     action: 'admin.thirdPartyMiniapp.id.get',
1000
   },
1020
   },
1001
  },
1021
  },
1022
+ wxDict: {
1023
+  list: {
1024
+    url: `${prefix}/tdWxDict`,
1025
+    method: 'GET',
1026
+    action: 'admin.tdWxDict.get',
1027
+  },
1028
+ },
1002
  poster: {
1029
  poster: {
1003
   posterTemplate: {
1030
   posterTemplate: {
1004
     url: `${prefix}/posterTemplate`,
1031
     url: `${prefix}/posterTemplate`,
1006
     action: 'admin.posterTemplate.get',
1033
     action: 'admin.posterTemplate.get',
1007
   },
1034
   },
1008
  },
1035
  },
1036
+ paorama: {
1037
+  panoramaApartList: {
1038
+    url: `${prefix}/panorama/apartment`,
1039
+    method: 'GET',
1040
+    action: 'admin.panoramaApartList.get',
1041
+  },
1042
+  add: {
1043
+    url: `${prefix}/panorama`,
1044
+    method: 'POST',
1045
+    action: 'admin.panorama.post',
1046
+  },
1047
+  list: {
1048
+    url: `${prefix}/panorama/:id`,
1049
+    method: 'GET',
1050
+    action: 'admin.panorama.id.get',
1051
+  },
1052
+  delete: {
1053
+    method: 'DELETE',
1054
+    url: `${prefix}/panorama/:id`,
1055
+    action: 'admin.panorama.id.delete',
1056
+  }
1057
+ },
1009
  amap: { // 高德地图
1058
  amap: { // 高德地图
1010
    webService: { // Web服务Api ---- 周边搜索
1059
    webService: { // Web服务Api ---- 周边搜索
1011
      url: `${amapPrefix}/place/around`,
1060
      url: `${amapPrefix}/place/around`,

+ 5
- 5
src/utils/request.js View File

89
       const { code, data, message } = await response.clone().json();
89
       const { code, data, message } = await response.clone().json();
90
       if (code != 1000) {
90
       if (code != 1000) {
91
         if (code === 1001) {
91
         if (code === 1001) {
92
-          notification.error({
93
-            message: `请登录系统`,
94
-            // description: '请登录系统',
95
-          });
96
-          throw new Error('请登录系统');
92
+          // notification.error({
93
+          //   message: `请登录系统`,
94
+          //   // description: '请登录系统',
95
+          // });
96
+          // throw new Error('请登录系统');
97
         } else {
97
         } else {
98
           notification.error({
98
           notification.error({
99
             message: message || '请求错误',
99
             message: message || '请求错误',