Sfoglia il codice sorgente

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

魏超 5 anni fa
parent
commit
1527941bfb

+ 53
- 14
config/routes.js Vedi File

@@ -21,13 +21,22 @@ export default [
21 21
         routes: [
22 22
           {
23 23
             path: '/',
24
-            redirect: '/welcome',
24
+            redirect: '/index',
25 25
           },
26 26
           {
27
-            path: '/welcome',
27
+            path: '/index',
28 28
             name: '首页',
29
-            component: './Welcome',
29
+            component: './Index',
30 30
           },
31
+          // {
32
+          //   path: '/',
33
+          //   redirect: '/welcome',
34
+          // },
35
+          // {
36
+          //   path: '/welcome',
37
+          //   name: '首页',
38
+          //   component: './Welcome',
39
+          // },
31 40
           {
32 41
             path: '/indexEcharts',
33 42
             name: '图表管理',
@@ -353,13 +362,13 @@ export default [
353 362
               },
354 363
               {
355 364
                 path: '/activity/liveActivity/add',
356
-                name: '新增', 
365
+                name: '新增',
357 366
                 hideInMenu: true,
358 367
                 component: './activity/liveActivity/add',
359 368
               },
360 369
               {
361 370
                 path: '/activity/liveActivity/edit',
362
-                name: '编辑', 
371
+                name: '编辑',
363 372
                 hideInMenu: true,
364 373
                 component: './activity/liveActivity/edit',
365 374
               },
@@ -573,6 +582,36 @@ export default [
573 582
                 name: '置业顾问KPI',
574 583
                 component: './statistical/consultant/index',
575 584
               },
585
+              {
586
+                path: '/statistical/consultant/table',
587
+                name: '拓客统计',
588
+                hideInMenu: true,
589
+                component: './statistical/consultant/table',
590
+              },
591
+              {
592
+                path: '/statistical/consultant/sharetable',
593
+                name: '分享统计',
594
+                hideInMenu: true,
595
+                component: './statistical/consultant/sharetable',
596
+              },
597
+              {
598
+                path: '/statistical/consultant/visitPersons',
599
+                name: '分享访问人数',
600
+                hideInMenu: true,
601
+                component: './statistical/consultant/visitPersons',
602
+              },
603
+              {
604
+                path: '/statistical/consultant/visitNum',
605
+                name: '分享访问次数',
606
+                hideInMenu: true,
607
+                component: './statistical/consultant/visitNum',
608
+              },
609
+              {
610
+                path: '/statistical/consultant/homePagePersons',
611
+                name: '主页访问人数',
612
+                hideInMenu: true,
613
+                component: './statistical/consultant/homePagePersons',
614
+              },
576 615
             ],
577 616
           },
578 617
           {
@@ -587,19 +626,19 @@ export default [
587 626
               },
588 627
               {
589 628
                 path: '/house/house/add',
590
-                name: '新增', 
629
+                name: '新增',
591 630
                 hideInMenu: true,
592 631
                 component: './house/house/add/index',
593 632
               },
594 633
               {
595 634
                 path: '/house/house/batch',
596
-                name: '批量上传', 
635
+                name: '批量上传',
597 636
                 hideInMenu: true,
598 637
                 component: './house/house/add/HouseBatchAdd',
599 638
               },
600 639
               {
601 640
                 path: '/house/house/edit',
602
-                name: '编辑', 
641
+                name: '编辑',
603 642
                 hideInMenu: true,
604 643
                 component: './house/house/edit/index',
605 644
               },
@@ -610,19 +649,19 @@ export default [
610 649
               },
611 650
               {
612 651
                 path: '/house/preSelect/add',
613
-                name: '新增', 
652
+                name: '新增',
614 653
                 hideInMenu: true,
615 654
                 component: './house/preSelect/add/index',
616 655
               },
617 656
               {
618 657
                 path: '/house/preSelect/batch',
619
-                name: '批量上传', 
658
+                name: '批量上传',
620 659
                 hideInMenu: true,
621 660
                 component: './house/preSelect/add/HouseBatchAdd',
622 661
               },
623 662
               {
624 663
                 path: '/house/preSelect/edit',
625
-                name: '编辑', 
664
+                name: '编辑',
626 665
                 hideInMenu: true,
627 666
                 component: './house/preSelect/edit/index',
628 667
               },
@@ -633,19 +672,19 @@ export default [
633 672
               },
634 673
               {
635 674
                 path: '/house/raise/add',
636
-                name: '新增', 
675
+                name: '新增',
637 676
                 hideInMenu: true,
638 677
                 component: './house/raise/add/index',
639 678
               },
640 679
               {
641 680
                 path: '/house/raise/batch',
642
-                name: '批量上传', 
681
+                name: '批量上传',
643 682
                 hideInMenu: true,
644 683
                 component: './house/raise/add/HouseBatchAdd',
645 684
               },
646 685
               {
647 686
                 path: '/house/raise/edit',
648
-                name: '编辑', 
687
+                name: '编辑',
649 688
                 hideInMenu: true,
650 689
                 component: './house/raise/edit/index',
651 690
               },

BIN
src/assets/border.png Vedi File


BIN
src/assets/consultantKPI.png Vedi File


BIN
src/assets/customer.png Vedi File


BIN
src/assets/items.png Vedi File


BIN
src/assets/picture.png Vedi File


BIN
src/assets/project.png Vedi File


BIN
src/assets/report.png Vedi File


BIN
src/assets/statistics.png Vedi File


+ 1
- 0
src/global.less Vedi File

@@ -50,6 +50,7 @@ ol {
50 50
 
51 51
 .ant-layout-header .ant-pro-global-header{
52 52
   background:#393C39;
53
+  border-bottom: 0.6px solid rgb(156, 153, 153);
53 54
 }
54 55
 .ant-layout .ant-pro-sider-menu-sider.light .ant-pro-sider-menu-logo{
55 56
   background:#EF273A;

+ 126
- 0
src/pages/Index.jsx Vedi File

@@ -0,0 +1,126 @@
1
+import React, { Component, useState, useEffect } from 'react';
2
+import { Card, Typography, Alert, Row, Col, Button } from 'antd';
3
+import router from 'umi/router';
4
+import request from '../utils/request';
5
+import bgImg from '../assets/picture.png';
6
+import itemsImg from '../assets/items.png';
7
+import consultantImg from '../assets/consultantKPI.png';
8
+import projectImg from '../assets/project.png';
9
+import reportImg from '../assets/report.png';
10
+import customerImg from '../assets/customer.png';
11
+import statisticsImg from '../assets/statistics.png';
12
+import borderImg from '../assets/border.png';
13
+
14
+const index = (props) => {
15
+
16
+    const [data, setData] = useState([])
17
+
18
+
19
+    useEffect(() => {
20
+
21
+    }, [])
22
+    const list = [
23
+        {
24
+            title: '项目列表',
25
+            img: itemsImg,
26
+            path: '/building/list',
27
+            value: '1',
28
+        },
29
+        {
30
+            title: '客户列表',
31
+            img: customerImg,
32
+            path: '',
33
+            value: '2',
34
+        },
35
+        {
36
+            title: '数据报表',
37
+            img: reportImg,
38
+            path: '',
39
+            value: '3',
40
+        },
41
+
42
+        {
43
+            title: '项目统计',
44
+            img: projectImg,
45
+            path: '',
46
+            value: '4',
47
+        },
48
+        {
49
+            title: '活动统计',
50
+            img: statisticsImg,
51
+            path: '',
52
+            value: '5',
53
+        },
54
+        {
55
+            title: '置业顾问KPI',
56
+            img: consultantImg,
57
+            path: '',
58
+            value: '6',
59
+        },
60
+
61
+    ]
62
+    const goNow = (path) => {
63
+        router.push({
64
+            pathname: path,
65
+        });
66
+    }
67
+
68
+
69
+
70
+    return (
71
+        <>
72
+            <div style={{
73
+                width: 'calc(100% + 48px)',
74
+                height: '0',
75
+                paddingBottom: 'calc(29.64% + 14.23px)',
76
+                position: 'relative',
77
+                top: '-24px',
78
+                left: '-24px',
79
+                backgroundImage: `url('` + bgImg + `')`,
80
+                backgroundRepeat: 'no-repeat',
81
+                backgroundSize: '100% 100%',
82
+            }} >
83
+            </div>
84
+            <div style={{
85
+                backgroundColor: '#fff',
86
+                margin: '-24px -24px 0.24rem -24px',
87
+                paddingBottom: '0.2rem',
88
+
89
+            }} >
90
+                <h2 style={{
91
+                    fontSize: '0.11rem',
92
+                    padding: '0.2rem 0 16px 24px'
93
+                }}>快捷入口</h2>
94
+                <Row style={{ textAlign: 'center' }}>
95
+                    {list.map(item => (
96
+                        <Col span={4} key={item.value} onClick={() => goNow(item.path)}>
97
+                            <div style={{
98
+                                width: '1.2rem',
99
+                                height: '0px',
100
+                                margin: '0 auto',
101
+                                paddingBottom: '0.66rem',
102
+                                position: 'relative',
103
+                                backgroundImage: `url('` + borderImg + `')`,
104
+                                backgroundRepeat: 'no-repeat',
105
+                                backgroundSize: '100% 100%',
106
+                                paddingTop: '0.12rem'
107
+                            }}>
108
+                                <p style={{ color: '#FF7F49', fontSize: '0.11rem', letterSpacing: '0.026rem', fontWeight: '600', }}>{item.title}</p>
109
+                                <img style={{ position: 'absolute', left: '0.08rem', bottom: '0.1rem', width: '0.3rem' }} src={item.img} alt="" />
110
+                            </div>
111
+                        </Col>
112
+                    ))}
113
+
114
+
115
+
116
+                </Row>
117
+
118
+            </div>
119
+
120
+
121
+        </>
122
+    )
123
+
124
+}
125
+export default index
126
+

+ 1
- 1
src/pages/Welcome.jsx Vedi File

@@ -64,7 +64,7 @@ const welcome = (props) => {
64 64
             boxShadow: '0px  0.106rem 14px -15px rgba(107,130,230,1)',
65 65
             borderRadius: '12px', width: '32%',
66 66
           }}>
67
-            <span style={{ fontSize: '24px', color: '#fff', borderBottom: '1px solid #fff', margin: '30px 0', cursor: 'pointer' }}>最近7天新增 </span>
67
+            <span style={{ fontSize: '24px', color: '#fff', borderBottom: '1px solid #fff', margin: '30px 0', cursor: 'pointer' }}>今日新增用户 </span>
68 68
             <span style={{ fontSize: '52px', color: '#fff', marginLeft: '26px', fontFamily: 'fantasy', lineHeight: '100px' }}>{data.selectRecentlyCount || '0'}</span>
69 69
           </div>
70 70
         }

+ 28
- 2
src/pages/indexEcharts/components/IntentionalCustomers.jsx Vedi File

@@ -88,12 +88,38 @@ const UserBehavior = (props) => {
88 88
     IntentionUsers({  pageNum: 1, pageSize: 5, buildingId: e })
89 89
     setBuildingId(e)
90 90
   }
91
+
92
+  //意向客户导出
93
+  function exportIntentionUsers () {
94
+    request({
95
+      ...apis.indexEcharts.exportIntentionUsers,
96
+      params: { buildingId }
97
+    }).then((data) => {
98
+      if (!data) {
99
+        return
100
+      }
101
+      const url = window.URL.createObjectURL(new Blob([data]))
102
+      const link = document.createElement('a')
103
+      link.style.display = 'none'
104
+      link.href = url
105
+      link.setAttribute('download', '意向客户.xlsx')
106
+      document.body.append(link)
107
+      link.click()
108
+    })
109
+  }
110
+
91 111
   return (
92 112
     <>
93 113
       <div>
94 114
       <p style={{fontSize:'0.12rem',fontWeight:'600'}}>意向客户</p>
95
-
96
-        <BuildSelect slot='action' onChange={(e => handleBuildingChange(e))} value={buildingId}></BuildSelect>
115
+        <Row>
116
+          <Col span={22}>
117
+            <BuildSelect slot='action' onChange={(e => handleBuildingChange(e))} value={buildingId}></BuildSelect>
118
+          </Col>
119
+          <Col span={2}>
120
+            <Button type="primary" onClick={exportIntentionUsers}>导出</Button>
121
+          </Col>
122
+        </Row>
97 123
 
98 124
         <Table rowKey="IntentionalCustomers" dataSource={data.records} columns={columns} style={{marginTop:'15px'}} pagination={{ total: data.total, defaultPageSize: 5, onChange: e => onChange(e) }} scroll={{ y: 500 }} />
99 125
 

+ 3
- 3
src/pages/indexEcharts/components/NewUsers.jsx Vedi File

@@ -24,7 +24,7 @@ const NewUsers = (props) => {
24 24
 
25 25
   function NewsUserCount (params) {
26 26
     request({
27
-      ...apis.indexEcharts.newUser,
27
+      ...apis.indexEcharts.changeNewUser,
28 28
       params,
29 29
     }).then((data) => {
30 30
       setData(data)
@@ -43,7 +43,7 @@ const NewUsers = (props) => {
43 43
       end: 100
44 44
     },
45 45
   ] : undefined 
46
-  const dataset = (data.selectNewsUserCount) || []
46
+  const dataset = data || []
47 47
   const options = {
48 48
 
49 49
    
@@ -74,7 +74,7 @@ const NewUsers = (props) => {
74 74
         }
75 75
       ],
76 76
       dataset: {
77
-        dimensions: ['date', 'userCount', 'authorizationCount'],
77
+        dimensions: ['createTime', 'fromNum', 'registeredNum'],
78 78
         source: dataset
79 79
       }
80 80
  

+ 62
- 9
src/pages/indexEcharts/newUsers.jsx Vedi File

@@ -16,20 +16,28 @@ import apis from '../../services/apis';
16 16
 //   return { startDate, endDate }
17 17
 // }
18 18
 
19
+let columns = [
20
+  {
21
+    title: '日期',
22
+    dataIndex: 'createTime',
23
+    key: 'createTime',
24
+  },
25
+]
19 26
 
20 27
 const header = props => {
21 28
 
22
-  const [tableData, setTableData] = useState({ records: [] })
23
-
29
+  const [tableData, setTableData] = useState([])
24 30
   const [endDate, setEndDate] = useState({})
31
+  const [data, setDate] = useState({})
25 32
   const [startDate, setStartDate] = useState({})
26 33
   let daterange= []
27 34
 
28 35
   useEffect(() => {
29 36
 
30 37
     setEndDate(new Date())
31
-    setStartDate(moment().subtract(7, 'day').toDate())
32
-
38
+    setStartDate(new Date())
39
+    // setStartDate(moment().subtract(7, 'day').toDate())
40
+    userResource({startDate: new Date(), endDate: new Date()})
33 41
   }, [])
34 42
 
35 43
   const { RangePicker } = DatePicker;
@@ -52,7 +60,7 @@ const header = props => {
52 60
  
53 61
     setEndDate(new Date())
54 62
     setStartDate(moment().subtract(days, 'day').toDate())
55
-
63
+    userResource({startDate: moment().subtract(days, 'day').toDate(), endDate: new Date()})
56 64
   }
57 65
 
58 66
   function onChange (e) {
@@ -64,15 +72,53 @@ const header = props => {
64 72
 
65 73
     setEndDate(daterange[1])
66 74
     setStartDate(daterange[0])
75
+    userResource({startDate: daterange[0], endDate: daterange[1]})
67 76
 
68 77
   }
69 78
 
70
- 
71
-  function handleSelectChange (e) {
79
+  function userResource(params) {
80
+    request({
81
+      ...apis.indexEcharts.selectPersonFrom,
82
+      params,
83
+    }).then((data) => {
84
+      setDate(data);
85
+      onTabledatas(data,"all")
86
+    })
87
+  }
72 88
 
73
-    console.log(e)
89
+  const onTabledatas = (e,changeType) => {
90
+    e.tdWxDicts.map(x => {
91
+        columns = columns.filter(y => y.key != x.sceneType).concat({
92
+          title: x.sceneAlias,
93
+          dataIndex: x.sceneType,
94
+          key: x.sceneType,
95
+        })
96
+    })
97
+    const data = (e.list || []).reduce((acc, item) => {
98
+      const { sceneType, fromNum, registeredNum, createTime } = item
99
+      const num = changeType === 'registered' ? registeredNum : fromNum
100
+      acc[createTime] = { ...acc[createTime], ...item, [`${sceneType}`]: !num ? 0 : num }
101
+      return acc
102
+    }, {})
103
+
104
+    const dictData =  e.tdWxDicts.reduce((acc,item,index) => {
105
+      const { sceneType } = item
106
+      acc[sceneType] = 0
107
+      return acc
108
+    },{})
109
+
110
+    const tableData = Object.keys(data).map(k => data[k]).reduce((acc,item,index) => {
111
+      acc[index] = { ...dictData, ...item }
112
+      return acc
113
+    },[])
114
+
115
+    setTableData(tableData)
74 116
 
75 117
   }
118
+ 
119
+  function handleSelectChange (e) {
120
+    onTabledatas(data,e)
121
+  }
76 122
 
77 123
   const { Column, ColumnGroup } = Table;
78 124
 
@@ -84,7 +130,8 @@ const header = props => {
84 130
       borderRadius: '12px',
85 131
       minHeight: '60vh'
86 132
     }}>
87
-      <Radio.Group onChange={onChange} buttonStyle="solid" defaultValue="a"  style={{marginBottom:'20px'}}>
133
+      <Radio.Group onChange={onChange} buttonStyle="solid" defaultValue="c"  style={{marginBottom:'20px'}}>
134
+        <Radio.Button value="c" onClick={getDataOf(0)}>今日</Radio.Button>
88 135
         <Radio.Button value="a" onClick={getDataOf(7)}>最近7天</Radio.Button>
89 136
         <Radio.Button value="b" onClick={getDataOf(30)}>最近1月</Radio.Button>
90 137
       </Radio.Group>
@@ -105,6 +152,12 @@ const header = props => {
105 152
       <div>
106 153
         <NewUsers BuildSelectHide={true} endDate={endDate} startDate={startDate}  dataZoom={true} ></NewUsers>
107 154
         {/* */}
155
+        <Select style={{ width: '180px' }} placeholder="所有用户" onChange={(e) => handleSelectChange(e)}>
156
+          <Option value='all'>所有用户</Option>
157
+          <Option value='registered'>注册用户</Option>
158
+        </Select>
159
+  
160
+        <Table style={{marginTop:'20px'}} dataSource={tableData} columns={columns} pagination={false} scroll={{ y: 500 }}></Table>
108 161
       </div>
109 162
     </div>
110 163
   </>

+ 23
- 23
src/pages/record/drainage/DrainageVisitRecordList.jsx Vedi File

@@ -46,9 +46,9 @@ const header = props => {
46 46
       dataIndex: 'activityName',
47 47
       key: 'activityName',
48 48
       align: 'center',
49
-      render: (text, record) => <span>{record.activityName != null ? record.activityName : 
50
-        record.drainageName != null ? record.drainageName : record.buildingName != null ? record.buildingName:record.newsName != null ? record.newsName : record.helpActivityName !=null ? record.helpActivityName :
51
-        record.groupActivityName!=null ? record.groupActivityName:''}</span>,
49
+      render: (text, record) => <span>{record.activityName != null ? record.activityName :
50
+        record.drainageName != null ? record.drainageName : record.buildingName != null ? record.buildingName : record.newsName != null ? record.newsName : record.helpActivityName != null ? record.helpActivityName :
51
+          record.groupActivityName != null ? record.groupActivityName : ''}</span>,
52 52
     },
53 53
     {
54 54
       title: '用户名',
@@ -86,10 +86,10 @@ const header = props => {
86 86
       dataIndex: 'personType',
87 87
       key: 'personType',
88 88
       align: 'center',
89
-      render: (text, record) => <span>{record.personType === 'Realty Consultant' ? '置业顾问' : '普通客户' }</span>,
89
+      render: (text, record) => <span>{record.personType === 'Realty Consultant' ? '置业顾问' : '普通客户'}</span>,
90 90
     },
91 91
   ];
92
-  
92
+
93 93
 
94 94
   const changePageNum = (pageNumber, props) => {
95 95
     getList({ pageNumber: pageNumber, pageSize: 10, ...props.form.getFieldsValue() })
@@ -104,7 +104,7 @@ const header = props => {
104 104
 
105 105
         if (!values.buildingId) {
106 106
           message.error("请选择项目")
107
-          return ;
107
+          return;
108 108
         }
109 109
 
110 110
         getList({ pageNum: 1, pageSize: 10, ...values })
@@ -113,7 +113,7 @@ const header = props => {
113 113
   }
114 114
 
115 115
   //重置搜索
116
-  function handleReset () {
116
+  function handleReset() {
117 117
     props.form.resetFields();
118 118
     getList({ pageNum: 1, pageSize: 10 })
119 119
   }
@@ -132,13 +132,13 @@ const header = props => {
132 132
         <Form.Item>
133 133
           {getFieldDecorator('eventType')(
134 134
             <Select placeholder="分享类型" style={{ width: 150 }}>
135
-            <Option value="activity_share">报名活动</Option>
136
-            <Option value="help_share">助力活动</Option>
137
-            <Option value="group_share">拼团活动</Option>
138
-            <Option value="h5_share">H5活动</Option>
139
-            <Option value="building_share">项目</Option>
140
-            <Option value="news_share">资讯</Option>
141
-          </Select>
135
+              <Option value="activity_share">报名活动</Option>
136
+              <Option value="help_share">助力活动</Option>
137
+              <Option value="group_share">拼团活动</Option>
138
+              <Option value="h5_share">H5活动</Option>
139
+              <Option value="building_share">项目</Option>
140
+              <Option value="news_share">资讯</Option>
141
+            </Select>
142 142
           )}
143 143
         </Form.Item>
144 144
         <Form.Item>
@@ -159,10 +159,10 @@ const header = props => {
159 159
         </Form.Item>
160 160
         <Form.Item>
161 161
           {getFieldDecorator('personType')(
162
-             <Select placeholder="分享者类型" style={{ width: 150 }}>
163
-             <Option value="Realty Consultant">置业顾问</Option>
164
-             <Option value="customer">普通客户</Option>
165
-           </Select>
162
+            <Select placeholder="分享者类型" style={{ width: 150 }}>
163
+              <Option value="Realty Consultant">置业顾问</Option>
164
+              <Option value="customer">普通客户</Option>
165
+            </Select>
166 166
           )}
167 167
         </Form.Item>
168 168
         <Form.Item>
@@ -174,9 +174,9 @@ const header = props => {
174 174
           )}
175 175
         </Form.Item>
176 176
         <Form.Item>
177
-        <AuthButton name="admin.visit.record.search" noRight={null}>
178
-          <Button type="primary" htmlType="submit" className={styles.searchBtn}> 
179
-            搜索
177
+          <AuthButton name="admin.visit.record.search" noRight={null}>
178
+            <Button type="primary" htmlType="submit" className={styles.searchBtn}>
179
+              搜索
180 180
           </Button>
181 181
           </AuthButton>
182 182
           <Button style={{ marginLeft: 8 }} onClick={handleReset}>
@@ -184,9 +184,9 @@ const header = props => {
184 184
             </Button>
185 185
         </Form.Item>
186 186
       </Form>
187
-      <Table style={{marginTop:'30px'}} dataSource={data.records} columns={columns} pagination={false} rowKey="activityList" locale={{ emptyText: defaultTip }} />
187
+      <Table style={{ marginTop: '30px' }} dataSource={data.records} columns={columns} pagination={false} rowKey="activityList" locale={{ emptyText: defaultTip }} />
188 188
       <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: '30px' }}>
189
-        <Pagination showQuickJumper defaultCurrent={1} total={data.total} onChange={e => changePageNum(e,props)} current={data.current} />
189
+        <Pagination showQuickJumper defaultCurrent={1} total={data.total} onChange={e => changePageNum(e, props)} current={data.current} />
190 190
       </div>
191 191
     </>
192 192
   )

+ 119
- 0
src/pages/statistical/consultant/homePagePersons.jsx Vedi File

@@ -0,0 +1,119 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Form, Button, Table, Pagination, Radio, Typography, Avatar } from 'antd';
3
+import router from 'umi/router';
4
+import moment from 'moment';
5
+import BuildSelect from '../../../components/SelectButton/BuildSelect'
6
+import apis from '../../../services/apis';
7
+import request from '../../../utils/request'
8
+
9
+/**
10
+  @param {*} props
11
+  @returns
12
+ */
13
+const { Text } = Typography;
14
+
15
+function record(props) {
16
+    const [formData, updateFormData] = useState({
17
+        pageNum: 1,
18
+        pageSize: 10,
19
+        ...props.location.query,
20
+
21
+    })
22
+
23
+    // 获取初始化数据
24
+    const [data, setData] = useState({})
25
+
26
+
27
+    useEffect(() => {
28
+        getList(formData);
29
+    }, [])
30
+
31
+    // 查询列表
32
+    const getList = (params) => {
33
+        request({ ...apis.stats.homePagePersons, params: { ...params }, }).then((data) => {
34
+            setData(data)
35
+        })
36
+    }
37
+
38
+    // 更新页码
39
+    const changePageNum = (pageNumber) => {
40
+        props.form.validateFields((err, values) => {
41
+            if (!err) {
42
+                getList({ ...props.location.query, pageNum: pageNumber });
43
+            }
44
+        });
45
+    }
46
+    const toPersonDetail = (personId) => {
47
+        router.push({
48
+            pathname: '/customer/customerlist/publicCustomerDetail',
49
+            query: {
50
+                id: personId,
51
+            },
52
+        });
53
+    }
54
+    // 表格数据
55
+    const columns = [
56
+
57
+        {
58
+            title: '头像',
59
+            dataIndex: 'picture',
60
+            key: 'picture',
61
+            align: 'center',
62
+            render: (_, record) => <Avatar shape="square" src={record.picture || record.avatarurl} size={64} icon="user" />,
63
+        },
64
+        {
65
+            title: '姓名',
66
+            dataIndex: 'name',
67
+            key: 'name',
68
+            align: 'center',
69
+            render: (_, record) => <span style={{ color: 'blue', cursor: 'pointer' }} onClick={() => toPersonDetail(record.personId)} >{record.name}</span>,
70
+        },
71
+        {
72
+            title: '电话',
73
+            dataIndex: 'phone',
74
+            key: 'phone',
75
+            align: 'center',
76
+        },
77
+        {
78
+            title: '性别',
79
+            dataIndex: 'sex',
80
+            key: 'sex',
81
+            align: 'center',
82
+            render: (_, record) => <span>{record.sex == 1 ? '男' : '女'}</span>,
83
+        },
84
+        {
85
+            title: '访问次数',
86
+            dataIndex: 'visitTimes',
87
+            key: 'visitTimes',
88
+            align: 'center',
89
+            render: (_, record) => <span style={{ color: 'blue', cursor: 'pointer' }} onClick={() => toPersonDetail(record.personId)} >{record.visitTimes}</span>,
90
+        },
91
+        {
92
+            title: '最后访问时间',
93
+            dataIndex: 'visitTime',
94
+            key: 'visitTime',
95
+            align: 'center',
96
+            render: (_, record) => <><span>{record.visitTime && moment(record.visitTime).format('YYYY-MM-DD HH:mm:ss')}</span></>,
97
+        },
98
+
99
+    ];
100
+
101
+    return (
102
+
103
+        <>
104
+            <Button type="danger" style={{ marginLeft: '18px' }} onClick={() => router.go(-1)}>返回</Button>
105
+            <Table rowKey={record => (record.phone + record.buildingId || '')}
106
+                style={{ marginTop: '30px' }}
107
+                dataSource={data.records}
108
+                columns={columns}
109
+                pagination={false}
110
+            />
111
+            < div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: '30px' }}>
112
+                <Pagination showQuickJumper defaultCurrent={1} total={data.total} onChange={changePageNum} current={data.current} />
113
+            </div>
114
+        </>
115
+    )
116
+}
117
+const WrappedHeader = Form.create({ name: 'record' })(record);
118
+
119
+export default WrappedHeader

+ 259
- 105
src/pages/statistical/consultant/index.jsx Vedi File

@@ -14,20 +14,30 @@ const { RangePicker } = DatePicker;
14 14
 const { Text } = Typography;
15 15
 
16 16
 function record(props) {
17
-    const { getFieldDecorator } = props.form
17
+    const [radioVal, updateRadioVal] = useState(7)
18
+    const [formData, updateFormData] = useState({
19
+        pageNum: 1,
20
+        pageSize: 10,
21
+        startDate: moment().subtract(radioVal, 'day').format('YYYYMMDD'),
22
+        endDate: moment().format('YYYYMMDD'),
23
+        buildingId: '',
24
+        asc: '',
25
+        desc: '',
26
+    })
18 27
 
19 28
     // 获取初始化数据
20 29
     const [data, setData] = useState({})
30
+    const [totalRow, setTotalRow] = useState({})
21 31
 
22 32
     useEffect(() => {
23
-        getList({ pageNum: 1, pageSize: 10 });
33
+        getList(formData);
24 34
     }, [])
25 35
 
26 36
     // 查询列表
27 37
     const getList = (params) => {
28
-        request({ ...apis.activity.saleCountList, params: { ...params }, }).then((data) => {
29
-            setData(data)
30
-            console.log("data:", data)
38
+        request({ ...apis.stats.consultantKPI, params: { ...params }, }).then((data) => {
39
+            setData(data.paged)
40
+            setTotalRow(data.total)
31 41
         })
32 42
     }
33 43
 
@@ -36,65 +46,165 @@ function record(props) {
36 46
         props.form.resetFields();
37 47
     }
38 48
 
39
-    // 分享详情
40
-    function shareCount(personId) {
41
-        router.push({
42
-            pathname: '/record/share/shareCountList',
43
-            query: {
44
-                id: personId,
45
-            },
46
-        });
47
-    }
48
-
49
-    // 点击人数详情
50
-    function clickCount(personId) {
51
-        router.push({
52
-            pathname: '/record/share/clickCountList',
53
-            query: {
54
-                id: personId,
55
-            },
56
-        });
57
-    }
58
-
59 49
     // 提交事件
60
-    const handleSubmit = (e, props) => {
50
+    const handleSubmit = (e) => {
61 51
         e.preventDefault();
62
-        props.form.validateFields((err, values) => {
63
-            if (!err) {
64
-                let { shareTime, receiveTime, ...submitValue } = values
65
-                if (null != shareTime && shareTime.length > 0) {
66
-                    const [startCreateDate, endCreateDate] = shareTime
67
-                    submitValue.startCreateDate = moment(startCreateDate).format('YYYY-MM-DD');
68
-                    submitValue.endCreateDate = moment(endCreateDate).format('YYYY-MM-DD');
69
-                } else {
70
-                    submitValue.startCreateDate = null
71
-                    submitValue.endCreateDate = null
72
-                }
73
-                console.log(submitValue)
74
-                getList({ pageNum: 1, pageSize: 10, ...submitValue })
75
-            }
76
-        });
52
+        getList(formData);
77 53
     }
78
-
54
+    // 更新页码
79 55
     const changePageNum = (pageNumber) => {
80 56
         props.form.validateFields((err, values) => {
81 57
             if (!err) {
82
-                let { shareTime, receiveTime, ...submitValue } = values
83
-                if (null != shareTime && shareTime.length > 0) {
84
-                    const [startCreateDate, endCreateDate] = shareTime
85
-                    submitValue.startCreateDate = moment(startCreateDate).format('YYYY-MM-DD');
86
-                    submitValue.endCreateDate = moment(endCreateDate).format('YYYY-MM-DD');
87
-                } else {
88
-                    submitValue.startCreateDate = null
89
-                    submitValue.endCreateDate = null
90
-                }
91
-                getList({ pageNum: pageNumber, pageSize: 10, ...submitValue })
58
+                getList({ ...formData, pageNum: pageNumber });
92 59
             }
93 60
         });
94 61
     }
95
-    function getDataOf(days) {
96
-        // this.setState({ endDate: new Date(), startDate: moment().subtract(days, 'day').toDate() })
62
+    // 切换日期 与picker联动
63
+    function setFormData(e) {
64
+        updateRadioVal(e.target.value)
65
+        updateFormData({
66
+            ...formData,
67
+            startDate: moment().subtract(e.target.value, 'day').format('YYYYMMDD'),
68
+            endDate: moment().format('YYYYMMDD'),
69
+        })
70
+        getList({
71
+            ...formData, startDate: moment().subtract(e.target.value, 'day').format('YYYYMMDD'),
72
+            endDate: moment().format('YYYYMMDD'),
73
+        });
74
+
75
+    }
76
+    // 选择日期
77
+    const handleDateChange = (val) => {
78
+        updateFormData({
79
+            ...formData,
80
+            startDate: val[0].format('YYYYMMDD'),
81
+            endDate: val[1].format('YYYYMMDD'),
82
+        })
83
+    }
84
+    // 选择项目
85
+    const handleBuildingChange = e => {
86
+        updateFormData({
87
+            ...formData,
88
+            buildingId: e,
89
+        })
97 90
     }
91
+
92
+    const clickCon = (val, record, type) => {
93
+        if (val == 0) {
94
+            return <><span onClick={() => toDetail(record, type)}>{val}</span></>
95
+        }
96
+        return <><span style={{ color: 'blue', cursor: 'pointer' }} onClick={() => toDetail(record, type)} >{val}</span></>
97
+    }
98
+
99
+    // 分享详情
100
+    function toDetail(record, type) {
101
+        if (type === 'totalPersons') {
102
+            router.push({
103
+                pathname: '/statistical/consultant/table',
104
+                query: {
105
+                    buildingId: formData.buildingId,
106
+                    userId: record.userId,
107
+                },
108
+            });
109
+        } else if (type === 'newPersons') {
110
+            router.push({
111
+                pathname: '/statistical/consultant/table',
112
+                query: {
113
+                    startDate: formData.startDate,
114
+                    endDate: formData.endDate,
115
+                    buildingId: formData.buildingId,
116
+                    userId: record.userId,
117
+                },
118
+            });
119
+        } else if (type === 'shareNum') {
120
+            router.push({
121
+                pathname: '/statistical/consultant/sharetable',
122
+                query: {
123
+                    startDate: formData.startDate,
124
+                    endDate: formData.endDate,
125
+                    buildingId: formData.buildingId,
126
+                    userId: record.userId,
127
+                },
128
+            });
129
+        } else if (type === 'visitPersons') {
130
+            router.push({
131
+                pathname: '/statistical/consultant/visitPersons',
132
+                query: {
133
+                    startDate: formData.startDate,
134
+                    endDate: formData.endDate,
135
+                    buildingId: formData.buildingId,
136
+                    userId: record.userId,
137
+                },
138
+            });
139
+        } else if (type === 'visitNum') {
140
+            router.push({
141
+                pathname: '/statistical/consultant/visitNum',
142
+                query: {
143
+                    startDate: formData.startDate,
144
+                    endDate: formData.endDate,
145
+                    buildingId: formData.buildingId,
146
+                    userId: record.userId,
147
+                },
148
+            });
149
+        } else if (type === 'sharePersons') {
150
+            router.push({
151
+                pathname: '/statistical/consultant/table',
152
+                query: {
153
+                    startDate: formData.startDate,
154
+                    endDate: formData.endDate,
155
+                    buildingId: formData.buildingId,
156
+                    userId: record.userId,
157
+                    type: 'sharePersons',
158
+                },
159
+            });
160
+        } else if (type === 'homePagePersons') {
161
+            router.push({
162
+                pathname: '/statistical/consultant/homePagePersons',
163
+                query: {
164
+                    startDate: formData.startDate,
165
+                    endDate: formData.endDate,
166
+                    buildingId: formData.buildingId,
167
+                    userId: record.userId,
168
+                },
169
+            });
170
+        } else if (type === 'homePageNums') {
171
+            router.push({
172
+                pathname: '/statistical/consultant/table',
173
+                query: {
174
+                    startDate: formData.startDate,
175
+                    endDate: formData.endDate,
176
+                    buildingId: formData.buildingId,
177
+                    userId: record.userId,
178
+                    type: 'homePageNums',
179
+                },
180
+            });
181
+        } else if (type === 'chatPersons') {
182
+            router.push({
183
+                pathname: '/statistical/consultant/table',
184
+                query: {
185
+                    startDate: formData.startDate,
186
+                    endDate: formData.endDate,
187
+                    buildingId: formData.buildingId,
188
+                    userId: record.userId,
189
+                    type: 'chatPersons',
190
+                },
191
+            });
192
+        } else if (type === 'favorNum') {
193
+            router.push({
194
+                pathname: '/statistical/consultant/table',
195
+                query: {
196
+                    startDate: formData.startDate,
197
+                    endDate: formData.endDate,
198
+                    buildingId: formData.buildingId,
199
+                    userId: record.userId,
200
+                    type: 'favorNum',
201
+                },
202
+            });
203
+        }
204
+
205
+    }
206
+
207
+    // 表格数据
98 208
     const columns = [
99 209
 
100 210
         {
@@ -102,114 +212,158 @@ function record(props) {
102 212
             dataIndex: 'buildingName',
103 213
             key: 'buildingName',
104 214
             align: 'center',
215
+            // render: (txt, _, index) => index ? txt : <span>总计</span>,
105 216
         },
217
+
106 218
         {
107
-            title: '置业顾问名称1',
108
-            dataIndex: 'consultantName',
109
-            key: 'consultantName',
219
+            title: '置业顾问名称',
220
+            dataIndex: 'userName',
221
+            key: 'userName',
110 222
             align: 'center',
111 223
         },
112 224
         {
113 225
             title: '置业顾问电话',
114
-            dataIndex: 'consultantPhone',
115
-            key: 'consultantPhone',
226
+            dataIndex: 'phone',
227
+            key: 'phone',
116 228
             align: 'center',
117 229
         },
118 230
         {
119 231
             title: '客户总计',
120
-            dataIndex: 'customerAggregate',
121
-            key: 'customerAggregate',
232
+            dataIndex: 'totalPersons',
233
+            key: 'totalPersons',
122 234
             align: 'center',
123
-            sorter: (a, b) => a.customerAggregate - b.customerAggregate,
124
-            render: (_, record) => <><span style={{ color: 'blue', cursor: 'pointer' }} onClick={() => shareCount(record.personId)} >{record.customerAggregate}</span></>,
235
+            sorter: (a, b) => a.totalPersons - b.totalPersons,
236
+            render: (txt, record, index) => clickCon(txt, record, 'totalPersons'),
237
+            // render: (txt, record, index) => index ? clickCon(txt, record, 'totalPersons') : <strong>{txt}</strong>,
125 238
         },
126 239
         {
127 240
             title: '新增客户',
128
-            dataIndex: 'newCustomers',
129
-            key: 'newCustomers',
241
+            dataIndex: 'newPersons',
242
+            key: 'newPersons',
130 243
             align: 'center',
131
-            sorter: (a, b) => a.newCustomers - b.newCustomers,
132
-            render: (_, record) => <><span style={{ color: 'blue', cursor: 'pointer' }} onClick={() => shareCount(record.personId)} >{record.newCustomers}</span></>,
244
+            sorter: (a, b) => a.newPersons - b.newPersons,
245
+            render: (txt, record, index) => clickCon(txt, record, 'newPersons'),
133 246
         },
134 247
         {
135 248
             title: '分享次数',
136
-            dataIndex: 'shareCount',
137
-            key: 'shareCount',
249
+            dataIndex: 'shareNum',
250
+            key: 'shareNum',
138 251
             align: 'center',
139
-            sorter: (a, b) => a.shareCount - b.shareCount,
140
-            render: (_, record) => <><span style={{ color: 'blue', cursor: 'pointer' }} onClick={() => shareCount(record.personId)} >{record.shareCount}</span></>,
252
+            sorter: (a, b) => a.shareNum - b.shareNum,
253
+            render: (txt, record, index) => clickCon(txt, record, 'shareNum'),
141 254
         },
142 255
         {
143 256
             title: '分享访问人数',
144
-            dataIndex: 'shareVisitPersonNum',
145
-            key: 'shareVisitPersonNum',
257
+            dataIndex: 'visitPersons',
258
+            key: 'visitPersons',
146 259
             align: 'center',
147
-            sorter: (a, b) => a.shareVisitPersonNum - b.shareVisitPersonNum,
148
-            render: (_, record) => <><span style={{ color: 'blue', cursor: 'pointer' }} onClick={() => shareCount(record.personId)} >{record.shareVisitPersonNum}</span></>,
260
+            sorter: (a, b) => a.visitPersons - b.visitPersons,
261
+            render: (txt, record, index) => clickCon(txt, record, 'visitPersons'),
149 262
         },
150 263
         {
151 264
             title: '分享访问次数',
152
-            dataIndex: 'shareVisitNum',
153
-            key: 'shareVisitNum',
265
+            dataIndex: 'visitNum',
266
+            key: 'visitNum',
154 267
             align: 'center',
155
-            sorter: (a, b) => a.shareVisitNum - b.shareVisitNum,
156
-            render: (_, record) => <><span style={{ color: 'blue', cursor: 'pointer' }} onClick={() => shareCount(record.personId)} >{record.shareVisitNum}</span></>,
268
+            sorter: (a, b) => a.visitNum - b.visitNum,
269
+            render: (txt, record, index) => clickCon(txt, record, 'visitNum'),
157 270
         },
158 271
 
159 272
         {
160 273
             title: '分享拓客',
161
-            dataIndex: 'sharePossess',
162
-            key: 'sharePossess',
274
+            dataIndex: 'sharePersons',
275
+            key: 'sharePersons',
163 276
             align: 'center',
164
-            sorter: (a, b) => a.sharePossess - b.sharePossess,
165
-            render: (_, record) => <><span style={{ color: 'blue', cursor: 'pointer' }} onClick={() => clickCount(record.personId)} >{record.sharePossess}</span></>,
277
+            sorter: (a, b) => a.sharePersons - b.sharePersons,
278
+            render: (txt, record, index) => clickCon(txt, record, 'sharePersons'),
166 279
         },
167 280
         {
168 281
             title: '主页访问人数',
169
-            dataIndex: 'visitPerson',
170
-            key: 'visitPerson',
282
+            dataIndex: 'homePagePersons',
283
+            key: 'homePagePersons',
171 284
             align: 'center',
172
-            sorter: (a, b) => a.visitPerson - b.visitPerson,
173
-            render: (_, record) => <><span style={{ color: 'blue', cursor: 'pointer' }} onClick={() => clickCount(record.personId)} >{record.visitPerson}</span></>,
285
+            sorter: (a, b) => a.homePagePersons - b.homePagePersons,
286
+            render: (txt, record, index) => clickCon(txt, record, 'homePagePersons'),
174 287
         },
175 288
         {
176 289
             title: '主页访问次数',
177
-            dataIndex: 'clickNum',
178
-            key: 'clickNum',
290
+            dataIndex: 'homePageNums',
291
+            key: 'homePageNums',
292
+            align: 'center',
293
+            sorter: (a, b) => a.homePageNums - b.homePageNums,
294
+            render: (txt, record, index) => clickCon(txt, record, 'homePageNums'),
295
+        },
296
+        {
297
+            title: '咨询数',
298
+            dataIndex: 'chatPersons',
299
+            key: 'chatPersons',
300
+            align: 'center',
301
+            sorter: (a, b) => a.chatPersons - b.chatPersons,
302
+            render: (txt, record, index) => clickCon(txt, record, 'chatPersons'),
303
+        },
304
+        {
305
+            title: '点赞数',
306
+            dataIndex: 'favorNum',
307
+            key: 'favorNum',
179 308
             align: 'center',
180
-            sorter: (a, b) => a.clickNum - b.clickNum,
181
-            render: (_, record) => <><span style={{ color: 'blue', cursor: 'pointer' }} onClick={() => clickCount(record.personId)} >{record.clickNum}</span></>,
309
+            sorter: (a, b) => a.favorNum - b.favorNum,
310
+            render: (txt, record, index) => clickCon(txt, record, 'favorNum'),
182 311
         },
183 312
     ];
313
+    // 下载文档
314
+    function download(data) {
315
+        if (!data) {
316
+            return
317
+        }
318
+        const url = window.URL.createObjectURL(new Blob([data]))
319
+        const link = document.createElement('a')
320
+        link.style.display = 'none'
321
+        link.href = url
322
+        link.setAttribute('download', '置业顾问KPI.xlsx')
323
+        document.body.append(link)
324
+        link.click()
325
+    }
326
+    // 导出
327
+    function exportRecord() {
328
+        request({ ...apis.stats.exportConsultantKPI, responseType: 'blob', params: { startDate: formData.startDate, endDate: formData.endDate, buildingId: formData.buildingId } })
329
+            .then(response => {
330
+                download(response)
331
+            }).catch(error => {
184 332
 
185
-
186
-
333
+            })
334
+    }
335
+    // 默认日期
336
+    const dateRange = [
337
+        moment(formData.startDate),
338
+        moment(formData.endDate),
339
+    ]
340
+    // const list = data.records
341
+    // const _list = list && list.length > 0 ? [totalRow, ...list] : [];
187 342
     return (
188 343
 
189 344
         <>
190
-            <Form layout="inline" onSubmit={e => handleSubmit(e, props)}>
345
+            <Form layout="inline">
191 346
                 <div style={{ display: 'flex', alignItems: 'center' }}>
192
-                    <Radio.Group buttonStyle="solid" defaultValue="a" style={{ marginRight: '16px', }}>
193
-                        <Radio.Button value="a" onClick={getDataOf(7)}>最近7天</Radio.Button>
194
-                        <Radio.Button value="b" onClick={getDataOf(30)}>最近1月</Radio.Button>
347
+                    <Radio.Group buttonStyle="solid" value={radioVal} onChange={setFormData} style={{ marginRight: '16px', }}>
348
+                        <Radio.Button value={7}>最近7天</Radio.Button>
349
+                        <Radio.Button value={30}>最近1月</Radio.Button>
195 350
                     </Radio.Group>
196 351
                     <Form.Item>
197
-                        {getFieldDecorator('shareTime')(
198
-                            <RangePicker placeholder={['开始日期', '结束日期']} />
199
-                        )}
352
+                        <RangePicker value={dateRange} onChange={handleDateChange} placeholder={['开始日期', '结束日期']} />
200 353
                     </Form.Item>
201 354
                     <Form.Item>
202
-                        {getFieldDecorator('buildingId')(
203
-                            <BuildSelect />,
204
-                        )}
355
+                        <BuildSelect value={formData.buildingId} onChange={handleBuildingChange} />
205 356
                     </Form.Item>
206 357
                     <Form.Item style={{ position: 'absolute', right: '38px' }}>
207
-                        <Button type="primary" onClick={handleReset}>查询</Button>
358
+                        <Button type="primary" onClick={handleSubmit}>查询</Button>
208 359
                         <Button style={{ marginLeft: 8 }} onClick={handleReset}>重置</Button>
209 360
                     </Form.Item>
210 361
                 </div>
211 362
             </Form>
212
-            <Table rowKey="KPIRecords"
363
+            <Button type="primary" onClick={exportRecord} style={{ float: 'right', margin: '20px 23px 20px 0', zIndex: 1 }}>
364
+                导出
365
+          </Button>
366
+            <Table rowKey={record => (record.userId + record.buildingId || '')}
213 367
                 style={{ marginTop: '30px' }}
214 368
                 dataSource={data.records}
215 369
                 columns={columns}

+ 131
- 0
src/pages/statistical/consultant/sharetable.jsx Vedi File

@@ -0,0 +1,131 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Form, Button, Table, Pagination, Select, Input, Icon } from 'antd';
3
+import router from 'umi/router';
4
+import moment from 'moment';
5
+import apis from '../../../services/apis';
6
+import request from '../../../utils/request'
7
+
8
+/**
9
+  @param {*} props
10
+  @returns
11
+ */
12
+const { Option } = Select;
13
+
14
+function record(props) {
15
+    const [radioVal, updateRadioVal] = useState(7)
16
+    const [formData, updateFormData] = useState({
17
+        pageNum: 1,
18
+        pageSize: 10,
19
+        ...props.location.query,
20
+    })
21
+
22
+    // 获取初始化数据
23
+    const [data, setData] = useState({})
24
+
25
+    useEffect(() => {
26
+        getList(formData);
27
+    }, [])
28
+
29
+    // 查询列表
30
+    const getList = (params) => {
31
+        request({ ...apis.stats.totalPersons, params: { ...params }, }).then((data) => {
32
+            setData(data)
33
+        })
34
+    }
35
+
36
+    //重置搜索
37
+    function handleReset() {
38
+        props.form.resetFields();
39
+    }
40
+
41
+    // 提交事件
42
+    const handleSubmit = (e) => {
43
+        e.preventDefault();
44
+        props.form.validateFields((err, values) => {
45
+            if (!err) {
46
+                console.log('提交数据: ', values)
47
+
48
+            }
49
+        });
50
+        // getList(formData);
51
+    }
52
+    // 更新页码
53
+    const changePageNum = (pageNumber) => {
54
+        props.form.validateFields((err, values) => {
55
+            if (!err) {
56
+                getList({ ...formData, pageNum: pageNumber });
57
+            }
58
+        });
59
+    }
60
+
61
+
62
+    // 表格数据
63
+    const columns = [
64
+
65
+        {
66
+            title: '分享标题',
67
+            dataIndex: 'intention',
68
+            key: 'intention',
69
+            align: 'center',
70
+        },
71
+        {
72
+            title: '分享时间',
73
+            dataIndex: 'userName',
74
+            key: 'userName',
75
+            align: 'center',
76
+            render: (_, record) => <><span>{record.reportDate && moment(record.reportDate).format('YYYY-MM-DD HH:mm:ss')}</span></>,
77
+        },
78
+
79
+    ];
80
+
81
+    const { getFieldDecorator } = props.form
82
+    return (
83
+
84
+        <>
85
+            <Button type="danger" style={{ margin: '0 0 18px 8px' }} onClick={() => router.go(-1)}>返回</Button>
86
+            <Form layout="inline">
87
+                <div style={{ display: 'flex', alignItems: 'center' }}>
88
+                    <Form.Item>
89
+                        {getFieldDecorator('eventType')(
90
+                            <Select placeholder="分享类型" style={{ width: 150 }}>
91
+                                <Option value="activity_share">报名活动</Option>
92
+                                <Option value="help_share">助力活动</Option>
93
+                                <Option value="group_share">拼团活动</Option>
94
+                                <Option value="h5_share">H5活动</Option>
95
+                                <Option value="live_share">直播活动</Option>
96
+                                <Option value="house_share">房源列表</Option>
97
+                                <Option value="building_share">项目</Option>
98
+                                <Option value="news_share">资讯</Option>
99
+                                <Option value="index_share">首页</Option>
100
+                            </Select>
101
+                        )}
102
+                    </Form.Item>
103
+                    <Form.Item>
104
+                        {getFieldDecorator('activityName')(
105
+                            <Input
106
+                                prefix={<Icon type="text" style={{ color: 'rgba(0,0,0,.25)' }} />}
107
+                                placeholder="分享标题"
108
+                            />,
109
+                        )}
110
+                    </Form.Item>
111
+                    <Form.Item style={{ position: 'absolute', right: '38px' }}>
112
+                        <Button type="primary" onClick={handleSubmit}>搜索</Button>
113
+                        <Button style={{ marginLeft: 8 }} onClick={handleReset}>重置</Button>
114
+                    </Form.Item>
115
+                </div>
116
+            </Form>
117
+            <Table rowKey={record => (record.userId + record.buildingId || '')}
118
+                style={{ marginTop: '30px' }}
119
+                dataSource={data.records}
120
+                columns={columns}
121
+                pagination={false}
122
+            />
123
+            < div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: '30px' }}>
124
+                <Pagination showQuickJumper defaultCurrent={1} total={data.total} onChange={changePageNum} current={data.current} />
125
+            </div>
126
+        </>
127
+    )
128
+}
129
+const WrappedHeader = Form.create({ name: 'record' })(record);
130
+
131
+export default WrappedHeader

+ 156
- 0
src/pages/statistical/consultant/table.jsx Vedi File

@@ -0,0 +1,156 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Form, Button, Table, Pagination, Radio, Typography, Avatar } from 'antd';
3
+import router from 'umi/router';
4
+import moment from 'moment';
5
+import BuildSelect from '../../../components/SelectButton/BuildSelect'
6
+import apis from '../../../services/apis';
7
+import request from '../../../utils/request'
8
+
9
+/**
10
+  @param {*} props
11
+  @returns
12
+ */
13
+const { Text } = Typography;
14
+
15
+function record(props) {
16
+    const [formData, updateFormData] = useState({
17
+        pageNum: 1,
18
+        pageSize: 10,
19
+        ...props.location.query,
20
+
21
+    })
22
+
23
+    // 获取初始化数据
24
+    const [data, setData] = useState({})
25
+
26
+
27
+    useEffect(() => {
28
+        getList(formData);
29
+    }, [])
30
+
31
+    // 查询列表
32
+    const typeTag = props.location.query.type || ''
33
+
34
+    const getList = (params) => {
35
+        if (typeTag == 'sharePersons') {
36
+            request({ ...apis.stats.sharePersons, params: { ...params }, }).then((data) => {
37
+                setData(data)
38
+            })
39
+        }
40
+        else if (typeTag == 'homePageNums') {
41
+            request({ ...apis.stats.homePageNums, params: { ...params }, }).then((data) => {
42
+                setData(data)
43
+            })
44
+        }
45
+        else if (typeTag == 'chatPersons') {
46
+            request({ ...apis.stats.chatPersons, params: { ...params }, }).then((data) => {
47
+                setData(data)
48
+            })
49
+        }
50
+        else {
51
+            request({ ...apis.stats.totalPersons, params: { ...params }, }).then((data) => {
52
+                setData(data)
53
+            })
54
+        }
55
+
56
+    }
57
+
58
+    // 更新页码
59
+    const changePageNum = (pageNumber) => {
60
+        props.form.validateFields((err, values) => {
61
+            if (!err) {
62
+                getList({ ...props.location.query, pageNum: pageNumber });
63
+            }
64
+        });
65
+    }
66
+    const toPersonDetail = (personId) => {
67
+        router.push({
68
+            pathname: '/customer/customerlist/publicCustomerDetail',
69
+            query: {
70
+                id: personId,
71
+            },
72
+        });
73
+    }
74
+
75
+    const basicColunms = [
76
+        {
77
+            title: '头像',
78
+            dataIndex: 'picture',
79
+            key: 'picture',
80
+            align: 'center',
81
+            render: (_, record) => <Avatar shape="square" src={record.picture || record.avatarurl} size={64} icon="user" />,
82
+        },
83
+        {
84
+            title: '姓名',
85
+            dataIndex: 'name',
86
+            key: 'name',
87
+            align: 'center',
88
+            render: (_, record) => <span style={{ color: 'blue', cursor: 'pointer' }} onClick={() => toPersonDetail(record.personId)} >{record.name}</span>,
89
+        },
90
+        {
91
+            title: '电话',
92
+            dataIndex: 'phone',
93
+            key: 'phone',
94
+            align: 'center',
95
+        },
96
+        {
97
+            title: '性别',
98
+            dataIndex: 'sex',
99
+            key: 'sex',
100
+            align: 'center',
101
+            render: (_, record) => <span>{record.sex == 1 ? '男' : '女'}</span>,
102
+        },
103
+    ]
104
+
105
+    // 表格数据
106
+    const lastColum = typeTag == 'homePageNums' ? [
107
+        {
108
+            title: '访问时间',
109
+            dataIndex: 'visitTime',
110
+            key: 'visitTime',
111
+            align: 'center',
112
+            render: (_, record) => <> <span>{record.visitTime && moment(record.visitTime).format('YYYY-MM-DD HH:mm:ss')}</span></>,
113
+        },
114
+    ] : typeTag == 'chatPersons' ?
115
+            [
116
+                {
117
+                    title: '最后咨询时间',
118
+                    dataIndex: 'visitTime',
119
+                    key: 'visitTime',
120
+                    align: 'center',
121
+                    render: (_, record) => <> <span>{record.visitTime && moment(record.visitTime).format('YYYY-MM-DD HH:mm:ss')}</span></>,
122
+                },
123
+
124
+            ] : typeTag == 'favorNum' ? [] :
125
+                [
126
+                    {
127
+                        title: '报备时间',
128
+                        dataIndex: 'reportDate',
129
+                        key: 'reportDate',
130
+                        align: 'center',
131
+                        render: (_, record) => <><span>{record.reportDate && moment(record.reportDate).format('YYYY-MM-DD HH:mm:ss')}</span>}</>,
132
+                    },
133
+                ]
134
+    const columns = basicColunms.concat(lastColum)
135
+
136
+
137
+
138
+    return (
139
+
140
+        <>
141
+            <Button type="danger" style={{ marginLeft: '18px' }} onClick={() => router.go(-1)}>返回</Button>
142
+            <Table rowKey={record => (record.phone + record.buildingId || '')}
143
+                style={{ marginTop: '30px' }}
144
+                dataSource={data.records}
145
+                columns={columns}
146
+                pagination={false}
147
+            />
148
+            < div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: '30px' }}>
149
+                <Pagination showQuickJumper defaultCurrent={1} total={data.total} onChange={changePageNum} current={data.current} />
150
+            </div>
151
+        </>
152
+    )
153
+}
154
+const WrappedHeader = Form.create({ name: 'record' })(record);
155
+
156
+export default WrappedHeader

+ 158
- 0
src/pages/statistical/consultant/visitNum.jsx Vedi File

@@ -0,0 +1,158 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Form, Button, Table, Pagination, Select, Input, Icon } from 'antd';
3
+import router from 'umi/router';
4
+import moment from 'moment';
5
+import apis from '../../../services/apis';
6
+import request from '../../../utils/request'
7
+
8
+/**
9
+  @param {*} props
10
+  @returns
11
+ */
12
+const { Option } = Select;
13
+
14
+function record(props) {
15
+    const [radioVal, updateRadioVal] = useState(7)
16
+    const [formData, updateFormData] = useState({
17
+        pageNum: 1,
18
+        pageSize: 10,
19
+        ...props.location.query,
20
+    })
21
+
22
+    // 获取初始化数据
23
+    const [data, setData] = useState({})
24
+
25
+    useEffect(() => {
26
+        getList(formData);
27
+    }, [])
28
+
29
+    // 查询列表
30
+    const getList = (params) => {
31
+        request({ ...apis.stats.totalPersons, params: { ...params }, }).then((data) => {
32
+            setData(data)
33
+        })
34
+    }
35
+
36
+    //重置搜索
37
+    function handleReset() {
38
+        props.form.resetFields();
39
+    }
40
+
41
+    // 提交事件
42
+    const handleSubmit = (e) => {
43
+        e.preventDefault();
44
+        props.form.validateFields((err, values) => {
45
+            if (!err) {
46
+                console.log('提交数据: ', values)
47
+
48
+            }
49
+        });
50
+        // getList(formData);
51
+    }
52
+    // 更新页码
53
+    const changePageNum = (pageNumber) => {
54
+        props.form.validateFields((err, values) => {
55
+            if (!err) {
56
+                getList({ ...formData, pageNum: pageNumber });
57
+            }
58
+        });
59
+    }
60
+
61
+
62
+    // 表格数据
63
+    const columns = [
64
+
65
+        {
66
+            title: '分享标题',
67
+            dataIndex: 'intention',
68
+            key: 'intention',
69
+            align: 'center',
70
+        },
71
+        {
72
+            title: '姓名',
73
+            dataIndex: 'name',
74
+            key: 'name',
75
+            align: 'center',
76
+        },
77
+        {
78
+            title: '电话',
79
+            dataIndex: 'phone',
80
+            key: 'phone',
81
+            align: 'center',
82
+        },
83
+        {
84
+            title: '性别',
85
+            dataIndex: 'sex',
86
+            key: 'sex',
87
+            align: 'center',
88
+            render: (_, record) => <span>{record.sex == 1 ? '男' : '女'}</span>,
89
+        },
90
+        {
91
+            title: '访问时间',
92
+            dataIndex: 'userName',
93
+            key: 'userName',
94
+            align: 'center',
95
+            render: (_, record) => <><span>{record.reportDate && moment(record.reportDate).format('YYYY-MM-DD HH:mm:ss')}</span></>,
96
+        },
97
+
98
+    ];
99
+
100
+    const { getFieldDecorator } = props.form
101
+    return (
102
+
103
+        <>
104
+            <Button type="danger" style={{ margin: '0 0 18px 8px' }} onClick={() => router.go(-1)}>返回</Button>
105
+            <Form layout="inline">
106
+                <div style={{ display: 'flex', alignItems: 'center' }}>
107
+                    <Form.Item>
108
+                        {getFieldDecorator('eventType')(
109
+                            <Select placeholder="分享类型" style={{ width: 150 }}>
110
+                                <Option value="activity_share">报名活动</Option>
111
+                                <Option value="help_share">助力活动</Option>
112
+                                <Option value="group_share">拼团活动</Option>
113
+                                <Option value="h5_share">H5活动</Option>
114
+                                <Option value="live_share">直播活动</Option>
115
+                                <Option value="house_share">房源列表</Option>
116
+                                <Option value="building_share">项目</Option>
117
+                                <Option value="news_share">资讯</Option>
118
+                                <Option value="index_share">首页</Option>
119
+                            </Select>
120
+                        )}
121
+                    </Form.Item>
122
+                    <Form.Item>
123
+                        {getFieldDecorator('activityName')(
124
+                            <Input
125
+                                prefix={<Icon type="text" style={{ color: 'rgba(0,0,0,.25)' }} />}
126
+                                placeholder="分享标题"
127
+                            />,
128
+                        )}
129
+                    </Form.Item>
130
+                    <Form.Item>
131
+                        {getFieldDecorator('userName')(
132
+                            <Input
133
+                                prefix={<Icon type="text" style={{ color: 'rgba(0,0,0,.25)' }} />}
134
+                                placeholder="用户名"
135
+                            />,
136
+                        )}
137
+                    </Form.Item>
138
+                    <Form.Item style={{ position: 'absolute', right: '38px' }}>
139
+                        <Button type="primary" onClick={handleSubmit}>搜索</Button>
140
+                        <Button style={{ marginLeft: 8 }} onClick={handleReset}>重置</Button>
141
+                    </Form.Item>
142
+                </div>
143
+            </Form>
144
+            <Table rowKey={record => (record.userId + record.buildingId || '')}
145
+                style={{ marginTop: '30px' }}
146
+                dataSource={data.records}
147
+                columns={columns}
148
+                pagination={false}
149
+            />
150
+            < div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: '30px' }}>
151
+                <Pagination showQuickJumper defaultCurrent={1} total={data.total} onChange={changePageNum} current={data.current} />
152
+            </div>
153
+        </>
154
+    )
155
+}
156
+const WrappedHeader = Form.create({ name: 'record' })(record);
157
+
158
+export default WrappedHeader

+ 111
- 0
src/pages/statistical/consultant/visitPersons.jsx Vedi File

@@ -0,0 +1,111 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Form, Button, DatePicker, Table, Pagination, Radio, Typography, Avatar } from 'antd';
3
+import router from 'umi/router';
4
+import moment from 'moment';
5
+import BuildSelect from '../../../components/SelectButton/BuildSelect'
6
+import apis from '../../../services/apis';
7
+import request from '../../../utils/request'
8
+
9
+/**
10
+  @param {*} props
11
+  @returns
12
+ */
13
+const { RangePicker } = DatePicker;
14
+const { Text } = Typography;
15
+
16
+function record(props) {
17
+    const [formData, updateFormData] = useState({
18
+        pageNum: 1,
19
+        pageSize: 10,
20
+        ...props.location.query,
21
+
22
+    })
23
+
24
+    // 获取初始化数据
25
+    const [data, setData] = useState({})
26
+
27
+
28
+    useEffect(() => {
29
+        getList(formData);
30
+    }, [])
31
+
32
+    // 查询列表
33
+    const getList = (params) => {
34
+        request({ ...apis.stats.totalPersons, params: { ...params }, }).then((data) => {
35
+            setData(data)
36
+        })
37
+    }
38
+
39
+    // 更新页码
40
+    const changePageNum = (pageNumber) => {
41
+        props.form.validateFields((err, values) => {
42
+            if (!err) {
43
+                getList({ ...props.location.query, pageNum: pageNumber });
44
+            }
45
+        });
46
+    }
47
+    const toPersonDetail = (personId) => {
48
+        router.push({
49
+            pathname: '/customer/customerlist/publicCustomerDetail',
50
+            query: {
51
+                id: personId,
52
+            },
53
+        });
54
+    }
55
+    // 表格数据
56
+    const columns = [
57
+        {
58
+            title: '姓名',
59
+            dataIndex: 'name',
60
+            key: 'name',
61
+            align: 'center',
62
+        },
63
+        {
64
+            title: '电话',
65
+            dataIndex: 'phone',
66
+            key: 'phone',
67
+            align: 'center',
68
+        },
69
+        {
70
+            title: '性别',
71
+            dataIndex: 'sex',
72
+            key: 'sex',
73
+            align: 'center',
74
+            render: (_, record) => <span>{record.sex == 1 ? '男' : '女'}</span>,
75
+        },
76
+        {
77
+            title: '访问次数',
78
+            dataIndex: 'visitNum',
79
+            key: 'visitNum',
80
+            align: 'center',
81
+            render: (_, record) => <span style={{ color: 'blue', cursor: 'pointer' }} onClick={() => toPersonDetail(record.personId)} >{record.visitNum}</span>,
82
+        },
83
+        {
84
+            title: '最后访问时间',
85
+            dataIndex: 'reportDate',
86
+            key: 'reportDate',
87
+            align: 'center',
88
+            render: (_, record) => <><span>{record.reportDate && moment(record.reportDate).format('YYYY-MM-DD HH:mm:ss')}</span></>,
89
+        },
90
+
91
+    ];
92
+
93
+    return (
94
+
95
+        <>
96
+            <Button type="danger" style={{ marginLeft: '18px' }} onClick={() => router.go(-1)}>返回</Button>
97
+            <Table rowKey={record => (record.phone + record.buildingId || '')}
98
+                style={{ marginTop: '30px' }}
99
+                dataSource={data.records}
100
+                columns={columns}
101
+                pagination={false}
102
+            />
103
+            < div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: '30px' }}>
104
+                <Pagination showQuickJumper defaultCurrent={1} total={data.total} onChange={changePageNum} current={data.current} />
105
+            </div>
106
+        </>
107
+    )
108
+}
109
+const WrappedHeader = Form.create({ name: 'record' })(record);
110
+
111
+export default WrappedHeader

+ 53
- 9
src/services/apis.js Vedi File

@@ -399,6 +399,11 @@ export default {
399 399
       url: `${prefix}/selectNewsUserCount`,
400 400
       action: 'selectNewsUserCount',
401 401
     },
402
+    changeNewUser: {
403
+      method: 'GET',
404
+      url: `${prefix}/changeNewsUserCount`,
405
+      action: 'selectNewsUserCount',
406
+    },
402 407
     userConversion: {
403 408
       method: 'GET',
404 409
       url: `${prefix}/selectConversion`,
@@ -419,8 +424,11 @@ export default {
419 424
       url: `${prefix}/listNoticeByCondition`,
420 425
       action: 'listNoticeByCondition',
421 426
     },
422
-
423
-
427
+    exportIntentionUsers: {
428
+      method: 'GET',
429
+      url: `${prefix}/exportIntentionUser`,
430
+      action: 'exportIntentionUser',
431
+    },
424 432
   },
425 433
   activity: {
426 434
     list: {
@@ -1425,27 +1433,27 @@ export default {
1425 1433
     },
1426 1434
   },
1427 1435
   taH5SampleManager: {
1428
-    taH5Demand:{
1436
+    taH5Demand: {
1429 1437
       url: `${prefix}/taH5Demand`,
1430 1438
       method: 'GET',
1431 1439
       action: 'admin.taH5Demand.get',
1432 1440
     },
1433
-    addTaH5Demand:{
1441
+    addTaH5Demand: {
1434 1442
       url: `${prefix}/taH5Demand`,
1435 1443
       method: 'POST',
1436 1444
       action: 'admin.taH5Demand.get',
1437 1445
     },
1438
-    taH5DemandById:{
1446
+    taH5DemandById: {
1439 1447
       url: `${prefix}/taH5Demand/:id`,
1440 1448
       method: 'GET',
1441 1449
       action: 'admin.taH5Demand.get',
1442 1450
     },
1443
-    updateH5DemandById:{
1451
+    updateH5DemandById: {
1444 1452
       url: `${prefix}/taH5Demand/:id`,
1445 1453
       method: 'PUT',
1446 1454
       action: 'admin.taH5Demand.get',
1447 1455
     },
1448
-    batchDelDemands:{
1456
+    batchDelDemands: {
1449 1457
       url: `${prefix}/batchDelTaH5Demands`,
1450 1458
       method: 'PUT',
1451 1459
       action: 'admin.taH5Demand.get',
@@ -1562,7 +1570,7 @@ export default {
1562 1570
       url: `${prefix}/taContractTemplate/:id`,
1563 1571
       action: 'admin.getContractTemplate.get',
1564 1572
     },
1565
-   
1573
+
1566 1574
   },
1567 1575
   manage: {
1568 1576
     list: {
@@ -1581,7 +1589,7 @@ export default {
1581 1589
       action: 'admin.contract.id.put',
1582 1590
     },
1583 1591
   },
1584
-  activityDataStatis:{
1592
+  activityDataStatis: {
1585 1593
     total: {
1586 1594
       method: 'GET',
1587 1595
       url: `${prefix}/activityStatistical/total`,
@@ -1614,6 +1622,42 @@ export default {
1614 1622
       url: `${prefix}/stats/tableList`,
1615 1623
       action: 'admin.contract.list.get',
1616 1624
     },
1625
+    consultantKPI: {
1626
+      method: 'GET',
1627
+      url: `${prefix}/stats/consultant/kpi`,
1628
+      action: 'admin.contract.list.get',
1629
+    },
1630
+    exportConsultantKPI: {
1631
+      method: 'POST',
1632
+      url: `${prefix}/stats/consultant/kpi`,
1633
+      action: 'admin.contract.list.post',
1634
+    },
1635
+    totalPersons: { // 客户总计
1636
+      method: 'GET',
1637
+      url: `${prefix}/stats/consultant/customer`,
1638
+      action: 'admin.contract.list.get',
1639
+    },
1640
+    sharePersons: { // 分享拓客
1641
+      method: 'GET',
1642
+      url: `${prefix}/stats/consultant/share/customer`,
1643
+      action: 'admin.contract.list.get',
1644
+    },
1645
+    homePagePersons: { // 主页访问人数
1646
+      method: 'GET',
1647
+      url: `${prefix}/stats/consultant/homepage/persons`,
1648
+      action: 'admin.contract.list.get',
1649
+    },
1650
+    homePageNums: { // 主页访问次数
1651
+      method: 'GET',
1652
+      url: `${prefix}/stats/consultant/homepage/times`,
1653
+      action: 'admin.contract.list.get',
1654
+    },
1655
+    chatPersons: { // 咨询数
1656
+      method: 'GET',
1657
+      url: `${prefix}/stats/consultant/chat/persons`,
1658
+      action: 'admin.contract.list.get',
1659
+    },
1660
+
1617 1661
     buildingExport: {
1618 1662
       method: 'GET',
1619 1663
       url: `${prefix}/stats/buildingExport`,